rouge 0.0.3 → 0.0.4
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/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
|