AppleScript to open current page in PDF Expert

Context: I have a lot of PDFs in DT3 that are subject to the strange PDFKit bug in MacOS that destroys the OCR layer of certain PDFs when highlighted directly in DT3. In order to avoid this bug, I only highlight PDFs outside of DT3.

I am trying to write an AppleScript that I can trigger by hotkey from Keyboard Maestro to open the current page of the selected PDF in PDF Expert. I have tried to work from this AppleScript from @pete31 but I do not seem to be able to get it to retrieve the page number of the current PDF in DT3. Here is my script:

tell application id "DNtp"
	try
		if not (exists think window 1) then
			error "Please open a window"
		else
			set theWindow to think window 1
		end if
		
		set theRecord to content record of theWindow
		
		if theRecord ≠ missing value then
			set thePage to current page of theRecord
			set thePDFPage to thePage + 1
		else
			error "Please select a record"
		end if
	end try
end tell

My intent is to call the variables from within KBM:

DT3 page: %Variable%thePage%
PDF page: %Variable%thePDFPage%

When I run the script from KBM, the variables are not getting set by the script. This is probably due to an error that should be obvious, but I am not seeing it. Advice?

current page is a property of windows and tabs, not of records.

Thanks. This works:

tell application id "DNtp"
	return current page of think window 1
end tell

Is the most complete AppleScript guide for DT3 in the Help browser? I’m looking for documentation on how to access all the fields, the data structures (e.g., how to discover what properties are intrinsic to windows and tabs as opposed to records), etc.

You can view the description of the complete AppleScript support by dropping DEVONthink 3 (or any scriptable app) onto the Dock/Finder icon of the Script Editor.app.

1 Like

Perfect! I had no idea…

This should do it. Note that there’s no error checking done in the macro.

-- DEVONthink - Get current PDF page and save it to Keyboard Maestro variable

tell application id "DNtp"
	try
		if not (exists think window 1) then
			error "Please open a window"
		else
			set theWindow to think window 1
		end if
		
		set theRecord to content record of theWindow
		
		if theRecord ≠ missing value then
			set theType to type of theRecord as string
			if theType ≠ "PDF document" then error "Please open a PDF record"
			set thePath to path of theRecord
			do shell script "open -a " & quoted form of (POSIX path of (path to application "PDF Expert")) & space & quoted form of thePath
			set thePage to (current page of think window 1) + 1
		else
			error "Please open a PDF record"
		end if
		
	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

tell application id "com.stairways.keyboardmaestro.engine"
	setvariable "theCurrentPDF_Page" to thePage
end tell

1 Like

It’s also possible to go the other way around, i.e. open the current PDF Expert tab’s PDF in DEVONthink Script: Open DEVONthink record for PDF Expert tab.

Brilliant! I had to add a couple delays in the script for PDF Expert to fully load (otherwise it kept adding the page number as text to the page), but otherwise it works as-is. Much appreciated, @pete31

1 Like

What is the rationale behind that? I noticed that also the columns/rows of a sheet are not properties of the record but of the window. I find that a bit weird, but probably only because I don’t understand the “why” in these cases.

It’s a property of the current state of the user interface, not of the database and its records. There could be even multiple windows/tabs showing the same record.

Yes, I didn’t think properly. But the rows and columns of a sheet are properties of the record (or should be) and are only accessible through the window?

Records have actually cells and columns attributes which can be used to easily get/change/set them.

Sorry, I was not specific enough. There are methods “number of rows” and “number of columns” that work only with the window, as far as I can tell. I think they should actually be attached to the sheet itself. Granted, there are cells and columns (the latter providing the names of the columns). So I have to look at the length of cells and the length of columns and divide the former by the latter to get the number of rows…

The cell consists of an array/list containing the rows and each row is another array/list containing the values. Therefore the number of rows is just count of cells.

Thanks for the explanation! Maybe you could add that to the script documentation in the future?

Sure, no problem.