2011/06/24

Send DEVONthink tags to BibDesk as keywords

Continuing in the same spirit as in the previous post, I wrote an AppleScript for sending DEVONthink tags to BibDesk. Only one item should be selected in DEVONthink and BibDesk. No duplicate keywords are created in BibDesk.

The AppleScript code is the following:
tell application "BibDesk"
    --only one item should be selected in BibDesk
    set thePub to the selection of document 1
    set keywordsPub to keywords of (item 1 in thePub)
   
    set old_delimiters to AppleScript's text item delimiters
    --the space inside quotes is very important!
    set AppleScript's text item delimiters to ", "
    set keywordsPubList to text items of keywordsPub
    set AppleScript's text item delimiters to old_delimiters
   
end tell

tell application "DEVONthink Pro"
    set thisSelection to the selection
    if thisSelection is {} then error "Please select something"
    if (length of thisSelection) is greater than 1 then error "Please select only one item"
    set the clipboard to ""
    set thisItem to (item 1 of thisSelection)
    set tagsItem to tags of thisItem
   
    repeat with x from 1 to the count of tagsItem
        set positionOfDuplicate to list_position(item x of tagsItem, keywordsPubList) of me
       
        if positionOfDuplicate is 0 then
            set keywordsPub to keywordsPub & ", " & item x of tagsItem
        else
            set keywordsPub to keywordsPub
        end if
       
    end repeat
   
end tell
tell application "BibDesk"
    if the first character of keywordsPub is "," then
        set keywordsPub to text 3 thru -1 of keywordsPub as text
    end if
    set keywords of (item 1 in the thePub) to keywordsPub
end tell

--subroutine from "AppleScript 1-2-3" p.567 for checking for duplicates
on list_position(this_item, this_list)
    repeat with i from 1 to the count of this_list
        if item i of this_list is this_item then return i
    end repeat
    return 0
end list_position

2011/06/18

Convert DEVONthink tags to MediaWiki categories

DEVONthink has a quite efficient tagging capability. Especially, the autocomplete feature of the tag bar, at the lower part of a DEVONthink window, saves me a lot of time and provides increased consistency in my tags.

Moreover, I maintain a separate page in my wiki for each book or paper that I have read. There I write all my notes and thoughts about each source. MediaWiki's name for tag is category and the required markup code for it is the following:
[[Category:tagName]] 
As I did not want to insert manually the tags for each source twice I wrote an AppleScript, which converts DEVONthink tags to MediaWiki categories. One item should be selected in DEVONthink before executing the script. The result is sent to the clipboard.

The AppleScript code is the following:
--2011-06-18
--http://organognosi.blogspot.com

tell application "DEVONthink Pro"
    set thisSelection to the selection
    if thisSelection is {} then error "Please select something"
    if (length of thisSelection) is greater than 1 then error "Please select only one item"
    set the clipboard to ""
    set newCategories to ""
    repeat with thisItem in thisSelection
        set tagsItem to tags of thisItem
        repeat with eachTag in tagsItem
            set tagForCategory to eachTag
            if tagForCategory is in {"Linked with MediaWiki"} then
                set newCategories to newCategories
            else
                set newCategories to "[[category:" & tagForCategory & "]] "
                set the clipboard to (the clipboard) & newCategories
            end if
        end repeat
    end repeat
end tell

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.

2011/06/05

Add tags to many DEVONthink items at the same time

In DEVONthink, when two or more items have exactly the same tags, new tags can be added to them using the tag bar at the lower part of a DEVONthink window. But when their tags are different the message "Multiple Selection" appears in the bar and you cannot edit it. With the following AppleScript you can add multiple tags even to these items.
--2011-06-05
--http://organognosi.blogspot.com/

display dialog "Enter tags to add (separated by commas):" default answer ""
set newTags to text returned of the result

set old_delimiters to AppleScript's text item delimiters
set AppleScript's text item delimiters to ","
set tagList to text items of newTags
set AppleScript's text item delimiters to old_delimiters

tell application id "com.devon-technologies.thinkpro2"
   
    try
        set these_items to the selection
        if these_items is {} then error "Please select some contents."
       
        repeat with this_item in these_items
            set tags of this_item to (tags of this_item) & tagList
        end repeat
    end try
end tell

2011/06/01

Add keywords to many entries of BibDesk at the same time

The following AppleScript performs the above function:
tell application "BibDesk"
    set theSelection to the selection of document 1
    display dialog "Give the new keywords separated by commas:" default answer "" buttons {"Cancel", "OK"} default button 2
    set the newKeywords to the text returned of the result
   
    repeat with thePub in theSelection
        set oldKeywords to keywords of thePub
        if oldKeywords is "" then
            set keywords of thePub to newKeywords
        else
            set keywords of thePub to keywords of thePub & ", " & newKeywords
        end if
    end repeat
end tell