markdown-it-rust / markdown-it

markdown-it js library rewritten in rust
Other
79 stars 9 forks source link

Add headings with IDs plugin #9

Closed lucperkins closed 1 year ago

lucperkins commented 1 year ago

I've been enjoying this library a bunch recently so I thought I'd contribute an example as thanks. I'm not sure how idiomatic this implementation is but I think it provides a decent real-world use case.

rlidwka commented 1 year ago

Thanks, that is indeed a real-world use case.

Should it be an example, or just a plugin (in extras, like syntax highlighting is now)? For markdown-it we have https://github.com/valeriangalliat/markdown-it-anchor, maybe it's useful to add a plugin with similar api.

lucperkins commented 1 year ago

@rlidwka I'm certainly happy to make it a plugin would be happy to update the API to be a bit more robust à la markdown-it-anchor!

Update: actually it looks like passing in configuration to plugins may not be possible, unless I'm mistaken.

Update number 2: okay, never mind, I see from the Syntect plugin how to pass configuration 🤣

ShafSpecs commented 1 year ago

@lucperkins any update to this PR? As mentioned, it's a great real life implementation that would be nice to have

rlidwka commented 1 year ago

I've implemented it from scratch in #18, it's actually much simpler than proposed here (e.g. no new tags are required, you can push attributes into existing ones).

Not completely sure we need it, since you can copy-paste it into your own project. This is the entire thing:

use markdown_it::parser::core::CoreRule;
use markdown_it::plugins::cmark::block::heading::ATXHeading;
use markdown_it::plugins::cmark::block::lheading::SetextHeader;
use markdown_it::{MarkdownIt, Node};

fn main() {
    let md = &mut MarkdownIt::new();
    markdown_it::plugins::cmark::add(md);

    md.add_rule::<AddHeadingAnchors>();

    pub struct AddHeadingAnchors;
    impl CoreRule for AddHeadingAnchors {
        fn run(root: &mut Node, _md: &MarkdownIt) {
            root.walk_mut(|node, _| {
                if node.is::<ATXHeading>() || node.is::<SetextHeader>() {
                    // collect_text() is new api proposed in #18
                    node.attrs.push(("id", slug::slugify(node.collect_text())));
                }
            });
        }
    }

    dbg!(md.parse("## An example heading").render());
}
rlidwka commented 1 year ago

published as 0.5.0, closing as resolved