I’m working with indexed markdown notes, and add tags within DEVONthink. However, when working in an external editor, the tags don’t carry over.
I see @cgrunenberg created a script to append tags and comments to a selection of notes, which is great, but I have been unable to format the output so each tag is appended with a hashtag. I also don’t need the comments appended, so adapted to remove this feature.
This is what I am trying to achieve with a script:
-- Append Tags to selection
-- Created by John Mickey on 2017-02-23
-- Based on a script created by Christian Grunenberg on Aug Tue 16 2011.
tell application id "DNtp"
try
set theSelection to the selection
set theWindow to missing value
set {od, text item delimiters of AppleScript} to {text item delimiters of AppleScript, ", "}
repeat with theRecord in theSelection
if type of theRecord is rtf or type of theRecord is rtfd then
set theTab to open tab for record theRecord in theWindow
set theWindow to think window of theTab
set theTags to tags of theRecord as string -- tags
set theTab to open tab for record theRecord in theWindow
set current tab of theWindow to theTab -- Rich text scripting needs a visible document
tell text of theTab to make new paragraph with data (return & return & "Tags: " & theTags & return) at end
save theTab
end if
end repeat
set text item delimiters of AppleScript to od
if theWindow is not missing value then close theWindow
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink Pro" message error_message as warning
end try
end tell
It also updates tags if you removed them in DEVONthink.
-- Append to/update tags in markdown text
tell application id "DNtp"
try
set theRecords to selection of think window 1
if theRecords = {} then error "Nothing selected."
repeat with thisRecord in theRecords
set theType to (type of thisRecord) as string
if theType = "markdown" or theType = "«constant Ctypmkdn»" then
set theText to plain text of thisRecord
if theText ≠ "" then
set theText_cleaned to my trimEnd(theText)
set theParagraphs to paragraphs of theText_cleaned
set lastLine to (item -1 of theParagraphs) as string
set theTags to tags of thisRecord
if theTags ≠ {} then
set theTags_sorted to my sort_list(theTags)
set theTextTags to {}
repeat with thisTag in theTags_sorted
set end of theTextTags to "#" & thisTag as string
end repeat
set newLastLine to my tid(theTextTags, space & "," & space)
if lastLine starts with "#" then
set newText_list to (items 1 thru -2 in theParagraphs)
else
set newText_list to theParagraphs
end if
set newText to my tid(newText_list, linefeed)
set newText_cleaned to my trimEnd(newText)
set plain text of thisRecord to (newText_cleaned & linefeed & linefeed & newLastLine) as string
else if theTags = {} and lastLine starts with "#" then
set newText_list to items 1 thru -2 in theParagraphs
set newText to my tid(newText_list, linefeed)
set plain text of thisRecord to (newText & linefeed) as string
end if
end if
end if
end repeat
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
on trimEnd(str)
local str, whiteSpace
try
set str to str as string
set whiteSpace to {character id 10, return, space, tab}
try
repeat while str's last character is in whiteSpace
set str to str's text 1 thru -2
end repeat
return str
on error number -1728
return ""
end try
on error eMsg number eNum
error "Can't trimEnd: " & eMsg number eNum
end try
end trimEnd
on tid(theList, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theString to theList as text
set AppleScript's text item delimiters to d
return theString
end tid
on sort_list(theList)
considering numeric strings
set theIndexList to {}
set theSortedList to {}
repeat (length of theList) times
set theLowItem to ""
repeat with a from 1 to (length of theList)
if a is not in theIndexList then
set theCurrentItem to item a of theList as text
if theLowItem is "" then
set theLowItem to theCurrentItem
set theLowItemIndex to a
else if theCurrentItem comes before theLowItem then
set theLowItem to theCurrentItem
set theLowItemIndex to a
end if
end if
end repeat
set end of theSortedList to theLowItem
set end of theIndexList to theLowItemIndex
end repeat
end considering
return theSortedList
end sort_list
I’ve also adapted it so it can be used as a smart rule
-- Append to/update tags in markdown text
-- pete31 @ https://discourse.devontechnologies.com/t/append-tags-to-selection-with-hashtag/58812
on performSmartRule(theRecords)
tell application id "DNtp"
try
set theRecords to selection of think window 1
if theRecords = {} then error "Nothing selected."
repeat with thisRecord in theRecords
set theType to (type of thisRecord) as string
if theType = "markdown" or theType = "«constant Ctypmkdn»" then
set theText to plain text of thisRecord
if theText ≠ "" then
set theText_cleaned to my trimEnd(theText)
set theParagraphs to paragraphs of theText_cleaned
set lastLine to (item -1 of theParagraphs) as string
set theTags to tags of thisRecord
if theTags ≠ {} then
set theTags_sorted to my sort_list(theTags)
set theTextTags to {}
repeat with thisTag in theTags_sorted
set end of theTextTags to "#" & thisTag as string
end repeat
set newLastLine to my tid(theTextTags, space & "," & space)
if lastLine starts with "#" then
set newText_list to (items 1 thru -2 in theParagraphs)
else
set newText_list to theParagraphs
end if
set newText to my tid(newText_list, linefeed)
set newText_cleaned to my trimEnd(newText)
set plain text of thisRecord to (newText_cleaned & linefeed & linefeed & newLastLine) as string
else if theTags = {} and lastLine starts with "#" then
set newText_list to items 1 thru -2 in theParagraphs
set newText to my tid(newText_list, linefeed)
set plain text of thisRecord to (newText & linefeed) as string
end if
end if
end if
end repeat
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
end performSmartRule
on trimEnd(str)
local str, whiteSpace
try
set str to str as string
set whiteSpace to {character id 10, return, space, tab}
try
repeat while str's last character is in whiteSpace
set str to str's text 1 thru -2
end repeat
return str
on error number -1728
return ""
end try
on error eMsg number eNum
error "Can't trimEnd: " & eMsg number eNum
end try
end trimEnd
on tid(theList, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theString to theList as text
set AppleScript's text item delimiters to d
return theString
end tid
on sort_list(theList)
considering numeric strings
set theIndexList to {}
set theSortedList to {}
repeat (length of theList) times
set theLowItem to ""
repeat with a from 1 to (length of theList)
if a is not in theIndexList then
set theCurrentItem to item a of theList as text
if theLowItem is "" then
set theLowItem to theCurrentItem
set theLowItemIndex to a
else if theCurrentItem comes before theLowItem then
set theLowItem to theCurrentItem
set theLowItemIndex to a
end if
end if
end repeat
set end of theSortedList to theLowItem
set end of theIndexList to theLowItemIndex
end repeat
end considering
return theSortedList
end sort_list