Last active
April 30, 2023 20:29
-
-
Save mnot/0d7825bde9b9d3233f623c71765f20ca to your computer and use it in GitHub Desktop.
Look up PDFs on crossref.org in DevonThink
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- Look up document metadata on CrossRef.org in DevonThink 3 | |
-- | |
-- Currently sets: | |
-- * Created date to the document's publication date | |
-- * Title in document properties | |
-- * Author in document properties (first author only) | |
-- * Crossref DOI URL in document properties | |
-- * A tag for the type of document | |
-- * Finder comments to a formatted citation (see below) | |
-- | |
-- | |
-- To install: | |
-- 0. Quit DevonThink | |
-- 1. Place this script in the DevonThink Scripts folder (`Scripts -> Open Scripts Folder`) | |
-- 2. In Terminal, navigate to that folder and run `osacompile -o Crossref\ Lookup.scpt crossref-lookup.applescript; rm crossref-lookup.applescript` | |
-- 3. Install JSON Helper: https://apps.apple.com/au/app/json-helper-for-applescript/id453114608?mt=12 | |
-- 4. Install exiftool: `brew install exiftool` (using homebrew; see https://brew.sh) | |
-- 5. Give the script a keyboard shortcut (`System Preferences -> Keyboard -> Shortcuts -> App Shortcuts`) (optional) | |
-- | |
-- To use: | |
-- 0. Open a PDF in DevonThink | |
-- 1. Using your cursor, select a paper's title, ISSN, or similar identifying information | |
-- 2. Trigger the script (e.g., using they keyboard shortcut | |
-- 3. Select the best fitting candidate from the list | |
-- 4. Click `OK` | |
-- | |
-- To set your citation format: | |
-- 0. Look up your desired format here: <https://github.com/citation-style-language/styles> | |
-- 1. Set CitationName below to the name of the apppopriate file *without* the `.csl` extension | |
set CitationName to "australian-guide-to-legal-citation" | |
set UAString to "XRefLookup/1.0 (https://gist.github.com/mnot/0d7825bde9b9d3233f623c71765f20ca; mailto:[email protected])" | |
tell application id "DNtp" | |
try | |
if not (exists think window 1) then error "No window open." | |
if not (exists content record) then error "No document selected." | |
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 | |
set theRecord to content record | |
set query to the selected text of think window 1 as string | |
if query is "" then | |
set query to name of theRecord | |
end if | |
show progress indicator "Looking up references..." steps -1 | |
set theJson to my crossrefLookup(query) | |
hide progress indicator | |
-- Populate and display a dialogue | |
try | |
set theItems to |items| of message of theJson | |
set theChoices to {} | |
repeat with a from 1 to length of theItems | |
set currentItem to item a of theItems | |
set titleList to title of currentItem | |
set title to item 1 of titleList | |
set dateString to my extractDate(currentItem) | |
set detailString to my extractAuthor(currentItem) | |
if not detailString is equal to "" then | |
set detailString to detailString & ", " | |
end if | |
set detailString to detailString & dateString | |
set theChoice to title & " (" & detailString & ")" | |
set end of theChoices to theChoice | |
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 | |
set theChoice to choose from list theChoices with prompt "Select:" | |
if theChoice is false then return | |
repeat with a from 1 to length of theChoices | |
set currentItem to item a of theChoices | |
if currentItem as string is equal to theChoice as string then | |
set chosenItem to item a of theItems | |
end if | |
end repeat | |
-- update document | |
set dateString to my extractDate(chosenItem) | |
set dateStruct to my appleDate(dateString) | |
try | |
set recordPath to path of theRecord | |
-- date | |
set the date of theRecord to dateStruct | |
-- tags | |
set typeTag to |type| of chosenItem | |
if typeTag is not in tags of theRecord then | |
set tagList to tags of theRecord | |
set end of tagList to typeTag | |
set tags of theRecord to tagList | |
end if | |
-- url | |
set uri to |URL| of chosenItem | |
set the URL of theRecord to uri | |
-- comment | |
set citation to my lookupCitation(uri) | |
set the comment of theRecord to citation | |
-- title | |
set recordTitle to item 1 of title of chosenItem | |
my setPDFMetadata("Title", recordTitle, recordPath) | |
-- author | |
set authorString to my extractAuthor(chosenItem) | |
my setPDFMetadata("Author", authorString, recordPath) | |
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 | |
on crossrefLookup(query) | |
set apiURL to "https://api.crossref.org/works" | |
set shellScript to ("curl -A \"" & my UAString & "\" -G " & apiURL ¬ | |
& " --data-urlencode query.bibliographic=" & quoted form of query ¬ | |
& " -d rows=5 -d select=author,title,type,publisher,issued,subject,URL") | |
set apiResult to (do shell script shellScript) | |
-- parse json | |
tell application "JSON Helper" | |
set jsonResponse to read JSON from apiResult | |
end tell | |
if not status of jsonResponse is equal to "OK" then | |
error "API response not OK: " & message of jsonResponse | |
return | |
end if | |
return jsonResponse | |
end crossrefLookup | |
on extractDate(record_item) | |
try | |
set [iyear, imonth, iday] to item 1 of |date-parts| of issued of record_item | |
set dateString to ((iday as string) & "-" & imonth as string) & "-" & iyear as string | |
on error | |
try | |
set [iyear, imonth] to item 1 of |date-parts| of issued of record_item | |
set dateString to "01-" & (imonth as string) & "-" & iyear as string | |
on error | |
try | |
set iyear to item 1 of |date-parts| of issued of record_item | |
set dateString to "01-01-" & iyear as string | |
on error | |
set dateString to "" | |
end try | |
end try | |
end try | |
return dateString | |
end extractDate | |
on appleDate(date_string) | |
return date (date_string) | |
end appleDate | |
on extractAuthor(record_item) | |
set firstAuthor to "" | |
try | |
set author_entries to author of record_item | |
on error | |
return "" | |
end try | |
repeat with a from 1 to length of author_entries | |
set this_entry to item a of author_entries | |
if sequence of this_entry is equal to "first" then | |
set firstAuthor to this_entry | |
end if | |
end repeat | |
if firstAuthor is equal to "" then | |
return "" | |
end if | |
try | |
set authorString to |given| of firstAuthor & " " & family of firstAuthor | |
on error | |
try | |
set authorString to family of firstAuthor | |
on error | |
set authorString to |name| of firstAuthor | |
end try | |
end try | |
return authorString | |
end extractAuthor | |
on setPDFMetadata(mdKey, mdValue, recordPath) | |
set shellCommand to "/opt/homebrew/bin/exiftool -overwrite_original -" & mdKey & "=" & quoted form of mdValue & " " & quoted form of recordPath | |
set exifresult to do shell script shellCommand | |
end setPDFMetadata | |
on lookupCitation(uri) | |
set shellScript to ("curl -A \"" & my UAString & "\" " & ¬ | |
"-LH \"Accept: text/bibliography; style=" & my CitationName & "\" " & uri) | |
set apiResult to (do shell script shellScript) | |
return apiResult | |
end lookupCitation |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment