mirror of
https://github.com/affaan-m/ECC.git
synced 2026-11-07 08:35:54 +00:00
fix(docs-governance): read a comment that starts a list item or a block quote line as an HTML block
Only indentation counted as the start of a block, so '- <!--' was inline HTML, and a blank line before its closer turned it into text. Its hidden links were then reported. Block quote and list markers before the opener now count too, as in CommonMark. A comment after text in a list item stays inline.
This commit is contained in:
5 files changed
+49
-26
No files matched your search
@@ -19,6 +19,8 @@ REFERENCE_USAGE_RE = re.compile(
|
||||
r"(?<![\\])(?:\\\\)*\[(?P<text>[^\]\n]+)\](?:\[(?P<label>[^\]\n]*)\])?"
|
||||
)
|
||||
BLANK_LINE_RE = re.compile(r"\n[ \t]*\r?\n")
|
||||
# -- what may come before a block on its line: indentation and block quote or list markers --
|
||||
CONTAINER_PREFIX_RE = re.compile(r"(?:[ \t]*(?:>|[-+*][ \t]|\d{1,9}[.)][ \t]))*[ \t]*")
|
||||
LINK_TITLE_RE = re.compile(
|
||||
r'\s+(?:"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'|\([^()]*\))\s*$'
|
||||
)
|
||||
@@ -72,15 +74,18 @@ def _is_escaped(text: str, index: int) -> bool:
|
||||
def _html_comment_end(text: str, start: int, closing: int, blank: int) -> int:
|
||||
"""Where the comment that opens at `start` and closes at `closing` ends, or -1 if it is text.
|
||||
|
||||
One that starts a line, after at most three spaces, opens an HTML block. The block may span
|
||||
blank lines and takes the rest of the line that holds its closer. One inside a line is inline
|
||||
HTML, which cannot outlast its paragraph, so when the first blank line after it, at `blank`,
|
||||
comes before its closer, it is text.
|
||||
One that starts a block, after nothing but indentation and block quote or list markers on
|
||||
its line (as in `- <!--`), opens an HTML block. The block may span blank lines and takes the
|
||||
rest of the line that holds its closer. One after text on its line is inline HTML, which
|
||||
cannot outlast its paragraph, so when the first blank line after it, at `blank`, comes before
|
||||
its closer, it is text.
|
||||
"""
|
||||
indent = 0
|
||||
while indent < 4 and start - indent > 0 and text[start - indent - 1] == " ":
|
||||
indent += 1
|
||||
if indent < 4 and (start - indent == 0 or text[start - indent - 1] == "\n"):
|
||||
# -- only the 64 characters before the opener are read, so a long line stays cheap --
|
||||
window = max(0, start - 64)
|
||||
line_start = text.rfind("\n", window, start) + 1
|
||||
if (line_start or not window) and CONTAINER_PREFIX_RE.fullmatch(
|
||||
text, line_start, start
|
||||
):
|
||||
newline = text.find("\n", closing + 3)
|
||||
return len(text) if newline == -1 else newline
|
||||
return -1 if blank < closing else closing + 3
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"id": "hand-seeded",
|
||||
"source": "manual-curation-pending-regeneration"
|
||||
},
|
||||
"registryDigest": "05f9875a0e4eaef5502902595e48b201ed8d83df7dec8587d1cfebaf08efa132",
|
||||
"registryDigest": "e6f889b5f158501ed2a6b7dc99f67dd7baa29127b0f75d77bccb59cfab94a676",
|
||||
"schemaVersion": 1,
|
||||
"triggers": {
|
||||
"skill:agent-runtime-gateway-smoke-test": [
|
||||
|
||||
@@ -19,6 +19,8 @@ REFERENCE_USAGE_RE = re.compile(
|
||||
r"(?<![\\])(?:\\\\)*\[(?P<text>[^\]\n]+)\](?:\[(?P<label>[^\]\n]*)\])?"
|
||||
)
|
||||
BLANK_LINE_RE = re.compile(r"\n[ \t]*\r?\n")
|
||||
# -- what may come before a block on its line: indentation and block quote or list markers --
|
||||
CONTAINER_PREFIX_RE = re.compile(r"(?:[ \t]*(?:>|[-+*][ \t]|\d{1,9}[.)][ \t]))*[ \t]*")
|
||||
LINK_TITLE_RE = re.compile(
|
||||
r'\s+(?:"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'|\([^()]*\))\s*$'
|
||||
)
|
||||
@@ -72,15 +74,18 @@ def _is_escaped(text: str, index: int) -> bool:
|
||||
def _html_comment_end(text: str, start: int, closing: int, blank: int) -> int:
|
||||
"""Where the comment that opens at `start` and closes at `closing` ends, or -1 if it is text.
|
||||
|
||||
One that starts a line, after at most three spaces, opens an HTML block. The block may span
|
||||
blank lines and takes the rest of the line that holds its closer. One inside a line is inline
|
||||
HTML, which cannot outlast its paragraph, so when the first blank line after it, at `blank`,
|
||||
comes before its closer, it is text.
|
||||
One that starts a block, after nothing but indentation and block quote or list markers on
|
||||
its line (as in `- <!--`), opens an HTML block. The block may span blank lines and takes the
|
||||
rest of the line that holds its closer. One after text on its line is inline HTML, which
|
||||
cannot outlast its paragraph, so when the first blank line after it, at `blank`, comes before
|
||||
its closer, it is text.
|
||||
"""
|
||||
indent = 0
|
||||
while indent < 4 and start - indent > 0 and text[start - indent - 1] == " ":
|
||||
indent += 1
|
||||
if indent < 4 and (start - indent == 0 or text[start - indent - 1] == "\n"):
|
||||
# -- only the 64 characters before the opener are read, so a long line stays cheap --
|
||||
window = max(0, start - 64)
|
||||
line_start = text.rfind("\n", window, start) + 1
|
||||
if (line_start or not window) and CONTAINER_PREFIX_RE.fullmatch(
|
||||
text, line_start, start
|
||||
):
|
||||
newline = text.find("\n", closing + 3)
|
||||
return len(text) if newline == -1 else newline
|
||||
return -1 if blank < closing else closing + 3
|
||||
|
||||
@@ -19,6 +19,8 @@ REFERENCE_USAGE_RE = re.compile(
|
||||
r"(?<![\\])(?:\\\\)*\[(?P<text>[^\]\n]+)\](?:\[(?P<label>[^\]\n]*)\])?"
|
||||
)
|
||||
BLANK_LINE_RE = re.compile(r"\n[ \t]*\r?\n")
|
||||
# -- what may come before a block on its line: indentation and block quote or list markers --
|
||||
CONTAINER_PREFIX_RE = re.compile(r"(?:[ \t]*(?:>|[-+*][ \t]|\d{1,9}[.)][ \t]))*[ \t]*")
|
||||
LINK_TITLE_RE = re.compile(
|
||||
r'\s+(?:"(?:\\.|[^"\\])*"|\'(?:\\.|[^\'\\])*\'|\([^()]*\))\s*$'
|
||||
)
|
||||
@@ -72,15 +74,18 @@ def _is_escaped(text: str, index: int) -> bool:
|
||||
def _html_comment_end(text: str, start: int, closing: int, blank: int) -> int:
|
||||
"""Where the comment that opens at `start` and closes at `closing` ends, or -1 if it is text.
|
||||
|
||||
One that starts a line, after at most three spaces, opens an HTML block. The block may span
|
||||
blank lines and takes the rest of the line that holds its closer. One inside a line is inline
|
||||
HTML, which cannot outlast its paragraph, so when the first blank line after it, at `blank`,
|
||||
comes before its closer, it is text.
|
||||
One that starts a block, after nothing but indentation and block quote or list markers on
|
||||
its line (as in `- <!--`), opens an HTML block. The block may span blank lines and takes the
|
||||
rest of the line that holds its closer. One after text on its line is inline HTML, which
|
||||
cannot outlast its paragraph, so when the first blank line after it, at `blank`, comes before
|
||||
its closer, it is text.
|
||||
"""
|
||||
indent = 0
|
||||
while indent < 4 and start - indent > 0 and text[start - indent - 1] == " ":
|
||||
indent += 1
|
||||
if indent < 4 and (start - indent == 0 or text[start - indent - 1] == "\n"):
|
||||
# -- only the 64 characters before the opener are read, so a long line stays cheap --
|
||||
window = max(0, start - 64)
|
||||
line_start = text.rfind("\n", window, start) + 1
|
||||
if (line_start or not window) and CONTAINER_PREFIX_RE.fullmatch(
|
||||
text, line_start, start
|
||||
):
|
||||
newline = text.find("\n", closing + 3)
|
||||
return len(text) if newline == -1 else newline
|
||||
return -1 if blank < closing else closing + 3
|
||||
|
||||
@@ -292,6 +292,11 @@ def test_artifact_scope_reads_html_comments_as_commonmark_does(project: Path) ->
|
||||
# -- the line that holds its closer --
|
||||
"<!--\n[hidden](missing-hidden.md)\n\n[hidden2](missing-hidden2.md)\n-->\n\n"
|
||||
"<!-- c --> [rest](missing-rest.md)\n\n"
|
||||
# -- so does one that starts a list item or a block quote line --
|
||||
"- <!--\n\n [listed](missing-listed.md)\n -->\n\n"
|
||||
"> <!-- c --> [quoted](missing-quoted.md)\n\n"
|
||||
# -- after text in a list item, a comment is inline again --
|
||||
"- item <!-- c\n\n [item-real](missing-item-real.md)\n -->\n\n"
|
||||
# -- a comment where a destination must begin does not make a definition --
|
||||
"[foo]: <!-- note --> missing-definition.md\n\n[foo]\n\n"
|
||||
"[bar]: <!-- only a comment -->\n\n[bar]\n\n"
|
||||
@@ -310,10 +315,13 @@ def test_artifact_scope_reads_html_comments_as_commonmark_does(project: Path) ->
|
||||
assert "Broken Markdown link: 'guide.md' -> 'missing-real.md'" in result.stdout
|
||||
assert "missing-hidden" not in result.stdout
|
||||
assert "missing-rest.md" not in result.stdout
|
||||
assert "missing-listed.md" not in result.stdout
|
||||
assert "missing-quoted.md" not in result.stdout
|
||||
assert "Broken Markdown link: 'guide.md' -> 'missing-item-real.md'" in result.stdout
|
||||
assert "missing-definition.md" not in result.stdout
|
||||
assert "Broken Markdown link: 'guide.md' -> 'missing-titled.md'" in result.stdout
|
||||
assert "missing-fenced.md" not in result.stdout
|
||||
assert result.stdout.count("Broken Markdown link") == 4, result.stdout
|
||||
assert result.stdout.count("Broken Markdown link") == 5, result.stdout
|
||||
|
||||
|
||||
def test_artifact_scope_ignores_title_with_escaped_quotes(project: Path) -> None:
|
||||
|
||||
Reference in new issue
Block a user