I almost never use tags, mainly because it’s generally tedious to assign them and especially as it’s distracting to check what tags already exist.
However @josieduffy had a great idea:
With a tag selected we could search all records whose content contains the tag.
Of course this might be no good idea if you’ve carefully maintained your tags as it blindly assigns the tag to everything that matches. However if you’ve also maintained your databases this carefully then it might be an interesting mix of tags and smart groups.
This script
- takes one or more selected tags
- asks in which group it should search
- gets the tag’s aliases
- assigns the selected tag to every matching record
If property useGroupSelector
is set to false then the current database is used.
If property includeNameInSearch
is set to false then only text
is searched.
Tag aliases are always included.
Thanks @josieduffy!
-- Assign selected tag to matching records based on content and name
property useGroupSelector : true -- if false the current database is used
property includeNameInSearch : true -- if false only text is searched
tell application id "DNtp"
try
set theTagRecords to selected records
if theTagRecords = {} then error "Please select some tags."
if useGroupSelector = true then
set theSearchScope to display group selector "Search and assign Tags to records in:" for current database
else
set theSearchScope to root of current database
end if
show progress indicator "Tagging... " steps (count theTagRecords) as string with cancel button
repeat with thisRecord in theTagRecords
if (location of thisRecord) starts with "/Tags/" then
set thisRecord_Name to name of thisRecord
step progress indicator thisRecord_Name
set thisRecord_Aliases to aliases of thisRecord
set theNames to {thisRecord_Name} & my tid(thisRecord_Aliases, {", ", "; ", ",", ";"})
set theNames_readyForQuery to "\"" & my tid(theNames, "\" OR \"") & "\""
if includeNameInSearch = true then
set theQuery to "tags!=" & thisRecord_Name & " kind:any {any: name:" & theNames_readyForQuery & " text:" & theNames_readyForQuery & "}"
else
set theQuery to "tags!=" & thisRecord_Name & " kind:any text:" & theNames_readyForQuery
end if
set theResults to search theQuery in theSearchScope
repeat with thisResult in theResults
set tags of thisResult to (tags of thisResult) & thisRecord_Name
end repeat
end if
end repeat
hide progress indicator
on error error_message number error_number
hide progress indicator
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
on tid(theInput, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
if class of theInput = text then
set theOutput to text items of theInput
else if class of theInput = list then
set theOutput to theInput as text
end if
set AppleScript's text item delimiters to d
return theOutput
end tid