Last active
January 9, 2017 01:36
-
-
Save fractaledmind/6489258 to your computer and use it in GitHub Desktop.
REQUIRED PROGRAMS:
- Skim (pdf viewer and annotator)
- Evernote (cloud based note app) This script will (as the title suggests) export all of you Skim notes directly to Evernote with hyperlinks. It integrates the GENERATE TOP 3 NOTES WITH SYSTEM URL script that will put 3 notes at the top of the PDF with linking information. This means your PDF …
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
(* EXPORT ALL SKIM NOTES TO EVERNOTE WITH HYPERLINKS | |
-- Stephen Margheim | |
-- 9/7/13 | |
-- open source | |
REQUIRED PROGRAMS: | |
- Skim (pdf viewer and annotator) | |
- Evernote (cloud based note app) | |
This script will (as the title suggests) export all of you Skim notes directly to Evernote with hyperlinks. It integrates the GENERATE TOP 3 NOTES WITH SYSTEM URL script that will put 3 notes at the top of the PDF with linking information. This means your PDF workflow is now contained in a single script. | |
When launched, the script will ask you a series of questions: | |
* if the current PDF is saved where you want it to finally reside, | |
* what the relation of the Printed page number is relative to Skim's indexed page number, | |
* if the PDF is a Primary Source or a Secondary Source. | |
Your choices will determine (1) the file path used in the custom URL, (2) the key to generating the hyperlinked printed page numbers, (3) the text values for the 6 different highlight colors. | |
Possible alterations include (1) exporting to a web-based site (instead of Evernote), (2) changing the text translation for the various highlight colors (down in the color2text Handler) | |
*) | |
(* PROPERTIES *) | |
property LF : (ASCII character 10) | |
property LF1 : (ASCII character 32) & (ASCII character 32) & (ASCII character 10) | |
property tid : AppleScript's text item delimiters | |
property theHome : path to home folder as string | |
(* THE SCRIPT *) | |
tell application "Skim" | |
(* /// | |
PART 1: | |
Dialog Boxes | |
/// *) | |
--get partial file path of PDF | |
set theFile to file of document 1 as string | |
set theFilePath to my replaceString(theFile, theHome, "") | |
set theFilePath_view to my replaceString(theFilePath, ":", "/") | |
--save PDF file in proper place | |
set checkFilePath to display dialog "Is the PDF saved in its final resting place?" & LF & LF & theFilePath_view with title "PDF Annotation Export" buttons {"Yes", "No"} default button {"Yes"} | |
if button returned of checkFilePath is "No" then | |
set myFile to choose file name with prompt "Save file as:" default location (alias ((theHome) & "Desktop:")) | |
end if | |
--get relation of printed page number to Skim's indexed page number | |
set pageRelation to text returned of (display dialog ¬ | |
"Subtract printed page number from Skim's indexed page number" with title "Relation of Printed page # to indexed page #" default answer "") as number | |
--determine type of PDF | |
set theTextStatus to display dialog "Is the PDF a Primary or Secondary text?" buttons {"Primary", "Secondary"} default button {"Secondary"} | |
(* /// | |
PART 2: | |
Generate Top 3 Notes with relevant Meta-Data | |
/// *) | |
--URL encode partial file path | |
set pdfPath to my encode_text(theFilePath, true, false) | |
set pdfPath to my replaceString(pdfPath, ":", "/") | |
--create Custom URL with partial file path | |
set customurl to "customurl://com.hackademic.AppleScript.URL_Handler?action=1$" & pdfPath & "#" | |
--create the three opening notes | |
set PdfName to name of document 1 of application "Skim" | |
tell page 1 of document 1 | |
make note with properties {type:anchored note, bounds:{579, 842, 595, 826}, text:customurl, extended text:PdfName} | |
delay 0.1 | |
make note with properties {type:anchored note, bounds:{579, 826, 595, 810}, text:"[" & PdfName & "](" & customurl} | |
delay 0.1 | |
make note with properties {type:anchored note, bounds:{579, 810, 595, 794}, text:pageRelation, extended text:"pr# - sk#"} | |
end tell | |
--save PDF with new notes | |
save front document | |
delay 1 | |
(* /// | |
PART 3: | |
Get all Annotation Information | |
/// *) | |
--get info for all notes | |
set allNotes to every note of document 1 | |
set allNotes_types to every type of notes of document 1 | |
set allNotes_text to text of every note of document 1 | |
set allNotes_pages to index of every page of every note of document 1 | |
--get info for all notes except top 3 | |
set selNotes to items 1 through -4 of allNotes | |
set selNotes_types to items 1 through -4 of allNotes_types | |
set selNotes_text to items 1 through -4 of allNotes_text | |
set selNotes_pages to items 1 through -4 of allNotes_pages | |
--get info from those top 3 notes | |
set pdfTitle to (get extended text of note -3 of page 1 of document 1) as string | |
set PDFLink to (get text of note -3 of page 1 of document 1) as string | |
set Markdownlink to (get text of note -2 of page 1 of document 1) as string | |
set number_of_Note3 to (get text of note -1 of page 1 of document 1) as string | |
--prepare Headers for all of the various note types | |
set notesText_text to "<hr />" & LF & LF & "<h2>The ToC</h2>" & LF1 & LF & LF | |
set notesText_anchor to "<hr />" & LF & LF & "<h2>All of my Text Notes</h2>" & LF1 & LF & LF | |
set notesText_highlight to "<hr />" & LF & LF & "<h2>All of the Highlighted Text </h2>" & LF1 & LF & LF | |
set notesText_underline to "<hr />" & LF & LF & "<h2>All of the Underlined Text</h2>" & LF1 & LF & LF | |
set notesText_strikethru to "<hr />" & LF & LF & "<h2>All of the Strike-Through Text</h2>" & LF1 & LF & LF | |
(* /// | |
PART 4: | |
The Meat-n-Potatoes of the Script | |
/// *) | |
repeat with i from 1 to count of selNotes_types | |
--prepare Skim page # and actual page # | |
set notePage to item i of selNotes_pages | |
set theRealPage to notePage + number_of_Note3 as string | |
--collect Text Notes | |
if item i of selNotes_types is text note then | |
set noteText to item i of selNotes_text | |
set notesText_text to notesText_text & "<p>" & noteText & " (<a href=\"" & PDFLink & notePage & "\">" & "p." & theRealPage & "</a>)" & LF & LF | |
--collect Anchor Notes | |
else if item i of selNotes_types is anchored note then | |
set titleText to item i of selNotes_text | |
set noteText to extended text of item i of selNotes | |
--precaution for running script multiple times | |
repeat 1 times | |
if titleText contains "customurl://" or noteText contains "pr# - sk#" then exit repeat | |
set notesText_anchor to notesText_anchor & "<p><strong>" & titleText & ":</strong> " & noteText & " (<a href=\"" & PDFLink & notePage & "\">p." & theRealPage & "</a>)" & LF & LF | |
end repeat | |
--collect Underline Notes | |
else if item i of selNotes_types is underline note then | |
set noteText to item i of selNotes_text | |
set notesText_underline to notesText_underline & "<p>\"" & noteText & "\"" & " (<a href=\"" & PDFLink & notePage & "\">" & "p." & theRealPage & "</a>)" & LF & LF | |
--collect Strike-Thru Notes | |
else if item i of selNotes_types is strike out note then | |
set noteText to item i of selNotes_text | |
set notesText_strikethru to notesText_strikethru & "<p>\"" & noteText & "\"" & " (<a href=\"" & PDFLink & notePage & "\">" & "p." & theRealPage & "</a>)" & LF & LF | |
--collect Highlight Notes | |
else if item i of selNotes_types is highlight note then | |
set theColor to color of item i of selNotes | |
set titleText to my color2text(theColor, theTextStatus) | |
set noteText to item i of selNotes_text | |
set notesText_highlight to notesText_highlight & "<p><strong>" & titleText & ":</strong> " & LF1 & "\"" & noteText & "\"" & " (<a href=\"" & PDFLink & notePage & "\">p." & theRealPage & "</a>)" & LF & LF | |
end if | |
end repeat | |
(* /// | |
PART 5: | |
Extract Summary Annotations | |
/// *) | |
--extract "Summary" notes from the collection of all highlight notes | |
set theSummary to {} | |
set theParas to paragraphs of notesText_highlight | |
repeat with i from 1 to count of theParas | |
if item i of theParas contains "<p><strong>Summary:" then | |
set theTitle to item i of theParas | |
set theText to item (i + 1) of theParas | |
set theSumm to theTitle & LF & theText & LF & LF | |
copy theSumm to the end of theSummary | |
end if | |
end repeat | |
--remove "Summary" highlight notes from collection of highlight notes | |
if (not (theSummary is {})) then | |
set SumText to theSummary as string | |
set SumList to paragraphs of SumText | |
set empty to {""} | |
set FinalSum to my cleanmyList(SumList, empty) | |
set HighList to paragraphs of notesText_highlight | |
set finalHighlights to my cleanmyList(HighList, FinalSum) | |
set AppleScript's text item delimiters to LF | |
set notesText_highlight to (finalHighlights as string) | |
set theSummary to "<hr />" & LF & LF & "<h2>Text Summary</h2>" & LF1 & LF & LF & SumText | |
end if | |
--ALWAYS RETURN TEXT ITEM DELIMITERS TO NORMAL | |
set AppleScript's text item delimiters to tid | |
(* /// | |
PART 6: | |
Remove any Empty Annotation Sections | |
/// *) | |
--remove any note sections that are empty | |
set FinalList to my textCheck(notesText_text, notesText_anchor, notesText_highlight, notesText_underline, notesText_strikethru, theSummary) | |
--prepare the final collection of notes, with MetaData | |
set FinalText to FinalList | |
(* /// | |
PART 7: | |
Create the Evernote Note | |
/// *) | |
tell application "Evernote" | |
--create new "notes" tag if necessary | |
if (not (tag named "notes" exists)) then | |
set theTag to make tag with properties {name:"notes"} | |
else | |
set theTag to tag "notes" | |
end if | |
--create new "PDF Notes" notebook if necessary | |
if (not (notebook named "PDF Notes" exists)) then | |
make notebook with properties {name:"PDF Notes"} | |
end if | |
--create the HTML note | |
set theTitle to "Notes: " & pdfTitle | |
set newNote to create note title theTitle with html FinalText notebook "PDF Notes" | |
assign theTag to newNote | |
--synchronize Evernote | |
repeat until isSynchronizing is false | |
synchronize | |
end repeat | |
repeat until isSynchronizing is false | |
end repeat | |
end tell | |
(* /// | |
PART 8: | |
Display Growl Notifications | |
/// *) | |
--is Growl installed? | |
set Growl_ to my Growl_Check() | |
--notify on Success or Failure | |
if Growl_ is true then | |
tell application "Growl" | |
set allNotificationsFiles to {"Success Notification", "Failure Notification"} | |
set enabledNotificationsFiles to {"Success Notification", "Failure Notification"} | |
register as application ¬ | |
"Skim Annotations to Evernote" all notifications allNotificationsFiles ¬ | |
default notifications enabledNotificationsFiles ¬ | |
icon of application "URL Handler" | |
end tell | |
--on Success | |
tell application "Growl" | |
if newNote exists then | |
notify with name ¬ | |
"Success Notification" title ¬ | |
"Import Success!" description "Successfully Exported All Skim Annotations to Evernote" application name "Skim Annotations to Evernote" icon of application "Custom URL Handler" | |
else | |
notify with name ¬ | |
"Failure Notification" title ¬ | |
"Import Failed" description "The script failed to export all Skim notes to Evernote" application name "Skim Annotations to Evernote" icon of application "Custom URL Handler" | |
end if | |
end tell | |
end if | |
end tell | |
(* HANDLERS *) | |
--URL encode text | |
on encode_text(this_text, encode_URL_A, encode_URL_B) | |
set the standard_characters to "abcdefghijklmnopqrstuvwxyz0123456789" | |
set the URL_A_chars to "$+!'/?;&@=#%><{}[]\"~`^\\|*" | |
set the URL_B_chars to ".-_:" | |
set the acceptable_characters to the standard_characters | |
if encode_URL_A is false then set the acceptable_characters to the acceptable_characters & the URL_A_chars | |
if encode_URL_B is false then set the acceptable_characters to the acceptable_characters & the URL_B_chars | |
set the encoded_text to "" | |
repeat with this_char in this_text | |
if this_char is in the acceptable_characters then | |
set the encoded_text to (the encoded_text & this_char) | |
else | |
set the encoded_text to (the encoded_text & encode_char(this_char)) as string | |
end if | |
end repeat | |
return the encoded_text | |
end encode_text | |
on encode_char(this_char) | |
set the ASCII_num to (the ASCII number this_char) | |
set the hex_list to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"} | |
set x to item ((ASCII_num div 16) + 1) of the hex_list | |
set y to item ((ASCII_num mod 16) + 1) of the hex_list | |
return ("%" & x & y) as string | |
end encode_char | |
on replaceString(theText, oldString, newString) | |
-- ljr (http://applescript.bratis-lover.net/library/string/) | |
local ASTID, theText, oldString, newString, lst | |
set ASTID to AppleScript's text item delimiters | |
try | |
considering case | |
set AppleScript's text item delimiters to oldString | |
set lst to every text item of theText | |
set AppleScript's text item delimiters to newString | |
set theText to lst as string | |
end considering | |
set AppleScript's text item delimiters to ASTID | |
return theText | |
on error eMsg number eNum | |
set AppleScript's text item delimiters to ASTID | |
error "Can't replaceString: " & eMsg number eNum | |
end try | |
end replaceString | |
--convert highlights into text values | |
on color2text(noteColor, theTextStatus) | |
set colorText to {} | |
if theTextStatus is {button returned:"Secondary"} then | |
if noteColor is {64634, 900, 1905, 65535} then | |
set end of colorText to "Disagree" | |
else if noteColor is {64907, 32785, 2154, 65535} then | |
set end of colorText to "Agree" | |
else if noteColor is {65535, 65531, 2689, 65535} then | |
set end of colorText to "Summary" | |
else if noteColor is {8608, 65514, 1753, 65535} then | |
set end of colorText to "Reference" | |
else if noteColor is {8372, 65519, 65472, 65535} then | |
set end of colorText to "Quotable" | |
else if noteColor is {64587, 1044, 65481, 65535} then | |
set end of colorText to "Technique" | |
end if | |
else if theTextStatus is {button returned:"Primary"} then | |
if noteColor is {64634, 900, 1905, 65535} then | |
set end of colorText to "Key Quote" | |
else if noteColor is {64907, 32785, 2154, 65535} then | |
set end of colorText to "Key Theme" | |
else if noteColor is {65535, 65531, 2689, 65535} then | |
set end of colorText to "Summary Passage" | |
else if noteColor is {8608, 65514, 1753, 65535} then | |
set end of colorText to "Key Motif" | |
else if noteColor is {8372, 65519, 65472, 65535} then | |
set end of colorText to "Confusing Passage" | |
else if noteColor is {64587, 1044, 65481, 65535} then | |
set end of colorText to "\"Purple\" Passage" | |
end if | |
end if | |
return colorText | |
end color2text | |
--remove any empty note sections | |
on textCheck(notesText_text, notesText_anchor, notesText_highlight, notesText_underline, notesText_strikethru, theSummary) | |
if notesText_text is "<hr /> | |
<h2>The ToC</h2> | |
" then | |
set notesText_text to "" | |
else | |
set notesText_text to notesText_text & LF & LF | |
end if | |
if notesText_anchor is "<hr /> | |
<h2>All of my Text Notes</h2> | |
" then | |
set notesText_anchor to "" | |
else | |
set notesText_anchor to notesText_anchor & LF & LF | |
end if | |
if notesText_highlight is "<hr /> | |
<h2>All of the Highlighted Text </h2> | |
" then | |
set notesText_highlight to "" | |
else | |
set notesText_highlight to notesText_highlight & LF & LF | |
end if | |
if notesText_underline is "<hr /> | |
<h2>All of the Underlined Text</h2> | |
" then | |
set notesText_underline to "" | |
else | |
set notesText_underline to notesText_underline & LF & LF | |
end if | |
if notesText_strikethru is "<hr /> | |
<h2>All of the Strike-Through Text</h2> | |
" then | |
set notesText_strikethru to "" | |
else | |
set notesText_strikethru to notesText_strikethru & LF & LF | |
end if | |
if theSummary is {} then | |
set theSummary to "" | |
else | |
set theSummary to theSummary & LF & LF | |
end if | |
return notesText_text & theSummary & notesText_anchor & notesText_highlight & notesText_underline & notesText_strikethru | |
end textCheck | |
--remove items from a list | |
on cleanmyList(theList, itemsToDelete) | |
set cleanList to {} | |
repeat with i from 1 to count theList | |
if {theList's item i} is not in itemsToDelete then set cleanList's end to theList's item i | |
end repeat | |
return cleanList | |
end cleanmyList | |
--Check For Growl | |
on Growl_Check() | |
if appIsRunning("Growl") then | |
set growl_Running to true | |
tell application "Growl" | |
set allNotificationsFiles to {"Import To Evernote", "Success Notification", "Failure Notification"} | |
set enabledNotificationsFiles to {"Import To Evernote", "Success Notification", "Failure Notification"} | |
register as application ¬ | |
"Skim Annotations to Evernote" all notifications allNotificationsFiles ¬ | |
default notifications enabledNotificationsFiles ¬ | |
icon of application "Custom URL Handler" | |
end tell | |
return growl_Running | |
else | |
error | |
end if | |
end Growl_Check | |
--App Detect | |
on appIsRunning(appName) | |
tell application "System Events" to (name of processes) contains appName | |
end appIsRunning |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment