rouge 0.2.8 → 0.2.9

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.
data/Gemfile CHANGED
@@ -3,7 +3,6 @@ source 'http://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'minitest'
6
- gem 'sexp_processor', '~> 3.0'
7
6
  gem 'wrong', '~> 0.6.2'
8
7
 
9
8
  gem 'rake'
@@ -1,16 +1,27 @@
1
1
  # stdlib
2
2
  require 'pathname'
3
3
 
4
+ # The containing module for Rouge
4
5
  module Rouge
5
6
  class << self
6
- def highlight(text, lexer, formatter)
7
+ # Highlight some text with a given lexer and formatter.
8
+ #
9
+ # @example
10
+ # Rouge.highlight('@foo = 1', 'ruby', 'html')
11
+ # Rouge.highlight('var foo = 1;', 'js', 'terminal256')
12
+ #
13
+ # # streaming - chunks become available as they are lexed
14
+ # Rouge.highlight(large_string, 'ruby', 'html') do |chunk|
15
+ # $stdout.print chunk
16
+ # end
17
+ def highlight(text, lexer, formatter, &b)
7
18
  lexer = Lexer.find(lexer) unless lexer.respond_to? :lex
8
19
  raise "unknown lexer #{lexer}" unless lexer
9
20
 
10
21
  formatter = Formatter.find(formatter) unless formatter.respond_to? :format
11
22
  raise "unknown formatter #{formatter}" unless formatter
12
23
 
13
- formatter.format(lexer.lex(text))
24
+ formatter.format(lexer.lex(text), &b)
14
25
  end
15
26
  end
16
27
  end
@@ -38,6 +49,9 @@ load load_dir.join('rouge/lexers/sql.rb')
38
49
  load load_dir.join('rouge/lexers/make.rb')
39
50
  load load_dir.join('rouge/lexers/shell.rb')
40
51
  load load_dir.join('rouge/lexers/viml.rb')
52
+ load load_dir.join('rouge/lexers/nginx.rb')
53
+ load load_dir.join('rouge/lexers/conf.rb')
54
+ load load_dir.join('rouge/lexers/sed.rb')
41
55
 
42
56
  load load_dir.join('rouge/lexers/javascript.rb')
43
57
  load load_dir.join('rouge/lexers/css.rb')
@@ -60,6 +74,7 @@ load load_dir.join('rouge/lexers/perl.rb')
60
74
  load load_dir.join('rouge/lexers/factor.rb')
61
75
  load load_dir.join('rouge/lexers/clojure.rb')
62
76
  load load_dir.join('rouge/lexers/groovy.rb')
77
+ load load_dir.join('rouge/lexers/io.rb')
63
78
 
64
79
  load load_dir.join('rouge/lexers/haskell.rb')
65
80
  load load_dir.join('rouge/lexers/scheme.rb')
@@ -60,7 +60,7 @@ module Rouge
60
60
  formatter = formatter_class.new(normalize_hash_keys(options[:formatter_opts]))
61
61
  lexer = lexer_class.new(normalize_hash_keys(options[:lexer_opts]))
62
62
 
63
- puts Rouge.highlight(source, lexer, formatter)
63
+ formatter.format(lexer.lex(source), &method(:print))
64
64
  end
65
65
 
66
66
  desc 'style THEME', 'render THEME as css'
@@ -69,7 +69,7 @@ module Rouge
69
69
  theme = Theme.find(theme_name)
70
70
  raise "unknown theme: #{theme_name}" unless theme
71
71
 
72
- puts theme.new(options).render
72
+ theme.new(options).render(&method(:puts))
73
73
  end
74
74
 
75
75
  desc 'list', 'list the available lexers, formatters, and styles'
@@ -0,0 +1,4 @@
1
+ # A generic configuration file
2
+ option1 "val1"
3
+ option2 23
4
+ option3 'val3'
@@ -0,0 +1,11 @@
1
+ bottle := method(i,
2
+ if(i==0, return "no more bottles of beer")
3
+ if(i==1, return "1 bottle of beer")
4
+ return i asString .. " bottles of beer"
5
+ )
6
+
7
+ for(i, 99, 1, -1,
8
+ write(bottle(i), " on the wall, ", bottle(i), ",\n")
9
+ write("take one down, pass it around,\n")
10
+ write(bottle(i - 1), " on the wall.\n\n")
11
+ )
@@ -0,0 +1,4 @@
1
+ /begin/,/end/ {
2
+ /begin/n # skip over the line that has "begin" on it
3
+ s/old/new/
4
+ }
@@ -19,13 +19,18 @@ module Rouge
19
19
  end
20
20
 
21
21
  # Format a token stream. Delegates to {#format}.
22
- def self.format(tokens, opts={})
23
- new(opts).format(tokens)
22
+ def self.format(tokens, opts={}, &b)
23
+ new(opts).format(tokens, &b)
24
24
  end
25
25
 
26
26
  # Format a token stream.
27
- def format(tokens)
28
- enum_for(:stream, tokens).to_a.join
27
+ def format(tokens, &b)
28
+ return stream(tokens, &b) if block_given?
29
+
30
+ out = ''
31
+ stream(tokens) { |piece| out << piece }
32
+
33
+ out
29
34
  end
30
35
 
31
36
  # @deprecated Use {#format} instead.
@@ -73,7 +73,7 @@ module Rouge
73
73
  when ''
74
74
  yield val
75
75
  when nil
76
- raise "unknown token: #{tok.inspect}"
76
+ raise "unknown token: #{tok.inspect} for #{val.inspect}"
77
77
  else
78
78
  yield '<span class='
79
79
  yield tok.shortname.inspect
@@ -265,13 +265,9 @@ module Rouge
265
265
  # be changed once it has begun lexing. This method will redefine
266
266
  # itself on the first call to a noop if "debug" is not set.
267
267
  if option(:debug)
268
- class << self
269
- def debug; puts yield; end
270
- end
268
+ def self.debug; puts yield; end
271
269
  else
272
- class << self
273
- def debug; end
274
- end
270
+ def self.debug; end
275
271
  end
276
272
 
277
273
  debug(&b)
@@ -299,7 +295,7 @@ module Rouge
299
295
  # consolidate consecutive tokens of the same type
300
296
  last_token = nil
301
297
  last_val = nil
302
- stream_tokens(StringScanner.new(string)) do |tok, val|
298
+ stream_tokens(string) do |tok, val|
303
299
  next if val.empty?
304
300
 
305
301
  if tok == last_token
@@ -0,0 +1,21 @@
1
+ module Rouge
2
+ module Lexers
3
+ class Conf < RegexLexer
4
+ tag 'conf'
5
+ aliases 'config', 'configuration'
6
+
7
+ desc 'A generic lexer for configuration files'
8
+ filenames '*.conf', '*.config'
9
+
10
+ # short and sweet
11
+ state :root do
12
+ rule /#.*?\n/, 'Comment'
13
+ rule /".*?"/, 'Literal.String.Double'
14
+ rule /'.*?'/, 'Literal.String.Single'
15
+ rule /[a-z]\w*/i, 'Name'
16
+ rule /\d+/, 'Literal.Number'
17
+ rule /[^\d\w#"']+/, 'Text'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,65 @@
1
+ module Rouge
2
+ module Lexers
3
+ class IO < RegexLexer
4
+ tag 'io'
5
+ desc 'The IO programming language (http://iolanguage.com)'
6
+ mimetypes 'text/x-iosrc'
7
+ filenames '*.io'
8
+
9
+ def self.analyze_text(text)
10
+ return 1 if text.shebang? 'io'
11
+ end
12
+
13
+ def self.constants
14
+ @constants ||= Set.new %w(nil false true)
15
+ end
16
+
17
+ def self.builtins
18
+ @builtins ||= Set.new %w(
19
+ args call clone do doFile doString else elseif for if list
20
+ method return super then
21
+ )
22
+ end
23
+
24
+ state :root do
25
+ rule /\s+/m, 'Text'
26
+ rule %r(//.*?\n), 'Comment.Single'
27
+ rule %r(#.*?\n), 'Comment.Single'
28
+ rule %r(/(\\\n)?[*].*?[*](\\\n)?/)m, 'Comment.Multiline'
29
+ rule %r(/[+]), 'Comment.Multiline', :nested_comment
30
+
31
+ rule /"(\\\\|\\"|[^"])*"/, 'Literal.String'
32
+
33
+ rule %r(:?:=), 'Keyword'
34
+ rule /[()]/, 'Punctuation'
35
+
36
+ rule %r([-=;,*+><!/|^.%&\[\]{}]), 'Operator'
37
+
38
+ rule /[A-Z]\w*/, 'Name.Class'
39
+
40
+ rule /[a-z_]\w*/ do |m|
41
+ name = m[0]
42
+
43
+ if self.class.constants.include? name
44
+ token 'Keyword.Constant'
45
+ elsif self.class.builtins.include? name
46
+ token 'Name.Builtin'
47
+ else
48
+ token 'Name'
49
+ end
50
+ end
51
+
52
+ rule %r((\d+[.]?\d*|\d*[.]\d+)(e[+-]?[0-9]+)?)i, 'Literal.Number.Float'
53
+ rule /\d+/, 'Literal.Number.Integer'
54
+
55
+ rule /@@?/, 'Keyword'
56
+ end
57
+
58
+ state :nested_comment do
59
+ rule %r([^/+]+)m, 'Comment.Multiline'
60
+ rule %r(/[+]), 'Comment.Multiline', :nested_comment
61
+ rule %r([+]/), 'Comment.Multiline', :pop!
62
+ end
63
+ end
64
+ end
65
+ end
@@ -3,6 +3,7 @@ module Rouge
3
3
  class Nginx < RegexLexer
4
4
  tag 'nginx'
5
5
  mimetypes 'text/x-nginx-conf'
6
+ filenames 'nginx.conf'
6
7
 
7
8
  id = /[^\s$;{}()#]+/
8
9
 
@@ -55,7 +55,7 @@ module Rouge
55
55
  rule %r({(\\\\|\\}|[^}])*}[egimosx]*), re_tok, :pop!
56
56
  rule %r(<(\\\\|\\>|[^>])*>[egimosx]*), re_tok, :pop!
57
57
  rule %r(\[(\\\\|\\\]|[^\]])*\][egimosx]*), re_tok, :pop!
58
- rule %r(\((\\\\|\\\)|[^\)])*\)[egimosx]*), re_tok, :pop!
58
+ rule %r[\((\\\\|\\\)|[^\)])*\)[egimosx]*], re_tok, :pop!
59
59
  rule %r(@(\\\\|\\\@|[^\@])*@[egimosx]*), re_tok, :pop!
60
60
  rule %r(%(\\\\|\\\%|[^\%])*%[egimosx]*), re_tok, :pop!
61
61
  rule %r(\$(\\\\|\\\$|[^\$])*\$[egimosx]*), re_tok, :pop!
@@ -87,7 +87,7 @@ module Rouge
87
87
  rule %r(s{(\\\\|\\}|[^}])*}\s*), re_tok, :balanced_regex
88
88
  rule %r(s<(\\\\|\\>|[^>])*>\s*), re_tok, :balanced_regex
89
89
  rule %r(s\[(\\\\|\\\]|[^\]])*\]\s*), re_tok, :balanced_regex
90
- rule %r(s\((\\\\|\\\)|[^\)])*\)\s*), re_tok, :balanced_regex
90
+ rule %r[s\((\\\\|\\\)|[^\)])*\)\s*], re_tok, :balanced_regex
91
91
 
92
92
  rule %r(m?/(\\\\|\\/|[^/\n])*/[gcimosx]*), re_tok
93
93
  rule %r(m(?=[/!\\{<\[\(@%\$])), re_tok, :balanced_regex
@@ -135,7 +135,10 @@ module Rouge
135
135
  end
136
136
 
137
137
  state :root do
138
+ rule /\n\s*/m, 'Text', :expr_start
139
+ rule /\s+/, 'Text' # NB: NOT /m
138
140
  rule /#.*$/, 'Comment.Single'
141
+
139
142
  rule %r(=begin\b.*?end\b)m, 'Comment.Multiline'
140
143
  rule /(?:#{keywords.join('|')})\b/, 'Keyword', :expr_start
141
144
  rule /(?:#{keywords_pseudo.join('|')})\b/, 'Keyword.Pseudo', :expr_start
@@ -194,8 +197,6 @@ module Rouge
194
197
  rule /[-+\/*%=<>&!^|~]=?/, 'Operator', :expr_start
195
198
  rule %r<[({,?:\\;/]>, 'Punctuation', :expr_start
196
199
  rule %r<[)}]>, 'Punctuation'
197
- rule /\n\s*/m, 'Text', :expr_start
198
- rule /\s+/, 'Text' # NB: NOT /m
199
200
  end
200
201
 
201
202
  state :has_heredocs do
@@ -1,21 +1,166 @@
1
1
  module Rouge
2
2
  module Lexers
3
- class Sed < Lexer
4
- # TODO: add rules for this
5
- class Regex < TextLexer
6
- default_option :token, 'Literal.String.Regex'
3
+ class Sed < RegexLexer
4
+ desc 'sed, the ultimate stream editor'
5
+
6
+ tag 'sed'
7
+ filenames '*.sed'
8
+ mimetypes 'text/x-sed'
9
+
10
+ def self.analyze_text(text)
11
+ return 1 if text.shebang? 'sed'
7
12
  end
8
13
 
9
- state :root do
14
+ class Regex < RegexLexer
15
+ state :root do
16
+ rule /\\./, 'Literal.String.Escape'
17
+ rule /\[/, 'Punctuation', :brackets
18
+ rule /[$^.*]/, 'Operator'
19
+ rule /[()]/, 'Punctuation'
20
+ rule /./, 'Literal.String.Regex'
21
+ end
22
+
23
+ state :brackets do
24
+ rule /\^?/ do
25
+ token 'Punctuation'
26
+ pop!; push :brackets_int
27
+ end
28
+ end
29
+
30
+ state :brackets_int do
31
+ # ranges
32
+ rule /.-./, 'Name.Variable'
33
+ rule /\]/, 'Punctuation', :pop!
34
+ rule /./, 'Literal.String.Regex'
35
+ end
36
+ end
37
+
38
+ class Replacement < RegexLexer
39
+ state :root do
40
+ rule /\\./m, 'Literal.String.Escape'
41
+ rule /&/, 'Operator'
42
+ rule /[^\\&]+/m, 'Text'
43
+ end
44
+ end
45
+
46
+ def regex
47
+ @regex ||= Regex.new(options)
48
+ end
49
+
50
+ def replacement
51
+ @replacement ||= Replacement.new(options)
52
+ end
53
+
54
+ start { regex.reset!; replacement.reset! }
55
+
56
+ state :whitespace do
10
57
  rule /\s+/m, 'Text'
11
- rule /#.*?\n/, 'Comment'
58
+ rule(/#.*?\n/) { token 'Comment'; reset_stack }
59
+ rule(/\n/) { token 'Text'; reset_stack }
60
+ rule(/;/) { token 'Punctuation'; reset_stack }
61
+ end
62
+
63
+ state :root do
64
+ mixin :addr_range
65
+ end
66
+
67
+ edot = /\\.|./m
68
+
69
+ state :command do
70
+ mixin :whitespace
71
+
72
+ # subst and transliteration
73
+ rule /(s)(.)(#{edot}*?)(\2)(#{edot}*?)(\2)/m do |m|
74
+ token 'Keyword', m[1]
75
+ token 'Punctuation', m[2]
76
+ delegate regex, m[3]
77
+ token 'Punctuation', m[4]
78
+ delegate replacement, m[5]
79
+ token 'Punctuation', m[6]
80
+
81
+
82
+ pop!; push :flags
83
+ end
84
+
85
+ rule /(y)(.)(#{edot}*?)(\2)(#{edot}*?)(\2)/m do |m|
86
+ token 'Keyword', m[1]
87
+ token 'Punctuation', m[2]
88
+ delegate replacement, m[3]
89
+ token 'Punctuation', m[4]
90
+ delegate replacement, m[5]
91
+ token 'Punctuation', m[6]
92
+
93
+ pop!
94
+ end
95
+
96
+ # commands that take a text segment as an argument
97
+ rule /([aic])(\s*)/ do
98
+ group 'Keyword'; group 'Text'; pop!; push :text
99
+ end
100
+
101
+ rule /[pd]/, 'Keyword'
12
102
 
13
- rule /s(.)(\\.|.*?)(\1)/ do
14
- token re_tok
15
- push :flags
16
- push :subst
17
- push :regex
103
+ # commands that take a number argument
104
+ rule /([qQl])(\s+)(\d+)/i do
105
+ group 'Keyword'; group 'Text'; group 'Literal.Number'
106
+ pop!
18
107
  end
108
+
109
+ # no-argument commands
110
+ rule /[={}dDgGhHlnpPqx]/, 'Keyword', :pop!
111
+
112
+ # commands that take a filename argument
113
+ rule /([rRwW])(\s+)(\S+)/ do
114
+ group 'Keyword'; group 'Text'; group 'Name'
115
+ pop!
116
+ end
117
+
118
+ # commands that take a label argument
119
+ rule /([:btT])(\s+)(\S+)/ do
120
+ group 'Keyword'; group 'Text'; group 'Name.Label'
121
+ pop!
122
+ end
123
+ end
124
+
125
+ state :addr_range do
126
+ mixin :whitespace
127
+
128
+ ### address ranges ###
129
+ addr_tok = 'Keyword.Namespace'
130
+ rule /\d+/, addr_tok
131
+ rule /[$,~+!]/, addr_tok
132
+
133
+ rule %r((/)(\\.|.)*?(/)) do |m|
134
+ token addr_tok, m[1]; delegate regex, m[2]; token addr_tok, m[3]
135
+ end
136
+
137
+ # alternate regex rage delimiters
138
+ rule %r((\\)(.)(\\.|.)*?(\2)) do |m|
139
+ token addr_tok, m[1] + m[2]
140
+ delegate regex, m[3]
141
+ token addr_tok, m[4]
142
+ end
143
+
144
+ rule(//) { push :command }
145
+ end
146
+
147
+ state :text do
148
+ rule /[^\\\n]+/, 'Literal.String'
149
+ rule /\\\n/, 'Literal.String.Escape'
150
+ rule /\\/, 'Literal.String'
151
+ rule /\n/, 'Text', :pop!
152
+ end
153
+
154
+ state :flags do
155
+ rule /[gp]+/, 'Keyword', :pop!
156
+
157
+ # writing to a file with the subst command.
158
+ # who'da thunk...?
159
+ rule /([wW])(\s+)(\S+)/ do
160
+ token 'Keyword'; token 'Text'; token 'Name'
161
+ end
162
+
163
+ rule(//) { pop! }
19
164
  end
20
165
  end
21
166
  end
@@ -72,6 +72,7 @@ module Rouge
72
72
  end
73
73
 
74
74
  state :data do
75
+ rule /\s+/, 'Text'
75
76
  rule /\\./, 'Literal.String.Escape'
76
77
  rule /\$?"/, 'Literal.String.Double', :double_quotes
77
78
 
@@ -85,9 +86,8 @@ module Rouge
85
86
  rule /\*/, 'Keyword'
86
87
 
87
88
  rule /;/, 'Text'
88
- rule /\s+/, 'Text'
89
89
  rule /[^=\*\s{}()$"\'`\\<]+/, 'Text'
90
- rule /\d+(?= |\Z)/, 'Number'
90
+ rule /\d+(?= |\Z)/, 'Literal.Number'
91
91
  rule /</, 'Text'
92
92
  mixin :interp
93
93
  end
@@ -108,7 +108,7 @@ module Rouge
108
108
  state :math do
109
109
  rule /\)\)/, 'Keyword', :pop!
110
110
  rule %r([-+*/%^|&]|\*\*|\|\|), 'Operator'
111
- rule /\d+/, 'Number'
111
+ rule /\d+/, 'Literal.Number'
112
112
  mixin :root
113
113
  end
114
114
 
@@ -13,8 +13,8 @@ module Rouge
13
13
  @token ||= Token[option :token]
14
14
  end
15
15
 
16
- def stream_tokens(stream, &b)
17
- yield self.token, stream.string
16
+ def stream_tokens(string, &b)
17
+ yield self.token, string
18
18
  end
19
19
  end
20
20
  end
@@ -183,7 +183,9 @@ module Rouge
183
183
  # is consumed with an `'Error'` token, and we continue at (1.)
184
184
  #
185
185
  # @see #step #step (where (2.) is implemented)
186
- def stream_tokens(stream, &b)
186
+ def stream_tokens(str, &b)
187
+ stream = StringScanner.new(str)
188
+
187
189
  until stream.eos?
188
190
  debug { "lexer: #{self.class.tag}" }
189
191
  debug { "stack: #{stack.map(&:name).inspect}" }
@@ -354,7 +356,7 @@ module Rouge
354
356
  private
355
357
  def with_output_stream(output_stream, &b)
356
358
  old_output_stream = @output_stream
357
- @output_stream = Yielder.new do |tok, val|
359
+ @output_stream = Enumerator::Yielder.new do |tok, val|
358
360
  debug { " yielding #{tok.to_s.inspect}, #{val.inspect}" }
359
361
  output_stream.call(Token[tok], val)
360
362
  end
@@ -1,14 +1,4 @@
1
1
  module Rouge
2
- class Yielder
3
- def initialize(&pr)
4
- @proc = pr
5
- end
6
-
7
- def <<(*a)
8
- @proc && @proc.call(*a)
9
- end
10
- end
11
-
12
2
  class InheritableHash < Hash
13
3
  def initialize(parent=nil)
14
4
  @parent = parent
@@ -1,5 +1,5 @@
1
1
  module Rouge
2
2
  def self.version
3
- "0.2.8"
3
+ "0.2.9"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rouge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.8
4
+ version: 0.2.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-30 00:00:00.000000000 Z
12
+ date: 2012-11-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -42,6 +42,7 @@ files:
42
42
  - lib/rouge/lexers/sql.rb
43
43
  - lib/rouge/lexers/common_lisp.rb
44
44
  - lib/rouge/lexers/erb.rb
45
+ - lib/rouge/lexers/conf.rb
45
46
  - lib/rouge/lexers/scheme.rb
46
47
  - lib/rouge/lexers/clojure.rb
47
48
  - lib/rouge/lexers/xml.rb
@@ -53,6 +54,7 @@ files:
53
54
  - lib/rouge/lexers/perl.rb
54
55
  - lib/rouge/lexers/javascript.rb
55
56
  - lib/rouge/lexers/diff.rb
57
+ - lib/rouge/lexers/io.rb
56
58
  - lib/rouge/lexers/viml.rb
57
59
  - lib/rouge/lexers/objective_c.rb
58
60
  - lib/rouge/lexers/smalltalk.rb
@@ -109,6 +111,7 @@ files:
109
111
  - lib/rouge/demos/scheme
110
112
  - lib/rouge/demos/diff
111
113
  - lib/rouge/demos/markdown
114
+ - lib/rouge/demos/io
112
115
  - lib/rouge/demos/javascript
113
116
  - lib/rouge/demos/json
114
117
  - lib/rouge/demos/css
@@ -116,10 +119,12 @@ files:
116
119
  - lib/rouge/demos/php
117
120
  - lib/rouge/demos/shell
118
121
  - lib/rouge/demos/make
122
+ - lib/rouge/demos/sed
119
123
  - lib/rouge/demos/java
120
124
  - lib/rouge/demos/yaml
121
125
  - lib/rouge/demos/sql
122
126
  - lib/rouge/demos/groovy
127
+ - lib/rouge/demos/conf
123
128
  - lib/rouge/demos/nginx
124
129
  - lib/rouge/demos/tcl
125
130
  - lib/rouge/demos/c