Class: HTML::Pipeline::SyntaxHighlightFilter

Inherits:
Filter
  • Object
show all
Defined in:
lib/html/pipeline/syntax_highlight_filter.rb

Overview

HTML Filter that syntax highlights text inside code blocks.

Context options:

:highlight => String represents the language to pick lexer. Defaults to empty string.
:scope => String represents the class attribute adds to pre element after.
          Defaults to "highlight highlight-css" if highlights a css code block.

This filter does not write any additional information to the context hash.

Instance Attribute Summary

Attributes inherited from Filter

#context, #result

Instance Method Summary collapse

Methods inherited from Filter

#base_url, call, #current_user, #doc, #has_ancestor?, #html, #needs, #parse_html, #repository, to_document, to_html, #validate

Constructor Details

#initialize(*args) ⇒ SyntaxHighlightFilter

Returns a new instance of SyntaxHighlightFilter.


17
18
19
20
# File 'lib/html/pipeline/syntax_highlight_filter.rb', line 17

def initialize(*args)
  super(*args)
  @formatter = Rouge::Formatters::HTML.new
end

Instance Method Details

#callObject


22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/html/pipeline/syntax_highlight_filter.rb', line 22

def call
  doc.search('pre').each do |node|
    default = context[:highlight] && context[:highlight].to_s
    next unless lang = node['lang'] || default
    next unless lexer = lexer_for(lang)

    text = node.inner_text
    html = highlight_with_timeout_handling(text, lexer)
    next if html.nil?

    node.inner_html = html
    scope = context.fetch(:scope) { 'highlight' }
    node['class'] = "#{scope} #{scope}-#{lang}"
  end
  doc
end

#highlight_with_timeout_handling(text, lexer) ⇒ Object


39
40
41
42
43
# File 'lib/html/pipeline/syntax_highlight_filter.rb', line 39

def highlight_with_timeout_handling(text, lexer)
  Rouge.highlight(text, lexer, @formatter)
rescue Timeout::Error => _
  nil
end

#lexer_for(lang) ⇒ Object


45
46
47
# File 'lib/html/pipeline/syntax_highlight_filter.rb', line 45

def lexer_for(lang)
  Rouge::Lexer.find(lang)
end