rouge 0.2.5 → 0.2.6

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.
@@ -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