diff --git a/CHANGELOG.md b/CHANGELOG.md index e4b18dc..350fbc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## Version 0.0.10 + +* Allow caption elements within indented blocks (e.g. admonitions). Can be disabled + with the `allow_indented_caption` option. + ## Version 0.0.9 * Fixed problem of leaking the figure caption element into the resulting HTML. diff --git a/demo/docs/index.md b/demo/docs/index.md index 89c9bca..602d0e8 100644 --- a/demo/docs/index.md +++ b/demo/docs/index.md @@ -17,6 +17,14 @@ and it goes on for multiple lines ![](assets/demo.png){width="200"} + +!!! warning + + Figure: This uses a Figure identifier as caption and + it goes on for multiple lines + + ![](assets/demo.png){width="200"} + ## Tables Table: Table caption diff --git a/demo/mkdocs.yml b/demo/mkdocs.yml index 591c7f6..de5a691 100644 --- a/demo/mkdocs.yml +++ b/demo/mkdocs.yml @@ -1,7 +1,13 @@ site_name: MkDocs Captions Demo +theme: + name: material + markdown_extensions: - pymdownx.extra: {} + - pymdownx.extra: {} + - admonition + - pymdownx.details + - pymdownx.superfences plugins: caption: diff --git a/docs/config.md b/docs/config.md index bb78dbb..7265503 100644 --- a/docs/config.md +++ b/docs/config.md @@ -18,6 +18,7 @@ plugins: reference_text: 'Table {index}' caption_prefix: 'Table {index}:' markdown_identifier: 'Table:' + allow_indented_caption: True figure: # (3)! enable: true start_index: 1 @@ -27,6 +28,7 @@ plugins: reference_text: 'Figure {index}' caption_prefix: 'Figure {index}:' markdown_identifier: 'Figure:' + allow_indented_caption: True custom: # (4)! enable: true start_index: 1 @@ -36,6 +38,7 @@ plugins: reference_text: '{Identifier} {index}' caption_prefix: '{Identifier} {index}:' markdown_identifier: '{Identifier}:' + allow_indented_caption: True ``` 1. list of additional identifiers (e.g. [`List`, `Example`]. These identifiers will be treated as @@ -68,6 +71,7 @@ The following table lists all available options. | reference_text | The text used for references to this element. Note, this only will be applied if the anchor does not specify its own link text | | caption_prefix | The prefix put before of the caption text | | markdown_identifier | The identifier that this plugin will search for in the markdown. (Note that every match of this identifier will be treated as a caption element. A false match will most likely result in an error) | +| allow_indented_caption | Flag if caption elements should also be parsed within indented blocks. By default this is enabled. | ## Overwriting the default configuration diff --git a/mkdocs.yml b/mkdocs.yml index cfc2736..b320fb8 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -82,3 +82,9 @@ plugins: min_length: 3 caption: additional_identifier: [List, Example] + figure: + allow_indented_caption: false + table: + allow_indented_caption: false + custom: + allow_indented_caption: false \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index cf16aaa..4007bfb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,7 +54,7 @@ dependencies = ["coverage[toml]>=6.5", "pytest", "lxml"] python = ["3.8", "3.9", "3.10", "3.11"] [tool.hatch.envs.test] -dependencies = ["coverage[toml]>=6.5", "pytest", "pymdown-extensions"] +dependencies = ["coverage[toml]>=6.5", "pytest", "pymdown-extensions", "mkdocs-material"] [tool.hatch.envs.test.scripts] test = "pytest {args:tests}" diff --git a/src/mkdocs_caption/config.py b/src/mkdocs_caption/config.py index 42d1349..965e77b 100644 --- a/src/mkdocs_caption/config.py +++ b/src/mkdocs_caption/config.py @@ -27,6 +27,7 @@ class IdentifierCaption(base.Config): reference_text = config_options.Type(str, default="{Identifier} {index}") caption_prefix = config_options.Type(str, default="{Identifier} {index}:") markdown_identifier = config_options.Type(str, default="{Identifier}:") + allow_indented_caption = config_options.Type(bool, default=True) @staticmethod def _format_string( diff --git a/src/mkdocs_caption/custom.py b/src/mkdocs_caption/custom.py index e616eed..f2b54d8 100644 --- a/src/mkdocs_caption/custom.py +++ b/src/mkdocs_caption/custom.py @@ -41,6 +41,7 @@ def preprocess_markdown( markdown, identifier=md_identifier, html_tag=CAPTION_TAG, + allow_indented_caption=config.allow_indented_caption, ) return markdown diff --git a/src/mkdocs_caption/helper.py b/src/mkdocs_caption/helper.py index ce4fc01..948433a 100644 --- a/src/mkdocs_caption/helper.py +++ b/src/mkdocs_caption/helper.py @@ -68,16 +68,23 @@ def _escape_md_caption(match: re.Match, *, target_tag: str) -> str: Returns: A string with the custom caption escaped using a custom HTML tag. """ - identifier = match.group(1).rstrip(":") - caption = match.group(2).replace("\n", " ") - options = _parse_extended_markdown(match.group(4)) + prefix = match.group(1) + identifier = match.group(2).rstrip(":") + caption = match.group(3).replace("\n", " ") + options = _parse_extended_markdown(match.group(5)) return str( - f'\n<{target_tag} identifier="{identifier}"' + f'\n{prefix}<{target_tag} identifier="{identifier}"' f"{options}>{caption}\n\n", ) -def wrap_md_captions(markdown: str, *, identifier: str, html_tag: str) -> str: +def wrap_md_captions( + markdown: str, + *, + identifier: str, + html_tag: str, + allow_indented_caption: bool, +) -> str: """Preprocess markdown to wrap custom captions. The custom captions are wrapped in a custom html @@ -87,12 +94,14 @@ def wrap_md_captions(markdown: str, *, identifier: str, html_tag: str) -> str: markdown: markdown string identifier: identifier to wrap html_tag: html tag to wrap the caption in + allow_indented_caption: Flag if indented captions are allowed Returns: markdown string with custom captions wrapped """ + prefix = r"([^\S\r\n]*?)" if allow_indented_caption else "^()" return re.sub( - rf"^({identifier}) (.*?)({{(.*?)}})?\n\n", + rf"{prefix}({identifier}) (.*?)({{(.*?)}})?\n\n", lambda match: _escape_md_caption(match, target_tag=html_tag), markdown, flags=re.MULTILINE | re.DOTALL, diff --git a/src/mkdocs_caption/image.py b/src/mkdocs_caption/image.py index 642ac96..bb08a5e 100644 --- a/src/mkdocs_caption/image.py +++ b/src/mkdocs_caption/image.py @@ -30,7 +30,12 @@ def preprocess_markdown(markdown: str, *, config: IdentifierCaption) -> str: if not config.enable: return markdown identifier = config.get_markdown_identifier("figure") - return wrap_md_captions(markdown, identifier=identifier, html_tag=IMG_CAPTION_TAG) + return wrap_md_captions( + markdown, + identifier=identifier, + html_tag=IMG_CAPTION_TAG, + allow_indented_caption=config.allow_indented_caption, + ) def wrap_image( diff --git a/src/mkdocs_caption/table.py b/src/mkdocs_caption/table.py index 9660916..3397794 100644 --- a/src/mkdocs_caption/table.py +++ b/src/mkdocs_caption/table.py @@ -35,7 +35,12 @@ def preprocess_markdown(markdown: str, *, config: IdentifierCaption) -> str: if not config.enable: return markdown identifier = config.get_markdown_identifier("table") - return wrap_md_captions(markdown, identifier=identifier, html_tag=TABLE_CAPTION_TAG) + return wrap_md_captions( + markdown, + identifier=identifier, + html_tag=TABLE_CAPTION_TAG, + allow_indented_caption=config.allow_indented_caption, + ) def _create_colgroups(coldef: str) -> TreeElement: diff --git a/tests/test_image.py b/tests/test_image.py index f9a1a42..64c7324 100644 --- a/tests/test_image.py +++ b/tests/test_image.py @@ -40,6 +40,23 @@ def test_preprocess_intended(): Figure: My Caption + hjkhjk + """ + result = image.preprocess_markdown(markdown, config=config) + assert ( + ' My Caption' in result + ) + + +def test_preprocess_intended_disabled(): + config = IdentifierCaption() + config.allow_indented_caption = False + markdown = """\ + This is a test + hkjbnk + + Figure: My Caption + hjkhjk """ assert image.preprocess_markdown(markdown, config=config) == markdown @@ -70,6 +87,22 @@ def test_preprocess_default_identifier(): assert 'My Caption' in result +def test_preprocess_default_identifier_indent(): + config = IdentifierCaption() + markdown = """\ +This is a test +hkjbnk + + Figure: My Caption + +hjkhjk + """ + result = image.preprocess_markdown(markdown, config=config) + assert ( + ' My Caption' in result + ) + + def test_preprocess_options_ok(): config = IdentifierCaption() markdown = """\ diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 22c06c1..d61c68a 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -1,6 +1,7 @@ """Test the plugin with a MkDocs demo site.""" import tempfile from pathlib import Path +from unittest.mock import MagicMock from mkdocs import config from mkdocs.commands import build @@ -19,4 +20,5 @@ def test_demo(caplog): if __name__ == "__main__": - test_demo() + log = MagicMock() + test_demo(log)