From af24bc246a6938ebcae7cf6ff677b194cf1af95c Mon Sep 17 00:00:00 2001 From: Oleh Prypin Date: Sat, 12 Dec 2020 01:25:35 +0100 Subject: [PATCH] fix: Fix footnotes appearing in all following objects Fixes #186 --- src/mkdocstrings/handlers/base.py | 21 +++++++++++++++- tests/fixtures/footnotes.py | 15 ++++++++++++ tests/test_extension.py | 40 ++++++++++++++++++++++++++----- 3 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 tests/fixtures/footnotes.py diff --git a/src/mkdocstrings/handlers/base.py b/src/mkdocstrings/handlers/base.py index 9728cad9..a6a89b2c 100644 --- a/src/mkdocstrings/handlers/base.py +++ b/src/mkdocstrings/handlers/base.py @@ -9,6 +9,7 @@ - `teardown`, that will teardown all the cached handlers, and then clear the cache. """ +import functools import importlib import re import textwrap @@ -124,6 +125,23 @@ def do_any(seq: Sequence, attribute: str = None) -> bool: return any(_[attribute] for _ in seq) +def do_convert_markdown(md: Markdown, text: str) -> Markup: + """ + Render Markdown text; for use inside templates. + + Arguments: + md: A `markdown.Markdown` instance. + text: The text to convert. + + Returns: + An HTML string. + """ + try: + return Markup(md.convert(text)) + finally: + md.reset() + + class BaseRenderer(ABC): """ The base renderer class. @@ -198,7 +216,8 @@ def update_env(self, md: Markdown, config: dict) -> None: """ # Re-instantiate md: see https://github.com/tomchristie/mkautodoc/issues/14 md = Markdown(extensions=config["mdx"], extension_configs=config["mdx_configs"]) - self.env.filters["convert_markdown"] = lambda text: Markup(md.convert(text)) + + self.env.filters["convert_markdown"] = functools.partial(do_convert_markdown, md) class BaseCollector(ABC): diff --git a/tests/fixtures/footnotes.py b/tests/fixtures/footnotes.py new file mode 100644 index 00000000..ff1786ef --- /dev/null +++ b/tests/fixtures/footnotes.py @@ -0,0 +1,15 @@ +def func_a(): + """func_a[^1]. + + [^1]: Footnote\x20A + """ + +def func_b(): + """func_b[^x]. + + [^x]: Footnote\x20B + """ + +def func_c(): + """func_c. + """ diff --git a/tests/test_extension.py b/tests/test_extension.py index 01c56b45..86b01397 100644 --- a/tests/test_extension.py +++ b/tests/test_extension.py @@ -1,4 +1,6 @@ """Tests for the extension module.""" +from textwrap import dedent + from markdown import Markdown from mkdocstrings.extension import MkdocstringsExtension @@ -14,18 +16,44 @@ def test_render_html_escaped_sequences(): """Assert HTML-escaped sequences are correctly parsed as XML.""" - config = _DEFAULT_CONFIG - md = Markdown(extensions=[MkdocstringsExtension(config, Handlers(config))]) + config = dict(_DEFAULT_CONFIG) + config["mdx"].append(MkdocstringsExtension(config, Handlers(config))) + md = Markdown(extensions=config["mdx"]) + md.convert("::: tests.fixtures.html_escaped_sequences") +def test_multiple_footnotes(): + """Assert footnotes don't get added to subsequent docstrings.""" + config = dict(_DEFAULT_CONFIG, mdx=["footnotes"]) + config["mdx"].append(MkdocstringsExtension(config, Handlers(config))) + md = Markdown(extensions=config["mdx"]) + + output = md.convert( + dedent( + """ + Top.[^aaa] + + ::: tests.fixtures.footnotes.func_a + + ::: tests.fixtures.footnotes.func_b + + ::: tests.fixtures.footnotes.func_c + + [^aaa]: Top footnote + """ + ) + ) + assert output.count("Footnote A") == 1 + assert output.count("Footnote B") == 1 + assert output.count("Top footnote") == 1 + + def test_reference_inside_autodoc(): """Assert cross-reference Markdown extension works correctly.""" config = dict(_DEFAULT_CONFIG) - ext = MkdocstringsExtension(config, Handlers(config)) - config["mdx"].append(ext) - - md = Markdown(extensions=[ext]) + config["mdx"].append(MkdocstringsExtension(config, Handlers(config))) + md = Markdown(extensions=config["mdx"]) output = md.convert("::: tests.fixtures.cross_reference") snippet = 'Link to something.Else.'