rouge 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -0
- data/lib/rouge.rb +6 -2
- data/lib/rouge/lexer.rb +8 -0
- data/lib/rouge/lexers/tcl.rb +180 -0
- data/lib/rouge/lexers/text.rb +1 -1
- data/lib/rouge/plugins/redcarpet.rb +19 -0
- data/lib/rouge/version.rb +1 -1
- metadata +3 -1
data/Gemfile
CHANGED
data/lib/rouge.rb
CHANGED
@@ -4,8 +4,8 @@ require 'pathname'
|
|
4
4
|
module Rouge
|
5
5
|
class << self
|
6
6
|
def highlight(text, lexer, formatter)
|
7
|
-
lexer = Lexer.find(lexer) unless lexer.
|
8
|
-
raise "unknown lexer #{
|
7
|
+
lexer = Lexer.find(lexer) unless lexer.respond_to? :lex
|
8
|
+
raise "unknown lexer #{lexer}" unless lexer
|
9
9
|
|
10
10
|
formatter.render(lexer.lex(text))
|
11
11
|
end
|
@@ -17,11 +17,15 @@ load load_dir.join('rouge/token.rb')
|
|
17
17
|
load load_dir.join('rouge/lexer.rb')
|
18
18
|
load load_dir.join('rouge/lexers/text.rb')
|
19
19
|
load load_dir.join('rouge/lexers/diff.rb')
|
20
|
+
|
20
21
|
load load_dir.join('rouge/lexers/shell.rb')
|
22
|
+
|
21
23
|
load load_dir.join('rouge/lexers/javascript.rb')
|
22
24
|
load load_dir.join('rouge/lexers/css.rb')
|
23
25
|
load load_dir.join('rouge/lexers/html.rb')
|
24
26
|
|
27
|
+
load load_dir.join('rouge/lexers/tcl.rb')
|
28
|
+
|
25
29
|
load load_dir.join('rouge/formatter.rb')
|
26
30
|
load load_dir.join('rouge/formatters/html.rb')
|
27
31
|
|
data/lib/rouge/lexer.rb
CHANGED
@@ -206,6 +206,14 @@ module Rouge
|
|
206
206
|
stack.push(state.relative_state(state_name))
|
207
207
|
end
|
208
208
|
|
209
|
+
def in_state?(state_name)
|
210
|
+
stack.map(&:name).include? state_name.to_s
|
211
|
+
end
|
212
|
+
|
213
|
+
def state?(state_name)
|
214
|
+
state_name.to_s == state.name
|
215
|
+
end
|
216
|
+
|
209
217
|
delegate :debug, :lexer
|
210
218
|
|
211
219
|
delegate :[], :scanner
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Rouge
|
2
|
+
module Lexers
|
3
|
+
class TCLLexer < RegexLexer
|
4
|
+
tag 'tcl'
|
5
|
+
|
6
|
+
KEYWORDS = %w(
|
7
|
+
after apply array break catch continue elseif else error
|
8
|
+
eval expr for foreach global if namespace proc rename return
|
9
|
+
set switch then trace unset update uplevel upvar variable
|
10
|
+
vwait while
|
11
|
+
)
|
12
|
+
|
13
|
+
BUILTINS = %w(
|
14
|
+
append bgerror binary cd chan clock close concat dde dict
|
15
|
+
encoding eof exec exit fblocked fconfigure fcopy file
|
16
|
+
fileevent flush format gets glob history http incr info interp
|
17
|
+
join lappend lassign lindex linsert list llength load loadTk
|
18
|
+
lrange lrepeat lreplace lreverse lsearch lset lsort mathfunc
|
19
|
+
mathop memory msgcat open package pid pkg::create pkg_mkIndex
|
20
|
+
platform platform::shell puts pwd re_syntax read refchan
|
21
|
+
regexp registry regsub scan seek socket source split string
|
22
|
+
subst tell time tm unknown unload
|
23
|
+
)
|
24
|
+
|
25
|
+
OPEN = %w| \( \[ \{ " |
|
26
|
+
CLOSE = %w| \) \] \} |
|
27
|
+
ALL = OPEN + CLOSE
|
28
|
+
END_LINE = CLOSE + %w(; \n)
|
29
|
+
END_WORD = END_LINE + %w(\s)
|
30
|
+
|
31
|
+
CHARS = lambda { |list| Regexp.new %/[#{list.join}]/ }
|
32
|
+
NOT_CHARS = lambda { |list| Regexp.new %/[^#{list.join}]/ }
|
33
|
+
|
34
|
+
state :word do
|
35
|
+
rule /\{\*\}/, 'Keyword'
|
36
|
+
|
37
|
+
mixin :brace_abort
|
38
|
+
mixin :interp
|
39
|
+
rule /\{/, 'Punctuation', :brace
|
40
|
+
rule /\(/, 'Punctuation', :paren
|
41
|
+
rule /"/, 'Literal.String.Double', :string
|
42
|
+
rule /#{NOT_CHARS[END_WORD]}+?(?=#{CHARS[OPEN+['\\\\']]})/, 'Text'
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.gen_command_state(name='')
|
46
|
+
state(:"command#{name}") do
|
47
|
+
mixin :word
|
48
|
+
|
49
|
+
rule /##{NOT_CHARS[END_LINE]}+/, 'Comment.Single'
|
50
|
+
|
51
|
+
rule /(?=#{CHARS[END_WORD]})/ do
|
52
|
+
push :"params#{name}"
|
53
|
+
end
|
54
|
+
|
55
|
+
rule /#{NOT_CHARS[END_WORD]}+/ do |m|
|
56
|
+
if KEYWORDS.include? m[0]
|
57
|
+
token 'Keyword'
|
58
|
+
elsif BUILTINS.include? m[0]
|
59
|
+
token 'Name.Builtin'
|
60
|
+
else
|
61
|
+
token 'Text'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
mixin :whitespace
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.gen_delimiter_states(name, close, opts={})
|
70
|
+
gen_command_state("_in_#{name}")
|
71
|
+
|
72
|
+
state :"params_in_#{name}" do
|
73
|
+
rule close do
|
74
|
+
token 'Punctuation'
|
75
|
+
pop!; pop!
|
76
|
+
end
|
77
|
+
|
78
|
+
# mismatched delimiters. Braced strings with mismatched
|
79
|
+
# closing delimiters should be okay, since this is standard
|
80
|
+
# practice, like {]]]]}
|
81
|
+
if opts[:strict]
|
82
|
+
rule CHARS[CLOSE - [close]], 'Error'
|
83
|
+
else
|
84
|
+
rule CHARS[CLOSE - [close]], 'Text'
|
85
|
+
end
|
86
|
+
|
87
|
+
mixin :params
|
88
|
+
end
|
89
|
+
|
90
|
+
state name do
|
91
|
+
rule close, 'Punctuation', :pop!
|
92
|
+
mixin :"command_in_#{name}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
# tcl is freaking impossible. If we're in braces and we encounter
|
98
|
+
# a close brace, we have to drop everything and close the brace.
|
99
|
+
# This is so silly things like {abc"def} and {abc]def} don't b0rk
|
100
|
+
# everything after them.
|
101
|
+
|
102
|
+
# TODO: TCL seems to have this aborting behavior quite a lot.
|
103
|
+
# such things as [ abc" ] are a runtime error, but will still
|
104
|
+
# parse. Currently something like this will muck up the lex.
|
105
|
+
state :brace_abort do
|
106
|
+
rule /}/ do
|
107
|
+
if in_state? :brace
|
108
|
+
pop! until state? :brace
|
109
|
+
pop!
|
110
|
+
token 'Punctuation'
|
111
|
+
else
|
112
|
+
token 'Error'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
state :params do
|
118
|
+
rule /;/, 'Punctuation', :pop!
|
119
|
+
rule /\n/, 'Text', :pop!
|
120
|
+
rule /else|elseif|then/, 'Keyword'
|
121
|
+
mixin :word
|
122
|
+
mixin :whitespace
|
123
|
+
rule /#{NOT_CHARS[END_WORD]}+/, 'Text'
|
124
|
+
end
|
125
|
+
|
126
|
+
gen_delimiter_states :brace, /\}/, :strict => false
|
127
|
+
gen_delimiter_states :paren, /\)/, :strict => true
|
128
|
+
gen_delimiter_states :bracket, /\]/, :strict => true
|
129
|
+
gen_command_state
|
130
|
+
|
131
|
+
state :root do
|
132
|
+
mixin :command
|
133
|
+
end
|
134
|
+
|
135
|
+
state :whitespace do
|
136
|
+
# not a multiline regex because we want to capture \n sometimes
|
137
|
+
rule /\s+/, 'Text'
|
138
|
+
end
|
139
|
+
|
140
|
+
state :interp do
|
141
|
+
rule /\[/, 'Punctuation', :bracket
|
142
|
+
rule /\$[a-z0-9.:-]+/, 'Name.Variable'
|
143
|
+
rule /\$\{.*?\}/m, 'Name.Variable'
|
144
|
+
rule /\$/, 'Text'
|
145
|
+
|
146
|
+
# escape sequences
|
147
|
+
rule /\\[0-7]{3}/, 'Literal.String.Escape'
|
148
|
+
rule /\\x[0-9a-f]{2}/i, 'Literal.String.Escape'
|
149
|
+
rule /\\u[0-9a-f]{4}/i, 'Literal.String.Escape'
|
150
|
+
rule /\\./m, 'Literal.String.Escape'
|
151
|
+
end
|
152
|
+
|
153
|
+
state :string do
|
154
|
+
rule /"/, 'Literal.String.Double', :pop!
|
155
|
+
mixin :interp
|
156
|
+
rule /[^\\\[\$"{}]+/m, 'Literal.String.Double'
|
157
|
+
|
158
|
+
# strings have to keep count of their internal braces, to support
|
159
|
+
# for example { "{ }" }.
|
160
|
+
rule /{/ do
|
161
|
+
@brace_count ||= 0
|
162
|
+
@brace_count += 1
|
163
|
+
|
164
|
+
token 'Literal.String.Double'
|
165
|
+
end
|
166
|
+
|
167
|
+
rule /}/ do
|
168
|
+
if in_state? :brace and @brace_count.to_i == 0
|
169
|
+
pop! until state? :brace
|
170
|
+
pop!
|
171
|
+
token 'Punctuation'
|
172
|
+
else
|
173
|
+
@brace_count -= 1
|
174
|
+
token 'Literal.String.Double'
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/lib/rouge/lexers/text.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
# this file is not require'd from the root. To use this plugin, run:
|
2
|
+
#
|
3
|
+
# require 'rouge/plugins/redcarpet'
|
4
|
+
|
5
|
+
# this plugin depends on redcarpet
|
6
|
+
require 'redcarpet'
|
7
|
+
|
8
|
+
module Rouge
|
9
|
+
module Plugins
|
10
|
+
module Redcarpet
|
11
|
+
def block_code(code, language)
|
12
|
+
lexer = Lexer.find(language) || Lexers::Text
|
13
|
+
formatter = Formatters::HTML.new(:css_class => "highlight #{lexer.tag}")
|
14
|
+
|
15
|
+
Rouge.highlight(code, lexer, formatter)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
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.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -24,7 +24,9 @@ files:
|
|
24
24
|
- lib/rouge/lexers/diff.rb
|
25
25
|
- lib/rouge/lexers/text.rb
|
26
26
|
- lib/rouge/lexers/html.rb
|
27
|
+
- lib/rouge/lexers/tcl.rb
|
27
28
|
- lib/rouge/lexers/css.rb
|
29
|
+
- lib/rouge/plugins/redcarpet.rb
|
28
30
|
- lib/rouge/themes/thankful_eyes.rb
|
29
31
|
- lib/rouge/themes/colorful.rb
|
30
32
|
- lib/rouge/token.rb
|