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

Function parse_markdown

atomic-canonical/src/lift.rs:298–335  ·  view source on GitHub ↗

Minimal frontmatter splitter for a full markdown document: `---\n \n---\n `. Enough for templates and the CLI; values may be quoted strings or `[a, b]` arrays. Not a full YAML parser.

(doc: &str)

Source from the content-addressed store, hash-verified

296/// `---\n<key: value lines>\n---\n<body>`. Enough for templates and the CLI;
297/// values may be quoted strings or `[a, b]` arrays. Not a full YAML parser.
298pub fn parse_markdown(doc: &str) -> Result<(Map<String, Value>, String)> {
299 // Normalize CRLF so a Windows-authored file parses identically to LF —
300 // otherwise the "---\n" prefix match fails and the whole doc is silently
301 // treated as body with empty frontmatter.
302 let normalized = doc
303 .strip_prefix('\u{feff}')
304 .unwrap_or(doc)
305 .replace("\r\n", "\n");
306 let doc = normalized.as_str();
307 let rest = match doc.strip_prefix("---\n") {
308 Some(r) => r,
309 None => return Ok((Map::new(), doc.to_string())),
310 };
311 let end = rest
312 .find("\n---")
313 .ok_or_else(|| CanonicalError::Lift("unterminated frontmatter block".into()))?;
314 let fm_src = &rest[..end];
315 // body starts after the closing --- line
316 let after = &rest[end + 1..]; // at "---..."
317 let body = after
318 .strip_prefix("---")
319 .map(|b| b.trim_start_matches(['\n', '\r']).to_string())
320 .unwrap_or_default();
321
322 let mut fm = Map::new();
323 for line in fm_src.lines() {
324 let line = line.trim();
325 if line.is_empty() {
326 continue;
327 }
328 if let Some(colon) = line.find(':') {
329 let key = line[..colon].trim().to_string();
330 let raw = line[colon + 1..].trim();
331 fm.insert(key, parse_scalar(raw));
332 }
333 }
334 Ok((fm, body))
335}
336
337fn parse_scalar(raw: &str) -> Value {
338 if raw.starts_with('[') && raw.ends_with(']') {

Callers 3

runMethod · 0.85
runMethod · 0.85
parse_markdown_then_liftFunction · 0.85

Calls 6

parse_scalarFunction · 0.85
replaceMethod · 0.45
as_strMethod · 0.45
linesMethod · 0.45
is_emptyMethod · 0.45
insertMethod · 0.45

Tested by 1

parse_markdown_then_liftFunction · 0.68