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

Function parse_markdown

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

279/// `---\n<key: value lines>\n---\n<body>`. Enough for templates and the CLI;
280/// values may be quoted strings or `[a, b]` arrays. Not a full YAML parser.
281pub fn parse_markdown(doc: &str) -> Result<(Map<String, Value>, String)> {
282 // Normalize CRLF so a Windows-authored file parses identically to LF —
283 // otherwise the "---\n" prefix match fails and the whole doc is silently
284 // treated as body with empty frontmatter.
285 let normalized = doc
286 .strip_prefix('\u{feff}')
287 .unwrap_or(doc)
288 .replace("\r\n", "\n");
289 let doc = normalized.as_str();
290 let rest = match doc.strip_prefix("---\n") {
291 Some(r) => r,
292 None => return Ok((Map::new(), doc.to_string())),
293 };
294 let end = rest
295 .find("\n---")
296 .ok_or_else(|| CanonicalError::Lift("unterminated frontmatter block".into()))?;
297 let fm_src = &rest[..end];
298 // body starts after the closing --- line
299 let after = &rest[end + 1..]; // at "---..."
300 let body = after
301 .strip_prefix("---")
302 .map(|b| b.trim_start_matches(['\n', '\r']).to_string())
303 .unwrap_or_default();
304
305 let mut fm = Map::new();
306 for line in fm_src.lines() {
307 let line = line.trim();
308 if line.is_empty() {
309 continue;
310 }
311 if let Some(colon) = line.find(':') {
312 let key = line[..colon].trim().to_string();
313 let raw = line[colon + 1..].trim();
314 fm.insert(key, parse_scalar(raw));
315 }
316 }
317 Ok((fm, body))
318}
319
320fn parse_scalar(raw: &str) -> Value {
321 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