I usually get up an hour or two before I start my work day and “play.” Playtime usually results in half-finished scripts and deleted git branches, but sometimes I do something simple and useful (to me). Wednesday was Bash fun, and here’s this morning’s project: LaunchBar actions to url encode and decode strings1. If you run them outside of LaunchBar, they’ll encode/decode your clipboard, replacing what’s in your clipboard with the result, so they have multiple applications. These have probably been done before, but my quick DuckDuckGo search didn’t yield any immediate results.

I find it especially useful to be able to quickly encode and decode urls and strings when I’m testing online APIs out, but there are many times when I find I need this. I usually use a shell function or the very handy Hash Widget for Dashboard, but as a LaunchBar user, this is faster.

To use with LaunchBar, open the script in your Script Editor (instant-open links provided) and save it to ~/Library/Application Support/LaunchBar/Actions, creating the folder if it doesn’t already exist. Then, assuming you have Actions enabled in your indexing preferences, you can just type “urle” to get the action, then hit space to enter or paste the text to encode/decode. Alternatively, you can paste first or use Instant Send on a selection, then hit Tab and select the encode or decode action. To use elsewhere, such as in FastScripts, just save them as scripts in your ~/Library/Scripts folder. Using them outside of LaunchBar won’t be interactive; they will encode or decode your clipboard in place.

Side note: I decided to do the encoding/decoding in pure AppleScript, using functions I’ve mentioned previously from http://harvey.nu/. You can encode faster with Perl using a shell call, if you prefer. In a shell script for encoding, you’d use echo "string to encode"|perl -pe's/([^-_.~A-Za-z0-9])/sprintf("%%%02X", ord("$1"))/seg'. In AppleScript, that would look like set _res to do shell script "echo \"" & ASTextVar & "\"|perl -pe's/([^-_.~A-Za-z0-9])/sprintf(\"%%%02X\", ord(\"$1\"))/seg'", where ASTextVar is your string to encode.

The LaunchBar actions copy the resulting text to the clipboard, but you may prefer to have it passed back to LaunchBar for subsequent processing. There are commented lines in the scripts for doing so, just comment out the last line in the handle_string function and uncomment the line above it.

URL Encode

Open this script in your AppleScript editor

on handle_string(lbText)
	set _res to urlencode(lbText)
	-- to return the result to launchbar instead of copying it substitute
	-- the next line for the line after it (set the clipboard to _res)
	-- open location "x-launchbar:select?string=" & urlencode(_res)
	set the clipboard to _res
end handle_string

on run
	set the clipboard to urlencode(the clipboard as text)
end run

on urlencode(theText) -- http://harvey.nu/applescript_url_encode_routine.html
	set theTextEnc to ""
	repeat with eachChar in characters of theText
		set useChar to eachChar
		set eachCharNum to ASCII number of eachChar
		if eachCharNum = 32 then
			set useChar to "+"
		else if (eachCharNum is not equal to 42) and (eachCharNum is not equal to 95) and (eachCharNum < 45 or eachCharNum > 46) and (eachCharNum < 48 or eachCharNum > 57) and (eachCharNum < 65 or eachCharNum > 90) and (eachCharNum < 97 or eachCharNum > 122) then
			set firstDig to round (eachCharNum / 16) rounding down
			set secondDig to eachCharNum mod 16
			if firstDig > 9 then
				set aNum to firstDig + 55
				set firstDig to ASCII character aNum
			end if
			if secondDig > 9 then
				set aNum to secondDig + 55
				set secondDig to ASCII character aNum
			end if
			set numHex to ("%" & (firstDig as string) & (secondDig as string)) as string
			set useChar to numHex
		end if
		set theTextEnc to theTextEnc & useChar as string
	end repeat
	return theTextEnc
end urlencode

URL Decode

on handle_string(lbText)
	set _res to urldecode(lbText)
	-- to return the result to launchbar instead of copying it substitute
	-- the next line for the line after it (set the clipboard to _res)
	-- open location "x-launchbar:select?string="&urldecode(_res)
	set the clipboard to _res
end handle_string

on run
	set the clipboard to urldecode(the clipboard as text)
end run

on urldecode(theText) -- http://harvey.nu/applescript_url_decode_routine.html
	set sDst to ""
	set sHex to "0123456789ABCDEF"
	set i to 1
	repeat while i <= length of theText
		set c to character i of theText
		if c = "+" then
			set sDst to sDst & " "
		else if c = "%" then
			if i > ((length of theText) - 2) then
				display dialog ("Invalid URL Encoded string - missing hex char") buttons {"Crap..."} with icon stop
				return ""
			end if
			set iCVal1 to (offset of (character (i + 1) of theText) in sHex) - 1
			set iCVal2 to (offset of (character (i + 2) of theText) in sHex) - 1
			if iCVal1 = -1 or iCVal2 = -1 then
				display dialog ("Invalid URL Encoded string - not 2 hex chars after % sign") buttons {"Crap..."} with icon stop
				return ""
			end if
			set sDst to sDst & (ASCII character (iCVal1 * 16 + iCVal2))
			set i to i + 2
		else
			set sDst to sDst & c
		end if
		set i to i + 1
	end repeat
	return sDst
end urldecode
  1. People may love Alfred, but this is another example of why I will probably always prefer LaunchBar. Extensibility. Also, QuickSilver is dead, just give up.