jiffy 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +13 -0
  3. data/Gemfile.lock +1 -1
  4. data/README.md +27 -28
  5. data/Rakefile +17 -0
  6. data/bin/jiffy +28 -3
  7. data/jiffy.gemspec +15 -66
  8. data/lib/jiffy.rb +27 -27
  9. data/lib/jiffy/array_mimicking_io.rb +1 -1
  10. data/lib/jiffy/outputter.rb +85 -0
  11. data/lib/jiffy/outputters/json.rb +35 -0
  12. data/lib/jiffy/outputters/ruby.rb +35 -0
  13. data/lib/jiffy/parser.rb +17 -0
  14. data/lib/jiffy/parsers/json.rb +18 -42
  15. data/lib/jiffy/parsers/json.rl +10 -22
  16. data/lib/jiffy/parsers/json_array.rb +22 -29
  17. data/lib/jiffy/parsers/json_array.rl +11 -12
  18. data/lib/jiffy/parsers/json_float.rb +39 -21
  19. data/lib/jiffy/parsers/json_float.rl +15 -7
  20. data/lib/jiffy/parsers/json_object.rb +30 -49
  21. data/lib/jiffy/parsers/json_object.rl +13 -20
  22. data/lib/jiffy/parsers/json_string.rb +70 -27
  23. data/lib/jiffy/parsers/json_string.rl +21 -6
  24. data/lib/jiffy/parsers/json_value.rb +33 -52
  25. data/lib/jiffy/parsers/json_value.rl +15 -34
  26. data/lib/jiffy/version.rb +1 -1
  27. data/test/jiffy_test.rb +261 -34
  28. data/test/outputter_test.rb +155 -0
  29. data/test/outputters/json_test.rb +22 -0
  30. metadata +9 -60
  31. data/lib/jiffy/json_outputter.rb +0 -62
  32. data/test/negative-examples/hexadecimal.json +0 -3
  33. data/test/negative-examples/infinity-value.json +0 -3
  34. data/test/negative-examples/leading-comma.json +0 -3
  35. data/test/negative-examples/leading-zero.json +0 -3
  36. data/test/negative-examples/line-break.json +0 -4
  37. data/test/negative-examples/missing-colon.json +0 -3
  38. data/test/negative-examples/nan-value,json +0 -3
  39. data/test/negative-examples/positive-float.json +0 -3
  40. data/test/negative-examples/positive-integer.json +0 -3
  41. data/test/negative-examples/single-quote.json +0 -3
  42. data/test/negative-examples/string-as-root.json +0 -1
  43. data/test/negative-examples/tab-character.json +0 -3
  44. data/test/negative-examples/trailing-array-seperator.json +0 -3
  45. data/test/negative-examples/trailing-object-seperator.json +0 -3
  46. data/test/negative-examples/true-as-root.json +0 -1
  47. data/test/negative-examples/unclosed-array.json +0 -2
  48. data/test/negative-examples/unclosed-object.json +0 -2
  49. data/test/positive-examples/array-as-root.json +0 -3
  50. data/test/positive-examples/array-nested-inside-array.json +0 -5
  51. data/test/positive-examples/array-nested-inside-object.json +0 -5
  52. data/test/positive-examples/false-value.json +0 -3
  53. data/test/positive-examples/null-value.json +0 -3
  54. data/test/positive-examples/number-1.json +0 -3
  55. data/test/positive-examples/number-10.json +0 -3
  56. data/test/positive-examples/number-11.json +0 -3
  57. data/test/positive-examples/number-12.json +0 -3
  58. data/test/positive-examples/number-13.json +0 -3
  59. data/test/positive-examples/number-14.json +0 -3
  60. data/test/positive-examples/number-15.json +0 -3
  61. data/test/positive-examples/number-16.json +0 -3
  62. data/test/positive-examples/number-17.json +0 -3
  63. data/test/positive-examples/number-18.json +0 -3
  64. data/test/positive-examples/number-19.json +0 -3
  65. data/test/positive-examples/number-2.json +0 -3
  66. data/test/positive-examples/number-20.json +0 -3
  67. data/test/positive-examples/number-3.json +0 -3
  68. data/test/positive-examples/number-4.json +0 -3
  69. data/test/positive-examples/number-5.json +0 -3
  70. data/test/positive-examples/number-6.json +0 -3
  71. data/test/positive-examples/number-7.json +0 -3
  72. data/test/positive-examples/number-8.json +0 -3
  73. data/test/positive-examples/number-9.json +0 -3
  74. data/test/positive-examples/object-as-root.json +0 -3
  75. data/test/positive-examples/object-nested-inside-array.json +0 -5
  76. data/test/positive-examples/object-nested-inside-object.json +0 -5
  77. data/test/positive-examples/seperated-array-values.json +0 -4
  78. data/test/positive-examples/seperated-object-properties.json +0 -4
  79. data/test/positive-examples/string-backspace.json +0 -3
  80. data/test/positive-examples/string-carriage-return.json +0 -3
  81. data/test/positive-examples/string-formfeed.json +0 -3
  82. data/test/positive-examples/string-horizontal-tab.json +0 -3
  83. data/test/positive-examples/string-newline.json +0 -3
  84. data/test/positive-examples/string-quotation.json +0 -3
  85. data/test/positive-examples/string-reverse-solidus.json +0 -3
  86. data/test/positive-examples/string-solidus.json +0 -3
  87. data/test/positive-examples/string-trivial.json +0 -3
  88. data/test/positive-examples/string-unicode.json +0 -3
  89. data/test/positive-examples/true-value.json +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2bc1a30ffa4bb53cb826e029643ec2572da25375
4
- data.tar.gz: a7c79105994a82bbb12d5525148d6c9696b0f921
3
+ metadata.gz: e0b24cab682865e66e57fcef137dbb16492158d5
4
+ data.tar.gz: bf680796b8fec83793ed3f781b60d2108f5cf41f
5
5
  SHA512:
6
- metadata.gz: 12374f963d089e7c772371f93aecd3f4a7959659a3b2be8e36ec2917d4c79cc20ceac0b7db78bb73083895b3b3059afcd5e9656e9667eebfc109667dd9d3ce3c
7
- data.tar.gz: 7841afcdcf39e0cb7ec6bac9499a36fa0e6924d85084afa0422b1ed0e064958552d74698bc3b334fbe7b160f9308729066d20797722c6a2bd2cca92f9762f973
6
+ metadata.gz: cd4319b4bb0d99edfed8d5836487a15759fa8800ee01edc196532a13e230b84a1311634fcadb7b21da25aff57647f49eeabb3f6ded723d9a84fe6b4b7e6c8791
7
+ data.tar.gz: 8dac509b4f86bd815a51f84b5e4a9877fdcf3d6f12b032e4d37886e6206265623a3b606fbc6a7160f534f0ad28fd96711dceaf0149e827b1e58e9638d0fec96f
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ - 2.1.1
7
+ - 2.1.2
8
+ - 2.1.3
9
+ - 2.1.4
10
+ - 2.1.5
11
+ - 2.2.0
12
+ script:
13
+ - bundle exec rake test
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jiffy (1.0.4)
4
+ jiffy (1.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -2,6 +2,8 @@ Jiffy
2
2
  =====
3
3
 
4
4
  [![Build Status](https://travis-ci.org/badeball/jiffy.png)](https://travis-ci.org/badeball/jiffy)
5
+ [![Test Coverage](https://codeclimate.com/github/badeball/jiffy/badges/coverage.svg)](https://codeclimate.com/github/badeball/jiffy)
6
+ [![Code Climate](https://codeclimate.com/github/badeball/jiffy/badges/gpa.svg)](https://codeclimate.com/github/badeball/jiffy)
5
7
 
6
8
  A streaming-based JSON formatter in Ruby that utilizes Ragel in order to parse
7
9
  and continuously format JSON data. This allows it to achieve a somewhat
@@ -34,46 +36,33 @@ $ yaourt -S ruby-jiffy
34
36
  ```ruby
35
37
  require 'jiffy'
36
38
 
37
- Jiffy.new(in: 'some.json').format
38
-
39
- # {
40
- # "menu": {
41
- # "id": "file",
42
- # "value": "File",
43
- # "popup": {
44
- # "menuitem": [
45
- # {
46
- # "value": "New",
47
- # "onclick": "CreateNewDoc()"
48
- # },
49
- # {
50
- # "value": "Open",
51
- # "onclick": "OpenDoc()"
52
- # },
53
- # {
54
- # "value": "Close",
55
- # "onclick": "CloseDoc()"
56
- # }
57
- # ]
58
- # }
59
- # }
60
- # }
39
+ Jiffy.new(in: StringIO.new('[false, true, null]')).tokenize.to_a # => [:begin_array, :false, :value_separator, :true, :value_separator, :null, :end_array]
61
40
  ```
62
41
 
63
- One can also chose to specify an IO object as input stream.
42
+ Any IO object that responds to `readpartial` can be used as an input source.
64
43
 
65
44
  ```ruby
66
- Jiffy.new(in: File.open('some.json')).format
45
+ Jiffy.new(in: File.open('some.json'))
67
46
  ```
68
47
 
69
- It is also possible to specify an IO object as output stream.
48
+ One can also chose to specify a file path instead of an IO object as input source.
49
+
50
+ ```ruby
51
+ Jiffy.new(in: 'some.json')
52
+ ```
53
+
54
+ `Jiffy#format` can be used to format the input source instead of just tokenizing it.
70
55
 
71
56
  ```ruby
72
57
  require 'stringio'
73
58
 
59
+ in = StringIO.new('[false, true, null]')
74
60
  out = StringIO.new
61
+ outputter = Jiffy::Outputters::Json.new(out: out)
75
62
 
76
- Jiffy.new(in: 'some.json', out: out).format
63
+ Jiffy.new(in: in).format(outputter: outputter)
64
+
65
+ out.string # => "[\n false,\n true,\n null\n]"
77
66
  ```
78
67
 
79
68
  ### Command line usage
@@ -94,6 +83,7 @@ $ cat incredibly-large.json | jiffy | less
94
83
 
95
84
  Tested against the following Ruby versions.
96
85
 
86
+ * 1.9.3
97
87
  * 2.0.0
98
88
  * 2.1.0
99
89
  * 2.1.1
@@ -101,9 +91,18 @@ Tested against the following Ruby versions.
101
91
  * 2.1.3
102
92
  * 2.1.4
103
93
  * 2.1.5
94
+ * 2.2.0
104
95
 
105
96
  ## Changelog
106
97
 
98
+ ### 1.1.0
99
+
100
+ * Fixing an issue where the first digit in numbers was tokenized to :char.
101
+ * Add numerous extra tokens to represent things that was previously emitted as :chars.
102
+ * Add an option to colorize output.
103
+ * Add an option to output Ruby objects instead of Json.
104
+ * Different refactorings, which unfortunately breaks API compatibility.
105
+
107
106
  ### 1.0.4
108
107
 
109
108
  * SIGPIPE is handled by exiting (with exit code 141).
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs.push 'lib'
5
+ t.test_files = FileList['test/*_test.rb']
6
+ t.verbose = true
7
+ end
8
+
9
+ desc 'Compile every parser using Ragel'
10
+
11
+ task :compile do
12
+ Dir.chdir 'lib/jiffy/parsers/' do
13
+ (Dir['*.rl'] - ['json_common.rl']).each do |parser|
14
+ system "ragel -R #{parser}"
15
+ end
16
+ end
17
+ end
data/bin/jiffy CHANGED
@@ -4,17 +4,35 @@ require 'optparse'
4
4
  require 'jiffy'
5
5
  require 'jiffy/version'
6
6
 
7
+ options = {
8
+ indent_size: 2,
9
+ outputter: "json",
10
+ color: STDOUT.tty?
11
+ }
12
+
7
13
  opts = OptionParser.new do |opts|
8
14
  opts.banner = "Usage: jiffy [options] [FILE]"
9
15
  opts.separator "Standard input is read when FILE is not present"
10
16
  opts.separator ""
11
17
 
18
+ opts.on_tail("-iSIZE", "--indent=SIZE", Integer, "how many spaces to use for indenting") do |size|
19
+ options[:indent_size] = size
20
+ end
21
+
22
+ opts.on_tail("-oNAME", "--output=NAME", ["json", "ruby"], "which format to output (json, ruby)") do |outputter|
23
+ options[:outputter] = outputter
24
+ end
25
+
26
+ opts.on_tail("-c", "--[no-]color", "colorize the output") do |color|
27
+ options[:color] = color
28
+ end
29
+
12
30
  opts.on_tail("-h", "--help", "Show this message") do
13
31
  puts opts
14
32
  exit
15
33
  end
16
34
 
17
- opts.on_tail("-v", "--version", "Print the version number of format-json") do
35
+ opts.on_tail("-v", "--version", "Print the version number of jiffy") do
18
36
  puts "jiffy #{Jiffy::VERSION}"
19
37
  exit
20
38
  end
@@ -36,10 +54,17 @@ Signal.trap("PIPE") do
36
54
  exit 141
37
55
  end
38
56
 
57
+ outputter = case options[:outputter]
58
+ when "json"
59
+ Jiffy::Outputters::Json
60
+ when "ruby"
61
+ Jiffy::Outputters::Ruby
62
+ end
63
+
39
64
  result = if ARGV.empty?
40
- Jiffy.new(in: STDIN).cl_format(err: STDERR)
65
+ Jiffy.new(in: STDIN).cl_format(outputter: outputter.new(options))
41
66
  else
42
- Jiffy.new(in: ARGF).cl_format(err: STDERR)
67
+ Jiffy.new(in: ARGF).cl_format(outputter: outputter.new(options))
43
68
  end
44
69
 
45
70
  exit 1 unless result
data/jiffy.gemspec CHANGED
@@ -16,7 +16,20 @@ Gem::Specification.new do |s|
16
16
  s.executables = 'jiffy'
17
17
 
18
18
  s.files = %w[
19
+ .travis.yml
20
+ Gemfile
21
+ Gemfile.lock
22
+ LICENSE
23
+ README.md
24
+ Rakefile
19
25
  bin/jiffy
26
+ jiffy.gemspec
27
+ lib/jiffy.rb
28
+ lib/jiffy/array_mimicking_io.rb
29
+ lib/jiffy/outputter.rb
30
+ lib/jiffy/outputters/json.rb
31
+ lib/jiffy/outputters/ruby.rb
32
+ lib/jiffy/parser.rb
20
33
  lib/jiffy/parsers/json.rb
21
34
  lib/jiffy/parsers/json.rl
22
35
  lib/jiffy/parsers/json_array.rb
@@ -30,74 +43,10 @@ Gem::Specification.new do |s|
30
43
  lib/jiffy/parsers/json_string.rl
31
44
  lib/jiffy/parsers/json_value.rb
32
45
  lib/jiffy/parsers/json_value.rl
33
- lib/jiffy/array_mimicking_io.rb
34
- lib/jiffy/json_outputter.rb
35
46
  lib/jiffy/version.rb
36
- lib/jiffy.rb
37
- test/negative-examples/hexadecimal.json
38
- test/negative-examples/infinity-value.json
39
- test/negative-examples/leading-comma.json
40
- test/negative-examples/leading-zero.json
41
- test/negative-examples/line-break.json
42
- test/negative-examples/missing-colon.json
43
- test/negative-examples/nan-value,json
44
- test/negative-examples/positive-float.json
45
- test/negative-examples/positive-integer.json
46
- test/negative-examples/single-quote.json
47
- test/negative-examples/string-as-root.json
48
- test/negative-examples/tab-character.json
49
- test/negative-examples/trailing-array-seperator.json
50
- test/negative-examples/trailing-object-seperator.json
51
- test/negative-examples/true-as-root.json
52
- test/negative-examples/unclosed-array.json
53
- test/negative-examples/unclosed-object.json
54
- test/positive-examples/array-as-root.json
55
- test/positive-examples/array-nested-inside-array.json
56
- test/positive-examples/array-nested-inside-object.json
57
- test/positive-examples/false-value.json
58
- test/positive-examples/null-value.json
59
- test/positive-examples/number-1.json
60
- test/positive-examples/number-10.json
61
- test/positive-examples/number-11.json
62
- test/positive-examples/number-12.json
63
- test/positive-examples/number-13.json
64
- test/positive-examples/number-14.json
65
- test/positive-examples/number-15.json
66
- test/positive-examples/number-16.json
67
- test/positive-examples/number-17.json
68
- test/positive-examples/number-18.json
69
- test/positive-examples/number-19.json
70
- test/positive-examples/number-2.json
71
- test/positive-examples/number-20.json
72
- test/positive-examples/number-3.json
73
- test/positive-examples/number-4.json
74
- test/positive-examples/number-5.json
75
- test/positive-examples/number-6.json
76
- test/positive-examples/number-7.json
77
- test/positive-examples/number-8.json
78
- test/positive-examples/number-9.json
79
- test/positive-examples/object-as-root.json
80
- test/positive-examples/object-nested-inside-array.json
81
- test/positive-examples/object-nested-inside-object.json
82
- test/positive-examples/seperated-array-values.json
83
- test/positive-examples/seperated-object-properties.json
84
- test/positive-examples/string-backspace.json
85
- test/positive-examples/string-carriage-return.json
86
- test/positive-examples/string-formfeed.json
87
- test/positive-examples/string-horizontal-tab.json
88
- test/positive-examples/string-newline.json
89
- test/positive-examples/string-quotation.json
90
- test/positive-examples/string-reverse-solidus.json
91
- test/positive-examples/string-solidus.json
92
- test/positive-examples/string-trivial.json
93
- test/positive-examples/string-unicode.json
94
- test/positive-examples/true-value.json
95
47
  test/jiffy_test.rb
96
- Gemfile
97
- Gemfile.lock
98
- jiffy.gemspec
99
- LICENSE
100
- README.md
48
+ test/outputter_test.rb
49
+ test/outputters/json_test.rb
101
50
  ]
102
51
 
103
52
  s.add_development_dependency('minitest')
data/lib/jiffy.rb CHANGED
@@ -1,32 +1,19 @@
1
+ require 'jiffy/array_mimicking_io'
2
+ require 'jiffy/outputter'
3
+ require 'jiffy/outputters/json'
4
+ require 'jiffy/outputters/ruby'
5
+ require 'jiffy/parser'
1
6
  require 'jiffy/parsers/json'
2
7
  require 'jiffy/parsers/json_array'
3
8
  require 'jiffy/parsers/json_float'
4
9
  require 'jiffy/parsers/json_object'
5
10
  require 'jiffy/parsers/json_string'
6
11
  require 'jiffy/parsers/json_value'
7
- require 'jiffy/array_mimicking_io'
8
- require 'jiffy/json_outputter'
9
12
 
10
13
  class Jiffy
11
14
  class UnparseableError < StandardError; end
12
15
  class UnexpectedEndError < StandardError; end
13
16
 
14
- class << self
15
- attr_accessor :json_start
16
- end
17
-
18
- prepend Parsers::Json
19
- prepend Parsers::JsonArray
20
- prepend Parsers::JsonFloat
21
- prepend Parsers::JsonObject
22
- prepend Parsers::JsonString
23
- prepend Parsers::JsonValue
24
-
25
- attr_accessor :io, :data, :outputter
26
-
27
- alias_method :o, :outputter
28
- alias_method :format, :parse_json
29
-
30
17
  def initialize(options = {})
31
18
  if options[:in].is_a?(String)
32
19
  @io = File.open(options[:in])
@@ -37,14 +24,33 @@ class Jiffy
37
24
  end
38
25
 
39
26
  @data = ArrayMimickingIO.new(@io)
27
+ end
40
28
 
41
- @outputter = JsonOutputter.new(options)
29
+ def tokenize
30
+ Enumerator.new do |yielder|
31
+ begin
32
+ parser = Parsers::Json.new(p: 0, data: @data, yielder: yielder)
33
+ parser.parse
34
+ rescue EOFError
35
+ if parser.p < @data.bytes_read || @data.bytes_read == 0
36
+ raise UnexpectedEndError, 'Unexpected end of input'
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+ def format(options = {})
43
+ enumerator = tokenize
44
+
45
+ loop do
46
+ options[:outputter].process_token *enumerator.next
47
+ end
42
48
  end
43
49
 
44
50
  def cl_format(options = {})
45
- format
51
+ format options
46
52
 
47
- @outputter.t :char, "\n"
53
+ options[:outputter].process_token :char, "\n"
48
54
 
49
55
  true
50
56
  rescue Errno::EACCES
@@ -84,10 +90,4 @@ class Jiffy
84
90
 
85
91
  false
86
92
  end
87
-
88
- private
89
-
90
- def raise_unparseable(p)
91
- raise UnparseableError, "Unexpected token at position #{p}"
92
- end
93
93
  end
@@ -29,7 +29,7 @@ class Jiffy
29
29
  end
30
30
 
31
31
  def read_chunk
32
- @chunk = @io.readpartial(CHUNK_SIZE).codepoints
32
+ @chunk = @io.readpartial(CHUNK_SIZE).each_codepoint.to_a
33
33
 
34
34
  @bytes_read += @chunk.length
35
35
  end
@@ -0,0 +1,85 @@
1
+ class Jiffy
2
+ class Outputter
3
+ class << self
4
+ attr_accessor :rules
5
+
6
+ def rule(token, options = {}, &block)
7
+ if options[:break_before] && options[:break_after]
8
+ raise ArgumentError, "Cannot specify both :break_before and :break_after"
9
+ end
10
+
11
+ options[:format] ||= block
12
+ @rules ||= {}
13
+ @rules[token] = options
14
+ end
15
+ end
16
+
17
+ COLOR_SEQUENCES = {
18
+ reset: "\e[0m",
19
+ black: "\e[0;30m",
20
+ gray: "\e[0;37m",
21
+ red: "\e[0;31m",
22
+ green: "\e[0;32m",
23
+ yellow: "\e[0;33m",
24
+ blue: "\e[0;34m",
25
+ purple: "\e[0;35m",
26
+ light_purple: "\e[38;5;174m",
27
+ cyan: "\e[0;36m",
28
+ white: "\e[0;37m"
29
+ }
30
+
31
+ attr_accessor :out, :cur_indent, :indent_size, :last_color
32
+
33
+ def initialize(options = {})
34
+ @out = options[:out] || $stdout
35
+ @color = options[:color]
36
+ @last_color = options[:last_color]
37
+ @cur_indent = options[:cur_indent] || 0
38
+ @indent_size = options[:indent_size] || 2
39
+
40
+ raise ArgumentError, "Invalid output source, must respond to #print" unless @out.respond_to? :print
41
+ raise ArgumentError, "Invalid current indent, expected fixnum" unless @cur_indent.is_a? Fixnum
42
+ raise ArgumentError, "Invalid indent size, expected fixnum" unless @indent_size.is_a? Fixnum
43
+ end
44
+
45
+ def process_token(token, payload = nil)
46
+ unless self.class.rules.has_key? token
47
+ raise ArgumentError, "No rule exists for token #{token.inspect}"
48
+ end
49
+
50
+ apply_rule self.class.rules[token], payload
51
+ end
52
+
53
+ def apply_rule(rule, payload = nil)
54
+ @cur_indent += rule[:indent] if rule[:indent]
55
+
56
+ if rule[:break_before]
57
+ @out.print "\n" << " " * @cur_indent * @indent_size
58
+ end
59
+
60
+ if @color
61
+ if rule[:color]
62
+ if @last_color.nil? || @last_color != rule[:color]
63
+ @last_color = rule[:color]
64
+ @out.print COLOR_SEQUENCES[rule[:color]]
65
+ end
66
+ elsif !@last_color.nil?
67
+ @last_color = nil
68
+ @out.print COLOR_SEQUENCES[:reset]
69
+ end
70
+ end
71
+
72
+ payload ||= rule[:payload]
73
+
74
+ if rule[:format]
75
+ @out.print rule[:format].call payload
76
+ else
77
+ @out.print payload.to_s
78
+ end
79
+
80
+ if rule[:break_after]
81
+ @out.print "\n" << " " * @cur_indent * @indent_size
82
+ end
83
+ end
84
+ end
85
+ end