Background
The excellent Rainlab.Blog plugin uses Markdown formatting of posts. Unfortunately the built-in Markdown interpreter Parsedown interferes with the standard MathJax library for typesetting matematical formulas using LaTeX syntax. While Parsedown seems to handle some MathJax constructions properly, the parse roften produces output that causes MathJax rendering to fail.
For example: in a blog post containing text like
The equation $x_{n+2} - 5x_{n+1} + 6x_{n} = 0$.
Parsedown sees the _
as italic markers, and produces the following
HTML code
<p>The equation $x<em>{n+2} - 5x</em>{n+1} + 6x_{n} = 0$.</p>
The incorrectly inserted <em> tags destroys the LaTeX markup and thus MathJax fails to typeset the formulas properly.
Solution
The ExtendMarkdown plugin provides a simple, reasonable clean solution allowing the user to create a number of replacement "rules", protecting certain input from the Parsedown interpreter. These rules will be applied everytime a blog post is saved.
Also, the plugin can be used to add extra shortcuts for commonly used markup.
By default, the plugin comes with the following rules
Rules protecting input from the Parsedown interpreter:
Input start tag | Input close tag | Output start tag | Output close tag |
---|---|---|---|
$ | $ | $ | $ |
$$ | $$ | $$ | $$ |
\begin{equation} | \end{equation} | \begin{equation} | \end{equation} |
\begin{align} | \end{align} | \begin{align} | \end{align} |
Additional markup shortcuts
Input start tag | Input close tag | Output start tag | Output close tag |
---|---|---|---|
@@ | @@ | <strong class="text-primary"> | </strong> |
The plugin provides a backend interface for modifying and adding additional rules as needed.
Live MathJax updates when previewing a blog post in the backend
If you write a lot of MathJax heavy blog posts, you probably want to render the MathJax markup, also in the backend preview.
To do this, install the Mossadal.MathJax plugin.
Technical documentation
System requirement
The plugin uses the markdown.parse
and markdown.beforeParse
event that are emitted by the \October\Rain\Support\Markdown
helper class just before and just after the Parsedown interpreter
has parsed Markdown input to HTML.
These events were added to octobercms/library in commit e9152ee on January 18, 2015. If you are using an older build, you first need to update.
Rule definitions
The plugin allows the user to define a number of regular expressions that are applied before and/or after Parsedown has interpreted Markdown input.
Each rule comes with four properties:
start_markdown
close_markdown
start_tag
close_tag
is_protected
If the is_protected
flag is set, the plugin captures and removes the
input between the start_markdown
and close markdown
tags (including
the tags) before the text is sent through Parsedown.
After Parsedown has returned the resulting HTML, the plugin puts the
captured input back into the correct place, also replacing the start_markdown
and close_markdown
tags with the corresponding start_tag
and close_tag
,
respectively.
If the is_protected
flag is not set, the replacement of
start_markdown
+ input +close_markdown
tostart_tag
+ input +close_tag
is done in one go, after the Parsedown phase.
Examples
The plugin comes with four predefined rules, where is_protected
is set.
All of these are meant to protect MathJax markup from being destroyed
by Parsedown. For example, one rule has all four tags set to $
, thus
protecting inline mathematical formulas, making sure that Parsedown
does not destroy the MathJax markup, so that expressions like
$x_{n+1} + x_{n+2}$
is left untouched by Parsedown.
How does the plugin work?
The plugin hooks into markdown.beforeParse and markdown.Parse.
The hook in markdown.beforeParse goes through all the defined rules
where is_protected
is set, replacing text matching the tags with
a generated string containing an uuid for identification.
The hook in markdown.Parse then replaces the generated uuid strings with the correct content, possibly replacing the surrounding tags.
Finally, the markdown.Parse hook also goes through the rules where
is_protected
is not set and performs the relevant replacements.
-
This plugin has not been reviewed yet.
-
1.0.4 |
Updated syntax in columns.yaml. Better support for nested tags. Aug 13, 2016 |
---|---|
1.0.3 |
Minor bug fixes. Jan 04, 2016 |
1.0.2 |
Rewritten to make use of the markdown.beforeParse and markdown.parse events Jan 18, 2015 |
1.0.1 |
Initialize plugin Jan 18, 2015 |