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.
- data/lib/rouge/cli.rb +1 -0
- data/lib/rouge/formatters/html.rb +59 -15
- data/lib/rouge/lexer.rb +3 -1
- data/lib/rouge/lexers/coffeescript.rb +17 -20
- data/lib/rouge/lexers/sed.rb +22 -0
- data/lib/rouge/regex_lexer.rb +20 -6
- data/lib/rouge/theme.rb +5 -0
- data/lib/rouge/themes/thankful_eyes.rb +1 -0
- data/lib/rouge/token.rb +2 -0
- data/lib/rouge/version.rb +1 -1
- metadata +3 -2
data/lib/rouge/cli.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/rouge/lexer.rb
CHANGED
@@ -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}
|
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
|
data/lib/rouge/regex_lexer.rb
CHANGED
@@ -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
|
data/lib/rouge/theme.rb
CHANGED
@@ -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
|
data/lib/rouge/token.rb
CHANGED
data/lib/rouge/version.rb
CHANGED
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.
|
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-
|
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
|