summaryrefslogtreecommitdiffstats
path: root/mdit_py_plugins/admon
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-29 04:29:52 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-29 04:29:52 +0000
commitfcb2f10732db61d216e2105c8154486f66b3e3ff (patch)
treeefda929db4b1543eecc583e3b7d9c0bad4cd86a6 /mdit_py_plugins/admon
parentInitial commit. (diff)
downloadmdit-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/LICENSE24
-rw-r--r--mdit_py_plugins/admon/__init__.py1
-rw-r--r--mdit_py_plugins/admon/index.py172
-rw-r--r--mdit_py_plugins/admon/port.yaml4
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