Copy link to a part (e.g. page) of a PDF document?

I’ve put together a script that makes this workflow so much quicker. I prefer to read and annotate my PDFs in Skim.

It’s based on a modified version of a script that @ChristinWhite shared over in the topic Video Playback and Annotations.
Basically all I did was take their script, and then use find/replace to substitute words like “video” and “time” with “PDF” and “page”, then spent a couple minutes fixing errors. It’s not perfect, but its very close! Sometimes the page numbers are off by one.

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

# # Copy Markdown Link for DEVONthink PDF Open in Skim on Current Page
#
# This script will copy that URL as a markdown link in the format: [352](x-devonthink-item://45151EC1-8A15-4109-AFE9-1B4EA8C6DE2B?page=352)
#
# Created by [Christin White](http://christindwhite.com)
# and then heavily modified to work with Skim instead of VLC
#

# # Set Options
# 
# - `DatabaseName`     *text*: The name for the database to use, if a valid database is not found the front database will be used.
# - `parameter` *boolean*: this is leftover from the VLC version, but it breaks when deleted.
#
set DatabaseName to "Research"
set parameter to true

try
	# Get Reference URL from DEVONthink and Assemble Link
	set thePDF to GetPDFFromSkim(parameter)
	
	# Get Reference URL
	set TheReferenceURL to GetReferenceURLFromPath(thePDFPath of thePDF, DatabaseName)
	
	# Assemble Link
	set PageCodeURL to TheReferenceURL & "?page=" & (TheCurrentPage of thePDF)
	set PageCode to (TheCurrentPage of thePDF)
	set MarkdownLink to "[" & PageCode & "](" & PageCodeURL & ")"
	
	# Copy to Clipboard
	set the clipboard to MarkdownLink
on error ErrorMessage number ErrorNumber
	if the ErrorNumber is not -128 then display alert "DEVONthink" message ErrorMessage as warning
end try


# # GetReferenceURLFromPath
#
# Get the reference URL for a file in a specified or active database.
#
# Parameters:
# - `TheFilepath`  *text*: The path to the file.
# - `DatabaseName` *text*: That database to look in.
#
# Returns:
# - *text*: The Reference URL.
#
on GetReferenceURLFromPath(TheFilePath, DatabaseName)
	tell application id "DNtp"
		# Check if the database is valid, if not use the active database.
		if exists database DatabaseName then
			set TheRecordList to lookup records with path TheFilePath in database DatabaseName
		else
			display notification "The specified database wasn't found, trying the active database instead" subtitle "Invalid Database"
			set TheRecordList to lookup records with path TheFilePath
		end if
		
		# Make sure we found a matching record.
		if (count of TheRecordList) is greater than 0 then
			# A list could return more than one record such as if a file is indexed to more than one group. Use the first item but notify the user.
			if (count of TheRecordList) is greater than 1 then
				display notification "More than one record was found, using the first record" subtitle "Multiple Records"
			end if
			set TheReferenceURL to reference URL of item 1 of TheRecordList
			return TheReferenceURL
		else
			error "File not found in database."
		end if
	end tell
end GetReferenceURLFromPath


# # GetPDFFromSkim
#
# Gets metadata about the front PDF open in Skim
#
# Parameters:
# - `parameter` *boolean*: leftover from VLC.
#
# Returns:
# - *list* (indexed)
#   - `thePDFPath`     *text*: The path for front PDF.
#   - `TheCurrentPage` *number*: The current page of playback.
on GetPDFFromSkim(parameter)
	tell application "Skim"
		if (exists path of front document) then
			set thePDFPath to path of front document
			set TheCurrentPage to index of current page of the front document
		else
			error "Skim does not have a PDF open."
		end if
		
		return {thePDFPath:thePDFPath, TheCurrentPage:TheCurrentPage}
	end tell
end GetPDFFromSkim
1 Like