Class: Banzai::Filter::MathFilter

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

Overview

HTML filter that adds class=“code math” and removes the dollar sign in $`2+2`$.

Constant Summary collapse

CSS_MATH =
'pre.code.language-math'
XPATH_MATH =
Gitlab::Utils::Nokogiri.css_to_xpath(CSS_MATH).freeze
CSS_CODE =
'code'
XPATH_CODE =
Gitlab::Utils::Nokogiri.css_to_xpath(CSS_CODE).freeze
STYLE_ATTRIBUTE =

Attribute indicating inline or display math.

'data-math-style'
TAG_CLASS =

Class used for tagging elements that should be rendered

'js-render-math'
INLINE_CLASSES =
"code math #{TAG_CLASS}"
DOLLAR_SIGN =
'$'
RENDER_NODES_LIMIT =

Limit to how many nodes can be marked as math elements. Prevents timeouts for large notes. For more information check: gitlab.com/gitlab-org/gitlab/-/issues/341832

50

Instance Method Summary collapse

Instance Method Details

#callObject


33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/banzai/filter/math_filter.rb', line 33

def call
  nodes_count = 0

  doc.xpath(XPATH_CODE).each do |code|
    closing = code.next
    opening = code.previous

    # We need a sibling before and after.
    # They should end and start with $ respectively.
    if closing && opening &&
        closing.text? && opening.text? &&
        closing.content.first == DOLLAR_SIGN &&
        opening.content.last == DOLLAR_SIGN

      code[:class] = INLINE_CLASSES
      code[STYLE_ATTRIBUTE] = 'inline'
      closing.content = closing.content[1..]
      opening.content = opening.content[0..-2]

      nodes_count += 1
      break if nodes_count >= RENDER_NODES_LIMIT
    end
  end

  doc.xpath(XPATH_MATH).each do |el|
    el[STYLE_ATTRIBUTE] = 'display'
    el[:class] += " #{TAG_CLASS}"
  end

  doc
end