wooorm / markdown-rs

CommonMark compliant markdown parser in Rust with ASTs and extensions
https://docs.rs/markdown/1.0.0-alpha.18/markdown/
MIT License
836 stars 41 forks source link

Add support for nested fenced code blocks #119

Closed nokome closed 4 days ago

nokome commented 4 days ago

First, thanks for this crate! (and more generally all the awesome work you do to help developers parse Markdown! 🙌🏽 )

In my usage, I need to handle nested fenced code blocks, but as the follow test shows, this is currently not supported. If you think this would be a good thing to support let me know and I can have a go at a PR.

use common_dev::pretty_assertions::assert_eq;
use markdown::{
    mdast::{Code, Node},
    to_mdast, ParseOptions,
};

#[test]
fn nested_code_block() {
    let options = ParseOptions::gfm();

    let mdast = to_mdast(
        r#"
```md

First code block

````python
# Nested code block
"#,
        &options,
    )
    .unwrap();

    match mdast.children().unwrap().first().unwrap() {
        Node::Code(Code { lang, value, .. }) => {
            assert_eq!(lang.as_deref(), Some("md"));
            // This currently passes but it shouldn't: the python code block is truncated
            assert_eq!(
                value,
                "
First code block

````python
# Nested code block"
            );
        }
        _ => assert!(false, "unexpected node type"),
    }
}
ChristianMurphy commented 4 days ago

Welcome @nokome! 👋 It is supported, the syntax is different from what you are trying. It needs to have a descending number of backticks. Larger on the outside smaller on the inside.

````md

First code block

```python
# Nested code block
nokome commented 4 days ago

Thanks @ChristianMurphy for the quick response! That syntax is a little more awkward to implement for my use case but great to know it is supported.

ChristianMurphy commented 4 days ago

I assume your use case is wanting to use markdown. The markdown crate, follows the markdown standard https://commonmark.org/ Descending number of backticks is how nesting code works in markdown.

If your use case includes making yet another markdown flavor, see https://github.com/wooorm/markdown-rs/issues/32 for work toward plugins and syntax extensions.

wooorm commented 4 days ago

Sticking with standards (in this case, CommonMark/GFM), means that your markdown files will work everywhere. Here on GH too. And in the syntax highlighter in your editor. Going with a non-standard format would mean the content is not so portable!