logo

Markdown Filter

← Back to Filter List

Markdown


↓ examples

Runs a Markdown processor to convert markdown to HTML. Markdown extensions can be enabled in your config: http://packages.python.org/Markdown/extensions/index.html

Aliases for this filter

  • markdown

Converts from file formats:

  • .*

To file formats:

  • .html

Available settings:

SettingDescriptionDefault
add-new-filesBoolean or list of extensions/patterns to match.False
added-in-versionDexy version when this filter was first available.
additional-doc-filtersFilters to apply to additional documents created as side effects.{}
additional-doc-settingsSettings to apply to additional documents created as side effects.{}
data-typeAlias of custom data class to use to store filter output.generic
examplesTemplates which should be used as examples for this filter.[u'markdown']
exclude-add-new-filesList of patterns to skip even if they match add-new-files.[]
exclude-new-files-from-dirList of directories to skip when adding new files.[]
extFile extension to output.None
extension-mapDictionary mapping input extensions to default output extensions.None
extensionsWhich Markdown extensions to enable.{u'toc': {}}
helpHelpstring for plugin.Runs a Markdown processor to convert markdown to HTML. Markdown extensions can be enabled in your config: http://packages.python.org/Markdown/extensions/index.html
input-extensionsList of extensions which this filter can accept as input.[u'.*']
keep-originalsWhether, if additional-doc-filters are specified, the original unmodified docs should also be added.False
mkdirA directory which should be created in working dir.None
mkdirsA list of directories which should be created in working dir.[]
nodocWhether filter should be excluded from documentation.False
outputWhether to output results of this filter by default by reporters such as 'output' or 'website'.False
output-extensionsList of extensions which this filter can produce as output.[u'.html']
override-workspace-exclude-filtersIf True, document will be populated to other workspaces ignoring workspace-exclude-filters.False
preserve-prior-data-classWhether output data class should be set to match the input data class.False
require-outputShould dexy raise an exception if no output is produced by this filter?True
tagsTags which describe the filter.[]
variablesA dictionary of variable names and values to make available to this filter.{}
varsA dictionary of variable names and values to make available to this filter.{}
workspace-exclude-filtersFilters whose output should be excluded from workspace.[u'pyg']
workspace-includesIf set to a list of filenames or extensions, only these will be populated to working dir.None

Markdown Example

The markdown filter converts markdown, like this:

[TOC]

A First Level Header
====================

A Second Level Header
---------------------

This is just a regular paragraph.

### Header 3

> This is a blockquote.

into HTML, like this:

<div class="toc">
<ul>
<li><a href="#a-first-level-header">A First Level Header</a><ul>
<li><a href="#a-second-level-header">A Second Level Header</a><ul>
<li><a href="#header-3">Header 3</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<h1 id="a-first-level-header">A First Level Header</h1>
<h2 id="a-second-level-header">A Second Level Header</h2>
<p>This is just a regular paragraph.</p>
<h3 id="header-3">Header 3</h3>
<blockquote>
<p>This is a blockquote.</p>
</blockquote>

Here is how this is specified in YAML:

- example.md|markdown

Markdown & Jinja

If you are running a document through both the markdown and jinja filters, then put jinja earlier in the filter chain, before markdown, so that markdown doesn't mangle the jinja tags. This will mean that markdown will run on the content returned by jinja during its processing. For example:

- example-with-jinja.md|jinja|markdown:
    - example-with-jinja.md|pyg

If your jinja content is returning already-formatted HTML, then markdown will leave this alone as long as there are no blank lines within your content. Dexy's pyg and idio filters have the lineanchors feature enabled by default which, in addition to giving each line of output a linkable URL, also means there are no blank lines in the pygments output, so the markdown filter should not cause problems as long as this feature is kept enabled.

Here is an example of a markdown document with jinja tags:

Here is some text.

Here is some code with syntax highlighting:

{{ d['example-with-jinja.md|pyg'] }}

Here is the HTML after this has been processed by both jinja and markdown:

<p>Here is some text.</p>
<p>Here is some code with syntax highlighting:</p>
<div class="highlight"><pre><a name="example-with-jinja.md-pyg.html-1"></a><span class="n">Here</span> <span class="k">is</span> <span class="n">some</span> <span class="n">text</span><span class="p">.</span>
<a name="example-with-jinja.md-pyg.html-2"></a>
<a name="example-with-jinja.md-pyg.html-3"></a><span class="n">Here</span> <span class="k">is</span> <span class="n">some</span> <span class="n">code</span> <span class="k">with</span> <span class="n">syntax</span> <span class="n">highlighting</span><span class="p">:</span>
<a name="example-with-jinja.md-pyg.html-4"></a>
<a name="example-with-jinja.md-pyg.html-5"></a><span class="p">{{</span> <span class="n">d</span><span class="p">[</span><span class="err">&#39;</span><span class="n">example</span><span class="p">-</span><span class="k">with</span><span class="p">-</span><span class="n">jinja</span><span class="p">.</span><span class="n">md</span><span class="p">|</span><span class="n">pyg</span><span class="err">&#39;</span><span class="p">]</span> <span class="p">}}</span>
</pre></div>

Markdown Extensions

The python-markdown implementation has a number of extensions which, when enabled, make available additional markdown features. By default the Table of Contents extension is enabled (with no custom configuration options set).

To enable an extension, you need to pass a dictionary of arguments to the markdown filter. For each extension you wish to enable, you need to pass that extension's module name as the key, and a dictionary setting any custom configuration options for that extension as the value (this must be a blank dictionary if you don't wish to set any custom options).

Here is a markdown document containing a table:

Here is a table:

First Header  | Second Header
------------- | -------------
Content Cell  | Content Cell
Content Cell  | Content Cell

Without any extensions enabled, this doesn't render specially:

<p>Here is a table:</p>
<p>First Header  | Second Header
------------- | -------------
Content Cell  | Content Cell
Content Cell  | Content Cell</p>

However when we enable tables like this:

- table-example.md|markdown:
    - markdown: { extensions: { tables: {} } }

Then we get a HTML table in our output:

<p>Here is a table:</p>
<table>
<thead>
<tr>
<th>First Header</th>
<th>Second Header</th>
</tr>
</thead>
<tbody>
<tr>
<td>Content Cell</td>
<td>Content Cell</td>
</tr>
<tr>
<td>Content Cell</td>
<td>Content Cell</td>
</tr>
</tbody>
</table>

If we set a custom option, then the TOC module is no longer automatically enabled. Here is an example of enabling the tables and toc modules, and setting a custom option to the toc module:

- table-and-toc-example.md|markdown:
    - markdown: { extensions: { tables: {}, toc: { anchorlink : true } } }

Here is the HTML we generate:

<div class="toc">
<ul>
<li><a href="#table-1">Table 1</a></li>
<li><a href="#table-2">Table 2</a></li>
</ul>
</div>
<h1 id="table-1"><a class="toclink" href="#table-1">Table 1</a></h1>
<table>
<thead>
<tr>
<th>Function name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>help()</code></td>
<td>Display the help window.</td>
</tr>
<tr>
<td><code>destroy()</code></td>
<td><strong>Destroy your computer!</strong></td>
</tr>
</tbody>
</table>
<h1 id="table-2"><a class="toclink" href="#table-2">Table 2</a></h1>
<table>
<thead>
<tr>
<th>Item</th>
<th align="right">Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Computer</td>
<td align="right">$1600</td>
</tr>
<tr>
<td>Phone</td>
<td align="right">$12</td>
</tr>
<tr>
<td>Pipe</td>
<td align="right">$1</td>
</tr>
</tbody>
</table>
<p>Examples from <a href="http://michelf.ca/projects/php-markdown/extra/#table">http://michelf.ca/projects/php-markdown/extra/#table</a>.</p>
Filter Source Code
class MarkdownFilter(DexyFilter):
    """
    Runs a Markdown processor to convert markdown to HTML.

    Markdown extensions can be enabled in your config:
    http://packages.python.org/Markdown/extensions/index.html
    """
    aliases = ['markdown']
    _settings = {
            'examples' : ['markdown'],
            'input-extensions' : ['.*'],
            'output-extensions' : ['.html'],
            'extensions' : ("Which Markdown extensions to enable.", { 'toc' : {} }),
            }

    def capture_markdown_logger(self):
        markdown_logger = logging.getLogger('MARKDOWN')
        markdown_logger.addHandler(self.doc.wrapper.log.handlers[-1])

    def initialize_markdown(self):
        extension_configs = self.setting('extensions')
        extensions = extension_configs.keys()

        dbg = "Initializing Markdown with extensions: %s and extension configs: %s"
        self.log_debug(dbg % (json.dumps(extensions), json.dumps(extension_configs)))

        try:
            md = markdown.Markdown(
                    extensions=extensions,
                    extension_configs=extension_configs)
        except ValueError as e:
            self.log_debug(e.message)
            if "markdown.Extension" in e.message:
                raise dexy.exceptions.UserFeedback("There's a problem with the markdown extensions you specified.")
            else:
                raise
        except KeyError as e:
            raise dexy.exceptions.UserFeedback("Couldn't find a markdown extension option matching '%s'" % e.message)

        return md

    def process_text(self, input_text):
        self.capture_markdown_logger()
        md = self.initialize_markdown()
        return md.convert(input_text)

Content © 2013 Dr. Ana Nelson | Site Design © Copyright 2011 Andre Gagnon | All Rights Reserved.