cmark-writer
A CommonMark writer implementation in Rust.
Basic Usage
use ;
use CommonMarkWriter;
use ToCommonMark;
// Create a document
let document = Document;
// Render to CommonMark
let mut writer = new;
document.to_commonmark.expect;
let markdown = writer.into_string;
println!;
Custom Options
use WriterOptionsBuilder;
use CommonMarkWriter;
// Use builder pattern for custom options
let options = new
.strict
.hard_break_spaces
.indent_spaces
.build;
let mut writer = with_options;
Table Support
use ;
// Create tables with the builder pattern
let table = new
.headers
.add_row
.add_row
.build;
GitHub Flavored Markdown (GFM)
Enable GFM features by adding to your Cargo.toml:
[]
= { = "0.7.0", = ["gfm"] }
GFM Support:
- Tables with column alignment
- Strikethrough text
- Task lists
- Extended autolinks
- HTML element filtering
HTML Writing
The library provides dedicated HTML writing capabilities through the HtmlWriter class:
use ;
// Create HTML writer with custom options
let options = HtmlWriterOptions ;
let mut writer = with_options;
// Write some nodes
let paragraph = Paragraph;
paragraph.to_html.unwrap;
// Get resulting HTML
let html = writer.into_string;
assert_eq!;
Custom Nodes
The recommended way to build custom nodes is via standard Rust traits. Implement Format for each writer you want to support, and optionally MultiFormat for capability checks and HTML fallback.
use ;
use ;
use EcoString;
// Inline custom node with CommonMark + HTML implementations
// Block-level custom node example
// Only CommonMark support with graceful HTML fallback
// Usage
let highlight = HighlightNode ;
let mut md = new;
let mut html = new;
highlight.to_commonmark.unwrap;
highlight.to_html.unwrap;
assert!;
Simplified Custom Nodes with Derive Macro
For custom nodes that only support CommonMark output, you can use the #[derive(CommonMarkOnly)] macro to automatically implement the MultiFormat trait with appropriate defaults:
use ;
use ;
use EcoString;
// Simple custom node with automatic MultiFormat implementation for CommonMark-only nodes
// Only implement CommonMark format
// Usage - MultiFormat methods are automatically available
let note = SimpleNote ;
// Check format support
assert!; // Returns false since only CommonMark is implemented
// CommonMark rendering works as expected
let mut md = new;
note.to_commonmark.unwrap;
assert_eq!;
// HTML rendering provides a helpful fallback comment
let mut html = new;
note.html_format.unwrap;
assert!;
The CommonMarkOnly derive macro automatically provides:
supports_html()method that returnsfalsehtml_format()method that outputs a helpful comment indicating HTML is not supported- No need to manually implement
MultiFormattrait for CommonMark-only custom nodes
Note: This macro is specifically for nodes that only support CommonMark. For nodes that support both CommonMark and HTML formats, implement both Format<CommonMarkWriter> and Format<HtmlWriter>, and the MultiFormat trait will be automatically implemented through the blanket implementation.
This approach provides:
- Type safety and clear format boundaries
- Easy extensibility for new formats
- Consistent, idiomatic Rust traits across the API
Custom Error Handling
The library provides convenient macros for creating structured custom errors:
use ;
// Structure error - for invalid document structure
;
// Coded error - for custom errors with error codes
;
// Usage examples
// Convert to standard WriteError
let write_err: WriteError = TableColumnMismatchError.into;
assert!;
The error macros provide:
#[structure_error]: For document structure validation errors#[coded_error]: For custom errors with error codes and messages- Automatic conversion to
WriteErrortypes - Consistent error formatting and display
Development
# Build
# Run tests
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Feel free to submit a Pull Request.