This value returned by this code reveals that there are three distinct attribute runs. Only the second has a URL.
tell application "DEVONthink 3"
tell front think window
set refText to a reference to its selected text
URL of attribute runs of refText
end tell
end tell
-- > {missing value, "https://discourse.devontechnologies.com/c/devonthink/scripting/18", missing value}
And yet if I right-click on the selection it gives me the option to grab a link for the selection. Any idea why that works, but calling it via AppleScript doesn’t?
on run
set mdLinks to mdFromLabelledLinks(selectedTextLabelLinkPairs())
set the clipboard to mdLinks
return mdLinks
end run
on selectedTextLabelLinkPairs()
tell application "DEVONthink 3"
set thinkWindow to its front think window
if exists thinkWindow then
tell thinkWindow to ¬
set refText to a reference to (its selected text)
if exists refText then
set runs to a reference to (attribute runs of refText)
my zip(text of runs, URL of runs)
else
{}
end if
else
{}
end if
end tell
end selectedTextLabelLinkPairs
on mdFromLabelledLinks(kvs)
script f
on |λ|(kv)
set {k, v} to kv
if missing value is not v then
{"[" & k & "](" & v & ")"}
else
{}
end if
end |λ|
end script
my unlines(my concatMap(f, kvs))
end mdFromLabelledLinks
on concatMap(f, xs)
set lng to length of xs
set acc to {}
tell f
repeat with i from 1 to lng
set acc to acc & (|λ|(item i of xs, i, xs))
end repeat
end tell
acc
end concatMap
on min(x, y)
if y < x then
y
else
x
end if
end min
on unlines(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set s to xs as text
set my text item delimiters to dlm
s
end unlines
on zip(xs, ys)
set n to min(length of xs, length of ys)
set vs to {}
repeat with i from 1 to n
set end of vs to {item i of xs, item i of ys}
end repeat
return vs
end zip
It can, of course, be expressed more parsimoniously, but perhaps not without straining a reader’s patience with the overloading of it and its.
Extracting just the main function:
on selectedTextLabelLinkPairs()
tell application "DEVONthink 3"
tell front think window
if exists then
tell (a reference to (its selected text))
if exists then
tell attribute runs
my zip(text of it, URL of it)
end tell
else
{}
end if
end tell
else
{}
end if
end tell
end tell
end selectedTextLabelLinkPairs
I realized my error after dissecting winter’s solution.
When I saw the feature in 3.9 allowing a direct link to a selection in pdfs, I dove into my automation scripts to make things in my workflow better. Because I know you all love automation as much as I do, I assumed that there would be a new AppleScript link to that feature so when I saw “selected text” as an option in the AS dictionary my self-delusion was complete.
Thank you for a great product and for loving making it better and AppleScript-able for those of us geeks who love to use it!
Currently there is no AppleScript property for a record’s selection link, page link, paragraph link, or annotation link. There is only the reference url and item link parameters that potentially can be strung together to create such entities.
The page reference looks pretty easy to find, and the length parameter is obviously easy. Finding the start parameter though doesn’t seem straight forward other than "find"ing the selection within the total text and then hoping it’s the only text like that in the document…
this code creates a link into devonthink equivalent to a “selection link”. Let me know any improvements you see that need to be done.
-- Return md link to selected text
tell application id "DNtp"
set fWindow to its front window
if exists fWindow then
set refText to a reference to selected text of fWindow
if exists refText then
set attr to a reference to (attribute runs of refText)
set theText to text of attr
set theText to first item of theText
set theURL to URL of attr
set theURL to first item of theURL
-- build link
set theRecord to content record of fWindow
set allText to plain text of theRecord
set theStart to offset of theText in allText
set theStart to theStart - 1
set theLength to count of theText
set theLink to reference URL of theRecord & ¬
"?page=" & current page of fWindow & ¬
"&start=" & (theStart as string) & ¬
"&length=" & (length of theText) as string
if missing value is not theURL then
set theText to "[" & theText & "](" & theURL & ")"
end if
set returnText to ((theText & "[^" & theStart as string) & "]}" & return & return & ¬
"[^" & theStart as string) & "]: " & theLink
return returnText
end if
end if
return ""
end tell
This parameter is actually relative to beginning of the page. However, it’s possible to create selection links without having to use start/length parameters.
The page and search parameters are sufficient if the search parameter contains the escaped content of the selected text.