From 56ce8d7c1fc3b6bd97161c955f571ea49c436068 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sun, 18 Dec 2022 16:50:22 -0500 Subject: [PATCH 01/16] feat: start expanded set of markers --- mdit_py_plugins/admon/index.py | 24 +++++++++--------------- tox.ini | 2 +- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 8ebbe8f..77eb4f4 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -27,10 +27,8 @@ def validate(params: str) -> bool: return bool(tag) -MIN_MARKERS = 3 -MARKER_STR = "!" -MARKER_CHAR = ord(MARKER_STR) -MARKER_LEN = len(MARKER_STR) +MARKERS = ("!!!", "???", "???+", "..") +MARKER_CHARS = {_m[0] for _m in MARKERS} def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: @@ -38,18 +36,14 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> 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]): + if state.src[start] not in MARKER_CHARS: 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: + marker = state.src[startLine:maximum].split(" ")[0] + if marker not in MARKERS: return False - marker_pos = pos - ((pos - start) % MARKER_LEN) + + marker_pos = start + len(marker) params = state.src[marker_pos:maximum] markup = state.src[start:marker_pos] @@ -64,7 +58,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> old_line_max = state.lineMax old_indent = state.blkIndent - blk_start = pos + blk_start = marker_pos while blk_start < maximum and state.src[blk_start] == " ": blk_start += 1 @@ -128,7 +122,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> state.md.block.tokenize(state, startLine + 1, next_line) token = state.push("admonition_close", "div", -1) - token.markup = state.src[start:pos] + token.markup = state.src[start:marker_pos] token.block = True state.parentType = old_parent diff --git a/tox.ini b/tox.ini index 163d38b..57ca562 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ usedevelop = true [testenv:py{37,38,39,310}] extras = testing -commands = pytest {posargs} +commands = pytest {posargs} --failed-first -x [testenv:docs-{update,clean}] extras = rtd From 7ba7dcd2dfc492554d7a296e0029c26deab8f10d Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sun, 18 Dec 2022 17:02:41 -0500 Subject: [PATCH 02/16] fix: correctly calculate marker_pos --- mdit_py_plugins/admon/index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 77eb4f4..621cf7c 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -43,7 +43,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> if marker not in MARKERS: return False - marker_pos = start + len(marker) + marker_pos = len(marker) params = state.src[marker_pos:maximum] markup = state.src[start:marker_pos] From a21285dcb834f75bf311858b54f6187f6afbc8a1 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sun, 18 Dec 2022 17:15:00 -0500 Subject: [PATCH 03/16] fix: pass all tests when not separate by space --- mdit_py_plugins/admon/index.py | 15 ++++++++++----- tox.ini | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 621cf7c..fca72c2 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -1,6 +1,5 @@ # Process admonitions and pass to cb. -import math from typing import Callable, Optional, Tuple from markdown_it import MarkdownIt @@ -29,6 +28,7 @@ def validate(params: str) -> bool: MARKERS = ("!!!", "???", "???+", "..") MARKER_CHARS = {_m[0] for _m in MARKERS} +MAX_MARKER_LEN = max(len(_m) for _m in MARKERS) def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: @@ -38,14 +38,19 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> # Check out the first character quickly, which should filter out most of non-containers if state.src[start] not in MARKER_CHARS: return False + # Check out the rest of the marker string - marker = state.src[startLine:maximum].split(" ")[0] - if marker not in MARKERS: + marker_len = MAX_MARKER_LEN + while marker_len > 0: + marker_pos = start + marker_len + markup = state.src[start:marker_pos] + if markup in MARKERS: + break + marker_len -= 1 + else: return False - marker_pos = len(marker) params = state.src[marker_pos:maximum] - markup = state.src[start:marker_pos] if not validate(params): return False diff --git a/tox.ini b/tox.ini index 57ca562..163d38b 100644 --- a/tox.ini +++ b/tox.ini @@ -11,7 +11,7 @@ usedevelop = true [testenv:py{37,38,39,310}] extras = testing -commands = pytest {posargs} --failed-first -x +commands = pytest {posargs} [testenv:docs-{update,clean}] extras = rtd From 5132ec5949ebbf6c23c86b7b274ef39832a76b27 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sun, 18 Dec 2022 18:02:13 -0500 Subject: [PATCH 04/16] test: remove reST and add MkDocs tests --- mdit_py_plugins/admon/index.py | 4 ++-- tests/fixtures/admon.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index fca72c2..1c036bf 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -26,7 +26,7 @@ def validate(params: str) -> bool: return bool(tag) -MARKERS = ("!!!", "???", "???+", "..") +MARKERS = ("!!!", "???", "???+") MARKER_CHARS = {_m[0] for _m in MARKERS} MAX_MARKER_LEN = max(len(_m) for _m in MARKERS) @@ -127,7 +127,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> state.md.block.tokenize(state, startLine + 1, next_line) token = state.push("admonition_close", "div", -1) - token.markup = state.src[start:marker_pos] + token.markup = markup token.block = True state.parentType = old_parent diff --git a/tests/fixtures/admon.md b/tests/fixtures/admon.md index 587ae80..365af5e 100644 --- a/tests/fixtures/admon.md +++ b/tests/fixtures/admon.md @@ -267,3 +267,32 @@ Does not render

!!! content

. + + + +MKdocs Closed Collapsible Sections +. +??? note + content +. +
+

Note

+

content

+
+. + + +MKdocs Open Collapsible Sections +. +???+ note + content +. +
+

Note

+

content

+
+. + + + + From 34d74cb0548a730f6f2ca45447d7d5543cf6b2d2 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sat, 14 Jan 2023 11:58:37 -0500 Subject: [PATCH 05/16] fix: indent is always 4 for admonitions --- mdit_py_plugins/admon/index.py | 7 ++++++- tests/fixtures/admon.md | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 1c036bf..9983d76 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -26,6 +26,7 @@ def validate(params: str) -> bool: return bool(tag) +MARKER_LEN = 3 # Regardless of extra characters, block indent stays the same MARKERS = ("!!!", "???", "???+") MARKER_CHARS = {_m[0] for _m in MARKERS} MAX_MARKER_LEN = max(len(_m) for _m in MARKERS) @@ -40,11 +41,13 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> return False # Check out the rest of the marker string + marker = "" marker_len = MAX_MARKER_LEN while marker_len > 0: marker_pos = start + marker_len markup = state.src[start:marker_pos] if markup in MARKERS: + marker = markup break marker_len -= 1 else: @@ -68,7 +71,9 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> blk_start += 1 state.parentType = "admonition" - state.blkIndent += blk_start - start + # Correct block indentation when extra marker characters are present + marker_alignment_correction = MARKER_LEN - len(marker) + state.blkIndent += blk_start - start + marker_alignment_correction was_empty = False diff --git a/tests/fixtures/admon.md b/tests/fixtures/admon.md index 365af5e..eae8c9f 100644 --- a/tests/fixtures/admon.md +++ b/tests/fixtures/admon.md @@ -285,7 +285,7 @@ MKdocs Closed Collapsible Sections MKdocs Open Collapsible Sections . ???+ note - content + content .

Note

From 34d78a06ddb8c827ba93a4e1aa4a2c9ba628c980 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sat, 14 Jan 2023 12:05:11 -0500 Subject: [PATCH 06/16] refactor: trim trailing new line in fixture --- tests/fixtures/admon.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/fixtures/admon.md b/tests/fixtures/admon.md index eae8c9f..85414c2 100644 --- a/tests/fixtures/admon.md +++ b/tests/fixtures/admon.md @@ -292,7 +292,3 @@ MKdocs Open Collapsible Sections

content

. - - - - From 5ca80283dbe181027026c2e1f959ad36da029205 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sat, 18 Feb 2023 07:47:52 -0500 Subject: [PATCH 07/16] fix: keep incoming change --- mdit_py_plugins/admon/index.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index c8f3125..9983d76 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -37,7 +37,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> maximum = state.eMarks[startLine] # Check out the first character quickly, which should filter out most of non-containers - if ord(state.src[start]) != MARKER_CHAR: + if state.src[start] not in MARKER_CHARS: return False # Check out the rest of the marker string From 137cbbdc9e64e2f8af2e0e60160a2dcc50fa3ffe Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sun, 19 Feb 2023 20:11:32 -0500 Subject: [PATCH 08/16] test: add data_regression test --- tests/test_admon.py | 8 ++ tests/test_admon/test_plugin_parse.yml | 145 +++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 tests/test_admon/test_plugin_parse.yml diff --git a/tests/test_admon.py b/tests/test_admon.py index efd0ee8..ffae8b0 100644 --- a/tests/test_admon.py +++ b/tests/test_admon.py @@ -1,4 +1,5 @@ from pathlib import Path +from textwrap import dedent from markdown_it import MarkdownIt from markdown_it.utils import read_fixture_file @@ -19,3 +20,10 @@ def test_all(line, title, input, expected): text = md.render(input) print(text) assert text.rstrip() == expected.rstrip() + + +def test_plugin_parse(data_regression): + breakpoint() + md = MarkdownIt().use(admon_plugin) + tokens = md.parse(dedent("??? note\n content")) + data_regression.check([t.as_dict() for t in tokens]) diff --git a/tests/test_admon/test_plugin_parse.yml b/tests/test_admon/test_plugin_parse.yml new file mode 100644 index 0000000..1a386c0 --- /dev/null +++ b/tests/test_admon/test_plugin_parse.yml @@ -0,0 +1,145 @@ +- attrs: + - - class + - admonition note + block: true + children: null + content: Note + hidden: false + info: " note" + level: 0 + map: + - 0 + - 2 + markup: ??? + meta: + tag: note + nesting: 1 + tag: div + type: admonition_open +- attrs: + - - class + - admonition-title + block: true + children: null + content: "" + hidden: false + info: "" + level: 1 + map: + - 0 + - 1 + markup: ??? note + meta: {} + nesting: 1 + tag: p + type: admonition_title_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: Note + hidden: false + info: "" + level: 0 + map: null + markup: "" + meta: {} + nesting: 0 + tag: "" + type: text + content: Note + hidden: false + info: "" + level: 2 + map: + - 0 + - 1 + markup: "" + meta: {} + nesting: 0 + tag: "" + type: inline +- attrs: null + block: true + children: null + content: "" + hidden: false + info: "" + level: 1 + map: null + markup: ??? note + meta: {} + nesting: -1 + tag: p + type: admonition_title_close +- attrs: null + block: true + children: null + content: "" + hidden: false + info: "" + level: 1 + map: + - 1 + - 2 + markup: "" + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: content + hidden: false + info: "" + level: 0 + map: null + markup: "" + meta: {} + nesting: 0 + tag: "" + type: text + content: content + hidden: false + info: "" + level: 2 + map: + - 1 + - 2 + markup: "" + meta: {} + nesting: 0 + tag: "" + type: inline +- attrs: null + block: true + children: null + content: "" + hidden: false + info: "" + level: 1 + map: null + markup: "" + meta: {} + nesting: -1 + tag: p + type: paragraph_close +- attrs: null + block: true + children: null + content: "" + hidden: false + info: "" + level: 0 + map: null + markup: ??? + meta: {} + nesting: -1 + tag: div + type: admonition_close From 61e382f5618257a9547471581a82b002308ea9ac Mon Sep 17 00:00:00 2001 From: Kyle King Date: Sun, 19 Feb 2023 20:14:20 -0500 Subject: [PATCH 09/16] ci: unprettier yaml --- tests/test_admon.py | 1 - tests/test_admon/test_plugin_parse.yml | 118 ++++++++++++------------- 2 files changed, 59 insertions(+), 60 deletions(-) diff --git a/tests/test_admon.py b/tests/test_admon.py index ffae8b0..c962521 100644 --- a/tests/test_admon.py +++ b/tests/test_admon.py @@ -23,7 +23,6 @@ def test_all(line, title, input, expected): def test_plugin_parse(data_regression): - breakpoint() md = MarkdownIt().use(admon_plugin) tokens = md.parse(dedent("??? note\n content")) data_regression.check([t.as_dict() for t in tokens]) diff --git a/tests/test_admon/test_plugin_parse.yml b/tests/test_admon/test_plugin_parse.yml index 1a386c0..8c53a41 100644 --- a/tests/test_admon/test_plugin_parse.yml +++ b/tests/test_admon/test_plugin_parse.yml @@ -1,15 +1,15 @@ - attrs: - - - class - - admonition note + - - class + - admonition note block: true children: null content: Note hidden: false - info: " note" + info: ' note' level: 0 map: - - 0 - - 2 + - 0 + - 2 markup: ??? meta: tag: note @@ -17,17 +17,17 @@ tag: div type: admonition_open - attrs: - - - class - - admonition-title + - - class + - admonition-title block: true children: null - content: "" + content: '' hidden: false - info: "" + info: '' level: 1 map: - - 0 - - 1 + - 0 + - 1 markup: ??? note meta: {} nesting: 1 @@ -36,37 +36,37 @@ - attrs: null block: true children: - - attrs: null - block: false - children: null - content: Note - hidden: false - info: "" - level: 0 - map: null - markup: "" - meta: {} - nesting: 0 - tag: "" - type: text + - attrs: null + block: false + children: null + content: Note + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text content: Note hidden: false - info: "" + info: '' level: 2 map: - - 0 - - 1 - markup: "" + - 0 + - 1 + markup: '' meta: {} nesting: 0 - tag: "" + tag: '' type: inline - attrs: null block: true children: null - content: "" + content: '' hidden: false - info: "" + info: '' level: 1 map: null markup: ??? note @@ -77,14 +77,14 @@ - attrs: null block: true children: null - content: "" + content: '' hidden: false - info: "" + info: '' level: 1 map: - - 1 - - 2 - markup: "" + - 1 + - 2 + markup: '' meta: {} nesting: 1 tag: p @@ -92,40 +92,40 @@ - attrs: null block: true children: - - attrs: null - block: false - children: null - content: content - hidden: false - info: "" - level: 0 - map: null - markup: "" - meta: {} - nesting: 0 - tag: "" - type: text + - attrs: null + block: false + children: null + content: content + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text content: content hidden: false - info: "" + info: '' level: 2 map: - - 1 - - 2 - markup: "" + - 1 + - 2 + markup: '' meta: {} nesting: 0 - tag: "" + tag: '' type: inline - attrs: null block: true children: null - content: "" + content: '' hidden: false - info: "" + info: '' level: 1 map: null - markup: "" + markup: '' meta: {} nesting: -1 tag: p @@ -133,9 +133,9 @@ - attrs: null block: true children: null - content: "" + content: '' hidden: false - info: "" + info: '' level: 0 map: null markup: ??? From 0c8ed1f11cfa66897720d15f383cad281a36195d Mon Sep 17 00:00:00 2001 From: Kyle King Date: Thu, 23 Feb 2023 18:59:34 -0500 Subject: [PATCH 10/16] docs; expand admon docstring --- mdit_py_plugins/admon/index.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 9983d76..7e922e4 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -153,6 +153,14 @@ def admon_plugin(md: MarkdownIt, render: Optional[Callable] = None) -> None: !!! note *content* + `And mkdocs-style collapsible blocks + `_. + + .. code-block:: md + + ???+ note + *content* + Note, this is ported from `markdown-it-admon `_. From af05e78dfa1ee194a5d86f711c80fa0bed70cfb2 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Thu, 23 Feb 2023 19:07:31 -0500 Subject: [PATCH 11/16] test: generate data with prior version of the tool --- tests/test_admon.py | 10 ++- ...gin_parse.yml => test_plugin_parse_0_.yml} | 12 +-- tests/test_admon/test_plugin_parse_1_.yml | 82 +++++++++++++++++++ tests/test_admon/test_plugin_parse_2_.yml | 82 +++++++++++++++++++ 4 files changed, 178 insertions(+), 8 deletions(-) rename tests/test_admon/{test_plugin_parse.yml => test_plugin_parse_0_.yml} (93%) create mode 100644 tests/test_admon/test_plugin_parse_1_.yml create mode 100644 tests/test_admon/test_plugin_parse_2_.yml diff --git a/tests/test_admon.py b/tests/test_admon.py index c962521..8e246c4 100644 --- a/tests/test_admon.py +++ b/tests/test_admon.py @@ -22,7 +22,13 @@ def test_all(line, title, input, expected): assert text.rstrip() == expected.rstrip() -def test_plugin_parse(data_regression): +@pytest.mark.parametrize("text_idx", (0, 1, 2)) +def test_plugin_parse(data_regression, text_idx): + texts = [ + "!!! note\n content 1", + "??? note\n content 2", + "???+ note\n content 3", + ] md = MarkdownIt().use(admon_plugin) - tokens = md.parse(dedent("??? note\n content")) + tokens = md.parse(dedent(texts[text_idx])) data_regression.check([t.as_dict() for t in tokens]) diff --git a/tests/test_admon/test_plugin_parse.yml b/tests/test_admon/test_plugin_parse_0_.yml similarity index 93% rename from tests/test_admon/test_plugin_parse.yml rename to tests/test_admon/test_plugin_parse_0_.yml index 8c53a41..0b3677b 100644 --- a/tests/test_admon/test_plugin_parse.yml +++ b/tests/test_admon/test_plugin_parse_0_.yml @@ -10,7 +10,7 @@ map: - 0 - 2 - markup: ??? + markup: '!!!' meta: tag: note nesting: 1 @@ -28,7 +28,7 @@ map: - 0 - 1 - markup: ??? note + markup: '!!! note' meta: {} nesting: 1 tag: p @@ -69,7 +69,7 @@ info: '' level: 1 map: null - markup: ??? note + markup: '!!! note' meta: {} nesting: -1 tag: p @@ -95,7 +95,7 @@ - attrs: null block: false children: null - content: content + content: content 1 hidden: false info: '' level: 0 @@ -105,7 +105,7 @@ nesting: 0 tag: '' type: text - content: content + content: content 1 hidden: false info: '' level: 2 @@ -138,7 +138,7 @@ info: '' level: 0 map: null - markup: ??? + markup: "!!! note\n " meta: {} nesting: -1 tag: div diff --git a/tests/test_admon/test_plugin_parse_1_.yml b/tests/test_admon/test_plugin_parse_1_.yml new file mode 100644 index 0000000..71a1fc3 --- /dev/null +++ b/tests/test_admon/test_plugin_parse_1_.yml @@ -0,0 +1,82 @@ +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 0 + - 2 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: ??? note + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + - attrs: null + block: false + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: br + type: softbreak + - attrs: null + block: false + children: null + content: content 2 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: "??? note\n content 2" + hidden: false + info: '' + level: 1 + map: + - 0 + - 2 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: p + type: paragraph_close diff --git a/tests/test_admon/test_plugin_parse_2_.yml b/tests/test_admon/test_plugin_parse_2_.yml new file mode 100644 index 0000000..2ed4ba8 --- /dev/null +++ b/tests/test_admon/test_plugin_parse_2_.yml @@ -0,0 +1,82 @@ +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: + - 0 + - 2 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: + - attrs: null + block: false + children: null + content: ???+ note + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + - attrs: null + block: false + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: br + type: softbreak + - attrs: null + block: false + children: null + content: content 3 + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: 0 + tag: '' + type: text + content: "???+ note\n content 3" + hidden: false + info: '' + level: 1 + map: + - 0 + - 2 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: '' + meta: {} + nesting: -1 + tag: p + type: paragraph_close From 0258a7f6a1a76aac5418be435d7c821234bed455 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Thu, 23 Feb 2023 19:08:13 -0500 Subject: [PATCH 12/16] test: update regression data with the current implementation --- tests/test_admon/test_plugin_parse_0_.yml | 2 +- tests/test_admon/test_plugin_parse_1_.yml | 109 +++++++++++++++++----- tests/test_admon/test_plugin_parse_2_.yml | 109 +++++++++++++++++----- 3 files changed, 173 insertions(+), 47 deletions(-) diff --git a/tests/test_admon/test_plugin_parse_0_.yml b/tests/test_admon/test_plugin_parse_0_.yml index 0b3677b..8d75712 100644 --- a/tests/test_admon/test_plugin_parse_0_.yml +++ b/tests/test_admon/test_plugin_parse_0_.yml @@ -138,7 +138,7 @@ info: '' level: 0 map: null - markup: "!!! note\n " + markup: '!!!' meta: {} nesting: -1 tag: div diff --git a/tests/test_admon/test_plugin_parse_1_.yml b/tests/test_admon/test_plugin_parse_1_.yml index 71a1fc3..c1ff4c1 100644 --- a/tests/test_admon/test_plugin_parse_1_.yml +++ b/tests/test_admon/test_plugin_parse_1_.yml @@ -1,25 +1,45 @@ -- attrs: null +- attrs: + - - class + - admonition note block: true children: null - content: '' + content: Note hidden: false - info: '' + info: ' note' level: 0 map: - 0 - 2 - markup: '' + markup: ??? + meta: + tag: note + nesting: 1 + tag: div + type: admonition_open +- attrs: + - - class + - admonition-title + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 0 + - 1 + markup: ??? note meta: {} nesting: 1 tag: p - type: paragraph_open + type: admonition_title_open - attrs: null block: true children: - attrs: null block: false children: null - content: ??? note + content: Note hidden: false info: '' level: 0 @@ -29,19 +49,49 @@ nesting: 0 tag: '' type: text - - attrs: null - block: false - children: null - content: '' - hidden: false - info: '' - level: 0 - map: null - markup: '' - meta: {} - nesting: 0 - tag: br - type: softbreak + content: Note + hidden: false + info: '' + level: 2 + map: + - 0 + - 1 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: null + markup: ??? note + meta: {} + nesting: -1 + tag: p + type: admonition_title_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 1 + - 2 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: - attrs: null block: false children: null @@ -55,12 +105,12 @@ nesting: 0 tag: '' type: text - content: "??? note\n content 2" + content: content 2 hidden: false info: '' - level: 1 + level: 2 map: - - 0 + - 1 - 2 markup: '' meta: {} @@ -73,10 +123,23 @@ content: '' hidden: false info: '' - level: 0 + level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: ??? + meta: {} + nesting: -1 + tag: div + type: admonition_close diff --git a/tests/test_admon/test_plugin_parse_2_.yml b/tests/test_admon/test_plugin_parse_2_.yml index 2ed4ba8..32da38f 100644 --- a/tests/test_admon/test_plugin_parse_2_.yml +++ b/tests/test_admon/test_plugin_parse_2_.yml @@ -1,25 +1,45 @@ -- attrs: null +- attrs: + - - class + - admonition note block: true children: null - content: '' + content: Note hidden: false - info: '' + info: ' note' level: 0 map: - 0 - 2 - markup: '' + markup: ???+ + meta: + tag: note + nesting: 1 + tag: div + type: admonition_open +- attrs: + - - class + - admonition-title + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 0 + - 1 + markup: ???+ note meta: {} nesting: 1 tag: p - type: paragraph_open + type: admonition_title_open - attrs: null block: true children: - attrs: null block: false children: null - content: ???+ note + content: Note hidden: false info: '' level: 0 @@ -29,19 +49,49 @@ nesting: 0 tag: '' type: text - - attrs: null - block: false - children: null - content: '' - hidden: false - info: '' - level: 0 - map: null - markup: '' - meta: {} - nesting: 0 - tag: br - type: softbreak + content: Note + hidden: false + info: '' + level: 2 + map: + - 0 + - 1 + markup: '' + meta: {} + nesting: 0 + tag: '' + type: inline +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: null + markup: ???+ note + meta: {} + nesting: -1 + tag: p + type: admonition_title_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 1 + map: + - 1 + - 2 + markup: '' + meta: {} + nesting: 1 + tag: p + type: paragraph_open +- attrs: null + block: true + children: - attrs: null block: false children: null @@ -55,12 +105,12 @@ nesting: 0 tag: '' type: text - content: "???+ note\n content 3" + content: content 3 hidden: false info: '' - level: 1 + level: 2 map: - - 0 + - 1 - 2 markup: '' meta: {} @@ -73,10 +123,23 @@ content: '' hidden: false info: '' - level: 0 + level: 1 map: null markup: '' meta: {} nesting: -1 tag: p type: paragraph_close +- attrs: null + block: true + children: null + content: '' + hidden: false + info: '' + level: 0 + map: null + markup: ???+ + meta: {} + nesting: -1 + tag: div + type: admonition_close From f592d24ce39aac0c971a35572f7608bc46bae9a5 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Wed, 26 Apr 2023 19:32:35 -0400 Subject: [PATCH 13/16] refactor: remove redundant markup on close --- mdit_py_plugins/admon/index.py | 1 - tests/test_admon/test_plugin_parse_0_.yml | 2 +- tests/test_admon/test_plugin_parse_1_.yml | 2 +- tests/test_admon/test_plugin_parse_2_.yml | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 7e922e4..df9a63a 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -127,7 +127,6 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> token.children = [] token = state.push("admonition_title_close", "p", -1) - token.markup = title_markup state.md.block.tokenize(state, startLine + 1, next_line) diff --git a/tests/test_admon/test_plugin_parse_0_.yml b/tests/test_admon/test_plugin_parse_0_.yml index 8d75712..3272842 100644 --- a/tests/test_admon/test_plugin_parse_0_.yml +++ b/tests/test_admon/test_plugin_parse_0_.yml @@ -69,7 +69,7 @@ info: '' level: 1 map: null - markup: '!!! note' + markup: '' meta: {} nesting: -1 tag: p diff --git a/tests/test_admon/test_plugin_parse_1_.yml b/tests/test_admon/test_plugin_parse_1_.yml index c1ff4c1..8e95291 100644 --- a/tests/test_admon/test_plugin_parse_1_.yml +++ b/tests/test_admon/test_plugin_parse_1_.yml @@ -69,7 +69,7 @@ info: '' level: 1 map: null - markup: ??? note + markup: '' meta: {} nesting: -1 tag: p diff --git a/tests/test_admon/test_plugin_parse_2_.yml b/tests/test_admon/test_plugin_parse_2_.yml index 32da38f..2942719 100644 --- a/tests/test_admon/test_plugin_parse_2_.yml +++ b/tests/test_admon/test_plugin_parse_2_.yml @@ -69,7 +69,7 @@ info: '' level: 1 map: null - markup: ???+ note + markup: '' meta: {} nesting: -1 tag: p From d5ed5cbefa654a0d0e38047f067203e10116e355 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Wed, 26 Apr 2023 19:38:27 -0400 Subject: [PATCH 14/16] refactor: add better docstrings and make functions private --- mdit_py_plugins/admon/index.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index df9a63a..df6daa7 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -6,7 +6,8 @@ from markdown_it.rules_block import StateBlock -def get_tag(params: str) -> Tuple[str, str]: +def _get_tag(params: str) -> Tuple[str, str]: + """Separate the tag name from the admonition title.""" if not params.strip(): return "", "" @@ -21,7 +22,8 @@ def get_tag(params: str) -> Tuple[str, str]: return tag.lower(), title -def validate(params: str) -> bool: +def _validate(params: str) -> bool: + """Validate the presence of the tag name after the marker.""" tag = params.strip().split(" ", 1)[-1] or "" return bool(tag) @@ -55,7 +57,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> params = state.src[marker_pos:maximum] - if not validate(params): + if not _validate(params): return False # Since start is found, we can report success here in validation mode @@ -103,7 +105,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> # this will prevent lazy continuations from ever going past our end marker state.lineMax = next_line - tag, title = get_tag(params) + tag, title = _get_tag(params) token = state.push("admonition_open", "div", 1) token.markup = markup From 5251beb05db29cb9f11c8684ca7b51d1a96fd61d Mon Sep 17 00:00:00 2001 From: Kyle King Date: Wed, 26 Apr 2023 19:50:05 -0400 Subject: [PATCH 15/16] refactor: add the collapsible class name --- mdit_py_plugins/admon/index.py | 13 +++++++++++-- tests/fixtures/admon.md | 4 ++-- tests/test_admon/test_plugin_parse_1_.yml | 2 +- tests/test_admon/test_plugin_parse_2_.yml | 2 +- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index df6daa7..39c39ee 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -1,6 +1,6 @@ # Process admonitions and pass to cb. -from typing import Callable, Optional, Tuple +from typing import Callable, List, Optional, Tuple from markdown_it import MarkdownIt from markdown_it.rules_block import StateBlock @@ -34,6 +34,15 @@ def _validate(params: str) -> bool: MAX_MARKER_LEN = max(len(_m) for _m in MARKERS) +def _extra_classes(markup: str) -> List[str]: + """Return the list of additional classes based on the markup.""" + if markup.startswith("?"): + if markup.endswith("+"): + return ["collapsible-open"] + return ["collapsible-closed"] + return [] + + def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> bool: start = state.bMarks[startLine] + state.tShift[startLine] maximum = state.eMarks[startLine] @@ -110,7 +119,7 @@ def admonition(state: StateBlock, startLine: int, endLine: int, silent: bool) -> token = state.push("admonition_open", "div", 1) token.markup = markup token.block = True - token.attrs = {"class": f"admonition {tag}"} + token.attrs = {"class": " ".join(["admonition", tag, *_extra_classes(markup)])} token.meta = {"tag": tag} token.content = title token.info = params diff --git a/tests/fixtures/admon.md b/tests/fixtures/admon.md index 85414c2..6b7a253 100644 --- a/tests/fixtures/admon.md +++ b/tests/fixtures/admon.md @@ -275,7 +275,7 @@ MKdocs Closed Collapsible Sections ??? note content . -
+

Note

content

@@ -287,7 +287,7 @@ MKdocs Open Collapsible Sections ???+ note content . -
+

Note

content

diff --git a/tests/test_admon/test_plugin_parse_1_.yml b/tests/test_admon/test_plugin_parse_1_.yml index 8e95291..8e23110 100644 --- a/tests/test_admon/test_plugin_parse_1_.yml +++ b/tests/test_admon/test_plugin_parse_1_.yml @@ -1,6 +1,6 @@ - attrs: - - class - - admonition note + - admonition note collapsible-closed block: true children: null content: Note diff --git a/tests/test_admon/test_plugin_parse_2_.yml b/tests/test_admon/test_plugin_parse_2_.yml index 2942719..def9f43 100644 --- a/tests/test_admon/test_plugin_parse_2_.yml +++ b/tests/test_admon/test_plugin_parse_2_.yml @@ -1,6 +1,6 @@ - attrs: - - class - - admonition note + - admonition note collapsible-open block: true children: null content: Note From c5f278d2e2586bd152c84855125af839447e1109 Mon Sep 17 00:00:00 2001 From: Kyle King Date: Wed, 26 Apr 2023 20:03:43 -0400 Subject: [PATCH 16/16] refactor: add is-collapsible --- mdit_py_plugins/admon/index.py | 4 ++-- tests/fixtures/admon.md | 4 ++-- tests/test_admon/test_plugin_parse_1_.yml | 2 +- tests/test_admon/test_plugin_parse_2_.yml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mdit_py_plugins/admon/index.py b/mdit_py_plugins/admon/index.py index 39c39ee..fe58b82 100644 --- a/mdit_py_plugins/admon/index.py +++ b/mdit_py_plugins/admon/index.py @@ -38,8 +38,8 @@ def _extra_classes(markup: str) -> List[str]: """Return the list of additional classes based on the markup.""" if markup.startswith("?"): if markup.endswith("+"): - return ["collapsible-open"] - return ["collapsible-closed"] + return ["is-collapsible collapsible-open"] + return ["is-collapsible collapsible-closed"] return [] diff --git a/tests/fixtures/admon.md b/tests/fixtures/admon.md index 6b7a253..91057a5 100644 --- a/tests/fixtures/admon.md +++ b/tests/fixtures/admon.md @@ -275,7 +275,7 @@ MKdocs Closed Collapsible Sections ??? note content . -
+

Note

content

@@ -287,7 +287,7 @@ MKdocs Open Collapsible Sections ???+ note content . -
+

Note

content

diff --git a/tests/test_admon/test_plugin_parse_1_.yml b/tests/test_admon/test_plugin_parse_1_.yml index 8e23110..3a8c206 100644 --- a/tests/test_admon/test_plugin_parse_1_.yml +++ b/tests/test_admon/test_plugin_parse_1_.yml @@ -1,6 +1,6 @@ - attrs: - - class - - admonition note collapsible-closed + - admonition note is-collapsible collapsible-closed block: true children: null content: Note diff --git a/tests/test_admon/test_plugin_parse_2_.yml b/tests/test_admon/test_plugin_parse_2_.yml index def9f43..bfada8e 100644 --- a/tests/test_admon/test_plugin_parse_2_.yml +++ b/tests/test_admon/test_plugin_parse_2_.yml @@ -1,6 +1,6 @@ - attrs: - - class - - admonition note collapsible-open + - admonition note is-collapsible collapsible-open block: true children: null content: Note