Script: Smart Rule - Assign Tags with ignoring punctuation in text

This Smart Rule script assigns tags with ignoring punctuation in text.

Intro

Using DEVONthink’s Smart Rule script “Assign tags” it’s possible to assign a tag Hello, world to a record that doesn’t contain the exact tag if you’ve added an alias without punctuation Hello world to the tag:

See Script: Add tag alias without punctuation

Objective

But

I’t not possible with the default “Assign tags” Smart Rule script.
However it is possible with a little setup and these scripts.

This capture shows the result without the usage of an alias:

This capture shows the result when you’ve added an alias without punctuation:

So with a little setup it’s possible to ignore punctuation in both, in tags and in text.

Script 1

This is a Script Library which is necessary as we can’t use AppleScriptObjC directly in Smart Rule scripts, neither embedded nor external.

In Script Editor.app

  • create a new document
  • paste Script 1
  • press ⌘S
  • press ⇧⌘G
  • paste ~/Library/Script Libraries/DEVONthink - Ignore Punctuation.scpt
  • press Enter/Return.
  • press Enter/Return.
-- Script Library - DEVONthink - Ignore Punctuation
-- Save this script in "~/Library/Script Libraries/DEVONthink - Ignore Punctuation.scpt"

use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

on getCharacterSet(theIgnoredPunctuation)
	try
		if theIgnoredPunctuation ≠ "" then
			set theCharacterSet to current application's NSMutableCharacterSet's alloc()'s init()
			theCharacterSet's addCharactersInString:(theIgnoredPunctuation)
		else
			set theCharacterSet to current application's NSCharacterSet's punctuationCharacterSet()
		end if
		return theCharacterSet
		
	on error error_message number error_number
		activate
		display alert "Error: Handler \"getCharacterSet\"" message error_message as warning
		error number -128
	end try
end getCharacterSet

on stripPunctuation(theText, theCharacterSet)
	try
		set theString to (current application's NSString's stringWithString:theText)
		set theArray to theString's componentsSeparatedByCharactersInSet:(theCharacterSet)
		set theString_withoutPunctuation to theArray's componentsJoinedByString:""
		return theString_withoutPunctuation as string
		
	on error error_message number error_number
		activate
		display alert "Error: Handler \"stripPunctuation\"" message error_message as warning
		error number -128
	end try
end stripPunctuation

Script 2

The actual Smart Rule script.

  • By default all punctuation is ignored.

    • If you want to restrict ignored punctuation set property theIgnoredPunctuation to e.g. ",". Don’t include a space, i.e. don’t set ", " (or ", ;" ). This is correct: "," (or ",;").
  • Save it to DEVONthink’s Smart Rule folder
    ~/Library/Application Scripts/com.devon-technologies.think3/Smart Rules/.

-- Smart Rule script - Assign Tags with ignoring punctuation in text

-- Setup, required: 		Save script "DEVONthink - Ignore Punctuation" in "~/Library/Script Libraries/DEVONthink - Ignore Punctuation.scpt"

-- Setup, optional:  	By default all punctuation is ignored. If you want to restrict ignored punctuation set property theIgnoredPunctuation to e.g. ",".
--						Don't include a space " " in property theIgnoredPunctuation. Don't do this: ", " (or ", ;"). This is correct: "," (or ",;").

property theIgnoredPunctuation : "" -- Add punctuation to ignore it (or leave this property set to to an empty string "" to ignore all punctuation)

on performSmartRule(theRecords)
	tell application id "DNtp"
		try
			set theCharacterSet to script "DEVONthink - Ignore Punctuation"'s getCharacterSet(theIgnoredPunctuation)
			
			repeat with thisRecord in theRecords
				set theTags to extract keywords from record thisRecord with existing tags
				set theText to plain text of thisRecord
				set theText_withoutPunctuation to script "DEVONthink - Ignore Punctuation"'s stripPunctuation(theText, theCharacterSet)
				set theTag_Names to (name of tag groups of database of thisRecord) & (aliases of tag groups of database of thisRecord)
				
				repeat with thisTag in theTag_Names
					set thisTag to thisTag as string
					if theText_withoutPunctuation contains thisTag then
						set end of theTags to thisTag
					end if
				end repeat
				
				if theTags ≠ {} then set tags of thisRecord to (tags of thisRecord) & theTags
			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

:warning: Note:

Please test the script with duplicates in a new database. I don’t use tags or tag aliases that much so I might have missed something.