Module: HANSON

Defined in:
lib/json/next/parser/hanson.rb

Constant Summary collapse

BACKTICK_ML_QUOTE =
JSON::Next::BACKTICK_ML_QUOTE
SINGLE_QUOTE =
JSON::Next::SINGLE_QUOTE
DOUBLE_QUOTE =
JSON::Next::DOUBLE_QUOTE
CLANG_ML_COMMENT =
JSON::Next::CLANG_ML_COMMENT
CLANG_COMMENT =
JSON::Next::CLANG_COMMENT
KEYWORDS =
JSON::Next::KEYWORDS
IDENTIFIER =
JSON::Next::IDENTIFIER
TRAILING_COMMA =
JSON::Next::TRAILING_COMMA
UNESCAPE_MAP =
JSON::Next::UNESCAPE_MAP
ML_ESCAPE_MAP =
JSON::Next::ML_ESCAPE_MAP

Class Method Summary collapse

Class Method Details

.convert(text) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 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) ⇒ Object

pass 2



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 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) ⇒ Object



97
98
99
# File 'lib/json/next/parser/hanson.rb', line 97

def self.parse( text )
  JSON.parse( self.convert( text ) )
end

.strip_comments(text) ⇒ Object

pass 1



27
28
29
30
31
32
33
34
35
36
37
# 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