copy selection plus title as URL/link?

maybe this has been dealt with here before, I couldn’t find it though.

What I’d like to be able to do:
Copy a selection in any application (pdf, website, email etc.) and have the link to the document automatically inserted in DT right after the selected text. So it would look something like this

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. (placeholder text)

the bracketed text being the title I give the selection in the DT panel.

Why would I want this?

I like to keep quotes etc. not in separate notes but bring them together in notes according to the subject. Plus, with the link automatically attached, I can always refer to the source with one click (and don’t have to attache the link in additional steps, which I do at the moment).

Am I making myself understood?


Whenever possible DEVONthink does this already. But it highly depends on whether the originating application presents this information or not. It does this e.g. for text copied from Safari.

Well, not exactly, as far as I can see.

a) DT does copy the URL, but not as a clickable link; to get from the link to the original document, you have to copy and paste the url. Couldn’t it be a clickable link?

b) it copies the full URL which may be loooong. The title as clickable link would be more convenient.

Using text clipped from Safari as an example, DEVONthink gives you 2 options for clicking on the link. The first is the URL in the Navigation bar (above the document toolbar in the picture below) and the second is in the Info pane (click on the @ symbol to the right of the URL).

You can select the text that you want to make a link (placeholder text), select ‘Format>Add Link…’ and drag the URL from the info pane to the entry box to make the URL.

The above will only work with apps that present a URL as Eric mentioned. When clipping text from a PDF in Preview, you will not get a URL to the document so all this could be a moot point anyway if you are looking for a consistent workflow.

Really? I feel like I’m missing out on some basic (and great) functionality. This doesn’t happen when I cut and paste from Safari, nor from within in DTP. Is there a “paste with url” script somewhere or something that I’m missing?


A straight copy/paste will not capture the URL from Safari, but using the Take Rich/Plain Text commands from the Services menu, the DEVONthink clipper extension, the DEVONthink bookmarklets, or dragging text to the Sorter will.

@greg I am aware of that and it works great.

my problem is a different one (also @eric): i want the url (as a clickable link with a title of my choosing) neither on the info panen or in the navigation bar, but right behind the text I clipped.

so that I can copy the text and the link out of the note and put it where I want to have the text without losing the link.

would that be possible - and how?

Does the second example, and picture, that I posted above not do that for you?

I went through the whole process again and found a solution (but maybe there’s a better way). To get the result I want I do the following:

Select Text
New RTF-Memo (via services or else)
Copy URL
write short “placeholder text” after the copied text (in DT-memo)
highlight “placeholder text”
add link
copy URL into entry box to make the URL

It works. But: Is there a smarter way to do it?

Thanks so much so far

script it

I tried to make a script to do this, but I’ve gotten as far as I can with my teeny knowledge of things. The script below sometimes works – for some reason it works when run out of AppleScript Editor, but not out of DTP. It is supposed to take the selected text, copy it to the clipboard, then append to the clipboard a parenthesis with the text “Link” and a link to the current DTP record. [“Selected text (Link)”] Then it could be pasted anywhere. I thought that this would be an easier method than having to have the origin and destination records open at the same time. Unfortunately, getting applescript to add links to rich text on the clipboard is hard, so I had to use a shell script (which for me is really hard) and I only got most of the way there.

Anyway, if someone more capable than me can figure out how to make this work within DTP, rather than only from within AppleScript Editor, I would be grateful!

do shell script "defaults write .GlobalPreferences AppleKeyboardUIMode -int 2"

tell application "System Events" to keystroke "c" using {command down}

tell application id "com.devon-technologies.thinkpro2"
	set Citation to the clipboard as text
	set TheLink to "x-devonthink-item://" & the uuid of content record of think window 1
	set T to "\"{@rtf1@ansi@ansicpg1252@cocoartf1038@cocoasubrtf320 @f0@fs24 @cf0 " & Citation & " ({@field{@*@fldinst{HYPERLINK \"" & TheLink & "\"}}{@fldrslt Link}})}\""
	do shell script "echo " & (T) & " | sed 's/@/\\\\/g' | pbcopy -Prefer rtf"
end tell

So, personally I find it difficult to make RTFs using scripts, especially with links. The easy way out in DTPO is to make an HTML record, and then use Data > Convert to make that into RTF. This script takes the current selected text in the current window and makes an HTML clipfile with the link embedded. Not canonical HTML, but it works. I add a keyboard shortcut to this script by naming it something like “Make clipfile___Cmd-Opt-K.scpt” (three underscores). You can make a whole series of individual clipfiles as you are reading through a document, then select them all and use Data > Merge to make one file. I believe this satisfies one of your initial criteria.

This works best with clipping from PDFs. I get weird and inconsistent results from other file types. Wrapping the code in “repeat-with selection” is not necessary, but is convenient.

tell application id "com.devon-technologies.thinkpro2"
	set theSelection to selection
	if theSelection is {} then error "Please select something"
	repeat with thisItem in theSelection
		set theCitation to selected text of think window 1
		if the current page of think window 1 ≠ -1 then
			set thePage to "?page=" & ((the current page of think window 1) as string)
			set thePage to ""
		end if
		set theURL to "x-devonthink-item://" & (uuid of thisItem) & thePage
		set theAnnotation to theCitation & " <a href=\"" & theURL & "\">(click here)</a>"
		set theName to name of thisItem
		create record with {name:theName, source:theAnnotation, type:html}
	end repeat
end tell

Making an HTML clip is probably a safer way to go, but I don’t always want to make a new record for every citation…

I fixed my last script so that it works within DTPO (and added some nice bits from the HTML post above!). I think that this will probably hang if the copied text includes a \ or a ", and I haven’t figured out how to work that out. But in case anyone reading this thread is still interested in the initial request, here is a (closer) stab at it:

tell application id "com.devon-technologies.thinkpro2"
	set Citation to selected text of think window 1 as text
	if Citation is "" then error "No text selected"
	if the current page of think window 1 ≠ -1 then
		set thePage to "?page=" & ((the current page of think window 1) as string)
		set thePage to ""
	end if
	set TheLink to "x-devonthink-item://" & (the uuid of content record) & thePage
	set T to "\"{¤rtf1¤ansi¤ansicpg1252¤cocoartf1038¤cocoasubrtf320 ¤f0¤fs24 ¤cf0 " & Citation & " ({¤field{¤*¤fldinst{HYPERLINK \"" & TheLink & "\"}}{¤fldrslt Link}})}\""
	do shell script "echo " & (T) & " | sed 's/¤/\\\\/g' | pbcopy -Prefer rtf"
end tell

I was away from any computer for a week (yes, there still are offline-areas in this world), so I couldn’t follow the thread to my initial request.

I am absolutely delighted about the scripting (which I am incapable of doing) and will try it asap.

Thanks a lot!

as you said: it works within dtpo and with pdfs. great!
(it screws up german umlaute though (ä,ü,ö))

if anyone else is interested in this problem: what would it take to make it work in other applications as well (safari, firefox) for import into dtpo?

I modified the script so that it can remove accents from input text, so that the output text isn’t messy. (I couldn’t find a way to preserve the accented characters in a shell script.) I added the accents I commonly come across for French text – but you can see how to add replacement characters for other accents in the script.

tell application id "com.devon-technologies.thinkpro2"
	set Citation to selected text of think window 1 as text
	if Citation is "" then error "No text selected"
	set ReplacementsList to {¬
		{{"À", "Á", "Â"}, "A"}, ¬
		{{"à", "á", "â"}, "a"}, ¬
		{{"è", "é", "ê", "ë"}, "e"}, ¬
		{{"î", "í", "ì"}, "i"}, ¬
		{{"ô"}, "o"} ¬
	repeat with ReplacementPair in ReplacementsList
		set AccentedItemList to item 1 in ReplacementPair
		set UnaccentedItem to item 2 in ReplacementPair
		repeat with AccentedItem in AccentedItemList
			set Citation to my replaceCharacter(Citation, AccentedItem, UnaccentedItem)
		end repeat
	end repeat
	if the current page of think window 1 ≠ -1 then
		set thePage to "?page=" & ((the current page of think window 1) as string)
		set thePage to ""
	end if
	set TheLink to "x-devonthink-item://" & (the uuid of content record) & thePage
	set T to "\"{¤rtf1¤ansi¤ansicpg1252¤cocoartf1038¤cocoasubrtf320 ¤f0¤fs24 ¤cf0 " & (quoted form of Citation) & " ({¤field{¤*¤fldinst{HYPERLINK \"" & TheLink & "\"}}{¤fldrslt Link}})}\""
	do shell script "echo " & (T) & " | sed 's/¤/\\\\/g' | pbcopy -Prefer rtf"
end tell

on replaceCharacter(theString, theOriginalChar, theNewChar)
	local od
	set {od, AppleScript's text item delimiters} to {AppleScript's text item delimiters, theOriginalChar}
	set theStringParts to text items of theString
	if (count of theStringParts) is greater than 1 then
		set theString to text item 1 of theStringParts as string
		repeat with eachPart in items 2 thru -1 of theStringParts
			set theString to theString & theNewChar & eachPart as string
		end repeat
	end if
	set AppleScript's text item delimiters to od
	return theString
end replaceCharacter

The accents can be preserved by specifying UTF-8 encoding.

Something like this:

-- Robin Trew - Houthakker 2011 Apr 5
-- Create a link, in the clipboard, to the selected DT folder or record, 
-- with text and page number if any text is selected.

tell application id "DNtp"
	tell think windows
		if (count) < 1 then return
			set strText to (its selected text) as string
			set blnTextSeln to strText ≠ ""
			if blnTextSeln then set lngPage to (its current page)
			set oRec to content record
			if oRec is not missing value then -- 	-- GET THE NAME AND URL OF ANY SELECTED RECORD
				tell oRec
					if blnTextSeln then -- 		-- ADD ANY PAGE NUMBER TO THE NAME & URL
						set {strName, strURL} to {name & "  p." & (lngPage + 1), reference URL & "?page=" & lngPage}
						set {strName, strURL} to {name, reference URL}
					end if
				end tell
				set lstSeln to selection
				if (count of lstSeln) < 1 then return
				tell first item of lstSeln
					set {strName, strURL} to {name, reference URL}
				end tell
			end if
		end tell
	end tell
end tell

set strHTML to "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"/>
<font size=3 face=Verdana>"

if blnTextSeln then
	set strHTML to strHTML & strText & "&nbsp;<a href=\"" & strURL & "\">" & strName & "</a></font>"
	set strHTML to strHTML & "<a href=\"" & strURL & "\">" & strName & "</a></font>"
end if
do shell script ("echo " & quoted form of strHTML & " | textutil -format html -convert rtf -stdin -stdout | pbcopy -Prefer rtf")
Growl(strName & return & strText)

on Growl(strText)
	tell application id "sevs"
		set blnGrowlRunning to (count of (every process whose name is "GrowlHelperApp")) > 0
		if blnGrowlRunning then
			set strLegend to "Link placed in clipboard"
			tell application "GrowlHelperApp"
				register as application "houthakker scripts" all notifications {strLegend} default notifications {strLegend} icon of application "DevonThink Pro"
				notify with name strLegend title strLegend application name "houthakker scripts" description strText
			end tell
		end if
	end tell
end Growl

That’s great, thanks!

I don’t use Growl, so I deleted the lines starting with “Growl(strName & return & strText)” to the end, and it still worked fine.

If anyone is looking for a script that aggregates the clippings into a clip file, there is an older thread and script I wrote that does similar things here:

I use this script every day, and though it has its quirks because of the way Devonthink implements its applescript commands manipulating windows, these quirks are documented in the somewhat whiney comments within the script.

This script uses search strings as well as page numbers to find the selected text.

Hopefully it is still useful!