use pulldown_cmark::{Event, Options, Parser};
fn parser_options() -> Options {
Options::ENABLE_TABLES | Options::ENABLE_STRIKETHROUGH | Options::ENABLE_HEADING_ATTRIBUTES
}
#[cfg(test)]
pub(crate) fn round_trip(content: &str) -> Option<String> {
serialize(parse(content))
}
pub(crate) fn parse(content: &str) -> Vec<Event<'_>> {
Parser::new_ext(content, parser_options()).collect()
}
fn serializer_options() -> pulldown_cmark_to_cmark::Options<'static> {
pulldown_cmark_to_cmark::Options {
increment_ordered_list_bullets: true,
..Default::default()
}
}
pub(crate) fn serialize(events: Vec<Event>) -> Option<String> {
let mut output = String::new();
pulldown_cmark_to_cmark::cmark_with_options(
events.into_iter(),
&mut output,
serializer_options(),
)
.ok()?;
Some(output)
}
#[cfg(test)]
mod tests {
use super::*;
use pulldown_cmark::TagEnd;
#[test]
fn round_trip_preserves_plain_text() {
assert_eq!(round_trip("hello world").unwrap(), "hello world");
}
#[test]
fn round_trip_preserves_table_cells() {
let input = "| a | b |\n| --- | --- |\n| 1 | 2 |\n";
let output = round_trip(input).unwrap();
for token in ["a", "b", "1", "2"] {
assert!(output.contains(token), "missing {token:?} in {output:?}");
}
}
#[test]
fn serialize_tolerates_a_structurally_invalid_event_stream() {
let events = vec![Event::End(TagEnd::Emphasis)];
assert!(serialize(events).is_some());
}
#[test]
fn round_trip_of_empty_content_is_empty() {
assert_eq!(round_trip("").unwrap(), "");
}
#[test]
fn renumbers_an_out_of_order_ordered_list_sequentially() {
let output = round_trip("1. a\n5. b\n3. c\n").unwrap();
assert_eq!(output, "1. a\n2. b\n3. c");
}
#[test]
fn renumbers_a_same_number_ordered_list_sequentially() {
let output = round_trip("1. a\n1. b\n1. c\n").unwrap();
assert_eq!(output, "1. a\n2. b\n3. c");
}
#[test]
fn preserves_an_already_sequential_lists_start_value() {
let output = round_trip("5. a\n6. b\n7. c\n").unwrap();
assert_eq!(output, "5. a\n6. b\n7. c");
}
#[test]
fn numbers_a_nested_ordered_list_independently_of_its_parent() {
let output = round_trip("1. a\n 1. x\n 3. y\n2. b\n").unwrap();
assert_eq!(output, "1. a\n 1. x\n 2. y\n2. b");
}
}