From 570a34eb6e8a0f91f3500f1242d61558abe20157 Mon Sep 17 00:00:00 2001 From: Abhishek Date: Wed, 11 Nov 2026 22:52:08 +0530 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20Render=20the=20task=20lis?= =?UTF-8?q?t=20checkbox=20after=20any=20GFM=20whitespace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #42 made a tab or form feed after [ ] / [x] count as a task list marker, but make_checkbox still only matched a literal space. The marker was stripped and an empty html_inline was inserted, so the checkbox vanished, and with label_after the leftover ' id="task-item-...">' text leaked into the page. --- mdit_py_plugins/tasklists/__init__.py | 6 ++++-- tests/fixtures/tasklists.md | 8 ++++---- tests/test_tasklists.py | 2 ++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/mdit_py_plugins/tasklists/__init__.py b/mdit_py_plugins/tasklists/__init__.py index 089bb5d..81a9bd4 100644 --- a/mdit_py_plugins/tasklists/__init__.py +++ b/mdit_py_plugins/tasklists/__init__.py @@ -108,12 +108,14 @@ def todoify(token: Token) -> None: def make_checkbox(token: Token) -> Token: checkbox = Token("html_inline", "", 0) disabled_attr = 'disabled="disabled"' if disable_checkboxes else "" - if token.content.startswith("[ ] "): + # starts_with_todo_markdown already matched "[ ]", "[x]" or "[X]" followed by + # any GFM whitespace, so only the character inside the brackets matters here + if token.content[1] == " ": checkbox.content = ( '' ) - elif token.content.startswith("[x] ") or token.content.startswith("[X] "): + else: checkbox.content = ( '' diff --git a/tests/fixtures/tasklists.md b/tests/fixtures/tasklists.md index dec0fef..9b209f2 100644 --- a/tests/fixtures/tasklists.md +++ b/tests/fixtures/tasklists.md @@ -114,8 +114,8 @@ Tab after task list item marker + [ ] item 2 . . @@ -125,7 +125,7 @@ Form feed after task list item marker + [ ] item 2 . . diff --git a/tests/test_tasklists.py b/tests/test_tasklists.py index 7a21218..54a30e0 100644 --- a/tests/test_tasklists.py +++ b/tests/test_tasklists.py @@ -45,6 +45,8 @@ def test_all(line, title, input, expected): ), pytest.param("- [x] a & b\n", " a & b", id="ampersand"), pytest.param("- [ ] plain task\n", " plain task", id="plain"), + pytest.param("- [ ]\tplain task\n", "\tplain task", id="tab-unchecked"), + pytest.param("- [x]\tplain task\n", "\tplain task", id="tab-checked"), ], ) def test_label_after_is_escaped(source, label):