467

Product support

Get help in the plugin support forum.

Categories

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 to start_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.

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