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 CHANGED
@@ -8,5 +8,7 @@ gem 'wrong', '~> 0.6.2'
8
8
 
9
9
  gem 'rake'
10
10
 
11
+ gem 'redcarpet'
12
+
11
13
  # for visual tests
12
14
  gem 'sinatra'
@@ -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.is_a?(Lexer)
8
- raise "unknown lexer #{lexer_name}" unless 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
 
@@ -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
@@ -4,7 +4,7 @@ module Rouge
4
4
  tag 'text'
5
5
 
6
6
  def stream_tokens(stream, &b)
7
- yield Token['Text'], stream
7
+ yield Token['Text'], stream.string
8
8
  end
9
9
  end
10
10
  end
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Rouge
2
2
  def self.version
3
- "0.0.3"
3
+ "0.0.4"
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.0.3
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