From 581fefe8dae5e94d3cbf5b5c44e20921a9ba9af0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 19 Jul 2026 18:29:29 +0000 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20myst=5Frole=20backslash-g?= =?UTF-8?q?uard=20misparse=20at=20inline=20start?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The guard checking the char before the role read state.src[state.pos - 1], which at pos 0 wraps to the last char of the inline source (negative indexing; the IndexError branch never fires), wrongly rejecting a role at the start of inline content whenever the content ends with a backslash. The guard is removed entirely: \{ is already consumed by the core escape rule before this rule runs (so the guard was dead for its intended case), and for an escaped backslash (\\{name}`x`) it wrongly suppressed a live role. Closes #62 --- CHANGELOG.md | 2 ++ mdit_py_plugins/myst_role/index.py | 11 +++-------- tests/fixtures/myst_role.md | 21 +++++++++++++++++++++ 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c8165b..797ba9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ **Requires markdown-it-py >= 4.1.0.** +- 🐛 FIX: `myst_role` no longer mis-rejects a role at the start of inline content when the content ends with a backslash, and `\\{name}`x`` (an escaped backslash before a role) now parses the role (#62) + ## 0.6.1 - 2026-05-13 - 🐛 FIX: Nested field lists incorrectly nesting inside parent containers (#139) diff --git a/mdit_py_plugins/myst_role/index.py b/mdit_py_plugins/myst_role/index.py index 97a5eb9..411c360 100644 --- a/mdit_py_plugins/myst_role/index.py +++ b/mdit_py_plugins/myst_role/index.py @@ -21,20 +21,15 @@ def myst_role_plugin(md: MarkdownIt) -> None: def myst_role(state: StateInline, silent: bool) -> bool: + # note ``\{`` escaping is handled by the core ``escape`` rule, + # which runs before this rule + # check name match = VALID_NAME_PATTERN.match(state.src[state.pos :]) if not match: return False name = match.group(1) - # check for starting backslash escape - try: - if state.src[state.pos - 1] == "\\": - # escaped (this could be improved in the case of edge case '\\{') - return False - except IndexError: - pass - # scan opening tick length start = pos = state.pos + match.end() try: diff --git a/tests/fixtures/myst_role.md b/tests/fixtures/myst_role.md index 4b2c248..1072d45 100644 --- a/tests/fixtures/myst_role.md +++ b/tests/fixtures/myst_role.md @@ -102,3 +102,24 @@ Escaped: .

{abc}xyz

. + +Role at start with trailing backslash (#62): +. +{foo}`ar`\ +. +

{foo}[ar]\

+. + +Escaped role backslash: +. +\{foo}`x` +. +

{foo}x

+. + +Escaped double backslash before role (#62): +. +\\{foo}`x` +. +

\{foo}[x]

+.