aboutsummaryrefslogtreecommitdiff
path: root/docs/extensions
diff options
context:
space:
mode:
Diffstat (limited to 'docs/extensions')
-rw-r--r--docs/extensions/Abbreviations.txt53
-rw-r--r--docs/extensions/CodeHilite.txt113
-rw-r--r--docs/extensions/Definition_Lists.txt55
-rw-r--r--docs/extensions/Fenced_Code_Blocks.txt63
-rw-r--r--docs/extensions/HTML_Tidy.txt27
-rw-r--r--docs/extensions/HeaderId.txt104
-rw-r--r--docs/extensions/ImageLinks.txt27
-rw-r--r--docs/extensions/Meta-Data.txt88
-rw-r--r--docs/extensions/RSS.txt35
-rw-r--r--docs/extensions/Tables.txt53
-rw-r--r--docs/extensions/Tables_of_Contents.txt50
-rw-r--r--docs/extensions/WikiLinks.txt144
-rw-r--r--docs/extensions/abbreviations.md51
-rw-r--r--docs/extensions/admonition.md115
-rw-r--r--docs/extensions/api.md886
-rw-r--r--docs/extensions/attr_list.md202
-rw-r--r--docs/extensions/code_hilite.md308
-rw-r--r--docs/extensions/definition_lists.md58
-rw-r--r--docs/extensions/extra.md62
-rw-r--r--docs/extensions/extra.txt43
-rw-r--r--docs/extensions/fenced_code_blocks.md269
-rw-r--r--docs/extensions/footnotes.md133
-rw-r--r--docs/extensions/footnotes.txt62
-rw-r--r--docs/extensions/index.md87
-rw-r--r--docs/extensions/index.txt44
-rw-r--r--docs/extensions/legacy_attrs.md66
-rw-r--r--docs/extensions/legacy_em.md31
-rw-r--r--docs/extensions/md_in_html.md237
-rw-r--r--docs/extensions/meta_data.md113
-rw-r--r--docs/extensions/nl2br.md41
-rw-r--r--docs/extensions/sane_lists.md104
-rw-r--r--docs/extensions/smarty.md84
-rw-r--r--docs/extensions/tables.md87
-rw-r--r--docs/extensions/toc.md232
-rw-r--r--docs/extensions/wikilinks.md154
35 files changed, 3320 insertions, 961 deletions
diff --git a/docs/extensions/Abbreviations.txt b/docs/extensions/Abbreviations.txt
deleted file mode 100644
index fa54d3c..0000000
--- a/docs/extensions/Abbreviations.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-Abbreviations
--------------
-
-Summary
--------
-
-The Markdown Abbreviation Extension adds the ability to define abbreviations.
-Specifically, any defined abbreviation is wrapped in an `<abbr>` tag.
-
-The Abbreviation extension is included in the standard Markdown library.
-
-Syntax
-------
-
-Abbreviations are defined using the syntax established in
-[PHP Markdown Extra][php].
-
-[php]: http://www.michelf.com/projects/php-markdown/extra/#abbr
-
-Thus, the following text (taken from the above referenced PHP documentation):
-
- The HTML specification
- is maintained by the W3C.
-
- *[HTML]: Hyper Text Markup Language
- *[W3C]: World Wide Web Consortium
-
-will be rendered like so:
-
- <p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification
- is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p>
-
-Usage
------
-
-From the Python interpreter:
-
- >>> import markdown
- >>> text = """
- ... Some text with an ABBR.
- ...
- ... *[ABBR]: Abbreviation
- ... """
- >>> html = markdown.markdown(text, ['abbr'])
-
-To use with other extensions, just add them to the list, like this:
-
- >>> html = markdown.markdown(text, ['abbr', 'footnotes'])
-
-Abbreviations can also be called from the command line using Markdown's `-x`
-parameter, like so:
-
- markdown.py -x abbr source.txt > output.html
diff --git a/docs/extensions/CodeHilite.txt b/docs/extensions/CodeHilite.txt
deleted file mode 100644
index 482ad60..0000000
--- a/docs/extensions/CodeHilite.txt
+++ /dev/null
@@ -1,113 +0,0 @@
-CodeHilite
-==========
-
-Summary
--------
-
-The CodeHilite Extension adds code/syntax highlighting to standard
-Python-Markdown code blocks using [Pygments][].
-
-[Python-Markdown]: http://www.freewisdom.org/projects/python-markdown/
-[Pygments]: http://pygments.org/
-
-This extension is included in the Markdown library.
-
-Setup
------
-
-You will also need to [download][dl] and install the Pygments package on your
-`PYTHONPATH`. You will need to determine the appropriate CSS classes and create
-appropriate rules for them, which are either defined in or linked from the
-header of your HTML templates. See the excellent [documentation][] for more
-details. If no language is defined, Pygments will attempt to guess the
-language. When that fails, the code block will display as un-highlighted code.
-
-[dl]: http://pygments.org/download/
-[documentation]: http://pygments.org/docs
-
-**Note:** The css and/or javascript is not included as part of this extension
-but shall always be provided by the end user.
-
-Syntax
-------
-
-The CodeHilite Extension follows the same [syntax][] as regular Markdown code
-blocks, with one exception. The hiliter needs to know what language to use for
-the code block. There are three ways to tell the hiliter what language the code
-block contains and each one has a different result.
-
-[syntax]: http://daringfireball.net/projects/markdown/syntax#precode
-
-###SheBang (with path)
-
-If the first line of the codeblock contains a shebang, the language is derived
-from that and line numbers are used.
-
- #!/usr/bin/python
- # Code goes here ...
-
-Will result in:
-
- #!/usr/bin/python
- # Code goes here ...
-
-
-###SheBang (no path)
-
-If the first line contains a shebang, but the shebang line does not contain a
-path (a single `/` or even a space), then that line is removed from the code
-block before processing. Line numbers are used.
-
- #!python
- # Code goes here ...
-
-Will result in:
-
- # Code goes here ...
-
-####Colons
-
-If the first line begins with three or more colons, the text following the
-colons identifies the language. The first line is removed from the code block
-before processing and line numbers are not used.
-
- :::python
- # Code goes here ...
-
-Will result in:
-
- # Code goes here ...
-
-###When No Language is Defined
-
-CodeHilite is completely backward compatible so that if a code block is
-encountered that does not define a language, the block is simple wrapped in
-`<pre>` tags and output. Note: one exception would be that the Pygments
-highlighting engine will try to guess the language. Upon failure, the same
-behavior will happen as described here.
-
- # Code goes here ...
-
-Will result in:
-
- # Code goes here ...
-
-Lets see the source for that:
-
- <div class="codehilite" ><pre><code># Code goes here ...
- </code></pre></div>
-
-Usage
------
-
-From the Python interpreter:
-
- >>> html = markdown.markdown(text, ['codehilite'])
-
-If you want every code block to have line numbers, even when using colons
-(`:::`) for language identification, the setting `force_linenos` is available
-to do so.
-
- >>> html = markdown.markdown(text,
- ... ['codehilite(force_linenos=True)']
- ... )
diff --git a/docs/extensions/Definition_Lists.txt b/docs/extensions/Definition_Lists.txt
deleted file mode 100644
index 983070d..0000000
--- a/docs/extensions/Definition_Lists.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-Definition Lists
-----------------
-
-Summary
--------
-
-The Definition List Extension adds the ability to create definition list in
-Markdown documents.
-
-This extension is included in the standard Markdown library.
-
-Syntax
-------
-
-Definition lists are defined using the syntax established in
-[PHP Markdown Extra][php].
-
-[php]: http://www.michelf.com/projects/php-markdown/extra/#def-list
-
-Thus, the following text (taken from the above referenced PHP documentation):
-
- Apple
- : Pomaceous fruit of plants of the genus Malus in
- the family Rosaceae.
-
- Orange
- : The fruit of an evergreen tree of the genus Citrus.
-
-will be rendered like so:
-
- <dl>
- <dt>Apple</dt>
- <dd>Pomaceous fruit of plants of the genus Malus in
- the family Rosaceae.</dd>
-
- <dt>Orange</dt>
- <dd>The fruit of an evergreen tree of the genus Citrus.</dd>
- </dl>
-
-
-Usage
------
-
-From the Python interpreter:
-
- >>> html = markdown.markdown(text, ['def_list'])
-
-To use with other extensions, just add them to the list, like this:
-
- >>> html = markdown.markdown(text, ['def_list', 'footnotes'])
-
-The extension can also be called from the command line using Markdown's `-x`
-parameter:
-
- markdown.py -x def_list source.txt > output.html
diff --git a/docs/extensions/Fenced_Code_Blocks.txt b/docs/extensions/Fenced_Code_Blocks.txt
deleted file mode 100644
index 6b1ba76..0000000
--- a/docs/extensions/Fenced_Code_Blocks.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-Fenced Code Blocks
-==================
-
-Summary
--------
-
-This extension adds a secondary way to define code blocks which overcomes a few
-limitations of the indented code blocks.
-
-This extension is included in the standard Markdown library.
-
-Syntax
-------
-
-Fenced Code Blocks are defined using the syntax established in
-[PHP Markdown Extra][php].
-
-[php]: http://www.michelf.com/projects/php-markdown/extra/#fenced-code-blocks
-
-Thus, the following text (taken from the above referenced PHP documentation):
-
- This is a paragraph introducing:
-
- ~~~~~~~~~~~~~~~~~~~~
- a one-line code block
- ~~~~~~~~~~~~~~~~~~~~
-
-Fenced code blocks can have a blank line as the first and/or last line of a
-code block and they can also come immediately after a list item without becoming
-part of the list.
-
-In addition to PHP Extra's syntax, you can define the language of the code
-block for use by syntax highlighters etc. The language will be assigned as a
-class attribute of the ``<code>`` element in the output. Therefore, you should
-define the language as you would a css class - ``.language``. For consistency
-with other markdown syntax, the language can *optionally* be wrapped in curly
-brackets:
-
- ~~~~{.python}
- # python code
- ~~~~
-
- ~~~~.html
- <p>HTML Document</p>
- ~~~~
-
-The above will output:
-
- <pre><code class="python"># python code
- </code></pre>
-
- <pre><code class="html">&lt;p&gt;HTML Document&lt;/p&gt;
- </code></pre>
-
-Usage
------
-
-From the Python interpreter:
-
- >>> html = markdown.markdown(text, ['fenced_code'])
-
-
-
diff --git a/docs/extensions/HTML_Tidy.txt b/docs/extensions/HTML_Tidy.txt
deleted file mode 100644
index 52f991f..0000000
--- a/docs/extensions/HTML_Tidy.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-HTML Tidy
-=========
-
-Runs [HTML Tidy][] on the output of Python-Markdown using the [uTidylib][]
-Python wrapper. Both libtidy and uTidylib must be installed on your system.
-
-This extension is available in the standard Markdown library since version 2.0.
-
-[HTML Tidy]: http://tidy.sourceforge.net/
-[uTidylib]: http://utidylib.berlios.de/
-
-Note than any Tidy [options][] can be passed in as extension configs. So,
-for example, to output HTML rather than XHTML, set ``output_xhtml=0``. To
-indent the output, set ``indent=auto`` and to have Tidy wrap the output in
-``<html>`` and ``<body>`` tags, set ``show_body_only=0``. See Tidy's
-[options][] for a full list of the available options. The defaults are set to
-most closely match Markdowns defaults with the exception that you get much
-better pretty-printing.
-
-[options]: http://tidy.sourceforge.net/docs/quickref.html
-
-Note that options set in this extension will override most any other settings
-passed on to Markdown (such as "output_format"). Unlike Markdown, this extension
-will also treat raw HTML no different than that output by Markdown. In other
-words, it may munge a document authors carefully crafted HTML. Of course, it
-may also transform poorly formed raw HTML into nice, valid HTML. Take these
-things into consideration when electing to use this extension.
diff --git a/docs/extensions/HeaderId.txt b/docs/extensions/HeaderId.txt
deleted file mode 100644
index efd1eb8..0000000
--- a/docs/extensions/HeaderId.txt
+++ /dev/null
@@ -1,104 +0,0 @@
-HeaderId
-========
-
-Summary
--------
-
-An extension to Python-Markdown that adds an 'id' attribute to HTML header
-elements (h1-h6) in markdown's output.
-
-This extension is included in the standard Markdown library.
-
-Syntax
-------
-
-The basic syntax follows [PHP Markdown Extra][]'s implementation:
-
-[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/#header-id
-
- Header 1 {#header1}
- ========
-
- ## Header 2 ## {#header2}
-
-will result in the following HTML:
-
- <h1 id="header1">Header 1</h1>
-
- <h2 id="header2">Header 2</h2>
-
-However, there is much more that this extension does.
-
-By default, all headers will automatically have unique "id" attributes
-generated based upon the text of the header (See below to turn this off).
-Note this example in which all three headers would have the same "id":
-
- #Header
- #Another Header {#header}
- #Header
-
-Results in:
-
- <h1 id="header">Header</h1>
- <h1 id="header_1">Another Header</h1>
- <h1 id="header_2">Third Header</h1>
-
-Configuring the Output
-----------------------
-
-The HeaderId extension has two configuration settings:
-
-* **level**: Base level for headers.
-
- Default: `1`
-
-* **forceid**: Force all headers to have an id.
-
- Default: `True`
-
-The `level` setting allows you to automatically adjust the header levels to fit
-within the hierarchy of your html templates. For example, the markdown text for
-this page should not contain any headers higher than level 3 (`<h3>`).
-Therefore, do the following:
-
- >>> text = '''
- ... #Some Header
- ... ## Next Level'''
- >>> html = markdown.markdown(text, ['headerid(level=3)'])
- >>> print html
- <h3 id="some_header">Some Header</h3>
- <h4 id="next_level">Next Level</h4>'
-
-The `forceid` setting turns on or off the automatically generated ids for
-headers that do not have one explicitly defined.
-
- >>> text = '''
- ... # Some Header
- ... # Header with ID # { #foo }'''
- >>> html = markdown.markdown(text, ['headerid(forceid=False)'])
- >>> print html
- <h1>Some Header</h1>
- <h1 id="foo">Header with ID</h1>
-
-Using with Meta-Data
---------------------
-
-The HeaderId Extension also supports the [[Meta-Data]] Extension. Please see the documentation for that extension for specifics. The supported meta-data keywords are:
-
-* `header_level`
-* `header_forceid`
-
-When used, the meta-data will override the settings provided through the
-`extension_configs` interface.
-
-This document:
-
- header_level: 2
- header_forceid: Off
-
- # A Header
-
-
-Will result in the following output:
-
- <h2>A Header</h2>
diff --git a/docs/extensions/ImageLinks.txt b/docs/extensions/ImageLinks.txt
deleted file mode 100644
index db4f99f..0000000
--- a/docs/extensions/ImageLinks.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-ImageLinks
-==========
-
-Summary
--------
-
-ImageLinks is a Python-Markdown extension that provides a mechanism for
-defining mini-photo galleries within a markdown document.
-
-This extension is part of the Markdown library since 2.0.
-
-Syntax
-------
-
-Turns paragraphs like
-
- <~~~~~~~~~~~~~~~~~~~~~~~~
- dir/subdir
- dir/subdir
- dir/subdir
- ~~~~~~~~~~~~~~
- dir/subdir
- dir/subdir
- dir/subdir
- ~~~~~~~~~~~~~~~~~~~>
-
-Into mini-photo galleries.
diff --git a/docs/extensions/Meta-Data.txt b/docs/extensions/Meta-Data.txt
deleted file mode 100644
index 982ea67..0000000
--- a/docs/extensions/Meta-Data.txt
+++ /dev/null
@@ -1,88 +0,0 @@
-Meta-Data
-=========
-
-Summary
--------
-
-An extension to Python-Markdown that adds a syntax for defining meta-data about
-a document. The Meta-Data extension is inspired by and follows the syntax of
-[MultiMarkdown][]. Currently, this extension does not use the meta-data in any
-way, but simply provides it as a `Meta` attribute of a markdown instance for
-use by other extensions or directly by your python code.
-
-[MultiMarkdown]: http://fletcherpenney.net/MultiMarkdown_Syntax_Guide#metadata
-
-This extension has been a part of the Markdown library since 2.0.
-
-Syntax
-------
-
-Meta-data consists of a series of keywords and values defined at the beginning
-of a markdown document like this:
-
- Title: My Document
- Summary: A brief description of my document.
- Authors: Waylan Limberg
- John Doe
- Date: October 2, 2007
- blank-value:
- base_url: http://example.com
-
- This is the first paragraph of the document.
-
-The keywords are case-insensitive and may consist of letters, numbers,
-underscores and dashes and must end with a colon. The values consist of
-anything following the colon on the line and may even be blank. If a line is
-indented 4 or more spaces, that line is assumed to be an additional line of the
-value for the previous keyword. A keyword may have as many lines as desired.
-The first blank line ends all meta-data for the document. Therefore, the first
-line of a document must not be blank. All meta-data is stripped from the
-document prior to any further processing by markdown.
-
-Accessing the Meta-Data
------------------------
-
-The meta-data is made available as a python Dict in the `Meta` attribute of an
-instance of the Markdown class. For example, using the above document:
-
- >>> md = markdown.Markdown(extensions = ['meta'])
- >>> html = md.convert(text)
- >>> # Meta-data has been stripped from output
- >>> print html
- <p>This is the first paragraph of the document.</p>
-
- >>> # View meta-data
- >>> print md.Meta
- {
- 'title' : ['My Document'],
- 'summary' : ['A brief description of my document.'],
- 'authors' : ['Waylan Limberg', 'John Doe'],
- 'date' : ['October 2, 2007'],
- 'blank-value' : [''],
- 'base_url' : ['http://example.com']
- }
-
-Note that the keys are all lowercase and the values consist of a list of
-strings where each item is one line for that key. This way, one could preserve
-line breaks if desired. Or the items could be joined where appropriate. No
-assumptions are made regarding the data. It is simply passed as found to the
-`Meta` attribute.
-
-Perhaps the meta-data could be passed into a template system, or used by
-various markdown extensions. The possibilities are left to the imagination of
-the developer.
-
-Compatible Extensions
----------------------
-
-The following are extensions currently known to work with the Meta-Data
-Extension and the keywords they are known to support:
-
-* [[HeaderId]]
- * `header_level`
- * `header_forceid`
-* [[WikiLinks]]
- * `wiki_base_url`
- * `wiki_end_url`
- * `wiki_html_class`
-
diff --git a/docs/extensions/RSS.txt b/docs/extensions/RSS.txt
deleted file mode 100644
index f2ecf0c..0000000
--- a/docs/extensions/RSS.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-RSS
-===
-
-Summary
--------
-
-An extension to Python-Markdown that outputs a markdown document as RSS. This
-extension has been included with Python-Markdown since 1.7 and should be
-available to anyone who has a typical install of Python-Markdown.
-
-Usage
------
-
-From the Python interpreter:
-
- >>> import markdown
- >>> text = "Some markdown document."
- >>> rss = markdown.markdown(text, ['rss'])
-
-Configuring the Output
-----------------------
-
-An RSS document includes some data about the document (URI, author, title) that
-will likely need to be configured for your needs. Therefore, three configuration
-options are available:
-
-* **URL** : The Main URL for the document.
-* **CREATOR** : The Feed creator's name.
-* **TITLE** : The title for the feed.
-
-An example:
-
- >>> rss = markdown.markdown(text, extensions = \
- ... ['rss(URL=http://example.com,CREATOR=JOHN DOE,TITLE=My Document)']
- ... )
diff --git a/docs/extensions/Tables.txt b/docs/extensions/Tables.txt
deleted file mode 100644
index 63d6849..0000000
--- a/docs/extensions/Tables.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-Tables
-----------------
-
-Summary
--------
-
-The Table Extension adds the ability to create tables in Markdown documents.
-
-This extension is included in the standard Markdown library.
-
-Syntax
-------
-
-Tables are defined using the syntax established in [PHP Markdown Extra][php].
-
-[php]: http://www.michelf.com/projects/php-markdown/extra/#table
-
-Thus, the following text (taken from the above referenced PHP documentation):
-
-First Header | Second Header
-------------- | -------------
-Content Cell | Content Cell
-Content Cell | Content Cell
-
-will be rendered as:
-
-<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>
-
-Usage
------
-
-From the Python interpreter:
-
- >>> html = markdown.markdown(text, ['tables'])
-
diff --git a/docs/extensions/Tables_of_Contents.txt b/docs/extensions/Tables_of_Contents.txt
deleted file mode 100644
index 032c25c..0000000
--- a/docs/extensions/Tables_of_Contents.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-Table of Contents
-=================
-
-Summary
--------
-
-Adds a Table of Contents to a Markdown document.
-
-This extension is included with the Markdown library since version 2.0.
-
-Syntax
-------
-
-Place a marker in the document where you would like the table of contents to
-appear. Then, a nested list of all the headers in the document will replace the
-marker. The marker defaults to ``[TOC]`` so the following document:
-
- [TOC]
-
- # Header 1
-
- ## Header 2
-
-would generate the following output:
-
- <div class="toc">
- <ul>
- <li><a href="#header-1">Header 1</a></li>
- <ul>
- <li><a href="#header-2">Header 2</a></li>
- </ul>
- </ul>
- </div>
- <h1 id="header-1">Header 1</h1>
- <h1 id="header-2">Header 2</h1>
-
-Configuration Options
----------------------
-
-The following options are provided to configure the output:
-
-* **marker**: Text to find and replace with the Table of Contents. Defaults
- to ``[TOC]``.
-* **slugify**: Callable to generate anchors based on header text. Defaults to a
- built in ``slugify`` method. The callable must accept one argument which
- contains the text content of the header and return a string which will be
- used as the anchor text.
-* **title**: Title to insert in TOC ``<div>``. Defaults to ``None``.
-* **anchorlink**: Set to ``True`` to have the headers link to themselves.
- Default is ``False``.
diff --git a/docs/extensions/WikiLinks.txt b/docs/extensions/WikiLinks.txt
deleted file mode 100644
index 8bbead5..0000000
--- a/docs/extensions/WikiLinks.txt
+++ /dev/null
@@ -1,144 +0,0 @@
-WikiLinks
-=========
-
-Summary
--------
-
-An extension to Python-Markdown that adds [WikiLinks][]. Specifically, any
-``[[bracketed]]`` word is converted to a link.
-
-[WikiLinks]: http://en.wikipedia.org/wiki/Wikilink
-
-This extension has been included in the Markdown library since 2.0.
-
-Syntax
-------
-
-A ``[[bracketed]]`` word is any combination of upper or lower case letters,
-number, dashes, underscores and spaces surrounded by double brackets. Therefore
-
- [[Bracketed]]
-
-Would produce the following html:
-
- <a href="/Bracketed/" class="wikilink">Bracketed</a>
-
-Note that wikilinks are automatically assigned `class="wikilink"` making it
-easy to style wikilinks differently from other links on a page if one so
-desires. See below for ways to alter the class.
-
-You should also note that when a space is used, the space is converted to an
-underscore in the link but left as-is in the label. Perhaps an example
-would illustrate this best:
-
- [[Wiki Link]]
-
-Becomes
-
- <a href="/Wiki_Link/" class="wikilink">Wiki Link</a>
-
-Usage
------
-
-From the Python interpreter:
-
- >>> text = "Some text with a [[WikiLink]]."
- >>> html = markdown.markdown(text, ['wikilink'])
-
-The default behavior is to point each link to the document root of the current
-domain and close with a trailing slash. Additionally, each link is assigned to
-the html class `wikilink`. This may not always be desirable. Therefore, one can
-customize that behavior within Python code. Three settings are provided to
-change the default behavior:
-
-1. **base_url**: String to append to beginning of URL.
-
- Default: `'/'`
-
-2. **end_url**: String to append to end of URL.
-
- Default: `'/'`
-
-3. **html_class**: CSS hook. Leave blank for none.
-
- Default: `'wikilink'`
-
-4. **build_url**: Callable which formats the URL from it's parts.
-
-For an example, let us suppose links should always point to the subdirectory
-`/wiki/` and end with `.html`
-
- >>> html = markdown.markdown(text,
- ... ['wikilink(base_url=/wiki/,end_url=.html)']
- ... )
-
-The above would result in the following link for `[[WikiLink]]`.
-
- <a href="/wiki/WikiLink.html" class="wikilink">WikiLink</a>
-
-If you want to do more that just alter the base and/or end of the URL, you
-could also pass in a callable which must accept three arguments (``label``,
-``base``, and ``end``). The callable must return the URL in it's entirety.
-
- def my_url_builder(label, base, end):
- # do stuff
- return url
-
- md = markdown.Markdown(
- extensions=['wikilinks],
- extension_configs={'wikilinks' : [('build_url', my_url_builder)]}
- )
-
-
-The option is also provided to change or remove the class attribute.
-
- >>> html = markdown.markdown(text,
- ... ['wikilink(base_url=myclass)']
- ... )
-
-Would cause all wikilinks to be assigned to the class `myclass`.
-
- <a href="/WikiLink/" class="myclass">WikiLink</a>
-
-The same options can be used on the command line as well:
-
- python markdown.py -x wikilink(base_url=http://example.com/,end_url=.html,html_class=foo) src.txt
-
-Some may prefer the more complex format when calling the `Markdown` class directly:
-
- >>> md = markdown.Markdown(
- ... extensions = ['wikilink'],
- ... extension_configs = {'wikilink': [
- ... ('base_url', 'http://example.com/'),
- ... ('end_url', '.html'),
- ... ('html_class', '') ]},
- ... safe_mode = True
- ... )
- >>> html = md.convert(text)
-
-Using with Meta-Data
---------------------
-
-The WikiLink Extension also supports the [[Meta-Data]] Extension. Please see
-the documentation for that extension for specifics. The supported meta-data
-keywords are:
-
-* `wiki_base_url`
-* `wiki_end_url`
-* `wiki_html_class`
-
-When used, the meta-data will override the settings provided through the
-`extension_configs` interface.
-
-This document:
-
- wiki_base_url: http://example.com/
- wiki_end_url: .html
- wiki_html_class:
-
- A [[WikiLink]] in the first paragraph.
-
-would result in the following output (notice the blank `wiki_html_class`):
-
- <p>A <a href="http://example.com/WikiLink.html">WikiLink</a> in the first paragraph.</p>
-
diff --git a/docs/extensions/abbreviations.md b/docs/extensions/abbreviations.md
new file mode 100644
index 0000000..d03651f
--- /dev/null
+++ b/docs/extensions/abbreviations.md
@@ -0,0 +1,51 @@
+title: Abbreviations Extension
+
+Abbreviations
+=============
+
+Summary
+-------
+
+The Abbreviations extension adds the ability to define abbreviations.
+Specifically, any defined abbreviation is wrapped in an `<abbr>` tag.
+
+The Abbreviations extension is included in the standard Markdown library.
+
+Syntax
+------
+
+Abbreviations are defined using the syntax established in
+[PHP Markdown Extra][php].
+
+[php]: http://www.michelf.com/projects/php-markdown/extra/#abbr
+
+Thus, the following text (taken from the above referenced PHP documentation):
+
+```md
+The HTML specification
+is maintained by the W3C.
+
+*[HTML]: Hyper Text Markup Language
+*[W3C]: World Wide Web Consortium
+```
+
+will be rendered as:
+
+```html
+<p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification
+is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.</p>
+```
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `abbr` as the name
+of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['abbr'])
+```
diff --git a/docs/extensions/admonition.md b/docs/extensions/admonition.md
new file mode 100644
index 0000000..4f79d48
--- /dev/null
+++ b/docs/extensions/admonition.md
@@ -0,0 +1,115 @@
+title: Admonition Extension
+
+Admonition
+==========
+
+Summary
+-------
+
+The Admonition extension adds [rST-style][rST] admonitions to Markdown documents.
+
+This extension is included in the standard Markdown library.
+
+[rST]: http://docutils.sourceforge.net/docs/ref/rst/directives.html#specific-admonitions
+
+Syntax
+------
+
+Admonitions are created using the following syntax:
+
+```md
+!!! type "optional explicit title within double quotes"
+ Any number of other indented markdown elements.
+
+ This is the second paragraph.
+```
+
+`type` will be used as the CSS class name and as default title. It must be a
+single word. So, for instance:
+
+```md
+!!! note
+ You should note that the title will be automatically capitalized.
+```
+
+will render:
+
+```html
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>You should note that the title will be automatically capitalized.</p>
+</div>
+```
+
+Optionally, you can use custom titles. For instance:
+
+```md
+!!! danger "Don't try this at home"
+ ...
+```
+
+will render:
+
+```html
+<div class="admonition danger">
+<p class="admonition-title">Don't try this at home</p>
+<p>...</p>
+</div>
+```
+
+If you don't want a title, use a blank string `""`:
+
+```md
+!!! important ""
+ This is an admonition box without a title.
+```
+
+results in:
+
+```html
+<div class="admonition important">
+<p>This is an admonition box without a title.</p>
+</div>
+```
+
+You can also provide additional CSS class names separated by spaces. The first
+class should be the "type." For example:
+
+```md
+!!! danger highlight blink "Don't try this at home"
+ ...
+```
+
+will render:
+
+```html
+<div class="admonition danger highlight blink">
+<p class="admonition-title">Don't try this at home</p>
+<p>...</p>
+</div>
+```
+
+rST suggests the following "types": `attention`, `caution`, `danger`, `error`,
+`hint`, `important`, `note`, `tip`, and `warning`; however, you're free to use
+whatever you want.
+
+Styling
+-------
+
+There is no CSS included as part of this extension. Check out the default
+[Sphinx][sphinx] theme for inspiration.
+
+[sphinx]: https://www.sphinx-doc.org/en/master/
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `admonition` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['admonition'])
+```
diff --git a/docs/extensions/api.md b/docs/extensions/api.md
new file mode 100644
index 0000000..d7eb689
--- /dev/null
+++ b/docs/extensions/api.md
@@ -0,0 +1,886 @@
+title: Extensions API
+
+# Writing Extensions for Python-Markdown
+
+Python-Markdown includes an API for extension writers to plug their own custom functionality and syntax into the
+parser. An extension will patch into one or more stages of the parser:
+
+* [*Preprocessors*](#preprocessors) alter the source before it is passed to the parser.
+* [*Block Processors*](#blockprocessors) work with blocks of text separated by blank lines.
+* [*Tree Processors*](#treeprocessors) modify the constructed ElementTree
+* [*Inline Processors*](#inlineprocessors) are common tree processors for inline elements, such as `*strong*`.
+* [*Postprocessors*](#postprocessors) munge of the output of the parser just before it is returned.
+
+The parser loads text, applies the preprocessors, creates and builds an [ElementTree][ElementTree] object from the
+block processors and inline processors, renders the ElementTree object as Unicode text, and then then applies the
+postprocessors.
+
+There are classes and helpers provided to ease writing your extension. Each part of the API is discussed in its
+respective section below. Additionally, you can walk through the [Tutorial on Writing Extensions][tutorial]; look at
+some of the [Available Extensions][] and their [source code][extension source]. As always, you may report bugs, ask
+for help, and discuss various other issues on the [bug tracker].
+
+## Phases of processing {: #stages }
+
+### Preprocessors {: #preprocessors }
+
+Preprocessors munge the source text before it is passed to the Markdown parser. This is an excellent place to clean up
+bad characters or to extract portions for later processing that the parser may otherwise choke on.
+
+Preprocessors inherit from `markdown.preprocessors.Preprocessor` and implement a `run` method, which takes a single
+parameter `lines`. This parameter is the entire source text stored as a list of Unicode strings, one per line. `run`
+should return its processed list of Unicode strings, one per line.
+
+#### Example
+
+This simple example removes any lines with 'NO RENDER' before processing:
+
+```python
+from markdown.preprocessors import Preprocessor
+import re
+
+class NoRender(Preprocessor):
+ """ Skip any line with words 'NO RENDER' in it. """
+ def run(self, lines):
+ new_lines = []
+ for line in lines:
+ m = re.search("NO RENDER", line)
+ if not m:
+ # any line without NO RENDER is passed through
+ new_lines.append(line)
+ return new_lines
+```
+
+#### Usages
+
+Some preprocessors in the Markdown source tree include:
+
+| Class | Kind | Description |
+| ------------------------------|-----------|------------------------------------------------- |
+| [`NormalizeWhiteSpace`][c1] | built-in | Normalizes whitespace by expanding tabs, fixing `\r` line endings, etc. |
+| [`HtmlBlockPreprocessor`][c2] | built-in | Removes html blocks from the text and stores them for later processing |
+| [`ReferencePreprocessor`][c3] | built-in | Removes reference definitions from text and stores for later processing |
+| [`MetaPreprocessor`][c4] | extension | Strips and records meta data at top of documents |
+| [`FootnotesPreprocessor`][c5] | extension | Removes footnote blocks from the text and stores them for later processing |
+
+[c1]: https://github.com/Python-Markdown/markdown/blob/master/markdown/preprocessors.py
+[c2]: https://github.com/Python-Markdown/markdown/blob/master/markdown/preprocessors.py
+[c3]: https://github.com/Python-Markdown/markdown/blob/master/markdown/preprocessors.py
+[c4]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/meta.py
+[c5]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/footnotes.py
+
+### Block Processors {: #blockprocessors }
+
+A block processor parses blocks of text and adds new elements to the `ElementTree`. Blocks of text, separated from
+other text by blank lines, may have a different syntax and produce a differently structured tree than other Markdown.
+Block processors excel at code formatting, equation layouts, and tables.
+
+Block processors inherit from `markdown.blockprocessors.BlockProcessor`, are passed `md.parser` on initialization, and
+implement both the `test` and `run` methods:
+
+* `test(self, parent, block)` takes two parameters: `parent` is the parent `ElementTree` element and `block` is a
+ single, multi-line, Unicode string of the current block. `test`, often a regular expression match, returns a true
+ value if the block processor's `run` method should be called to process starting at that block.
+* `run(self, parent, blocks)` has the same `parent` parameter as `test`; and `blocks` is the list of all remaining
+ blocks in the document, starting with the `block` passed to `test`. `run` may return `False` (not `None`) to signal
+ failure, meaning that it did not process the blocks after all. On success, `run` is expected to `pop` one or more
+ blocks from the front of `blocks` and attach new nodes to `parent`.
+
+Crafting block processors is more involved and flexible than the other processors, involving controlling recursive
+parsing of the block's contents and managing state across invocations. For example, a blank line is allowed in
+indented code, so the second invocation of the inline code processor appends to the element tree generated by the
+previous call. Other block processors may insert new text into the `blocks` list, signal to future calls of itself,
+and more.
+
+To make writing these complex beasts more tractable, three convenience functions have been provided by the
+`BlockProcessor` parent class:
+
+* `lastChild(parent)` returns the last child of the given element or `None` if it has no children.
+* `detab(text)` removes one level of indent (four spaces by default) from the front of each line of the given
+ multi-line, text string, until a non-blank line is indented less.
+* `looseDetab(text, level)` removes multiple levels
+ of indent from the front of each line of `text` but does not affect lines indented less.
+
+Also, `BlockProcessor` provides the fields `self.tab_length`, the tab length (default 4), and `self.parser`, the
+current `BlockParser` instance.
+
+#### BlockParser
+
+`BlockParser`, not to be confused with `BlockProcessor`, is the class used by Markdown to cycle through all the
+registered block processors. You should never need to create your own instance; use `self.parser` instead.
+
+The `BlockParser` instance provides a stack of strings for its current state, which your processor can push with
+`self.parser.set(state)`, pop with `self.parser.reset()`, or check the the top state with
+`self.parser.isstate(state)`. Be sure your code pops the states it pushes.
+
+The `BlockParser` instance can also be called recursively, that is, to process blocks from within your block
+processor. There are three methods:
+
+* `parseDocument(lines)` parses a list of lines, each a single-line Unicode string, returning a complete
+ `ElementTree`.
+* `parseChunk(parent, text)` parses a single, multi-line, possibly multi-block, Unicode string `text` and attaches the
+ resulting tree to `parent`.
+* `parseBlocks(parent, blocks)` takes a list of `blocks`, each a multi-line Unicode string without blank lines, and
+ attaches the resulting tree to `parent`.
+
+For perspective, Markdown calls `parseDocument` which calls `parseChunk` which calls `parseBlocks` which calls your
+block processor, which, in turn, might call one of these routines.
+
+#### Example
+
+This example calls out important paragraphs by giving them a border. It looks for a fence line of exclamation points
+before and after and renders the fenced blocks into a new, styled `div`. If it does not find the ending fence line,
+it does nothing.
+
+Our code, like most block processors, is longer than other examples:
+
+```python
+def test_block_processor():
+ class BoxBlockProcessor(BlockProcessor):
+ RE_FENCE_START = r'^ *!{3,} *\n' # start line, e.g., ` !!!! `
+ RE_FENCE_END = r'\n *!{3,}\s*$' # last non-blank line, e.g, '!!!\n \n\n'
+
+ def test(self, parent, block):
+ return re.match(self.RE_FENCE_START, block)
+
+ def run(self, parent, blocks):
+ original_block = blocks[0]
+ blocks[0] = re.sub(self.RE_FENCE_START, '', blocks[0])
+
+ # Find block with ending fence
+ for block_num, block in enumerate(blocks):
+ if re.search(self.RE_FENCE_END, block):
+ # remove fence
+ blocks[block_num] = re.sub(self.RE_FENCE_END, '', block)
+ # render fenced area inside a new div
+ e = etree.SubElement(parent, 'div')
+ e.set('style', 'display: inline-block; border: 1px solid red;')
+ self.parser.parseBlocks(e, blocks[0:block_num + 1])
+ # remove used blocks
+ for i in range(0, block_num + 1):
+ blocks.pop(0)
+ return True # or could have had no return statement
+ # No closing marker! Restore and do nothing
+ blocks[0] = original_block
+ return False # equivalent to our test() routine returning False
+
+ class BoxExtension(Extension):
+ def extendMarkdown(self, md):
+ md.parser.blockprocessors.register(BoxBlockProcessor(md.parser), 'box', 175)
+```
+
+Start with this example input:
+
+``` text
+A regular paragraph of text.
+
+!!!!!
+First paragraph of wrapped text.
+
+Second Paragraph of **wrapped** text.
+!!!!!
+
+Another regular paragraph of text.
+```
+
+The fenced text adds one node with two children to the tree:
+
+* `div`, with a `style` attribute. It renders as
+ `<div style="display: inline-block; border: 1px solid red;">...</div>`
+ * `p` with text `First paragraph of wrapped text.`
+ * `p` with text `Second Paragraph of **wrapped** text`. The conversion to a `<strong>` tag will happen when
+ running the inline processors, which will happen after all of the block processors have completed.
+
+The example output might display as follows:
+
+!!! note ""
+ <p>A regular paragraph of text.</p>
+ <div style="display: inline-block; border: 1px solid red;">
+ <p>First paragraph of wrapped text.</p>
+ <p>Second Paragraph of **wrapped** text.</p>
+ </div>
+ <p>Another regular paragraph of text.</p>
+
+#### Usages
+
+Some block processors in the Markdown source tree include:
+
+| Class | Kind | Description |
+| ----------------------------|-----------|---------------------------------------------|
+| [`HashHeaderProcessor`][b1] | built-in | Title hashes (`#`), which may split blocks |
+| [`HRProcessor`][b2] | built-in | Horizontal lines, e.g., `---` |
+| [`OListProcessor`][b3] | built-in | Ordered lists; complex and using `state` |
+| [`Admonition`][b4] | extension | Render each [Admonition][] in a new `div` |
+
+[b1]: https://github.com/Python-Markdown/markdown/blob/master/markdown/blockprocessors.py
+[b2]: https://github.com/Python-Markdown/markdown/blob/master/markdown/blockprocessors.py
+[b3]: https://github.com/Python-Markdown/markdown/blob/master/markdown/blockprocessors.py
+[Admonition]: https://python-markdown.github.io/extensions/admonition/
+[b4]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/admonition.py
+
+### Tree processors {: #treeprocessors }
+
+Tree processors manipulate the tree created by block processors. They can even create an entirely new ElementTree
+object. This is an excellent place for creating summaries, adding collected references, or last minute adjustments.
+
+A tree processor must inherit from `markdown.treeprocessors.Treeprocessor` (note the capitalization). A tree processor
+must implement a `run` method which takes a single argument `root`. In most cases `root` would be an
+`xml.etree.ElementTree.Element` instance; however, in rare cases it could be some other type of ElementTree object.
+The `run` method may return `None`, in which case the (possibly modified) original `root` object is used, or it may
+return an entirely new `Element` object, which will replace the existing `root` object and all of its children. It is
+generally preferred to modify `root` in place and return `None`, which avoids creating multiple copies of the entire
+document tree in memory.
+
+For specifics on manipulating the ElementTree, see [Working with the ElementTree][workingwithetree] below.
+
+#### Example
+
+A pseudo example:
+
+```python
+from markdown.treeprocessors import Treeprocessor
+
+class MyTreeprocessor(Treeprocessor):
+ def run(self, root):
+ root.text = 'modified content'
+ # No return statement is same as `return None`
+```
+
+#### Usages
+
+The core `InlineProcessor` class is a tree processor. It walks the tree, matches patterns, and splits and creates
+nodes on matches.
+
+Additional tree processors in the Markdown source tree include:
+
+| Class | Kind | Description |
+| ----------------------------------|-----------|---------------------------------------------------------------|
+| [`PrettifyTreeprocessor`][e1] | built-in | Add line breaks to the html document |
+| [`TocTreeprocessor`][e2] | extension | Builds a [table of contents][] from the finished tree |
+| [`FootnoteTreeprocessor`][e3] | extension | Create [footnote][] div at end of document |
+| [`FootnotePostTreeprocessor`][e4] | extension | Amend div created by `FootnoteTreeprocessor` with duplicates |
+
+[e1]: https://github.com/Python-Markdown/markdown/blob/master/markdown/treeprocessors.py
+[e2]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/toc.py
+[e3]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/footnotes.py
+[e4]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/footnotes.py
+[table of contents]: https://python-markdown.github.io/extensions/toc/
+[footnote]: https://python-markdown.github.io/extensions/footnotes/
+
+### Inline Processors {: #inlineprocessors }
+
+Inline processors, previously called inline patterns, are used to add formatting, such as `**emphasis**`, by replacing
+a matched pattern with a new element tree node. It is an excellent for adding new syntax for inline tags. Inline
+processor code is often quite short.
+
+Inline processors inherit from `InlineProcessor`, are initialized, and implement `handleMatch`:
+
+* `__init__(self, pattern, md=None)` is the inherited constructor. You do not need to implement your own.
+ * `pattern` is the regular expression string that must match the code block in order for the `handleMatch` method
+ to be called.
+ * `md`, an optional parameter, is a pointer to the instance of `markdown.Markdown` and is available as `self.md`
+ on the `InlineProcessor` instance.
+
+* `handleMatch(self, m, data)` must be implemented in all `InlineProcessor` subclasses.
+ * `m` is the regular expression [match object][] found by the `pattern` passed to `__init__`.
+ * `data` is a single, multi-line, Unicode string containing the entire block of text around the pattern. A block
+ is text set apart by blank lines.
+ * Returns either `(None, None, None)`, indicating the provided match was rejected or `(el, start, end)`, if the
+ match was successfully processed. On success, `el` is the element being added the tree, `start` and `end` are
+ indexes in `data` that were "consumed" by the pattern. The "consumed" span will be replaced by a placeholder.
+ The same inline processor may be called several times on the same block.
+
+Inline Processors can define the property `ANCESTOR_EXCLUDES` which is either a list or tuple of undesirable ancestors.
+The processor will be skipped if it would cause the content to be a descendant of one of the listed tag names.
+
+##### Convenience Classes
+
+Convenience subclasses of `InlineProcessor` are provide for common operations:
+
+* [`SimpleTextInlineProcessor`][i1] returns the text of `group(1)` of the match.
+* [`SubstituteTagInlineProcessor`][i4] is initialized as `SubstituteTagInlineProcessor(pattern, tag)`. It returns a
+ new element `tag` whenever `pattern` is matched.
+* [`SimpleTagInlineProcessor`][i3] is initialized as `SimpleTagInlineProcessor(pattern, tag)`. It returns an element
+ `tag` with a text field of `group(2)` of the match.
+
+##### Example
+
+This example changes `--strike--` to `<del>strike</del>`.
+
+```python
+from markdown.inlinepatterns import InlineProcessor
+from markdown.extensions import Extension
+import xml.etree.ElementTree as etree
+
+
+class DelInlineProcessor(InlineProcessor):
+ def handleMatch(self, m, data):
+ el = etree.Element('del')
+ el.text = m.group(1)
+ return el, m.start(0), m.end(0)
+
+class DelExtension(Extension):
+ def extendMarkdown(self, md):
+ DEL_PATTERN = r'--(.*?)--' # like --del--
+ md.inlinePatterns.register(DelInlineProcessor(DEL_PATTERN, md), 'del', 175)
+```
+
+Use this input example:
+
+``` text
+First line of the block.
+This is --strike one--.
+This is --strike two--.
+End of the block.
+```
+
+The example output might display as follows:
+
+!!! note ""
+ <p>First line of the block.
+ This is <del>strike one</del>.
+ This is <del>strike two</del>.
+ End of the block.</p>
+
+* On the first call to `handleMatch`
+ * `m` will be the match for `--strike one--`
+ * `data` will be the string:
+ `First line of the block.\nThis is --strike one--.\nThis is --strike two--.\nEnd of the block.`
+
+ Because the match was successful, the region between the returned `start` and `end` are replaced with a
+ placeholder token and the new element is added to the tree.
+
+* On the second call to `handleMatch`
+ * `m` will be the match for `--strike two--`
+ * `data` will be the string
+ `First line of the block.\nThis is klzzwxh:0000.\nThis is --strike two--.\nEnd of the block.`
+
+Note the placeholder token `klzzwxh:0000`. This allows the regular expression to be run against the entire block,
+not just the the text contained in an individual element. The placeholders will later be swapped back out for the
+actual elements by the parser.
+
+Actually it would not be necessary to create the above inline processor. The fact is, that example is not very DRY
+(Don't Repeat Yourself). A pattern for `**strong**` text would be almost identical, with the exception that it would
+create a `strong` element. Therefore, Markdown provides a number of generic `InlineProcessor` subclasses that can
+provide some common functionality. For example, strike could be implemented with an instance of the
+`SimpleTagInlineProcessor` class as demonstrated below. Feel free to use or extend any of the `InlineProcessor`
+subclasses found at `markdown.inlinepatterns`.
+
+```python
+from markdown.inlinepatterns import SimpleTagInlineProcessor
+from markdown.extensions import Extension
+
+class DelExtension(Extension):
+ def extendMarkdown(self, md):
+ md.inlinePatterns.register(SimpleTagInlineProcessor(r'()--(.*?)--', 'del'), 'del', 175)
+```
+
+
+##### Usages
+
+Here are some convenience functions and other examples:
+
+| Class | Kind | Description |
+| ---------------------------------|-----------|---------------------------------------------------------------|
+| [`AsteriskProcessor`][i5] | built-in | Emphasis processor for handling strong and em matches inside asterisks |
+| [`AbbrInlineProcessor`][i6] | extension | Apply tag to abbreviation registered by preprocessor |
+| [`WikiLinksInlineProcessor`][i7] | extension | Link `[[article names]]` to wiki given in metadata |
+| [`FootnoteInlineProcessor`][i8] | extension | Replaces footnote in text with link to footnote div at bottom |
+
+[i1]: https://github.com/Python-Markdown/markdown/blob/master/markdown/inlinepatterns.py
+[i2]: https://github.com/Python-Markdown/markdown/blob/master/markdown/inlinepatterns.py
+[i3]: https://github.com/Python-Markdown/markdown/blob/master/markdown/inlinepatterns.py
+[i4]: https://github.com/Python-Markdown/markdown/blob/master/markdown/inlinepatterns.py
+[i5]: https://github.com/Python-Markdown/markdown/blob/master/markdown/inlinepatterns.py
+[i6]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/abbr.py
+[i7]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/wikilinks.py
+[i8]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/footnotes.py
+
+### Patterns
+
+In version 3.0, a new, more flexible inline processor was added, `markdown.inlinepatterns.InlineProcessor`. The
+original inline patterns, which inherit from `markdown.inlinepatterns.Pattern` or one of its children are still
+supported, though users are encouraged to migrate.
+
+#### Comparison with new `InlineProcessor`
+
+The new `InlineProcessor` provides two major enhancements to `Patterns`:
+
+1. Inline Processors no longer need to match the entire block, so regular expressions no longer need to start with
+ `r'^(.*?)'` and end with `r'(.*?)%'`. This runs faster. The returned [match object][] will only contain what is
+ explicitly matched in the pattern, and extension pattern groups now start with `m.group(1)`.
+
+2. The `handleMatch` method now takes an additional input called `data`, which is the entire block under analysis,
+ not just what is matched with the specified pattern. The method now returns the element *and* the indexes relative
+ to `data` that the return element is replacing (usually `m.start(0)` and `m.end(0)`). If the boundaries are
+ returned as `None`, it is assumed that the match did not take place, and nothing will be altered in `data`.
+
+ This allows handling of more complex constructs than regular expressions can handle, e.g., matching nested
+ brackets, and explicit control of the span "consumed" by the processor.
+
+#### Inline Patterns
+
+Inline Patterns can implement inline HTML element syntax for Markdown such as `*emphasis*` or
+`[links](http://example.com)`. Pattern objects should be instances of classes that inherit from
+`markdown.inlinepatterns.Pattern` or one of its children. Each pattern object uses a single regular expression and
+must have the following methods:
+
+* **`getCompiledRegExp()`**:
+
+ Returns a compiled regular expression.
+
+* **`handleMatch(m)`**:
+
+ Accepts a match object and returns an ElementTree element of a plain Unicode string.
+
+Inline Patterns can define the property `ANCESTOR_EXCLUDES` with is either a list or tuple of undesirable ancestors.
+The pattern will be skipped if it would cause the content to be a descendant of one of the listed tag names.
+
+Note that any regular expression returned by `getCompiledRegExp` must capture the whole block. Therefore, they should
+all start with `r'^(.*?)'` and end with `r'(.*?)!'`. When using the default `getCompiledRegExp()` method provided in
+the `Pattern` you can pass in a regular expression without that and `getCompiledRegExp` will wrap your expression for
+you and set the `re.DOTALL` and `re.UNICODE` flags. This means that the first group of your match will be `m.group(2)`
+as `m.group(1)` will match everything before the pattern.
+
+For an example, consider this simplified emphasis pattern:
+
+```python
+from markdown.inlinepatterns import Pattern
+import xml.etree.ElementTree as etree
+
+class EmphasisPattern(Pattern):
+ def handleMatch(self, m):
+ el = etree.Element('em')
+ el.text = m.group(2)
+ return el
+```
+
+As discussed in [Integrating Your Code Into Markdown][], an instance of this class will need to be provided to
+Markdown. That instance would be created like so:
+
+```python
+# an oversimplified regex
+MYPATTERN = r'\*([^*]+)\*'
+# pass in pattern and create instance
+emphasis = EmphasisPattern(MYPATTERN)
+```
+
+### Postprocessors {: #postprocessors }
+
+Postprocessors munge the document after the ElementTree has been serialized into a string. Postprocessors should be
+used to work with the text just before output. Usually, they are used add back sections that were extracted in a
+preprocessor, fix up outgoing encodings, or wrap the whole document.
+
+Postprocessors inherit from `markdown.postprocessors.Postprocessor` and implement a `run` method which takes a single
+parameter `text`, the entire HTML document as a single Unicode string. `run` should return a single Unicode string
+ready for output. Note that preprocessors use a list of lines while postprocessors use a single multi-line string.
+
+#### Example
+
+Here is a simple example that changes the output to one big page showing the raw html.
+
+```python
+from markdown.postprocessors import Postprocessor
+import re
+
+class ShowActualHtmlPostprocesor(Postprocessor):
+ """ Wrap entire output in <pre> tags as a diagnostic. """
+ def run(self, text):
+ return '<pre>\n' + re.sub('<', '&lt;', text) + '</pre>\n'
+```
+
+#### Usages
+
+Some postprocessors in the Markdown source tree include:
+
+| Class | Kind | Description |
+| ------------------------------|-----------|----------------------------------------------------|
+| [`raw_html`][p1] | built-in | Restore raw html from `htmlStash`, stored by `HTMLBlockPreprocessor`, and code highlighters |
+| [`amp_substitute`][p2] | built-in | Convert ampersand substitutes to `&`; used in links |
+| [`unescape`][p3] | built-in | Convert some escaped characters back from integers; used in links |
+| [`FootnotePostProcessor`][p4] | extension | Replace footnote placeholders with html entities; as set by other stages |
+
+ [p1]: https://github.com/Python-Markdown/markdown/blob/master/markdown/postprocessors.py
+ [p2]: https://github.com/Python-Markdown/markdown/blob/master/markdown/postprocessors.py
+ [p3]: https://github.com/Python-Markdown/markdown/blob/master/markdown/postprocessors.py
+ [p4]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/footnotes.py
+
+
+## Working with the ElementTree {: #working_with_et }
+
+As mentioned, the Markdown parser converts a source document to an [ElementTree][ElementTree] object before
+serializing that back to Unicode text. Markdown has provided some helpers to ease that manipulation within the context
+of the Markdown module.
+
+First, import the ElementTree module:
+
+```python
+import xml.etree.ElementTree as etree
+```
+Sometimes you may want text inserted into an element to be parsed by [Inline Patterns][]. In such a situation, simply
+insert the text as you normally would and the text will be automatically run through the Inline Patterns. However, if
+you do *not* want some text to be parsed by Inline Patterns, then insert the text as an `AtomicString`.
+
+```python
+from markdown.util import AtomicString
+some_element.text = AtomicString(some_text)
+```
+
+Here's a basic example which creates an HTML table (note that the contents of the second cell (`td2`) will be run
+through Inline Patterns latter):
+
+```python
+table = etree.Element("table")
+table.set("cellpadding", "2") # Set cellpadding to 2
+tr = etree.SubElement(table, "tr") # Add child tr to table
+td1 = etree.SubElement(tr, "td") # Add child td1 to tr
+td1.text = markdown.util.AtomicString("Cell content") # Add plain text content
+td2 = etree.SubElement(tr, "td") # Add second td to tr
+td2.text = "*text* with **inline** formatting." # Add markup text
+table.tail = "Text after table" # Add text after table
+```
+
+You can also manipulate an existing tree. Consider the following example which adds a `class` attribute to `<a>`
+elements:
+
+```python
+def set_link_class(self, element):
+ for child in element:
+ if child.tag == "a":
+ child.set("class", "myclass") #set the class attribute
+ set_link_class(child) # run recursively on children
+```
+
+For more information about working with ElementTree see the [ElementTree
+Documentation][ElementTree].
+
+## Working with Raw HTML {: #working_with_raw_html }
+
+Occasionally an extension may need to call out to a third party library which returns a pre-made string
+of raw HTML that needs to be inserted into the document unmodified. Raw strings can be stashed for later
+retrieval using an `htmlStash` instance, rather than converting them into `ElementTree` objects. A raw string
+(which may or may not be raw HTML) passed to `self.md.htmlStash.store()` will be saved to the stash and a
+placeholder string will be returned which should be inserted into the tree instead. After the tree is
+serialized, a postprocessor will replace the placeholder with the raw string. This prevents subsequent
+processing steps from modifying the HTML data. For example,
+
+```python
+html = "<p>This is some <em>raw</em> HTML data</p>"
+el = etree.Element("div")
+el.text = self.md.htmlStash.store(html)
+```
+
+For the global `htmlStash` instance to be available from a processor, the `markdown.Markdown` instance must
+be passed to the processor from [extendMarkdown](#extendmarkdown) and will be available as `self.md.htmlStash`.
+
+## Integrating Your Code Into Markdown {: #integrating_into_markdown }
+
+Once you have the various pieces of your extension built, you need to tell Markdown about them and ensure that they
+are run in the proper sequence. Markdown accepts an `Extension` instance for each extension. Therefore, you will need
+to define a class that extends `markdown.extensions.Extension` and over-rides the `extendMarkdown` method. Within this
+class you will manage configuration options for your extension and attach the various processors and patterns to the
+Markdown instance.
+
+It is important to note that the order of the various processors and patterns matters. For example, if we replace
+`http://...` links with `<a>` elements, and *then* try to deal with inline HTML, we will end up with a mess.
+Therefore, the various types of processors and patterns are stored within an instance of the `markdown.Markdown` class
+in a [Registry][]. Your `Extension` class will need to manipulate those registries appropriately. You may `register`
+instances of your processors and patterns with an appropriate priority, `deregister` built-in instances, or replace a
+built-in instance with your own.
+
+### `extendMarkdown` {: #extendmarkdown }
+
+The `extendMarkdown` method of a `markdown.extensions.Extension` class accepts one argument:
+
+* **`md`**:
+
+ A pointer to the instance of the `markdown.Markdown` class. You should use this to access the
+ [Registries][Registry] of processors and patterns. They are found under the following attributes:
+
+ * `md.preprocessors`
+ * `md.inlinePatterns`
+ * `md.parser.blockprocessors`
+ * `md.treeprocessors`
+ * `md.postprocessors`
+
+ Some other things you may want to access on the `markdown.Markdown` instance are:
+
+ * `md.htmlStash`
+ * `md.output_formats`
+ * `md.set_output_format()`
+ * `md.output_format`
+ * `md.serializer`
+ * `md.registerExtension()`
+ * `md.tab_length`
+ * `md.block_level_elements`
+ * `md.isBlockLevel()`
+
+!!! Warning
+ With access to the above items, theoretically you have the option to change anything through various
+ [monkey_patching][] techniques. However, you should be aware that the various undocumented parts of Markdown may
+ change without notice and your monkey_patches may break with a new release. Therefore, what you really should be
+ doing is inserting processors and patterns into the Markdown pipeline. Consider yourself warned!
+
+[monkey_patching]: https://en.wikipedia.org/wiki/Monkey_patch
+
+A simple example:
+
+```python
+from markdown.extensions import Extension
+
+class MyExtension(Extension):
+ def extendMarkdown(self, md):
+ # Register instance of 'mypattern' with a priority of 175
+ md.inlinePatterns.register(MyPattern(md), 'mypattern', 175)
+```
+
+### registerExtension {: #registerextension }
+
+Some extensions may need to have their state reset between multiple runs of the `markdown.Markdown` class. For
+example, consider the following use of the [Footnotes][] extension:
+
+```python
+md = markdown.Markdown(extensions=['footnotes'])
+html1 = md.convert(text_with_footnote)
+md.reset()
+html2 = md.convert(text_without_footnote)
+```
+
+Without calling `reset`, the footnote definitions from the first document will be inserted into the second document as
+they are still stored within the class instance. Therefore the `Extension` class needs to define a `reset` method that
+will reset the state of the extension (i.e.: `self.footnotes = {}`). However, as many extensions do not have a need
+for `reset`, `reset` is only called on extensions that are registered.
+
+To register an extension, call `md.registerExtension` from within your `extendMarkdown` method:
+
+```python
+def extendMarkdown(self, md):
+ md.registerExtension(self)
+ # insert processors and patterns here
+```
+
+Then, each time `reset` is called on the `markdown.Markdown` instance, the `reset` method of each registered extension
+will be called as well. You should also note that `reset` will be called on each registered extension after it is
+initialized the first time. Keep that in mind when over-riding the extension's `reset` method.
+
+### Configuration Settings {: #configsettings }
+
+If an extension uses any parameters that the user may want to change, those parameters should be stored in
+`self.config` of your `markdown.extensions.Extension` class in the following format:
+
+```python
+class MyExtension(markdown.extensions.Extension):
+ def __init__(self, **kwargs):
+ self.config = {
+ 'option1' : ['value1', 'description1'],
+ 'option2' : ['value2', 'description2']
+ }
+ super(MyExtension, self).__init__(**kwargs)
+```
+
+When implemented this way the configuration parameters can be over-ridden at run time (thus the call to `super`). For
+example:
+
+```python
+markdown.Markdown(extensions=[MyExtension(option1='other value')])
+```
+
+Note that if a keyword is passed in that is not already defined in `self.config`, then a `KeyError` is raised.
+
+The `markdown.extensions.Extension` class and its subclasses have the following methods available to assist in working
+with configuration settings:
+
+* **`getConfig(key [, default])`**:
+
+ Returns the stored value for the given `key` or `default` if the `key` does not exist. If not set, `default`
+ returns an empty string.
+
+* **`getConfigs()`**:
+
+ Returns a dict of all key/value pairs.
+
+* **`getConfigInfo()`**:
+
+ Returns all configuration descriptions as a list of tuples.
+
+* **`setConfig(key, value)`**:
+
+ Sets a configuration setting for `key` with the given `value`. If `key` is unknown, a `KeyError` is raised. If the
+ previous value of `key` was a Boolean value, then `value` is converted to a Boolean value. If the previous value
+ of `key` is `None`, then `value` is converted to a Boolean value except when it is `None`. No conversion takes
+ place when the previous value of `key` is a string.
+
+* **`setConfigs(items)`**:
+
+ Sets multiple configuration settings given a dict of key/value pairs.
+
+### Naming an Extension { #naming_an_extension }
+
+As noted in the [library reference] an instance of an extension can be passed directly to `markdown.Markdown`. In
+fact, this is the preferred way to use third-party extensions.
+
+For example:
+
+```python
+import markdown
+from path.to.module import MyExtension
+md = markdown.Markdown(extensions=[MyExtension(option='value')])
+```
+
+However, Markdown also accepts "named" third party extensions for those occasions when it is impractical to import an
+extension directly (from the command line or from within templates). A "name" can either be a registered [entry
+point](#entry_point) or a string using Python's [dot notation](#dot_notation).
+
+#### Entry Point { #entry_point }
+
+[Entry points] are defined in a Python package's `setup.py` script. The script must use [setuptools] to support entry
+points. Python-Markdown extensions must be assigned to the `markdown.extensions` group. An entry point definition
+might look like this:
+
+```python
+from setuptools import setup
+
+setup(
+ # ...
+ entry_points={
+ 'markdown.extensions': ['myextension = path.to.module:MyExtension']
+ }
+)
+```
+
+After a user installs your extension using the above script, they could then call the extension using the
+`myextension` string name like this:
+
+```python
+markdown.markdown(text, extensions=['myextension'])
+```
+
+Note that if two or more entry points within the same group are assigned the same name, Python-Markdown will only ever
+use the first one found and ignore all others. Therefore, be sure to give your extension a unique name.
+
+For more information on writing `setup.py` scripts, see the Python documentation on [Packaging and Distributing
+Projects].
+
+#### Dot Notation { #dot_notation }
+
+If an extension does not have a registered entry point, Python's dot notation may be used instead. The extension must
+be installed as a Python module on your PYTHONPATH. Generally, a class should be specified in the name. The class must
+be at the end of the name and be separated by a colon from the module.
+
+Therefore, if you were to import the class like this:
+
+```python
+from path.to.module import MyExtension
+```
+
+Then the extension can be loaded as follows:
+
+```python
+markdown.markdown(text, extensions=['path.to.module:MyExtension'])
+```
+
+You do not need to do anything special to support this feature. As long as your extension class is able to be
+imported, a user can include it with the above syntax.
+
+The above two methods are especially useful if you need to implement a large number of extensions with more than one
+residing in a module. However, if you do not want to require that your users include the class name in their string,
+you must define only one extension per module and that module must contain a module-level function called
+`makeExtension` that accepts `**kwargs` and returns an extension instance.
+
+For example:
+
+```python
+class MyExtension(markdown.extensions.Extension)
+ # Define extension here...
+
+def makeExtension(**kwargs):
+ return MyExtension(**kwargs)
+```
+
+When `markdown.Markdown` is passed the "name" of your extension as a dot notation string that does not include a class
+(for example `path.to.module`), it will import the module and call the `makeExtension` function to initiate your
+extension.
+
+## Registries
+
+The `markdown.util.Registry` class is a priority sorted registry which Markdown uses internally to determine the
+processing order of its various processors and patterns.
+
+A `Registry` instance provides two public methods to alter the data of the registry: `register` and `deregister`. Use
+`register` to add items and `deregister` to remove items. See each method for specifics.
+
+When registering an item, a "name" and a "priority" must be provided. All items are automatically sorted by the value
+of the "priority" parameter such that the item with the highest value will be processed first. The "name" is used to
+remove (`deregister`) and get items.
+
+A `Registry` instance is like a list (which maintains order) when reading data. You may iterate over the items, get an
+item and get a count (length) of all items. You may also check that the registry contains an item.
+
+When getting an item you may use either the index of the item or the string-based "name". For example:
+
+```python
+registry = Registry()
+registry.register(SomeItem(), 'itemname', 20)
+# Get the item by index
+item = registry[0]
+# Get the item by name
+item = registry['itemname']
+```
+
+When checking that the registry contains an item, you may use either the string-based "name", or a reference to the
+actual item. For example:
+
+```python
+someitem = SomeItem()
+registry.register(someitem, 'itemname', 20)
+# Contains the name
+assert 'itemname' in registry
+# Contains the item instance
+assert someitem in registry
+```
+
+`markdown.util.Registry` has the following methods:
+
+### `Registry.register(self, item, name, priority)` {: #registry.register data-toc-label='Registry.register'}
+
+: Add an item to the registry with the given name and priority.
+
+ Parameters:
+
+ * `item`: The item being registered.
+ * `name`: A string used to reference the item.
+ * `priority`: An integer or float used to sort against all items.
+
+ If an item is registered with a "name" which already exists, the existing item is replaced with the new item.
+ Be careful as the old item is lost with no way to recover it. The new item will be sorted according to its
+ priority and will **not** retain the position of the old item.
+
+### `Registry.deregister(self, name, strict=True)` {: #registry.deregister data-toc-label='Registry.deregister'}
+
+: Remove an item from the registry.
+
+ Set `strict=False` to fail silently.
+
+### `Registry.get_index_for_name(self, name)` {: #registry.get_index_for_name data-toc-label='Registry.get_index_for_name'}
+
+: Return the index of the given `name`.
+
+[match object]: https://docs.python.org/3/library/re.html#match-objects
+[bug tracker]: https://github.com/Python-Markdown/markdown/issues
+[extension source]: https://github.com/Python-Markdown/markdown/tree/master/markdown/extensions
+[tutorial]: https://github.com/Python-Markdown/markdown/wiki/Tutorial-1---Writing-Extensions-for-Python-Markdown
+[workingwithetree]: #working_with_et
+[Integrating your code into Markdown]: #integrating_into_markdown
+[extendMarkdown]: #extendmarkdown
+[Registry]: #registry
+[registerExtension]: #registerextension
+[Config Settings]: #configsettings
+[makeExtension]: #makeextension
+[ElementTree]: https://docs.python.org/3/library/xml.etree.elementtree.html
+[Available Extensions]: index.md
+[Footnotes]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/footnotes.py
+[Definition Lists]: https://github.com/Python-Markdown/markdown/blob/master/markdown/extensions/definition_lists
+[library reference]: ../reference.md
+[setuptools]: https://packaging.python.org/key_projects/#setuptools
+[Entry points]: https://setuptools.readthedocs.io/en/latest/setuptools.html#dynamic-discovery-of-services-and-plugins
+[Packaging and Distributing Projects]: https://packaging.python.org/tutorials/distributing-packages/
diff --git a/docs/extensions/attr_list.md b/docs/extensions/attr_list.md
new file mode 100644
index 0000000..d3d5e12
--- /dev/null
+++ b/docs/extensions/attr_list.md
@@ -0,0 +1,202 @@
+title: Attribute Lists Extension
+
+# Attribute Lists
+
+## Summary
+
+The Attribute Lists extension adds a syntax to define attributes on the various
+HTML elements in markdown's output.
+
+This extension is included in the standard Markdown library.
+
+## Syntax
+
+The basic syntax was inspired by Maruku's Attribute Lists feature (see [web archive][Maruku]).
+
+[Maruku]: https://web.archive.org/web/20170324172643/http://maruku.rubyforge.org/proposal.html
+
+### The List
+
+An example attribute list might look like this:
+
+```text
+{: #someid .someclass somekey='some value' }
+```
+
+A word which starts with a hash (`#`) will set the id of an element.
+
+A word which starts with a dot (`.`) will be added to the list of classes
+assigned to an element.
+
+A key/value pair (`somekey='some value'`) will assign that pair to the element.
+
+Be aware that while the dot syntax will add to a class, using key/value pairs
+will always override the previously defined attribute. Consider the following:
+
+```text
+{: #id1 .class1 id=id2 class="class2 class3" .class4 }
+```
+
+The above example would result in the following attributes being defined:
+
+```text
+id="id2" class="class2 class3 class4"
+```
+
+HTML includes support for some attributes to be a single term, like `checked`, for example. Therefore, the attribute
+list `{: checked }` would result in `checked` if the [output format](../reference.md#output_format) is `html` or
+`checked="checked"` if the output format is `xhtml`.
+
+Curly braces can be backslash escaped to avoid being identified as an attribute list.
+
+```text
+\{ not an attribute list }
+```
+
+Opening and closing curly braces which are empty or only contain whitespace are ignored whether they are escaped or
+not. Additionally, any attribute lists which are not located in the specific locations documented below are ignored.
+
+The colon after the opening brace is optional, but is supported to maintain consistency with other implementations.
+Therefore, the following is also a valid attribute list:
+
+```text
+{ #someid .someclass somekey='some value' }
+```
+
+In addition, the spaces after the opening brace and before the closing brace are optional. They are recommended as
+they improve readability, but they are not required.
+
+The Attribute List extension does not have any knowledge of which keys and/or values are valid in HTML. Therefore, it
+is up to the document author to ensure that valid keys and values are used. However, the extension will escape any
+characters in the key which are not valid by replacing them with an underscore. Multiple consecutive invalid
+characters are reduced to a single underscore.
+
+### Block Level
+
+To define attributes for a block level element, the attribute list should
+be defined on the last line of the block by itself.
+
+```text
+This is a paragraph.
+{: #an_id .a_class }
+```
+
+The above results in the following output:
+
+```html
+<p id="an_id" class="a_class">This is a paragraph.</p>
+```
+
+An exception is headers, as they are only ever allowed on one line.
+
+```text
+A setext style header {: #setext}
+=================================
+
+### A hash style header ### {: #hash }
+```
+
+The above results in the following output:
+
+```html
+<h1 id="setext">A setext style header</h1>
+<h3 id="hash">A hash style header</h3>
+```
+
+!!! seealso "See Also"
+ By default, the [Fenced Code Blocks](./fenced_code_blocks.md#attributes) extension includes limited support for
+ attribute lists. To get [full support](./fenced_code_blocks.md#keyvalue-pairs), both extensions must be enabled.
+
+### Inline
+
+To define attributes on inline elements, the attribute list should be defined
+immediately after the inline element with no white space.
+
+```text
+[link](http://example.com){: class="foo bar" title="Some title!" }
+```
+
+The above results in the following output:
+
+```html
+<p><a href="http://example.com" class="foo bar" title="Some title!">link</a></p>
+```
+
+If the [tables](./tables.md) extension is enabled, attribute lists can be defined on table cells. To differentiate
+attributes for an inline element from attributes for the containing cell, the attribute list must be separated from
+the content by at least one space and be defined at the end of the cell content. As table cells can only ever be on
+a single line, the attribute list must remain on the same line as the content of the cell.
+
+```text
+| set on td | set on em |
+|--------------|-------------|
+| *a* { .foo } | *b*{ .foo } |
+```
+
+The above example results in the following output:
+
+```html
+<table>
+ <thead>
+ <tr>
+ <th>set on td</th>
+ <th>set on em</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td class="foo"><em>a</em></td>
+ <td><em class="foo">b</em></td>
+ </tr>
+ </tbody>
+</table>
+```
+
+Note that in the first column, the attribute list is preceded by a space; therefore, it is assigned to the table cell
+(`<td>` element). However, in the second column, the attribute list is not preceded by a space; therefore, it is
+assigned to the inline element (`<em>`) which immediately preceded it.
+
+Attribute lists may also be defined on table header cells (`<th>` elements) in the same manner.
+
+### Limitations
+
+There are a few types of elements which attribute lists do not work with. As a reminder, Markdown is a subset of HTML
+and anything which cannot be expressed in Markdown can always be expressed with raw HTML directly.
+
+__Code Blocks:__
+
+: Code blocks are unique in that they must be able to display Markdown syntax. Therefore, there is no way to
+ determine if an attribute list is intended to be part of the code block or intended to define attributes on the
+ wrapping element. For that reason, the extension ignores code blocks. To define attributes on code blocks, the
+ [codehilite] and [fenced code blocks] extensions provide some options.
+
+[codehilite]: code_hilite.md
+[fenced code blocks]: fenced_code_blocks.md
+
+__Nested Elements:__
+
+: Markdown provides mechanisms for nesting various block level elements within other elements. However, attribute
+ lists only ever get applied to the immediate parent. There is no way to specify that an attribute list should be
+ applied some number of levels up the document tree. For example, when including an attribute list within a
+ blockquote, the attribute list is only ever applied to the paragraph the list is defined in. There is no way to
+ define attributes on the `blockquote` element itself.
+
+__Implied Elements:__
+
+: There are various HTML elements which are not represented in Markdown text, but only implied. For example, the
+ `ul` and `ol` elements do not exist in Markdown. They are only implied by the presence of list items (`li`). There
+ is no way to use an attribute list to define attributes on implied elements, including but not limited to the
+ following: `ul`, `ol`, `dl`, `table`, `thead`, `tbody`, and `tr`.
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `attr_list` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['attr_list'])
+```
diff --git a/docs/extensions/code_hilite.md b/docs/extensions/code_hilite.md
new file mode 100644
index 0000000..19b9d52
--- /dev/null
+++ b/docs/extensions/code_hilite.md
@@ -0,0 +1,308 @@
+title: CodeHilite Extension
+
+# CodeHilite
+
+## Summary
+
+The CodeHilite extension adds code/syntax highlighting to standard
+Python-Markdown code blocks using [Pygments][].
+
+[Pygments]: http://pygments.org/
+
+This extension is included in the standard Markdown library.
+
+## Setup
+
+### Step 1: Download and Install Pygments
+
+You will also need to [download][dl] and install the Pygments package on your
+`PYTHONPATH`. The CodeHilite extension will produce HTML output without
+Pygments, but it won't highlight anything (same behavior as setting
+`use_pygments` to `False`).
+
+[dl]: http://pygments.org/download/
+
+### Step 2: Add CSS Classes
+
+You will need to define the appropriate CSS classes with appropriate rules.
+The CSS rules either need to be defined in or linked from the header of your
+HTML templates. Pygments can generate CSS rules for you. Just run the following
+command from the command line:
+
+```bash
+pygmentize -S default -f html -a .codehilite > styles.css
+```
+
+If you are using a different `css_class` (default: `.codehilite`), then
+set the value of the `-a` option to that class name. The CSS rules will be
+written to the `styles.css` file which you can copy to your site and link from
+your HTML templates.
+
+If you would like to use a different theme, swap out `default` for the desired
+theme. For a list of themes installed on your system (additional themes can be
+installed via Pygments plugins), run the following command:
+
+```bash
+pygmentize -L style
+```
+
+See Pygments' excellent [documentation] for more details. If no language is
+defined, Pygments will attempt to guess the language. When that fails, the code
+block will not be highlighted.
+
+!!! seealso "See Also"
+
+ GitHub user [richeland] has provided a number of different [CSS style
+ sheets][rich] which work with Pygments along with a [preview] of each theme.
+ The `css_class` used is `.highlight`. Therefore, one would need to override the
+ [`css_class`](#css_class) option when using richeland's CSS styles. However, the
+ Python-Markdown project makes no guarantee that richeland's CSS styles will
+ work with the version of Pygments you are using. To ensure complete
+ compatibility, you should generate the CSS rules from your own installation
+ of Pygments.
+
+[richeland]: https://github.com/richleland
+[rich]: https://github.com/richleland/pygments-css
+[preview]: https://richleland.github.io/pygments-css/
+[documentation]: http://pygments.org/docs/
+
+## Syntax
+
+The CodeHilite extension follows the same [syntax][] as regular Markdown code
+blocks, with one exception. The highlighter needs to know what language to use for
+the code block. There are three ways to tell the highlighter what language the
+code block contains and each one has a different result.
+
+!!! Note
+ The format of the language identifier only effects the display of line numbers
+ if `linenums` is set to `None` (the default). If set to `True` or `False`
+ (see [Usage](#usage) below) the format of the identifier has no effect on the
+ display of line numbers -- it only serves as a means to define the language
+ of the code block.
+
+[syntax]: https://daringfireball.net/projects/markdown/syntax#precode
+
+### Shebang (with path)
+
+If the first line of the code block contains a shebang, the language is derived
+from that and line numbers are used.
+
+```md
+ #!/usr/bin/python
+ # Code goes here ...
+```
+
+Will result in:
+
+ #!/usr/bin/python
+ # Code goes here ...
+
+### Shebang (no path)
+
+If the first line contains a shebang, but the shebang line does not contain a
+path (a single `/` or even a space), then that line is removed from the code
+block before processing. Line numbers are used.
+
+```md
+ #!python
+ # Code goes here ...
+```
+
+Will result in:
+
+ #!python
+ # Code goes here ...
+
+### Colons
+
+If the first line begins with three or more colons, the text following the
+colons identifies the language. The first line is removed from the code block
+before processing and line numbers are not used.
+
+```md
+ :::python
+ # Code goes here ...
+```
+
+Will result in:
+
+ :::python
+ # Code goes here ...
+
+Certain lines can be selected for emphasis with the colon syntax. When
+using Pygments' default CSS styles, emphasized lines have a yellow background.
+This is useful to direct the reader's attention to specific lines.
+
+```md
+ :::python hl_lines="1 3"
+ # This line is emphasized
+ # This line isn't
+ # This line is emphasized
+```
+
+Will result in:
+
+ :::python hl_lines="1 3"
+ # This line is emphasized
+ # This line isn't
+ # This line is emphasized
+
+!!! Note
+ `hl_lines` is named for Pygments' option meaning "highlighted lines".
+
+### When No Language is Defined
+
+CodeHilite is completely backwards compatible so that if a code block is
+encountered that does not define a language, the block is simply wrapped in
+`<pre>` tags and output.
+
+```md
+ # Code goes here ...
+```
+
+Will result in:
+
+ # Code goes here ...
+
+Lets see the source for that:
+
+```html
+<div class="codehilite"><pre><code># Code goes here ...
+</code></pre></div>
+```
+
+!!! Note
+ When no language is defined, the Pygments highlighting engine will try to guess
+ the language (unless `guess_lang` is set to `False`). Upon failure, the same
+ behavior will happen as described above.
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `codehilite` as the
+name of the extension.
+
+See the [Library Reference](../reference.md#extensions) for information about
+configuring extensions.
+
+The following options are provided to configure the output:
+
+* **`linenums`**{ #linenums }:
+ An alias to Pygments' `linenos` formatter option. Possible values are `True` for yes, `False` for no and `None`
+ for auto. Defaults to `None`.
+
+ Using `True` will force every code block to have line numbers, even when
+ using colons (`:::`) for language identification.
+
+ Using `False` will turn off all line numbers, even when using shebangs
+ (`#!`) for language identification.
+
+* **`guess_lang`**{ #guess_lang }:
+ Automatic language detection. Defaults to `True`.
+
+ Using `False` will prevent Pygments from guessing the language, and thus
+ highlighting blocks only when you explicitly set the language.
+
+* **`css_class`**{ #css_class }:
+ An alias to Pygments `cssclass` formatter option. Set CSS class name for the wrapper `<div>` tag. Defaults to
+ `codehilite`.
+
+* **`pygments_style`**{ #pygments_style }:
+ Pygments HTML Formatter Style (`ColorScheme`). Defaults to `default`.
+
+ !!! Note
+ This is useful only when `noclasses` is set to `True`, otherwise the
+ CSS styles must be provided by the end user.
+
+* **`noclasses`**{ #noclasses }:
+ Use inline styles instead of CSS classes. Defaults to `False`.
+
+* **`use_pygments`**{ #use_pygments }:
+ Specifies the use of Pygments in generating the output.
+
+ If `True` (the default) and Pygments is available, CodeHilite will use
+ Pygments to analyze and format the output. Additionally, if using Pygments
+ &gt;= 2.4, the output will be wrapped in `<code>` tags, whereas earlier
+ versions will not.
+
+ Otherwise, Pygments will not be used. If a language is defined for a code block, it will be assigned to the
+ `<code>` tag as a class in the manner suggested by the [HTML5 spec][spec] and may be used by a JavaScript library
+ in the browser to highlight the code block. See the [`lang_prefix`](#lang_prefix) option to customize the prefix.
+
+* **`lang_prefix`**{ #lang_prefix }:
+ The prefix prepended to the language class assigned to the HTML `<code>` tag. Default: `language-`.
+
+* **`pygments_formatter`**{ #pygments_formatter }:
+ This option can be used to change the Pygments formatter used for highlighting code blocks. By default, this
+ is set to the string `'html'`, which means it'll use the default `HtmlFormatter` provided by Pygments.
+
+ This can be set to a string representing any of the other default formatters, or set to a formatter class (or
+ any callable).
+
+ The code's language is always passed to the formatter as an extra option `lang_str`, with the value formatted as
+ `{lang_prefix}{lang}`. If the language is unspecified, the language guessed by Pygments will be used. While
+ this option has no effect to the Pygments's builtin formatters, a user can make use of the language in their custom
+ formatter. See an example below.
+
+ To see what formatters are available and how to subclass an existing formatter, please visit [Pygments
+ documentation on this topic][pygments formatters].
+
+* Any other Pygments' options:
+
+ All other options are accepted and passed on to Pygments' lexer and formatter. Therefore,
+ valid options include any options which are accepted by the [html formatter] or
+ whichever [lexer] the code's language uses. Invalid options are ignored without error.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['codehilite'])
+```
+
+To keep the code block's language in the Pygments generated HTML output, one can provide a custom Pygments formatter
+that takes the `lang_str` option. For example,
+
+```python
+from pygments.formatters import HtmlFormatter
+from markdown.extensions.codehilite import CodeHiliteExtension
+
+
+class CustomHtmlFormatter(HtmlFormatter):
+ def __init__(self, lang_str='', **options):
+ super().__init__(**options)
+ # lang_str has the value {lang_prefix}{lang}
+ # specified by the CodeHilite's options
+ self.lang_str = lang_str
+
+ def _wrap_code(self, source):
+ yield 0, f'<code class="{self.lang_str}">'
+ yield from source
+ yield 0, '</code>'
+
+
+some_text = '''\
+ :::python
+ print('hellow world')
+'''
+
+markdown.markdown(
+ some_text,
+ extensions=[CodeHiliteExtension(pygments_formatter=CustomHtmlFormatter)],
+)
+```
+
+The formatter above will output the following HTML structure for a code block:
+
+```html
+<div class="codehilite">
+ <pre>
+ <code class="language-python">
+ ...
+ </code>
+ </pre>
+</div>
+```
+
+[html formatter]: https://pygments.org/docs/formatters/#HtmlFormatter
+[lexer]: https://pygments.org/docs/lexers/
+[spec]: https://www.w3.org/TR/html5/text-level-semantics.html#the-code-element
+[pygments formatters]: https://pygments.org/docs/formatters/
diff --git a/docs/extensions/definition_lists.md b/docs/extensions/definition_lists.md
new file mode 100644
index 0000000..047996a
--- /dev/null
+++ b/docs/extensions/definition_lists.md
@@ -0,0 +1,58 @@
+title: Definition Lists Extension
+
+Definition Lists
+================
+
+Summary
+-------
+
+The Definition Lists extension adds the ability to create definition lists in
+Markdown documents.
+
+This extension is included in the standard Markdown library.
+
+Syntax
+------
+
+Definition lists are defined using the syntax established in
+[PHP Markdown Extra][php].
+
+[php]: http://www.michelf.com/projects/php-markdown/extra/#def-list
+
+Thus, the following text (taken from the above referenced PHP documentation):
+
+```md
+Apple
+: Pomaceous fruit of plants of the genus Malus in
+ the family Rosaceae.
+
+Orange
+: The fruit of an evergreen tree of the genus Citrus.
+```
+
+will be rendered as:
+
+```html
+<dl>
+<dt>Apple</dt>
+<dd>Pomaceous fruit of plants of the genus Malus in
+the family Rosaceae.</dd>
+
+<dt>Orange</dt>
+<dd>The fruit of an evergreen tree of the genus Citrus.</dd>
+</dl>
+```
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `def_list` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['def_list'])
+```
diff --git a/docs/extensions/extra.md b/docs/extensions/extra.md
new file mode 100644
index 0000000..77f5de0
--- /dev/null
+++ b/docs/extensions/extra.md
@@ -0,0 +1,62 @@
+title: Extra Extension
+
+# Python-Markdown Extra
+
+## Summary
+
+A compilation of various Python-Markdown extensions that (mostly) imitates
+[PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/).
+
+The supported extensions include:
+
+* [Abbreviations](abbreviations.md)
+* [Attribute Lists](attr_list.md)
+* [Definition Lists](definition_lists.md)
+* [Fenced Code Blocks](fenced_code_blocks.md)
+* [Footnotes](footnotes.md)
+* [Tables](tables.md)
+* [Markdown in HTML](md_in_html.md)
+
+See each individual extension for syntax documentation. Extra and all its
+supported extensions are included in the standard Markdown library.
+
+## Usage
+
+From the Python interpreter:
+
+```pycon
+>>> import markdown
+>>> html = markdown.markdown(text, extensions=['extra'])
+```
+
+To pass configuration options to the extensions included with Extra, they must be passed to Extra, with the
+underlying extension identified as well. In that way Extra will have access to the options and can pass them on to
+the appropriate underlying extension.
+
+```python
+config = {
+ 'extra': {
+ 'footnotes': {
+ 'UNIQUE_IDS': True
+ },
+ 'fenced_code': {
+ 'lang_prefix': 'lang-'
+ }
+ },
+ 'toc': {
+ 'permalink': True
+ }
+}
+
+html = markdown.markdown(text, extensions=['extra', 'toc'], extension_configs=config)
+```
+
+Note that in the above example, `footnotes` and `fenced_code` are both nested under the `extra` key as those
+extensions are included with Extra. However, the `toc` extension is not included with `extra` and therefore its
+configuration options are not nested under the `extra` key.
+
+See each individual extension for a list of supported configuration options.
+
+There are many other [extensions](index.md) which are distributed with Python-Markdown that are not included here in
+Extra. The features of those extensions are not part of PHP Markdown Extra, and therefore, not part of Python-Markdown
+Extra.
diff --git a/docs/extensions/extra.txt b/docs/extensions/extra.txt
deleted file mode 100644
index 817d58f..0000000
--- a/docs/extensions/extra.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Python-Markdown Extra
-=====================
-
-Summary
--------
-
-A compilation of various Python-Markdown extensions that (mostly) imitates
-[PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/).
-
-The supported extensions include:
-
-* [[Abbreviations]]
-* [[Definition_Lists]]
-* [[Fenced_Code_Blocks]]
-* [[Footnotes]]
-* [[HeaderId]]
-* [[Tables]]
-
-See each individual extension for syntax documentation. Extra and all it's
-supported extensions are included in the standard Markdown library.
-
-Usage
------
-
-From the Python interpreter:
-
- >>> import markdown
- >>> html = markdown.markdown(text, ['extra'])
-
-In the unlikely event that one or more of the supported extensions are not
-available for import, Markdown will simply continue without that
-extension. If you would like to be notified of such failures,
-you may set Python-Markdown's logger level to "WARN".
-
-There may be additional extensions that are distributed with
-Python-Markdown that are not included here in Extra. Those extensions
-are not part of PHP Markdown Extra, and therefore, not part of
-Python-Markdown Extra. If you really would like Extra to include
-additional extensions, we suggest creating your own clone of Extra
-under a different name (see [[Writing Extensions]]). You could also
-edit the `extensions` global variable defined in the source, but be
-aware that such changes may be lost when you upgrade to any future
-version of Python-Markdown.
diff --git a/docs/extensions/fenced_code_blocks.md b/docs/extensions/fenced_code_blocks.md
new file mode 100644
index 0000000..fc5c9ca
--- /dev/null
+++ b/docs/extensions/fenced_code_blocks.md
@@ -0,0 +1,269 @@
+title: Fenced Code Blocks Extension
+
+# Fenced Code Blocks
+
+## Summary
+
+The Fenced Code Blocks extension adds a secondary way to define code blocks, which overcomes a few limitations of
+indented code blocks.
+
+This extension is included in the standard Markdown library.
+
+## Syntax
+
+Fenced Code Blocks are defined using the syntax originally established in [PHP Markdown Extra][php] and popularized by
+[GitHub Flavored Markdown][gfm].
+
+Fenced code blocks begin with three or more backticks (` ``` `) or tildes (`~~~`) on a line by themselves and end with
+a matching set of backticks or tildes on a line by themselves. The closing set must contain the same number and type
+of characters as the opening set. It is recommended that a blank line be placed before and after the code block.
+
+````md
+A paragraph before the code block.
+
+```
+a one-line code block
+```
+
+A paragraph after the code block.
+````
+
+While backticks seem to be more popular among users, tildes may be used as well.
+
+````md
+~~~
+a one-line code block
+~~~
+````
+
+To include a set of backticks (or tildes) within a code block, use a different number of backticks for the
+deliminators.
+
+`````md
+````
+```
+````
+`````
+
+Fenced code blocks can have a blank line as the first and/or last line of the code block and those lines will be
+preserved.
+
+````md
+```
+
+a three-line code block
+
+```
+````
+
+Unlike indented code blocks, a fenced code block can immediately follow a list item without becoming
+part of the list.
+
+````md
+* A list item.
+
+```
+not part of the list
+```
+````
+
+!!! warning
+
+ Fenced Code Blocks are only supported at the document root level. Therefore, they cannot be nested inside lists or
+ blockquotes. If you need to nest fenced code blocks, you may want to try the third party extension [SuperFences]
+ instead.
+
+### Attributes
+
+Various attributes may be defined on a per-code-block basis by defining them immediately following the opening
+deliminator. The attributes should be wrapped in curly braces `{}` and be on the same line as the deliminator. It is
+generally best to separate the attribute list from the deliminator with a space. Attributes within the list must be
+separated by a space.
+
+````md
+``` { attributes go here }
+a code block with attributes
+```
+````
+
+How those attributes will affect the output will depend on various factors as described below.
+
+#### Language
+
+The language of the code within a code block can be specified for use by syntax highlighters, etc. The language should
+be prefixed with a dot and not contain any whitespace (`.language-name`).
+
+````md
+``` { .html }
+<p>HTML Document</p>
+```
+````
+
+So long as the language is the only option specified, the curly brackets and/or the dot may be excluded:
+
+````md
+``` html
+<p>HTML Document</p>
+```
+````
+
+Either of the above examples will output the following HTML:
+
+```html
+<pre><code class="language-html">&lt;p&gt;HTML Document&lt;/p&gt;
+</code></pre>
+```
+
+Note that the language name has been prefixed with `language-` and it has been assigned to the `class` attribute on
+the `<code>` tag, which is the format suggested by the [HTML 5 Specification][html5] (see the second "example" in the
+Specification). While `language` is the default prefix, the prefix may be overridden using the
+[`lang_prefix`](#lang_prefix) configuration option.
+
+#### Classes
+
+In addition to the language, additional classes may be defined by prefixing them with a dot, just like the language.
+
+````md
+``` { .html .foo .bar }
+<p>HTML Document</p>
+```
+````
+
+When defining multiple classes, only the first class will be used as the "language" for the code block. All others are
+assigned to the `<pre>` tag unaltered. Additionally, the curly braces and dot are required for all classes, including
+the language class if more than one class is defined.
+
+The above example will output the following HTML:
+
+```html
+<pre class="foo bar"><code class="language-html">&lt;p&gt;HTML Document&lt;/p&gt;
+</code></pre>
+```
+
+#### ID
+
+An `id` can be defined for a code block, which would allow a link to point directly to the code block using a URL
+hash. IDs must be prefixed with a hash character (`#`) and only contain characters permitted in HTML `id` attributes.
+
+````md
+``` { #example }
+A linkable code block
+```
+````
+
+The `id` attribute is assigned to the `<pre>` tag of the output. The above example will output the following HTML:
+
+```html
+<pre id="example"><code>A linkable code block
+</code></pre>
+```
+
+From elsewhere within the same document, one could link to the code block with `[link](#example)`.
+
+IDs may be defined along with the language, other classes, or any other supported attributes. The order of items does
+not matter.
+
+````md
+``` { #example .lang .foo .bar }
+A linkable code block
+```
+````
+
+#### Key/Value Pairs
+
+If the `fenced_code` and [`attr_list`][attr_list] extensions are both enabled, then key/value pairs can be defined in
+the attribute list. So long as code highlighting is not enabled (see below), the key/value pairs will be assigned as
+attributes on the `<code>` tag in the output. Key/value pairs must be defined using the syntax documented for the
+`attr_list` extension (for example, values with whitespace must be wrapped in quotes).
+
+````md
+``` { .lang #example style="color: #333; background: #f8f8f8;" }
+A code block with inline styles. Fancy!
+```
+````
+
+The above example will output the following HTML:
+
+```html
+<pre id="example"><code class="language-lang" style="color: #333; background: #f8f8f8;">A code block with inline styles. Fancy!
+</code></pre>
+```
+
+If the `attr_list` extension is not enabled, then the key/value pairs will be ignored.
+
+#### Syntax Highlighting
+
+If the `fenced_code` extension and syntax highlighting are both enabled, then the [`codehilite`][codehilite]
+extension will be used for syntax highlighting the contents of the code block. The language defined in the attribute
+list will be passed to `codehilite` to ensure that the correct language is used. If no language is specified and
+language guessing is not disabled for the `codehilite` extension, then the language will be guessed.
+
+The `codehilite` extension uses the [Pygments] engine to do syntax highlighting. Any valid Pygments options can be
+defined as key/value pairs in the attribute list and will be passed on to Pygments.
+
+````md
+``` { .lang linenos=true linenostart=42 hl_lines="43-44 50" title="An Example Code Block" }`
+A truncated code block...
+```
+````
+
+Valid options include any option accepted by Pygments' [`HTMLFormatter`][HTMLFormatter] except for the `full` option,
+as well as any options accepted by the relevant [lexer][lexer] (each language has its own lexer). While most lexers
+don't have options that are all that useful in this context, there are a few important exceptions. For example, the
+[PHP lexer's] `startinline` option eliminates the need to start each code fragment with `<?php`.
+
+!!! note
+
+ The `fenced_code` extension does not alter the output provided by Pygments. Therefore, only options which Pygments
+ provides can be utilized. As Pygments does not currently provide a way to define an ID, any ID defined in an
+ attribute list will be ignored when syntax highlighting is enabled. Additionally, any key/value pairs which are not Pygments options will be ignored, regardless of whether the `attr_list` extension is enabled.
+
+##### Enabling Syntax Highlighting
+
+To enable syntax highlighting, the [`codehilite`][codehilite] extension must be enabled and the `codehilite`
+extension's `use_pygments` option must be set to `True` (the default).
+
+Alternatively, so long as the `codehilite` extension is enabled, you can override a global `use_pygments=False`
+option for an individual code block by including `use_pygments=true` in the attribute list. While the `use_pygments`
+key/value pair will not be included in the output, all other attributes will behave as they would if syntax
+highlighting was enabled only for that code block.
+
+Conversely, to disable syntax highlighting on an individual code block, include `use_pygments=false` in the attribute
+list. While the `use_pygments` key/value pair will not be included in the output, all other attributes will behave as
+they would if syntax highlighting was disabled for that code block regardless of any global setting.
+
+!!! seealso "See Also"
+
+ You will need to properly install and setup Pygments for syntax highlighting to work. See the `codehilite`
+ extension's [documentation][setup] for details.
+
+## Usage
+
+See [Extensions] for general extension usage. Use `fenced_code` as the name of the extension.
+
+See the [Library Reference] for information about configuring extensions.
+
+The following option is provided to configure the output:
+
+* **`lang_prefix`**{#lang_prefix}:
+ The prefix prepended to the language class assigned to the HTML `<code>` tag. Default: `language-`.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['fenced_code'])
+```
+
+[php]: http://www.michelf.com/projects/php-markdown/extra/#fenced-code-blocks
+[gfm]: https://help.github.com/en/github/writing-on-github/creating-and-highlighting-code-blocks
+[SuperFences]: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/
+[html5]: https://html.spec.whatwg.org/#the-code-element
+[attr_list]: ./attr_list.md
+[codehilite]: ./code_hilite.md
+[Pygments]: http://pygments.org/
+[HTMLFormatter]: https://pygments.org/docs/formatters/#HtmlFormatter
+[lexer]: https://pygments.org/docs/lexers/
+[PHP lexer's]: https://pygments.org/docs/lexers/#lexers-for-php-and-related-languages
+[setup]: ./code_hilite.md#setup
+[Extensions]: ./index.md
+[Library Reference]: ../reference.md#extensions
diff --git a/docs/extensions/footnotes.md b/docs/extensions/footnotes.md
new file mode 100644
index 0000000..e841a32
--- /dev/null
+++ b/docs/extensions/footnotes.md
@@ -0,0 +1,133 @@
+title: Footnotes Extension
+
+Footnotes
+=========
+
+Summary
+-------
+
+The Footnotes extension adds syntax for defining footnotes in Markdown
+documents.
+
+This extension is included in the standard Markdown library.
+
+Syntax
+------
+
+Python-Markdown's Footnote syntax follows the generally accepted syntax of the
+Markdown community at large and almost exactly matches [PHP Markdown Extra][]'s
+implementation of footnotes. The only differences involve a few subtleties in
+the output.
+
+[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/#footnotes
+
+Example:
+
+```md
+Footnotes[^1] have a label[^@#$%] and the footnote's content.
+
+[^1]: This is a footnote content.
+[^@#$%]: A footnote on the label: "@#$%".
+```
+
+A footnote label must start with a caret `^` and may contain any inline text
+(including spaces) between a set of square brackets `[]`. Only the first
+caret has any special meaning.
+
+A footnote content must start with the label followed by a colon and at least
+one space. The label used to define the content must exactly match the label used
+in the body (including capitalization and white space). The content would then
+follow the label either on the same line or on the next line. The content may
+contain multiple lines, paragraphs, code blocks, blockquotes and most any other
+markdown syntax. The additional lines must be indented one level (four spaces or
+one tab).
+
+When working with multiple blocks, it may be helpful to start the content on a
+separate line from the label which defines the content. This way the entire block
+is indented consistently and any errors are more easily discernible by the author.
+
+```md
+[^1]:
+ The first paragraph of the definition.
+
+ Paragraph two of the definition.
+
+ > A blockquote with
+ > multiple lines.
+
+ a code block
+
+ A final paragraph.
+```
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `footnotes` as the
+name of the extension.
+
+See the [Library Reference](../reference.md#extensions) for information about
+configuring extensions.
+
+The following options are provided to configure the output:
+
+* **`PLACE_MARKER`**:
+ A text string used to mark the position where the footnotes are rendered.
+ Defaults to `///Footnotes Go Here///`.
+
+ If the place marker text is not found in the document, the footnote
+ definitions are placed at the end of the resulting HTML document.
+
+* **`UNIQUE_IDS`**:
+ Whether to avoid collisions across multiple calls to `reset()`. Defaults to
+ `False`.
+
+* **`BACKLINK_TEXT`**:
+ The text string that links from the footnote definition back to the position
+ in the document. Defaults to `&#8617;`.
+
+* **`SUPERSCRIPT_TEXT`**:
+ The text string that links from the position in the document to the footnote
+ definition. Defaults to `{}`, i.e. only the footnote's number.
+
+* **`BACKLINK_TITLE`**:
+ The text string for the `title` HTML attribute of the footnote definition link.
+ The placeholder `{}` will be replaced by the footnote number. Defaults to
+ `Jump back to footnote {} in the text`.
+
+* **`SEPARATOR`**:
+ The text string used to set the footnote separator. Defaults to `:`.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['footnotes'])
+```
+
+Resetting Instance State
+-----
+
+Footnote definitions are stored within the `markdown.Markdown` class instance between
+multiple runs of the class. This allows footnotes from all runs to be included in
+output, with links and references that are unique, even though the class has been
+called multiple times.
+
+However, if needed, the definitions can be cleared between runs by calling `reset`.
+
+For instance, the home page of a blog might include the content from multiple documents.
+By not calling `reset`, all of the footnotes will be rendered, and they will all have
+unique links and references.
+
+On the other hand, individual blog post pages might need the content from only one
+document, and should have footnotes pertaining only to that page. By calling `reset`
+between runs, the footnote definitions from the first document will be cleared before
+the second document is rendered.
+
+An example of calling `reset`:
+
+```python
+md = markdown.Markdown(extensions=['footnotes'])
+html1 = md.convert(text_with_footnote)
+md.reset()
+html2 = md.convert(text_without_footnote)
+```
diff --git a/docs/extensions/footnotes.txt b/docs/extensions/footnotes.txt
deleted file mode 100644
index 7188f44..0000000
--- a/docs/extensions/footnotes.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-Footnotes
-=========
-
-Summary
--------
-
-An extension to Python-Markdown that adds footnote syntax. This extension has
-been included with Python-Markdown since 1.7 and should be available to anyone
-who has a typical install of Python-Markdown.
-
-Syntax
-------
-
-Python-Markdown's Footnote syntax follows the generally accepted syntax of the
-Markdown community at large and almost exactly matches [PHP Markdown Extra][]'s
-implementation of footnotes. The only differences involve a few subtleties in
-the output.
-
-[PHP Markdown Extra]: http://michelf.com/projects/php-markdown/extra/#footnotes
-
-Example:
-
- Footnotes[^1] have a label[^label] and a definition[^!DEF].
-
- [^1]: This is a footnote
- [^label]: A footnote on "label"
- [^!DEF]: The definition of a footnote.
-
-A footnote definition may contain multiple lines, paragraphs, code blocks,
-blockquotes and most any other markdown syntax. The additional line simply
-must be indented at least an additional four spaces.
-
- [^1]: The first paragraph of the definition.
-
- Paragraph two of the definition.
-
- > A blockquote with
- > multiple lines.
-
- a code block
-
- A final paragraph.
-
-By default, the footnote definitions are placed at the end of the resulting
-HTML document. However, you may want the footnotes in another location within
-the document. Simply place the following text at that location within your
-markdown document (See how to configure this text below):
-
- ///Footnotes Go Here///
-
-Usage
------
-
-From the Python interpreter:
-
- >>> html = markdown.markdown(text, ['footnotes'])
-
-To configure the place marker for footnote definitions (just be sure not to
-use any existing markdown syntax):
-
- >>> html = markdown.markdown(text, ['footnotes(PLACE_MARKER=+++my marker+++)'])
-
diff --git a/docs/extensions/index.md b/docs/extensions/index.md
new file mode 100644
index 0000000..6481caa
--- /dev/null
+++ b/docs/extensions/index.md
@@ -0,0 +1,87 @@
+title: Extensions
+
+# Extensions
+
+Python Markdown offers a flexible extension mechanism, which makes it possible
+to change and/or extend the behavior of the parser without having to edit the
+actual source files.
+
+To use an extension, pass it to markdown with the `extensions` keyword.
+
+```python
+markdown.markdown(some_text, extensions=[MyExtClass(), 'myext', 'path.to.my.ext:MyExtClass'])
+```
+
+See the [Library Reference](../reference.md#extensions) for more details.
+
+From the command line, specify an extension with the `-x` option.
+
+```bash
+python -m markdown -x myext -x path.to.module:MyExtClass input.txt > output.html
+```
+
+See the [Command Line docs](../cli.md) or use the `--help` option for more details.
+
+!!! seealso "See Also"
+ If you would like to write your own extensions, see the
+ [Extension API](api.md) for details.
+
+Officially Supported Extensions
+-------------------------------
+
+The extensions listed below are included with (at least) the most recent release
+and are officially supported by Python-Markdown. Any documentation is
+maintained here and all bug reports should be made to the project. If you
+have a typical install of Python-Markdown, these extensions are already
+available to you using the "Entry Point" name listed in the second column below.
+
+Extension | Entry Point | Dot Notation
+---------------------------------- | -------------- | ------------
+[Extra] | `extra` | `markdown.extensions.extra`
+&nbsp; &nbsp; [Abbreviations] | `abbr` | `markdown.extensions.abbr`
+&nbsp; &nbsp; [Attribute Lists] | `attr_list` | `markdown.extensions.attr_list`
+&nbsp; &nbsp; [Definition Lists] | `def_list` | `markdown.extensions.def_list`
+&nbsp; &nbsp; [Fenced Code Blocks] | `fenced_code` | `markdown.extensions.fenced_code`
+&nbsp; &nbsp; [Footnotes] | `footnotes` | `markdown.extensions.footnotes`
+&nbsp; &nbsp; [Markdown in HTML] | `md_in_html` | `markdown.extensions.md_in_html`
+&nbsp; &nbsp; [Tables] | `tables` | `markdown.extensions.tables`
+[Admonition] | `admonition` | `markdown.extensions.admonition`
+[CodeHilite] | `codehilite` | `markdown.extensions.codehilite`
+[Legacy Attributes] | `legacy_attrs` | `markdown.extensions.legacy_attrs`
+[Legacy Emphasis] | `legacy_em` | `markdown.extensions.legacy_em`
+[Meta-Data] | `meta` | `markdown.extensions.meta`
+[New Line to Break] | `nl2br` | `markdown.extensions.nl2br`
+[Sane Lists] | `sane_lists` | `markdown.extensions.sane_lists`
+[SmartyPants] | `smarty` | `markdown.extensions.smarty`
+[Table of Contents] | `toc` | `markdown.extensions.toc`
+[WikiLinks] | `wikilinks` | `markdown.extensions.wikilinks`
+
+[Extra]: extra.md
+[Abbreviations]: abbreviations.md
+[Attribute Lists]: attr_list.md
+[Definition Lists]: definition_lists.md
+[Fenced Code Blocks]: fenced_code_blocks.md
+[Footnotes]: footnotes.md
+[Tables]: tables.md
+[Admonition]: admonition.md
+[CodeHilite]: code_hilite.md
+[Legacy Attributes]: legacy_attrs.md
+[Legacy Emphasis]: legacy_em.md
+[Meta-Data]: meta_data.md
+[New Line to Break]: nl2br.md
+[Markdown in HTML]: md_in_html.md
+[Sane Lists]: sane_lists.md
+[SmartyPants]: smarty.md
+[Table of Contents]: toc.md
+[WikiLinks]: wikilinks.md
+
+Third Party Extensions
+----------------------
+
+Various individuals and/or organizations have developed extensions which they
+have made available to the public. A [list of third party extensions][list]
+is maintained on the wiki for your convenience. The Python-Markdown team
+offers no official support for these extensions. Please see the developer of
+each extension for support.
+
+[list]: https://github.com/Python-Markdown/markdown/wiki/Third-Party-Extensions
diff --git a/docs/extensions/index.txt b/docs/extensions/index.txt
deleted file mode 100644
index 71d857c..0000000
--- a/docs/extensions/index.txt
+++ /dev/null
@@ -1,44 +0,0 @@
-Available Extensions
-====================
-
-Officially Supported Extensions
--------------------------------
-
-These extensions are included with (at least) the most recent release and are
-officially supported by the Python-Markdown developers. Any documentation is
-maintained here and all bug reports should be made to the project. If you
-have a typical install of Python-Markdown, these extensions are already
-available to you.
-
-* [[Extra]]
- * [[Abbreviations]]
- * [[Definition_Lists]]
- * [[Fenced_Code_Blocks]]
- * [[Footnotes]]
- * [[HeaderId]]
- * [[Tables]]
-* [[CodeHilite]]
-* [[HTML_Tidy]]
-* [[ImageLinks]]
-* [[Meta-Data]]
-* [[RSS]]
-* [[Table_of_Contents]]
-* [[WikiLinks]]
-
-Unofficially Supported Extensions
----------------------------------
-
-These extensions have not yet been included in any official Python-Markdown
-release. However, the code is maintained in the projects
-[mainline git repository](http://gitorious.org/projects/python-markdown/repos/mainline)
-by the Python-Markdown developers and the official documentation is maintained
-here. All bug reports should be made to the project. It is anticipated that
-these extensions will be included with some future official release, at which
-time they will be moved to the above list of official extensions.
-
-* [[Legacy]]
-
-
-
-
-
diff --git a/docs/extensions/legacy_attrs.md b/docs/extensions/legacy_attrs.md
new file mode 100644
index 0000000..daa566d
--- /dev/null
+++ b/docs/extensions/legacy_attrs.md
@@ -0,0 +1,66 @@
+title: Legacy Attributes Extension
+
+# Legacy Attributes
+
+## Summary
+
+The Legacy Attributes extension restores Python-Markdown's original attribute
+setting syntax. Older versions of Python Markdown (prior to 3.0) included
+built-in and undocumented support for defining attributes on elements. Most
+users have never made use of the syntax and it has been deprecated in favor of
+[Attribute Lists](attr_list.md). This extension restores the legacy behavior for
+users who have existing documents which use the syntax.
+
+## Syntax
+
+Attributes are defined by including the following within the element you wish to
+assign the attributes to:
+
+```md
+{@key=value}
+```
+
+For example, to define a class to a paragraph:
+
+```md
+A paragraph with the attribute defined {@class=foo}anywhere within.
+```
+
+Which results in the following output:
+
+```html
+<p class="foo">A paragraph with the attribute defined anywhere within.</p>
+```
+
+The same applies for inline elements:
+
+```md
+Some *emphasized{@id=bar}* text.
+```
+
+```html
+<p>Some <em id="bar">emphasized</em> text.</p>
+```
+
+You can also define attributes in images:
+
+```md
+![Alt text{@id=baz}](path/to/image.jpg)
+```
+
+```html
+<p><img alt="Alt text" id="baz" src="path/to/image.jpg" /></p>
+```
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `legacy_attrs` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['legacy_attrs'])
+```
diff --git a/docs/extensions/legacy_em.md b/docs/extensions/legacy_em.md
new file mode 100644
index 0000000..67c6cd0
--- /dev/null
+++ b/docs/extensions/legacy_em.md
@@ -0,0 +1,31 @@
+title: Legacy EM Extension
+
+# Legacy EM
+
+## Summary
+
+The Legacy EM extension restores Markdown's original behavior for emphasis and
+strong syntax when using underscores.
+
+By default Python-Markdown treats `_connected_words_` intelligently by
+recognizing that mid-word underscores should not be used for emphasis. In other
+words, by default, that input would result in this output:
+`<em>connected_words</em>`.
+
+However, that behavior is not consistent with the original rules or the behavior
+of the reference implementation. Therefore, this extension can be used to better
+match the reference implementation. With the extension enabled, the above input
+would result in this output: `<em>connected</em>words_`.
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `legacy_em` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['legacy_em'])
+```
diff --git a/docs/extensions/md_in_html.md b/docs/extensions/md_in_html.md
new file mode 100644
index 0000000..978f5c3
--- /dev/null
+++ b/docs/extensions/md_in_html.md
@@ -0,0 +1,237 @@
+title: Markdown in HTML Extension
+
+# Markdown in HTML
+
+## Summary
+
+An extension that parses Markdown inside of HTML tags.
+
+## Syntax
+
+By default, Markdown ignores any content within a raw HTML block-level element. With the `md-in-html` extension
+enabled, the content of a raw HTML block-level element can be parsed as Markdown by including a `markdown` attribute
+on the opening tag. The `markdown` attribute will be stripped from the output, while all other attributes will be
+preserved.
+
+The `markdown` attribute can be assigned one of three values: [`"1"`](#1), [`"block"`](#block), or [`"span"`](#span).
+
+!!! note
+
+ The expressions "block-level" and "span-level" as used in this document refer to an element's designation
+ according to the HTML specification. Whereas the `"span"` and `"block"` values assigned to the `markdown`
+ attribute refer to the Markdown parser's behavior.
+
+### `markdown="1"` { #1 }
+
+When the `markdown` attribute is set to `"1"`, then the parser will use the default behavior for that specific tag.
+
+The following tags have the `block` behavior by default: `article`, `aside`, `blockquote`, `body`, `colgroup`,
+`details`, `div`, `dl`, `fieldset`, `figcaption`, `figure`, `footer`, `form`, `group`, `header`, `hgroup`, `hr`,
+`iframe`, `main`, `map`, `menu`, `nav`, `noscript`, `object`, `ol`, `output`, `progress`, `section`, `table`,
+`tbody`, `tfoot`, `thead`, `tr`, `ul` and `video`.
+
+For example, the following:
+
+```
+<div markdown="1">
+This is a *Markdown* Paragraph.
+</div>
+```
+
+... is rendered as:
+
+``` html
+<div>
+<p>This is a <em>Markdown</em> Paragraph.</p>
+</div>
+```
+
+The following tags have the `span` behavior by default: `address`, `dd`, `dt`, `h[1-6]`, `legend`, `li`, `p`, `td`,
+and `th`.
+
+For example, the following:
+
+```
+<p markdown="1">
+This is not a *Markdown* Paragraph.
+</p>
+```
+
+... is rendered as:
+
+``` html
+<p>
+This is not a <em>Markdown</em> Paragraph.
+</p>
+```
+
+### `markdown="block"` { #block }
+
+When the `markdown` attribute is set to `"block"`, then the parser will force the `block` behavior on the contents of
+the element so long as it is one of the `block` or `span` tags.
+
+The content of a `block` element is parsed into block-level content. In other words, the text is rendered as
+paragraphs, headers, lists, blockquotes, etc. Any inline syntax within those elements is processed as well.
+
+For example, the following:
+
+```
+<section markdown="block">
+# A header.
+
+A *Markdown* paragraph.
+
+* A list item.
+* A second list item.
+
+</section>
+```
+
+... is rendered as:
+
+``` html
+<section>
+<h1>A header.</h1>
+<p>A <em>Markdown</em> paragraph.</p>
+<ul>
+<li>A list item.</li>
+<li>A second list item.</li>
+</ul>
+</section>
+```
+
+!!! warning
+
+ Forcing elements to be parsed as `block` elements when they are not by default could result in invalid HTML.
+ For example, one could force a `<p>` element to be nested within another `<p>` element. In most cases it is
+ recommended to use the default behavior of `markdown="1"`. Explicitly setting `markdown="block"` should be
+ reserved for advanced users who understand the HTML specification and how browsers parse and render HTML.
+
+### `markdown="span"` { #span }
+
+When the `markdown` attribute is set to `"span"`, then the parser will force the `span` behavior on the contents
+of the element so long as it is one of the `block` or `span` tags.
+
+The content of a `span` element is not parsed into block-level content. In other words, the content will not be
+rendered as paragraphs, headers, etc. Only inline syntax will be rendered, such as links, strong, emphasis, etc.
+
+For example, the following:
+
+```
+<div markdown="span">
+# *Not* a header
+</div>
+```
+
+... is rendered as:
+
+``` html
+<div>
+# <em>Not</em> a header
+</div>
+```
+
+### Ignored Elements
+
+The following tags are always ignored, regardless of any `markdown` attribute: `canvas`, `math`, `option`, `pre`,
+`script`, `style`, and `textarea`. All other raw HTML tags are treated as span-level tags and are not affected by this
+extension.
+
+### Nesting
+
+When nesting multiple levels of raw HTML elements, a `markdown` attribute must be defined for each block-level
+element. For any block-level element which does not have a `markdown` attribute, everything inside that element is
+ignored, including child elements with `markdown` attributes.
+
+For example, the following:
+
+```
+<article id="my-article" markdown="1">
+# Article Title
+
+A Markdown paragraph.
+
+<section id="section-1" markdown="1">
+## Section 1 Title
+
+<p>Custom raw **HTML** which gets ignored.</p>
+
+</section>
+
+<section id="section-2" markdown="1">
+## Section 2 Title
+
+<p markdown="1">**Markdown** content.</p>
+
+</section>
+
+</article>
+```
+
+... is rendered as:
+
+```html
+<article id="my-article">
+<h1>Article Title</h1>
+<p>A Markdown paragraph.</p>
+<section id="section-1">
+<h2>Section 1 Title</h2>
+<p>Custom raw **HTML** which gets ignored.</p>
+</section>
+<section id="section-2">
+<h2>Section 2 Title</h2>
+<p><strong>Markdown</strong> content.</p>
+</section>
+</article>
+```
+
+When the value of an element's `markdown` attribute is more permissive that its parent, then the parent's stricter
+behavior is enforced. For example, a `block` element nested within a `span` element will be parsed using the `span`
+behavior. However, if the value of an element's `markdown` attribute is the same as, or more restrictive than, its
+parent, the the child element's behavior is observed. For example, a `block` element may contain either `block`
+elements or `span` elements as children and each element will be parsed using the specified behavior.
+
+### Tag Normalization
+
+While the default behavior is for Markdown to not alter raw HTML, as this extension is parsing the content of raw HTML elements, it will do some normalization of the tags of block-level elements. For example, the following raw HTML:
+
+```
+<div markdown="1">
+<p markdown="1">A Markdown paragraph with *no* closing tag.
+<p>A raw paragraph with *no* closing tag.
+</div>
+```
+
+... is rendered as:
+
+``` html
+<div>
+<p>A Markdown paragraph with <em>no</em> closing tag.
+</p>
+<p>A raw paragraph with *no* closing tag.
+</p>
+</div>
+```
+
+Notice that the parser properly recognizes that an unclosed `<p>` tag ends when another `<p>` tag begins or when the
+parent element ends. In both cases, a closing `</p>` was added to the end of the element, regardless of whether a
+`markdown` attribute was assigned to the element.
+
+To avoid any normalization, an element must not be a descendant of any block-level element which has a `markdown`
+attribute defined.
+
+!!! warning
+
+ The normalization behavior is only documented here so that document authors are not surprised when their carefully
+ crafted raw HTML is altered by Markdown. This extension should not be relied on to normalize and generate valid
+ HTML. For the best results, always include valid raw HTML (with both opening and closing tags) in your Markdown
+ documents.
+
+## Usage
+
+From the Python interpreter:
+
+``` pycon
+>>> import markdown
+>>> html = markdown.markdown(text, extensions=['md_in_html'])
+```
diff --git a/docs/extensions/meta_data.md b/docs/extensions/meta_data.md
new file mode 100644
index 0000000..d5a4c87
--- /dev/null
+++ b/docs/extensions/meta_data.md
@@ -0,0 +1,113 @@
+title: Meta-Data Extension
+
+Meta-Data
+=========
+
+Summary
+-------
+
+The Meta-Data extension adds a syntax for defining meta-data about a document.
+It is inspired by and follows the syntax of [MultiMarkdown][]. Currently,
+this extension does not use the meta-data in any way, but simply provides it as
+a `Meta` attribute of a Markdown instance for use by other extensions or
+directly by your python code.
+
+This extension is included in the standard Markdown library.
+
+[MultiMarkdown]: https://fletcherpenney.net/multimarkdown/#metadata
+
+Syntax
+------
+
+Meta-data consists of a series of keywords and values defined at the beginning
+of a markdown document like this:
+
+```md
+Title: My Document
+Summary: A brief description of my document.
+Authors: Waylan Limberg
+ John Doe
+Date: October 2, 2007
+blank-value:
+base_url: http://example.com
+
+This is the first paragraph of the document.
+```
+
+The keywords are case-insensitive and may consist of letters, numbers,
+underscores and dashes and must end with a colon. The values consist of
+anything following the colon on the line and may even be blank.
+
+If a line is indented by 4 or more spaces, that line is assumed to be an
+additional line of the value for the previous keyword. A keyword may have as
+many lines as desired.
+
+The first blank line ends all meta-data for the document. Therefore, the first
+line of a document must not be blank.
+
+Alternatively, You may use YAML style deliminators to mark the start and/or end
+of your meta-data. When doing so, the first line of your document must be `---`.
+The meta-data ends at the first blank line or the first line containing an end
+deliminator (either `---` or `...`), whichever comes first. Even though YAML
+deliminators are supported, meta-data is not parsed as YAML.
+
+All meta-data is stripped from the document prior to any further processing
+by Markdown.
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `meta` as the name
+of the extension.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['meta'])
+```
+
+Accessing the Meta-Data
+-----------------------
+
+The meta-data is made available as a python Dict in the `Meta` attribute of an
+instance of the Markdown class. For example, using the above document:
+
+```pycon
+>>> md = markdown.Markdown(extensions = ['meta'])
+>>> html = md.convert(text)
+>>> # Meta-data has been stripped from output
+>>> print html
+<p>This is the first paragraph of the document.</p>
+
+>>> # View meta-data
+>>> print md.Meta
+{
+'title' : ['My Document'],
+'summary' : ['A brief description of my document.'],
+'authors' : ['Waylan Limberg', 'John Doe'],
+'date' : ['October 2, 2007'],
+'blank-value' : [''],
+'base_url' : ['http://example.com']
+}
+```
+
+Note that the keys are all lowercase and the values consist of a list of
+strings where each item is one line for that key. This way, one could preserve
+line breaks if desired. Or the items could be joined where appropriate. No
+assumptions are made regarding the data. It is simply passed as found to the
+`Meta` attribute.
+
+Perhaps the meta-data could be passed into a template system, or used by
+various Markdown extensions. The possibilities are left to the imagination of
+the developer.
+
+Compatible Extensions
+---------------------
+
+The following extensions are currently known to work with the Meta-Data
+extension. The keywords they are known to support are also listed.
+
+* [WikiLinks](wikilinks.md)
+ * `wiki_base_url`
+ * `wiki_end_url`
+ * `wiki_html_class`
diff --git a/docs/extensions/nl2br.md b/docs/extensions/nl2br.md
new file mode 100644
index 0000000..2c7a1a5
--- /dev/null
+++ b/docs/extensions/nl2br.md
@@ -0,0 +1,41 @@
+title: New Line to Break Extension
+
+New-Line-to-Break Extension
+===========================
+
+Summary
+-------
+
+The New-Line-to-Break (`nl2br`) Extension will cause newlines to be treated as
+hard breaks; like StackOverflow and [GitHub][] flavored Markdown do.
+
+[Github]: https://github.github.com/github-flavored-markdown/
+
+Example
+-------
+
+```pycon
+>>> import markdown
+>>> text = """
+... Line 1
+... Line 2
+... """
+>>> html = markdown.markdown(text, extensions=['nl2br'])
+>>> print html
+<p>Line 1<br />
+Line 2</p>
+```
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `nl2br` as the name
+of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['nl2br'])
+```
diff --git a/docs/extensions/sane_lists.md b/docs/extensions/sane_lists.md
new file mode 100644
index 0000000..bb43833
--- /dev/null
+++ b/docs/extensions/sane_lists.md
@@ -0,0 +1,104 @@
+title: Sane Lists Extension
+
+Sane Lists
+==========
+
+Summary
+-------
+
+The Sane Lists extension alters the behavior of the Markdown List syntax
+to be less surprising.
+
+This extension is included in the standard Markdown library.
+
+Syntax
+------
+
+Sane Lists do not allow the mixing of list types. In other words, an ordered
+list will not continue when an unordered list item is encountered and
+vice versa. For example:
+
+```md
+1. Ordered item 1
+2. Ordered item 2
+
+* Unordered item 1
+* Unordered item 2
+```
+
+will result in the following output:
+
+```html
+<ol>
+ <li>Ordered item 1</li>
+ <li>Ordered item 2</li>
+</ol>
+
+<ul>
+ <li>Unordered item 1</li>
+ <li>Unordered item 2</li>
+</ul>
+```
+
+Whereas the default Markdown behavior would be to generate an unordered list.
+
+Note that, unlike the default Markdown behavior, if a blank line is not
+included between list items, the different list type is ignored completely.
+This corresponds to the behavior of paragraphs. For example:
+
+```md
+A Paragraph.
+* Not a list item.
+
+1. Ordered list item.
+* Not a separate list item.
+```
+
+With this extension the above will result in the following output:
+
+```html
+<p>A Paragraph.
+* Not a list item.</p>
+
+<ol>
+ <li>Ordered list item.
+ * Not a separate list item.</li>
+</ol>
+```
+
+Sane lists also recognize the number used in ordered lists. Given the following
+list:
+
+```md
+4. Apples
+5. Oranges
+6. Pears
+```
+
+By default markdown will ignore the fact that the first line started
+with item number "4" and the HTML list will start with a number "1".
+This extension will result in the following HTML output:
+
+```html
+<ol start="4">
+ <li>Apples</li>
+ <li>Oranges</li>
+ <li>Pears</li>
+</ol>
+```
+
+In all other ways, Sane Lists should behave as normal Markdown lists.
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `sane_lists` as the
+name of the extension.
+
+This extension does not accept any special configuration options.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['sane_lists'])
+```
diff --git a/docs/extensions/smarty.md b/docs/extensions/smarty.md
new file mode 100644
index 0000000..d7211c0
--- /dev/null
+++ b/docs/extensions/smarty.md
@@ -0,0 +1,84 @@
+title: SmartyPants Extension
+
+SmartyPants
+===========
+
+Summary
+-------
+
+The SmartyPants extension converts ASCII dashes, quotes and ellipses to
+their HTML entity equivalents.
+
+ASCII symbol | Replacements | HTML Entities | Substitution Keys
+------------ | --------------- | ------------------- | ----------------------------------------
+`'` | &lsquo; &rsquo; | `&lsquo;` `&rsquo;` | `'left-single-quote'`, `'right-single-quote'`
+`"` | &ldquo; &rdquo; | `&ldquo;` `&rdquo;` | `'left-double-quote'`, `'right-double-quote'`
+`<< >>` | &laquo; &raquo; | `&laquo;` `&raquo;` | `'left-angle-quote'`, `'right-angle-quote'`
+`...` | &hellip; | `&hellip;` | `'ellipsis'`
+`--` | &ndash; | `&ndash;` | `'ndash'`
+`---` | &mdash; | `&mdash;` | `'mdash'`
+
+Using the configuration option 'substitutions' you can overwrite the
+default substitutions. Just pass a dict mapping (a subset of) the
+keys to the substitution strings.
+
+For example, one might use the following configuration to get correct quotes for
+the German language:
+
+```python
+extension_configs = {
+ 'smarty': {
+ 'substitutions': {
+ 'left-single-quote': '&sbquo;', # sb is not a typo!
+ 'right-single-quote': '&lsquo;',
+ 'left-double-quote': '&bdquo;',
+ 'right-double-quote': '&ldquo;'
+ }
+ }
+}
+```
+
+!!! note
+ This extension re-implements the Python [SmartyPants]
+ library by integrating it into the markdown parser.
+ While this does not provide any additional features,
+ it does offer a few advantages. Notably, it will not
+ try to work on highlighted code blocks (using the
+ [CodeHilite] Extension) like the third party library
+ has been known to do.
+
+[SmartyPants]: https://pythonhosted.org/smartypants/
+[CodeHilite]: code_hilite.md
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `smarty` as the
+name of the extension.
+
+See the [Library Reference](../reference.md#extensions) for information about
+configuring extensions.
+
+The following options are provided to configure the output:
+
+Option | Default value | Description
+------ | ------------- | -----------
+`smart_dashes` | `True` | whether to convert dashes
+`smart_quotes` | `True` | whether to convert straight quotes
+`smart_angled_quotes` | `False` | whether to convert angled quotes
+`smart_ellipses` | `True` | whether to convert ellipses
+`substitutions` | `{}` | overwrite default substitutions
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['smarty'])
+```
+
+Further reading
+---------------
+
+SmartyPants extension is based on the original SmartyPants implementation
+by John Gruber. Please read its [documentation][1] for details.
+
+[1]: https://daringfireball.net/projects/smartypants/
diff --git a/docs/extensions/tables.md b/docs/extensions/tables.md
new file mode 100644
index 0000000..aaffc09
--- /dev/null
+++ b/docs/extensions/tables.md
@@ -0,0 +1,87 @@
+title: Tables Extension
+
+Tables
+======
+
+Summary
+-------
+
+The Tables extension adds the ability to create tables in Markdown documents.
+
+This extension is included in the standard Markdown library.
+
+Syntax
+------
+
+Tables are defined using the syntax established in [PHP Markdown Extra][php].
+
+[php]: http://www.michelf.com/projects/php-markdown/extra/#table
+
+Thus, the following text (taken from the above referenced PHP documentation):
+
+```md
+First Header | Second Header
+------------- | -------------
+Content Cell | Content Cell
+Content Cell | Content Cell
+```
+
+will be rendered as:
+
+```html
+<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>
+```
+
+!!! seealso "See Also"
+ The [Attribute Lists](./attr_list.md) extension includes support for defining attributes on table cells.
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `tables` as the
+name of the extension.
+
+See the [Library Reference](../reference.md#extensions) for information about
+configuring extensions.
+
+The following options are provided to change the default behavior:
+
+* **`use_align_attribute`**: Set to `True` to use `align` instead of an appropriate `style` attribute
+
+ Default: `'False'`
+
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['tables'])
+```
+
+### Examples
+
+For an example, let us suppose that alignment should be controlled by the legacy `align`
+attribute.
+
+```pycon
+>>> from markdown.extensions.tables import TableExtension
+>>> html = markdown.markdown(text,
+... extensions=[TableExtension(use_align_attribute=True)]
+... )
+```
diff --git a/docs/extensions/toc.md b/docs/extensions/toc.md
new file mode 100644
index 0000000..8d7bd35
--- /dev/null
+++ b/docs/extensions/toc.md
@@ -0,0 +1,232 @@
+title: Table of Contents Extension
+
+Table of Contents
+=================
+
+Summary
+-------
+
+The Table of Contents extension generates a Table of Contents from a Markdown
+document and adds it into the resulting HTML document.
+
+This extension is included in the standard Markdown library.
+
+Syntax
+------
+
+By default, all headers will automatically have unique `id` attributes
+generated based upon the text of the header. Note this example, in which all
+three headers would have the same `id`:
+
+```md
+#Header
+#Header
+#Header
+```
+
+Results in:
+
+```html
+<h1 id="header">Header</h1>
+<h1 id="header_1">Header</h1>
+<h1 id="header_2">Header</h1>
+```
+
+Place a marker in the document where you would like the Table of Contents to
+appear. Then, a nested list of all the headers in the document will replace the
+marker. The marker defaults to `[TOC]` so the following document:
+
+```md
+[TOC]
+
+# Header 1
+
+## Header 2
+```
+
+would generate the following output:
+
+```html
+<div class="toc">
+ <ul>
+ <li><a href="#header-1">Header 1</a></li>
+ <ul>
+ <li><a href="#header-2">Header 2</a></li>
+ </ul>
+ </ul>
+</div>
+<h1 id="header-1">Header 1</h1>
+<h2 id="header-2">Header 2</h2>
+```
+
+Regardless of whether a `marker` is found in the document (or disabled), the
+Table of Contents is available as an attribute (`toc`) on the Markdown class.
+This allows one to insert the Table of Contents elsewhere in their page
+template. For example:
+
+```pycon
+>>> md = markdown.Markdown(extensions=['toc'])
+>>> html = md.convert(text)
+>>> page = render_some_template(context={'body': html, 'toc': md.toc})
+```
+
+The `toc_tokens` attribute is also available on the Markdown class and contains
+a nested list of dict objects. For example, the above document would result in
+the following object at `md.toc_tokens`:
+
+```python
+[
+ {
+ 'level': 1,
+ 'id': 'header-1',
+ 'name': 'Header 1',
+ 'children': [
+ {'level': 2, 'id': 'header-2', 'name': 'Header 2', 'children':[]}
+ ]
+ }
+]
+```
+
+Note that the `level` refers to the `hn` level. In other words, `<h1>` is level
+`1` and `<h2>` is level `2`, etc. Be aware that improperly nested levels in the
+input may result in odd nesting of the output.
+
+### Custom Labels
+
+In most cases, the text label in the Table of Contents should match the text of
+the header. However, occasionally that is not desirable. In that case, if this
+extension is used in conjunction with the [Attribute Lists Extension] and a
+`data-toc-label` attribute is defined on the header, then the contents of that
+attribute will be used as the text label for the item in the Table of Contents.
+For example, the following Markdown:
+
+[Attribute Lists Extension]: attr_list.md
+
+```md
+[TOC]
+
+# Functions
+
+## `markdown.markdown(text [, **kwargs])` { #markdown data-toc-label='markdown.markdown' }
+```
+would generate the following output:
+
+```html
+<div class="toc">
+ <ul>
+ <li><a href="#functions">Functions</a></li>
+ <ul>
+ <li><a href="#markdown">markdown.markdown</a></li>
+ </ul>
+ </ul>
+</div>
+<h1 id="functions">Functions</h1>
+<h2 id="markdown"><code>markdown.markdown(text [, **kwargs])</code></h2>
+```
+
+Notice that the text in the Table of Contents is much cleaner and easier to read
+in the context of a Table of Contents. The `data-toc-label` is not included in
+the HTML header element. Also note that the ID was manually defined in the
+attribute list to provide a cleaner URL when linking to the header. If the ID is
+not manually defined, it is always derived from the text of the header, never
+from the `data-toc-label` attribute.
+
+Usage
+-----
+
+See [Extensions](index.md) for general extension usage. Use `toc` as the name
+of the extension.
+
+See the [Library Reference](../reference.md#extensions) for information about
+configuring extensions.
+
+The following options are provided to configure the output:
+
+* **`marker`**:
+ Text to find and replace with the Table of Contents. Defaults to `[TOC]`.
+
+ Set to an empty string to disable searching for a marker, which may save
+ some time, especially on long documents.
+
+* **`title`**:
+ Title to insert in the Table of Contents' `<div>`. Defaults to `None`.
+
+* **`toc_class`**:
+ CSS class(es) used for the `<div>` containing the Table of Contents. Defaults to `toc`.
+
+* **`anchorlink`**:
+ Set to `True` to cause all headers to link to themselves. Default is `False`.
+
+* **`anchorlink_class`**:
+ CSS class(es) used for the link. Defaults to `toclink`.
+
+* **`permalink`**:
+ Set to `True` or a string to generate permanent links at the end of each header.
+ Useful with Sphinx style sheets.
+
+ When set to `True` the paragraph symbol (&para; or "`&para;`") is used as
+ the link text. When set to a string, the provided string is used as the link
+ text.
+
+* **`permalink_class`**:
+ CSS class(es) used for the link. Defaults to `headerlink`.
+
+* **`permalink_title`**:
+ Title attribute of the permanent link. Defaults to `Permanent link`.
+
+* **`baselevel`**:
+ Base level for headers. Defaults to `1`.
+
+ The `baselevel` setting allows the header levels to be automatically
+ adjusted to fit within the hierarchy of your HTML templates. For example,
+ suppose the Markdown text for a page should not contain any headers higher
+ than level 3 (`<h3>`). The following will accomplish that:
+
+ :::pycon
+ >>> text = '''
+ ... #Some Header
+ ... ## Next Level'''
+ >>> from markdown.extensions.toc import TocExtension
+ >>> html = markdown.markdown(text, extensions=[TocExtension(baselevel=3)])
+ >>> print html
+ <h3 id="some_header">Some Header</h3>
+ <h4 id="next_level">Next Level</h4>'
+
+* **`slugify`**:
+ Callable to generate anchors.
+
+ Default: `markdown.extensions.headerid.slugify`
+
+ In order to use a different algorithm to define the id attributes, define and
+ pass in a callable which takes the following two arguments:
+
+ * `value`: The string to slugify.
+ * `separator`: The Word Separator.
+
+ The callable must return a string appropriate for use in HTML `id` attributes.
+
+ An alternate version of the default callable supporting Unicode strings is also
+ provided as `markdown.extensions.headerid.slugify_unicode`.
+
+* **`separator`**:
+ Word separator. Character which replaces white space in id. Defaults to "`-`".
+
+* **`toc_depth`**
+ Define the range of section levels to include in the Table of Contents.
+ A single integer (`b`) defines the bottom section level (`<h1>..<hb>`) only.
+ A string consisting of two digits separated by a hyphen in between (`"2-5"`),
+ define the top (`t`) and the bottom (`b`) (`<ht>..<hb>`). Defaults to `6` (bottom).
+
+ When used with conjunction with `baselevel`, this parameter will not
+ take the fitted hierarchy from `baselevel` into account. That is, if
+ both `toc_depth` and `baselevel` are `3`, then only the highest level
+ will be present in the table. If you set `baselevel` to `3` and
+ `toc_depth` to `"2-6"`, the *first* headline will be `<h3>` and so still
+ included in the Table of Contents. To exclude this first level, you
+ have to set `toc_depth` to `"4-6"`.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['toc'])
+```
diff --git a/docs/extensions/wikilinks.md b/docs/extensions/wikilinks.md
new file mode 100644
index 0000000..cd355f7
--- /dev/null
+++ b/docs/extensions/wikilinks.md
@@ -0,0 +1,154 @@
+title: WikiLinks Extension
+
+# WikiLinks
+
+## Summary
+
+The WikiLinks extension adds support for [WikiLinks][]. Specifically, any
+``[[bracketed]]`` word is converted to a link.
+
+This extension is included in the standard Markdown library.
+
+[WikiLinks]: https://en.wikipedia.org/wiki/Wikilink
+
+## Syntax
+
+A ``[[bracketed]]`` word is any combination of upper or lower case letters,
+number, dashes, underscores and spaces surrounded by double brackets. Therefore
+
+```md
+[[Bracketed]]
+```
+
+would produce the following HTML:
+
+```html
+<a href="/Bracketed/" class="wikilink">Bracketed</a>
+```
+
+Note that WikiLinks are automatically assigned `class="wikilink"` making it
+easy to style WikiLinks differently from other links on a page if one so
+desires. See below for ways to alter the class.
+
+Also note that when a space is used, the space is converted to an underscore in
+the link but left as-is in the label. Perhaps an example would illustrate this
+best:
+
+```md
+[[Wiki Link]]
+```
+
+becomes
+
+```html
+<a href="/Wiki_Link/" class="wikilink">Wiki Link</a>
+```
+
+## Usage
+
+See [Extensions](index.md) for general extension usage. Use `wikilinks` as the
+name of the extension.
+
+See the [Library Reference](../reference.md#extensions) for information about
+configuring extensions.
+
+The default behavior is to point each link to the document root of the current
+domain and close with a trailing slash. Additionally, each link is assigned to
+the HTML class `wikilink`.
+
+The following options are provided to change the default behavior:
+
+* **`base_url`**: String to append to beginning of URL.
+
+ Default: `'/'`
+
+* **`end_url`**: String to append to end of URL.
+
+ Default: `'/'`
+
+* **`html_class`**: CSS class. Leave blank for none.
+
+ Default: `'wikilink'`
+
+* **`build_url`**: Callable which formats the URL from its parts.
+
+A trivial example:
+
+```python
+markdown.markdown(some_text, extensions=['wikilinks'])
+```
+
+### Examples
+
+For an example, let us suppose links should always point to the sub-directory
+`/wiki/` and end with `.html`
+
+```pycon
+>>> from markdown.extensions.wikilinks import WikiLinkExtension
+>>> html = markdown.markdown(text,
+... extensions=[WikiLinkExtension(base_url='/wiki/', end_url='.html')]
+... )
+```
+
+The above would result in the following link for `[[WikiLink]]`.
+
+```html
+<a href="/wiki/WikiLink.html" class="wikilink">WikiLink</a>
+```
+
+If you want to do more that just alter the base and/or end of the URL, you
+could also pass in a callable which must accept three arguments (``label``,
+``base``, and ``end``). The callable must return the URL in it's entirety.
+
+```pycon
+>>> def my_url_builder(label, base, end):
+... # do stuff
+... return url
+...
+>>> html = markdown.markdown(text,
+... extensions=[WikiLinkExtension(build_url=my_url_builder)],
+... )
+```
+
+The option is also provided to change or remove the class attribute.
+
+```pycon
+>>> html = markdown.markdown(text,
+... extensions=[WikiLinkExtension(html_class='myclass')]
+... )
+```
+
+Would cause all WikiLinks to be assigned to the class `myclass`.
+
+```html
+<a href="/WikiLink/" class="myclass">WikiLink</a>
+```
+
+## Using with Meta-Data extension
+
+The WikiLink extension also supports the [Meta-Data](meta_data.md) extension.
+Please see the documentation for that extension for specifics. The supported
+meta-data keywords are:
+
+* `wiki_base_url`
+* `wiki_end_url`
+* `wiki_html_class`
+
+When used, the meta-data will override the settings provided through the
+`extension_configs` interface.
+
+This document:
+
+```md
+wiki_base_url: http://example.com/
+wiki_end_url: .html
+wiki_html_class:
+
+A [[WikiLink]] in the first paragraph.
+```
+
+would result in the following output (notice the blank `wiki_html_class`):
+
+```html
+<p>A <a href="http://example.com/WikiLink.html">WikiLink</a> in the first paragraph.</p>
+```