Add MDS035 rule to flag renderer-specific TOC directives - #144
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #144 +/- ##
==========================================
+ Coverage 86.70% 86.76% +0.05%
==========================================
Files 95 96 +1
Lines 10387 10446 +59
==========================================
+ Hits 9006 9063 +57
- Misses 899 900 +1
- Partials 482 483 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Implements a new opt-in linting rule (MDS035: toc-directive) to detect renderer-specific TOC tokens that render as literal text under CommonMark/goldmark.
Changes:
- Added MDS035 rule implementation and unit tests to detect
[TOC],[[_TOC_]],[[toc]], and${toc}, with[TOC]suppressed when a matching link reference definition exists. - Added fixtures and documentation for MDS035 and updated rule indexes/background docs.
- Registered the new rule in the CLI and test import sets; updated integration fixture settings restoration behavior.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| plan/88_toc-directive-migration.md | Marks the TOC-directive migration plan as completed. |
| internal/rules/tocdirective/rule.go | Adds the MDS035 rule implementation. |
| internal/rules/tocdirective/rule_test.go | Adds unit tests for directive detection/suppression behavior. |
| internal/rules/index.md | Adds MDS035 to the rules index table. |
| internal/rules/MDS035-toc-directive/README.md | Documents the new rule, configuration, and examples. |
| internal/rules/MDS035-toc-directive/good/*.md | Adds “good” fixtures for non-diagnostics cases (code, link-ref suppression). |
| internal/rules/MDS035-toc-directive/bad/*.md | Adds “bad” fixtures for each directive variant. |
| internal/integration/rules_test.go | Changes fixture settings application to snapshot/restore rule state. |
| internal/engine/categories_test.go | Imports the new rule for category-related tests. |
| internal/config/config_test.go | Imports the new rule for config-related tests. |
| docs/background/markdown-linters.md | Adds a renderer portability section referencing MDS035. |
| cmd/mdsmith/main.go | Registers the new rule in the main binary imports. |
| PLAN.md | Updates plan catalog status for item 88. |
hasTOCLinkReference previously used goldmark.New(), which omits mdsmith's PIBlockParserPrioritized. Extract the parser construction in lint.NewFile into an exported lint.NewParser() so rules that need a secondary parse (here, to consult the link reference map for [TOC] suppression) stay consistent with the original lint parse instead of drifting from it. No behavior change on the current test corpus; defensive alignment for future parser additions. Addresses review feedback on PR #144.
|
🟢 Merge Queue — picked up This PR is in the queue and will be batched with other Next: No action needed — you'll get another comment when CI starts on the batch. View merge queue run. |
|
This PR could not be merged into the batch branch without conflicts with Next: Rebase onto or merge |
hasTOCLinkReference previously used goldmark.New(), which omits mdsmith's PIBlockParserPrioritized. Extract the parser construction in lint.NewFile into an exported lint.NewParser() so rules that need a secondary parse (here, to consult the link reference map for [TOC] suppression) stay consistent with the original lint parse instead of drifting from it. No behavior change on the current test corpus; defensive alignment for future parser additions. Addresses review feedback on PR #144.
2fb0f4c to
cdb2caf
Compare
|
🟢 Merge Queue — picked up This PR is in the queue and will be batched with other Next: No action needed — you'll get another comment when CI starts on the batch. View merge queue run. |
|
This PR could not be merged into the batch branch without conflicts with Next: Rebase onto or merge |
Add a new opt-in rule that flags renderer-specific table-of-contents
directives which render as literal text on CommonMark and goldmark:
- `[TOC]` (Python-Markdown / MultiMarkdown / Pandoc)
- `[[_TOC_]]` (GitLab, Azure DevOps)
- `[[toc]]` (markdown-it, VitePress)
- `${toc}` (VitePress configs)
Detection is paragraph-scoped line matching, so fenced/indented code
blocks and inline code spans are naturally excluded. For the `[TOC]`
variant only, a matching link reference definition suppresses the
diagnostic, because the token then resolves to a legitimate link.
Side fix: integration test cleanup now snapshots the rule's value via
reflect and restores it on cleanup, rather than calling
`ApplySettings(DefaultSettings())`. The previous approach left
directory-structure's `configured` flag set across tests, which only
surfaced as a warning now that MDS035 is the first fixture to run
after MDS033 and triggered the `sync.Once` warning.
https://claude.ai/code/session_$(uuidgen 2>/dev/null | tr -d - | head -c 22 || echo 01T569bC9ogHHf5A6Cgxn9NW)
hasTOCLinkReference previously used goldmark.New(), which omits mdsmith's PIBlockParserPrioritized. Extract the parser construction in lint.NewFile into an exported lint.NewParser() so rules that need a secondary parse (here, to consult the link reference map for [TOC] suppression) stay consistent with the original lint parse instead of drifting from it. No behavior change on the current test corpus; defensive alignment for future parser additions. Addresses review feedback on PR #144.
cdb2caf to
5e7c283
Compare
|
🟢 Merge Queue — picked up This PR is in the queue and will be batched with other Next: No action needed — you'll get another comment when CI starts on the batch. View merge queue run. |
|
🔵 Merge Queue — CI running Merged into batch branch Next: No action needed — you'll be notified when CI completes. |
|
✅ Merge Queue — merged This PR landed on Next: Done — nothing more to do here. |
Summary
Implements MDS035 (toc-directive), a new opt-in linting rule that detects renderer-specific table-of-contents directives that render as literal text in CommonMark and goldmark.
Key Changes
New rule implementation (
internal/rules/tocdirective/rule.go):[TOC],[[_TOC_]],[[toc]], and${toc}[TOC]diagnostics when a matching link reference definition exists (case-insensitive per CommonMark)metacategory, disabled by default (opt-in)Comprehensive test suite (
internal/rules/tocdirective/rule_test.go):Documentation and fixtures:
internal/rules/MDS035-toc-directive/README.mdwith rationale for detection-only approach[TOC]as legitimate link via reference definitionIntegration updates:
docs/background/markdown-linters.mdImplementation Details
The rule uses goldmark's parser context to check for link reference definitions, delegating label normalization and code-block scoping to the parser rather than approximating them at the source level. This ensures accurate handling of CommonMark's case-insensitive label matching and proper exclusion of definitions inside code blocks.
The diagnostic message guides users toward two alternatives:
<?catalog?>for file-index use cases (MDS019) or manual maintenance for in-document heading TOCs.https://claude.ai/code/session_01T569bC9ogHHf5A6Cgxn9NW