|
1 | 1 | # Process admonitions and pass to cb.
|
| 2 | + |
2 | 3 | from __future__ import annotations
|
3 | 4 |
|
4 |
| -from typing import TYPE_CHECKING, Callable, Sequence |
| 5 | +from contextlib import suppress |
| 6 | +import re |
| 7 | +from typing import TYPE_CHECKING, Callable, List, Sequence, Tuple |
5 | 8 |
|
6 | 9 | from markdown_it import MarkdownIt
|
7 | 10 | from markdown_it.rules_block import StateBlock
|
|
14 | 17 | from markdown_it.utils import EnvType, OptionsDict
|
15 | 18 |
|
16 | 19 |
|
17 |
| -def _get_tag(params: str) -> tuple[str, str]: |
| 20 | +def _get_multiple_tags(params: str) -> Tuple[List[str], str]: |
| 21 | + """Check for multiple tags when the title is double quoted.""" |
| 22 | + re_tags = re.compile(r'^\s*(?P<tokens>[^"]+)\s+"(?P<title>.*)"\S*$') |
| 23 | + match = re_tags.match(params) |
| 24 | + if match: |
| 25 | + tags = match["tokens"].strip().split(" ") |
| 26 | + return [tag.lower() for tag in tags], match["title"] |
| 27 | + raise ValueError("No match found for parameters") |
| 28 | + |
| 29 | + |
| 30 | +def _get_tag(_params: str) -> Tuple[List[str], str]: |
18 | 31 | """Separate the tag name from the admonition title."""
|
19 |
| - if not params.strip(): |
20 |
| - return "", "" |
| 32 | + params = _params.strip() |
| 33 | + if not params: |
| 34 | + return [""], "" |
| 35 | + |
| 36 | + with suppress(ValueError): |
| 37 | + return _get_multiple_tags(params) |
21 | 38 |
|
22 |
| - tag, *_title = params.strip().split(" ") |
| 39 | + tag, *_title = params.split(" ") |
23 | 40 | joined = " ".join(_title)
|
24 | 41 |
|
25 | 42 | title = ""
|
26 | 43 | if not joined:
|
27 | 44 | title = tag.title()
|
28 |
| - elif joined != '""': |
| 45 | + elif joined != '""': # Specifically check for no title |
29 | 46 | title = joined
|
30 |
| - return tag.lower(), title |
| 47 | + return [tag.lower()], title |
31 | 48 |
|
32 | 49 |
|
33 | 50 | def _validate(params: str) -> bool:
|
@@ -125,12 +142,13 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) ->
|
125 | 142 | # this will prevent lazy continuations from ever going past our end marker
|
126 | 143 | state.lineMax = next_line
|
127 | 144 |
|
128 |
| - tag, title = _get_tag(params) |
| 145 | + tags, title = _get_tag(params) |
| 146 | + tag = tags[0] |
129 | 147 |
|
130 | 148 | token = state.push("admonition_open", "div", 1)
|
131 | 149 | token.markup = markup
|
132 | 150 | token.block = True
|
133 |
| - token.attrs = {"class": " ".join(["admonition", tag, *_extra_classes(markup)])} |
| 151 | + token.attrs = {"class": " ".join(["admonition", *tags, *_extra_classes(markup)])} |
134 | 152 | token.meta = {"tag": tag}
|
135 | 153 | token.content = title
|
136 | 154 | token.info = params
|
|
0 commit comments