rouge 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile +14 -2
  3. data/lib/rouge.rb +45 -41
  4. data/lib/rouge/cli.rb +26 -2
  5. data/lib/rouge/demos/escape +3 -0
  6. data/lib/rouge/demos/supercollider +11 -0
  7. data/lib/rouge/demos/xojo +13 -0
  8. data/lib/rouge/formatter.rb +36 -0
  9. data/lib/rouge/formatters/html.rb +2 -0
  10. data/lib/rouge/formatters/html_linewise.rb +6 -11
  11. data/lib/rouge/formatters/html_table.rb +20 -31
  12. data/lib/rouge/formatters/terminal256.rb +1 -0
  13. data/lib/rouge/guessers/disambiguation.rb +13 -0
  14. data/lib/rouge/guessers/source.rb +1 -1
  15. data/lib/rouge/lexer.rb +44 -13
  16. data/lib/rouge/lexers/c.rb +6 -29
  17. data/lib/rouge/lexers/coffeescript.rb +14 -6
  18. data/lib/rouge/lexers/common_lisp.rb +1 -1
  19. data/lib/rouge/lexers/console.rb +2 -2
  20. data/lib/rouge/lexers/coq.rb +1 -1
  21. data/lib/rouge/lexers/csharp.rb +0 -1
  22. data/lib/rouge/lexers/diff.rb +8 -4
  23. data/lib/rouge/lexers/docker.rb +1 -1
  24. data/lib/rouge/lexers/escape.rb +55 -0
  25. data/lib/rouge/lexers/go.rb +1 -1
  26. data/lib/rouge/lexers/graphql.rb +10 -0
  27. data/lib/rouge/lexers/html.rb +1 -0
  28. data/lib/rouge/lexers/java.rb +4 -0
  29. data/lib/rouge/lexers/javascript.rb +12 -16
  30. data/lib/rouge/lexers/jinja.rb +15 -1
  31. data/lib/rouge/lexers/julia.rb +140 -17
  32. data/lib/rouge/lexers/kotlin.rb +11 -4
  33. data/lib/rouge/lexers/markdown.rb +21 -4
  34. data/lib/rouge/lexers/matlab.rb +9 -2
  35. data/lib/rouge/lexers/objective_c.rb +7 -12
  36. data/lib/rouge/lexers/perl.rb +38 -6
  37. data/lib/rouge/lexers/powershell.rb +1 -1
  38. data/lib/rouge/lexers/rust.rb +1 -1
  39. data/lib/rouge/lexers/scala.rb +28 -2
  40. data/lib/rouge/lexers/shell.rb +1 -1
  41. data/lib/rouge/lexers/slim.rb +2 -2
  42. data/lib/rouge/lexers/supercollider.rb +116 -0
  43. data/lib/rouge/lexers/xml.rb +1 -1
  44. data/lib/rouge/lexers/xojo.rb +61 -0
  45. data/lib/rouge/regex_lexer.rb +12 -12
  46. data/lib/rouge/themes/bw.rb +41 -0
  47. data/lib/rouge/token.rb +30 -22
  48. data/lib/rouge/version.rb +1 -1
  49. metadata +10 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 48cc6c6c6d8f17128a0b1347b6871a2553f5742d
4
- data.tar.gz: 7f0d0d895becf6c8a6f52c9e029ea4d1ccceb861
2
+ SHA256:
3
+ metadata.gz: 5794858ca2a3090f6302e34bf98115e3dd56ad8b7abe30151c304b26ff414547
4
+ data.tar.gz: e633c0de8ab7553b7873e75108a9fcd233b438fb93a19d5f317a8c3b83faf844
5
5
  SHA512:
6
- metadata.gz: 073ba0c6ed9e932fd4ab069b99b2cef3d7efcb49dd7841caa71d48ce2faf5cf645eeba1937f56e831c2856ec88f23236ef7a9795e2a453f22c6a22adc36cf47e
7
- data.tar.gz: 68e38b4636dc835270f420b884f3f71ceb2bc87d41cc0ed8d811e03e6cd28d6357977911f8e8df3e95f924fa8ddda710af1cc384fd54b7c5eb1aba61fa97438b
6
+ metadata.gz: 11f8425d849b2f5f0307942c47b99a7504cf6c560d5ae8d87371b901d44ec610cd91b616c2eb6efae6bc0ce3064e0e336b83d2c2393461075f1d14498e239fc1
7
+ data.tar.gz: d0d07ed86419b3c3b1043b1ff5fcfce7fce1da4fb1a1827edf861603e8f99b79e16b3aa4f2e0f4471eeafce8f79ff93b41cdb79d936afc68302af99fe7e82023
data/Gemfile CHANGED
@@ -4,17 +4,25 @@ source 'http://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- gem 'bundler', '~> 1.15'
8
7
  gem 'rake'
9
8
 
10
9
  gem 'minitest', '>= 5.0'
11
10
  gem 'minitest-power_assert'
12
11
 
12
+ gem 'parallel', '~> 1.13.0' if RUBY_VERSION < '2.2.0'
13
13
  gem 'rubocop', '~> 0.49.1'
14
14
 
15
15
  # don't try to install redcarpet under jruby
16
16
  gem 'redcarpet', :platforms => :ruby
17
17
 
18
+ # Profiling
19
+ if RUBY_VERSION >= '2.3.0'
20
+ gem 'memory_profiler', :require => false
21
+ end
22
+
23
+ # Needed for a Rake task
24
+ gem 'git'
25
+
18
26
  group :development do
19
27
  gem 'pry'
20
28
 
@@ -23,6 +31,10 @@ group :development do
23
31
  gem 'github-markup'
24
32
 
25
33
  # for visual tests
26
- gem 'sinatra'
34
+ if RUBY_VERSION < '2.2.0'
35
+ gem 'sinatra', '~> 1.4.8'
36
+ else
37
+ gem 'sinatra'
38
+ end
27
39
  gem 'shotgun'
28
40
  end
@@ -34,51 +34,55 @@ module Rouge
34
34
  end
35
35
  end
36
36
 
37
- load_dir = Pathname.new(__FILE__).dirname
38
- load load_dir.join('rouge/version.rb')
37
+ # mimic Kernel#require_relative API
38
+ def load_relative(path)
39
+ load File.join(__dir__, "#{path}.rb")
40
+ end
39
41
 
40
- load load_dir.join('rouge/util.rb')
42
+ def lexer_dir(path = '')
43
+ File.join(__dir__, 'rouge', 'lexers', path)
44
+ end
41
45
 
42
- load load_dir.join('rouge/text_analyzer.rb')
43
- load load_dir.join('rouge/token.rb')
46
+ load_relative 'rouge/version'
47
+ load_relative 'rouge/util'
48
+ load_relative 'rouge/text_analyzer'
49
+ load_relative 'rouge/token'
44
50
 
45
- load load_dir.join('rouge/lexer.rb')
46
- load load_dir.join('rouge/regex_lexer.rb')
47
- load load_dir.join('rouge/template_lexer.rb')
51
+ load_relative 'rouge/lexer'
52
+ load_relative 'rouge/regex_lexer'
53
+ load_relative 'rouge/template_lexer'
48
54
 
49
- lexers_dir = load_dir.join('rouge/lexers')
50
- Dir.glob(lexers_dir.join('*.rb')).each do |f|
51
- Rouge::Lexers.load_lexer(Pathname.new(f).relative_path_from(lexers_dir).to_s)
52
- end
55
+ Dir.glob(lexer_dir('*rb')).each { |f| Rouge::Lexers.load_lexer(f.sub(lexer_dir, '')) }
53
56
 
54
- load load_dir.join('rouge/guesser.rb')
55
- load load_dir.join('rouge/guessers/util.rb')
56
- load load_dir.join('rouge/guessers/glob_mapping.rb')
57
- load load_dir.join('rouge/guessers/modeline.rb')
58
- load load_dir.join('rouge/guessers/filename.rb')
59
- load load_dir.join('rouge/guessers/mimetype.rb')
60
- load load_dir.join('rouge/guessers/source.rb')
61
- load load_dir.join('rouge/guessers/disambiguation.rb')
57
+ load_relative 'rouge/guesser'
58
+ load_relative 'rouge/guessers/util'
59
+ load_relative 'rouge/guessers/glob_mapping'
60
+ load_relative 'rouge/guessers/modeline'
61
+ load_relative 'rouge/guessers/filename'
62
+ load_relative 'rouge/guessers/mimetype'
63
+ load_relative 'rouge/guessers/source'
64
+ load_relative 'rouge/guessers/disambiguation'
62
65
 
63
- load load_dir.join('rouge/formatter.rb')
64
- load load_dir.join('rouge/formatters/html.rb')
65
- load load_dir.join('rouge/formatters/html_table.rb')
66
- load load_dir.join('rouge/formatters/html_pygments.rb')
67
- load load_dir.join('rouge/formatters/html_legacy.rb')
68
- load load_dir.join('rouge/formatters/html_linewise.rb')
69
- load load_dir.join('rouge/formatters/html_inline.rb')
70
- load load_dir.join('rouge/formatters/terminal256.rb')
71
- load load_dir.join('rouge/formatters/null.rb')
66
+ load_relative 'rouge/formatter'
67
+ load_relative 'rouge/formatters/html'
68
+ load_relative 'rouge/formatters/html_table'
69
+ load_relative 'rouge/formatters/html_pygments'
70
+ load_relative 'rouge/formatters/html_legacy'
71
+ load_relative 'rouge/formatters/html_linewise'
72
+ load_relative 'rouge/formatters/html_inline'
73
+ load_relative 'rouge/formatters/terminal256'
74
+ load_relative 'rouge/formatters/null'
72
75
 
73
- load load_dir.join('rouge/theme.rb')
74
- load load_dir.join('rouge/themes/thankful_eyes.rb')
75
- load load_dir.join('rouge/themes/colorful.rb')
76
- load load_dir.join('rouge/themes/base16.rb')
77
- load load_dir.join('rouge/themes/github.rb')
78
- load load_dir.join('rouge/themes/igor_pro.rb')
79
- load load_dir.join('rouge/themes/monokai.rb')
80
- load load_dir.join('rouge/themes/molokai.rb')
81
- load load_dir.join('rouge/themes/monokai_sublime.rb')
82
- load load_dir.join('rouge/themes/gruvbox.rb')
83
- load load_dir.join('rouge/themes/tulip.rb')
84
- load load_dir.join('rouge/themes/pastie.rb')
76
+ load_relative 'rouge/theme'
77
+ load_relative 'rouge/themes/thankful_eyes'
78
+ load_relative 'rouge/themes/colorful'
79
+ load_relative 'rouge/themes/base16'
80
+ load_relative 'rouge/themes/github'
81
+ load_relative 'rouge/themes/igor_pro'
82
+ load_relative 'rouge/themes/monokai'
83
+ load_relative 'rouge/themes/molokai'
84
+ load_relative 'rouge/themes/monokai_sublime'
85
+ load_relative 'rouge/themes/gruvbox'
86
+ load_relative 'rouge/themes/tulip'
87
+ load_relative 'rouge/themes/pastie'
88
+ load_relative 'rouge/themes/bw'
@@ -186,6 +186,11 @@ module Rouge
186
186
  yield %[]
187
187
  yield %[--require|-r <filename> require a filename or library before]
188
188
  yield %[ highlighting]
189
+ yield %[]
190
+ yield %[--escape allow the use of escapes between <! and !>]
191
+ yield %[]
192
+ yield %[--escape-with <l> <r> allow the use of escapes between custom]
193
+ yield %[ delimiters. implies --escape]
189
194
  end
190
195
 
191
196
  def self.parse(argv)
@@ -218,6 +223,10 @@ module Rouge
218
223
  opts[:css_class] = argv.shift
219
224
  when '--lexer-opts', '-L'
220
225
  opts[:lexer_opts] = parse_cgi(argv.shift)
226
+ when '--escape'
227
+ opts[:escape] = ['<!', '!>']
228
+ when '--escape-with'
229
+ opts[:escape] = [argv.shift, argv.shift]
221
230
  when /^--/
222
231
  error! "unknown option #{arg.inspect}"
223
232
  else
@@ -244,11 +253,23 @@ module Rouge
244
253
  )
245
254
  end
246
255
 
256
+ def raw_lexer
257
+ lexer_class.new(@lexer_opts)
258
+ end
259
+
260
+ def escape_lexer
261
+ Rouge::Lexers::Escape.new(
262
+ start: @escape[0],
263
+ end: @escape[1],
264
+ lang: raw_lexer,
265
+ )
266
+ end
267
+
247
268
  def lexer
248
- @lexer ||= lexer_class.new(@lexer_opts)
269
+ @lexer ||= @escape ? escape_lexer : raw_lexer
249
270
  end
250
271
 
251
- attr_reader :input_file, :lexer_name, :mimetype, :formatter
272
+ attr_reader :input_file, :lexer_name, :mimetype, :formatter, :escape
252
273
 
253
274
  def initialize(opts={})
254
275
  Rouge::Lexer.enable_debug!
@@ -281,9 +302,12 @@ module Rouge
281
302
  else
282
303
  error! "unknown formatter preset #{opts[:formatter]}"
283
304
  end
305
+
306
+ @escape = opts[:escape]
284
307
  end
285
308
 
286
309
  def run
310
+ Formatter.enable_escape! if @escape
287
311
  formatter.format(lexer.lex(input), &method(:print))
288
312
  end
289
313
 
@@ -0,0 +1,3 @@
1
+ If Formatter.enable_escape! is called, this allows escaping into html
2
+ or the parent format with a special delimiter. For example:
3
+ <!<span style="text-decoration: underline">!>underlined text!<!</span>!>
@@ -0,0 +1,11 @@
1
+ // modulate a sine frequency and a noise amplitude with another sine
2
+ // whose frequency depends on the horizontal mouse pointer position
3
+ ~myFunction = {
4
+ var x = SinOsc.ar(MouseX.kr(1, 100));
5
+ SinOsc.ar(300 * x + 800, 0, 0.1)
6
+ +
7
+ PinkNoise.ar(0.1 * x + 0.1)
8
+ };
9
+
10
+ ~myFunction.play;
11
+ "that's all, folks!".postln;
@@ -0,0 +1,13 @@
1
+ Dim f As FolderItem
2
+ f = GetOpenFolderItem(FileTypes1.jpeg) // defined in the File Type Set editor
3
+ If not f.Exists Then
4
+ Beep
5
+ MsgBox("The file " + f.NativePath + "doesn't ""exist.""")
6
+ Else // document exists
7
+ ImageWell1.image=Picture.Open(f)
8
+ End If
9
+ if f isa folderitem then
10
+ msgbox(f.name)
11
+ end if
12
+ Exception err As NilObjectException
13
+ MsgBox("Invalid pathname!")
@@ -21,6 +21,26 @@ module Rouge
21
21
  REGISTRY[tag]
22
22
  end
23
23
 
24
+ def self.with_escape
25
+ Thread.current[:'rouge/with-escape'] = true
26
+ yield
27
+ ensure
28
+ Thread.current[:'rouge/with-escape'] = false
29
+ end
30
+
31
+ def self.escape_enabled?
32
+ !!(@escape_enabled || Thread.current[:'rouge/with-escape'])
33
+ end
34
+
35
+ def self.enable_escape!
36
+ @escape_enabled = true
37
+ end
38
+
39
+ def self.disable_escape!
40
+ @escape_enabled = false
41
+ Thread.current[:'rouge/with-escape'] = false
42
+ end
43
+
24
44
  # Format a token stream. Delegates to {#format}.
25
45
  def self.format(tokens, *a, &b)
26
46
  new(*a).format(tokens, &b)
@@ -30,8 +50,24 @@ module Rouge
30
50
  # pass
31
51
  end
32
52
 
53
+ def escape?(tok)
54
+ tok == Token::Tokens::Escape
55
+ end
56
+
57
+ def filter_escapes(tokens)
58
+ tokens.each do |t, v|
59
+ if t == Token::Tokens::Escape
60
+ yield Token::Tokens::Error, v
61
+ else
62
+ yield t, v
63
+ end
64
+ end
65
+ end
66
+
33
67
  # Format a token stream.
34
68
  def format(tokens, &b)
69
+ tokens = enum_for(:filter_escapes, tokens) unless Formatter.escape_enabled?
70
+
35
71
  return stream(tokens, &b) if block_given?
36
72
 
37
73
  out = String.new('')
@@ -13,6 +13,8 @@ module Rouge
13
13
  end
14
14
 
15
15
  def span(tok, val)
16
+ return val if escape?(tok)
17
+
16
18
  safe_span(tok, val.gsub(/[&<>]/, TABLE_FOR_ESCAPE_HTML))
17
19
  end
18
20
 
@@ -6,23 +6,18 @@ module Rouge
6
6
  class HTMLLinewise < Formatter
7
7
  def initialize(formatter, opts={})
8
8
  @formatter = formatter
9
+ @tag_name = opts.fetch(:tag_name, 'div')
9
10
  @class_format = opts.fetch(:class, 'line-%i')
10
11
  end
11
12
 
12
13
  def stream(tokens, &b)
13
- token_lines(tokens) do |line|
14
- yield "<div class=#{next_line_class}>"
15
- line.each do |tok, val|
16
- yield @formatter.span(tok, val)
17
- end
18
- yield '</div>'
14
+ lineno = 0
15
+ token_lines(tokens) do |line_tokens|
16
+ yield %(<#{@tag_name} class="#{sprintf @class_format, lineno += 1}">)
17
+ @formatter.stream(line_tokens) {|formatted| yield formatted }
18
+ yield %(\n</#{@tag_name}>)
19
19
  end
20
20
  end
21
-
22
- def next_line_class
23
- @lineno ||= 0
24
- sprintf(@class_format, @lineno += 1).inspect
25
- end
26
21
  end
27
22
  end
28
23
  end
@@ -16,46 +16,35 @@ module Rouge
16
16
  end
17
17
 
18
18
  def style(scope)
19
- yield "#{scope} .rouge-table { border-spacing: 0 }"
20
- yield "#{scope} .rouge-gutter { text-align: right }"
19
+ yield %(#{scope} .rouge-table { border-spacing: 0 })
20
+ yield %(#{scope} .rouge-gutter { text-align: right })
21
21
  end
22
22
 
23
23
  def stream(tokens, &b)
24
- num_lines = 0
25
- last_val = ''
26
- formatted = String.new('')
27
-
28
- tokens.each do |tok, val|
29
- last_val = val
30
- num_lines += val.scan(/\n/).size
31
- formatted << @inner.span(tok, val)
32
- end
33
-
34
- # add an extra line for non-newline-terminated strings
35
- if last_val[-1] != "\n"
24
+ last_val = nil
25
+ num_lines = tokens.reduce(0) {|count, (_, val)| count + (last_val = val).count(?\n) }
26
+ formatted = @inner.format(tokens)
27
+ unless last_val && last_val.end_with?(?\n)
36
28
  num_lines += 1
37
- @inner.span(Token::Tokens::Text::Whitespace, "\n") { |str| formatted << str }
29
+ formatted << ?\n
38
30
  end
39
31
 
40
32
  # generate a string of newline-separated line numbers for the gutter>
41
- formatted_line_numbers = (@start_line..num_lines+@start_line-1).map do |i|
42
- sprintf("#{@line_format}", i) << "\n"
43
- end.join('')
44
-
45
- numbers = %(<pre class="lineno">#{formatted_line_numbers}</pre>)
46
-
47
- yield %(<table class="#@table_class"><tbody><tr>)
33
+ formatted_line_numbers = (@start_line..(@start_line + num_lines - 1)).map do |i|
34
+ sprintf(@line_format, i)
35
+ end.join(?\n) << ?\n
48
36
 
37
+ buffer = [%(<table class="#@table_class"><tbody><tr>)]
49
38
  # the "gl" class applies the style for Generic.Lineno
50
- yield %(<td class="#@gutter_class gl">)
51
- yield numbers
52
- yield '</td>'
53
-
54
- yield %(<td class="#@code_class"><pre>)
55
- yield formatted
56
- yield '</pre></td>'
57
-
58
- yield "</tr></tbody></table>"
39
+ buffer << %(<td class="#@gutter_class gl">)
40
+ buffer << %(<pre class="lineno">#{formatted_line_numbers}</pre>)
41
+ buffer << '</td>'
42
+ buffer << %(<td class="#@code_class"><pre>)
43
+ buffer << formatted
44
+ buffer << '</pre></td>'
45
+ buffer << '</tr></tbody></table>'
46
+
47
+ yield buffer.join
59
48
  end
60
49
  end
61
50
  end
@@ -159,6 +159,7 @@ module Rouge
159
159
 
160
160
  # private
161
161
  def escape_sequence(token)
162
+ return '' if escape?(token)
162
163
  @escape_sequences ||= {}
163
164
  @escape_sequences[token.qualname] ||=
164
165
  EscapeSequence.new(get_style(token))
@@ -101,6 +101,19 @@ module Rouge
101
101
 
102
102
  Cpp
103
103
  end
104
+
105
+ disambiguate '*.plist' do
106
+ next XML if matches?(/\A<\?xml\b/)
107
+
108
+ Plist
109
+ end
110
+
111
+ disambiguate '*.sc' do
112
+ next Python if matches?(/^#/)
113
+ next SuperCollider if matches?(/(?:^~|;$)/)
114
+
115
+ next Python
116
+ end
104
117
  end
105
118
  end
106
119
  end
@@ -22,7 +22,7 @@ module Rouge
22
22
  source_text = TextAnalyzer.new(source_text)
23
23
 
24
24
  collect_best(lexers) do |lexer|
25
- next unless lexer.methods(false).include? :detect?
25
+ next unless lexer.detectable?
26
26
  lexer.detect?(source_text) ? 1 : nil
27
27
  end
28
28
  end
@@ -23,6 +23,14 @@ module Rouge
23
23
  new(opts).lex(stream, &b)
24
24
  end
25
25
 
26
+ # In case #continue_lex is called statically, we simply
27
+ # begin a new lex from the beginning, since there is no state.
28
+ #
29
+ # @see #continue_lex
30
+ def continue_lex(*a, &b)
31
+ lex(*a, &b)
32
+ end
33
+
26
34
  # Given a name in string, return the correct lexer class.
27
35
  # @param [String] name
28
36
  # @return [Class<Rouge::Lexer>,nil]
@@ -118,7 +126,7 @@ module Rouge
118
126
 
119
127
  # @return a list of all lexers.
120
128
  def all
121
- registry.values.uniq
129
+ @all ||= registry.values.uniq
122
130
  end
123
131
 
124
132
  # Guess which lexer to use based on a hash of info.
@@ -188,16 +196,24 @@ module Rouge
188
196
  end
189
197
 
190
198
  def disable_debug!
191
- @debug_enabled = false
199
+ remove_instance_variable :@debug_enabled
192
200
  end
193
201
 
194
202
  def debug_enabled?
195
- !!@debug_enabled
203
+ (defined? @debug_enabled) ? true : false
204
+ end
205
+
206
+ # Determine if a lexer has a method named +:detect?+ defined in its
207
+ # singleton class.
208
+ def detectable?
209
+ @detectable ||= methods(false).include?(:detect?)
196
210
  end
197
211
 
198
212
  protected
199
213
  # @private
200
214
  def register(name, lexer)
215
+ # reset an existing list of lexers
216
+ @all = nil if @all
201
217
  registry[name.to_s] = lexer
202
218
  end
203
219
 
@@ -236,6 +252,13 @@ module Rouge
236
252
 
237
253
  # Specify a list of filename globs associated with this lexer.
238
254
  #
255
+ # If a filename glob is associated with more than one lexer, this can
256
+ # cause a Guesser::Ambiguous error to be raised in various guessing
257
+ # methods. These errors can be avoided by disambiguation. Filename globs
258
+ # are disambiguated in one of two ways. Either the lexer will define a
259
+ # `self.detect?` method (intended for use with shebangs and doctypes) or a
260
+ # manual rule will be specified in Guessers::Disambiguation.
261
+ #
239
262
  # @example
240
263
  # class Ruby < Lexer
241
264
  # filenames '*.rb', '*.ruby', 'Gemfile', 'Rakefile'
@@ -256,7 +279,9 @@ module Rouge
256
279
 
257
280
  # @private
258
281
  def assert_utf8!(str)
259
- return if %w(US-ASCII UTF-8 ASCII-8BIT).include? str.encoding.name
282
+ encoding = str.encoding.name
283
+ return if encoding == 'US-ASCII' || encoding == 'UTF-8' || encoding == 'ASCII-8BIT'
284
+
260
285
  raise EncodingError.new(
261
286
  "Bad encoding: #{str.encoding.names.join(',')}. " +
262
287
  "Please convert your string to UTF-8."
@@ -390,15 +415,23 @@ module Rouge
390
415
 
391
416
  # Given a string, yield [token, chunk] pairs. If no block is given,
392
417
  # an enumerator is returned.
393
- #
394
- # @option opts :continue
395
- # Continue the lex from the previous state (i.e. don't call #reset!)
396
- def lex(string, opts={}, &b)
397
- return enum_for(:lex, string, opts) unless block_given?
418
+ def lex(string, opts=nil, &b)
419
+ if opts
420
+ warn 'the :continue option to Formatter#lex is deprecated, use #continue_lex instead.'
421
+ return continue_lex(string, &b)
422
+ end
423
+
424
+ return enum_for(:lex, string) unless block_given?
398
425
 
399
426
  Lexer.assert_utf8!(string)
427
+ reset!
400
428
 
401
- reset! unless opts[:continue]
429
+ continue_lex(string, &b)
430
+ end
431
+
432
+ # Continue the lex from the the current state without resetting
433
+ def continue_lex(string, &b)
434
+ return enum_for(:continue_lex, string, &b) unless block_given?
402
435
 
403
436
  # consolidate consecutive tokens of the same type
404
437
  last_token = nil
@@ -454,9 +487,7 @@ module Rouge
454
487
  def self.load_lexer(relpath)
455
488
  return if @_loaded_lexers.key?(relpath)
456
489
  @_loaded_lexers[relpath] = true
457
-
458
- root = Pathname.new(__FILE__).dirname.join('lexers')
459
- load root.join(relpath)
490
+ load File.join(__dir__, 'lexers', relpath)
460
491
  end
461
492
  end
462
493
  end