An ergonomic library for manipulating markdown documents.

There are two fundamental concepts in markedit ,

Matcher - something which can match an Event from pulldown-cmark (typically implemented using state machines or simple functions)

- something which can match an from pulldown-cmark (typically implemented using state machines or simple functions) Rewriter - something which can rewrite part of a stream of Event s (typically just a function)

Together we can use these to transform a stream of Event s on the fly with minimal overhead.

The use case which prompted this entire library was to insert arbitrary markdown after a heading.

use pulldown_cmark ::{ Event , Tag }; use markedit ::{ Matcher , Heading }; let src = "# Heading

Some text

some more text



# Another Heading" ; let matcher = Heading :: with_level ( 1 ). falling_edge (); let rule = markedit :: insert_markdown_before ( "## Sub-Heading" , matcher ); let events = markedit :: parse ( src ); let mutated : Vec < _ > = markedit :: rewrite ( events , rule ). collect (); assert_eq ! ( mutated [ 1 ], Event :: Text ( "Heading" . into ())); assert_eq ! ( mutated [ 3 ], Event :: Start ( Tag :: Heading ( 2 ))); assert_eq ! ( mutated [ 4 ], Event :: Text ( "Sub-Heading" . into ())); assert_eq ! ( mutated [ 5 ], Event :: End ( Tag :: Heading ( 2 ))); assert_eq ! ( mutated [ 7 ], Event :: Text ( "Some text" . into ()));

You can also use change_text() to upper-case text based on a predicate (e.g. the text contains a certain keyword).

use pulldown_cmark :: Event ; let src = "# Heading

Some text

some more text



# Another Heading" ; let rule = markedit :: change_text ( | text | text . contains ( "Heading" ), | text | text . to_uppercase (), ); let events_before : Vec < _ > = markedit :: parse ( src ). collect (); assert_eq ! ( events_before [ 1 ], Event :: Text ( "Heading" . into ())); assert_eq ! ( events_before [ 9 ], Event :: Text ( "Another Heading" . into ())); let events_after : Vec < _ > = markedit :: rewrite ( events_before , rule ) . collect (); println ! ( "{:?}" , events_after ); assert_eq ! ( events_after [ 1 ], Event :: Text ( "HEADING" . into ())); assert_eq ! ( events_after [ 9 ], Event :: Text ( "ANOTHER HEADING" . into ()));