mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(agents): use GitHub-compatible heading slugs
This commit is contained in:
1 parent
244b1e43ce
commit
98e6fd3983
6 files changed
+32
-11
No files matched your search
@@ -40,11 +40,12 @@ prefix or Markdown link for other ambiguous filenames that resemble code symbols
|
||||
Multi-part dotfiles are path candidates too. Link paths and fragments are decoded
|
||||
separately so encoded filename delimiters stay in the filename. Fenced and indented examples
|
||||
do not count as root guidance imports or satisfy the required Claude import.
|
||||
Heading anchors decode HTML character references in text. Explicit HTML anchors
|
||||
Heading anchors decode HTML character references in text and use `github-slugger`
|
||||
for GitHub-compatible character filtering and duplicate suffixes. Explicit HTML anchors
|
||||
use `parse5`, excluding comments, scripts, styles and template contents.
|
||||
Rendered HTML anchor hrefs and image sources use the same local-reference checks
|
||||
as Markdown links, including decoded attributes and fragment validation.
|
||||
The Nx test hash includes `marked` and `parse5` so dependency changes invalidate parser coverage.
|
||||
The Nx test hash includes `marked`, `parse5` and `github-slugger` so dependency changes invalidate parser coverage.
|
||||
It cannot prove semantic equivalence; review changed contracts as well.
|
||||
|
||||
## Protected Markdown edits
|
||||
|
||||
@@ -215,6 +215,7 @@
|
||||
"eslint-plugin-import": "2.32.0",
|
||||
"eslint-plugin-playwright": "^1.6.2",
|
||||
"express": "5.2.1",
|
||||
"github-slugger": "2.0.0",
|
||||
"globals": "15.9.0",
|
||||
"html-escaper": "3.0.3",
|
||||
"istanbul-lib-coverage": "3.2.2",
|
||||
|
||||
Generated
+3
@@ -404,6 +404,9 @@ importers:
|
||||
express:
|
||||
specifier: 5.2.1
|
||||
version: 5.2.1
|
||||
github-slugger:
|
||||
specifier: 2.0.0
|
||||
version: 2.0.0
|
||||
globals:
|
||||
specifier: 15.9.0
|
||||
version: 15.9.0
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import GithubSlugger from 'github-slugger';
|
||||
import { Marked, Tokenizer } from 'marked';
|
||||
import { parseFragment } from 'parse5';
|
||||
|
||||
@@ -83,18 +84,12 @@ export function guidanceProse(markdown) {
|
||||
}
|
||||
|
||||
export function guidanceAnchors(markdown) {
|
||||
const slugger = new GithubSlugger();
|
||||
const found = new Set();
|
||||
const html = [];
|
||||
markdownLexer.walkTokens(markdownLexer.lexer(markdown), (token) => {
|
||||
if (token.type === 'heading') {
|
||||
const slug = inlineText(token.tokens)
|
||||
.toLowerCase()
|
||||
.replace(/[^\p{L}\p{M}\p{N}_\-\s]/gu, '')
|
||||
.replace(/\s/gu, '-');
|
||||
let unique = slug;
|
||||
let suffix = 0;
|
||||
while (found.has(unique)) unique = `${slug}-${++suffix}`;
|
||||
found.add(unique);
|
||||
found.add(slugger.slug(inlineText(token.tokens)));
|
||||
}
|
||||
if (token.type === 'html') html.push(token.raw);
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"{projectRoot}/*.mjs",
|
||||
"{projectRoot}/project.json",
|
||||
{
|
||||
"externalDependencies": ["marked", "parse5"]
|
||||
"externalDependencies": ["marked", "parse5", "github-slugger"]
|
||||
}
|
||||
],
|
||||
"options": {
|
||||
|
||||
@@ -537,3 +537,24 @@ test('non-rendered HTML navigation is ignored', async (t) => {
|
||||
[]
|
||||
);
|
||||
});
|
||||
|
||||
test('GitHub heading slugs remove non-ASCII whitespace', async (t) => {
|
||||
for (const heading of ['A B', 'A\u00a0B', 'A\u2003B']) {
|
||||
assert.deepEqual(
|
||||
await diagnostics(t, {
|
||||
'AGENTS.md': '[Heading](docs/example.md#ab)',
|
||||
'docs/example.md': '# ' + heading,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
assert.match(
|
||||
(
|
||||
await diagnostics(t, {
|
||||
'AGENTS.md': '[Heading](docs/example.md#a-b)',
|
||||
'docs/example.md': '# ' + heading,
|
||||
})
|
||||
).join('\n'),
|
||||
/missing anchor/
|
||||
);
|
||||
}
|
||||
});
|
||||
Reference in new issue
Block a user