From: Glenn Parker Date: 2005-03-14T03:57:53+09:00 Subject: Re: [SOLUTION] Quoted Printable (#23) Note: I assumed it would be cheating to use the builtin quoted printable facilities. I found it somewhat frustrating that String#each_byte does not return any useful value (see encode_str). I found it a bit more frustrating that String#chomp! is a greedier than you might expect, discarding all sorts of potential line endings, instead of limiting itself to $/. I would also suggest that adding support for GetoptLong#[] to query options directly, instead of requiring a full iteration. #!/usr/bin/env ruby -w require 'getoptlong' MaxLength = 76 def main opts = GetoptLong.new( [ "-d", GetoptLong::NO_ARGUMENT ], [ "-x", GetoptLong::NO_ARGUMENT ] ) $opt_decode = false $opt_xml = false opts.each do |opt, arg| case opt when "-d": $opt_decode = true when "-x": $opt_xml = true end end if $opt_decode decode_input else encode_input end end def encode_input STDOUT.binmode # We need to control the line-endings. while (line = gets) do # Note: String#chomp! swallows more than just $/. line.sub!(/#{$/}$/o, "") # Encode the entire line. line.gsub!(/[^\t -<>-~]+/) { |str| encode_str(str) } line.gsub!(/[&<>]+/) { |str| encode_str(str) } if $opt_xml line.sub!(/\s*$/) { |str| encode_str(str) } # Split the line up as needed. while line.length > MaxLength split = line.index("=", MaxLength - 4) - 1 split = (MaxLength - 2) if split.nil? or (split > MaxLength - 2) print line[0..split], "=\r\n" line = line[(split + 1)..-1] end print line, "\r\n" end end def encode_str(str) encoded = "" str.each_byte { |c| encoded << "=%02X" % c } encoded end def decode_input while (line = gets) do line.chomp! line.gsub!(/=([\dA-F]{2})/) { $1.hex.chr } if line[-1] == ?= print line[0..-2] else print line, $/ end end end main -- Glenn Parker | glenn.parker-AT-comcast.net |