Skip to content

Commit

Permalink
Allow caption elements within indented blocks (e.g. admonitions)
Browse files Browse the repository at this point in the history
This commit adds a new option `allow_indented_caption` to the config.
If enabled (default) caption elements are also parsed if they are
indented. This is necessary to allow captions within admonitions.
  • Loading branch information
tobiasah committed Nov 20, 2023
1 parent df85134 commit 94af93e
Show file tree
Hide file tree
Showing 13 changed files with 96 additions and 11 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
8 changes: 8 additions & 0 deletions demo/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion demo/mkdocs.yml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
4 changes: 4 additions & 0 deletions docs/config.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
Expand Down
1 change: 1 addition & 0 deletions src/mkdocs_caption/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 1 addition & 0 deletions src/mkdocs_caption/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def preprocess_markdown(
markdown,
identifier=md_identifier,
html_tag=CAPTION_TAG,
allow_indented_caption=config.allow_indented_caption,
)
return markdown

Expand Down
21 changes: 15 additions & 6 deletions src/mkdocs_caption/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}</{target_tag}>\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
Expand All @@ -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,
Expand Down
7 changes: 6 additions & 1 deletion src/mkdocs_caption/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
7 changes: 6 additions & 1 deletion src/mkdocs_caption/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
33 changes: 33 additions & 0 deletions tests/test_image.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,23 @@ def test_preprocess_intended():
Figure: My Caption
hjkhjk
"""
result = image.preprocess_markdown(markdown, config=config)
assert (
' <figure-caption identifier="Figure">My Caption</figure-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
Expand Down Expand Up @@ -70,6 +87,22 @@ def test_preprocess_default_identifier():
assert '<figure-caption identifier="Figure">My Caption</figure-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 (
' <figure-caption identifier="Figure">My Caption</figure-caption>' in result
)


def test_preprocess_options_ok():
config = IdentifierCaption()
markdown = """\
Expand Down
4 changes: 3 additions & 1 deletion tests/test_plugin.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -19,4 +20,5 @@ def test_demo(caplog):


if __name__ == "__main__":
test_demo()
log = MagicMock()
test_demo(log)

0 comments on commit 94af93e

Please sign in to comment.