How to paste a URL from the Clipboard to BibDesk as a LaTeX (and Harvard) compatible reference

Now after I’ve ended up about 700 times to always do the same thing: In BibDesk, add a “Note” field to a publication, copy my template for that note field, paste it into the publication, then copy and paste the URL I want to refer to into the right place, I got bored. Here’s another way of doing it (obviously attached to a keyboard shortcut by one of the usual means, e.g. BetterTouchTool). It takes the URL on the clipboard, escapes some characters that LaTeX would choke on, wraps it with my template, calculates the current date, and adds it to the notes field (which is created if it wasn’t there). If the field was there, nothing is added, but the result is copied back to the clipboard.

-- Create a Note field in Bibdesk and paste
-- the content of the clipboard as a link

-- [Online]. Available from: \url{} (Accessed: January 21, 2014)

property theFieldToSet : "Note"
property theFormatString : "[Online]. Available from: \\url{###url###} (Accessed: ###date###)"

tell application "BibDesk"
	activate
	set theBooks to the selection of document 1
	repeat with theBook in theBooks
		set shouldSet to true
		if (value of field theFieldToSet of theBook is not "") then
			set shouldSet to false -- do not set but copy to clipboard
		end if
		
		set theUrl to the clipboard as text
		set theUrl to my replaceString(theUrl, "%", "\\%")
		set theUrl to my replaceString(theUrl, "#", "\\#")
		set theUrl to my replaceString(theUrl, "&", "\\&")
		set theUrl to my trim(theUrl)
		
		set theValue to theFormatString
		set theValue to my replaceString(theValue, "###url###", theUrl)
		set theValue to my replaceString(theValue, "###date###", my timeStamp())
		
		if shouldSet then
			set the value of field theFieldToSet of theBook to theValue
		else
			set the clipboard to theValue
		end if
	end repeat
end tell

on timeStamp()
	tell (current date) to get (it's month) & " " & day & ", " & (it's year as integer as text)
	return result as text
end timeStamp

on replaceString(theText, oldString, newString)
	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

on trim(t)
	set tc to (count t)
	repeat with i from 1 to tc -- remove leading space
		if text i of t is not " " then repeat with j from tc to i by -1 -- remove trailing space
			if text j of t is not " " then return text i thru j of t
		end repeat
	end repeat
	return "" -- the text contains only spaces, return empty string
end trim
Share