1313from xml .etree .ElementTree import Element
1414from markdown .inlinepatterns import InlineProcessor
1515from markdown .extensions import Extension
16+ from markdown .preprocessors import Preprocessor
1617from markdown .util import AtomicString
1718
1819
@@ -47,6 +48,38 @@ def handleMatch(self, m, data):
4748 return node , m .start (0 ), m .end (0 )
4849
4950
51+ class GitLabPreprocessor (Preprocessor ):
52+ """
53+ Preprocessor for GitLab-style standalone syntax:
54+
55+ ```math
56+ math goes here
57+ ```
58+ """
59+
60+ def run (self , lines ):
61+ inside_math_block = False
62+ math_block_start = None
63+ math_blocks = []
64+
65+ for line_number , line in enumerate (lines ):
66+ if line == '```math' and not inside_math_block :
67+ math_block_start = line_number
68+ inside_math_block = True
69+ if line == '```' and inside_math_block :
70+ math_blocks .append ((math_block_start , line_number ))
71+ inside_math_block = False
72+
73+ for math_block_start , math_block_end in reversed (math_blocks ):
74+ math_lines = lines [math_block_start + 1 :math_block_end ]
75+ math_content = '\n ' .join (math_lines )
76+ html = '<script type="%s; mode=display">\n %s\n </script>'
77+ html %= (self ._content_type , math_content )
78+ placeholder = self .md .htmlStash .store (html )
79+ lines [math_block_start :math_block_end + 1 ] = [placeholder ]
80+ return lines
81+
82+
5083class MathExtension (Extension ):
5184 def __init__ (self , * args , ** kwargs ):
5285 self .config = {
@@ -64,6 +97,7 @@ def extendMarkdown(self, md):
6497 add_preview = self .getConfig ('add_preview' )
6598 use_asciimath = self .getConfig ('use_asciimath' )
6699 use_gitlab_delimiters = self .getConfig ('use_gitlab_delimiters' )
100+ content_type = 'math/asciimath' if use_asciimath else 'math/tex'
67101
68102 inlinemathpatterns = (
69103 InlineMathPattern (r'(?<!\\|\$)(\$)([^\$]+)(\$)' ), # $...$
@@ -84,8 +118,13 @@ def extendMarkdown(self, md):
84118 inlinemathpatterns = (
85119 InlineMathPattern (r'(?<!\\)(\$`)([^`]+)(`\$)' ), # $`...`$
86120 )
121+ mathpatterns = ()
122+ preprocessor = GitLabPreprocessor (md )
123+ preprocessor ._content_type = content_type
124+ # we should have higher priority than 'fenced_code_block' which
125+ # has 25
126+ md .preprocessors .register (preprocessor , 'math-gitlab' , 27 )
87127
88- content_type = 'math/asciimath' if use_asciimath else 'math/tex'
89128 for i , pattern in enumerate (mathpatterns ):
90129 pattern ._add_preview = add_preview
91130 pattern ._content_type = content_type
0 commit comments