Skip to content

Commit a024cae

Browse files
author
merge-queue-bot
committed
Merge PR #228: Implement MDS052: no-undefined-reference-labels rule
2 parents ec78002 + 36bf158 commit a024cae

25 files changed

Lines changed: 1076 additions & 17 deletions

PLAN.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ footer: |
3939
| 125 || sonnet | [No space inside link text rule](plan/125_no-space-in-link-text.md) |
4040
| 126 || sonnet | [Proper-name capitalization rule](plan/126_proper-names.md) |
4141
| 127 || sonnet | [Single H1 per file rule](plan/127_single-h1.md) |
42-
| 128 | 🔲 | sonnet | [Reject undefined reference-link labels](plan/128_no-undefined-reference-labels.md) |
42+
| 128 | | sonnet | [Reject undefined reference-link labels](plan/128_no-undefined-reference-labels.md) |
4343
| 129 || sonnet | [Flag unused or duplicate link reference definitions](plan/129_no-unused-link-definitions.md) |
4444
| 52 || | [Archetype / Template Library for Agentic Patterns](plan/52_archetype-template-library.md) |
4545
| 61 || | [Required Structure Rule Hardening](plan/61_required-structure-hardening.md) |

cmd/mdsmith/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ import (
6262
_ "github.com/jeduden/mdsmith/internal/rules/nospaceinlinktext"
6363
_ "github.com/jeduden/mdsmith/internal/rules/notrailingpunctuation"
6464
_ "github.com/jeduden/mdsmith/internal/rules/notrailingspaces"
65+
_ "github.com/jeduden/mdsmith/internal/rules/noundefinedreferencelabels"
6566
_ "github.com/jeduden/mdsmith/internal/rules/nounusedlinkdefinitions"
6667
_ "github.com/jeduden/mdsmith/internal/rules/orderedlistnumbering"
6768
_ "github.com/jeduden/mdsmith/internal/rules/paragraphreadability"

internal/config/config_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import (
4949
_ "github.com/jeduden/mdsmith/internal/rules/nospaceinlinktext"
5050
_ "github.com/jeduden/mdsmith/internal/rules/notrailingpunctuation"
5151
_ "github.com/jeduden/mdsmith/internal/rules/notrailingspaces"
52+
_ "github.com/jeduden/mdsmith/internal/rules/noundefinedreferencelabels"
5253
_ "github.com/jeduden/mdsmith/internal/rules/nounusedlinkdefinitions"
5354
_ "github.com/jeduden/mdsmith/internal/rules/orderedlistnumbering"
5455
_ "github.com/jeduden/mdsmith/internal/rules/paragraphreadability"

internal/engine/categories_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import (
4949
_ "github.com/jeduden/mdsmith/internal/rules/nospaceinlinktext"
5050
_ "github.com/jeduden/mdsmith/internal/rules/notrailingpunctuation"
5151
_ "github.com/jeduden/mdsmith/internal/rules/notrailingspaces"
52+
_ "github.com/jeduden/mdsmith/internal/rules/noundefinedreferencelabels"
5253
_ "github.com/jeduden/mdsmith/internal/rules/nounusedlinkdefinitions"
5354
_ "github.com/jeduden/mdsmith/internal/rules/orderedlistnumbering"
5455
_ "github.com/jeduden/mdsmith/internal/rules/paragraphreadability"

internal/integration/rules_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import (
5454
_ "github.com/jeduden/mdsmith/internal/rules/nospaceinlinktext"
5555
_ "github.com/jeduden/mdsmith/internal/rules/notrailingpunctuation"
5656
_ "github.com/jeduden/mdsmith/internal/rules/notrailingspaces"
57+
_ "github.com/jeduden/mdsmith/internal/rules/noundefinedreferencelabels"
5758
_ "github.com/jeduden/mdsmith/internal/rules/nounusedlinkdefinitions"
5859
_ "github.com/jeduden/mdsmith/internal/rules/orderedlistnumbering"
5960
_ "github.com/jeduden/mdsmith/internal/rules/paragraphreadability"
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
---
2+
id: MDS054
3+
name: no-undefined-reference-labels
4+
status: ready
5+
description: Reference-style links and images must have a matching link reference definition in the same file.
6+
---
7+
# MDS054: no-undefined-reference-labels
8+
9+
Reference-style links and images must have a matching link reference
10+
definition in the same file.
11+
12+
## Settings
13+
14+
| Setting | Type | Default | Description |
15+
|----------------|--------|-------------|----------------------------------------------------------------------------------------------------------------------------|
16+
| `shortcut` | string | `heuristic` | Controls when bare `[label]` shortcut references are checked: `heuristic`, `always`, or `collapsed-only`. |
17+
| `placeholders` | list | `[]` | Placeholder tokens to treat as opaque; see [placeholder grammar](../../../docs/background/concepts/placeholder-grammar.md) |
18+
19+
### `shortcut` values
20+
21+
| Value | Behaviour |
22+
|------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
23+
| `heuristic` | Flag bare `[label]` only when the label has no spaces and contains a digit, hyphen, or underscore. Image shortcuts (`![label]`) are always checked regardless of this setting. |
24+
| `always` | Flag every bare `[label]` whose definition is missing. |
25+
| `collapsed-only` | Only flag `[text][label]` (full) and `[label][]` (collapsed) forms; never bare `[label]`. |
26+
27+
## Config
28+
29+
```yaml
30+
rules:
31+
no-undefined-reference-labels:
32+
shortcut: heuristic
33+
placeholders: []
34+
```
35+
36+
Disable:
37+
38+
```yaml
39+
rules:
40+
no-undefined-reference-labels: false
41+
```
42+
43+
## Examples
44+
45+
### Good
46+
47+
<?include
48+
file: good/full-reference.md
49+
wrap: markdown
50+
?>
51+
52+
```markdown
53+
# Full Reference
54+
55+
See [example][site] for more.
56+
57+
[site]: https://example.com
58+
```
59+
60+
<?/include?>
61+
62+
### Good -- collapsed reference
63+
64+
<?include
65+
file: good/collapsed-reference.md
66+
wrap: markdown
67+
?>
68+
69+
```markdown
70+
# Collapsed Reference
71+
72+
See [example][] for more.
73+
74+
[example]: https://example.com
75+
```
76+
77+
<?/include?>
78+
79+
### Good -- prose brackets skipped by heuristic
80+
81+
<?include
82+
file: good/prose-brackets.md
83+
wrap: markdown
84+
?>
85+
86+
```markdown
87+
# Prose Brackets
88+
89+
Use [just brackets] in prose without a definition; the heuristic
90+
skips it because the label has spaces.
91+
```
92+
93+
<?/include?>
94+
95+
### Bad -- undefined full reference
96+
97+
<?include
98+
file: bad/undefined-full-reference.md
99+
wrap: markdown
100+
?>
101+
102+
```markdown
103+
# Undefined Full Reference
104+
105+
See [example][broken] for more.
106+
```
107+
108+
<?/include?>
109+
110+
### Bad -- undefined collapsed reference
111+
112+
<?include
113+
file: bad/undefined-collapsed-reference.md
114+
wrap: markdown
115+
?>
116+
117+
```markdown
118+
# Undefined Collapsed Reference
119+
120+
See [broken][] for more.
121+
```
122+
123+
<?/include?>
124+
125+
### Bad -- undefined shortcut (heuristic)
126+
127+
<?include
128+
file: bad/undefined-shortcut-heuristic.md
129+
wrap: markdown
130+
?>
131+
132+
```markdown
133+
# Shortcut Heuristic
134+
135+
See [plan128] for the plan.
136+
```
137+
138+
<?/include?>
139+
140+
## Diagnostics
141+
142+
| Condition | Message |
143+
|-------------------------------|---------------------------------------------------------------|
144+
| undefined full reference | reference label "X" has no matching link reference definition |
145+
| undefined collapsed reference | reference label "X" has no matching link reference definition |
146+
| undefined shortcut (flagged) | reference label "X" has no matching link reference definition |
147+
148+
## Background
149+
150+
goldmark only constructs an `*ast.Link` for a reference-style usage
151+
when a matching link reference definition exists. When the definition
152+
is missing, goldmark leaves the bracketed text as plain text. A
153+
source-level scan is required to detect these dropped patterns.
154+
155+
Reference labels are CommonMark-normalized before lookup: case-folded,
156+
inner whitespace collapsed, and ends trimmed. `[Foo Bar][BAR]` resolves
157+
against `[bar]: url`.
158+
159+
## Meta-Information
160+
161+
- **ID**: MDS054
162+
- **Name**: `no-undefined-reference-labels`
163+
- **Status**: ready
164+
- **Default**: enabled, shortcut: heuristic, placeholders: []
165+
- **Fixable**: no
166+
- **Implementation**: [source](./)
167+
- **Category**: link
168+
169+
## See also
170+
171+
- [MDS027 cross-file-reference-integrity](../MDS027-cross-file-reference-integrity/README.md)
172+
- [Plan 107: no-reference-style](../../../plan/107_no-reference-style.md)
173+
- [Plan 129: no-unused-link-definitions](../../../plan/129_no-unused-link-definitions.md)
174+
- [Placeholder grammar](../../../docs/background/concepts/placeholder-grammar.md)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
diagnostics:
3+
- line: 3
4+
column: 5
5+
message: 'reference label "broken" has no matching link reference definition'
6+
---
7+
# Undefined Collapsed Reference
8+
9+
See [broken][] for more.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
diagnostics:
3+
- line: 3
4+
column: 5
5+
message: 'reference label "broken" has no matching link reference definition'
6+
---
7+
# Undefined Full Reference
8+
9+
See [example][broken] for more.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
diagnostics:
3+
- line: 3
4+
column: 5
5+
message: 'reference label "plan128" has no matching link reference definition'
6+
---
7+
# Shortcut Heuristic
8+
9+
See [plan128] for the plan.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Case Normalized
2+
3+
CommonMark normalizes reference labels: [Foo Bar][BAR] resolves to the
4+
definition below.
5+
6+
[bar]: https://example.com

0 commit comments

Comments
 (0)