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

Function parse_markdown

atomic-canonical/src/lift.rs:354–391  ·  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

352/// `---\n<key: value lines>\n---\n<body>`. Enough for templates and the CLI;
353/// values may be quoted strings or `[a, b]` arrays. Not a full YAML parser.
354pub fn parse_markdown(doc: &str) -> Result<(Map<String, Value>, String)> {
355 // Normalize CRLF so a Windows-authored file parses identically to LF —
356 // otherwise the "---\n" prefix match fails and the whole doc is silently
357 // treated as body with empty frontmatter.
358 let normalized = doc
359 .strip_prefix('\u{feff}')
360 .unwrap_or(doc)
361 .replace("\r\n", "\n");
362 let doc = normalized.as_str();
363 let rest = match doc.strip_prefix("---\n") {
364 Some(r) => r,
365 None => return Ok((Map::new(), doc.to_string())),
366 };
367 let end = rest
368 .find("\n---")
369 .ok_or_else(|| CanonicalError::Lift("unterminated frontmatter block".into()))?;
370 let fm_src = &rest[..end];
371 // body starts after the closing --- line
372 let after = &rest[end + 1..]; // at "---..."
373 let body = after
374 .strip_prefix("---")
375 .map(|b| b.trim_start_matches(['\n', '\r']).to_string())
376 .unwrap_or_default();
377
378 let mut fm = Map::new();
379 for line in fm_src.lines() {
380 let line = line.trim();
381 if line.is_empty() {
382 continue;
383 }
384 if let Some(colon) = line.find(':') {
385 let key = line[..colon].trim().to_string();
386 let raw = line[colon + 1..].trim();
387 fm.insert(key, parse_scalar(raw));
388 }
389 }
390 Ok((fm, body))
391}
392
393fn parse_scalar(raw: &str) -> Value {
394 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