### Real-world Blog Processor Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md A conceptual example of how to process blog posts, extracting frontmatter and rendering content. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; // Assume 'blog_post_content' is a string containing the Markdown content of a blog post. let blog_post_content = "---\nauthor: John Doe\ndate: 2023-10-27\ntags: [rust, markdown]\n---\n# My Blog Post\n\nThis is the content of the blog post."; let mut extractor = FrontmatterExtractor::new(blog_post_content.as_bytes()); let frontmatter_data = match extractor.extract().unwrap() { Some(fm) => { // Process the frontmatter (e.g., parse as TOML, JSON, YAML) println!("Extracted Frontmatter: {}", fm); Some(fm) } None => { println!("No frontmatter found."); None } }; let html_content = extractor.into_html(); println!("Rendered HTML: {}", html_content); // Now you can use 'frontmatter_data' and 'html_content' for display. ``` -------------------------------- ### HTML Example - Rendering Markdown to HTML Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md This example demonstrates rendering Markdown content, including frontmatter, into HTML. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown_input = "---\ntitle: My Article\nauthor: John Doe\n---\n# Introduction\n\nThis is the **content** of the article."; let mut extractor = FrontmatterExtractor::new(markdown_input.as_bytes()); // Extract frontmatter (optional if only rendering to HTML) if let Some(frontmatter) = extractor.extract().unwrap() { println!("Frontmatter: {:?}", frontmatter); } // Render the rest of the markdown to HTML let html_output = extractor.into_html(); println!("\n--- Rendered HTML ---\n{}", html_output); ``` -------------------------------- ### Extractor Example - Basic Extraction Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md A basic example showing how to use FrontmatterExtractor to get frontmatter and the remaining content. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown_input = "---\nkey: value\n---\n# Main Content\n\nSome text here."; let mut extractor = FrontmatterExtractor::new(markdown_input.as_bytes()); // Extract frontmatter and the rest of the markdown content match extractor.extract().unwrap() { Some(frontmatter) => { println!("Extracted Frontmatter: {}", frontmatter); let remaining_markdown = extractor.as_str(); println!("Remaining Markdown:\n{}", remaining_markdown); } None => { println!("No frontmatter found."); let remaining_markdown = extractor.as_str(); println!("Remaining Markdown:\n{}", remaining_markdown); } } // You can also render to HTML after extraction let html_output = extractor.into_html(); println!("\n--- Rendered HTML ---\n{}", html_output); ``` -------------------------------- ### Real-world Blog Processor Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/INDEX.md A more complex example simulating a real-world scenario, like processing a blog post with frontmatter. ```rust use pulldown_cmark_frontmatter::{parse_with, FrontMatter}; use pulldown_cmark::{html, Options, Parser}; use serde::Deserialize; #[derive(Deserialize, Debug)] struct BlogPostMeta { title: String, date: String, tags: Vec, } let blog_post_md = "---\ntitle: My Awesome Blog Post\ndate: 2023-10-27\ntags: [rust, markdown, example]\n---\n# Introduction\n This is the content of the blog post. ## Details More details here."; let mut parser = Parser::new(blog_post_md).map_with_frontmatter(|fm| { match fm { FrontMatter::Text(text) => { toml::from_str::(&text).ok() } FrontMatter::None => None, } }); let mut html_content = String::new(); let mut metadata: Option = None; for event in parser { match event { pulldown_cmark::Event::FrontMatter(fm_data) => { metadata = fm_data.get::().cloned(); } _ => { // Push other events to HTML output // Note: This simplified example doesn't handle event-to-HTML conversion directly // A full implementation would use html::push_html or similar. } } } if let Some(meta) = metadata { println!("Blog Post Metadata:"); println!(" Title: {}", meta.title); println!(" Date: {}", meta.date); println!(" Tags: {:?}", meta.tags.join(", ")); } // In a real scenario, you would now render the rest of the content to HTML // For brevity, we are just showing metadata extraction here. println!("\n(HTML rendering would follow here)"); ``` -------------------------------- ### Error Recovery Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md Demonstrates how to handle potential errors during frontmatter extraction, such as malformed content. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; // Malformed frontmatter (missing closing ---) let markdown = "---\ntitle: Malformed\nThis is not valid frontmatter. # Content"; let mut extractor = FrontmatterExtractor::new(markdown.as_bytes()); match extractor.extract() { Ok(Some(frontmatter)) => { println!("Extracted Frontmatter: {:?}", frontmatter); } Ok(None) => { println!("No frontmatter found."); } Err(e) => { eprintln!("Error extracting frontmatter: {}", e); // Attempt to render the rest of the content anyway let html = extractor.into_html(); println!("HTML (potentially incomplete): {}", html); } } ``` -------------------------------- ### Zero Configuration Use Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Demonstrates the basic usage of FrontmatterExtractor for extracting frontmatter from markdown without any additional setup. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; fn main() { let markdown = "# Title\n\n```toml\nauthor = \"Alice\"\n```\n\nContent"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract(); if let Some(fm) = frontmatter { println!("Title: {:?}", fm.title); println!("Code block: {:?}", fm.code_block); } } ``` -------------------------------- ### Document Statistics Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/README.md Displays statistics about the documentation, including total lines, size, file count, code examples, and cross-references. ```text Total lines: 3,879 Total size: ~136 KB Files: 10 (.md) Code examples: 30+ Cross-references: 100+ ``` -------------------------------- ### Ensuring Owned Frontmatter Source Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md This example shows how to clone the code_block.source to ensure the Frontmatter is fully owned, even after the original markdown source is dropped. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let frontmatter = { let markdown = "# Title\n\n```toml\nkey = \"value\"\n```"; let extractor = FrontmatterExtractor::from_markdown(markdown); let mut fm = extractor.extract().unwrap(); // Convert borrowed source to owned if let Some(ref mut cb) = fm.code_block { cb.source = cb.source.clone(); } fm // markdown dropped here, but frontmatter.code_block.source is now owned }; ``` -------------------------------- ### Rust Example Using CowStr Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/types.md Demonstrates how to use CowStr, which can be treated as a &str or converted to a String. This is useful for accessing code block content and language identifiers. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\n```toml\nauthor = \"Alice\"\n```"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); let code_block = frontmatter.code_block.unwrap(); // CowStr can be used as &str let source_ref: &str = &code_block.source; // Or cloned to String let source_string: String = code_block.source.to_string(); ``` -------------------------------- ### Process Real-World Blog Post with Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/examples.md A realistic example demonstrating how to read a Markdown file, extract frontmatter (including metadata in TOML format), and render the rest of the content to HTML. This is useful for blog engines or content management systems. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::html; use serde::{Deserialize, Serialize}; use std::fs; #[derive(Debug, Serialize, Deserialize)] struct BlogMeta { author: String, published: bool, tags: Vec, } #[derive(Debug)] struct BlogPost { title: String, metadata: BlogMeta, html: String, } fn process_blog_post(file_path: &str) -> Result> { // Read file let markdown = fs::read_to_string(file_path)?; // Extract and render let mut extractor = FrontmatterExtractor::from_markdown(&markdown); let frontmatter = extractor.extract_buffered() .ok_or("No frontmatter found in blog post")?; // Get title let title = frontmatter.title.clone() .ok_or("Blog post must have a title")?; // Parse metadata let code_block = frontmatter.code_block.as_ref() .ok_or("Blog post must have metadata block")?; let metadata: BlogMeta = toml::from_str(&code_block.source) .map_err(|e| format!("Invalid metadata TOML: {}", e))?; // Render HTML let mut html = String::new(); html::push_html(&mut html, &mut extractor); Ok(BlogPost { title, metadata, html, }) } fn main() { // Example usage let markdown = rлід"# My First Blog Post ```toml author = "Emma" published = true tags = ["rust", "blog"] ``` This is my first blog post! It demonstrates how to use pulldown-cmark-frontmatter for blog post processing. Here's a list: - Easy to use - Fast - Flexible "; // Save to temp file for demo let temp_path = "/tmp/test-blog.md"; let _ = fs::write(temp_path, markdown); match process_blog_post(temp_path) { Ok(post) => { println!("Blog Post: {}", post.title); println!("Author: {}", post.metadata.author); println!("Published: {}", post.metadata.published); println!("Tags: {:?}", post.metadata.tags); println!("\nHTML Content:\n{}", post.html); } Err(e) => eprintln!("Error: {}", e), } } ``` -------------------------------- ### Indented Code Block Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/INDEX.md Shows how frontmatter extraction handles Markdown content that includes indented code blocks. ```rust use pulldown_cmark_frontmatter::{parse_with, FrontMatter}; use pulldown_cmark::Parser; let markdown_input = "---\nkey: value\n---\n // This is an indented code block\n let x = 5;\n"; let mut parser = Parser::new(markdown_input).map_with_frontmatter(|fm| { match fm { FrontMatter::Text(text) => { println!("Frontmatter found: {text}"); Some(text.to_string()) } FrontMatter::None => None, } }); // Iterate through events to ensure parsing works correctly for _event in parser { // ... } ``` -------------------------------- ### Rust FrontmatterExtractor Lifetime Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/overview.md Demonstrates correct lifetime management when creating a FrontmatterExtractor from a markdown string. The markdown string must live for the scope of the extractor. ```Rust let markdown = "# Title".to_string(); // let extractor = FrontmatterExtractor::from_markdown(&markdown); // ^ error: markdown does not live long enough // Use: let extractor = { let markdown = "# Title"; FrontmatterExtractor::from_markdown(markdown) }; ``` -------------------------------- ### Rust Example Matching CodeBlockKind Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/types.md Shows how to use a match statement to handle different CodeBlockKind variants, differentiating between indented and fenced code blocks and extracting the language from fenced blocks. ```rust use pulldown_cmark::CodeBlockKind; match kind { CodeBlockKind::Indented => println!("Indented code block (no language)"), CodeBlockKind::Fenced(lang) => println!("Fenced code block, language: {:?}", lang), } ``` -------------------------------- ### YAML Frontmatter Parsing Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/examples.md Parses Markdown content with YAML frontmatter. Requires the 'serde_yaml' and 'serde' crates. This example assumes YAML frontmatter is present. ```rust use pulldown_cmark_frontmatter::frontmatter; fn main() { let md = "--- title: Some Title --- # Some content"; let (frontmatter_str, content) = frontmatter(md.as_bytes()).unwrap(); println!("Frontmatter: {:?}", frontmatter_str); println!("Content: {}", content); } ``` -------------------------------- ### Frontmatter Lifetime Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Demonstrates how the 'a lifetime is borrowed from the event iterator, typically the markdown source string. The Frontmatter itself can be moved, but the code_block.source may borrow from the original markdown. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\n```toml\nkey = \"value\"\n```"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); // frontmatter.code_block.source borrows from markdown // As long as markdown is in scope, frontmatter is valid drop(markdown); // OK — markdown is out of scope // frontmatter.code_block.source still points to the same memory // This is safe because markdown is still allocated ``` -------------------------------- ### Create FrontmatterExtractor from Markdown String Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/FrontmatterExtractor.md This convenience constructor directly takes a Markdown string, creates a pulldown_cmark::Parser internally, and wraps it in the extractor. It's useful for simple cases where you start with raw Markdown. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Document Title\n\n```toml\nkey = \"value\"\n```\n\nContent"; let extractor = FrontmatterExtractor::from_markdown(markdown); ``` -------------------------------- ### Parse YAML Code Block Content Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Parses a YAML code block within the frontmatter. The example shows how to identify the language and suggests using `serde_yaml` for parsing. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = r###"# Doc ```yaml author: Alice tags: - a - b ```"###; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); if let Some(code) = frontmatter.code_block { if code.language.as_deref() == Some("yaml") || code.language.as_deref() == Some("yml") { // Use serde_yaml::from_str() to parse // let data: MyStruct = serde_yaml::from_str(&code.source)?; println!("YAML source:\n{}", code.source); } } ``` -------------------------------- ### FrontmatterExtractor Iterator Implementation Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/FrontmatterExtractor.md This example demonstrates how to use FrontmatterExtractor as an iterator to process Markdown events. It shows how to iterate over filtered events and access the extracted frontmatter after parsing. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::Event; let markdown = "# Title\n\n```toml\nkey = \"value\"\n```\n\n**Bold**"; let mut extractor = FrontmatterExtractor::from_markdown(markdown); // Iterate over filtered events for event in &mut extractor { match event { Event::Start(_) => println!("Start tag"), Event::End(_) => println!("End tag"), Event::Text(_) => println!("Text node"), _ => {} } } // Frontmatter is now available println!("Title: {:?}", extractor.frontmatter.unwrap().title); ``` -------------------------------- ### Handling No Title in Markdown Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Handles Markdown documents that do not start with an h1 heading. The `title` field will be `None` in such cases. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "Regular paragraph, no h1\n\nMore content"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap_or_default(); assert_eq!(frontmatter.title, None); ``` -------------------------------- ### Extract and Render HTML Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/INDEX.md Extract frontmatter and then render the remaining Markdown content as HTML. This involves using `extract_buffered` and `html::push_html`. ```rust let mut extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract_buffered(); let mut html = String::new(); html::push_html(&mut html, &mut extractor); ``` -------------------------------- ### TOML Frontmatter Example Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/frontmatter-example.md This TOML block represents frontmatter in a Markdown document. The pulldown-cmark-frontmatter crate will strip this block from the rendered output. ```toml author = "https://fosstodon.org/@ecton" last_updated_at = "2023-01-10 08:54:12-08:00" # date --rfc-3339=seconds ``` -------------------------------- ### Extracting a Simple Title Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Extracts the plain-text content of an h1 heading from the beginning of a Markdown document. Assumes the document starts with a title. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Simple Title\n\nContent"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); assert_eq!(frontmatter.title, Some("Simple Title".to_string())); ``` -------------------------------- ### Create a Frontmatter Extractor Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/INDEX.md Instantiate a `FrontmatterExtractor` from Markdown content. This is the initial step before any extraction can occur. ```rust let extractor = FrontmatterExtractor::from_markdown(markdown); ``` -------------------------------- ### Render to HTML with Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md Illustrates rendering Markdown content to HTML while preserving frontmatter information. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "---\ntitle: Rendered\n---\nThis is **bold** text."; let mut extractor = FrontmatterExtractor::new(markdown.as_bytes()); // Extract frontmatter first (optional, but good practice if you need it) if let Some(_) = extractor.extract().unwrap() { // Frontmatter is processed internally } let html = extractor.into_html(); println!("Rendered HTML: {}", html); ``` -------------------------------- ### Create Parser with Standard Options Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Construct a pulldown-cmark parser with default options and pass it to FrontmatterExtractor. This is equivalent to using `from_markdown`. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::Parser; let markdown = "# Title\n\nContent"; // Default parser (same as from_markdown) let parser = Parser::new(markdown); let extractor = FrontmatterExtractor::new(parser); ``` -------------------------------- ### Transform Events During Frontmatter Extraction Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/patterns.md This pattern allows you to transform events as they are processed, for example, by converting text to uppercase. This is useful for modifying content before further processing. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::{Parser, Event}; let markdown = "# Title\n\n```toml\nkey = \"value\"\n```\n\nContent"; let extractor = FrontmatterExtractor::from_markdown(markdown); let transformed: Vec = extractor .map(|event| match event { Event::Text(text) => Event::Text(text.to_uppercase().into()), e => e, }) .collect(); ``` -------------------------------- ### extract Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/FrontmatterExtractor.md Scans the start of the document and extracts frontmatter, consuming the extractor. It stops as soon as the frontmatter section ends, making it efficient for metadata extraction. ```APIDOC ## extract ### Description Scans the start of the document and extracts frontmatter, consuming the extractor. This method advances the underlying iterator until frontmatter detection is complete, then returns the extracted `Frontmatter`. The underlying iterator is **not** fully consumed; it stops as soon as the frontmatter section ends. ### Method Consumes `self` (extractor) ### Returns `Option>` — `Some(frontmatter)` if any title or code block was detected; `None` if the document is empty or has no h1 heading or code block. ### Example ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# My Title\n\n```json\n{\"key\": \"value\"}\n```\n\nRegular content"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract(); if let Some(fm) = frontmatter { assert_eq!(fm.title, Some(\"My Title\".to_string())); assert_eq!(fm.code_block.as_ref().unwrap().language, Some(\"json\".into())); } ``` ``` -------------------------------- ### Manually Construct Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Shows how to manually construct a Frontmatter struct using struct literal syntax when direct construction is necessary. ```rust use pulldown_cmark_frontmatter::Frontmatter; let fm = Frontmatter { title: Some("My Title".to_string()), code_block: None, }; ``` -------------------------------- ### Extract Frontmatter Without Preserving Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/patterns.md Use `extract()` to get frontmatter metadata and remove the heading from the rendered output. This is useful when the heading is only for metadata purposes. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::html; let markdown = "# Title for metadata only\n\n```json\n{\"skip\": true}\n```\n\nContent to render"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract(); // If you continue iterating, the heading is NOT in the stream // (This example doesn't iterate further, but demonstrates the point) if let Some(fm) = frontmatter { println!(\"Metadata title: {:?}\", fm.title); } ``` -------------------------------- ### Basic Parser Usage with Frontmatter Extractor Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Illustrates creating a parser with custom markdown content and then using FrontmatterExtractor to extract frontmatter, title, and code block language. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::Parser; let markdown = r"# My Document ```toml version = "1.0" ``` Here is the content. - Item 1 - Item 2 "; let parser = Parser::new(markdown); let extractor = FrontmatterExtractor::new(parser); let frontmatter = extractor.extract().unwrap(); println!("Title: {:?}", frontmatter.title); println!("Code block language: {:?}", frontmatter.code_block.as_ref().map(|cb| &cb.language)); ``` -------------------------------- ### Check Extraction Status During Iteration Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Monitor the frontmatter extraction progress during iteration by calling the `extracted()` method on the extractor. This example breaks the loop once extraction is complete. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\n```text code ```\n\nDoc"; let mut extractor = FrontmatterExtractor::from_markdown(markdown); // Poll extraction status during iteration for event in &mut extractor { if extractor.extracted() { println!("Frontmatter extraction complete"); break; } } ``` -------------------------------- ### Gracefully Handle Frontmatter Extraction Errors Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/examples.md Demonstrates how to safely extract frontmatter and handle cases where no frontmatter is found or the metadata is malformed. This is crucial for robust content processing. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; fn extract_safe(markdown: &str) -> Result<(Option, Option), String> { let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract(); match frontmatter { Some(fm) => { let code_source = fm.code_block .as_ref() .map(|cb| cb.source.to_string()); Ok((fm.title, code_source)) } None => Err("No frontmatter found".to_string()), } } fn main() { let test_cases = vec![ "# Title\n\n```toml\nkey = \"value\"\n```", "Just content, no frontmatter", "# Only a title", ]; for (i, markdown) in test_cases.iter().enumerate() { println!("Test case {}:", i + 1); match extract_safe(markdown) { Ok((title, code)) => { println!(" Title: {:?}", title); println!(" Code: {:?}", code); } Err(e) => println!(" Error: {}", e), } println!(); } } ``` -------------------------------- ### Basic Frontmatter Extraction Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md Demonstrates the fundamental usage of FrontmatterExtractor to extract frontmatter from Markdown content. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "---\ntitle: My Document\n---\n# Hello, World!"; let mut extractor = FrontmatterExtractor::new(markdown.as_bytes()); if let Some(frontmatter) = extractor.extract().unwrap() { println!("Frontmatter: {:?}", frontmatter); } else { println!("No frontmatter found."); } let html = extractor.into_html(); println!("HTML: {}", html); ``` -------------------------------- ### Parse YAML Frontmatter in Rust Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/CodeBlock.md Extracts YAML frontmatter from Markdown. This example shows how to identify YAML but defers actual parsing to a YAML library like `serde_yaml`. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = r"# Post ```yaml title: My Blog Post date: 2024-06-28 categories: - tech - rust ``` Blog content..."; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); if let Some(code_block) = frontmatter.code_block { match code_block.language.as_deref() { Some("yaml" | "yml") => { // Use a YAML library like serde_yaml // let data: MyStruct = serde_yaml::from_str(&code_block.source)?; println!("Raw YAML:\n{}", code_block.source); } _ => eprintln!("Expected YAML language identifier"), } } ``` -------------------------------- ### Instantiate FrontmatterExtractor with a Parser Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Use this method when you need to provide a custom-configured pulldown_cmark::Parser to the FrontmatterExtractor. This allows for fine-grained control over the Markdown parsing process. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::Parser; let markdown = "# Title\n\nContent"; // Minimal configuration let parser = Parser::new(markdown); let extractor = FrontmatterExtractor::new(parser); ``` -------------------------------- ### Using FrontmatterExtractor with Markdown Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/types.md Shows different ways to use `FrontmatterExtractor` with markdown content. This includes extracting only the frontmatter, iterating through events while extracting, and integrating with HTML rendering. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Document\n\n```toml\nkey = \"value\"\n```\n\nContent"; // Option 1: Extract only let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract(); // Option 2: Extract and continue iterating let mut extractor = FrontmatterExtractor::from_markdown(markdown); for event in &mut extractor { println!("Event: {:?}", event); } println!("Frontmatter: {:?}", extractor.frontmatter); // Option 3: Use with HTML rendering let mut extractor = FrontmatterExtractor::from_markdown(markdown); let mut html = String::new(); pulldown_cmark::html::push_html(&mut html, &mut extractor); let fm = &extractor.frontmatter; ``` -------------------------------- ### Extract Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/FrontmatterExtractor.md Use `extract` to scan the start of a document for frontmatter and consume the extractor. It returns `Some(frontmatter)` if found, or `None` otherwise. The iterator stops after frontmatter detection. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# My Title\n\n```json\n{\"key\": \"value\"}\n```\n\nRegular content"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract(); if let Some(fm) = frontmatter { assert_eq!(fm.title, Some("My Title".to_string())); assert_eq!(fm.code_block.as_ref().unwrap().language, Some("json".into())); } ``` -------------------------------- ### Deriving Traits for Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Demonstrates cloning and debugging the `Frontmatter` struct. Cloning involves `CowStr` which can be cheap or expensive. ```rust use pulldown_cmark_frontmatter::{FrontmatterExtractor, Frontmatter}; let markdown = "# Title"; let mut extractor = FrontmatterExtractor::from_markdown(markdown); let _ = extractor.extract_buffered(); if let Some(fm) = &extractor.frontmatter { let fm_clone = fm.clone(); // Clones the Frontmatter println!("{:?}", fm_clone); // Debug output } ``` -------------------------------- ### Access Fenced Code Block with Language Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Demonstrates how to extract and assert the language and source of a fenced code block (e.g., TOML) from Markdown frontmatter. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\n```toml\nauthor = \"Alice\"\n```\n\nContent"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); let code = frontmatter.code_block.unwrap(); assert_eq!(code.language, Some("toml".into())); assert_eq!(code.source, "author = \"Alice\"\n"); ``` -------------------------------- ### Extract and Continue Iterating with Buffering Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Use `extract_buffered()` to get the frontmatter and buffer the remaining events. This allows processing the entire document afterward, with buffered events yielded first. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\n```json {} ```\n\nContent here"; let mut extractor = FrontmatterExtractor::from_markdown(markdown); // Extract frontmatter and buffer events let frontmatter = extractor.extract_buffered().unwrap(); // Continue iterating; buffered events are returned first for event in &mut extractor { // Process events } ``` -------------------------------- ### Error Recovery and Safe Extraction Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/INDEX.md Demonstrates how to handle potential errors during frontmatter parsing and ensure safe extraction. ```rust use pulldown_cmark_frontmatter::{parse_with, FrontMatter}; use pulldown_cmark::Parser; // Example with malformed TOML let markdown_input_malformed = "---\ntitle = My Title (missing quotes)\n---\n# Malformed Example"; // Example with valid TOML let markdown_input_valid = "---\ntitle = \"Valid Title\"\n---\n# Valid Example"; fn safe_extract_frontmatter(input: &str) { let mut parser = Parser::new(input).map_with_frontmatter(|fm| { match fm { FrontMatter::Text(text) => { // Attempt to parse, returning None on error toml::from_str::(&text).ok() } FrontMatter::None => None, } }); let mut found_metadata = false; for event in parser { if let pulldown_cmark::Event::FrontMatter(metadata) = event { if metadata.is_some() { println!("Successfully extracted and parsed frontmatter."); found_metadata = true; break; } } } if !found_metadata { println!("Failed to extract or parse frontmatter safely."); } } println!("Processing malformed input:"); safe_extract_frontmatter(markdown_input_malformed); println!("\nProcessing valid input:"); safe_extract_frontmatter(markdown_input_valid); ``` -------------------------------- ### Fenced Code Block Without Language Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/CodeBlock.md Illustrates that the 'language' field is None for a fenced code block that lacks a language specifier (e.g., just ```). This example uses FrontmatterExtractor to process such markdown. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\n```\nraw code\n```"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); let code = frontmatter.code_block.unwrap(); assert_eq!(code.language, None); ``` -------------------------------- ### Use Extractor with HTML Rendering Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md Demonstrates using FrontmatterExtractor with pulldown_cmark::html::push_html after enabling the 'html' feature. It prints the generated HTML and extracted frontmatter. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::html; let markdown = "# Title\n\n```toml\nauthor = \"Alice\"\n```\n\nContent"; let mut extractor = FrontmatterExtractor::from_markdown(markdown); let mut html_output = String::new(); html::push_html(&mut html_output, &mut extractor); println!("HTML:\n{}", html_output); println!("Frontmatter: {:?}", extractor.frontmatter); ``` -------------------------------- ### Create FrontmatterExtractor with Existing Parser Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/FrontmatterExtractor.md Use this constructor when you already have a pulldown_cmark::Parser instance. It wraps the parser to enable frontmatter extraction. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::Parser; let markdown = "# Title\n\nContent"; let parser = Parser::new(markdown); let extractor = FrontmatterExtractor::new(parser); ``` -------------------------------- ### Extract and Parse TOML Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Demonstrates extracting TOML-formatted frontmatter from a Markdown string and parsing it into a Rust struct using `serde` and `toml`. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct Metadata { author: String, date: String, } let markdown = r###"# Document ```toml author = "Alice" date = "2024-06-28" ``` Content"###; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); if let Some(code) = frontmatter.code_block { let metadata: Metadata = toml::from_str(&code.source) .expect("invalid TOML in frontmatter"); println!("Author: {}", metadata.author); } ``` -------------------------------- ### Extract Frontmatter and Render HTML Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/patterns.md Use this pattern when you need both metadata and the rendered HTML of a document. `extract_buffered()` preserves the heading in the HTML output. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::html; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize)] struct Metadata { author: String, date: String, } let markdown = "# My Article\n\n```toml\nauthor = \"Alice\"\ndate = \"2024-06-28\"\n```\n\nArticle content here."; let mut extractor = FrontmatterExtractor::from_markdown(markdown); // Extract frontmatter and buffer events let frontmatter = extractor.extract_buffered(); // Render to HTML (includes buffered heading) let mut html_output = String::new(); html::push_html(&mut html_output, &mut extractor); // Process metadata if let Some(fm) = frontmatter { if let Some(code) = &fm.code_block { let metadata: Metadata = toml::from_str(&code.source)?; println!("Author: {}", metadata.author); println!("HTML:\n{}", html_output); } } ``` -------------------------------- ### Handling Extracted Frontmatter with Default Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md This snippet shows how to use Option::unwrap_or_default with a helper to provide a default Frontmatter if extraction fails. ```rust let frontmatter = extractor.extract().unwrap_or(Frontmatter { title: None, code_block: None, }); ``` -------------------------------- ### Extract and Manually Parse Custom Format Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Illustrates extracting frontmatter with a custom code block language and manually parsing its content line by line. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = r###"# Document ```custom key1: value1 key2: value2 ``` Content"###; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); if let Some(code) = frontmatter.code_block { // Parse custom format manually for line in code.source.lines() { let parts: Vec<&str> = line.split(':').collect(); // Process parts... } } ``` -------------------------------- ### Extract and Parse JSON Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Shows how to extract JSON-formatted frontmatter from Markdown and parse it into a `serde_json::Value`. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use serde_json::json; let markdown = r###"# Document ```json {"author": "Alice", "tags": ["rust", "parser"]} ``` Content"###; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); if let Some(code) = frontmatter.code_block { let metadata = serde_json::from_str::(&code.source) .expect("invalid JSON"); println!("Author: {}", metadata["author"]); } ``` -------------------------------- ### Handle Markdown with No Code Block Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/Frontmatter.md Demonstrates how to handle Markdown content that does not contain a frontmatter code block, resulting in `None` for the `code_block` field. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Title\n\nContent starts immediately"; let extractor = FrontmatterExtractor::from_markdown(markdown); let frontmatter = extractor.extract().unwrap(); assert_eq!(frontmatter.code_block, None); ``` -------------------------------- ### Debug CodeBlock Instance Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/CodeBlock.md Shows how to print a CodeBlock instance using the debug formatter. This is useful for inspecting the source and language of a code block. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let extractor = FrontmatterExtractor::from_markdown("# Title\n\n```toml\nkey=\"value\"\n```"); let frontmatter = extractor.extract().unwrap(); let code_block = frontmatter.code_block.unwrap(); println!("{:#?}", code_block); // Output: // CodeBlock { // source: "key=\"value\"\n", // language: Some( // "toml", // ), // } ``` -------------------------------- ### Batch Process Markdown Documents for Metadata in Rust Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/patterns.md This pattern is useful for indexing metadata from multiple markdown files. It defines a struct to hold document metadata and a function to extract title and language from frontmatter. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use std::path::Path; use std::fs; struct DocumentMetadata { path: String, title: Option, language: Option, } fn extract_metadata_from_file(path: &Path) -> Result> { let content = fs::read_to_string(path)?; let extractor = FrontmatterExtractor::from_markdown(&content); let frontmatter = extractor.extract(); let (title, language) = match frontmatter { Some(fm) => ( fm.title, fm.code_block.as_ref().and_then(|cb| cb.language.as_ref().map(|l| l.to_string())) ), None => (None, None), }; Ok(DocumentMetadata { path: path.to_string_lossy().to_string(), title, language, }) } // Index multiple documents let documents = vec![ "docs/intro.md", "docs/guide.md", "docs/reference.md", ]; for doc_path in documents { match extract_metadata_from_file(Path::new(doc_path)) { Ok(metadata) => { println!("File: {}", metadata.path); println!(" Title: {:?}", metadata.title); println!(" Language: {:?}", metadata.language); } Err(e) => eprintln!("Error processing {}: {}", doc_path, e), } } ``` -------------------------------- ### Parse JSON Frontmatter Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/examples.md Extracts JSON frontmatter from a markdown string and demonstrates parsing it using serde_json. Requires the `serde_json` crate. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use serde_json::json; fn main() { let markdown = r"# Document ```json { "title": "Parsed Title", "author": "Charlie", "tags": ["example", "json"], "config": { "published": true, "views": 100 } } ``` Content here. "; ``` -------------------------------- ### Configure Cargo.toml for HTML Feature Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/configuration.md To enable HTML rendering with the extractor, add the 'html' feature to the pulldown-cmark dependency in your Cargo.toml. ```toml [dependencies] pulldown-cmark = { version = "0.12", features = ["html"] } pulldown-cmark-frontmatter = "0.4" ``` -------------------------------- ### Parse TOML Metadata Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md Shows how to parse TOML formatted metadata extracted from Markdown frontmatter. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use toml::Value; let markdown = "---\ntitle = \"TOML Example\"\nauthor = \"Jane Doe\"\n---\n# Content"; let mut extractor = FrontmatterExtractor::new(markdown.as_bytes()); if let Some(frontmatter) = extractor.extract().unwrap() { let toml_value: Value = frontmatter.parse().unwrap(); println!("TOML Metadata: {:?}", toml_value); } else { println!("No frontmatter found."); } ``` -------------------------------- ### Multiple Format Dispatch Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md Shows how the extractor can handle different frontmatter formats like TOML, JSON, and YAML. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; // Example with TOML let markdown_toml = "---\ntitle = \"TOML Example\"\n---\nContent."; let mut extractor_toml = FrontmatterExtractor::new(markdown_toml.as_bytes()); if let Some(fm) = extractor_toml.extract().unwrap() { println!("TOML FM: {:?}", fm); } // Example with JSON let markdown_json = "---\n{\"title\": \"JSON Example\"}\n---\nContent."; let mut extractor_json = FrontmatterExtractor::new(markdown_json.as_bytes()); if let Some(fm) = extractor_json.extract().unwrap() { println!("JSON FM: {:?}", fm); } // Example with YAML let markdown_yaml = "---\ntitle: YAML Example\n---\nContent."; let mut extractor_yaml = FrontmatterExtractor::new(markdown_yaml.as_bytes()); if let Some(fm) = extractor_yaml.extract().unwrap() { println!("YAML FM: {:?}", fm); } ``` -------------------------------- ### Iterating Through Markdown Events Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/types.md Demonstrates how to iterate through markdown parsing events using FrontmatterExtractor. This is useful for custom event handling or debugging. ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; use pulldown_cmark::Event; let markdown = "# Title\n\nContent"; let mut extractor = FrontmatterExtractor::from_markdown(markdown); for event in &mut extractor { match event { Event::Start(_) => println!("Start tag"), Event::Text(text) => println!("Text: {}", text), _ => {} } } ``` -------------------------------- ### Title Only (No Code Block) Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/MANIFEST.md Illustrates a scenario where only a title is present in the frontmatter, without a code block. ```Rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "---\ntitle: Only Title\n---\nContent here."; let mut extractor = FrontmatterExtractor::new(markdown.as_bytes()); if let Some(frontmatter) = extractor.extract().unwrap() { println!("Frontmatter: {:?}", frontmatter); } else { println!("No frontmatter found."); } let html = extractor.into_html(); println!("HTML: {}", html); ``` -------------------------------- ### FrontmatterExtractor::from_markdown Source: https://github.com/khonsulabs/pulldown-cmark-frontmatter/blob/main/_autodocs/api-reference/FrontmatterExtractor.md A convenience constructor that simplifies the creation of a FrontmatterExtractor by internally creating a pulldown_cmark::Parser from a Markdown string. ```APIDOC ## FrontmatterExtractor::from_markdown ### Description Convenience constructor that creates a `pulldown_cmark::Parser` and wraps it in an extractor. This is useful for quick setup when you have a Markdown string. ### Method `from_markdown` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **markdown** (`&'a str`) - Required - The Markdown source string. Must outlive the returned extractor. ### Returns - `Self` — a new `FrontmatterExtractor` with a default parser ### Example ```rust use pulldown_cmark_frontmatter::FrontmatterExtractor; let markdown = "# Document Title\n\n```toml\nkey = \"value\"\n```\n\nContent"; let extractor = FrontmatterExtractor::from_markdown(markdown); ``` ### Note This method is only available when `T` is `pulldown_cmark::Parser<'a, DefaultBrokenLinkCallback>`. It is a specialization of `new()` that handles parser creation internally. ```