summaryrefslogtreecommitdiff
path: root/lib/banzai/filter/dollar_math_pre_filter.rb
blob: aaa186f87a63d85bc518caafdcd0256191b6f041 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# frozen_string_literal: true

# Generated HTML is transformed back to GFM by:
# - app/assets/javascripts/behaviors/markdown/marks/math.js
# - app/assets/javascripts/behaviors/markdown/nodes/code_block.js
module Banzai
  module Filter
    # HTML filter that implements our dollar math syntax, one of three filters:
    # DollarMathPreFilter, DollarMathPostFilter, and MathFilter
    #
    class DollarMathPreFilter < HTML::Pipeline::TextFilter
      # Based on the Pandoc heuristics,
      # https://pandoc.org/MANUAL.html#extension-tex_math_dollars
      #
      # Handle the $$\n...\n$$ syntax in this filter, before markdown processing,
      # by converting it into the ```math syntax. In this way, we can ensure
      # that it's considered a code block and will not have any markdown processed inside it.

      # Corresponds to the "$$\n...\n$$" syntax
      REGEX = %r{
          #{::Gitlab::Regex.markdown_code_or_html_blocks}
        |
          (?=(?<=^\n|\A)\$\$\ *\n.*\n\$\$\ *(?=\n$|\z))(?:
            # Display math block:
            # $$
            # latex math
            # $$

            (?<=^\n|\A)\$\$\ *\n
            (?<display_math>
              (?:.)+?
            )
            \n\$\$\ *(?=\n$|\z)
          )
      }mx.freeze

      def call
        @text.gsub(REGEX) do
          if $~[:display_math]
            # change from $$ to ```math
            "```math\n#{$~[:display_math]}\n```"
          else
            $~[0]
          end
        end
      end
    end
  end
end