zeitlings Posted February 7, 2023 Posted February 7, 2023 (edited) Get either the DEVONthink 3 reference URL from PDF Expert, i.e. the x-devonthink-item page link for the active document opened in PDF Expert, the selection link if you have text selected, or the annotation link if your selection intersects an annotation and checking for annotations is enabled. cmd ⌘ to open the PDF on the same page in DEVONthink .xdev to enable or disable opening the document in DEVONthink when using the hotkey Expected result A x-devonthink-item://1D7FA99A-AAFF-4883-9853-F0666A650400?page=6Expected result B x-devonthink-item://1D7FA99A-AAFF-4883-9853-F0666A650400?page=6&start=66&length=9&search=selectionExpected result C x-devonthink-item://1D7FA99A-AAFF-4883-9853-F0666A650400?page=6&annotation=Squiggly&x=212&y=406 Known issues Fails with documents opened in PDF Expert split view Download and Preview: https://github.com/zeitlings/alfred-workflows#14-devonthink--pdf-expert Edited February 22, 2023 by zeitlings support for deep linking
zeitlings Posted February 22, 2023 Author Posted February 22, 2023 (edited) Now supports deep linking, which is new to DEVONthink 3.9, i.e. selection links and annotation links. To get the full annotation link, your text selection just needs to overlap it. I anticipate poor performance for very large PDFs and in cases where the selected text occurs quite often in the document. For these cases, the annotation check can be disabled in the configuration. Here is the AppleScript, if anyone is interested in it: (* Part of the DEVONthink ↔ PDF Expert workflow for Alfred v2.1.1 https://github.com/zeitlings/alfred-workflows#14-devonthink--pdf-expert Get the DEVONthink page link, selection link, or annotation link for the page viewed in PDF Expert ==================================================================== Credits - pete31: https://discourse.devontechnologies.com/t/script-open-devonthink-record-for-pdf-expert-tab/47243 - Umlaut fix: https://stackoverflow.com/a/23226449/7625403 *) use AppleScript version "2.4" use framework "PDFKit" use scripting additions property NSURL : a reference to current application's NSURL property NSString : a reference to current application's NSString property PDFDocument : a reference to current application's PDFDocument on run argv set checkForAnnotations to (item 1 of argv as integer) as boolean tell application "System Events" set bufferedClipboard to the clipboard activate application "PDF Expert" delay 0.5 tell process "PDF Expert" to keystroke "c" using {command down} delay 0.2 set perhapsSelection to the clipboard as text tell process "PDF Expert" to keystroke "g" using {command down, option down} -- go to tell application "System Events" to keystroke "c" using command down delay 0.5 tell application "System Events" to key code 53 -- esc set theActiveLabel to the clipboard try tell application process "PDF Expert" tell window 1 set theFileName to value of attribute "AXTitle" & ".pdf" if theFileName starts with "* " then set theFileName to characters 3 thru -1 in theFileName as string end tell set PID to unix id end tell on error error_message number error_number return "Error with code " & (error_number as text) & " " & (error_message as text) end try end tell set thePath to my recoveredPath(theFileName, PID) set theURL to NSURL's fileURLWithPath:(NSString's stringWithString:thePath) set pdf to PDFDocument's alloc()'s initWithURL:theURL set theCount to pdf's pageCount() set thePageIndex to -1 set cur to 0 repeat while cur < theCount set thePage to pdf's pageAtIndex:cur set theLabel to thePage's label() if theLabel ≠ missing value then if (theLabel as text) is theActiveLabel then set thePageIndex to cur exit repeat end if end if set cur to cur + 1 end repeat if thePageIndex is equal to -1 then set the cliboard to bufferedClipboard return "Unable to recover Page Index" end if set pageLink to my referenceURL(thePath, thePageIndex) try set thePage to pdf's pageAtIndex:thePageIndex -- ------------------------------------- -- -- Check for annotation intersection -- -- ------------------------------------- -- if checkForAnnotations then set theSelections to pdf's findString:perhapsSelection withOptions:3 repeat with thisSelection in theSelections if (thisSelection's pages() as list) contains thePage then set theBounds to (thisSelection's boundsForPage:thePage) set theOrigin to item 1 of theBounds set theSize to item 2 of theBounds set coorX to item 1 of theOrigin set coorY to item 2 of theOrigin set width to item 1 of theSize set height to item 2 of theSize repeat with thisAnnotation in thePage's annotations() set annotationBounds to thisAnnotation's |bounds|() set annotationOrigin to item 1 of annotationBounds set annotationSize to item 2 of annotationBounds set annoX to item 1 of annotationOrigin set annoY to item 2 of annotationOrigin set annoWidth to item 1 of annotationSize set annoHeight to item 2 of annotationSize set a to (coorX < (annoX + annoWidth)) set b to ((coorX + width) > annoX) set c to (coorY < (annoY + annoHeight)) set d to ((coorY + height) > annoY) set isIntersecting to a and b and c and d if isIntersecting then set theType to thisAnnotation's type() as text -- possibly nil if theType is missing value then set theType to "Highlight" end if set x to (round annoX rounding as taught in school) as text -- .... set y to (round annoY rounding as taught in school) as text set deepAnnotationLink to (pageLink as text) & "&annotation=" & theType & "&x=" & x & "&y=" & y set the clipboard to deepAnnotationLink return deepAnnotationLink end if end repeat end if end repeat end if -- ------------------------------ -- -- Reconstruct page selection -- -- ------------------------------ -- set theText to thePage's |string|() set theRange to theText's rangeOfString:perhapsSelection if theRange's |length|() ≠ 0 then set theStart to theRange's location() as text set theLength to theRange's |length|() as text set theSelection to NSString's stringWithString:perhapsSelection set theSearchString to theSelection's stringByAddingPercentEncodingWithAllowedCharacters:(current application's NSCharacterSet's URLQueryAllowedCharacterSet()) set deepSelectionLink to pageLink & "&start=" & theStart & "&length=" & theLength & "&search=" & theSearchString set the clipboard to deepSelectionLink return deepSelectionLink end if set the clipboard to pageLink return pageLink on error number -2753 -- not defined set the cliboard to bufferedClipboard return "Document not found in any open Database" end try end run on recoveredPath(theFileName, PID) set theOpenFiles to (do shell script "lsof -p " & PID) set convertedOutput to (do shell script "iconv -t UTF8-MAC <<<$" & quoted form of theOpenFiles) set theLines to paragraphs of convertedOutput repeat with thisLine in theLines if thisLine contains theFileName then set thePath to characters (offset of "/" in thisLine) thru -1 in thisLine as string return thePath end if end repeat end recoveredPath on referenceURL(thePath, thePageIndex) tell application id "DNtp" try set theDatabases to databases set theResults to {} repeat with thisDatabase in theDatabases set dbResults to lookup records with path thePath in thisDatabase set theResults to theResults & dbResults end repeat if theResults = {} then return else set theUUID to uuid of (item 1 of theResults) set referenceURL to "x-devonthink-item://" & theUUID & "?page=" & (thePageIndex as text) return referenceURL end if on error error_message number error_number return "Error with code " & (error_number as text) & " " & (error_message as text) end try end tell end referenceURL Edited February 22, 2023 by zeitlings
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now