module VimGolf class Session < Array def to_s(sep = '') @log.join(sep) end end class Keylog def self.parse(input) session = Session.new scan(input) {|s| session << s } session end def self.convert(input) parse(input).join('') end def self.score(input) keys = 0 scan(input) {|s| keys += 1 } keys end def self.scan(input) scanner = StringScanner.new(input) output = "" until scanner.eos? c = scanner.get_byte n = c.unpack('C').first out_char = \ case n # Special platform-independent encoding stuff when 0x80 code = scanner.get_byte + scanner.get_byte # This list has been populated by experimentation so far, # because I haven't bothered looking for a more authoritative # source. case code when "k1"; "" when "k2"; "" when "k3"; "" when "k4"; "" when "k5"; "" when "k6"; "" when "k7"; "" when "k8"; "" when "k9"; "" when "k;"; "" when "F1"; "" when "F2"; "" when "kP"; "" when "kN"; "" when "kh"; "" when "@7"; "" when "kI"; "" when "kD"; "" when "kb"; "" when "ku"; "" when "kd"; "" when "kl"; "" when "kr"; "" when "#4"; "" when "%i"; "" when "kB"; "" when "\xffX"; "" else #puts "Unknown Vim code: #{code.inspect}" '<%02x-%02x>' % code.unpack('CC') end # Control characters with special names when 0; "" when 9; "" when 10; "" when 13; "" when 27; "" when 127; "" # Otherwise, use format when 0..31; "" # The rest of ANSI is printable when 32..126; c else #puts "Unexpected extended ASCII: #{'%#04x' % n}" '<%#04x>' % n end yield out_char end end end end