aboutsummaryrefslogtreecommitdiff
path: root/plugins/render_math/pelican_mathjax_markdown_extension.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/render_math/pelican_mathjax_markdown_extension.py')
-rw-r--r--[-rwxr-xr-x]plugins/render_math/pelican_mathjax_markdown_extension.py120
1 files changed, 79 insertions, 41 deletions
diff --git a/plugins/render_math/pelican_mathjax_markdown_extension.py b/plugins/render_math/pelican_mathjax_markdown_extension.py
index e739363..77e0593 100755..100644
--- a/plugins/render_math/pelican_mathjax_markdown_extension.py
+++ b/plugins/render_math/pelican_mathjax_markdown_extension.py
@@ -8,33 +8,35 @@ gives Pelican the ability to use Mathjax as a "first class
citizen" of the blog
"""
-import markdown
+from xml.etree.ElementTree import Element
-from markdown.util import etree
+import markdown
from markdown.util import AtomicString
+
class PelicanMathJaxPattern(markdown.inlinepatterns.Pattern):
"""Inline markdown processing that matches mathjax"""
def __init__(self, pelican_mathjax_extension, tag, pattern):
- super(PelicanMathJaxPattern,self).__init__(pattern)
- self.math_tag_class = pelican_mathjax_extension.getConfig('math_tag_class')
+ super(PelicanMathJaxPattern, self).__init__(pattern)
+ self.math_tag_class = pelican_mathjax_extension.getConfig("math_tag_class")
self.pelican_mathjax_extension = pelican_mathjax_extension
self.tag = tag
def handleMatch(self, m):
- node = markdown.util.etree.Element(self.tag)
- node.set('class', self.math_tag_class)
+ node = Element(self.tag)
+ node.set("class", self.math_tag_class)
- prefix = '\\(' if m.group('prefix') == '$' else m.group('prefix')
- suffix = '\\)' if m.group('suffix') == '$' else m.group('suffix')
- node.text = markdown.util.AtomicString(prefix + m.group('math') + suffix)
+ prefix = "\\(" if m.group("prefix") == "$" else m.group("prefix")
+ suffix = "\\)" if m.group("suffix") == "$" else m.group("suffix")
+ node.text = markdown.util.AtomicString(prefix + m.group("math") + suffix)
# If mathjax was successfully matched, then JavaScript needs to be added
# for rendering. The boolean below indicates this
self.pelican_mathjax_extension.mathjax_needed = True
return node
+
class PelicanMathJaxCorrectDisplayMath(markdown.treeprocessors.Treeprocessor):
"""Corrects invalid html that results from a <div> being put inside
a <p> for displayed math"""
@@ -49,22 +51,22 @@ class PelicanMathJaxCorrectDisplayMath(markdown.treeprocessors.Treeprocessor):
current_idx = 0
for idx in div_math:
- el = markdown.util.etree.Element('p')
+ el = Element("p")
el.text = text
el.extend(children[current_idx:idx])
- # Test to ensure that empty <p> is not inserted
+ # Test to ensure that empty <p> is not inserted
if len(el) != 0 or (el.text and not el.text.isspace()):
- root.insert(insert_idx, el)
- insert_idx += 1
+ root.insert(insert_idx, el)
+ insert_idx += 1
text = children[idx].tail
children[idx].tail = None
root.insert(insert_idx, children[idx])
insert_idx += 1
- current_idx = idx+1
+ current_idx = idx + 1
- el = markdown.util.etree.Element('p')
+ el = Element("p")
el.text = text
el.extend(children[current_idx:])
@@ -75,14 +77,14 @@ class PelicanMathJaxCorrectDisplayMath(markdown.treeprocessors.Treeprocessor):
"""Searches for <div class="math"> that are children in <p> tags and corrects
the invalid HTML that results"""
- math_tag_class = self.pelican_mathjax_extension.getConfig('math_tag_class')
+ math_tag_class = self.pelican_mathjax_extension.getConfig("math_tag_class")
for parent in root:
div_math = []
children = list(parent)
- for div in parent.findall('div'):
- if div.get('class') == math_tag_class:
+ for div in parent.findall("div"):
+ if div.get("class") == math_tag_class:
div_math.append(children.index(div))
# Do not process further if no displayed math has been found
@@ -90,11 +92,14 @@ class PelicanMathJaxCorrectDisplayMath(markdown.treeprocessors.Treeprocessor):
continue
insert_idx = list(root).index(parent)
- self.correct_html(root, children, div_math, insert_idx, parent.text)
- root.remove(parent) # Parent must be removed last for correct insertion index
+ self.correct_html(root, children, div_math, insert_idx, parent.text)
+ root.remove(
+ parent
+ ) # Parent must be removed last for correct insertion index
return root
+
class PelicanMathJaxAddJavaScript(markdown.treeprocessors.Treeprocessor):
"""Tree Processor for adding Mathjax JavaScript to the blog"""
@@ -103,13 +108,15 @@ class PelicanMathJaxAddJavaScript(markdown.treeprocessors.Treeprocessor):
def run(self, root):
# If no mathjax was present, then exit
- if (not self.pelican_mathjax_extension.mathjax_needed):
+ if not self.pelican_mathjax_extension.mathjax_needed:
return root
# Add the mathjax script to the html document
- mathjax_script = etree.Element('script')
- mathjax_script.set('type','text/javascript')
- mathjax_script.text = AtomicString(self.pelican_mathjax_extension.getConfig('mathjax_script'))
+ mathjax_script = Element("script")
+ mathjax_script.set("type", "text/javascript")
+ mathjax_script.text = AtomicString(
+ self.pelican_mathjax_extension.getConfig("mathjax_script")
+ )
root.append(mathjax_script)
# Reset the boolean switch to false so that script is only added
@@ -117,22 +124,39 @@ class PelicanMathJaxAddJavaScript(markdown.treeprocessors.Treeprocessor):
self.pelican_mathjax_extension.mathjax_needed = False
return root
+
class PelicanMathJaxExtension(markdown.Extension):
"""A markdown extension enabling mathjax processing in Markdown for Pelican"""
+
def __init__(self, config):
try:
# Needed for markdown versions >= 2.5
- self.config['mathjax_script'] = ['', 'Mathjax JavaScript script']
- self.config['math_tag_class'] = ['math', 'The class of the tag in which mathematics is wrapped']
- self.config['auto_insert'] = [True, 'Determines if mathjax script is automatically inserted into content']
- super(PelicanMathJaxExtension,self).__init__(**config)
+ self.config["mathjax_script"] = ["", "Mathjax JavaScript script"]
+ self.config["math_tag_class"] = [
+ "math",
+ "The class of the tag in which mathematics is wrapped",
+ ]
+ self.config["auto_insert"] = [
+ True,
+ "Determines if mathjax script is automatically inserted into content",
+ ]
+ super(PelicanMathJaxExtension, self).__init__(**config)
except AttributeError:
# Markdown versions < 2.5
- config['mathjax_script'] = [config['mathjax_script'], 'Mathjax JavaScript script']
- config['math_tag_class'] = [config['math_tag_class'], 'The class of the tag in which mathematic is wrapped']
- config['auto_insert'] = [config['auto_insert'], 'Determines if mathjax script is automatically inserted into content']
- super(PelicanMathJaxExtension,self).__init__(config)
+ config["mathjax_script"] = [
+ config["mathjax_script"],
+ "Mathjax JavaScript script",
+ ]
+ config["math_tag_class"] = [
+ config["math_tag_class"],
+ "The class of the tag in which mathematic is wrapped",
+ ]
+ config["auto_insert"] = [
+ config["auto_insert"],
+ "Determines if mathjax script is automatically inserted into content",
+ ]
+ super(PelicanMathJaxExtension, self).__init__(config)
# Used as a flag to determine if javascript
# needs to be injected into a document
@@ -140,19 +164,33 @@ class PelicanMathJaxExtension(markdown.Extension):
def extendMarkdown(self, md):
# Regex to detect mathjax
- mathjax_inline_regex = r'(?P<prefix>\$)(?P<math>.+?)(?P<suffix>(?<!\s)\2)'
- mathjax_display_regex = r'(?P<prefix>\$\$|\\begin\{(.+?)\})(?P<math>.+?)(?P<suffix>\2|\\end\{\3\})'
+ mathjax_inline_regex = r"(?P<prefix>\$)(?P<math>.+?)(?P<suffix>(?<!\s)\2)"
+ mathjax_display_regex = (
+ r"(?P<prefix>\$\$|\\begin\{(.+?)\})(?P<math>.+?)(?P<suffix>\2|\\end\{\3\})"
+ )
# Process mathjax before escapes are processed since escape processing will
# intefer with mathjax. The order in which the displayed and inlined math
# is registered below matters: we should have higher priority than 'escape' which has 180
- md.inlinePatterns.register(PelicanMathJaxPattern(self, 'div', mathjax_display_regex), 'mathjax_displayed', 186)
- md.inlinePatterns.register(PelicanMathJaxPattern(self, 'span', mathjax_inline_regex), 'mathjax_inlined', 185)
-
- # Correct the invalid HTML that results from teh displayed math (<div> tag within a <p> tag)
- md.treeprocessors.register(PelicanMathJaxCorrectDisplayMath(self), 'mathjax_correctdisplayedmath', 15)
+ md.inlinePatterns.register(
+ PelicanMathJaxPattern(self, "div", mathjax_display_regex),
+ "mathjax_displayed",
+ 186,
+ )
+ md.inlinePatterns.register(
+ PelicanMathJaxPattern(self, "span", mathjax_inline_regex),
+ "mathjax_inlined",
+ 185,
+ )
+
+ # Correct the invalid HTML that results from teh displayed math (<div> tag within a <p> tag)
+ md.treeprocessors.register(
+ PelicanMathJaxCorrectDisplayMath(self), "mathjax_correctdisplayedmath", 15
+ )
# If necessary, add the JavaScript Mathjax library to the document. This must
# be last in the ordered dict (hence it is given the position '_end')
- if self.getConfig('auto_insert'):
- md.treeprocessors.register(PelicanMathJaxAddJavaScript(self), 'mathjax_addjavascript', 0)
+ if self.getConfig("auto_insert"):
+ md.treeprocessors.register(
+ PelicanMathJaxAddJavaScript(self), "mathjax_addjavascript", 0
+ )