From 08305e26db3be7de0a91b5736c63e5a9cad776ab Mon Sep 17 00:00:00 2001 From: "Brian S. Stephan" Date: Mon, 18 Apr 2022 14:40:01 -0500 Subject: [PATCH] pydot: handle multiple dot images in one file --- incorporealcms/mdx/pydot.py | 13 +++++++----- tests/functional_markdown_tests.py | 11 ++++++++++ tests/instance/config.py | 4 ++++ tests/instance/pages/test-two-graphviz.md | 25 +++++++++++++++++++++++ 4 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 tests/instance/pages/test-two-graphviz.md diff --git a/incorporealcms/mdx/pydot.py b/incorporealcms/mdx/pydot.py index 3228b25..a995905 100644 --- a/incorporealcms/mdx/pydot.py +++ b/incorporealcms/mdx/pydot.py @@ -25,9 +25,12 @@ class InlinePydotPreprocessor(markdown.preprocessors.Preprocessor): def run(self, lines): """Match and generate diagrams from dot code blocks.""" text = '\n'.join(lines) - for match in self.BLOCK_RE.finditer(text): - filename = match.group(1) - dot_string = match.group(2) + out = text + for block_match in self.BLOCK_RE.finditer(text): + filename = block_match.group(1) + dot_string = block_match.group(2) + logger.debug("matched markdown block: %s", dot_string) + logger.debug("match start/end: %s/%s", block_match.start(), block_match.end()) # use pydot to turn the text into pydot graphs = pydot.graph_from_dot_data(dot_string) @@ -41,9 +44,9 @@ class InlinePydotPreprocessor(markdown.preprocessors.Preprocessor): inline_image = f'![{filename}]({data_path})' # replace the image in the output markdown - text = f'{text[:match.start()]}\n{inline_image}\n{text[match.end():]}' + out = out.replace(block_match.group(0), inline_image) - return text.split('\n') + return out.split('\n') def makeExtension(*args, **kwargs): diff --git a/tests/functional_markdown_tests.py b/tests/functional_markdown_tests.py index 386730f..79345b1 100644 --- a/tests/functional_markdown_tests.py +++ b/tests/functional_markdown_tests.py @@ -29,6 +29,17 @@ def test_graphviz_is_rendered(): assert b'data:image/png;base64' in response.data +def test_two_graphviz_are_rendered(): + """Test two images are rendered.""" + app = app_with_pydot() + client = app.test_client() + + response = client.get('/test-two-graphviz') + assert response.status_code == 200 + assert b'~~~pydot' not in response.data + assert b'data:image/png;base64' in response.data + + def test_invalid_graphviz_is_not_rendered(): """Check that invalid graphviz doesn't blow things up.""" app = app_with_pydot() diff --git a/tests/instance/config.py b/tests/instance/config.py index 4a0c0de..5a4d43a 100644 --- a/tests/instance/config.py +++ b/tests/instance/config.py @@ -15,6 +15,10 @@ LOGGING = { }, }, 'loggers': { + 'incorporealcms.mdx': { + 'level': 'DEBUG', + 'handlers': ['console'], + }, 'incorporealcms.pages': { 'level': 'DEBUG', 'handlers': ['console'], diff --git a/tests/instance/pages/test-two-graphviz.md b/tests/instance/pages/test-two-graphviz.md new file mode 100644 index 0000000..97f7c31 --- /dev/null +++ b/tests/instance/pages/test-two-graphviz.md @@ -0,0 +1,25 @@ +# test + +test + +~~~pydot:attack-plan +digraph G { + rankdir=LR + Earth + Mars + Earth -> Mars +} +~~~ + +more test + +~~~pydot:new-attack-plan +digraph H { + rankdir=LR + Venus + Mars + Venus -> Mars +} +~~~ + +done