rouge 0.2.5 → 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -64,6 +64,7 @@ module Rouge
64
64
  end
65
65
 
66
66
  desc 'style THEME', 'render THEME as css'
67
+ option :scope, :desc => "a css selector to scope the styles to"
67
68
  def style(theme_name='thankful_eyes')
68
69
  theme = Theme.find(theme_name)
69
70
  raise "unknown theme: #{theme_name}" unless theme
@@ -11,30 +11,74 @@ module Rouge
11
11
  # A css class to be used for the generated <pre> tag.
12
12
  def initialize(opts={})
13
13
  @css_class = opts[:css_class] || 'highlight'
14
+ @line_numbers = opts.fetch(:line_numbers) { false }
14
15
  end
15
16
 
16
17
  # @yield the html output.
17
18
  def stream(tokens, &b)
19
+ if @line_numbers
20
+ stream_tableized(tokens, &b)
21
+ else
22
+ stream_untableized(tokens, &b)
23
+ end
24
+ end
25
+
26
+ def stream_untableized(tokens, &b)
18
27
  yield "<pre class=#{@css_class.inspect}>"
19
28
  tokens.each do |tok, val|
20
- # TODO: properly html-encode val
21
- val = CGI.escape_html(val)
22
-
23
- case tok.shortname
24
- when ''
25
- yield val
26
- when nil
27
- raise "unknown token: #{tok.inspect}"
28
- else
29
- yield '<span class='
30
- yield tok.shortname.inspect
31
- yield '>'
32
- yield val
33
- yield '</span>'
34
- end
29
+ span(tok, val, &b)
35
30
  end
36
31
  yield '</pre>'
37
32
  end
33
+
34
+ def stream_tableized(tokens, &b)
35
+ num_lines = 0
36
+ code = ''
37
+
38
+ tokens.each do |tok, val|
39
+ num_lines += val.scan(/\n/).size
40
+ span(tok, val) { |str| code << str }
41
+ end
42
+
43
+ # generate a string of newline-separated line numbers for the gutter
44
+ numbers = num_lines.times.map do |x|
45
+ %<<div class="lineno">#{x+1}</div>>
46
+ end.join
47
+
48
+ yield "<pre class=#{@css_class.inspect}>"
49
+ yield "<table><tbody><tr>"
50
+
51
+ # the "gl" class applies the style for Generic.Lineno
52
+ yield '<td class="gutter gl">'
53
+ yield numbers
54
+ yield '</td>'
55
+
56
+ yield '<td class="code">'
57
+ yield code
58
+ yield '</td>'
59
+
60
+ yield '</tr></tbody></table>'
61
+ yield '</pre>'
62
+ end
63
+
64
+ private
65
+ def span(tok, val, &b)
66
+ # TODO: properly html-encode val
67
+ val = CGI.escape_html(val)
68
+
69
+ case tok.shortname
70
+ when ''
71
+ yield val
72
+ when nil
73
+ raise "unknown token: #{tok.inspect}"
74
+ else
75
+ yield '<span class='
76
+ yield tok.shortname.inspect
77
+ yield '>'
78
+ yield val
79
+ yield '</span>'
80
+ end
81
+ end
38
82
  end
39
83
  end
40
84
  end
@@ -259,7 +259,9 @@ module Rouge
259
259
  # @example
260
260
  # debug { "hello, world!" }
261
261
  def debug(&b)
262
- puts(b.call) if option :debug
262
+ @debug = option(:debug) unless instance_variable_defined?(:@debug)
263
+
264
+ puts(b.call) if @debug
263
265
  end
264
266
 
265
267
  # @abstract
@@ -36,7 +36,6 @@ module Rouge
36
36
  end
37
37
 
38
38
  id = /[$a-zA-Z_][a-zA-Z0-9_]*/
39
- lval = /@?#{id}([.]#{id})*/
40
39
 
41
40
  state :comments_and_whitespace do
42
41
  rule /\s+/m, 'Text'
@@ -45,7 +44,11 @@ module Rouge
45
44
  end
46
45
 
47
46
  state :multiline_regex do
47
+ # this order is important, so that #{ isn't interpreted
48
+ # as a comment
49
+ mixin :has_interpolation
48
50
  mixin :comments_and_whitespace
51
+
49
52
  rule %r(///([gim]+\b|\B)), 'Literal.String.Regex', :pop!
50
53
  rule %r(/), 'Literal.String.Regex'
51
54
  rule %r([^/#]+), 'Literal.String.Regex'
@@ -90,7 +93,19 @@ module Rouge
90
93
 
91
94
  rule /#{id}(?=\s*:)/, 'Name.Attribute', :slash_starts_regex
92
95
 
93
- rule /#{id}/, 'Name.Other', :slash_starts_regex
96
+ rule /#{id}/ do |m|
97
+ if self.class.keywords.include? m[0]
98
+ token 'Keyword'
99
+ elsif self.class.constants.include? m[0]
100
+ token 'Name.Constant'
101
+ elsif self.class.builtins.include? m[0]
102
+ token 'Name.Builtin'
103
+ else
104
+ token 'Name.Other'
105
+ end
106
+
107
+ push :slash_starts_regex
108
+ end
94
109
 
95
110
  rule /[{(\[;,]/, 'Punctuation', :slash_starts_regex
96
111
  rule /[})\].]/, 'Punctuation'
@@ -153,24 +168,6 @@ module Rouge
153
168
  rule /'/, 'Literal.String'
154
169
  mixin :single_strings
155
170
  end
156
-
157
- postprocess 'Name' do |tok, val|
158
- if tok.name == 'Name.Attribute'
159
- if self.class.keywords.include? val
160
- tok = 'Error' # keywords as attributes = nono
161
- else
162
- # pass. leave attributes alone.
163
- end
164
- elsif self.class.keywords.include? val
165
- tok = 'Keyword'
166
- elsif self.class.constants.include? val
167
- tok = 'Name.Constant'
168
- elsif self.class.builtins.include? val
169
- tok = 'Name.Builtin'
170
- end
171
-
172
- token tok, val
173
- end
174
171
  end
175
172
  end
176
173
  end
@@ -0,0 +1,22 @@
1
+ module Rouge
2
+ module Lexers
3
+ class Sed < Lexer
4
+ # TODO: add rules for this
5
+ class Regex < TextLexer
6
+ default_option :token, 'Literal.String.Regex'
7
+ end
8
+
9
+ state :root do
10
+ rule /\s+/m, 'Text'
11
+ rule /#.*?\n/, 'Comment'
12
+
13
+ rule /s(.)(\\.|.*?)(\1)/ do
14
+ token re_tok
15
+ push :flags
16
+ push :subst
17
+ push :regex
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -15,6 +15,16 @@ module Rouge
15
15
  @callback = callback
16
16
  end
17
17
 
18
+ # Does the regex start with a ^?
19
+ #
20
+ # Since Regexps are immuntable, this is cached to avoid
21
+ # calling Regexp#source more than once.
22
+ def beginning_of_line?
23
+ return @beginning_of_line if instance_variable_defined?(:@beginning_of_line)
24
+
25
+ @beginning_of_line = re.source[0] == ?^
26
+ end
27
+
18
28
  def inspect
19
29
  "#<Rule #{@re.inspect}>"
20
30
  end
@@ -246,6 +256,13 @@ module Rouge
246
256
  res
247
257
  when Rule
248
258
  debug { " trying #{rule.inspect}" }
259
+ # XXX HACK XXX
260
+ # StringScanner's implementation of ^ is b0rken.
261
+ # see http://bugs.ruby-lang.org/issues/7092
262
+ # TODO: this doesn't cover cases like /(a|^b)/, but it's
263
+ # the most common, for now...
264
+ return false if rule.beginning_of_line? && !stream.beginning_of_line?
265
+
249
266
  scan(stream, rule.re) do
250
267
  debug { " got #{stream[0].inspect}" }
251
268
 
@@ -270,12 +287,6 @@ module Rouge
270
287
 
271
288
  # @private
272
289
  def scan(scanner, re, &b)
273
- # XXX HACK XXX
274
- # StringScanner's implementation of ^ is b0rken.
275
- # TODO: this doesn't cover cases like /(a|^b)/, but it's
276
- # the most common, for now...
277
- return false if re.source[0] == ?^ && !scanner.beginning_of_line?
278
-
279
290
  @null_steps ||= 0
280
291
 
281
292
  if @null_steps >= MAX_NULL_SCANS
@@ -398,3 +409,6 @@ module Rouge
398
409
  end
399
410
  end
400
411
  end
412
+
413
+ class Regexp
414
+ end
@@ -132,6 +132,11 @@ module Rouge
132
132
  def render(&b)
133
133
  return enum_for(:render).to_a.join("\n") unless b
134
134
 
135
+ # shared styles for tableized line numbers
136
+ yield "#{@scope} table { border-spacing: 0; }"
137
+ yield "#{@scope} table td { padding: 5px; }"
138
+ yield "#{@scope} table .gutter { text-align: right; }"
139
+
135
140
  styles.each do |tokname, style|
136
141
  style.render(css_selector(Token[tokname]), &b)
137
142
  end
@@ -21,6 +21,7 @@ module Rouge
21
21
  palette :schrill => '#ffb000'
22
22
 
23
23
  style 'Text', :fg => :unicorn, :bg => :krasna
24
+ style 'Generic.Lineno', :fg => :eggshell_cloud, :bg => :slate_blue
24
25
 
25
26
  style 'Comment', :fg => :cool_as_ice, :italic => true
26
27
  style 'Comment.Preproc', :fg => :go_get_it, :bold => true, :italic => true
@@ -176,5 +176,7 @@ module Rouge
176
176
  token 'Generic.Strong', 'gs'
177
177
  token 'Generic.Subheading', 'gu'
178
178
  token 'Generic.Traceback', 'gt'
179
+
180
+ token 'Generic.Lineno', 'gl'
179
181
  end
180
182
  end
@@ -1,5 +1,5 @@
1
1
  module Rouge
2
2
  def self.version
3
- "0.2.5"
3
+ "0.2.6"
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.5
4
+ version: 0.2.6
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-20 00:00:00.000000000 Z
12
+ date: 2012-10-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -57,6 +57,7 @@ files:
57
57
  - lib/rouge/lexers/php/builtins.rb
58
58
  - lib/rouge/lexers/haskell.rb
59
59
  - lib/rouge/lexers/c.rb
60
+ - lib/rouge/lexers/sed.rb
60
61
  - lib/rouge/lexers/handlebars.rb
61
62
  - lib/rouge/lexers/tex.rb
62
63
  - lib/rouge/lexers/text.rb