Class: Nanoc::Filters::ColorizeSyntax
- Inherits:
-
Nanoc::Filter
- Object
- Context
- Nanoc::Filter
- Nanoc::Filters::ColorizeSyntax
- Defined in:
- lib/nanoc/filters/colorize_syntax.rb
Constant Summary
- DEFAULT_COLORIZER =
The default colorizer to use for a language if the colorizer for that language is not overridden.
:coderay
- SIMON_HIGHLIGHT_OPT_MAP =
{ :wrap => '-W', :include_style => '-I', :line_numbers => '-l', }
Constants inherited from Nanoc::Filter
Nanoc::Filter::TMP_BINARY_ITEMS_DIR
Instance Attribute Summary
Attributes inherited from Nanoc::Filter
Instance Method Summary (collapse)
-
- (String) coderay(code, language, params = {})
private
Runs the code through CodeRay.
-
- (Object) coderay_postprocess(language, element)
Wraps the element in.
-
- (String) dummy(code, language, params = {})
Returns the input itself, not performing any code highlighting.
-
- (Object) parse(content, klass, is_fullpage)
private
Parses the given content using the given class.
-
- (String) pygmentize(code, language, params = {})
private
Runs the content through pygmentize, the commandline frontend for Pygments.
-
- (String) pygmentsrb(code, language, params = {})
private
Runs the content through Pygments via pygments.rb.
-
- (String) run(content, params = {})
Syntax-highlights code blocks in the given content.
-
- (String) simon_highlight(code, language, params = {})
private
Runs the content through Highlight.
Methods inherited from Nanoc::Filter
#depend_on, #filename, from_binary?, #initialize, #output_filename, requires, setup, #setup_and_run, to_binary?, type
Methods included from PluginRegistry::PluginMethods
#all, #identifier, #identifiers, #named, #register
Methods inherited from Context
Constructor Details
This class inherits a constructor from Nanoc::Filter
Instance Method Details
- (String) coderay(code, language, params = {})
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Runs the code through CodeRay.
187 188 189 190 191 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 187 def coderay(code, language, params = {}) require 'coderay' ::CodeRay.scan(code, language).html(params) end |
- (Object) coderay_postprocess(language, element)
Wraps the element in <div class="CodeRay"><div class="code">
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 300 def coderay_postprocess(language, element) # Skip if we're a free <code> return if element.parent.nil? # <div class="code"> div_inner = Nokogiri::XML::Node.new('div', element.document) div_inner['class'] = 'code' div_inner.children = element.dup # <div class="CodeRay"> div_outer = Nokogiri::XML::Node.new('div', element.document) div_outer['class'] = 'CodeRay' div_outer.children = div_inner # orig element element.swap div_outer end |
- (String) dummy(code, language, params = {})
Returns the input itself, not performing any code highlighting.
201 202 203 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 201 def dummy(code, language, params = {}) code end |
- (Object) parse(content, klass, is_fullpage)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Parses the given content using the given class. This method also handles an issue with Nokogiri on JRuby causing “cannot modify frozen string” errors.
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 160 def parse(content, klass, is_fullpage) begin if is_fullpage klass.parse(content, nil, 'UTF-8') else klass.fragment(content) end rescue => e if e. =~ /can't modify frozen string/ parse(content.dup, klass, is_fullpage) else raise e end end end |
- (String) pygmentize(code, language, params = {})
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Runs the content through pygmentize, the commandline frontend for Pygments.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 217 def pygmentize(code, language, params = {}) check_availability('pygmentize', '-V') params[:encoding] ||= 'utf-8' params[:nowrap] ||= 'True' cmd = [ 'pygmentize', '-l', language, '-f', 'html' ] cmd << '-O' << params.map { |k, v| "#{k}=#{v}" }.join(',') unless params.empty? stdout = StringIO.new stderr = $stderr piper = Nanoc::Extra::Piper.new(:stdout => stdout, :stderr => stderr) piper.run(cmd, code) stdout.string end |
- (String) pygmentsrb(code, language, params = {})
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Runs the content through Pygments via pygments.rb.
244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 244 def pygmentsrb(code, language, params = {}) require 'pygments' args = params.dup args[:lexer] ||= language args[:options] ||= {} args[:options][:encoding] ||= 'utf-8' args[:options][:nowrap] ||= 'True' Pygments.highlight(code, args) end |
- (String) run(content, params = {})
Syntax-highlights code blocks in the given content. Code blocks should
be enclosed in pre
elements that contain a code
element. The code
element should have an indication of the language the code is in. There
are two possible ways of adding such an indication:
-
A HTML class starting with
language-
and followed by the code language, as specified by HTML5. For example,<code class="language-ruby">
. -
A comment on the very first line of the code block in the format
#!language
wherelanguage
is the language the code is in. For example,#!ruby
.
Options for individual colorizers will be taken from the #run
options’ value for the given colorizer. For example, if the filter is
invoked with a :coderay => coderay_options_hash
option, the
coderay_options_hash
hash will be passed to the CodeRay colorizer.
Currently, the following colorizers are supported:
:coderay
for Coderay:pygmentize
for pygmentize, the commandline frontend for Pygments:pygmentsrb
for pygments.rb, a Ruby interface for Pygments:simon_highlight
for Highlight
Additional colorizer implementations are welcome!
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 85 def run(content, params = {}) Nanoc::Extra::JRubyNokogiriWarner.check_and_warn # Take colorizers from parameters @colorizers = Hash.new(params[:default_colorizer] || DEFAULT_COLORIZER) (params[:colorizers] || {}).each_pair do |language, colorizer| @colorizers[language] = colorizer end # Determine syntax (HTML or XML) syntax = params[:syntax] || :html case syntax when :html klass = Nokogiri::HTML when :xml, :xhtml klass = Nokogiri::XML else raise "unknown syntax: #{syntax.inspect} (expected :html or :xml)" end # Colorize doc = parse(content, klass, params.fetch(:is_fullpage, false)) selector = params[:outside_pre] ? 'code' : 'pre > code' doc.css(selector).each do |element| # Get language has_class = false language = nil if element['class'] # Get language from class match = element['class'].match(/(^| )language-([^ ]+)/) language = match[2] if match has_class = true if language else # Get language from comment line match = element.inner_text.strip.split[0].match(/^#!([^\/][^\n]*)$/) language = match[1] if match element.content = element.content.sub(/^#!([^\/][^\n]*)$\n/, '') if language end # Give up if there is no hope left next if language.nil? # Highlight raw = strip(element.inner_text) highlighted_code = highlight(raw, language, params) element.children = Nokogiri::HTML.fragment(strip(highlighted_code), 'utf-8') # Add language-something class unless has_class klass = element['class'] || '' klass << ' ' unless [' ', nil].include?(klass[-1, 1]) klass << "language-#{language}" element['class'] = klass end highlight_postprocess(language, element.parent) end method = "to_#{syntax}".to_sym doc.send(method, :encoding => 'UTF-8') end |
- (String) simon_highlight(code, language, params = {})
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Runs the content through Highlight.
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/nanoc/filters/colorize_syntax.rb', line 275 def simon_highlight(code, language, params = {}) check_availability('highlight', '--version') cmd = [ 'highlight', '--syntax', language, '--fragment' ] params.each do |key, value| if SIMON_HIGHLIGHT_OPT_MAP[key] cmd << SIMON_HIGHLIGHT_OPT_MAP[key] else # TODO allow passing other options case key when :style cmd << '--style' << params[:style] end end end stdout = StringIO.new stderr = $stderr piper = Nanoc::Extra::Piper.new(:stdout => stdout, :stderr => stderr) piper.run(cmd, code) stdout.string end |