MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / check_embedded_directives

Function check_embedded_directives

atomic-canonical/src/directive.rs:215–269  ·  view source on GitHub ↗

Reject a REGISTERED directive name embedded mid-prose with an attrs brace (e.g. `… ::file-ref{path=x} …` inside a sentence). The block parser only reads directives at line start, so an embedded one would silently stay prose and its edge would be lost. Unregistered names stay prose (the inline rule); `std::fs` and `foo::ref{...}` never match — the colon run must not follow an identifier character.

(text: &str)

Source from the content-addressed store, hash-verified

213/// prose (the inline rule); `std::fs` and `foo::ref{...}` never match — the
214/// colon run must not follow an identifier character.
215pub fn check_embedded_directives(text: &str) -> Result<()> {
216 let mut in_fence = false;
217 for raw_line in text.lines() {
218 let line = strip_html_comments(raw_line);
219 let t = line.trim_start();
220 if t.starts_with("```") {
221 in_fence = !in_fence;
222 continue;
223 }
224 // Lines the block parser handles itself (directive opens/closes).
225 if in_fence || t.starts_with(':') {
226 continue;
227 }
228 let bytes = line.as_bytes();
229 let mut i = 0;
230 while i < bytes.len() {
231 if bytes[i] != b':' {
232 i += 1;
233 continue;
234 }
235 let start = i;
236 while i < bytes.len() && bytes[i] == b':' {
237 i += 1;
238 }
239 let run = i - start;
240 if !(2..=3).contains(&run) {
241 continue;
242 }
243 if start > 0 {
244 let prev = bytes[start - 1];
245 if prev.is_ascii_alphanumeric() || prev == b'_' {
246 continue;
247 }
248 }
249 let name_start = i;
250 while i < bytes.len()
251 && (bytes[i].is_ascii_lowercase() || bytes[i].is_ascii_digit() || bytes[i] == b'-')
252 {
253 i += 1;
254 }
255 if i == name_start || i >= bytes.len() || bytes[i] != b'{' {
256 continue;
257 }
258 let name = &line[name_start..i];
259 if vocab::is_known_directive(name) {
260 return Err(CanonicalError::Directive(format!(
261 "directive '{}{name}' is embedded in prose — block \
262 directives must start their own line",
263 ":".repeat(run)
264 )));
265 }
266 }
267 }
268 Ok(())
269}
270
271/// Drop `<!-- … -->` spans so template guidance comments never trip the
272/// embedded-directive check.

Calls 7

strip_html_commentsFunction · 0.85
is_known_directiveFunction · 0.85
DirectiveClass · 0.85
linesMethod · 0.45
as_bytesMethod · 0.45
lenMethod · 0.45
containsMethod · 0.45