1mod accordion;
8mod callout;
9mod card;
10mod code_group;
11mod content;
12mod fields;
13mod frontmatter;
14mod heading;
15#[cfg(feature = "openapi")]
16mod openapi_parser;
17#[cfg(feature = "openapi")]
18mod openapi_tag;
19mod openapi_types;
20mod steps;
21mod tabs;
22mod types;
23mod update;
24mod utils;
25pub mod yaml_lite;
26
27pub use content::{get_raw_markdown, parse_mdx};
28pub use frontmatter::extract_frontmatter;
29pub use heading::strip_leading_h1;
30#[cfg(feature = "openapi")]
31pub use openapi_parser::{OpenApiError, parse_openapi};
32pub use openapi_types::*;
33pub use types::*;
34pub use yaml_lite::{YamlLiteError, YamlMap, YamlValue, parse_yaml_lite};
35
36pub fn parse_document(content: &str) -> ParsedDoc {
42 let (frontmatter, remaining) = extract_frontmatter(content);
43 let body = strip_leading_h1(remaining);
46 let nodes = content::parse_body(body);
49 let raw_markdown = get_raw_markdown(&nodes);
50
51 ParsedDoc {
52 frontmatter,
53 content: nodes,
54 raw_markdown,
55 }
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn parse_document_strips_duplicate_atx_h1() {
64 let content = "---\ntitle: Hello\n---\n\n# Hello\n\nbody text\n";
65 let doc = parse_document(content);
66 assert_eq!(doc.frontmatter.title, "Hello");
67 assert!(
68 !doc.raw_markdown.contains("# Hello"),
69 "expected leading H1 to be stripped, got: {:?}",
70 doc.raw_markdown
71 );
72 assert!(doc.raw_markdown.contains("body text"));
73 }
74
75 #[test]
76 fn parse_document_leaves_body_without_leading_h1_untouched() {
77 let content = "---\ntitle: Hello\n---\n\nintro paragraph\n\n## Subheading\n";
78 let doc = parse_document(content);
79 assert!(doc.raw_markdown.contains("intro paragraph"));
80 assert!(doc.raw_markdown.contains("## Subheading"));
81 }
82
83 #[test]
84 fn parse_document_preserves_h1_appearing_mid_document() {
85 let content = "---\ntitle: Hello\n---\n\nintro\n\n# Later heading\n\nmore body\n";
86 let doc = parse_document(content);
87 assert!(doc.raw_markdown.contains("intro"));
88 assert!(
89 doc.raw_markdown.contains("# Later heading"),
90 "mid-document H1 should survive, got: {:?}",
91 doc.raw_markdown
92 );
93 }
94
95 #[test]
96 fn parse_document_keeps_body_starting_with_thematic_break() {
97 let content = "---\ntitle: T\n---\n\n---\n\nfirst para\n\n---\n\nsecond para\n";
100 let doc = parse_document(content);
101 assert_eq!(doc.frontmatter.title, "T");
102 assert!(
103 doc.raw_markdown.contains("first para"),
104 "body before the second rule was eaten: {:?}",
105 doc.raw_markdown
106 );
107 assert!(doc.raw_markdown.contains("second para"));
108 }
109}