Class: Banzai::Filter::DollarMathPostFilter

Inherits:
HTML::Pipeline::Filter
  • Object
show all
Defined in:
lib/banzai/filter/dollar_math_post_filter.rb

Overview

HTML filter that implements our dollar math syntax, one of three filters: DollarMathPreFilter, DollarMathPostFilter, and MathFilter

Constant Summary collapse

DOLLAR_INLINE_UNTRUSTED =

Corresponds to the “$…$” syntax

'(?P<matched>\$(?P<math>(?:\S[^$\n]*?\S|[^$\s]))\$)(?:[^\d]|$)'
DOLLAR_INLINE_UNTRUSTED_REGEX =
Gitlab::UntrustedRegexp.new(DOLLAR_INLINE_UNTRUSTED, multiline: false).freeze
DOLLAR_DISPLAY_INLINE_UNTRUSTED =

Corresponds to the “$$…$$” syntax

'(?P<matched>\$\$\ *(?P<math>[^$\n]+?)\ *\$\$)'
DOLLAR_DISPLAY_INLINE_UNTRUSTED_REGEX =
Gitlab::UntrustedRegexp.new(DOLLAR_DISPLAY_INLINE_UNTRUSTED, multiline: false).freeze
DOLLAR_MATH_PIPELINE =

Order dependent. Handle the ‘$$` syntax before the `$` syntax

[
  { pattern: DOLLAR_DISPLAY_INLINE_UNTRUSTED_REGEX, style: :display },
  { pattern: DOLLAR_INLINE_UNTRUSTED_REGEX, style: :inline }
].freeze
IGNORED_ANCESTOR_TAGS =

Do not recognize math inside these tags

%w[pre code tt].to_set

Instance Method Summary collapse

Instance Method Details

#callObject



40
41
42
43
44
# File 'lib/banzai/filter/dollar_math_post_filter.rb', line 40

def call
  process_dollar_pipeline

  doc
end

#process_dollar_pipelineObject



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/banzai/filter/dollar_math_post_filter.rb', line 46

def process_dollar_pipeline
  doc.xpath('descendant-or-self::text()').each do |node|
    next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS)

    node_html = node.to_html
    next unless DOLLAR_INLINE_UNTRUSTED_REGEX.match?(node_html) ||
      DOLLAR_DISPLAY_INLINE_UNTRUSTED_REGEX.match?(node_html)

    temp_doc = Nokogiri::HTML.fragment(node_html)

    DOLLAR_MATH_PIPELINE.each do |pipeline|
      temp_doc.xpath('child::text()').each do |temp_node|
        html = temp_node.to_html

        pipeline[:pattern].scan(temp_node.content).each do |match|
          math = pipeline[:pattern].extract_named_group(:math, match)
          html.sub!(match.first, math_html(math: math, style: pipeline[:style]))
        end

        temp_node.replace(html)
      end
    end

    node.replace(temp_doc)
  end
end