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.
- checksums.yaml +4 -4
- data/.travis.yml +13 -0
- data/Gemfile.lock +1 -1
- data/README.md +27 -28
- data/Rakefile +17 -0
- data/bin/jiffy +28 -3
- data/jiffy.gemspec +15 -66
- data/lib/jiffy.rb +27 -27
- data/lib/jiffy/array_mimicking_io.rb +1 -1
- data/lib/jiffy/outputter.rb +85 -0
- data/lib/jiffy/outputters/json.rb +35 -0
- data/lib/jiffy/outputters/ruby.rb +35 -0
- data/lib/jiffy/parser.rb +17 -0
- data/lib/jiffy/parsers/json.rb +18 -42
- data/lib/jiffy/parsers/json.rl +10 -22
- data/lib/jiffy/parsers/json_array.rb +22 -29
- data/lib/jiffy/parsers/json_array.rl +11 -12
- data/lib/jiffy/parsers/json_float.rb +39 -21
- data/lib/jiffy/parsers/json_float.rl +15 -7
- data/lib/jiffy/parsers/json_object.rb +30 -49
- data/lib/jiffy/parsers/json_object.rl +13 -20
- data/lib/jiffy/parsers/json_string.rb +70 -27
- data/lib/jiffy/parsers/json_string.rl +21 -6
- data/lib/jiffy/parsers/json_value.rb +33 -52
- data/lib/jiffy/parsers/json_value.rl +15 -34
- data/lib/jiffy/version.rb +1 -1
- data/test/jiffy_test.rb +261 -34
- data/test/outputter_test.rb +155 -0
- data/test/outputters/json_test.rb +22 -0
- metadata +9 -60
- data/lib/jiffy/json_outputter.rb +0 -62
- data/test/negative-examples/hexadecimal.json +0 -3
- data/test/negative-examples/infinity-value.json +0 -3
- data/test/negative-examples/leading-comma.json +0 -3
- data/test/negative-examples/leading-zero.json +0 -3
- data/test/negative-examples/line-break.json +0 -4
- data/test/negative-examples/missing-colon.json +0 -3
- data/test/negative-examples/nan-value,json +0 -3
- data/test/negative-examples/positive-float.json +0 -3
- data/test/negative-examples/positive-integer.json +0 -3
- data/test/negative-examples/single-quote.json +0 -3
- data/test/negative-examples/string-as-root.json +0 -1
- data/test/negative-examples/tab-character.json +0 -3
- data/test/negative-examples/trailing-array-seperator.json +0 -3
- data/test/negative-examples/trailing-object-seperator.json +0 -3
- data/test/negative-examples/true-as-root.json +0 -1
- data/test/negative-examples/unclosed-array.json +0 -2
- data/test/negative-examples/unclosed-object.json +0 -2
- data/test/positive-examples/array-as-root.json +0 -3
- data/test/positive-examples/array-nested-inside-array.json +0 -5
- data/test/positive-examples/array-nested-inside-object.json +0 -5
- data/test/positive-examples/false-value.json +0 -3
- data/test/positive-examples/null-value.json +0 -3
- data/test/positive-examples/number-1.json +0 -3
- data/test/positive-examples/number-10.json +0 -3
- data/test/positive-examples/number-11.json +0 -3
- data/test/positive-examples/number-12.json +0 -3
- data/test/positive-examples/number-13.json +0 -3
- data/test/positive-examples/number-14.json +0 -3
- data/test/positive-examples/number-15.json +0 -3
- data/test/positive-examples/number-16.json +0 -3
- data/test/positive-examples/number-17.json +0 -3
- data/test/positive-examples/number-18.json +0 -3
- data/test/positive-examples/number-19.json +0 -3
- data/test/positive-examples/number-2.json +0 -3
- data/test/positive-examples/number-20.json +0 -3
- data/test/positive-examples/number-3.json +0 -3
- data/test/positive-examples/number-4.json +0 -3
- data/test/positive-examples/number-5.json +0 -3
- data/test/positive-examples/number-6.json +0 -3
- data/test/positive-examples/number-7.json +0 -3
- data/test/positive-examples/number-8.json +0 -3
- data/test/positive-examples/number-9.json +0 -3
- data/test/positive-examples/object-as-root.json +0 -3
- data/test/positive-examples/object-nested-inside-array.json +0 -5
- data/test/positive-examples/object-nested-inside-object.json +0 -5
- data/test/positive-examples/seperated-array-values.json +0 -4
- data/test/positive-examples/seperated-object-properties.json +0 -4
- data/test/positive-examples/string-backspace.json +0 -3
- data/test/positive-examples/string-carriage-return.json +0 -3
- data/test/positive-examples/string-formfeed.json +0 -3
- data/test/positive-examples/string-horizontal-tab.json +0 -3
- data/test/positive-examples/string-newline.json +0 -3
- data/test/positive-examples/string-quotation.json +0 -3
- data/test/positive-examples/string-reverse-solidus.json +0 -3
- data/test/positive-examples/string-solidus.json +0 -3
- data/test/positive-examples/string-trivial.json +0 -3
- data/test/positive-examples/string-unicode.json +0 -3
- data/test/positive-examples/true-value.json +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e0b24cab682865e66e57fcef137dbb16492158d5
|
4
|
+
data.tar.gz: bf680796b8fec83793ed3f781b60d2108f5cf41f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd4319b4bb0d99edfed8d5836487a15759fa8800ee01edc196532a13e230b84a1311634fcadb7b21da25aff57647f49eeabb3f6ded723d9a84fe6b4b7e6c8791
|
7
|
+
data.tar.gz: 8dac509b4f86bd815a51f84b5e4a9877fdcf3d6f12b032e4d37886e6206265623a3b606fbc6a7160f534f0ad28fd96711dceaf0149e827b1e58e9638d0fec96f
|
data/.travis.yml
ADDED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,8 @@ Jiffy
|
|
2
2
|
=====
|
3
3
|
|
4
4
|
[](https://travis-ci.org/badeball/jiffy)
|
5
|
+
[](https://codeclimate.com/github/badeball/jiffy)
|
6
|
+
[](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:
|
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
|
-
|
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'))
|
45
|
+
Jiffy.new(in: File.open('some.json'))
|
67
46
|
```
|
68
47
|
|
69
|
-
|
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:
|
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
|
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(
|
65
|
+
Jiffy.new(in: STDIN).cl_format(outputter: outputter.new(options))
|
41
66
|
else
|
42
|
-
Jiffy.new(in: ARGF).cl_format(
|
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
|
-
|
97
|
-
|
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
|
-
|
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
|
-
|
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
|
@@ -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
|