1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! Inline `# Spec References` block parsing (DOC-38 §2.1–§2.4, §3).
//!
//! # Spec References
//!
//! - [`SPEC-SLD-03~draft`](docs/specs/spec-linked-documentation.md#SPEC-SLD-03~draft)
//!
//! Why: code and config declare linkage inline, grouped under a `# Spec
//! References` block introduced by a marker line (§2.3). References belong to
//! the nearest preceding marker within the same comment/docstring region, and
//! fenced code blocks are NEVER scanned (§2.3) — the standard's own examples
//! would otherwise self-trigger. Scoping to declared blocks is what stops a
//! resolver inventing linkage from a `SPEC-…` mention in unrelated prose (G4).
//! What: [`parse_inline_refs`] — a single line-oriented state machine that
//! tracks the comment/docstring region (via [`CommentSyntax`]), the open
//! `# Spec References` block, and fenced-code state, then applies the §2.2
//! reference regex within each open, non-fenced block. Records 1-based line
//! numbers so a linter can emit `file:line` diagnostics.
//! Test: `super::tests::inline_*`.
use Reference;
use CommentSyntax;
use ;
/// True when a stripped line opens or closes a Markdown code fence (§2.3).
///
/// Why: fenced content must never be scanned for markers or references; the
/// spec's own body quotes many example blocks inside fences (DOC-38 is the acid
/// test). Detecting fences on the comment *content* (not the raw line) means a
/// Rust `/// ```` doc-fence is honoured too.
/// What: returns the fence character (`` ` `` or `~`) when `stripped` begins
/// with a run of three or more of it, else `None`.
/// Test: `super::tests::inline_skips_fenced`.
/// Extract the comment/docstring *content* of a line, updating docstring state.
///
/// Why: the marker phrase and reference grammar apply to comment content, not
/// raw source; docstring languages (Python `"""`, JSDoc `/* */`) carry
/// non-prefixed reference lines that are in scope only while the region is open.
/// What: returns `Some(content)` when the line is a line-comment or lies inside
/// an open docstring region (mutating `in_doc` as it opens/closes the region),
/// or `None` for a plain code line. A leading `*` (JSDoc continuation) is
/// stripped from docstring-interior lines.
/// Test: `super::tests::inline_python_docstring`, `inline_ts_jsdoc`.
/// Parse every inline `# Spec References` reference in a source file.
///
/// Why: a linter (and any resolver) must recover the exact set of declared
/// references — with line numbers — to resolve them and report unresolved ones
/// by `file:line`. Honouring only marker-scoped, non-fenced blocks is what keeps
/// the result to *declared* linkage (§2.3, §2.4). For a line-comment-only idiom
/// (shell/TOML/YAML's `#`), the comment lead-in strip removes the SAME `#` that
/// would otherwise mark a new heading, so a plain follow-on comment line (e.g.
/// prose that happens to mention another well-formed reference triple) is
/// indistinguishable from a continued declaration by heading-detection alone —
/// it must instead close the block by NOT looking like a block item (§2.3's
/// bullet convention: every real declaration line is blank or `-`-prefixed).
/// What: walks `source` line by line under `syntax`'s comment/docstring idiom.
/// A marker line (stripped content, minus leading `#`s, equal case-insensitively
/// to `Spec References`) opens a block; a nested heading or a non-comment line
/// closes it; fenced regions are skipped entirely. Within an open block, a line
/// stays part of the block (and is scanned by the §2.2 reference regex) only
/// while it is blank or `-`-prefixed after stripping the comment lead-in — the
/// first line that is neither closes the block WITHOUT being scanned, so trailing
/// prose in the same comment run can never masquerade as a declaration. Extracted
/// references drop any unsafe path (a `..` traversal segment or an absolute
/// path, §2.1's repo-root-relative canonical form). Duplicates are retained
/// (each keeps its own line) so a linter can flag each occurrence.
/// Test: `super::tests::inline_rust`, `inline_bare_shell`, `inline_skips_fenced`,
/// `inline_ignores_non_block_ref`, `inline_hash_block_closes_on_prose`.