rouge 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
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