2011/06/10

Export Skim notes according to their highlight colors

Adam Cronkright mentioned, in a thread in the Skim forum, that he uses different colors for highlighting various sections of a PDF, which have a common characteristic (e.g. author's points he agrees with, points he disagrees with, good phrases...). His problem is that he would like to have an efficient way to organize these different categories of notes and Skim's present features does not help him much to this end.

I think that a way to solve this problem is to use a specialized app for note management and an AppleScript, which exports Skim notes according to their color. So I found a reason to write an additional AppleScript or actually two!

The first is a simplified version, which has only one prerequisite for execution. Particularly, you need to use one or more of the following colors: ice, honey drew, flora, lemon, cantaloupe, silver, which are shown below.


You can change a color in the Favorite Colors by dragging a new color from the Color Panel (Tools> Show Colors) and drop it on the Favorite Colors toolbar item. Hold down the Option key to add a new color. You can remove a color from the Favorite Colors by dragging it to the Trash (from Tips and Tricks page in Skim's wiki).

Each color in Skim is represented as a list of four numbers (red, green, blue, alpha). The fourth number is constant (65535). For example, the ice color is represented by the list  {26214, 65535, 65535, 65535}. So you can change the hardwired colors in the scripts if you know the corresponding RGB (red, green, blue) code in 16-bit format for your preferred colors. Then you can add it in in the chooseColor subroutine (see the AppleScript below). 

When you execute the script the following windows will open consecutively:


You can choose more than one colors by pressing cmd + click.



If you choose "Some" then you will be asked to give the range of pages from which the notes will be extracted.


 

The result is sent to the clipboard. The code is the following:
--2011-06-10
--http://organognosi.blogspot.com/
tell application "Skim"
    set the clipboard to ""
    set numberOfPages to count pages of document 1
    activate
    set myColorCodes to my chooseColor()
    display dialog "Do you want to export all the notes or some of them?" buttons {"All", "Some"} default button 1
    set answer to button returned of the result
   
    if answer is "All" then
        set firstPage to "1" as number
        set lastPage to numberOfPages
        set the clipboard to "Skim notes" & return
    else
        display dialog "Give the number of the first page." default answer ""
        set firstPage to text returned of the result as number
       
        display dialog "Give the number of the last page" default answer ""
        set lastPage to text returned of the result as number
    end if
   
    repeat with currentPage from firstPage to lastPage
        set pageNotes to notes of page currentPage of document 1
        exportPageNotes(pageNotes, currentPage, myColorCodes) of me
    end repeat
   
end tell

on exportPageNotes(listOfNotes, pageForProcessing, myColorCodes)
    tell application "Skim"
       
        set currentPDFpage to pageForProcessing
        repeat with coloredNote in listOfNotes
           
            repeat with i from 1 to the count of myColorCodes
                if color of coloredNote is item i of myColorCodes then
                    set noteText to get text for coloredNote
                   
                    set the clipboard to (the clipboard) & noteText & return & return
                end if
            end repeat
        end repeat
       
    end tell
end exportPageNotes

on chooseColor()
    set selectedColors to (choose from list {"ice", "honey drew", "flora", "lemon", "cantaloupe", "silver"} with prompt ("Choose the color of notes for exporting (you can select multiple colors):") default items {"lemon"} with multiple selections allowed)
   
    set colorCodes to {}
    set noteColor to ""
    repeat with noteCol in selectedColors
        set noteColor to noteCol as text
        if noteColor is "ice" then
            set end of colorCodes to {26214, 65535, 65535, 65535}
        else if noteColor is "honey drew" then
            set end of colorCodes to {52428, 65535, 26214, 65535}
        else if noteColor is "flora" then
            set end of colorCodes to {26214, 65535, 26214, 65535}
        else if noteColor is "lemon" then
            set end of colorCodes to {65535, 65535, 2, 65535}
        else if noteColor is "cantaloupe" then
            set end of colorCodes to {65535, 52428, 26214, 65535}
        else if noteColor is "silver" then
            set end of colorCodes to {52428, 52428, 52428, 65535}
        end if
    end repeat
   
    return colorCodes
end chooseColor

The second AppleScript is that which I use and is quite more complicated. As you may know, my preferred program for managing notes is MediaWiki so the AppleScript's result is customized for import in a MediaWiki page.

Some additional features of this AppleScript are the following:
  • a hyperlink to the exact PDF page is created for each exported note
  • the annotation's date and time are added at the end of each exported note
  • the notes from each page are separated by a line 
  • the extended text of the note is exported as well
  • the first five notes of the first page are not exported
  • the written page numbers should be given in the dialog windows

If you want to use this AppleScript you need firstly to create the five Skim notes in the first PDF page as I describe in my post "How to create correctly the Skim notes which have the DEVONthink links, when you have already annotated the first page of the PDF document.

The code is the following:


--2011-06-10
--http://organognosi.blogspot.com/
tell application "Skim"
    set the clipboard to ""
    set numberOfNote5 to (get text for note 5 of page 1 of document 1) as string
    set pdfTitle to get (extended text of note 4) of page 1 of document 1 as string
    set numberOfPages to count pages of document 1
   
    activate
    set myColorCodes to my chooseColor() --εκτός των loops πρέπει να βρίσκεται, μια φορά το θέτεις
   
    display dialog "Do you want to export all the notes or only some of them?" buttons {"All", "Some"} default button 1
    set answer to button returned of the result
   
    if answer is "All" then
        set firstPage to "1" as number
        set lastPage to numberOfPages
        set the clipboard to "===Skim notes===" & return
    else
        display dialog "Give me the written number of the first page." default answer ""
        set firstPageWritten to text returned of the result as number
        set firstPage to firstPageWritten - numberOfNote5 as number
       
        display dialog "Give me the written numbers of the last page" default answer ""
        set lastPageWritten to text returned of the result as number
        set lastPage to lastPageWritten - numberOfNote5 as number
       
        set the clipboard to (the clipboard) & "Notes from \"[[@" & pdfTitle & "]]\" (pages " & firstPage & " - " & lastPage & ") <br />" & return
       
    end if
   
    repeat with currentPage from firstPage to lastPage
        --special provision for page 1
        if currentPage is 1 then
            set pageNotes to notes of page 1 of document 1
            set notesAfter5 to items 6 thru -1 of pageNotes
           
            exportPageNotes(notesAfter5, currentPage, myColorCodes) of me
        else
            set pageNotes to notes of page currentPage of document 1
           
            exportPageNotes(pageNotes, currentPage, myColorCodes) of me
        end if
    end repeat
   
end tell

on exportPageNotes(listOfNotes, pageForProcessing, myColorCodes)
    tell application "Skim"
        set numberOfNote5 to (get text for note 5 of page 1 of document 1) as string
        set pdfTitle to get (extended text of note 4) of page 1 of document 1 as string
        set numberOfPageNotes to count notes of page pageForProcessing of document 1
        set theWrittenPage to pageForProcessing + numberOfNote5 as string
        set pdfDevonThinkLink to (get text for note 4 of page 1 of document 1) as string
        set pdfDevonThinkLinkWihtoutZero to (text 1 thru ((length of pdfDevonThinkLink) - 1) of pdfDevonThinkLink) as string
       
        repeat with coloredNote in listOfNotes
           
            repeat with i from 1 to the count of myColorCodes
                if color of coloredNote is item i of myColorCodes then
                    set pdfText to get text for coloredNote
                    set pdfText2 to get extended text of coloredNote as text
                    set fullNoteText to pdfText & " " & pdfText2
                   
                    set annotationDate to modification date of coloredNote as text
                   
                    set pageForDevonThinkLink to pageForProcessing - 1
                   
                    --for use with MediaWiki semantic annotations
                    set firstCharacter to get the character 1 of fullNoteText
                    if firstCharacter = "[" then
                        set endofNote to "]]]"
                    else
                        set endofNote to "]"
                    end if
                   
                    set textAfterFullNoteText to "[" & pdfDevonThinkLinkWihtoutZero & pageForDevonThinkLink & " p. " & theWrittenPage & endofNote & " <small>(" & annotationDate & ")</small>"
                    set textForTextMate to fullNoteText & " " & textAfterFullNoteText
                    set textForTextMate2 to replaceText(textForTextMate, "missing value", "") of me
                    set textForTextMate3 to replaceText(textForTextMate2, " ()", "") of me
                   
                    set the clipboard to (the clipboard) & textForTextMate3 & return
                   
                end if
            end repeat
        end repeat
       
        set theSeperationLine to ""
        repeat with coloredNote in listOfNotes
            if numberOfPageNotes > 0 then
                repeat with i from 1 to the count of myColorCodes
                    if (color of coloredNote is item i of myColorCodes) then
                        set theSeperationLine to "----" & return
                        exit repeat
                    end if
                end repeat
            end if
        end repeat
        set the clipboard to (the clipboard) & theSeperationLine
    end tell
end exportPageNotes

on replaceText(thisText, searchString, replacementString)
    set AppleScript's text item delimiters to the searchString
    set the itemList to every text item of thisText
    set AppleScript's text item delimiters to the replacementString
    set thisText to the itemList as string
    set AppleScript's text item delimiters to {""}
    return thisText
end replaceText

on chooseColor()
    set selectedColors to (choose from list {"ice", "honey drew", "flora", "lemon", "cantaloupe", "silver"} with prompt ("Choose the color of notes for exporting (you can select multiple colors):") default items {"lemon"} with multiple selections allowed)
    --selectedColors is a list of lists
    set colorCodes to {}
    set noteColor to ""
    repeat with noteCol in selectedColors
        set noteColor to noteCol as text
        if noteColor is "ice" then
            set end of colorCodes to {26214, 65535, 65535, 65535}
        else if noteColor is "honey drew" then
            set end of colorCodes to {52428, 65535, 26214, 65535}
        else if noteColor is "flora" then
            set end of colorCodes to {26214, 65535, 26214, 65535}
        else if noteColor is "lemon" then
            set end of colorCodes to {65535, 65535, 2, 65535}
        else if noteColor is "cantaloupe" then
            set end of colorCodes to {65535, 52428, 26214, 65535}
        else if noteColor is "silver" then
            set end of colorCodes to {52428, 52428, 52428, 65535}
           
        end if
    end repeat
   
    return colorCodes
end chooseColor

I hope this AppleScript will help Adam! Anyway, your post was an inspiration for me. Finally, I would like to thank Martin who informed me about it.

No comments: