Chris@909: module CodeRay Chris@909: module Encoders Chris@909: Chris@909: # A simple JSON Encoder. Chris@909: # Chris@909: # Example: Chris@909: # CodeRay.scan('puts "Hello world!"', :ruby).json Chris@909: # yields Chris@909: # [ Chris@909: # {"type"=>"text", "text"=>"puts", "kind"=>"ident"}, Chris@909: # {"type"=>"text", "text"=>" ", "kind"=>"space"}, Chris@909: # {"type"=>"block", "action"=>"open", "kind"=>"string"}, Chris@909: # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, Chris@909: # {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"}, Chris@909: # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"}, Chris@909: # {"type"=>"block", "action"=>"close", "kind"=>"string"}, Chris@909: # ] Chris@909: class JSON < Encoder Chris@909: Chris@909: begin Chris@909: require 'json' Chris@909: rescue LoadError Chris@909: begin Chris@909: require 'rubygems' unless defined? Gem Chris@909: gem 'json' Chris@909: require 'json' Chris@909: rescue LoadError Chris@909: $stderr.puts "The JSON encoder needs the JSON library.\n" \ Chris@909: "Please gem install json." Chris@909: raise Chris@909: end Chris@909: end Chris@909: Chris@909: register_for :json Chris@909: FILE_EXTENSION = 'json' Chris@909: Chris@909: protected Chris@909: def setup options Chris@909: super Chris@909: Chris@909: @first = true Chris@909: @out << '[' Chris@909: end Chris@909: Chris@909: def finish options Chris@909: @out << ']' Chris@909: end Chris@909: Chris@909: def append data Chris@909: if @first Chris@909: @first = false Chris@909: else Chris@909: @out << ',' Chris@909: end Chris@909: Chris@909: @out << data.to_json Chris@909: end Chris@909: Chris@909: public Chris@909: def text_token text, kind Chris@909: append :type => 'text', :text => text, :kind => kind Chris@909: end Chris@909: Chris@909: def begin_group kind Chris@909: append :type => 'block', :action => 'open', :kind => kind Chris@909: end Chris@909: Chris@909: def end_group kind Chris@909: append :type => 'block', :action => 'close', :kind => kind Chris@909: end Chris@909: Chris@909: def begin_line kind Chris@909: append :type => 'block', :action => 'begin_line', :kind => kind Chris@909: end Chris@909: Chris@909: def end_line kind Chris@909: append :type => 'block', :action => 'end_line', :kind => kind Chris@909: end Chris@909: Chris@909: end Chris@909: Chris@909: end Chris@909: end