diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-29 04:29:52 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-29 04:29:52 +0000 |
commit | fcb2f10732db61d216e2105c8154486f66b3e3ff (patch) | |
tree | efda929db4b1543eecc583e3b7d9c0bad4cd86a6 /mdit_py_plugins/admon | |
parent | Initial commit. (diff) | |
download | mdit-py-plugins-fcb2f10732db61d216e2105c8154486f66b3e3ff.tar.xz mdit-py-plugins-fcb2f10732db61d216e2105c8154486f66b3e3ff.zip |
Adding upstream version 0.3.3.upstream/0.3.3upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mdit_py_plugins/admon')
-rw-r--r-- | mdit_py_plugins/admon/LICENSE | 24 | ||||
-rw-r--r-- | mdit_py_plugins/admon/__init__.py | 1 | ||||
-rw-r--r-- | mdit_py_plugins/admon/index.py | 172 | ||||
-rw-r--r-- | mdit_py_plugins/admon/port.yaml | 4 |
4 files changed, 201 insertions, 0 deletions
diff --git a/mdit_py_plugins/admon/LICENSE b/mdit_py_plugins/admon/LICENSE new file mode 100644 index 0000000..eb4033e --- /dev/null +++ b/mdit_py_plugins/admon/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin. +Copyright (c) 2018 jebbs +Copyright (c) 2021- commenthol + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/mdit_py_plugins/admon/__init__.py b/mdit_py_plugins/admon/__init__.py new file mode 100644 index 0000000..49b1c15 --- /dev/null +++ b/mdit_py_plugins/admon/__init__.py @@ -0,0 +1 @@ +from .index import admon_plugin # noqa: F401 diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py new file mode 100644 index 0000000..8ebbe8f --- /dev/null +++ b/mdit_py_plugins/admon/index.py @@ -0,0 +1,172 @@ +# Process admonitions and pass to cb. + +import math +from typing import Callable, Optional, Tuple + +from markdown_it import MarkdownIt +from markdown_it.rules_block import StateBlock + + +def get_tag(params: str) -> Tuple[str, str]: + if not params.strip(): + return "", "" + + tag, *_title = params.strip().split(" ") + joined = " ".join(_title) + + title = "" + if not joined: + title = tag.title() + elif joined != '""': + title = joined + return tag.lower(), title + + +def validate(params: str) -> bool: + tag = params.strip().split(" ", 1)[-1] or "" + return bool(tag) + + +MIN_MARKERS = 3 +MARKER_STR = "!" +MARKER_CHAR = ord(MARKER_STR) +MARKER_LEN = len(MARKER_STR) + + +def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: + start = state.bMarks[startLine] + state.tShift[startLine] + maximum = state.eMarks[startLine] + + # Check out the first character quickly, which should filter out most of non-containers + if MARKER_CHAR != ord(state.src[start]): + return False + + # Check out the rest of the marker string + pos = start + 1 + while pos <= maximum and MARKER_STR[(pos - start) % MARKER_LEN] == state.src[pos]: + pos += 1 + + marker_count = math.floor((pos - start) / MARKER_LEN) + if marker_count < MIN_MARKERS: + return False + marker_pos = pos - ((pos - start) % MARKER_LEN) + params = state.src[marker_pos:maximum] + markup = state.src[start:marker_pos] + + if not validate(params): + return False + + # Since start is found, we can report success here in validation mode + if silent: + return True + + old_parent = state.parentType + old_line_max = state.lineMax + old_indent = state.blkIndent + + blk_start = pos + while blk_start < maximum and state.src[blk_start] == " ": + blk_start += 1 + + state.parentType = "admonition" + state.blkIndent += blk_start - start + + was_empty = False + + # Search for the end of the block + next_line = startLine + while True: + next_line += 1 + if next_line >= endLine: + # unclosed block should be autoclosed by end of document. + # also block seems to be autoclosed by end of parent + break + pos = state.bMarks[next_line] + state.tShift[next_line] + maximum = state.eMarks[next_line] + is_empty = state.sCount[next_line] < state.blkIndent + + # two consecutive empty lines autoclose the block + if is_empty and was_empty: + break + was_empty = is_empty + + if pos < maximum and state.sCount[next_line] < state.blkIndent: + # non-empty line with negative indent should stop the block: + # - !!! + # test + break + + # this will prevent lazy continuations from ever going past our end marker + state.lineMax = next_line + + tag, title = get_tag(params) + + token = state.push("admonition_open", "div", 1) + token.markup = markup + token.block = True + token.attrs = {"class": f"admonition {tag}"} + token.meta = {"tag": tag} + token.content = title + token.info = params + token.map = [startLine, next_line] + + if title: + title_markup = f"{markup} {tag}" + token = state.push("admonition_title_open", "p", 1) + token.markup = title_markup + token.attrs = {"class": "admonition-title"} + token.map = [startLine, startLine + 1] + + token = state.push("inline", "", 0) + token.content = title + token.map = [startLine, startLine + 1] + token.children = [] + + token = state.push("admonition_title_close", "p", -1) + token.markup = title_markup + + state.md.block.tokenize(state, startLine + 1, next_line) + + token = state.push("admonition_close", "div", -1) + token.markup = state.src[start:pos] + token.block = True + + state.parentType = old_parent + state.lineMax = old_line_max + state.blkIndent = old_indent + state.line = next_line + + return True + + +def admon_plugin(md: MarkdownIt, render: Optional[Callable] = None) -> None: + """Plugin to use + `python-markdown style admonitions + <https://python-markdown.github.io/extensions/admonition>`_. + + .. code-block:: md + + !!! note + *content* + + Note, this is ported from + `markdown-it-admon + <https://github.com/commenthol/markdown-it-admon>`_. + """ + + def renderDefault(self, tokens, idx, _options, env): + return self.renderToken(tokens, idx, _options, env) + + render = render or renderDefault + + md.add_render_rule("admonition_open", render) + md.add_render_rule("admonition_close", render) + md.add_render_rule("admonition_title_open", render) + md.add_render_rule("admonition_title_close", render) + + md.block.ruler.before( + "fence", + "admonition", + admonition, + {"alt": ["paragraph", "reference", "blockquote", "list"]}, + ) diff --git a/mdit_py_plugins/admon/port.yaml b/mdit_py_plugins/admon/port.yaml new file mode 100644 index 0000000..d2835bc --- /dev/null +++ b/mdit_py_plugins/admon/port.yaml @@ -0,0 +1,4 @@ +- package: markdown-it-admon + commit: 9820ba89415c464a3cc18a780f222a0ceb3e18bd + date: Jul 3, 2021 + version: 1.0.0 |