@@ -6,7 +6,7 @@ summary: >-
66 Add a `<?toc?>...<?/toc?>` generated-section
77 directive that emits a nested list of the
88 current document's headings linked to their
9- anchors (MDS036 ). Upgrade MDS035 (plan 88) to
9+ anchors (MDS037 ). Upgrade MDS035 (plan 88) to
1010 auto-fix each detected renderer-specific TOC
1111 token by replacing it with a `<?toc?>` block,
1212 which the directive then regenerates on
@@ -85,19 +85,31 @@ produces with default settings.
8585### Generated content
8686
8787A nested unordered list, one item per heading
88- in source order. Each item links to a
89- GitHub-flavor slug of the heading text:
90-
91- - Lowercase the heading plain text.
92- - Replace spaces with ` - ` .
93- - Strip characters outside ` [a-z0-9-_] ` .
94- - Disambiguate repeats by appending ` -1 ` , ` -2 ` , …
95- in source order (matching goldmark-meta /
96- GitHub's behavior).
97-
98- Indentation is ` <?listindent?> ` -aware: use the
99- same per-level indent as MDS016 (two spaces by
100- default).
88+ in source order. Each item links to the same
89+ heading anchor mdsmith already computes for
90+ cross-file heading references.
91+
92+ Do not define a TOC-specific slug algorithm.
93+ Reuse the ` slugify ` function and
94+ duplicate-disambiguation logic currently in
95+ [ ` internal/rules/crossfilereferenceintegrity/rule.go ` ] [ cfri ]
96+ (around lines 349 and 389). Move that helper
97+ into a shared package — ` internal/mdtext/ ` is
98+ the natural home — and have both rules call
99+ the shared code so anchors stay consistent
100+ across rules. Repeated headings must receive
101+ the same ` -1 ` , ` -2 ` , … suffixes in source
102+ order as the existing reference-integrity
103+ rule.
104+
105+ [ cfri ] : ../internal/rules/crossfilereferenceintegrity/rule.go
106+
107+ Indentation uses the same per-level indent as
108+ the MDS016 ` list-indent ` rule (config key
109+ ` list-indent.spaces ` , default 2). There is no
110+ ` <?listindent?> ` directive; indentation is a
111+ property of the emitted output, not a
112+ configurable parameter of ` <?toc?> ` .
101113
102114List items respect the heading structure, not
103115the raw level. Given H2 → H4 → H2, the tree is:
@@ -110,9 +122,14 @@ the raw level. Given H2 → H4 → H2, the tree is:
110122
111123…not a flat list keyed on absolute level.
112124
113- ### Rule: MDS036 (toc)
125+ ### Rule: MDS037 (toc)
126+
127+ Note on numbering: plan 89 originally claimed
128+ MDS036, but plan 51 shipped first and took
129+ MDS036 for ` max-section-length ` . MDS034 remains
130+ reserved for plan 86. Plan 89 takes MDS037.
114131
115- - ID: ` MDS036 `
132+ - ID: ` MDS037 `
116133- Name: ` toc `
117134- Category: ` meta `
118135- Default: enabled (generated sections are
@@ -135,25 +152,25 @@ MDS035 becomes a `FixableRule`. On `Fix`, for
135152each matched directive line inside a paragraph:
136153
137154- ` [TOC] ` (unresolved), ` [[_TOC_]] ` , ` [[toc]] ` ,
138- ` ${toc} ` → replace the single line with:
155+ ` ${toc} ` → replace the single line with the
156+ canonical empty generated-section block:
139157
140158 ``` text
141- <?toc
142- ?>
159+ <?toc?>
143160 <?/toc?>
144161 ```
145162
146- The empty YAML body means "use defaults". A
147- trailing newline separator is inserted if the
148- surrounding paragraph would otherwise fuse
149- the directive into adjacent text.
163+ The empty body means "use defaults". MDS035's
164+ Fix must also insert surrounding blank lines
165+ when the directive would otherwise fuse into
166+ adjacent paragraph text.
150167
151168- ` [TOC] ` with a matching link reference
152169 definition → leave untouched (already
153170 suppressed by Check; must stay out of Fix).
154171
155172The Fix output is plain ` <?toc?>...<?/toc?> `
156- with an ** empty** body. MDS036 runs in a
173+ with an ** empty** body. MDS037 runs in a
157174subsequent pass of the same ` mdsmith fix `
158175invocation (mdsmith already supports
159176multi-pass fix, used by MDS019/MDS021) and
@@ -165,10 +182,11 @@ and fall back only if needed.
165182
166183### Interaction with existing rules
167184
168- - MDS015 (blank line around fenced code /
169- generated sections): the Fix output adds the
170- required blank-line padding around the
171- inserted block.
185+ - MDS015 only enforces blank lines around
186+ fenced code blocks, not generated-section
187+ markers. Blank-line padding around inserted
188+ ` <?toc?> ` blocks is MDS035's responsibility
189+ at Fix time, not MDS015's.
172190- MDS020 (required-structure): no change; TOC
173191 blocks are not a required section.
174192- MDS019 (catalog), MDS021 (include): orthogonal
@@ -191,39 +209,45 @@ and fall back only if needed.
191209
192210## Tasks
193211
194- 1 . Create the ` <?toc?> ` directive in a new
212+ 1 . Move ` slugify ` and the duplicate-anchor
213+ counter from
214+ ` internal/rules/crossfilereferenceintegrity/ `
215+ into a shared helper in ` internal/mdtext/ ` .
216+ Update the reference-integrity rule to call
217+ the shared helper. No behavior change.
218+ 2 . Create the ` <?toc?> ` directive in a new
195219 ` internal/rules/toc/ ` package using the
196220 shared ` internal/archetype/gensection.Engine `
197- (same engine as ` catalog ` ). Add a slug
198- helper in ` internal/mdtext/ ` or the toc
199- package. Register as MDS036 in category
200- ` meta ` , enabled by default, ` FixableRule ` .
201- 2 . Add MDS036 fixtures under
202- ` internal/rules/MDS036 -toc/ ` : ` good/ ` with a
221+ (same engine as ` catalog ` ) and the shared
222+ slug helper from task 1. Register as MDS037
223+ in category ` meta ` , enabled by default,
224+ ` FixableRule ` .
225+ 3 . Add MDS037 fixtures under
226+ ` internal/rules/MDS037 -toc/ ` : ` good/ ` with a
203227 correct body, ` bad/ ` with a stale body to
204228 verify Check, ` fixed/ ` with the expected
205229 output after Fix. Cover default parameters,
206230 custom ` min-level ` /` max-level ` , single-level
207231 docs, and deeply nested structures.
208- 3 . Upgrade MDS035 to ` FixableRule ` : replace
209- matched directive lines with
210- ` <?toc?>\n<?/toc?> ` blocks preserving
211- surrounding blank lines; leave ` [TOC] `
212- untouched when a link-ref definition
232+ 4 . Upgrade MDS035 to ` FixableRule ` : replace
233+ matched directive lines with the canonical
234+ empty block ` <?toc?>\n<?/toc?> ` , inserting
235+ blank lines above and below as needed ; leave
236+ ` [TOC] ` untouched when a link-ref definition
213237 suppresses Check; add ` fixed/ ` fixtures for
214238 each of the four variants.
215- 4 . Update MDS035's diagnostic message to point
216- at ` <?toc?> ` (MDS036 ) instead of
239+ 5 . Update MDS035's diagnostic message to point
240+ at ` <?toc?> ` (MDS037 ) instead of
217241 ` <?catalog?> ` (MDS019); wording:
218- ` unsupported TOC directive \ ` {token}\` ; use \` <? toc?> \` (MDS036 )`
219- 5 . Update MDS035 README (message + examples),
242+ ` unsupported TOC directive \ ` {token}\` ; use \` <? toc?> \` (MDS037 )`
243+ 6 . Update MDS035 README (message + examples),
220244 plan 88 status/deviation note, and the
221245 renderer-portability section in
222246 [ docs/background/markdown-linters.md] [ lnt ] .
223- 6 . Update the generated-section archetype doc
247+ 7 . Update the generated-section archetype doc
224248 to list ` toc ` alongside ` catalog ` and
225249 ` include ` .
226- 7 . Verify multi-pass ` mdsmith fix ` end-to-end:
250+ 8 . Verify multi-pass ` mdsmith fix ` end-to-end:
227251 starting from a document containing ` [TOC] ` ,
228252 a single ` fix ` run must yield a populated
229253 ` <?toc?>...<?/toc?> ` block. Add an
@@ -240,7 +264,7 @@ and fall back only if needed.
240264- [ ] ` min-level ` and ` max-level ` parameters
241265 gate which headings appear
242266- [ ] ` <?toc?> ` with a stale body produces
243- an MDS036 diagnostic on ` check `
267+ an MDS037 diagnostic on ` check `
244268- [ ] MDS035 ` fix ` rewrites ` [TOC] ` ,
245269 ` [[_TOC_]] ` , ` [[toc]] ` , and ` ${toc} `
246270 on their own line to
@@ -254,7 +278,7 @@ and fall back only if needed.
254278- [ ] Merge driver regenerates ` <?toc?> `
255279 bodies on conflict, same as ` <?catalog?> `
256280- [ ] MDS035 diagnostic message names
257- ` <?toc?> ` (MDS036 ) as the replacement
281+ ` <?toc?> ` (MDS037 ) as the replacement
258282- [ ] All tests pass: ` go test ./... `
259283- [ ] ` go tool golangci-lint run ` reports
260284 no issues
0 commit comments