Dave Burt wrote:

> Hi Florian,

Moin Dave.

> As always, I'm amazed by your concise code. But your solution seems to be 
> failing a bunch of my tests (and not just by chopping lines early, which is 
> allowed):

Thanks, I'll have a look.

> encoding:
> - escapes mid-line whitespace

I'm not sure I get this. Am I incorrectly escaping mid-line whitespace 
or am I incorrectly not escaping it? And what is mid-line whitespace?

> - escapes '~'

Heh, classic off-by-one. Easily fixed by changing the Regexp. See source 
below.

> - allows too-long lines (my tests saw up to 104 characters on a line)

Any hints on when this is happening? I can't see why and when this would 
happen.

> - allows unescaped whitespace on the end of a line (as long as it's preceded 
> by escaped whitespace)

Fixed. See code below.

> decoding:
> - doesn't ignore trailing literal whitespace

Well, I don't think that's much of an issue as I'm not sure when 
trailing whitespace would be prepended to lines, but I've fixed it anyway.

Here's the new code:

>   def encode(text, also_encode = "")
>     text.gsub(/[\t ](?:[\v\t ]|$)|[=\x00-\x08\x0B-\x1F\x7F-\xFF#{also_encode}]/) do |char|
>       char[0 ... -1] + "=%02X" % char[-1]
>     end.gsub(/^(.{75})(.{2,})$/) do |match|
>       base, continuation = $1, $2
>       continuation = base.slice!(/=(.{0,2})\Z/).to_s + continuation
>       base + "=\n" + continuation
>     end.gsub("\n", "\r\n")
>   end
> 
>   def decode(text, allow_lowercase = false)
>     encoded_re = Regexp.new("=([0-9A-F]{2})", allow_lowercase ? "i" : "")
>     text.gsub("\r\n", "\n").gsub("=\n", "").gsub(encoded_re) do
>       $1.to_i(16).chr
>     end
>   end

I'll repost the full source when I've sorted out that other problem as well.