Name extensions aren't excluded consistently thus leading to wrong search results

There’s a problem with DEVONthink’s naming of records: some names include the extension, some don’t.

While the problem discussed in thread AppleScript: Get record name without suffix was solved by adding the name without extension property (Thanks @cgrunenberg!) it seems the underlying problem wasn’t fixed.

The following captures were taken in a database that was definitely created with DEVONthink 3, so this quote …

… can’t explain the results, I think.

Search using “name ends with” without extension:

Search using “name ends with” without extension and with extension:

I think records that include the extension were created via Tools > Capture > Paginated PDF.


No idea whether that’s a useful info but disabling preference Show filename extensions doesn’t show extensions for all records, i.e. also not for the records that have the extension included:

Did you add all these items the same way to the database?

That’s it! All records that include the extension were created by using create PDF document from with bookmarks. I can say that for sure as the creation dates are immediately after a commit.

The rest was created via Tools > Capture > Paginated PDF (as the dates are after the time at which Apple changed the site again which made it possible again to view bookmarks inside DEVONthink).

So it’s obviously something with the AppleScript command :slight_smile:

1 Like

The code of the complete script would be useful.


property theDocumentationGroup_UUUID : "59CE3D5F-5E3C-405B-A39E-CBF2DD8F7013"

tell application id "DNtp"
	try
		set theRecords to selected records
		if theRecords = {} then error "Please select a bookmark"
		
		set theDocumentationGroup to (get record with uuid theDocumentationGroup_UUUID)
		set theDocumentationGroup_Name to name of theDocumentationGroup
		if theDocumentationGroup_Name contains "/" then set theDocumentationGroup_Name to my escapeSlash(theDocumentationGroup_Name)
		set theDocumentationGroup_Location to location of theDocumentationGroup
		
		repeat with thisRecord in theRecords
			set thisRecord to item 1 of theRecords
			set thisURL to URL of thisRecord
			set thisGroup to my getGroup(thisURL, theDocumentationGroup, theDocumentationGroup_Name, theDocumentationGroup_Location)
			set thisName to script "Get record name"'s recordName(name of thisRecord, filename of thisRecord)
			if thisName does not end with " | Apple Developer Documentation" then set name of thisRecord to thisName & " | Apple Developer Documentation"
			set thePDF to create PDF document from thisURL in thisGroup name thisName with pagination
			set comment of thePDF to comment of thisRecord
			set label of thePDF to label of thisRecord
			set tags of thePDF to tags of thisRecord
			set label of thisRecord to 2
			move record thisRecord to thisGroup
		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 getGroup(theURL, theDocumentationGroup, theDocumentationGroup_Name, theDocumentationGroup_Location)
	tell application id "DNtp"
		try
			set {theDocuPath_Location, theDocuPath_Name, theDocuPath} to my getBreadcrumbsPath(theURL)
			set theGroups to parents of theDocumentationGroup whose location = theDocuPath_Location and name = theDocuPath_Name
			if theGroups ≠ {} then
				set theGroup to item 1 of theGroups
			else
				set theGroup to create location theDocumentationGroup_Location & theDocumentationGroup_Name & "/" & theDocuPath in (database of theDocumentationGroup)
			end if
		on error error_message number error_number
			activate
			display alert "Error: Handler \"getGroup\"" message error_message as warning
			error number -128
		end try
	end tell
end getGroup

on getBreadcrumbsPath(theURL)
	try
		set theDocuPath to script "regexReplace"'s regexReplace(theURL, "https://developer.apple.com/|(/\\d+|\\?).*", "")
		set theDocuPath_Items to script "tid"'s tid(theDocuPath, "/")
		set theDocuPath_Location to "/" & (script "tid"'s tid(items 2 thru -2 in theDocuPath_Items, "/")) & "/"
		set theDocuPath_Name to item -1 in theDocuPath_Items
		return {theDocuPath_Location, theDocuPath_Name, theDocuPath_Location & theDocuPath_Name}
	on error error_message number error_number
		activate
		display alert "Error: Handler \"getBreadcumbsPath\"" message error_message as warning
		error number -128
	end try
end getBreadcrumbsPath

on escapeSlash(theText)
	set d to AppleScript's text item delimiters
	set AppleScript's text item delimiters to "/"
	set theTextItems to every text item of theText
	set AppleScript's text item delimiters to "\\/"
	set theText_escaped to theTextItems as string
	set AppleScript's text item delimiters to d
	return theText_escaped
end escapeSlash

The name (according to the name AppleScript property) & URL of an item selected before running this script would be useful too - thank you!

hasMemberInPlane:

https://developer.apple.com/documentation/foundation/nscharacterset/1412406-hasmemberinplane?language=objc

I created a bookmark using the above name & URL and executed this simplified script but everything seems to be as expected:

tell application id "DNtp"
	try
		repeat with thisRecord in selected records
			set thisURL to URL of thisRecord
			set thisName to name of thisRecord
			set thePDF to create PDF document from thisURL name thisName in current group with pagination
		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
	end try
end tell

I wonder what this line returns for you?

set thisName to script "Get record name"'s recordName(name of thisRecord, filename of thisRecord)

It gets the name without extension (the script was written before name without extension became availabe).

Are you able to reproduce my expected results (using the simplified script and a bookmark) or does it fail again?

Can’t reproduce it.

To figure out what might be the problem I created smart groups for the different scripts that I used. The result shows pretty clear that almost all names that include the extension were created with one of the Smart Rule scripts that used handler recordName. Immidately after replacing this handler with name without extension the resulting PDF’s name does not include the extension anymore.

The handler is ok, I’ve used it for a year without any problems.

Handler
-- Get name without extension

#set theName to "Hello World"
set theName to "Hello World.pdf"
set theFilename to "Hello World.pdf"

set theName_withoutExtension to my recordName(theName, theFilename)

on recordName(theName, theFilename)
	set theSuffix to my getSuffix(theFilename)
	try
		if theName ends with theSuffix and theName ≠ theSuffix then set theName to characters 1 thru -((length of theSuffix) + 2) in theName as string
	end try
	return theName
end recordName

on getSuffix(thePath)
	set revPath to reverse of characters in thePath as string
	try
		set theSuffix to reverse of characters 1 thru ((offset of "." in revPath) - 1) in revPath as string
	on error
		set theSuffix to ""
	end try
	return theSuffix
end getSuffix

But I’ve never used it in a Smart Rule script before. So I guess there’s something going on in the way name and/or filename are returned in a Smart Rule script.

Is it intended that moving a record (that returns name without extension) to a new database changes the returned value to the name including the extension? I guess that’s done because there’s now also name without extension, right? If so then I could temporarily move everything to update existing records.

Smart rules don’t change the results of scripts at all, the results should be always the same no matter how the script is executed.

I also tried your example handler both in a smart rule and in the Script Editor.app. Hello World is returned in both cases.

On the topic of extensions in names…

What is the preferred method of displaying the file name + extension in the same field? I’m finding my screen space in short supply, so I want to consolidate the two columns Name and Kind into one string, ie. filename.md rather than Name:filename, Kind: Markdown Text. I tried searching the help manual and this forum but couldn’t find an answer.

See preferences General > Appearance > Show filename extensions.

1 Like

Yes, that’s what I see here too. The problem really is that although this should work it obviously didn’t work (at some time). And this didn’t happen for the first time (see linked thread in first post - which was by the way created after already experiencing this for quite a long time. Just never reported it as I always thought I was doing something wrong.)

Meanwhile I’m pretty sure that it’s sometimes simply inconsistent. Unfortunately there’s no information what the expected outcome of name should be, neither after name without extension was introduced nor before.

Additional information about the expected behaviour would be very welcome. Especially as it seems to have changed (probably due to name without extension), see mentioned thread.

Not directly related but maybe with high potential for further investigation among different users:

Another user had the great idea of building a history record of opened records. Reading this I tried and wrote a script that tracks all opened records of each day, After writing it this smart rule script ran, I simply forgot about it. But when I stumbled across this script’s output something immediately draw my attention: It was obvious that not all Markdown link names included the records’ extension.

Personally, I don’t really understand why a filename would ever exclude the extension. That might come from my Unix background where the name is what it is and an extension has no meaning at all.

So if there’s a method name and one name without extension, I’d expect the first one to always return the complete name.

1 Like

Your post reminds me of this problem I experienced, and posted about. As you know, I’m no expert :grinning: but I do wonder if it’s in some way related to the issue being discussed here.

Stephen

1 Like