@@ -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,29 @@ 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 the
94+ duplicate-disambiguation logic in
95+ [ ` internal/rules/crossfilereferenceintegrity/rule.go ` ] [ cfri ]
96+ (used by ` collectHeadingAnchors ` ). Move it
97+ into a shared package. ` internal/mdtext/ ` is
98+ the natural home. Both rules then call shared
99+ code so anchors stay consistent. Repeated
100+ headings get ` -1 ` , ` -2 ` , … suffixes in source
101+ order, matching the reference-integrity rule.
102+
103+ [ cfri ] : ../internal/rules/crossfilereferenceintegrity/rule.go
104+
105+ Indentation uses the same per-level indent as
106+ the MDS016 ` list-indent ` rule's ` spaces `
107+ setting (default 2). There is no
108+ ` <?listindent?> ` directive; indentation is a
109+ property of the emitted output, not a
110+ configurable parameter of ` <?toc?> ` .
101111
102112List items respect the heading structure, not
103113the raw level. Given H2 → H4 → H2, the tree is:
@@ -110,9 +120,14 @@ the raw level. Given H2 → H4 → H2, the tree is:
110120
111121…not a flat list keyed on absolute level.
112122
113- ### Rule: MDS036 (toc)
123+ ### Rule: MDS037 (toc)
124+
125+ Note on numbering: plan 89 originally claimed
126+ MDS036, but plan 51 shipped first and took
127+ MDS036 for ` max-section-length ` . MDS034 remains
128+ reserved for plan 86. Plan 89 takes MDS037.
114129
115- - ID: ` MDS036 `
130+ - ID: ` MDS037 `
116131- Name: ` toc `
117132- Category: ` meta `
118133- Default: enabled (generated sections are
@@ -135,25 +150,25 @@ MDS035 becomes a `FixableRule`. On `Fix`, for
135150each matched directive line inside a paragraph:
136151
137152- ` [TOC] ` (unresolved), ` [[_TOC_]] ` , ` [[toc]] ` ,
138- ` ${toc} ` → replace the single line with:
153+ ` ${toc} ` → replace the single line with the
154+ canonical empty generated-section block:
139155
140156 ``` text
141- <?toc
142- ?>
157+ <?toc?>
143158 <?/toc?>
144159 ```
145160
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.
161+ The empty body means "use defaults". MDS035's
162+ Fix must also insert surrounding blank lines
163+ when the directive would otherwise fuse into
164+ adjacent paragraph text.
150165
151166- ` [TOC] ` with a matching link reference
152167 definition → leave untouched (already
153168 suppressed by Check; must stay out of Fix).
154169
155170The Fix output is plain ` <?toc?>...<?/toc?> `
156- with an ** empty** body. MDS036 runs in a
171+ with an ** empty** body. MDS037 runs in a
157172subsequent pass of the same ` mdsmith fix `
158173invocation (mdsmith already supports
159174multi-pass fix, used by MDS019/MDS021) and
@@ -165,10 +180,11 @@ and fall back only if needed.
165180
166181### Interaction with existing rules
167182
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.
183+ - MDS015 only enforces blank lines around
184+ fenced code blocks, not generated-section
185+ markers. Blank-line padding around inserted
186+ ` <?toc?> ` blocks is MDS035's responsibility
187+ at Fix time, not MDS015's.
172188- MDS020 (required-structure): no change; TOC
173189 blocks are not a required section.
174190- MDS019 (catalog), MDS021 (include): orthogonal
@@ -191,39 +207,45 @@ and fall back only if needed.
191207
192208## Tasks
193209
194- 1 . Create the ` <?toc?> ` directive in a new
210+ 1 . Move ` slugify ` and the duplicate-anchor
211+ counter from
212+ ` internal/rules/crossfilereferenceintegrity/ `
213+ into a shared helper in ` internal/mdtext/ ` .
214+ Update the reference-integrity rule to call
215+ the shared helper. No behavior change.
216+ 2 . Create the ` <?toc?> ` directive in a new
195217 ` internal/rules/toc/ ` package using the
196218 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
219+ (same engine as ` catalog ` ) and the shared
220+ slug helper from task 1. Register as MDS037
221+ in category ` meta ` , enabled by default,
222+ ` FixableRule ` .
223+ 3 . Add MDS037 fixtures under
224+ ` internal/rules/MDS037 -toc/ ` : ` good/ ` with a
203225 correct body, ` bad/ ` with a stale body to
204226 verify Check, ` fixed/ ` with the expected
205227 output after Fix. Cover default parameters,
206228 custom ` min-level ` /` max-level ` , single-level
207229 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
230+ 4 . Upgrade MDS035 to ` FixableRule ` : replace
231+ matched directive lines with the canonical
232+ empty block ` <?toc?>\n<?/toc?> ` , inserting
233+ blank lines above and below as needed ; leave
234+ ` [TOC] ` untouched when a link-ref definition
213235 suppresses Check; add ` fixed/ ` fixtures for
214236 each of the four variants.
215- 4 . Update MDS035's diagnostic message to point
216- at ` <?toc?> ` (MDS036 ) instead of
237+ 5 . Update MDS035's diagnostic message to point
238+ at ` <?toc?> ` (MDS037 ) instead of
217239 ` <?catalog?> ` (MDS019); wording:
218- ` unsupported TOC directive \ ` {token}\` ; use \` <? toc?> \` (MDS036 )`
219- 5 . Update MDS035 README (message + examples),
240+ ` unsupported TOC directive \ ` {token}\` ; use \` <? toc?> \` (MDS037 )`
241+ 6 . Update MDS035 README (message + examples),
220242 plan 88 status/deviation note, and the
221243 renderer-portability section in
222244 [ docs/background/markdown-linters.md] [ lnt ] .
223- 6 . Update the generated-section archetype doc
245+ 7 . Update the generated-section archetype doc
224246 to list ` toc ` alongside ` catalog ` and
225247 ` include ` .
226- 7 . Verify multi-pass ` mdsmith fix ` end-to-end:
248+ 8 . Verify multi-pass ` mdsmith fix ` end-to-end:
227249 starting from a document containing ` [TOC] ` ,
228250 a single ` fix ` run must yield a populated
229251 ` <?toc?>...<?/toc?> ` block. Add an
@@ -240,7 +262,7 @@ and fall back only if needed.
240262- [ ] ` min-level ` and ` max-level ` parameters
241263 gate which headings appear
242264- [ ] ` <?toc?> ` with a stale body produces
243- an MDS036 diagnostic on ` check `
265+ an MDS037 diagnostic on ` check `
244266- [ ] MDS035 ` fix ` rewrites ` [TOC] ` ,
245267 ` [[_TOC_]] ` , ` [[toc]] ` , and ` ${toc} `
246268 on their own line to
@@ -254,7 +276,7 @@ and fall back only if needed.
254276- [ ] Merge driver regenerates ` <?toc?> `
255277 bodies on conflict, same as ` <?catalog?> `
256278- [ ] MDS035 diagnostic message names
257- ` <?toc?> ` (MDS036 ) as the replacement
279+ ` <?toc?> ` (MDS037 ) as the replacement
258280- [ ] All tests pass: ` go test ./... `
259281- [ ] ` go tool golangci-lint run ` reports
260282 no issues
0 commit comments