summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/fixtures/admon.md269
-rw-r--r--tests/fixtures/amsmath.md223
-rw-r--r--tests/fixtures/anchors.md65
-rw-r--r--tests/fixtures/attrs.md169
-rw-r--r--tests/fixtures/colon_fence.md423
-rw-r--r--tests/fixtures/container.md286
-rw-r--r--tests/fixtures/deflist.md247
-rw-r--r--tests/fixtures/dollar_math.md552
-rw-r--r--tests/fixtures/field_list.md252
-rw-r--r--tests/fixtures/footnote.md346
-rw-r--r--tests/fixtures/front_matter.md87
-rw-r--r--tests/fixtures/myst_block.md149
-rw-r--r--tests/fixtures/myst_role.md104
-rw-r--r--tests/fixtures/span.md0
-rw-r--r--tests/fixtures/substitution.md125
-rw-r--r--tests/fixtures/tasklists.md131
-rw-r--r--tests/fixtures/texmath_bracket.md387
-rw-r--r--tests/fixtures/texmath_dollar.md438
-rw-r--r--tests/fixtures/wordcount.md51
-rw-r--r--tests/test_admon.py21
-rw-r--r--tests/test_amsmath.py39
-rw-r--r--tests/test_amsmath/test_plugin_parse.yml135
-rw-r--r--tests/test_anchors.py23
-rw-r--r--tests/test_attrs.py20
-rw-r--r--tests/test_colon_fence.py36
-rw-r--r--tests/test_colon_fence/test_plugin_parse.yml17
-rw-r--r--tests/test_container.py48
-rw-r--r--tests/test_container/test_no_new_line_issue.yml110
-rw-r--r--tests/test_container/test_plugin_parse.yml110
-rw-r--r--tests/test_deflist.py37
-rw-r--r--tests/test_deflist/test_plugin_parse.yml392
-rw-r--r--tests/test_dollarmath.py96
-rw-r--r--tests/test_dollarmath/test_plugin_parse.yml159
-rw-r--r--tests/test_field_list.py32
-rw-r--r--tests/test_field_list/test_plugin_parse.yml310
-rw-r--r--tests/test_footnote.py462
-rw-r--r--tests/test_front_matter.py49
-rw-r--r--tests/test_myst_block.py79
-rw-r--r--tests/test_myst_role.py89
-rw-r--r--tests/test_substitution.py33
-rw-r--r--tests/test_substitution/test_tokens.yml105
-rw-r--r--tests/test_tasklists.py34
-rw-r--r--tests/test_tasklists/test_plugin_parse.yml458
-rw-r--r--tests/test_texmath.py105
-rw-r--r--tests/test_texmath/test_plugin_parse.yml157
-rw-r--r--tests/test_wordcount.py23
46 files changed, 7483 insertions, 0 deletions
diff --git a/tests/fixtures/admon.md b/tests/fixtures/admon.md
new file mode 100644
index 0000000..587ae80
--- /dev/null
+++ b/tests/fixtures/admon.md
@@ -0,0 +1,269 @@
+
+Simple admonition
+.
+!!! note
+ *content*
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p><em>content</em></p>
+</div>
+.
+
+
+Could contain block elements too
+.
+!!! note
+ ### heading
+
+ -----------
+
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<h3>heading</h3>
+<hr>
+</div>
+.
+
+
+Shows custom title
+.
+!!! note Custom title
+
+ Some text
+
+.
+<div class="admonition note">
+<p class="admonition-title">Custom title</p>
+<p>Some text</p>
+</div>
+.
+
+
+Shows no title
+.
+!!! note ""
+ Some text
+
+.
+<div class="admonition note">
+<p>Some text</p>
+</div>
+.
+
+
+Closes block after 2 empty lines
+.
+!!! note
+ Some text
+
+
+ A code block
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Some text</p>
+</div>
+<pre><code>A code block
+</code></pre>
+.
+
+
+Nested blocks
+.
+!!! note
+ !!! note
+ Some text
+
+ code block
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>Some text</p>
+<pre><code>code block
+</code></pre>
+</div>
+</div>
+.
+
+
+Consecutive admonitions
+.
+!!! note
+
+!!! warning
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+</div>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+</div>
+.
+
+
+Marker may be indented up to 3 chars
+.
+ !!! note
+ content
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>content</p>
+</div>
+.
+
+
+But that's a code block
+.
+ !!! note
+ content
+.
+<pre><code>!!! note
+ content
+</code></pre>
+.
+
+
+Some more indent checks
+.
+ !!! note
+ not a code block
+
+ code block
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+</div>
+<p>not a code block</p>
+<pre><code>code block
+</code></pre>
+.
+
+
+Type could be adjacent to marker
+.
+!!!note
+ xxx
+
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>xxx</p>
+</div>
+.
+
+
+Type could be adjacent to marker and content may be shifted up to 3 chars
+.
+!!!note
+ xxx
+
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>xxx</p>
+</div>
+.
+
+
+Or several spaces apart
+.
+!!! note
+ xxx
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>xxx</p>
+</div>
+.
+
+
+Admonitions self-close at the end of the document
+.
+!!! note
+ xxx
+.
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>xxx</p>
+</div>
+.
+
+
+They could be nested in lists
+.
+- !!! note
+ - a
+ - b
+- !!! warning
+ - c
+ - d
+.
+<ul>
+<li>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<ul>
+<li>a</li>
+<li>b</li>
+</ul>
+</div>
+</li>
+<li>
+<div class="admonition warning">
+<p class="admonition-title">Warning</p>
+<ul>
+<li>c</li>
+<li>d</li>
+</ul>
+</div>
+</li>
+</ul>
+.
+
+
+Or in blockquotes
+.
+> !!! note
+> xxx
+> > yyy
+> zzz
+>
+.
+<blockquote>
+<div class="admonition note">
+<p class="admonition-title">Note</p>
+<p>xxx</p>
+<blockquote>
+<p>yyy
+zzz</p>
+</blockquote>
+</div>
+</blockquote>
+.
+
+
+Renders unknown admonition type
+.
+!!! unknown title
+ content
+.
+<div class="admonition unknown">
+<p class="admonition-title">title</p>
+<p>content</p>
+</div>
+.
+
+
+Does not render
+.
+!!!
+ content
+.
+<p>!!!
+content</p>
+.
diff --git a/tests/fixtures/amsmath.md b/tests/fixtures/amsmath.md
new file mode 100644
index 0000000..ba21544
--- /dev/null
+++ b/tests/fixtures/amsmath.md
@@ -0,0 +1,223 @@
+equation environment:
+.
+\begin{equation}
+a = 1
+\end{equation}
+.
+<div class="math amsmath">
+\begin{equation}
+a = 1
+\end{equation}
+</div>
+.
+
+equation* environment:
+.
+\begin{equation*}
+a = 1
+\end{equation*}
+.
+<div class="math amsmath">
+\begin{equation*}
+a = 1
+\end{equation*}
+</div>
+.
+
+multline environment:
+.
+\begin{multline}
+a = 1
+\end{multline}
+.
+<div class="math amsmath">
+\begin{multline}
+a = 1
+\end{multline}
+</div>
+.
+
+multline* environment:
+.
+\begin{multline*}
+a = 1
+\end{multline*}
+.
+<div class="math amsmath">
+\begin{multline*}
+a = 1
+\end{multline*}
+</div>
+.
+
+gather environment:
+.
+\begin{gather}
+a = 1
+\end{gather}
+.
+<div class="math amsmath">
+\begin{gather}
+a = 1
+\end{gather}
+</div>
+.
+
+gather* environment:
+.
+\begin{gather*}
+a = 1
+\end{gather*}
+.
+<div class="math amsmath">
+\begin{gather*}
+a = 1
+\end{gather*}
+</div>
+.
+
+align environment:
+.
+\begin{align}
+a = 1
+\end{align}
+.
+<div class="math amsmath">
+\begin{align}
+a = 1
+\end{align}
+</div>
+.
+
+align* environment:
+.
+\begin{align*}
+a = 1
+\end{align*}
+.
+<div class="math amsmath">
+\begin{align*}
+a = 1
+\end{align*}
+</div>
+.
+
+alignat environment:
+.
+\begin{alignat}
+a = 1
+\end{alignat}
+.
+<div class="math amsmath">
+\begin{alignat}
+a = 1
+\end{alignat}
+</div>
+.
+
+alignat* environment:
+.
+\begin{alignat*}
+a = 1
+\end{alignat*}
+.
+<div class="math amsmath">
+\begin{alignat*}
+a = 1
+\end{alignat*}
+</div>
+.
+
+flalign environment:
+.
+\begin{flalign}
+a = 1
+\end{flalign}
+.
+<div class="math amsmath">
+\begin{flalign}
+a = 1
+\end{flalign}
+</div>
+.
+
+flalign* environment:
+.
+\begin{flalign*}
+a = 1
+\end{flalign*}
+.
+<div class="math amsmath">
+\begin{flalign*}
+a = 1
+\end{flalign*}
+</div>
+.
+
+equation environment, with before/after paragraphs:
+.
+before
+\begin{equation}
+a = 1
+\end{equation}
+after
+.
+<p>before</p>
+<div class="math amsmath">
+\begin{equation}
+a = 1
+\end{equation}
+</div>
+<p>after</p>
+.
+
+equation environment, in list:
+.
+- \begin{equation}
+ a = 1
+ \end{equation}
+.
+<ul>
+<li>
+<div class="math amsmath">
+\begin{equation}
+ a = 1
+ \end{equation}
+</div>
+</li>
+</ul>
+.
+
+`alignat` environment and HTML escaping
+.
+\begin{alignat}{3}
+ & d = \frac{1}{1 + 0.2316419x} \quad && a_1 = 0.31938153 \quad && a_2 = -0.356563782 \\
+ & a_3 = 1.781477937 \quad && a_4 = -1.821255978 \quad && a_5 = 1.330274429
+\end{alignat}
+.
+<div class="math amsmath">
+\begin{alignat}{3}
+ &amp; d = \frac{1}{1 + 0.2316419x} \quad &amp;&amp; a_1 = 0.31938153 \quad &amp;&amp; a_2 = -0.356563782 \\
+ &amp; a_3 = 1.781477937 \quad &amp;&amp; a_4 = -1.821255978 \quad &amp;&amp; a_5 = 1.330274429
+\end{alignat}
+</div>
+.
+
+`alignat*` environment and HTML escaping
+.
+\begin{alignat*}{3}
+& m \quad && \text{módulo} \quad && m>0\\
+& a \quad && \text{multiplicador} \quad && 0<a<m\\
+& c \quad && \text{constante aditiva} \quad && 0\leq c<m\\
+& x_0 \quad && \text{valor inicial} \quad && 0\leq x_0 <m
+\end{alignat*}
+.
+<div class="math amsmath">
+\begin{alignat*}{3}
+&amp; m \quad &amp;&amp; \text{módulo} \quad &amp;&amp; m&gt;0\\
+&amp; a \quad &amp;&amp; \text{multiplicador} \quad &amp;&amp; 0&lt;a&lt;m\\
+&amp; c \quad &amp;&amp; \text{constante aditiva} \quad &amp;&amp; 0\leq c&lt;m\\
+&amp; x_0 \quad &amp;&amp; \text{valor inicial} \quad &amp;&amp; 0\leq x_0 &lt;m
+\end{alignat*}
+</div>
+. \ No newline at end of file
diff --git a/tests/fixtures/anchors.md b/tests/fixtures/anchors.md
new file mode 100644
index 0000000..bd96d1f
--- /dev/null
+++ b/tests/fixtures/anchors.md
@@ -0,0 +1,65 @@
+basic (max level 2):
+.
+# H1
+
+## H2
+
+### H3
+.
+<h1 id="h1">H1</h1>
+<h2 id="h2">H2</h2>
+<h3>H3</h3>
+.
+
+space:
+.
+# a b c
+.
+<h1 id="a-b--c">a b c</h1>
+.
+
+characters:
+.
+# a,b\cβÊ
+.
+<h1 id="abcβê">a,b\cβÊ</h1>
+.
+
+emoji:
+.
+# 🚀a
+.
+<h1 id="a">🚀a</h1>
+.
+
+html entity:
+.
+# foo&amp;bar
+.
+<h1 id="foobar">foo&amp;bar</h1>
+.
+
+uniqueness:
+.
+# a
+# a
+## a
+.
+<h1 id="a">a</h1>
+<h1 id="a-1">a</h1>
+<h2 id="a-2">a</h2>
+.
+
+standard (permalink after):
+.
+# a
+.
+<h1 id="a">a <a class="header-anchor" href="#a">¶</a></h1>
+.
+
+standard (permalink before):
+.
+# a
+.
+<h1 id="a"><a class="header-anchor" href="#a">¶</a> a</h1>
+.
diff --git a/tests/fixtures/attrs.md b/tests/fixtures/attrs.md
new file mode 100644
index 0000000..75b86aa
--- /dev/null
+++ b/tests/fixtures/attrs.md
@@ -0,0 +1,169 @@
+simple reference link
+.
+[text *emphasis*](a){#id .a}
+.
+<p><a href="a" id="id" class="a">text <em>emphasis</em></a></p>
+.
+
+simple definition link
+.
+[a][]{#id .b}
+
+[a]: /url
+.
+<p><a href="/url" id="id" class="b">a</a></p>
+.
+
+simple image
+.
+![a](b){#id .a b=c}
+.
+<p><img src="b" alt="a" id="id" b="c" class="a"></p>
+.
+
+simple inline code
+.
+`a`{#id .a b=c}
+.
+<p><code id="id" b="c" class="a">a</code></p>
+.
+
+ignore if space
+.
+![a](b) {#id key="*"}
+.
+<p><img src="b" alt="a"> {#id key=&quot;*&quot;}</p>
+.
+
+ignore if text
+.
+![a](b)b{#id key="*"}
+.
+<p><img src="b" alt="a">b{#id key=&quot;*&quot;}</p>
+.
+
+multi-line
+.
+![a](b){
+ #id .a
+ b=c
+ }
+more
+.
+<p><img src="b" alt="a" id="id" b="c" class="a">
+more</p>
+.
+
+merging attributes
+.
+![a](b){#a .a}{.b class=x other=h}{#x class="x g" other=a}
+.
+<p><img src="b" alt="a" id="x" class="a b x x g" other="a"></p>
+.
+
+spans: simple
+.
+[a]{#id .b}c
+.
+<p><span id="id" class="b">a</span>c</p>
+.
+
+spans: end of inline before attrs
+.
+[a]
+.
+<p>[a]</p>
+.
+
+spans: space between brace and attrs
+.
+[a] {.b}
+.
+<p>[a] {.b}</p>
+.
+
+spans: escaped span start
+.
+\[a]{.b}
+.
+<p>[a]{.b}</p>
+.
+
+spans: escaped span end
+.
+[a\]{.b}
+.
+<p>[a]{.b}</p>
+.
+
+spans: escaped span attribute
+.
+[a]\{.b}
+.
+<p>[a]{.b}</p>
+.
+
+spans: nested text syntax
+.
+[*a*]{.b}c
+.
+<p><span class="b"><em>a</em></span>c</p>
+.
+
+spans: nested span
+.
+*[a]{.b}c*
+.
+<p><em><span class="b">a</span>c</em></p>
+.
+
+spans: multi-line
+.
+x [a
+b]{#id
+b=c} y
+.
+<p>x <span id="id" b="c">a
+b</span> y</p>
+.
+
+spans: nested spans
+.
+[[a]{.b}]{.c}
+.
+<p><span class="c"><span class="b">a</span></span></p>
+.
+
+spans: short link takes precedence over span
+.
+[a]{#id .b}
+
+[a]: /url
+.
+<p><a href="/url" id="id" class="b">a</a></p>
+.
+
+spans: long link takes precedence over span
+.
+[a][a]{#id .b}
+
+[a]: /url
+.
+<p><a href="/url" id="id" class="b">a</a></p>
+.
+
+spans: link inside span
+.
+[[a]]{#id .b}
+
+[a]: /url
+.
+<p><span id="id" class="b"><a href="/url">a</a></span></p>
+.
+
+spans: merge attributes
+.
+[a]{#a .a}{#b .a .b other=c}{other=d}
+.
+<p><span id="b" class="a b" other="d">a</span></p>
+.
diff --git a/tests/fixtures/colon_fence.md b/tests/fixtures/colon_fence.md
new file mode 100644
index 0000000..b04e0e2
--- /dev/null
+++ b/tests/fixtures/colon_fence.md
@@ -0,0 +1,423 @@
+# The initial tests are adapted from the test for normal code fences in tests/test_port/fixtures/commonmark_spec.md
+
+src line: 1638
+
+.
+:::
+<
+ >
+:::
+.
+<pre><code>&lt;
+ &gt;
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1665
+
+.
+::
+foo
+::
+.
+<p>::
+foo
+::</p>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1676
+
+.
+:::
+aaa
+~~~
+:::
+.
+<pre><code>aaa
+~~~
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1688
+
+.
+:::
+aaa
+```
+:::
+.
+<pre><code>aaa
+```
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1702
+
+.
+::::
+aaa
+:::
+::::::
+.
+<pre><code>aaa
+:::
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1729
+
+.
+:::
+.
+<pre><code></code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1736
+
+.
+:::::
+
+:::
+aaa
+.
+<pre><code>
+:::
+aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1749
+
+.
+> :::
+> aaa
+
+bbb
+.
+<blockquote>
+<pre><code>aaa
+</code></pre>
+</blockquote>
+<p>bbb</p>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1765
+
+.
+:::
+
+
+:::
+.
+<pre><code>
+
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1779
+
+.
+:::
+:::
+.
+<pre><code></code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1791
+
+.
+ :::
+ aaa
+aaa
+:::
+.
+<pre><code>aaa
+aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1803
+
+.
+ :::
+aaa
+ aaa
+aaa
+ :::
+.
+<pre><code>aaa
+aaa
+aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1817
+
+.
+ :::
+ aaa
+ aaa
+ aaa
+ :::
+.
+<pre><code>aaa
+ aaa
+aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1833
+
+.
+ :::
+ aaa
+ :::
+.
+<pre><code>:::
+aaa
+:::
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1848
+
+.
+:::
+aaa
+ :::
+.
+<pre><code>aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1858
+
+.
+ :::
+aaa
+ :::
+.
+<pre><code>aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1870
+
+.
+:::
+aaa
+ :::
+.
+<pre><code>aaa
+ :::
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1884
+
+.
+::: :::
+aaa
+.
+<pre><code class="block-:::" >aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1907
+
+.
+foo
+:::
+bar
+:::
+baz
+.
+<p>foo</p>
+<pre><code>bar
+</code></pre>
+<p>baz</p>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1946
+
+.
+:::ruby
+def foo(x)
+ return 3
+end
+:::
+.
+<pre><code class="block-ruby" >def foo(x)
+ return 3
+end
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1974
+
+.
+::::;
+::::
+.
+<pre><code class="block-;" ></code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 1984
+
+.
+::: aa :::
+foo
+.
+<pre><code class="block-aa" >foo
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2007
+
+.
+:::
+::: aaa
+:::
+.
+<pre><code>::: aaa
+</code></pre>
+.
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+src line: 2007
+
+.
+:::
+::: aaa
+:::
+.
+<pre><code>::: aaa
+</code></pre>
+.
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Ending marker could be longer
+.
+::::: name :::::
+ hello world
+::::::::::::::::
+.
+<pre><code class="block-name" > hello world
+</code></pre>
+.
+
+Nested blocks
+.
+::::: name
+:::: name
+xxx
+::::
+:::::
+.
+<pre><code class="block-name" >:::: name
+xxx
+::::
+</code></pre>
+.
+
+Name could be adjacent to marker
+.
+:::name
+xxx
+:::
+.
+<pre><code class="block-name" >xxx
+</code></pre>
+.
+
+They should terminate paragraphs
+.
+blah blah
+::: name
+content
+:::
+.
+<p>blah blah</p>
+<pre><code class="block-name" >content
+</code></pre>
+.
+
+They could be nested in lists
+.
+ - ::: name
+ - xxx
+ :::
+.
+<ul>
+<li>
+<pre><code class="block-name" >- xxx
+</code></pre>
+</li>
+</ul>
+.
+
+Or in blockquotes
+.
+> ::: name
+> xxx
+>> yyy
+> zzz
+> :::
+.
+<blockquote>
+<pre><code class="block-name" >xxx
+&gt; yyy
+zzz
+</code></pre>
+</blockquote>
+.
+
+List indentation quirks
+.
+ - ::: name
+ xxx
+ yyy
+ :::
+
+ - ::: name
+ xxx
+ yyy
+ :::
+.
+<ul>
+<li>
+<pre><code class="block-name" >xxx
+yyy
+</code></pre>
+</li>
+</ul>
+<pre><code>
+- ::: name
+ xxx
+yyy
+</code></pre>
+.
diff --git a/tests/fixtures/container.md b/tests/fixtures/container.md
new file mode 100644
index 0000000..9475b6a
--- /dev/null
+++ b/tests/fixtures/container.md
@@ -0,0 +1,286 @@
+
+Simple container
+.
+::: name
+*content*
+:::
+.
+<div class="name">
+<p><em>content</em></p>
+</div>
+.
+
+Delimiters too short
+.
+:: name
+*content*
+::
+.
+<p>:: name
+<em>content</em>
+::</p>
+.
+
+
+Could contain block elements too
+.
+::: name
+### heading
+
+-----------
+:::
+.
+<div class="name">
+<h3>heading</h3>
+<hr>
+</div>
+.
+
+
+Ending marker could be longer
+.
+::::: name :::::
+ hello world
+::::::::::::::::
+.
+<div class="name">
+<p>hello world</p>
+</div>
+.
+
+
+Nested blocks
+.
+::::: name
+:::: name
+xxx
+::::
+:::::
+.
+<div class="name">
+<div class="name">
+<p>xxx</p>
+</div>
+</div>
+.
+
+
+Incorrectly nested blocks
+.
+:::: name
+this block is closed with 5 markers below
+
+::::: name
+auto-closed block
+
+:::::
+::::
+.
+<div class="name">
+<p>this block is closed with 5 markers below</p>
+<div class="name">
+<p>auto-closed block</p>
+</div>
+</div>
+<p>::::</p>
+.
+
+
+Marker could be indented up to 3 spaces
+.
+ ::: name
+ content
+ :::
+ :::
+.
+<div class="name">
+<p>content
+:::</p>
+</div>
+.
+
+
+But that's a code block
+.
+ ::: name
+ content
+ :::
+.
+<pre><code>::: name
+content
+:::
+</code></pre>
+.
+
+
+Some more indent checks
+.
+ ::: name
+ not a code block
+
+ code block
+ :::
+.
+<div class="name">
+<p>not a code block</p>
+<pre><code>code block
+</code></pre>
+</div>
+.
+
+
+Name could be adjacent to marker
+.
+:::name
+xxx
+:::
+.
+<div class="name">
+<p>xxx</p>
+</div>
+.
+
+
+Or several spaces apart
+.
+::: name
+xxx
+:::
+.
+<div class="name">
+<p>xxx</p>
+</div>
+.
+
+
+It could contain params
+.
+::: name arg=123 foo=456
+xxx
+:::
+.
+<div class="name">
+<p>xxx</p>
+</div>
+.
+
+
+But closing marker can't
+.
+::: name
+xxx
+::: arg=123
+.
+<div class="name">
+<p>xxx
+::: arg=123</p>
+</div>
+.
+
+
+This however isn't a valid one
+.
+::: namename
+xxx
+:::
+.
+<p>::: namename
+xxx
+:::</p>
+.
+
+
+Containers self-close at the end of the document
+.
+::: name
+xxx
+.
+<div class="name">
+<p>xxx</p>
+</div>
+.
+
+
+They should terminate paragraphs
+.
+blah blah
+::: name
+content
+:::
+.
+<p>blah blah</p>
+<div class="name">
+<p>content</p>
+</div>
+.
+
+
+They could be nested in lists
+.
+ - ::: name
+ - xxx
+ :::
+.
+<ul>
+<li>
+<div class="name">
+<ul>
+<li>xxx</li>
+</ul>
+</div>
+</li>
+</ul>
+.
+
+
+Or in blockquotes
+.
+> ::: name
+> xxx
+>> yyy
+> zzz
+> :::
+.
+<blockquote>
+<div class="name">
+<p>xxx</p>
+<blockquote>
+<p>yyy
+zzz</p>
+</blockquote>
+</div>
+</blockquote>
+.
+
+
+List indentation quirks
+.
+ - ::: name
+ xxx
+ yyy
+ :::
+
+ - ::: name
+ xxx
+ yyy
+ :::
+.
+<ul>
+<li>
+<div class="name">
+<p>xxx
+yyy</p>
+</div>
+</li>
+</ul>
+<p>:::</p>
+<ul>
+<li>
+<div class="name">
+<p>xxx</p>
+</div>
+</li>
+</ul>
+<p>yyy
+:::</p>
+.
diff --git a/tests/fixtures/deflist.md b/tests/fixtures/deflist.md
new file mode 100644
index 0000000..a32952d
--- /dev/null
+++ b/tests/fixtures/deflist.md
@@ -0,0 +1,247 @@
+
+Pandoc (with slightly changed indents):
+
+.
+Term 1
+
+: Definition 1
+
+Term 2 with *inline markup*
+
+: Definition 2
+
+ { some code, part of Definition 2 }
+
+ Third paragraph of definition 2.
+.
+<dl>
+<dt>Term 1</dt>
+<dd>
+<p>Definition 1</p>
+</dd>
+<dt>Term 2 with <em>inline markup</em></dt>
+<dd>
+<p>Definition 2</p>
+<pre><code>{ some code, part of Definition 2 }
+</code></pre>
+<p>Third paragraph of definition 2.</p>
+</dd>
+</dl>
+.
+
+Pandoc again:
+
+.
+Term 1
+
+: Definition
+with lazy continuation.
+
+ Second paragraph of the definition.
+.
+<dl>
+<dt>Term 1</dt>
+<dd>
+<p>Definition
+with lazy continuation.</p>
+<p>Second paragraph of the definition.</p>
+</dd>
+</dl>
+.
+
+Well, I might just copy-paste the third one while I'm at it:
+
+.
+Term 1
+ ~ Definition 1
+
+Term 2
+ ~ Definition 2a
+ ~ Definition 2b
+.
+<dl>
+<dt>Term 1</dt>
+<dd>Definition 1</dd>
+<dt>Term 2</dt>
+<dd>Definition 2a</dd>
+<dd>Definition 2b</dd>
+</dl>
+.
+
+Now, with our custom ones. Spaces after a colon:
+
+.
+Term 1
+ : paragraph
+
+Term 2
+ : code block
+.
+<dl>
+<dt>Term 1</dt>
+<dd>paragraph</dd>
+<dt>Term 2</dt>
+<dd>
+<pre><code>code block
+</code></pre>
+</dd>
+</dl>
+.
+
+There should be something after a colon by the way:
+
+.
+Non-term 1
+ :
+
+Non-term 2
+ :
+.
+<p>Non-term 1
+:</p>
+<p>Non-term 2
+:</p>
+.
+
+
+List is tight iff all dts are tight:
+.
+Term 1
+: foo
+: bar
+
+Term 2
+: foo
+
+: bar
+.
+<dl>
+<dt>Term 1</dt>
+<dd>
+<p>foo</p>
+</dd>
+<dd>
+<p>bar</p>
+</dd>
+<dt>Term 2</dt>
+<dd>
+<p>foo</p>
+</dd>
+<dd>
+<p>bar</p>
+</dd>
+</dl>
+.
+
+
+Regression test (first paragraphs shouldn't be tight):
+.
+Term 1
+: foo
+
+ bar
+Term 2
+: foo
+.
+<dl>
+<dt>Term 1</dt>
+<dd>
+<p>foo</p>
+<p>bar
+Term 2</p>
+</dd>
+<dd>
+<p>foo</p>
+</dd>
+</dl>
+.
+
+Definition lists should be second last in the queue. Exemplī grātiā, this isn't a valid one:
+
+.
+# test
+ : just a paragraph with a colon
+.
+<h1>test</h1>
+<p>: just a paragraph with a colon</p>
+.
+
+Nested definition lists:
+
+.
+test
+ : foo
+ : bar
+ : baz
+ : bar
+ : foo
+.
+<dl>
+<dt>test</dt>
+<dd>
+<dl>
+<dt>foo</dt>
+<dd>
+<dl>
+<dt>bar</dt>
+<dd>baz</dd>
+</dl>
+</dd>
+<dd>bar</dd>
+</dl>
+</dd>
+<dd>foo</dd>
+</dl>
+.
+
+
+Regression test, tabs
+.
+Term 1
+ : code block
+.
+<dl>
+<dt>Term 1</dt>
+<dd>
+<pre><code>code block
+</code></pre>
+</dd>
+</dl>
+.
+
+
+Regression test (blockquote inside deflist)
+.
+foo
+: > bar
+: baz
+.
+<dl>
+<dt>foo</dt>
+<dd>
+<blockquote>
+<p>bar</p>
+</blockquote>
+</dd>
+<dd>baz</dd>
+</dl>
+.
+
+
+Coverage, 1 blank line
+.
+test
+
+.
+<p>test</p>
+.
+
+
+Coverage, 2 blank lines
+.
+test
+
+
+.
+<p>test</p>
+.
diff --git a/tests/fixtures/dollar_math.md b/tests/fixtures/dollar_math.md
new file mode 100644
index 0000000..a1c2d43
--- /dev/null
+++ b/tests/fixtures/dollar_math.md
@@ -0,0 +1,552 @@
+single dollar
+.
+$
+.
+<p>$</p>
+.
+
+double-dollar
+.
+$$
+.
+<p>$$</p>
+.
+
+single character inline equation. (valid=True)
+.
+$a$
+.
+<p><span class="math inline">a</span></p>
+.
+
+inline equation with single greek character (valid=True)
+.
+$\\varphi$
+.
+<p><span class="math inline">\\varphi</span></p>
+.
+
+simple equation starting and ending with numbers. (valid=True)
+.
+$1+1=2$
+.
+<p><span class="math inline">1+1=2</span></p>
+.
+
+simple equation including special html character. (valid=True)
+.
+$1+1<3$
+.
+<p><span class="math inline">1+1&lt;3</span></p>
+.
+
+equation including backslashes. (valid=True)
+.
+$a \\backslash$
+.
+<p><span class="math inline">a \\backslash</span></p>
+.
+
+use of currency symbol, i.e. digits before/after opening/closing (valid=True)
+.
+3$1+2$ $1+2$3
+.
+<p>3$1+2$ $1+2$3</p>
+.
+
+use of currency symbol (valid=True)
+.
+If you solve $1+2$ you get $3
+.
+<p>If you solve <span class="math inline">1+2</span> you get $3</p>
+.
+
+inline fraction (valid=True)
+.
+$\\frac{1}{2}$
+.
+<p><span class="math inline">\\frac{1}{2}</span></p>
+.
+
+inline column vector (valid=True)
+.
+$\\begin{pmatrix}x\\\\y\\end{pmatrix}$
+.
+<p><span class="math inline">\\begin{pmatrix}x\\\\y\\end{pmatrix}</span></p>
+.
+
+inline bold vector notation (valid=True)
+.
+${\\tilde\\bold e}_\\alpha$
+.
+<p><span class="math inline">{\\tilde\\bold e}_\\alpha</span></p>
+.
+
+exponentiation (valid=True)
+.
+$a^{b}$
+.
+<p><span class="math inline">a^{b}</span></p>
+.
+
+conjugate complex (valid=True)
+.
+$a^\*b$ with $a^\*$
+.
+<p><span class="math inline">a^\*b</span> with <span class="math inline">a^\*</span></p>
+.
+
+Inline multi-line (valid=True)
+.
+a $a
+\not=1$ b
+.
+<p>a <span class="math inline">a
+\not=1</span> b</p>
+.
+
+Inline multi-line with newline (valid=False)
+.
+a $a
+
+\not=1$ b
+.
+<p>a $a</p>
+<p>\not=1$ b</p>
+.
+
+single block equation, greek index (valid=True)
+.
+$$e_\\alpha$$
+.
+<div class="math block">
+e_\\alpha
+</div>
+.
+
+display equation on its own single line. (valid=True)
+.
+$$1+1=2$$
+.
+<div class="math block">
+1+1=2
+</div>
+.
+
+display equation with number on its own single line. (valid=True)
+.
+$$1+1=2$$ (2)
+.
+<div id="2" class="math block">
+<a href="#2" class="mathlabel" title="Permalink to this equation">¶</a>
+1+1=2
+</div>
+.
+
+inline equation followed by block equation. (valid=True)
+.
+${e}_x$
+
+$$e_\\alpha$$
+.
+<p><span class="math inline">{e}_x</span></p>
+<div class="math block">
+e_\\alpha
+</div>
+.
+
+underline tests (valid=True)
+.
+$$c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha$$
+.
+<div class="math block">
+c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha
+</div>
+.
+
+non-numeric character before opening $ or
+after closing $ or both is allowed. (valid=True)
+.
+a$1+1=2$
+$1+1=2$b
+c$x$d
+.
+<p>a<span class="math inline">1+1=2</span>
+<span class="math inline">1+1=2</span>b
+c<span class="math inline">x</span>d</p>
+.
+
+following dollar character '$' is allowed. (valid=True)
+.
+$x$ $
+.
+<p><span class="math inline">x</span> $</p>
+.
+
+consecutive inline equations. (valid=True)
+.
+$x$ $y$
+.
+<p><span class="math inline">x</span> <span class="math inline">y</span></p>
+.
+
+inline equation after '-' sign in text. (valid=True)
+.
+so-what is $x$
+.
+<p>so-what is <span class="math inline">x</span></p>
+.
+
+display equation with line breaks. (valid=True)
+.
+$$
+1+1=2
+$$
+.
+<div class="math block">
+1+1=2
+</div>
+.
+
+multiple equations (valid=True)
+.
+$$
+a = 1
+$$
+
+$$
+b = 2
+$$
+.
+<div class="math block">
+a = 1
+</div>
+<div class="math block">
+b = 2
+</div>
+.
+
+equation followed by a labelled equation (valid=True)
+.
+$$
+a = 1
+$$
+
+$$
+b = 2
+$$ (1)
+.
+<div class="math block">
+a = 1
+</div>
+<div id="1" class="math block">
+<a href="#1" class="mathlabel" title="Permalink to this equation">¶</a>
+b = 2
+</div>
+.
+
+multiline equation. (valid=True)
+.
+$$\\begin{matrix}
+ f & = & 2 + x + 3 \\
+ & = & 5 + x
+\\end{matrix}$$
+.
+<div class="math block">
+\\begin{matrix}
+ f &amp; = &amp; 2 + x + 3 \\
+ &amp; = &amp; 5 + x
+\\end{matrix}
+</div>
+.
+
+vector equation. (valid=True)
+.
+$$\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} =
+\\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot
+\\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}$$
+.
+<div class="math block">
+\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} =
+\\begin{pmatrix} A &amp; B \\\\ C &amp; D \\end{pmatrix}\\cdot
+\\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}
+</div>
+.
+
+display equation with equation number. (valid=True)
+.
+$$f(x) = x^2 - 1$$ (1)
+.
+<div id="1" class="math block">
+<a href="#1" class="mathlabel" title="Permalink to this equation">¶</a>
+f(x) = x^2 - 1
+</div>
+.
+
+inline equation following code section. (valid=True)
+.
+`code`$a-b$
+.
+<p><code>code</code><span class="math inline">a-b</span></p>
+.
+
+equation following code block. (valid=True)
+.
+```
+code
+```
+$$a+b$$
+.
+<pre><code>code
+</code></pre>
+<div class="math block">
+a+b
+</div>
+.
+
+numbered equation following code block. (valid=True)
+.
+```
+code
+```
+$$a+b$$(1)
+.
+<pre><code>code
+</code></pre>
+<div id="1" class="math block">
+<a href="#1" class="mathlabel" title="Permalink to this equation">¶</a>
+a+b
+</div>
+.
+
+Equations in list. (valid=True)
+.
+1. $1+2$
+2. $2+3$
+ 1. $3+4$
+.
+<ol>
+<li><span class="math inline">1+2</span></li>
+<li><span class="math inline">2+3</span>
+<ol>
+<li><span class="math inline">3+4</span></li>
+</ol>
+</li>
+</ol>
+.
+
+Inline sum. (valid=True)
+.
+$\\sum\_{i=1}^n$
+.
+<p><span class="math inline">\\sum\_{i=1}^n</span></p>
+.
+
+Sum without equation number. (valid=True)
+.
+$$\\sum\_{i=1}^n$$
+.
+<div class="math block">
+\\sum\_{i=1}^n
+</div>
+.
+
+Sum with equation number. (valid=True)
+.
+$$\\sum\_{i=1}\^n$$ (2)
+.
+<div id="2" class="math block">
+<a href="#2" class="mathlabel" title="Permalink to this equation">¶</a>
+\\sum\_{i=1}\^n
+</div>
+.
+
+equation number always vertically aligned. (valid=True)
+.
+$${\\bold e}(\\varphi) = \\begin{pmatrix}
+\\cos\\varphi\\\\\\sin\\varphi
+\\end{pmatrix}$$ (3)
+.
+<div id="3" class="math block">
+<a href="#3" class="mathlabel" title="Permalink to this equation">¶</a>
+{\\bold e}(\\varphi) = \\begin{pmatrix}
+\\cos\\varphi\\\\\\sin\\varphi
+\\end{pmatrix}
+</div>
+.
+
+inline equations in blockquote. (valid=True)
+.
+> see $a = b + c$
+> $c^2=a^2+b^2$ (2)
+> $c^2=a^2+b^2$
+.
+<blockquote>
+<p>see <span class="math inline">a = b + c</span>
+<span class="math inline">c^2=a^2+b^2</span> (2)
+<span class="math inline">c^2=a^2+b^2</span></p>
+</blockquote>
+.
+
+display equation in blockquote. (valid=True)
+.
+> formula
+>
+> $$ a+b=c$$ (2)
+>
+> in blockquote.
+.
+<blockquote>
+<p>formula</p>
+<div id="2" class="math block">
+<a href="#2" class="mathlabel" title="Permalink to this equation">¶</a>
+a+b=c
+</div>
+<p>in blockquote.</p>
+</blockquote>
+.
+
+mixed syntax:
+.
+$$
+a=1 \\
+b=2
+$$ (abc)
+
+- ab $c=1$ d
+.
+<div id="abc" class="math block">
+<a href="#abc" class="mathlabel" title="Permalink to this equation">¶</a>
+a=1 \\
+b=2
+</div>
+<ul>
+<li>ab <span class="math inline">c=1</span> d</li>
+</ul>
+.
+
+escaped dollars '\\$' are interpreted as
+dollar '$' characters. (valid=True)
+.
+\\$1+1=2$
+$1+1=2\\$
+.
+<p>\<span class="math inline">1+1=2</span>
+<span class="math inline">1+1=2\\</span></p>
+.
+
+empty line between text and display formula is required. (valid=False)
+.
+some text
+ \$\\$a+b=c\$\$
+.
+<p>some text
+$\$a+b=c$$</p>
+.
+
+whitespace character after opening $
+or before closing $ is not allowed. (valid=False)
+.
+$ $
+$ x$
+$x $
+.
+<p>$ $
+$ x$
+$x $</p>
+.
+
+new line in blockquote block (valid=False):
+.
+> \$\$ a+b\n=c\$\$
+.
+<blockquote>
+<p>$$ a+b\n=c$$</p>
+</blockquote>
+.
+
+math-escaping: escaped start $:
+.
+\$p_2 = $a
+.
+<p>$p_2 = $a</p>
+.
+
+math-escaping: escaped end $:
+.
+$p_2 = \$a
+.
+<p>$p_2 = $a</p>
+.
+
+math-escaping: internal escaped $:
+.
+$p_2 = \$1$
+.
+<p><span class="math inline">p_2 = \$1</span></p>
+.
+
+math-escaping: double-escaped start $:
+.
+\\$p_2 = 1$
+.
+<p>\<span class="math inline">p_2 = 1</span></p>
+.
+
+math-escaping: double-escaped end $:
+.
+$p_2 = \\$a
+.
+<p><span class="math inline">p_2 = \\</span>a</p>
+.
+
+Inline double-dollar start:
+.
+$$a=1$$ b
+.
+<p><div class="math inline">a=1</div> b</p>
+.
+
+Inline double-dollar end:
+.
+a $$a=1$$
+.
+<p>a <div class="math inline">a=1</div></p>
+.
+
+Inline double-dollar enclosed:
+.
+a $$a=1$$ (1) b
+.
+<p>a <div class="math inline">a=1</div> (1) b</p>
+.
+
+Inline double-dollar, escaped:
+.
+a \$$a=1$$ b
+.
+<p>a $<span class="math inline">a=1</span>$ b</p>
+.
+
+Inline mixed single/double dollars:
+.
+Hence, for $\alpha \in (0, 1)$,
+$$
+ \mathbb P (\alpha \bar{X} \ge \mu) \le \alpha;
+$$
+i.e., $[\alpha \bar{X}, \infty)$ is a lower 1-sided $1-\alpha$ confidence bound for $\mu$.
+.
+<p>Hence, for <span class="math inline">\alpha \in (0, 1)</span>,
+<div class="math inline">\mathbb P (\alpha \bar{X} \ge \mu) \le \alpha;</div>
+i.e., <span class="math inline">[\alpha \bar{X}, \infty)</span> is a lower 1-sided <span class="math inline">1-\alpha</span> confidence bound for <span class="math inline">\mu</span>.</p>
+.
+
+display equation with label containing whitespace. (valid=True)
+.
+$$1+1=2$$ (a b)
+.
+<div id="a-b" class="math block">
+<a href="#a-b" class="mathlabel" title="Permalink to this equation">¶</a>
+1+1=2
+</div>
+.
diff --git a/tests/fixtures/field_list.md b/tests/fixtures/field_list.md
new file mode 100644
index 0000000..bf31ad9
--- /dev/null
+++ b/tests/fixtures/field_list.md
@@ -0,0 +1,252 @@
+Body alignment:
+.
+:no body:
+
+:single line: content
+:paragraph: content
+ running onto new line
+:body inline: paragraph 1
+
+ paragraph 2
+
+ paragraph 3
+
+:body on 2nd line:
+ paragraph 1
+
+ paragraph 2
+
+:body on 3rd line:
+
+ paragraph 1
+
+ paragraph 2
+.
+<dl class="field-list">
+<dt>no body</dt>
+<dd></dd>
+<dt>single line</dt>
+<dd>
+<p>content</p>
+</dd>
+<dt>paragraph</dt>
+<dd>
+<p>content
+running onto new line</p>
+</dd>
+<dt>body inline</dt>
+<dd>
+<p>paragraph 1</p>
+<p>paragraph 2</p>
+<p>paragraph 3</p>
+</dd>
+<dt>body on 2nd line</dt>
+<dd>
+<p>paragraph 1</p>
+<p>paragraph 2</p>
+</dd>
+<dt>body on 3rd line</dt>
+<dd>
+<p>paragraph 1</p>
+<p>paragraph 2</p>
+</dd>
+</dl>
+.
+
+Empty name:
+.
+::
+.
+<p>::</p>
+.
+
+Whitespace only name:
+.
+: :
+.
+<p>: :</p>
+.
+
+Name markup:
+.
+:inline *markup*:
+.
+<dl class="field-list">
+<dt>inline <em>markup</em></dt>
+<dd></dd>
+</dl>
+.
+
+Content paragraph markup:
+.
+:name: body *markup*
+.
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<p>body <em>markup</em></p>
+</dd>
+</dl>
+.
+
+Body list:
+.
+:name:
+ - item 1
+ - item 2
+:name: - item 1
+ - item 2
+.
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<ul>
+<li>item 1</li>
+<li>item 2</li>
+</ul>
+</dd>
+<dt>name</dt>
+<dd>
+<ul>
+<li>item 1</li>
+<li>item 2</li>
+</ul>
+</dd>
+</dl>
+.
+
+Body code block
+.
+:name:
+ code
+:name: body
+
+ code
+.
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<pre><code>code
+</code></pre>
+</dd>
+<dt>name</dt>
+<dd>
+<p>body</p>
+<pre><code>code
+</code></pre>
+</dd>
+</dl>
+.
+
+Body blockquote:
+.
+:name:
+ > item 1
+ > item 2
+:name: > item 1
+ > item 2
+.
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<blockquote>
+<p>item 1
+item 2</p>
+</blockquote>
+</dd>
+<dt>name</dt>
+<dd>
+<blockquote>
+<p>item 1
+item 2</p>
+</blockquote>
+</dd>
+</dl>
+.
+
+Body fence:
+.
+:name:
+ ```python
+ code
+ ```
+.
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<pre><code class="language-python">code
+</code></pre>
+</dd>
+</dl>
+.
+
+Following blocks:
+.
+:name: body
+- item 1
+:name: body
+> block quote
+:name: body
+```python
+code
+```
+.
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<p>body</p>
+</dd>
+</dl>
+<ul>
+<li>item 1</li>
+</ul>
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<p>body</p>
+</dd>
+</dl>
+<blockquote>
+<p>block quote</p>
+</blockquote>
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<p>body</p>
+</dd>
+</dl>
+<pre><code class="language-python">code
+</code></pre>
+.
+
+In list:
+.
+- :name: body
+- item 2
+.
+<ul>
+<li>
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<p>body</p>
+</dd>
+</dl>
+</li>
+<li>item 2</li>
+</ul>
+.
+
+In blockquote:
+.
+> :name: body
+.
+<blockquote>
+<dl class="field-list">
+<dt>name</dt>
+<dd>
+<p>body</p>
+</dd>
+</dl>
+</blockquote>
+.
diff --git a/tests/fixtures/footnote.md b/tests/fixtures/footnote.md
new file mode 100644
index 0000000..b0643e1
--- /dev/null
+++ b/tests/fixtures/footnote.md
@@ -0,0 +1,346 @@
+
+Pandoc example:
+.
+Here is a footnote reference,[^1] and another.[^longnote]
+
+[^1]: Here is the footnote.
+
+[^longnote]: Here's one with multiple blocks.
+
+ Subsequent paragraphs are indented to show that they
+belong to the previous footnote.
+
+ { some.code }
+
+ The whole paragraph can be indented, or just the first
+ line. In this way, multi-paragraph footnotes work like
+ multi-paragraph list items.
+
+This paragraph won't be part of the note, because it
+isn't indented.
+.
+<p>Here is a footnote reference,<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> and another.<sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p>
+<p>This paragraph won't be part of the note, because it
+isn't indented.</p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>Here is the footnote. <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn2" class="footnote-item"><p>Here's one with multiple blocks.</p>
+<p>Subsequent paragraphs are indented to show that they
+belong to the previous footnote.</p>
+<pre><code>{ some.code }
+</code></pre>
+<p>The whole paragraph can be indented, or just the first
+line. In this way, multi-paragraph footnotes work like
+multi-paragraph list items. <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+
+They could terminate each other:
+
+.
+[^1][^2][^3]
+
+[^1]: foo
+[^2]: bar
+[^3]: baz
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup><sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn2" class="footnote-item"><p>bar <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn3" class="footnote-item"><p>baz <a href="#fnref3" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+They could be inside blockquotes, and are lazy:
+.
+[^foo]
+
+> [^foo]: bar
+baz
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<blockquote></blockquote>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>bar
+baz <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Their labels could not contain spaces or newlines:
+
+.
+[^ foo]: bar baz
+
+[^foo
+]: bar baz
+.
+<p>[^ foo]: bar baz</p>
+<p>[^foo
+]: bar baz</p>
+.
+
+
+We support inline notes too (pandoc example):
+
+.
+Here is an inline note.^[Inlines notes are easier to write, since
+you don't have to pick an identifier and move down to type the
+note.]
+.
+<p>Here is an inline note.<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>Inlines notes are easier to write, since
+you don't have to pick an identifier and move down to type the
+note. <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+They could have arbitrary markup:
+
+.
+foo^[ *bar* ]
+.
+<p>foo<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p> <em>bar</em> <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Duplicate footnotes:
+.
+[^xxxxx] [^xxxxx]
+
+[^xxxxx]: foo
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn1" id="fnref1:1">[1:1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">↩︎</a> <a href="#fnref1:1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Indents:
+
+.
+[^xxxxx] [^yyyyy]
+
+[^xxxxx]: foo
+ ---
+
+[^yyyyy]: foo
+ ---
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p>
+<hr>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><h2>foo</h2>
+ <a href="#fnref1" class="footnote-backref">↩︎</a></li>
+<li id="fn2" class="footnote-item"><p>foo <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Indents for the first line:
+
+.
+[^xxxxx] [^yyyyy]
+
+[^xxxxx]: foo
+
+[^yyyyy]: foo
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+<li id="fn2" class="footnote-item"><pre><code>foo
+</code></pre>
+ <a href="#fnref2" class="footnote-backref">↩</a></li>
+</ol>
+</section>
+.
+
+Indents for the first line (tabs):
+.
+[^xxxxx]
+
+[^xxxxx]: foo
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>foo <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Security 1
+.
+[^__proto__]
+
+[^__proto__]: blah
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>blah <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Security 2
+.
+[^hasOwnProperty]
+
+[^hasOwnProperty]: blah
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>blah <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Should allow links in inline footnotes
+.
+Example^[this is another example https://github.com]
+.
+<p>Example<sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>this is another example https://github.com <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+Nested blocks:
+.
+[^a]
+
+[^a]: abc
+
+ def
+hij
+
+ - list
+
+ > block
+
+terminates here
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<p>terminates here</p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>abc</p>
+<p>def
+hij</p>
+<ul>
+<li>list</li>
+</ul>
+<blockquote>
+<p>block</p>
+</blockquote>
+ <a href="#fnref1" class="footnote-backref">↩︎</a></li>
+</ol>
+</section>
+.
+
+Empty lines after blockquote+footnote (markdown-it-py#133)
+.
+> b [^1]
+
+Some text
+
+> c
+
+[^1]: d
+
+
+.
+<blockquote>
+<p>b <sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+</blockquote>
+<p>Some text</p>
+<blockquote>
+<p>c</p>
+</blockquote>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"><p>d <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+</li>
+</ol>
+</section>
+.
+
+
+Newline after footnote identifier
+.
+[^a]
+
+[^a]:
+b
+.
+<p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup></p>
+<p>b</p>
+<hr class="footnotes-sep">
+<section class="footnotes">
+<ol class="footnotes-list">
+<li id="fn1" class="footnote-item"> <a href="#fnref1" class="footnote-backref"><-</a></li>
+</ol>
+</section>
+.
diff --git a/tests/fixtures/front_matter.md b/tests/fixtures/front_matter.md
new file mode 100644
index 0000000..e01fd4e
--- /dev/null
+++ b/tests/fixtures/front_matter.md
@@ -0,0 +1,87 @@
+
+should parse empty front matter:
+.
+---
+---
+# Head
+.
+
+<h1>Head</h1>
+.
+
+
+should parse basic front matter:
+.
+---
+x: 1
+---
+# Head
+.
+
+<h1>Head</h1>
+.
+
+should parse until triple dots:
+.
+---
+x: 1
+...
+# Head
+.
+
+<h1>Head</h1>
+.
+
+should parse front matter with indentation:
+.
+---
+title: Associative arrays
+people:
+ name: John Smith
+ age: 33
+morePeople: { name: Grace Jones, age: 21 }
+---
+# Head
+.
+
+<h1>Head</h1>
+.
+
+should ignore spaces after front matter delimiters:
+.
+---
+title: Associative arrays
+people:
+ name: John Smith
+ age: 33
+morePeople: { name: Grace Jones, age: 21 }
+---
+# Head
+.
+
+<h1>Head</h1>
+.
+
+should ignore front matter with less than 3 opening dashes:
+.
+--
+x: 1
+--
+# Head
+.
+<h2>--
+x: 1</h2>
+<h1>Head</h1>
+.
+
+should require front matter have matching number of opening and closing dashes:
+.
+----
+x: 1
+---
+# Head
+.
+<hr>
+<h2>x: 1</h2>
+<h1>Head</h1>
+.
diff --git a/tests/fixtures/myst_block.md b/tests/fixtures/myst_block.md
new file mode 100644
index 0000000..90bf9d3
--- /dev/null
+++ b/tests/fixtures/myst_block.md
@@ -0,0 +1,149 @@
+
+Block Break:
+.
++++
+.
+<hr class="myst-block">
+.
+
+Block Break Split Markers:
+.
+ + + + + xfsdfsdf
+.
+<hr class="myst-block">
+.
+
+Block Break Too Few Markers:
+.
+++
+.
+<p>++</p>
+.
+
+Block Break terminates other blocks:
+.
+a
++++
+- b
++++
+> c
++++
+.
+<p>a</p>
+<hr class="myst-block">
+<ul>
+<li>b</li>
+</ul>
+<hr class="myst-block">
+<blockquote>
+<p>c</p>
+</blockquote>
+<hr class="myst-block">
+.
+
+Target:
+.
+(a)=
+.
+<div class="myst-target"><a href="#a">(a)=</a></div>
+.
+
+Target characters:
+.
+(a bc |@<>*./_-+:)=
+.
+<div class="myst-target"><a href="#a bc |@<>*./_-+:">(a bc |@<>*./_-+:)=</a></div>
+.
+
+Empty target:
+.
+()=
+.
+<p>()=</p>
+.
+
+Escaped target:
+.
+\(a)=
+.
+<p>(a)=</p>
+.
+
+Indented target:
+.
+ (a)=
+.
+<div class="myst-target"><a href="#a">(a)=</a></div>
+.
+
+Target terminates other blocks:
+.
+a
+(a-b)=
+- b
+(a b)=
+> c
+(a)=
+.
+<p>a</p>
+<div class="myst-target"><a href="#a-b">(a-b)=</a></div><ul>
+<li>b</li>
+</ul>
+<div class="myst-target"><a href="#a b">(a b)=</a></div><blockquote>
+<p>c</p>
+</blockquote>
+<div class="myst-target"><a href="#a">(a)=</a></div>
+.
+
+Comment:
+.
+% abc
+.
+<!-- abc -->
+.
+
+Comment terminates other blocks:
+.
+a
+% abc
+- b
+% abc
+> c
+% abc
+.
+<p>a</p>
+<!-- abc --><ul>
+<li>b</li>
+</ul>
+<!-- abc --><blockquote>
+<p>c</p>
+</blockquote>
+<!-- abc -->
+.
+
+Multiline comment:
+.
+a
+% abc
+% def
+- b
+% abc
+%def
+> c
+%abc
+%
+%def
+.
+<p>a</p>
+<!-- abc
+def --><ul>
+<li>b</li>
+</ul>
+<!-- abc
+def --><blockquote>
+<p>c</p>
+</blockquote>
+<!-- abc
+
+def -->
+.
diff --git a/tests/fixtures/myst_role.md b/tests/fixtures/myst_role.md
new file mode 100644
index 0000000..4b2c248
--- /dev/null
+++ b/tests/fixtures/myst_role.md
@@ -0,0 +1,104 @@
+
+Basic:
+.
+{abc}`xyz`
+.
+<p><code class="myst role">{abc}[xyz]</code></p>
+.
+
+Multiple:
+.
+{abc}`xyz`{def}`uvw`
+.
+<p><code class="myst role">{abc}[xyz]</code><code class="myst role">{def}[uvw]</code></p>
+.
+
+Surrounding Text:
+.
+a {abc}`xyz` b
+.
+<p>a <code class="myst role">{abc}[xyz]</code> b</p>
+.
+
+New lines:
+.
+{abc}`xy
+z` `d
+e`
+.
+<p><code class="myst role">{abc}[xy z]</code> <code>d e</code></p>
+.
+
+In Code:
+.
+`` {abc}`xyz` ``
+.
+<p><code>{abc}`xyz`</code></p>
+.
+
+Empty content:
+.
+{name}`` a
+.
+<p>{name}`` a</p>
+.
+
+Surrounding Code:
+.
+`a` {abc}`xyz` `b`
+.
+<p><code>a</code> <code class="myst role">{abc}[xyz]</code> <code>b</code></p>
+.
+
+In list:
+.
+- {abc}`xyz`
+.
+<ul>
+<li><code class="myst role">{abc}[xyz]</code></li>
+</ul>
+.
+
+In Quote:
+.
+> {abc}`xyz` b
+.
+<blockquote>
+<p><code class="myst role">{abc}[xyz]</code> b</p>
+</blockquote>
+.
+
+Multiple ticks:
+.
+{abc}``xyz``
+.
+<p><code class="myst role">{abc}[xyz]</code></p>
+.
+
+Inner tick:
+.
+{abc}``x`yz``
+.
+<p><code class="myst role">{abc}[x`yz]</code></p>
+.
+
+Unbalanced ticks:
+.
+{abc}``xyz`
+.
+<p>{abc}``xyz`</p>
+.
+
+Space in name:
+.
+{ab c}`xyz`
+.
+<p>{ab c}<code>xyz</code></p>
+.
+
+Escaped:
+.
+\{abc}`xyz`
+.
+<p>{abc}<code>xyz</code></p>
+.
diff --git a/tests/fixtures/span.md b/tests/fixtures/span.md
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/fixtures/span.md
diff --git a/tests/fixtures/substitution.md b/tests/fixtures/substitution.md
new file mode 100644
index 0000000..1987354
--- /dev/null
+++ b/tests/fixtures/substitution.md
@@ -0,0 +1,125 @@
+Basic (space):
+.
+{{ block }}
+
+a {{ inline }} b
+.
+<div class="substitution" text="block" />
+<p>a <span class="substitution" text="inline" /> b</p>
+.
+
+Basic (no space):
+.
+{{block}}
+
+a {{inline}} b
+.
+<div class="substitution" text="block" />
+<p>a <span class="substitution" text="inline" /> b</p>
+.
+
+Same line:
+.
+{{a}}{{b}}
+.
+<p><span class="substitution" text="a" /><span class="substitution" text="b" /></p>
+.
+
+No closing:
+.
+{{ a
+
+{{b}
+
+{{c} }
+.
+<p>{{ a</p>
+<p>{{b}</p>
+<p>{{c} }</p>
+.
+
+Inside code
+.
+`{{ a }}`
+
+```python
+{{b}}
+```
+.
+<p><code>{{ a }}</code></p>
+<pre><code class="language-python">{{b}}
+</code></pre>
+.
+
+New line:
+.
+{{a}}
+{{b}}
+.
+<div class="substitution" text="a" />
+<div class="substitution" text="b" />
+.
+
+Blocks:
+.
+- {{a}}
+
+> {{b}}
+
+1. {{c}}
+.
+<ul>
+<li>
+<div class="substitution" text="a" />
+</li>
+</ul>
+<blockquote>
+<div class="substitution" text="b" />
+</blockquote>
+<ol>
+<li>
+<div class="substitution" text="c" />
+</li>
+</ol>
+.
+
+Inline:
+.
+- {{a}} x
+
+> {{b}} y
+
+1. {{c}} z
+.
+<ul>
+<li><span class="substitution" text="a" /> x</li>
+</ul>
+<blockquote>
+<p><span class="substitution" text="b" /> y</p>
+</blockquote>
+<ol>
+<li><span class="substitution" text="c" /> z</li>
+</ol>
+.
+
+Tables:
+.
+| | |
+|-|-|
+|{{a}}|{{b}} c|
+.
+<table>
+<thead>
+<tr>
+<th></th>
+<th></th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td><span class="substitution" text="a" /></td>
+<td><span class="substitution" text="b" /> c</td>
+</tr>
+</tbody>
+</table>
+.
diff --git a/tests/fixtures/tasklists.md b/tests/fixtures/tasklists.md
new file mode 100644
index 0000000..dec0fef
--- /dev/null
+++ b/tests/fixtures/tasklists.md
@@ -0,0 +1,131 @@
+
+bullet.md:
+
+.
+- [ ] unchecked item 1
+- [ ] unchecked item 2
+- [ ] unchecked item 3
+- [x] checked item 4
+.
+<ul class="contains-task-list">
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked item 1</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked item 2</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked item 3</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> checked item 4</li>
+</ul>
+
+.
+
+dirty.md:
+
+.
+- [ ] unchecked todo item 1
+- [ ]
+- [ ] not a todo item 2
+- [ x] not a todo item 3
+- [x ] not a todo item 4
+- [ x ] not a todo item 5
+- [x] todo item 6
+
+.
+<ul class="contains-task-list">
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked todo item 1</li>
+<li>[ ]</li>
+<li>[ ] not a todo item 2</li>
+<li>[ x] not a todo item 3</li>
+<li>[x ] not a todo item 4</li>
+<li>[ x ] not a todo item 5</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> todo item 6</li>
+</ul>
+
+.
+
+mixed-nested.md:
+
+.
+# Test 1
+
+1. foo
+ * [ ] nested unchecked item 1
+ * not a todo item 2
+ * not a todo item 3
+ * [x] nested checked item 4
+2. bar
+3. spam
+
+# Test 2
+
+- foo
+ - [ ] nested unchecked item 1
+ - [ ] nested unchecked item 2
+ - [x] nested checked item 3
+ - [X] nested checked item 4
+
+
+.
+<h1>Test 1</h1>
+<ol>
+<li>foo
+<ul class="contains-task-list">
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> nested unchecked item 1</li>
+<li>not a todo item 2</li>
+<li>not a todo item 3</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> nested checked item 4</li>
+</ul>
+</li>
+<li>bar</li>
+<li>spam</li>
+</ol>
+<h1>Test 2</h1>
+<ul>
+<li>foo
+<ul class="contains-task-list">
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> nested unchecked item 1</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> nested unchecked item 2</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> nested checked item 3</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> nested checked item 4</li>
+</ul>
+</li>
+</ul>
+
+.
+
+oedered.md:
+
+.
+1. [x] checked ordered 1
+2. [ ] unchecked ordered 2
+3. [x] checked ordered 3
+4. [ ] unchecked ordered 4
+
+.
+<ol class="contains-task-list">
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> checked ordered 1</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked ordered 2</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" checked="checked" disabled="disabled" type="checkbox"> checked ordered 3</li>
+<li class="task-list-item"><input class="task-list-item-checkbox" disabled="disabled" type="checkbox"> unchecked ordered 4</li>
+</ol>
+
+.
+
+Tab after task list item marker
+.
++ [x] item 1
++ [ ] item 2
+.
+<ul class="contains-task-list">
+<li class="task-list-item"> item 1</li>
+<li class="task-list-item"> item 2</li>
+</ul>
+.
+
+Form feed after task list item marker
+.
++ [x] item 1
++ [ ] item 2
+.
+<ul class="contains-task-list">
+<li class="task-list-item"> item 1</li>
+<li class="task-list-item"> item 2</li>
+</ul>
+.
diff --git a/tests/fixtures/texmath_bracket.md b/tests/fixtures/texmath_bracket.md
new file mode 100644
index 0000000..330f4cb
--- /dev/null
+++ b/tests/fixtures/texmath_bracket.md
@@ -0,0 +1,387 @@
+single character inline equation. (valid=True)
+.
+\(a\)
+.
+<p><eq>a</eq></p>
+.
+
+inline equation with single greek character (valid=True)
+.
+\(\\varphi\)
+.
+<p><eq>\\varphi</eq></p>
+.
+
+simple equation starting and ending with numbers. (valid=True)
+.
+\(1+1=2\)
+.
+<p><eq>1+1=2</eq></p>
+.
+
+simple equation including special html character. (valid=True)
+.
+\(1+1<3\)
+.
+<p><eq>1+1<3</eq></p>
+.
+
+equation including backslashes. (valid=True)
+.
+\(a \\backslash\)
+.
+<p><eq>a \\backslash</eq></p>
+.
+
+use of currency symbol (valid=True)
+.
+You get 3$ if you solve \(1+2\)
+.
+<p>You get 3$ if you solve <eq>1+2</eq></p>
+.
+
+use of currency symbol (valid=True)
+.
+If you solve \(1+2\) you get $3
+.
+<p>If you solve <eq>1+2</eq> you get $3</p>
+.
+
+inline fraction (valid=True)
+.
+\(\\frac{1}{2}\)
+.
+<p><eq>\\frac{1}{2}</eq></p>
+.
+
+inline column vector (valid=True)
+.
+\(\\begin{pmatrix}x\\\\y\\end{pmatrix}\)
+.
+<p><eq>\\begin{pmatrix}x\\\\y\\end{pmatrix}</eq></p>
+.
+
+inline bold vector notation (valid=True)
+.
+\({\\tilde\\bold e}_\\alpha\)
+.
+<p><eq>{\\tilde\\bold e}_\\alpha</eq></p>
+.
+
+exponentiation (valid=True)
+.
+\(a^{b}\)
+.
+<p><eq>a^{b}</eq></p>
+.
+
+conjugate complex (valid=True)
+.
+\(a^\*b\) with \(a^\*\)
+.
+<p><eq>a^\*b</eq> with <eq>a^\*</eq></p>
+.
+
+Inline multi-line (valid=True)
+.
+a \(a
+\not=1\) b
+.
+<p>a <eq>a
+\not=1</eq> b</p>
+.
+
+Inline multi-line with newline (valid=False)
+.
+a \(a
+
+\not=1\) b
+.
+<p>a (a</p>
+<p>\not=1) b</p>
+.
+
+single block equation, greek index (valid=True)
+.
+\[e_\\alpha\]
+.
+<section>
+<eqn>e_\\alpha</eqn>
+</section>
+.
+
+display equation on its own single line. (valid=True)
+.
+\[1+1=2\]
+.
+<section>
+<eqn>1+1=2</eqn>
+</section>
+.
+
+inline equation followed by block equation. (valid=True)
+.
+\({e}_x\)
+
+\[e_\\alpha\]
+.
+<p><eq>{e}_x</eq></p>
+<section>
+<eqn>e_\\alpha</eqn>
+</section>
+.
+
+underline tests (valid=True)
+.
+\[c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha\]
+.
+<section>
+<eqn>c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha</eqn>
+</section>
+.
+
+non-numeric character before opening $ or
+after closing $ or both is allowed. (valid=True)
+.
+a\(1+1=2\)
+\(1+1=2\)b
+c\(x\)d
+.
+<p>a<eq>1+1=2</eq>
+<eq>1+1=2</eq>b
+c<eq>x</eq>d</p>
+.
+
+following dollar character '$' is allowed. (valid=True)
+.
+\(x\) $
+.
+<p><eq>x</eq> $</p>
+.
+
+consecutive inline equations. (valid=True)
+.
+\(x\) \(y\)
+.
+<p><eq>x</eq> <eq>y</eq></p>
+.
+
+inline equation after '-' sign in text. (valid=True)
+.
+so-what is \(x\)
+.
+<p>so-what is <eq>x</eq></p>
+.
+
+display equation with line breaks. (valid=True)
+.
+\[
+1+1=2
+\]
+.
+<section>
+<eqn>
+1+1=2
+</eqn>
+</section>
+.
+
+multiple equations (valid=True)
+.
+\[
+a = 1
+\]
+
+\[
+b = 2
+\]
+.
+<section>
+<eqn>
+a = 1
+</eqn>
+</section>
+<section>
+<eqn>
+b = 2
+</eqn>
+</section>
+.
+
+equation followed by a labelled equation (valid=True)
+.
+\[
+a = 1
+\]
+
+\[
+b = 2
+\] (1)
+.
+<section>
+<eqn>
+a = 1
+</eqn>
+</section>
+<section>
+<eqn>
+b = 2
+</eqn>
+</section>
+.
+
+multiline equation. (valid=True)
+.
+\[\\begin{matrix}
+ f & = & 2 + x + 3 \\
+ & = & 5 + x
+\\end{matrix}\]
+.
+<section>
+<eqn>\\begin{matrix}
+ f & = & 2 + x + 3 \\
+ & = & 5 + x
+\\end{matrix}</eqn>
+</section>
+.
+
+vector equation. (valid=True)
+.
+\[\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} =
+\\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot
+\\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}\]
+.
+<section>
+<eqn>\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} =
+\\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot
+\\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}</eqn>
+</section>
+.
+
+display equation with equation number. (valid=True)
+.
+\[f(x) = x^2 - 1\] (1)
+.
+<section>
+<eqn>f(x) = x^2 - 1</eqn>
+</section>
+.
+
+inline equation following code section. (valid=True)
+.
+`code`\(a-b\)
+.
+<p><code>code</code><eq>a-b</eq></p>
+.
+
+equation following code block. (valid=True)
+.
+```
+code
+```
+\[a+b\]
+.
+<pre><code>code
+</code></pre>
+<section>
+<eqn>a+b</eqn>
+</section>
+.
+
+numbered equation following code block. (valid=True)
+.
+```
+code
+```
+\[a+b\](1)
+.
+<pre><code>code
+</code></pre>
+<section>
+<eqn>a+b</eqn>
+</section>
+.
+
+Equations in list. (valid=True)
+.
+1. \(1+2\)
+2. \(2+3\)
+ 1. \(3+4\)
+.
+<ol>
+<li><eq>1+2</eq></li>
+<li><eq>2+3</eq>
+<ol>
+<li><eq>3+4</eq></li>
+</ol>
+</li>
+</ol>
+.
+
+Inline sum. (valid=True)
+.
+\(\\sum\_{i=1}^n\)
+.
+<p><eq>\\sum\_{i=1}^n</eq></p>
+.
+
+Sum without equation number. (valid=True)
+.
+\[\\sum\_{i=1}^n\]
+.
+<section>
+<eqn>\\sum\_{i=1}^n</eqn>
+</section>
+.
+
+Sum with equation number. (valid=True)
+.
+\[\\sum\_{i=1}\^n\] \(2\)
+.
+<section>
+<eqn>\\sum\_{i=1}\^n</eqn>
+</section>
+.
+
+equation number always vertically aligned. (valid=True)
+.
+\[{\\bold e}(\\varphi) = \\begin{pmatrix}
+\\cos\\varphi\\\\\\sin\\varphi
+\\end{pmatrix}\] (3)
+.
+<section>
+<eqn>{\\bold e}(\\varphi) = \\begin{pmatrix}
+\\cos\\varphi\\\\\\sin\\varphi
+\\end{pmatrix}</eqn>
+</section>
+.
+
+inline equations in blockquote. (valid=True)
+.
+> see \(a = b + c\)
+> \(c^2=a^2+b^2\) (2)
+> \(c^2=a^2+b^2\)
+.
+<blockquote>
+<p>see <eq>a = b + c</eq>
+<eq>c^2=a^2+b^2</eq> (2)
+<eq>c^2=a^2+b^2</eq></p>
+</blockquote>
+.
+
+display equation in blockquote. (valid=True)
+.
+> formula
+>
+> \[ a+b=c\] (2)
+>
+> in blockquote.
+.
+<blockquote>
+<p>formula</p>
+<section>
+<eqn> a+b=c</eqn>
+</section>
+<p>in blockquote.</p>
+</blockquote>
+.
diff --git a/tests/fixtures/texmath_dollar.md b/tests/fixtures/texmath_dollar.md
new file mode 100644
index 0000000..bada6fe
--- /dev/null
+++ b/tests/fixtures/texmath_dollar.md
@@ -0,0 +1,438 @@
+single character inline equation. (valid=True)
+.
+$a$
+.
+<p><eq>a</eq></p>
+.
+
+inline equation with single greek character (valid=True)
+.
+$\\varphi$
+.
+<p><eq>\\varphi</eq></p>
+.
+
+simple equation starting and ending with numbers. (valid=True)
+.
+$1+1=2$
+.
+<p><eq>1+1=2</eq></p>
+.
+
+simple equation including special html character. (valid=True)
+.
+$1+1<3$
+.
+<p><eq>1+1<3</eq></p>
+.
+
+equation including backslashes. (valid=True)
+.
+$a \\backslash$
+.
+<p><eq>a \\backslash</eq></p>
+.
+
+use of currency symbol (valid=True)
+.
+You get 3$ if you solve $1+2$
+.
+<p>You get 3$ if you solve <eq>1+2</eq></p>
+.
+
+use of currency symbol (valid=True)
+.
+If you solve $1+2$ you get $3
+.
+<p>If you solve <eq>1+2</eq> you get $3</p>
+.
+
+inline fraction (valid=True)
+.
+$\\frac{1}{2}$
+.
+<p><eq>\\frac{1}{2}</eq></p>
+.
+
+inline column vector (valid=True)
+.
+$\\begin{pmatrix}x\\\\y\\end{pmatrix}$
+.
+<p><eq>\\begin{pmatrix}x\\\\y\\end{pmatrix}</eq></p>
+.
+
+inline bold vector notation (valid=True)
+.
+${\\tilde\\bold e}_\\alpha$
+.
+<p><eq>{\\tilde\\bold e}_\\alpha</eq></p>
+.
+
+exponentiation (valid=True)
+.
+$a^{b}$
+.
+<p><eq>a^{b}</eq></p>
+.
+
+conjugate complex (valid=True)
+.
+$a^\*b$ with $a^\*$
+.
+<p><eq>a^\*b</eq> with <eq>a^\*</eq></p>
+.
+
+Inline multi-line (valid=True)
+.
+a $a
+\not=1$ b
+.
+<p>a <eq>a
+\not=1</eq> b</p>
+.
+
+Inline multi-line with newline (valid=False)
+.
+a $a
+
+\not=1$ b
+.
+<p>a $a</p>
+<p>\not=1$ b</p>
+.
+
+single block equation, greek index (valid=True)
+.
+$$e_\\alpha$$
+.
+<section>
+<eqn>e_\\alpha</eqn>
+</section>
+.
+
+display equation on its own single line. (valid=True)
+.
+$$1+1=2$$
+.
+<section>
+<eqn>1+1=2</eqn>
+</section>
+.
+
+inline equation followed by block equation. (valid=True)
+.
+${e}_x$
+
+$$e_\\alpha$$
+.
+<p><eq>{e}_x</eq></p>
+<section>
+<eqn>e_\\alpha</eqn>
+</section>
+.
+
+underline tests (valid=True)
+.
+$$c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha$$
+.
+<section>
+<eqn>c{\\bold e}_x = a{\\bold e}_\\alpha - b\\tilde{\\bold e}_\\alpha</eqn>
+</section>
+.
+
+non-numeric character before opening $ or
+after closing $ or both is allowed. (valid=True)
+.
+a$1+1=2$
+$1+1=2$b
+c$x$d
+.
+<p>a<eq>1+1=2</eq>
+<eq>1+1=2</eq>b
+c<eq>x</eq>d</p>
+.
+
+following dollar character '$' is allowed. (valid=True)
+.
+$x$ $
+.
+<p><eq>x</eq> $</p>
+.
+
+consecutive inline equations. (valid=True)
+.
+$x$ $y$
+.
+<p><eq>x</eq> <eq>y</eq></p>
+.
+
+inline equation after '-' sign in text. (valid=True)
+.
+so-what is $x$
+.
+<p>so-what is <eq>x</eq></p>
+.
+
+display equation with line breaks. (valid=True)
+.
+$$
+1+1=2
+$$
+.
+<section>
+<eqn>
+1+1=2
+</eqn>
+</section>
+.
+
+multiple equations (valid=True)
+.
+$$
+a = 1
+$$
+
+$$
+b = 2
+$$
+.
+<section>
+<eqn>
+a = 1
+</eqn>
+</section>
+<section>
+<eqn>
+b = 2
+</eqn>
+</section>
+.
+
+equation followed by a labelled equation (valid=True)
+.
+$$
+a = 1
+$$
+
+$$
+b = 2
+$$ (1)
+.
+<section>
+<eqn>
+a = 1
+</eqn>
+</section>
+<section>
+<eqn>
+b = 2
+</eqn>
+</section>
+.
+
+multiline equation. (valid=True)
+.
+$$\\begin{matrix}
+ f & = & 2 + x + 3 \\
+ & = & 5 + x
+\\end{matrix}$$
+.
+<section>
+<eqn>\\begin{matrix}
+ f & = & 2 + x + 3 \\
+ & = & 5 + x
+\\end{matrix}</eqn>
+</section>
+.
+
+vector equation. (valid=True)
+.
+$$\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} =
+\\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot
+\\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}$$
+.
+<section>
+<eqn>\\begin{pmatrix}x_2 \\\\ y_2 \\end{pmatrix} =
+\\begin{pmatrix} A & B \\\\ C & D \\end{pmatrix}\\cdot
+\\begin{pmatrix} x_1 \\\\ y_1 \\end{pmatrix}</eqn>
+</section>
+.
+
+display equation with equation number. (valid=True)
+.
+$$f(x) = x^2 - 1$$ (1)
+.
+<section>
+<eqn>f(x) = x^2 - 1</eqn>
+</section>
+.
+
+inline equation following code section. (valid=True)
+.
+`code`$a-b$
+.
+<p><code>code</code><eq>a-b</eq></p>
+.
+
+equation following code block. (valid=True)
+.
+```
+code
+```
+$$a+b$$
+.
+<pre><code>code
+</code></pre>
+<section>
+<eqn>a+b</eqn>
+</section>
+.
+
+numbered equation following code block. (valid=True)
+.
+```
+code
+```
+$$a+b$$(1)
+.
+<pre><code>code
+</code></pre>
+<section>
+<eqn>a+b</eqn>
+</section>
+.
+
+Equations in list. (valid=True)
+.
+1. $1+2$
+2. $2+3$
+ 1. $3+4$
+.
+<ol>
+<li><eq>1+2</eq></li>
+<li><eq>2+3</eq>
+<ol>
+<li><eq>3+4</eq></li>
+</ol>
+</li>
+</ol>
+.
+
+Inline sum. (valid=True)
+.
+$\\sum\_{i=1}^n$
+.
+<p><eq>\\sum\_{i=1}^n</eq></p>
+.
+
+Sum without equation number. (valid=True)
+.
+$$\\sum\_{i=1}^n$$
+.
+<section>
+<eqn>\\sum\_{i=1}^n</eqn>
+</section>
+.
+
+Sum with equation number. (valid=True)
+.
+$$\\sum\_{i=1}\^n$$ \(2\)
+.
+<section>
+<eqn>\\sum\_{i=1}\^n</eqn>
+</section>
+.
+
+equation number always vertically aligned. (valid=True)
+.
+$${\\bold e}(\\varphi) = \\begin{pmatrix}
+\\cos\\varphi\\\\\\sin\\varphi
+\\end{pmatrix}$$ (3)
+.
+<section>
+<eqn>{\\bold e}(\\varphi) = \\begin{pmatrix}
+\\cos\\varphi\\\\\\sin\\varphi
+\\end{pmatrix}</eqn>
+</section>
+.
+
+inline equations in blockquote. (valid=True)
+.
+> see $a = b + c$
+> $c^2=a^2+b^2$ (2)
+> $c^2=a^2+b^2$
+.
+<blockquote>
+<p>see <eq>a = b + c</eq>
+<eq>c^2=a^2+b^2</eq> (2)
+<eq>c^2=a^2+b^2</eq></p>
+</blockquote>
+.
+
+display equation in blockquote. (valid=True)
+.
+> formula
+>
+> $$ a+b=c$$ (2)
+>
+> in blockquote.
+.
+<blockquote>
+<p>formula</p>
+<section>
+<eqn> a+b=c</eqn>
+</section>
+<p>in blockquote.</p>
+</blockquote>
+.
+
+mixed syntax:
+.
+$$
+a=1 \\
+b=2
+$$ (abc)
+
+- ab $c=1$ d
+.
+<section>
+<eqn>
+a=1 \\
+b=2
+</eqn>
+</section>
+<ul>
+<li>ab <eq>c=1</eq> d</li>
+</ul>
+.
+
+escaped dollars '\\$' are interpreted as
+dollar '$' characters. (valid=True)
+.
+\\$1+1=2$
+$1+1=2\\$
+.
+<p>\$1+1=2$
+$1+1=2\$</p>
+.
+
+empty line between text and display formula is required. (valid=False)
+.
+some text
+ \$\\$a+b=c\$\$
+.
+<p>some text
+$\$a+b=c$$</p>
+.
+
+whitespace character after opening $
+or before closing $ is not allowed. (valid=False)
+.
+$ $
+$ x$
+$x $
+.
+<p>$ $
+$ x$
+$x $</p>
+.
diff --git a/tests/fixtures/wordcount.md b/tests/fixtures/wordcount.md
new file mode 100644
index 0000000..e9c7948
--- /dev/null
+++ b/tests/fixtures/wordcount.md
@@ -0,0 +1,51 @@
+syntax (text)
+.
+one two
+three four
+
+- five six
+
+> seven eight
+
+[nine ten](link)
+.
+{
+ "minutes": 0,
+ "text": [
+ "one two",
+ "three four",
+ "five six",
+ "seven eight",
+ "nine ten"
+ ],
+ "words": 10
+}
+.
+
+non-words
+.
+Geeksforgeeks, is best @# Computer Science Portal.!!!
+.
+{
+ "minutes": 0,
+ "words": 6
+}
+.
+
+lore ipsum
+.
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent imperdiet hendrerit dictum. Etiam diam turpis, cursus in varius dignissim, imperdiet nec nibh. Nulla nec finibus dui. Phasellus fermentum venenatis placerat. Donec ut dui in sem rhoncus molestie. Sed auctor sem dapibus augue varius facilisis. Maecenas at suscipit dolor. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Vestibulum ornare dui ac tristique ultricies. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque arcu erat, ultricies ac lorem at, semper ornare nisl.
+
+Donec massa magna, commodo et ultrices ac, rutrum non nulla. Nunc fermentum fringilla ultrices. Morbi ante nibh, accumsan ac viverra quis, gravida rutrum mi. Integer lobortis, purus id laoreet ornare, sapien odio placerat massa, vel vestibulum dolor ante id mi. Donec ex leo, ultricies non ante eget, pharetra dictum orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vitae tortor ut nisi cursus egestas. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae; Morbi et nunc posuere, pharetra est aliquet, iaculis libero. Aliquam leo nibh, posuere eget eros a, convallis bibendum nibh. Phasellus vulputate bibendum lacus sit amet varius. Integer ut rutrum dolor, ac finibus neque. Maecenas ultrices pretium augue vitae mollis. Fusce semper lorem eu mauris iaculis pulvinar.
+
+Morbi ac pretium nunc, ac faucibus enim. Duis consequat nibh metus, at sodales sem luctus nec. Donec id finibus ante. Duis tincidunt vulputate efficitur. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Aenean porttitor augue consectetur, feugiat odio in, rutrum velit. Aliquam et mi lacinia, efficitur nisl nec, rutrum mauris. Mauris efficitur eros in maximus tempor. Suspendisse potenti. Quisque cursus non libero in faucibus. Etiam dignissim urna vel nibh feugiat, at vehicula dui vulputate.
+
+Praesent malesuada arcu quis neque condimentum vestibulum. Aliquam pretium eleifend neque, eget vulputate erat faucibus at. Quisque egestas nunc ac hendrerit fringilla. Vestibulum at tristique lacus, eget placerat risus. Aenean a metus ullamcorper, eleifend ante ut, feugiat lacus. Proin eget semper purus, ac vehicula nisl. Suspendisse eu mi enim. Nullam aliquam purus eu orci iaculis suscipit. Mauris dapibus non neque eu hendrerit. Sed eros purus, finibus ut ex ac, ultricies luctus enim. Quisque non lacus arcu. Ut dictum mauris ac tristique pulvinar. Aenean ut nisl massa. Donec nec dui scelerisque, egestas arcu sit amet, tempor eros.
+
+Donec sit amet faucibus tellus. Cras auctor mi id quam rhoncus, eget porttitor magna ultrices. Sed tristique ut augue in facilisis. Duis in finibus diam. In hac habitasse platea dictumst. Vestibulum in pulvinar orci. Sed a justo cursus enim ultrices egestas sed sit amet leo. Donec sed auctor urna. Praesent vitae dapibus ipsum. Nulla facilisi. Pellentesque non nisi sem. Sed ac mi rutrum, blandit purus ut, facilisis ipsum.
+.
+{
+ "minutes": 2,
+ "words": 458
+}
+.
diff --git a/tests/test_admon.py b/tests/test_admon.py
new file mode 100644
index 0000000..efd0ee8
--- /dev/null
+++ b/tests/test_admon.py
@@ -0,0 +1,21 @@
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.admon import admon_plugin
+
+FIXTURE_PATH = Path(__file__).parent
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected",
+ read_fixture_file(FIXTURE_PATH.joinpath("fixtures", "admon.md")),
+)
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(admon_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_amsmath.py b/tests/test_amsmath.py
new file mode 100644
index 0000000..55b4987
--- /dev/null
+++ b/tests/test_amsmath.py
@@ -0,0 +1,39 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.amsmath import amsmath_plugin
+
+FIXTURE_PATH = Path(__file__).parent
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(amsmath_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ a
+ \\begin{equation}
+ b=1
+ c=2
+ \\end{equation}
+ d
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected",
+ read_fixture_file(FIXTURE_PATH.joinpath("fixtures", "amsmath.md")),
+)
+def test_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(amsmath_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_amsmath/test_plugin_parse.yml b/tests/test_amsmath/test_plugin_parse.yml
new file mode 100644
index 0000000..4d6b949
--- /dev/null
+++ b/tests/test_amsmath/test_plugin_parse.yml
@@ -0,0 +1,135 @@
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: a
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: a
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: '\begin{equation}
+
+ b=1
+
+ c=2
+
+ \end{equation}'
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 1
+ - 4
+ markup: ''
+ meta:
+ environment: equation
+ numbered: ''
+ nesting: 0
+ tag: math
+ type: amsmath
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: d
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: d
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
diff --git a/tests/test_anchors.py b/tests/test_anchors.py
new file mode 100644
index 0000000..0515b92
--- /dev/null
+++ b/tests/test_anchors.py
@@ -0,0 +1,23 @@
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.anchors import anchors_plugin
+
+FIXTURE_PATH = Path(__file__).parent
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected",
+ read_fixture_file(FIXTURE_PATH.joinpath("fixtures", "anchors.md")),
+)
+def test_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(
+ anchors_plugin,
+ permalink="(permalink" in title,
+ permalinkBefore="before)" in title,
+ )
+ text = md.render(input)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_attrs.py b/tests/test_attrs.py
new file mode 100644
index 0000000..e4e9f0f
--- /dev/null
+++ b/tests/test_attrs.py
@@ -0,0 +1,20 @@
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.attrs import attrs_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures")
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected", read_fixture_file(FIXTURE_PATH / "attrs.md")
+)
+def test_attrs(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(attrs_plugin, spans=True)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_colon_fence.py b/tests/test_colon_fence.py
new file mode 100644
index 0000000..d520906
--- /dev/null
+++ b/tests/test_colon_fence.py
@@ -0,0 +1,36 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.colon_fence import colon_fence_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "colon_fence.md")
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(colon_fence_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ try:
+ assert text.rstrip() == expected.rstrip()
+ except AssertionError:
+ print(text)
+ raise
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(colon_fence_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ ::: name
+ *content*
+ :::
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
diff --git a/tests/test_colon_fence/test_plugin_parse.yml b/tests/test_colon_fence/test_plugin_parse.yml
new file mode 100644
index 0000000..16c7303
--- /dev/null
+++ b/tests/test_colon_fence/test_plugin_parse.yml
@@ -0,0 +1,17 @@
+- attrs: null
+ block: true
+ children: null
+ content: '*content*
+
+ '
+ hidden: false
+ info: ' name'
+ level: 0
+ map:
+ - 0
+ - 3
+ markup: ':::'
+ meta: {}
+ nesting: 0
+ tag: code
+ type: colon_fence
diff --git a/tests/test_container.py b/tests/test_container.py
new file mode 100644
index 0000000..daf2ce6
--- /dev/null
+++ b/tests/test_container.py
@@ -0,0 +1,48 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.container import container_plugin
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(container_plugin, "name")
+ tokens = md.parse(
+ dedent(
+ """\
+ ::: name
+ *content*
+ :::
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+def test_no_new_line_issue(data_regression):
+ """Fixed an IndexError when no newline on final line."""
+ md = MarkdownIt().use(container_plugin, "name")
+ tokens = md.parse(
+ dedent(
+ """\
+ ::: name
+ *content*
+ :::"""
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "container.md")
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(container_plugin, "name")
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_container/test_no_new_line_issue.yml b/tests/test_container/test_no_new_line_issue.yml
new file mode 100644
index 0000000..c744be7
--- /dev/null
+++ b/tests/test_container/test_no_new_line_issue.yml
@@ -0,0 +1,110 @@
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ' name'
+ level: 0
+ map:
+ - 0
+ - 2
+ markup: ':::'
+ meta: {}
+ nesting: 1
+ tag: div
+ type: container_name_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: em
+ type: em_open
+ - attrs: null
+ block: false
+ children: null
+ content: content
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ - attrs: null
+ block: false
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: em
+ type: em_close
+ content: '*content*'
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ':::'
+ meta: {}
+ nesting: -1
+ tag: div
+ type: container_name_close
diff --git a/tests/test_container/test_plugin_parse.yml b/tests/test_container/test_plugin_parse.yml
new file mode 100644
index 0000000..c744be7
--- /dev/null
+++ b/tests/test_container/test_plugin_parse.yml
@@ -0,0 +1,110 @@
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ' name'
+ level: 0
+ map:
+ - 0
+ - 2
+ markup: ':::'
+ meta: {}
+ nesting: 1
+ tag: div
+ type: container_name_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: em
+ type: em_open
+ - attrs: null
+ block: false
+ children: null
+ content: content
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ - attrs: null
+ block: false
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: em
+ type: em_close
+ content: '*content*'
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ':::'
+ meta: {}
+ nesting: -1
+ tag: div
+ type: container_name_close
diff --git a/tests/test_deflist.py b/tests/test_deflist.py
new file mode 100644
index 0000000..d924e93
--- /dev/null
+++ b/tests/test_deflist.py
@@ -0,0 +1,37 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.deflist import deflist_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "deflist.md")
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(deflist_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ Term 1
+
+ : Definition 1
+
+ Term 2
+ ~ Definition 2a
+ ~ Definition 2b
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(deflist_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_deflist/test_plugin_parse.yml b/tests/test_deflist/test_plugin_parse.yml
new file mode 100644
index 0000000..3202c2d
--- /dev/null
+++ b/tests/test_deflist/test_plugin_parse.yml
@@ -0,0 +1,392 @@
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 0
+ - 7
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dl
+ type: dl_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 0
+ - 0
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dt
+ type: dt_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Term 1
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Term 1
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 0
+ - 0
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dt
+ type: dt_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 2
+ - 4
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dd
+ type: dd_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 2
+ - 3
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Definition 1
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Definition 1
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 2
+ - 3
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dd
+ type: dd_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 4
+ - 4
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dt
+ type: dt_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Term 2
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Term 2
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 4
+ - 4
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dt
+ type: dt_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 4
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dd
+ type: dd_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Definition 2a
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Definition 2a
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dd
+ type: dd_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 6
+ - 7
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dd
+ type: dd_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 6
+ - 7
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Definition 2b
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Definition 2b
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 6
+ - 7
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dd
+ type: dd_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dl
+ type: dl_close
diff --git a/tests/test_dollarmath.py b/tests/test_dollarmath.py
new file mode 100644
index 0000000..9f88726
--- /dev/null
+++ b/tests/test_dollarmath.py
@@ -0,0 +1,96 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.rules_block import StateBlock
+from markdown_it.rules_inline import StateInline
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.dollarmath import dollarmath_plugin
+from mdit_py_plugins.dollarmath import index as main
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures")
+
+
+def test_inline_func():
+
+ inline_func = main.math_inline_dollar()
+
+ md = MarkdownIt()
+ src = r"$a=1$ $b=2$"
+ tokens = []
+ state = StateInline(src, md, {}, tokens)
+ inline_func(state, False)
+ assert tokens[0].as_dict() == {
+ "type": "math_inline",
+ "tag": "math",
+ "nesting": 0,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "a=1",
+ "markup": "$",
+ "info": "",
+ "meta": {},
+ "block": False,
+ "hidden": False,
+ }
+ assert state.pos == 5
+
+
+def test_block_func():
+ block_func = main.math_block_dollar()
+ md = MarkdownIt()
+ src = r"$$\na=1\n\nc\nb=2$$ (abc)"
+ tokens = []
+ state = StateBlock(src, md, {}, tokens)
+ block_func(state, 0, 10, False)
+ print(tokens[0].as_dict())
+ assert tokens[0].as_dict() == {
+ "type": "math_block_label",
+ "tag": "math",
+ "nesting": 0,
+ "attrs": None,
+ "map": [0, 1],
+ "level": 0,
+ "children": None,
+ "content": "\\na=1\\n\\nc\\nb=2",
+ "markup": "$$",
+ "info": "abc",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ }
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(dollarmath_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ $$
+ a=1
+ b=2
+ $$ (abc)
+
+ - ab $c=1$ d
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected",
+ read_fixture_file(FIXTURE_PATH.joinpath("dollar_math.md")),
+)
+def test_dollarmath_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(
+ dollarmath_plugin, allow_space=False, allow_digits=False, double_inline=True
+ )
+ md.options.xhtmlOut = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_dollarmath/test_plugin_parse.yml b/tests/test_dollarmath/test_plugin_parse.yml
new file mode 100644
index 0000000..789cbe7
--- /dev/null
+++ b/tests/test_dollarmath/test_plugin_parse.yml
@@ -0,0 +1,159 @@
+- attrs: null
+ block: true
+ children: null
+ content: '
+
+ a=1
+
+ b=2
+
+ '
+ hidden: false
+ info: abc
+ level: 0
+ map:
+ - 0
+ - 4
+ markup: $$
+ meta: {}
+ nesting: 0
+ tag: math
+ type: math_block_label
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 5
+ - 6
+ markup: '-'
+ meta: {}
+ nesting: 1
+ tag: ul
+ type: bullet_list_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 5
+ - 6
+ markup: '-'
+ meta: {}
+ nesting: 1
+ tag: li
+ type: list_item_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: 'ab '
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ - attrs: null
+ block: false
+ children: null
+ content: c=1
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: $
+ meta: {}
+ nesting: 0
+ tag: math
+ type: math_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' d'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: ab $c=1$ d
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: '-'
+ meta: {}
+ nesting: -1
+ tag: li
+ type: list_item_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '-'
+ meta: {}
+ nesting: -1
+ tag: ul
+ type: bullet_list_close
diff --git a/tests/test_field_list.py b/tests/test_field_list.py
new file mode 100644
index 0000000..cf00ae9
--- /dev/null
+++ b/tests/test_field_list.py
@@ -0,0 +1,32 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.field_list import fieldlist_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "field_list.md")
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(fieldlist_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ :abc: Content
+ :def: Content
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(fieldlist_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_field_list/test_plugin_parse.yml b/tests/test_field_list/test_plugin_parse.yml
new file mode 100644
index 0000000..c188c03
--- /dev/null
+++ b/tests/test_field_list/test_plugin_parse.yml
@@ -0,0 +1,310 @@
+- attrs:
+ - - class
+ - field-list
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 0
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dl
+ type: field_list_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 0
+ - 0
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dt
+ type: fieldlist_name_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: abc
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: abc
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 0
+ - 0
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dt
+ type: fieldlist_name_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dd
+ type: fieldlist_body_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Content
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Content
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dd
+ type: fieldlist_body_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 1
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dt
+ type: fieldlist_name_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: def
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: def
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 1
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dt
+ type: fieldlist_name_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: dd
+ type: fieldlist_body_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: Content
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: Content
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dd
+ type: fieldlist_body_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: dl
+ type: field_list_close
diff --git a/tests/test_footnote.py b/tests/test_footnote.py
new file mode 100644
index 0000000..c662cb6
--- /dev/null
+++ b/tests/test_footnote.py
@@ -0,0 +1,462 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.rules_block import StateBlock
+from markdown_it.rules_inline import StateInline
+from markdown_it.token import Token
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.footnote import footnote_plugin, index
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "footnote.md")
+
+
+def test_footnote_def():
+
+ md = MarkdownIt()
+ src = r"[^a]: xyz"
+ tokens = []
+ state = StateBlock(src, md, {}, tokens)
+ index.footnote_def(state, 0, 1, False)
+ assert [t.as_dict() for t in tokens] == [
+ {
+ "type": "footnote_reference_open",
+ "tag": "",
+ "nesting": 1,
+ "attrs": None,
+ "map": [0, 1],
+ "level": 0,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {"label": "a"},
+ "block": False,
+ "hidden": False,
+ },
+ {
+ "type": "paragraph_open",
+ "tag": "p",
+ "nesting": 1,
+ "attrs": None,
+ "map": [0, 1],
+ "level": 1,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ },
+ {
+ "type": "inline",
+ "tag": "",
+ "nesting": 0,
+ "attrs": None,
+ "map": [0, 1],
+ "level": 2,
+ "children": [],
+ "content": "xyz",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ },
+ {
+ "type": "paragraph_close",
+ "tag": "p",
+ "nesting": -1,
+ "attrs": None,
+ "map": None,
+ "level": 1,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ },
+ {
+ "type": "footnote_reference_close",
+ "tag": "",
+ "nesting": -1,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": False,
+ "hidden": False,
+ },
+ ]
+ assert state.env == {"footnotes": {"refs": {":a": -1}}}
+
+
+def test_footnote_ref():
+
+ md = MarkdownIt()
+ src = r"[^a]"
+ tokens = []
+ state = StateInline(src, md, {}, tokens)
+ state.env = {"footnotes": {"refs": {":a": -1}}}
+ index.footnote_ref(state, False)
+ # print([t.as_dict() for t in tokens])
+ assert [t.as_dict() for t in tokens] == [
+ {
+ "type": "footnote_ref",
+ "tag": "",
+ "nesting": 0,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {"id": 0, "subId": 0, "label": "a"},
+ "block": False,
+ "hidden": False,
+ }
+ ]
+ assert state.env == {
+ "footnotes": {"refs": {":a": 0}, "list": {0: {"label": "a", "count": 1}}}
+ }
+
+
+def test_footnote_inline():
+
+ md = MarkdownIt().use(footnote_plugin)
+ src = r"^[a]"
+ tokens = []
+ state = StateInline(src, md, {}, tokens)
+ state.env = {"footnotes": {"refs": {":a": -1}}}
+ index.footnote_inline(state, False)
+ # print([t.as_dict() for t in tokens])
+ assert [t.as_dict() for t in tokens] == [
+ {
+ "type": "footnote_ref",
+ "tag": "",
+ "nesting": 0,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {"id": 0},
+ "block": False,
+ "hidden": False,
+ }
+ ]
+ assert state.env == {
+ "footnotes": {
+ "refs": {":a": -1},
+ "list": {
+ 0: {
+ "content": "a",
+ "tokens": [
+ Token(
+ type="text",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="a",
+ markup="",
+ info="",
+ meta={},
+ block=False,
+ hidden=False,
+ )
+ ],
+ }
+ },
+ }
+ }
+
+
+def test_footnote_tail():
+ md = MarkdownIt()
+
+ tokens = [
+ Token(
+ **{
+ "type": "footnote_reference_open",
+ "tag": "",
+ "nesting": 1,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {"label": "a"},
+ "block": False,
+ "hidden": False,
+ }
+ ),
+ Token(
+ **{
+ "type": "paragraph_open",
+ "tag": "p",
+ "nesting": 1,
+ "attrs": None,
+ "map": [0, 1],
+ "level": 1,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ }
+ ),
+ Token(
+ **{
+ "type": "inline",
+ "tag": "",
+ "nesting": 0,
+ "attrs": None,
+ "map": [0, 1],
+ "level": 2,
+ "children": [],
+ "content": "xyz",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ }
+ ),
+ Token(
+ **{
+ "type": "paragraph_close",
+ "tag": "p",
+ "nesting": -1,
+ "attrs": None,
+ "map": None,
+ "level": 1,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ }
+ ),
+ Token(
+ **{
+ "type": "footnote_reference_close",
+ "tag": "",
+ "nesting": -1,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "",
+ "markup": "",
+ "info": "",
+ "meta": {},
+ "block": False,
+ "hidden": False,
+ }
+ ),
+ Token("other", "", 0),
+ ]
+ env = {"footnotes": {"refs": {":a": 0}, "list": {0: {"label": "a", "count": 1}}}}
+ state = StateBlock("", md, env, tokens)
+ index.footnote_tail(state)
+ assert state.tokens == [
+ Token(
+ type="other",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=False,
+ hidden=False,
+ ),
+ Token(
+ type="footnote_block_open",
+ tag="",
+ nesting=1,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=False,
+ hidden=False,
+ ),
+ Token(
+ type="footnote_open",
+ tag="",
+ nesting=1,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={"id": 0, "label": "a"},
+ block=False,
+ hidden=False,
+ ),
+ Token(
+ type="paragraph_open",
+ tag="p",
+ nesting=1,
+ attrs=None,
+ map=[0, 1],
+ level=1,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ ),
+ Token(
+ type="inline",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=[0, 1],
+ level=2,
+ children=[],
+ content="xyz",
+ markup="",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ ),
+ Token(
+ type="footnote_anchor",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={"id": 0, "subId": 0, "label": "a"},
+ block=False,
+ hidden=False,
+ ),
+ Token(
+ type="paragraph_close",
+ tag="p",
+ nesting=-1,
+ attrs=None,
+ map=None,
+ level=1,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ ),
+ Token(
+ type="footnote_close",
+ tag="",
+ nesting=-1,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=False,
+ hidden=False,
+ ),
+ Token(
+ type="footnote_block_close",
+ tag="",
+ nesting=-1,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=False,
+ hidden=False,
+ ),
+ ]
+
+
+def test_plugin_render():
+ md = MarkdownIt().use(footnote_plugin)
+ text = md.render(
+ dedent(
+ """\
+ [^1] ^[a] [^a] [^a]
+
+ [^1]: abc
+ [^a]: xyz
+ """
+ )
+ )
+ assert text == (
+ dedent(
+ """\
+ <p><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup> <sup class="footnote-ref"><a href="#fn2" id="fnref2">[2]</a></sup> <sup class="footnote-ref"><a href="#fn3" id="fnref3">[3]</a></sup> <sup class="footnote-ref"><a href="#fn3" id="fnref3:1">[3:1]</a></sup></p>
+ <hr class="footnotes-sep" />
+ <section class="footnotes">
+ <ol class="footnotes-list">
+ <li id="fn1" class="footnote-item"><p>abc <a href="#fnref1" class="footnote-backref">↩︎</a></p>
+ </li>
+ <li id="fn2" class="footnote-item"><p>a <a href="#fnref2" class="footnote-backref">↩︎</a></p>
+ </li>
+ <li id="fn3" class="footnote-item"><p>xyz <a href="#fnref3" class="footnote-backref">↩︎</a> <a href="#fnref3:1" class="footnote-backref">↩︎</a></p>
+ </li>
+ </ol>
+ </section>
+ """ # noqa: E501
+ )
+ )
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(footnote_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip().replace("↩︎", "<-").replace(
+ "↩", "<-"
+ ) == expected.rstrip().replace("↩︎", "<-").replace("↩", "<-")
diff --git a/tests/test_front_matter.py b/tests/test_front_matter.py
new file mode 100644
index 0000000..627cb89
--- /dev/null
+++ b/tests/test_front_matter.py
@@ -0,0 +1,49 @@
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.token import Token
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.front_matter import front_matter_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "front_matter.md")
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(front_matter_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
+
+
+def test_token():
+ md = MarkdownIt("commonmark").use(front_matter_plugin)
+ tokens = md.parse("---\na: 1\n---")
+ # print(tokens)
+ assert tokens == [
+ Token(
+ type="front_matter",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=[0, 3],
+ level=0,
+ children=None,
+ content="a: 1",
+ markup="---",
+ info="",
+ meta={},
+ block=True,
+ hidden=True,
+ )
+ ]
+
+
+def test_short_source():
+ md = MarkdownIt("commonmark").use(front_matter_plugin)
+
+ # The code should not raise an IndexError.
+ assert md.parse("-")
diff --git a/tests/test_myst_block.py b/tests/test_myst_block.py
new file mode 100644
index 0000000..632ed4b
--- /dev/null
+++ b/tests/test_myst_block.py
@@ -0,0 +1,79 @@
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.token import Token
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.myst_blocks import myst_block_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "myst_block.md")
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(myst_block_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
+
+
+def test_block_token():
+ md = MarkdownIt("commonmark").use(myst_block_plugin)
+ tokens = md.parse("+++")
+ expected_token = Token(
+ type="myst_block_break",
+ tag="hr",
+ nesting=0,
+ map=[0, 1],
+ level=0,
+ children=None,
+ content="",
+ markup="+++",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ )
+ expected_token.attrSet("class", "myst-block")
+ assert tokens == [expected_token]
+
+ tokens = md.parse("\n+ + + abc")
+ expected_token = Token(
+ type="myst_block_break",
+ tag="hr",
+ nesting=0,
+ map=[1, 2],
+ level=0,
+ children=None,
+ content="abc",
+ markup="+++",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ )
+ expected_token.attrSet("class", "myst-block")
+ assert tokens == [expected_token]
+
+
+def test_comment_token():
+ md = MarkdownIt("commonmark").use(myst_block_plugin)
+ tokens = md.parse("\n\n% abc \n%def")
+ expected_token = Token(
+ type="myst_line_comment",
+ tag="",
+ nesting=0,
+ map=[2, 4],
+ level=0,
+ children=None,
+ content=" abc\ndef",
+ markup="%",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ )
+ expected_token.attrSet("class", "myst-line-comment")
+ assert tokens == [expected_token]
diff --git a/tests/test_myst_role.py b/tests/test_myst_role.py
new file mode 100644
index 0000000..f70e3f8
--- /dev/null
+++ b/tests/test_myst_role.py
@@ -0,0 +1,89 @@
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.token import Token
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.myst_role import myst_role_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "myst_role.md")
+
+
+def test_basic():
+ md = MarkdownIt().use(myst_role_plugin)
+ src = "{abc}``` a ```"
+ tokens = md.parse(src)
+ print(tokens)
+ assert tokens == [
+ Token(
+ type="paragraph_open",
+ tag="p",
+ nesting=1,
+ attrs=None,
+ map=[0, 1],
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ ),
+ Token(
+ type="inline",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=[0, 1],
+ level=1,
+ children=[
+ Token(
+ type="myst_role",
+ tag="",
+ nesting=0,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content=" a ",
+ markup="",
+ info="",
+ meta={"name": "abc"},
+ block=False,
+ hidden=False,
+ )
+ ],
+ content="{abc}``` a ```",
+ markup="",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ ),
+ Token(
+ type="paragraph_close",
+ tag="p",
+ nesting=-1,
+ attrs=None,
+ map=None,
+ level=0,
+ children=None,
+ content="",
+ markup="",
+ info="",
+ meta={},
+ block=True,
+ hidden=False,
+ ),
+ ]
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(myst_role_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_substitution.py b/tests/test_substitution.py
new file mode 100644
index 0000000..706c1e2
--- /dev/null
+++ b/tests/test_substitution.py
@@ -0,0 +1,33 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+# from markdown_it.token import Token
+from mdit_py_plugins.substitution import substitution_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "substitution.md")
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").enable("table").use(substitution_plugin)
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
+
+
+def test_tokens(data_regression):
+ md = MarkdownIt().use(substitution_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ {{ block }}
+
+ a {{ inline }} b
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
diff --git a/tests/test_substitution/test_tokens.yml b/tests/test_substitution/test_tokens.yml
new file mode 100644
index 0000000..a3179d2
--- /dev/null
+++ b/tests/test_substitution/test_tokens.yml
@@ -0,0 +1,105 @@
+- attrs:
+ - - class
+ - substitution
+ - - text
+ - block
+ block: true
+ children: null
+ content: block
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 0
+ - 1
+ markup: '{}'
+ meta: {}
+ nesting: 0
+ tag: div
+ type: substitution_block
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 2
+ - 3
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: 'a '
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ - attrs:
+ - - class
+ - substitution
+ - - text
+ - inline
+ block: false
+ children: null
+ content: inline
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '{}'
+ meta: {}
+ nesting: 0
+ tag: span
+ type: substitution_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' b'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: a {{ inline }} b
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 2
+ - 3
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
diff --git a/tests/test_tasklists.py b/tests/test_tasklists.py
new file mode 100644
index 0000000..427c336
--- /dev/null
+++ b/tests/test_tasklists.py
@@ -0,0 +1,34 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.tasklists import tasklists_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "tasklists.md")
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(tasklists_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ * [ ] Task incomplete
+ * [x] Task complete
+ * [ ] Indented task incomplete
+ * [x] Indented task complete
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(tasklists_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_tasklists/test_plugin_parse.yml b/tests/test_tasklists/test_plugin_parse.yml
new file mode 100644
index 0000000..bc0d630
--- /dev/null
+++ b/tests/test_tasklists/test_plugin_parse.yml
@@ -0,0 +1,458 @@
+- attrs:
+ - - class
+ - contains-task-list
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 0
+ - 4
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: ul
+ type: bullet_list_open
+- attrs:
+ - - class
+ - task-list-item
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 0
+ - 1
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: li
+ type: list_item_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: <input class="task-list-item-checkbox" disabled="disabled" type="checkbox">
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: html_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' Task incomplete'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: ' Task incomplete'
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 0
+ - 1
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: li
+ type: list_item_close
+- attrs:
+ - - class
+ - task-list-item
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 1
+ - 4
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: li
+ type: list_item_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: <input class="task-list-item-checkbox" checked="checked" disabled="disabled"
+ type="checkbox">
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: html_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' Task complete'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: ' Task complete'
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 1
+ - 2
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs:
+ - - class
+ - contains-task-list
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 2
+ map:
+ - 2
+ - 4
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: ul
+ type: bullet_list_open
+- attrs:
+ - - class
+ - task-list-item
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 2
+ - 3
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: li
+ type: list_item_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 4
+ map:
+ - 2
+ - 3
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: <input class="task-list-item-checkbox" disabled="disabled" type="checkbox">
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: html_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' Indented task incomplete'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: ' Indented task incomplete'
+ hidden: false
+ info: ''
+ level: 5
+ map:
+ - 2
+ - 3
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 4
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 3
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: li
+ type: list_item_close
+- attrs:
+ - - class
+ - task-list-item
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 3
+ - 4
+ markup: '*'
+ meta: {}
+ nesting: 1
+ tag: li
+ type: list_item_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 4
+ map:
+ - 3
+ - 4
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: <input class="task-list-item-checkbox" checked="checked" disabled="disabled"
+ type="checkbox">
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: html_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' Indented task complete'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: ' Indented task complete'
+ hidden: false
+ info: ''
+ level: 5
+ map:
+ - 3
+ - 4
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 4
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 3
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: li
+ type: list_item_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 2
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: ul
+ type: bullet_list_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: li
+ type: list_item_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '*'
+ meta: {}
+ nesting: -1
+ tag: ul
+ type: bullet_list_close
diff --git a/tests/test_texmath.py b/tests/test_texmath.py
new file mode 100644
index 0000000..80bf67b
--- /dev/null
+++ b/tests/test_texmath.py
@@ -0,0 +1,105 @@
+from pathlib import Path
+from textwrap import dedent
+
+from markdown_it import MarkdownIt
+from markdown_it.rules_block import StateBlock
+from markdown_it.rules_inline import StateInline
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.texmath import index as main
+from mdit_py_plugins.texmath import texmath_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures")
+
+
+def test_inline_func():
+
+ inline_func = main.make_inline_func(main.rules["dollars"]["inline"][0])
+
+ md = MarkdownIt()
+ src = r"$a=1$ $b=2$"
+ tokens = []
+ state = StateInline(src, md, {}, tokens)
+ inline_func(state, False)
+ assert tokens[0].as_dict() == {
+ "type": "math_inline",
+ "tag": "math",
+ "nesting": 0,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "a=1",
+ "markup": "$",
+ "info": "",
+ "meta": {},
+ "block": False,
+ "hidden": False,
+ }
+ assert state.pos == 5
+
+
+def test_block_func():
+ block_func = main.make_block_func(main.rules["dollars"]["block"][0])
+ md = MarkdownIt()
+ src = r"$$\na=1\n\nc\nb=2$$ (abc)"
+ tokens = []
+ state = StateBlock(src, md, {}, tokens)
+ block_func(state, 0, 10, False)
+ assert tokens[0].as_dict() == {
+ "type": "math_block_eqno",
+ "tag": "math",
+ "nesting": 0,
+ "attrs": None,
+ "map": None,
+ "level": 0,
+ "children": None,
+ "content": "\\na=1\\n\\nc\\nb=2",
+ "markup": "$$",
+ "info": "abc",
+ "meta": {},
+ "block": True,
+ "hidden": False,
+ }
+
+
+def test_plugin_parse(data_regression):
+ md = MarkdownIt().use(texmath_plugin)
+ tokens = md.parse(
+ dedent(
+ """\
+ $$
+ a=1
+ b=2
+ $$ (abc)
+
+ - ab $c=1$ d
+ """
+ )
+ )
+ data_regression.check([t.as_dict() for t in tokens])
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected",
+ read_fixture_file(FIXTURE_PATH.joinpath("texmath_dollar.md")),
+)
+def test_dollar_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(texmath_plugin)
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
+
+
+@pytest.mark.parametrize(
+ "line,title,input,expected",
+ read_fixture_file(FIXTURE_PATH.joinpath("texmath_bracket.md")),
+)
+def test_bracket_fixtures(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(texmath_plugin, delimiters="brackets")
+ md.options["xhtmlOut"] = False
+ text = md.render(input)
+ print(text)
+ assert text.rstrip() == expected.rstrip()
diff --git a/tests/test_texmath/test_plugin_parse.yml b/tests/test_texmath/test_plugin_parse.yml
new file mode 100644
index 0000000..eac4e09
--- /dev/null
+++ b/tests/test_texmath/test_plugin_parse.yml
@@ -0,0 +1,157 @@
+- attrs: null
+ block: true
+ children: null
+ content: '
+
+ a=1
+
+ b=2
+
+ '
+ hidden: false
+ info: abc
+ level: 0
+ map: null
+ markup: $$
+ meta: {}
+ nesting: 0
+ tag: math
+ type: math_block_eqno
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map:
+ - 5
+ - 6
+ markup: '-'
+ meta: {}
+ nesting: 1
+ tag: ul
+ type: bullet_list_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map:
+ - 5
+ - 6
+ markup: '-'
+ meta: {}
+ nesting: 1
+ tag: li
+ type: list_item_open
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 1
+ tag: p
+ type: paragraph_open
+- attrs: null
+ block: true
+ children:
+ - attrs: null
+ block: false
+ children: null
+ content: 'ab '
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ - attrs: null
+ block: false
+ children: null
+ content: c=1
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: $
+ meta: {}
+ nesting: 0
+ tag: math
+ type: math_inline
+ - attrs: null
+ block: false
+ children: null
+ content: ' d'
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: text
+ content: ab $c=1$ d
+ hidden: false
+ info: ''
+ level: 3
+ map:
+ - 5
+ - 6
+ markup: ''
+ meta: {}
+ nesting: 0
+ tag: ''
+ type: inline
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: true
+ info: ''
+ level: 2
+ map: null
+ markup: ''
+ meta: {}
+ nesting: -1
+ tag: p
+ type: paragraph_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 1
+ map: null
+ markup: '-'
+ meta: {}
+ nesting: -1
+ tag: li
+ type: list_item_close
+- attrs: null
+ block: true
+ children: null
+ content: ''
+ hidden: false
+ info: ''
+ level: 0
+ map: null
+ markup: '-'
+ meta: {}
+ nesting: -1
+ tag: ul
+ type: bullet_list_close
diff --git a/tests/test_wordcount.py b/tests/test_wordcount.py
new file mode 100644
index 0000000..d7629d9
--- /dev/null
+++ b/tests/test_wordcount.py
@@ -0,0 +1,23 @@
+import json
+from pathlib import Path
+
+from markdown_it import MarkdownIt
+from markdown_it.utils import read_fixture_file
+import pytest
+
+from mdit_py_plugins.wordcount import wordcount_plugin
+
+FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures", "wordcount.md")
+
+
+@pytest.mark.parametrize("line,title,input,expected", read_fixture_file(FIXTURE_PATH))
+def test_all(line, title, input, expected):
+ md = MarkdownIt("commonmark").use(wordcount_plugin, store_text="(text)" in title)
+ env = {}
+ md.render(input, env)
+ data = json.dumps(env["wordcount"], indent=2, sort_keys=True)
+ try:
+ assert data.strip() == expected.strip()
+ except AssertionError:
+ print(data)
+ raise