nanoc 4.7.6 → 4.7.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/NEWS.md +7 -0
  4. data/lib/nanoc/base/entities/identifiable_collection.rb +8 -8
  5. data/lib/nanoc/base/entities/outdatedness_reasons.rb +0 -5
  6. data/lib/nanoc/base/repos/dependency_store.rb +23 -9
  7. data/lib/nanoc/base/services/compiler/stages/preprocess.rb +2 -1
  8. data/lib/nanoc/base/services/compiler_loader.rb +1 -1
  9. data/lib/nanoc/base/services/outdatedness_checker.rb +0 -1
  10. data/lib/nanoc/base/services/outdatedness_rules.rb +0 -1
  11. data/lib/nanoc/cli/commands/compile.rb +1 -0
  12. data/lib/nanoc/cli/commands/compile_listeners/diff_generator.rb +1 -1
  13. data/lib/nanoc/filters/colorize_syntax.rb +54 -316
  14. data/lib/nanoc/filters/colorize_syntax/colorizers.rb +177 -0
  15. data/lib/nanoc/version.rb +1 -1
  16. data/spec/nanoc/base/compiler_spec.rb +5 -2
  17. data/spec/nanoc/base/entities/identifiable_collection_spec.rb +29 -0
  18. data/spec/nanoc/base/repos/dependency_store_spec.rb +79 -79
  19. data/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb +5 -2
  20. data/spec/nanoc/base/services/dependency_tracker_spec.rb +7 -1
  21. data/spec/nanoc/base/services/outdatedness_checker_spec.rb +6 -7
  22. data/spec/nanoc/base/services/outdatedness_rules_spec.rb +3 -56
  23. data/spec/nanoc/base/views/document_view_spec.rb +7 -1
  24. data/spec/nanoc/base/views/item_rep_view_spec.rb +7 -1
  25. data/spec/nanoc/base/views/item_view_spec.rb +7 -1
  26. data/spec/nanoc/cli/commands/compile/diff_generator_spec.rb +44 -0
  27. data/spec/nanoc/cli/commands/show_data_spec.rb +1 -5
  28. data/spec/nanoc/integration/compile_command_spec.rb +31 -0
  29. data/test/base/test_dependency_tracker.rb +106 -86
  30. data/test/filters/test_xsl.rb +5 -1
  31. metadata +5 -3
  32. data/lib/nanoc/base/services/outdatedness_rules/paths_modified.rb +0 -20
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a40c3389c6ef42f0924566370507dfc3a2e361f8
4
- data.tar.gz: '09906841a6aa6ba7dc5d4bdc06e5914a4678d274'
3
+ metadata.gz: d25ba882d1c709e130d1da34de63b5bee85ffaa2
4
+ data.tar.gz: 6e3c673ec2c5b30a25edb775f42197813899cabf
5
5
  SHA512:
6
- metadata.gz: 91221955a35dfd5786f068f6fca88f6c3d2ee06cc9ece04e85aedd769c5d66147aec8d37c663c1dcc2e208ce32c38d0939a78d1539dd963f3380fe427d76d854
7
- data.tar.gz: 4ef5eac2bd6d99bbeb5c1276fa13dd498f7cf8e70cce12132945ff682cf90a02a8d11c459bb88300934fd1686f61c6c069a371c196ca51f605516c7454017c89
6
+ metadata.gz: 914fde5a0e842055cabfa804950d3b355f3b03b33b3a72cddbd1654aa4e9233163848386b728e2ce08238de98311d2af31305e874bc421549ac858acb310b73b
7
+ data.tar.gz: 2727ef6a9f49eedec58419971d324ce73a50dad71776ff1e303d7a50567b7a47881e4acb8be100cb095bbea68a4a6540da768aedfaaa29f7c05e63fd8732347f
@@ -1,6 +1,6 @@
1
1
  GIT
2
2
  remote: https://github.com/bbatsov/rubocop.git
3
- revision: cf07b9a493feed28577032c307ddab3cb7b8c2fc
3
+ revision: dcb3f160a2e23218a7826aadd0e64baefd6d7521
4
4
  specs:
5
5
  rubocop (0.48.1)
6
6
  parallel (~> 1.10)
@@ -13,7 +13,7 @@ GIT
13
13
  PATH
14
14
  remote: .
15
15
  specs:
16
- nanoc (4.7.6)
16
+ nanoc (4.7.7)
17
17
  cri (~> 2.8)
18
18
  ddplugin (~> 1.0)
19
19
  hamster (~> 3.0)
data/NEWS.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Nanoc news
2
2
 
3
+ ## 4.7.7 (2017-04-16)
4
+
5
+ Enhancements:
6
+
7
+ * Added `--diff` option to `compile` command as a one-time alternative to `enable_output_diff` (#1155)
8
+ * Sped up incremental compilation (#1156, #1157)
9
+
3
10
  ## 4.7.6 (2017-04-15)
4
11
 
5
12
  Enhancements:
@@ -64,6 +64,14 @@ module Nanoc::Int
64
64
  self.class.new(@config, @objects.reject(&block))
65
65
  end
66
66
 
67
+ def object_with_identifier(identifier)
68
+ if frozen?
69
+ @mapping[identifier.to_s]
70
+ else
71
+ @objects.find { |i| i.identifier == identifier }
72
+ end
73
+ end
74
+
67
75
  protected
68
76
 
69
77
  contract C::Any => C::Maybe[C::RespondTo[:identifier]]
@@ -96,14 +104,6 @@ module Nanoc::Int
96
104
  find_all_unmemoized(arg)
97
105
  end
98
106
 
99
- def object_with_identifier(identifier)
100
- if frozen?
101
- @mapping[identifier.to_s]
102
- else
103
- @objects.find { |i| i.identifier == identifier }
104
- end
105
- end
106
-
107
107
  def object_matching_glob(glob)
108
108
  if use_globs?
109
109
  pat = Nanoc::Int::Pattern.from(glob)
@@ -62,11 +62,6 @@ module Nanoc::Int
62
62
  end
63
63
  end
64
64
 
65
- PathsModified = Generic.new(
66
- 'One or more output paths of this item have been modified since the last time the site was compiled.',
67
- Props.new(path: true),
68
- )
69
-
70
65
  UsesAlwaysOutdatedFilter = Generic.new(
71
66
  'This item rep uses one or more filters that cannot track dependencies, and will thus always be considered as outdated.',
72
67
  Props.new(raw_content: true, attributes: true, compiled_content: true),
@@ -3,16 +3,17 @@ module Nanoc::Int
3
3
  class DependencyStore < ::Nanoc::Int::Store
4
4
  include Nanoc::Int::ContractsSupport
5
5
 
6
- # @return [Array<Nanoc::Int::Item, Nanoc::Int::Layout>]
7
- attr_accessor :objects
6
+ attr_accessor :items
7
+ attr_accessor :layouts
8
8
 
9
- # @param [Array<Nanoc::Int::Item, Nanoc::Int::Layout>] objects
10
- def initialize(objects, site: nil)
9
+ def initialize(items, layouts, site: nil)
11
10
  super(Nanoc::Int::Store.tmp_path_for(site: site, store_name: 'dependencies'), 4)
12
11
 
13
- @objects = objects
12
+ @items = items
13
+ @layouts = layouts
14
+
14
15
  @new_objects = []
15
- @graph = Nanoc::Int::DirectedGraph.new([nil] + @objects)
16
+ @graph = Nanoc::Int::DirectedGraph.new([nil] + @items.to_a + @layouts.to_a)
16
17
  end
17
18
 
18
19
  contract C::Or[Nanoc::Int::Item, Nanoc::Int::ItemRep, Nanoc::Int::Layout] => C::ArrayOf[Nanoc::Int::Dependency]
@@ -113,12 +114,25 @@ module Nanoc::Int
113
114
  end
114
115
 
115
116
  def data=(new_data)
117
+ objects = @items.to_a + @layouts.to_a
118
+
116
119
  # Create new graph
117
- @graph = Nanoc::Int::DirectedGraph.new([nil] + @objects)
120
+ @graph = Nanoc::Int::DirectedGraph.new([nil] + objects)
118
121
 
119
122
  # Load vertices
120
123
  previous_objects = new_data[:vertices].map do |reference|
121
- @objects.find { |obj| reference == obj.reference }
124
+ if reference
125
+ case reference[0]
126
+ when :item
127
+ @items.object_with_identifier(reference[1])
128
+ when :layout
129
+ @layouts.object_with_identifier(reference[1])
130
+ else
131
+ raise Nanoc::Int::Errors::InternalInconsistency, "unrecognised reference #{reference[0].inspect}"
132
+ end
133
+ else
134
+ nil
135
+ end
122
136
  end
123
137
 
124
138
  # Load edges
@@ -130,7 +144,7 @@ module Nanoc::Int
130
144
  end
131
145
 
132
146
  # Record dependency from all items on new items
133
- @new_objects = @objects - previous_objects
147
+ @new_objects = objects - previous_objects
134
148
  end
135
149
  end
136
150
  end
@@ -12,7 +12,8 @@ module Nanoc::Int::Compiler::Stages
12
12
  @site.data_source = Nanoc::Int::InMemDataSource.new(@site.items, @site.layouts)
13
13
  @action_provider.preprocess(@site)
14
14
 
15
- @dependency_store.objects = @site.items.to_a + @site.layouts.to_a
15
+ @dependency_store.items = @site.items
16
+ @dependency_store.layouts = @site.layouts
16
17
  @checksum_store.objects = @site.items.to_a + @site.layouts.to_a + @site.code_snippets + [@site.config]
17
18
  end
18
19
 
@@ -5,7 +5,7 @@ module Nanoc::Int
5
5
  action_sequence_store = Nanoc::Int::ActionSequenceStore.new(site: site)
6
6
 
7
7
  dependency_store =
8
- Nanoc::Int::DependencyStore.new(site.items.to_a + site.layouts.to_a, site: site)
8
+ Nanoc::Int::DependencyStore.new(site.items, site.layouts, site: site)
9
9
 
10
10
  objects = site.items.to_a + site.layouts.to_a + site.code_snippets + [site.config]
11
11
 
@@ -13,7 +13,6 @@ module Nanoc::Int
13
13
  RULES_FOR_ITEM_REP =
14
14
  [
15
15
  Rules::RulesModified,
16
- Rules::PathsModified,
17
16
  Rules::ContentModified,
18
17
  Rules::AttributesModified,
19
18
  Rules::NotWritten,
@@ -9,6 +9,5 @@ require_relative 'outdatedness_rules/code_snippets_modified'
9
9
  require_relative 'outdatedness_rules/configuration_modified'
10
10
  require_relative 'outdatedness_rules/content_modified'
11
11
  require_relative 'outdatedness_rules/not_written'
12
- require_relative 'outdatedness_rules/paths_modified'
13
12
  require_relative 'outdatedness_rules/rules_modified'
14
13
  require_relative 'outdatedness_rules/uses_always_outdated_filter'
@@ -4,6 +4,7 @@ description <<-EOS
4
4
  Compile all items of the current site.
5
5
  EOS
6
6
  flag nil, :profile, 'profile compilation' if Nanoc::Feature.enabled?(Nanoc::Feature::PROFILER)
7
+ flag nil, :diff, 'generate diff'
7
8
 
8
9
  require_relative 'compile_listeners/abstract'
9
10
  require_relative 'compile_listeners/debug_printer'
@@ -2,7 +2,7 @@ module Nanoc::CLI::Commands::CompileListeners
2
2
  class DiffGenerator < Abstract
3
3
  # @see Listener#enable_for?
4
4
  def self.enable_for?(command_runner)
5
- command_runner.site.config[:enable_output_diff]
5
+ command_runner.site.config[:enable_output_diff] || command_runner.options[:diff]
6
6
  end
7
7
 
8
8
  # @see Listener#start
@@ -5,92 +5,14 @@ module Nanoc::Filters
5
5
 
6
6
  requires 'nokogiri', 'stringio', 'open3'
7
7
 
8
- # The default colorizer to use for a language if the colorizer for that
9
- # language is not overridden.
10
8
  DEFAULT_COLORIZER = :coderay
11
9
 
12
- # Syntax-highlights code blocks in the given content. Code blocks should
13
- # be enclosed in `pre` elements that contain a `code` element. The code
14
- # element should have an indication of the language the code is in. There
15
- # are two possible ways of adding such an indication:
16
- #
17
- # 1. A HTML class starting with `language-` and followed by the
18
- # code language, as specified by HTML5. For example, `<code class="language-ruby">`.
19
- #
20
- # 2. A comment on the very first line of the code block in the format
21
- # `#!language` where `language` is the language the code is in. For
22
- # example, `#!ruby`.
23
- #
24
- # Options for individual colorizers will be taken from the {#run}
25
- # options’ value for the given colorizer. For example, if the filter is
26
- # invoked with a `:coderay => coderay_options_hash` option, the
27
- # `coderay_options_hash` hash will be passed to the CodeRay colorizer.
28
- #
29
- # Currently, the following colorizers are supported:
30
- #
31
- # * `:coderay` for [Coderay](http://coderay.rubychan.de/)
32
- # * `:pygmentize` for [pygmentize](http://pygments.org/docs/cmdline/), the
33
- # command-line frontend for [Pygments](http://pygments.org/)
34
- # * `:pygmentsrb` for [pygments.rb](https://github.com/tmm1/pygments.rb),
35
- # a Ruby interface for [Pygments](http://pygments.org/)
36
- # * `:simon_highlight` for [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html)
37
- # * `:rouge` for [Rouge](https://github.com/jayferd/rouge/)
38
- #
39
- # Additional colorizer implementations are welcome!
40
- #
41
- # @example Using a class to indicate type of code be highlighted
42
- #
43
- # <pre><code class="language-ruby">
44
- # def foo
45
- # "asdf"
46
- # end
47
- # </code></pre>
48
- #
49
- # @example Using a comment to indicate type of code be highlighted
50
- #
51
- # <pre><code>
52
- # #!ruby
53
- # def foo
54
- # "asdf"
55
- # end
56
- # </code></pre>
57
- #
58
- # @example Invoking the filter with custom parameters
59
- #
60
- # filter :colorize_syntax,
61
- # :colorizers => { :ruby => :coderay },
62
- # :coderay => { :line_numbers => :list }
63
- #
64
- # @param [String] content The content to filter
65
- #
66
- # @option params [Symbol] :default_colorizer (DEFAULT_COLORIZER) The
67
- # default colorizer, i.e. the colorizer that will be used when the
68
- # colorizer is not overriden for a specific language.
69
- #
70
- # @option params [Symbol] :syntax (:html) The syntax to use, which can be
71
- # `:html`, `:xml` or `:xhtml`, the latter two being the same.
72
- #
73
- # @option params [Hash] :colorizers ({}) A hash containing
74
- # a mapping of programming languages (symbols, not strings) onto
75
- # colorizers (symbols).
76
- #
77
- # @option params [Boolean] :outside_pre (false) `true` if the colorizer
78
- # should be applied on `code` elements outside `pre` elements, false
79
- # if only `code` elements inside` pre` elements should be colorized.
80
- #
81
- # @option params [Symbol] :is_fullpage (false) Whether to treat the input
82
- # as a full HTML page or a page fragment. When true, HTML boilerplate
83
- # such as the doctype, `html`, `head` and `body` elements will be added.
84
- #
85
- # @return [String] The filtered content
10
+ ExtractedLanguage = Struct.new(:language, :from_class)
11
+
86
12
  def run(content, params = {})
87
13
  Nanoc::Extra::JRubyNokogiriWarner.check_and_warn
88
14
 
89
- # Take colorizers from parameters
90
- @colorizers = Hash.new(params[:default_colorizer] || DEFAULT_COLORIZER)
91
- (params[:colorizers] || {}).each_pair do |language, colorizer|
92
- @colorizers[language] = colorizer
93
- end
15
+ @colorizers = colorizers_from_params(params)
94
16
 
95
17
  syntax = params.fetch(:syntax, :html)
96
18
  parser = parser_for(syntax)
@@ -100,42 +22,56 @@ module Nanoc::Filters
100
22
  selector = params[:outside_pre] ? 'code' : 'pre > code'
101
23
  doc.css(selector).each do |element|
102
24
  # Get language
103
- has_class = false
104
- language = nil
105
- if element['class']
106
- # Get language from class
107
- match = element['class'].match(/(^| )language-([^ ]+)/)
108
- language = match[2] if match
109
- has_class = true if language
110
- else
111
- # Get language from comment line
112
- match = element.inner_text.strip.split[0].match(/^#!([^\/][^\n]*)$/)
113
- language = match[1] if match
114
- element.content = element.content.sub(/^#!([^\/][^\n]*)$\n/, '') if language
115
- end
25
+ extracted_language = extract_language(element)
116
26
 
117
27
  # Give up if there is no hope left
118
- next if language.nil?
28
+ next unless extracted_language
119
29
 
120
30
  # Highlight
121
31
  raw = strip(element.inner_text)
122
- highlighted_code = highlight(raw, language, params)
32
+ highlighted_code = highlight(raw, extracted_language.language, params)
123
33
  element.children = parse_fragment(parser, strip(highlighted_code))
124
34
 
125
35
  # Add language-something class
126
- unless has_class
36
+ unless extracted_language.from_class
127
37
  klass = element['class'] || ''
128
38
  klass << ' ' unless [' ', nil].include?(klass[-1, 1])
129
- klass << "language-#{language}"
39
+ klass << "language-#{extracted_language.language}"
130
40
  element['class'] = klass
131
41
  end
132
42
 
133
- highlight_postprocess(language, element.parent)
43
+ highlight_postprocess(extracted_language.language, element.parent)
134
44
  end
135
45
 
136
46
  serialize(doc, syntax)
137
47
  end
138
48
 
49
+ def extract_language(element)
50
+ has_class = false
51
+ language = nil
52
+ if element['class']
53
+ # Get language from class
54
+ match = element['class'].match(/(^| )language-([^ ]+)/)
55
+ language = match[2] if match
56
+ has_class = true if language
57
+ else
58
+ # Get language from comment line
59
+ match = element.inner_text.strip.split[0].match(/^#!([^\/][^\n]*)$/)
60
+ language = match[1] if match
61
+ element.content = element.content.sub(/^#!([^\/][^\n]*)$\n/, '') if language
62
+ end
63
+
64
+ language ? ExtractedLanguage.new(language, has_class) : nil
65
+ end
66
+
67
+ def colorizers_from_params(params)
68
+ colorizers = Hash.new(params[:default_colorizer] || DEFAULT_COLORIZER)
69
+ (params[:colorizers] || {}).each_pair do |language, colorizer|
70
+ colorizers[language] = colorizer
71
+ end
72
+ colorizers
73
+ end
74
+
139
75
  def parser_for(syntax)
140
76
  case syntax
141
77
  when :html
@@ -173,16 +109,6 @@ module Nanoc::Filters
173
109
  parser_class.fragment(content)
174
110
  end
175
111
 
176
- # Parses the given content using the given class. This method also handles
177
- # an issue with Nokogiri on JRuby causing “cannot modify frozen string”
178
- # errors.
179
- #
180
- # @param [String] content The content to parse
181
- #
182
- # @param [Class] klass The Nokogiri parser class
183
- #
184
- # @param [Boolean] is_fullpage true if the given content is a full page,
185
- # false if it is a fragment
186
112
  def parse(content, klass, is_fullpage)
187
113
  if is_fullpage
188
114
  parse_full(klass, content)
@@ -197,225 +123,37 @@ module Nanoc::Filters
197
123
  end
198
124
  end
199
125
 
200
- # Runs the code through [CodeRay](http://coderay.rubychan.de/).
201
- #
202
- # @param [String] code The code to colorize
203
- #
204
- # @param [String] language The language the code is written in
205
- #
206
- # @param [Hash] params Parameters to pass on to CodeRay
207
- #
208
- # @return [String] The colorized output
209
- def coderay(code, language, params = {})
210
- require 'coderay'
211
-
212
- ::CodeRay.scan(code, language).html(params)
213
- end
214
-
215
- # Returns the input itself, not performing any code highlighting.
216
- #
217
- # @param [String] code The code to colorize
218
- #
219
- # @param [String] language The language the code is written in (unused)
220
- #
221
- # @return [String] The colorized output, which is identical to the input
222
- # in this case
223
- def dummy(code, language, params = {}) # rubocop:disable Lint/UnusedMethodArgument
224
- code
225
- end
226
-
227
- # Runs the content through [pygmentize](http://pygments.org/docs/cmdline/),
228
- # the command-line frontend for [Pygments](http://pygments.org/).
229
- #
230
- # @param [String] code The code to colorize
231
- #
232
- # @param [String] language The language the code is written in
233
- #
234
- # @option params [String, Symbol] :encoding The encoding of the code block
235
- #
236
- # @return [String] The colorized output
237
- def pygmentize(code, language, params = {})
238
- check_availability('pygmentize', '-V')
239
-
240
- params[:encoding] ||= 'utf-8'
241
- params[:nowrap] ||= 'True'
242
-
243
- cmd = ['pygmentize', '-l', language, '-f', 'html']
244
- cmd << '-O' << params.map { |k, v| "#{k}=#{v}" }.join(',') unless params.empty?
245
-
246
- stdout = StringIO.new
247
- stderr = $stderr
248
- piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr)
249
- piper.run(cmd, code)
250
-
251
- stdout.string
252
- end
253
-
254
- # Runs the content through [Pygments](http://pygments.org/) via
255
- # [pygments.rb](https://github.com/tmm1/pygments.rb).
256
- #
257
- # @param [String] code The code to colorize
258
- #
259
- # @param [String] language The language the code is written in
260
- #
261
- # @return [String] The colorized output
262
- def pygmentsrb(code, language, params = {})
263
- require 'pygments'
264
-
265
- args = params.dup
266
- args[:lexer] ||= language
267
- args[:options] ||= {}
268
- args[:options][:encoding] ||= 'utf-8'
269
- args[:options][:nowrap] ||= 'True'
270
-
271
- Pygments.highlight(code, args)
272
- end
273
-
274
- SIMON_HIGHLIGHT_OPT_MAP = {
275
- wrap: '-W',
276
- include_style: '-I',
277
- line_numbers: '-l',
278
- }.freeze
279
-
280
- # Runs the content through [Highlight](http://www.andre-simon.de/doku/highlight/en/highlight.html).
281
- #
282
- # @param [String] code The code to colorize
283
- #
284
- # @param [String] language The language the code is written in
285
- #
286
- # @option params [String] :style The style to use
287
- #
288
- # @return [String] The colorized output
289
- def simon_highlight(code, language, params = {})
290
- check_availability('highlight', '--version')
291
-
292
- cmd = ['highlight', '--syntax', language, '--fragment']
293
- params.each do |key, _value|
294
- if SIMON_HIGHLIGHT_OPT_MAP[key]
295
- cmd << SIMON_HIGHLIGHT_OPT_MAP[key]
296
- else
297
- # TODO: allow passing other options
298
- case key
299
- when :style
300
- cmd << '--style' << params[:style]
301
- end
302
- end
303
- end
304
-
305
- stdout = StringIO.new
306
- stderr = $stderr
307
- piper = Nanoc::Extra::Piper.new(stdout: stdout, stderr: stderr)
308
- piper.run(cmd, code)
309
-
310
- stdout.string
311
- end
312
-
313
- # Wraps the element in <div class="CodeRay"><div class="code">
314
- def coderay_postprocess(_language, element)
315
- # Skip if we're a free <code>
316
- return if element.parent.nil?
317
-
318
- # <div class="code">
319
- div_inner = Nokogiri::XML::Node.new('div', element.document)
320
- div_inner['class'] = 'code'
321
- div_inner.children = element.dup
322
-
323
- # <div class="CodeRay">
324
- div_outer = Nokogiri::XML::Node.new('div', element.document)
325
- div_outer['class'] = 'CodeRay'
326
- div_outer.children = div_inner
327
-
328
- # orig element
329
- element.swap div_outer
330
- end
331
-
332
- # Runs the content through [Rouge](https://github.com/jayferd/rouge/.
333
- #
334
- # @param [String] code The code to colorize
335
- #
336
- # @param [String] language The language the code is written in
337
- #
338
- # @return [String] The colorized output
339
- def rouge(code, language, params = {})
340
- require 'rouge'
341
-
342
- if Rouge.version < '2' || params.fetch(:legacy, false)
343
- # Rouge 1.x or Rouge 2.x legacy options
344
- formatter_options = {
345
- css_class: params.fetch(:css_class, 'highlight'),
346
- inline_theme: params.fetch(:inline_theme, nil),
347
- line_numbers: params.fetch(:line_numbers, false),
348
- start_line: params.fetch(:start_line, 1),
349
- wrap: params.fetch(:wrap, false),
350
- }
351
- formatter_cls = Rouge::Formatters.const_get(Rouge.version < '2' ? 'HTML' : 'HTMLLegacy')
352
- formatter = formatter_cls.new(formatter_options)
353
- else
354
- formatter = params.fetch(:formatter, Rouge::Formatters::HTML.new)
355
- end
356
-
357
- lexer = Rouge::Lexer.find_fancy(language, code) || Rouge::Lexers::PlainText
358
- formatter.format(lexer.lex(code))
359
- end
360
-
361
- # Removes the double wrapping.
362
- #
363
- # Before:
364
- #
365
- # <pre><code class="language-ruby"><pre class="highlight"><code>
366
- #
367
- # After:
368
- #
369
- # <pre><code class="language-ruby highlight">
370
- def rouge_postprocess(_language, element)
371
- return if element.name != 'pre'
372
-
373
- code1 = element.xpath('code').first
374
- return if code1.nil?
375
-
376
- pre = code1.xpath('pre').first
377
- return if pre.nil?
378
-
379
- code2 = pre.xpath('code').first
380
- return if code2.nil?
381
-
382
- code1.inner_html = code2.inner_html
383
- code1['class'] = [code1['class'], pre['class']].compact.join(' ')
384
- end
385
-
386
126
  protected
387
127
 
388
- KNOWN_COLORIZERS = %i[coderay dummy pygmentize pygmentsrb simon_highlight rouge].freeze
389
-
390
128
  # Removes the first blank lines and any whitespace at the end.
391
129
  def strip(s)
392
130
  s.lines.drop_while { |line| line.strip.empty? }.join.rstrip
393
131
  end
394
132
 
395
- def highlight(code, language, params = {})
396
- colorizer = @colorizers[language.to_sym]
397
- if KNOWN_COLORIZERS.include?(colorizer)
398
- send(colorizer, code, language, params[colorizer] || {})
399
- else
400
- raise "I don’t know how to highlight code using the “#{colorizer}” colorizer"
401
- end
133
+ def colorizer_name_for(language)
134
+ @colorizers[language.to_sym]
402
135
  end
403
136
 
404
- def highlight_postprocess(language, element)
405
- colorizer = @colorizers[language.to_sym]
406
- if KNOWN_COLORIZERS.include?(colorizer)
407
- sym = (colorizer.to_s + '_postprocess').to_sym
408
- if respond_to?(sym)
409
- send(sym, language, element)
410
- end
411
- else
412
- raise "I don’t know how to highlight code using the “#{colorizer}” colorizer"
137
+ def colorizer_named(name)
138
+ colorizer = Colorizers::Abstract.named(name.to_sym)
139
+ unless colorizer
140
+ raise "I don’t know how to highlight code using the “#{name}” colorizer"
413
141
  end
142
+ colorizer
143
+ end
144
+
145
+ def highlight(code, language, params = {})
146
+ colorizer_name = colorizer_name_for(language)
147
+ colorizer = colorizer_named(colorizer_name)
148
+ colorizer.new.process(code, language, params[colorizer_name] || {})
414
149
  end
415
150
 
416
- def check_availability(*cmd)
417
- piper = Nanoc::Extra::Piper.new(stdout: StringIO.new, stderr: StringIO.new)
418
- piper.run(cmd, nil)
151
+ def highlight_postprocess(language, element)
152
+ colorizer_name = colorizer_name_for(language)
153
+ colorizer = colorizer_named(colorizer_name)
154
+ colorizer.new.postprocess(language, element)
419
155
  end
420
156
  end
421
157
  end
158
+
159
+ require_relative 'colorize_syntax/colorizers'