module HANSON

based on github.com/timjansen/hanson

Thanks to Tim Jansen

Constants

BACKTICK_ML_QUOTE
CLANG_COMMENT
CLANG_ML_COMMENT
DOUBLE_QUOTE
IDENTIFIER
KEYWORDS
ML_ESCAPE_MAP
SINGLE_QUOTE
TRAILING_COMMA
UNESCAPE_MAP

Public Class Methods

convert( text ) click to toggle source
# File lib/json/next/parser/hanson.rb, line 64
def self.convert( text )

  # text is the HanSON string to convert.

  # todo: add keep_line_numbers options - why? why not?
  #  see github.com/timjansen/hanson

  ## pass 1: remove/strip comments
  text = strip_comments( text )

  ## pass 2: requote/normalize quotes
  text = normalize_quotes( text )

  ## pass 3: quote unquoted and remove trailing commas
  text = text.gsub( /#{KEYWORDS}|#{IDENTIFIER}|#{DOUBLE_QUOTE}|#{TRAILING_COMMA}/ox ) do |match|
     ## puts "match: >>#{match}<< : #{match.class.name}"

     m = Regexp.last_match
     if m[:identifier]
       ## puts "!!! identfier -- wrap in double quotes"
       '"' + m[:identifier] + '"'
     elsif m[:trailing_comma]
       ## puts "!!! trailing comma -- remove"
       ''
     else
       match
     end
  end

  text
end
normalize_quotes( text ) click to toggle source
# File lib/json/next/parser/hanson.rb, line 40
def self.normalize_quotes( text )  ## pass 2
   text.gsub( /#{BACKTICK_ML_QUOTE}|#{SINGLE_QUOTE}|#{DOUBLE_QUOTE}/ox ) do |match|
     ## puts "match: >>#{match}<< : #{match.class.name}"

     m = Regexp.last_match
     if m[:backtick_ml_quote]
       ## puts "!!! ml_quote -- convert to double quotes"
       str = m[:backtick_ml_quote]
       str = str.gsub( /\\./ ) {|r| UNESCAPE_MAP[r] || r }
       str = str.gsub( /[\n\r\t"]/ ) { |r| ML_ESCAPE_MAP[r] }
       '"' + str + '"'
     elsif m[:single_quote]
       ## puts "!!! single_quote -- convert to double quotes"
       str = m[:single_quote]
       str = str.gsub( /\\./ ) {|r| UNESCAPE_MAP[r] || r }
       str = str.gsub( /"/, %{\\"} )
       '"' + str + '"'
     else
       match
     end
  end
end
parse( text ) click to toggle source
# File lib/json/next/parser/hanson.rb, line 97
def self.parse( text )
  JSON.parse( self.convert( text ) )
end
strip_comments( text ) click to toggle source
# File lib/json/next/parser/hanson.rb, line 27
def self.strip_comments( text )   ## pass 1
  text.gsub( /#{BACKTICK_ML_QUOTE}|#{SINGLE_QUOTE}|#{DOUBLE_QUOTE}|#{CLANG_ML_COMMENT}|#{CLANG_COMMENT}/ox ) do |match|
     ## puts "match: >>#{match}<< : #{match.class.name}"
     if match[0] == ?/    ## comments start with // or /*
       ## puts "!!! removing comments"
       ''    ## remove / strip comments
     else
       match
     end
   end
end