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( """\

[1] [2] [3] [3:1]


  1. abc ↩︎

  2. a ↩︎

  3. xyz ↩︎ ↩︎

""" # 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("↩", "<-")