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

Function parse_inline

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

Extract inline directives (`:name[label]{attrs}`) from running prose. Recognition rules keep prose safe: - the `:` must sit at a word boundary (start of text, or after a non-alphanumeric character) — so `did:atomic:lee` never matches; - the name must be immediately followed by `[label]` — a bare `:word` is prose; - the name must be in the inline registry — `:unknown[x]` stays prose, because prose

(text: &str)

Source from the content-addressed store, hash-verified

140/// - the name must be in the inline registry — `:unknown[x]` stays prose,
141/// because prose is the unconstrained slot.
142pub fn parse_inline(text: &str) -> Result<Vec<Directive>> {
143 let bytes = text.as_bytes();
144 let mut out = Vec::new();
145 let mut i = 0;
146 while i < bytes.len() {
147 if bytes[i] != b':' {
148 i += 1;
149 continue;
150 }
151 // Word boundary: previous byte must not be alphanumeric or ':' (which
152 // would make this the tail of a URN/DID or a block-directive marker).
153 if i > 0 {
154 let prev = bytes[i - 1] as char;
155 if prev.is_ascii_alphanumeric() || prev == ':' {
156 i += 1;
157 continue;
158 }
159 }
160 // Read the name: [a-z0-9-]+ immediately after ':'.
161 let name_start = i + 1;
162 let mut j = name_start;
163 while j < bytes.len() && (bytes[j].is_ascii_alphanumeric() || bytes[j] == b'-') {
164 j += 1;
165 }
166 if j == name_start || j >= bytes.len() || bytes[j] != b'[' {
167 i += 1;
168 continue;
169 }
170 let name = &text[name_start..j];
171 if !vocab::is_known_inline_directive(name) {
172 i += 1;
173 continue;
174 }
175 // Label: up to the matching ']' (no nesting in labels).
176 let label_start = j + 1;
177 let Some(label_len) = text[label_start..].find(']') else {
178 return Err(CanonicalError::Directive(format!(
179 "unterminated inline directive ':{name}[' (missing closing ']')"
180 )));
181 };
182 let label = text[label_start..label_start + label_len].to_string();
183 let mut end = label_start + label_len + 1;
184 // Optional immediate `{attrs}`.
185 let mut attrs_src = "";
186 if bytes.get(end) == Some(&b'{') {
187 let Some(close) = text[end + 1..].find('}') else {
188 return Err(CanonicalError::Directive(format!(
189 "unterminated inline directive ':{name}[…]{{' (missing closing '}}')"
190 )));
191 };
192 attrs_src = &text[end + 1..end + 1 + close];
193 end = end + 1 + close + 1;
194 }
195 let (id, attrs) = parse_attrs(attrs_src)?;
196 out.push(Directive {
197 name: name.to_string(),
198 id,
199 attrs,

Calls 7

DirectiveClass · 0.85
parse_attrsFunction · 0.85
getMethod · 0.65
as_bytesMethod · 0.45
lenMethod · 0.45
pushMethod · 0.45