HTML5 spec: URL creation and implementation
2.5.5 URL manipulation and creation
To fragment-escape a string input, a user agent must run the following steps:
Let input be the string to be escaped.Let position point at the first character of input.
Let output be an empty string.
Loop: If position is past the end of input, then jump to the step labeled end.
If the character in input pointed to by position is in the range U+0000 to U+0020 or is one of the following characters:
U+003C LESS-THAN SIGN character (<)
...then append the percent-encoded form of the character to output. [RFC3986]
Otherwise, append the character itself to output.
This escapes any ASCII characters that are not valid in the URI <fragment> production without being escaped.
Advance position to the next character in input.
Return to the step labeled loop.
15: def escape(s) 16: s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) { 17: '%'+$1.unpack('H2'*bytesize($1)).join('%').upcase 18: }.tr(' ', '+') 19: end
23: def unescape(s) 24: s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){ 25: [$1.delete('%')].pack('H*') 26: } 27: end
http://rack.rubyforge.org/doc/classes/Rack/Utils.html