-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Render back to markdown #30
Comments
Heya, so no I don't believe there is currently a "Markdown Renderer" for markdown-it.rs. If someone is to create one, I would suggest having a look at https://github.com/executablebooks/mdformat, which is effectively the equivalent for https://github.com/executablebooks/markdown-it-py This does bring up another issue I was going to open, which is what is the best way to implement renderers? The HTML renderer (https://github.com/rlidwka/markdown-it.rs/blob/master/src/parser/renderer.rs) effectively holds a "priviledged" position, since But for rendering to e.g. Markdown, JSON, ..., I'm not sure what the best practice way would be? |
For example, this is something I was playing around with for rendering to https://github.com/syntax-tree/mdast But obviously it means you have to make sure to add every possible node type that you want to render, and there is some boilerplate use std::any::TypeId;
use markdown_it::*;
use serde_json::{json, Value};
pub struct Config;
pub trait RenderMdastNode {
fn render_mdast(&self, config: &Config) -> Value;
}
impl RenderMdastNode for Node {
fn render_mdast(&self, config: &Config) -> Value {
macro_rules! render_node {
($node_type:ty) => {
self.node_value
.downcast_ref::<$node_type>()
.unwrap()
.to_mdast(self, config)
};
}
match self.node_type.id {
id if id == TypeId::of::<Root>() => render_node!(Root),
id if id == TypeId::of::<Paragraph>() => render_node!(Paragraph),
id if id == TypeId::of::<Text>() => render_node!(Text),
// ...
_ => unimplemented!("node type not implemented: {:?}", self.node_type)
}
}
}
trait RenderMdast: NodeValue {
fn to_mdast(&self, node: &Node, config: &Config) -> Value;
fn create_children(&self, node: &Node, config: &Config) -> Vec<Value> {
return node
.children
.iter()
.map(|child| child.render_mdast(config))
.collect::<Vec<Value>>();
}
}
impl RenderMdast for Root {
fn to_mdast(&self, node: &Node, config: &Config) -> Value {
json!({
"type": "root",
"children": self.create_children(node, config),
})
}
}
impl RenderMdast for Paragraph {
fn to_mdast(&self, node: &Node, config: &Config) -> Value {
json!({
"type": "paragraph",
"children": self.create_children(node, config),
})
}
}
impl RenderMdast for Text {
fn to_mdast(&self, _: &Node, _: &Config) -> Value {
json!({
"type": "text",
"value": self.content,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_render() {
let md = &mut markdown_it::MarkdownIt::new();
markdown_it::plugins::cmark::add(md);
md.parse("hallo").render_mdast(&Config);
}
} |
@chrisjsewell, your assessment above is correct. As of now, you can override Renderer to render slightly differently (e.g. html vs xhtml). But there is no good way to implement rendering into something that's not html-like. What are use-cases for this? Render back into markdown and... anything else? |
Well in theory, anything that pandoc can output 😅 But I think at a "minimum"; a round-trip (i.e. Markdown) renderer, a programming language agnostic (e.g. JSON) AST renderer |
The use case is to parse the source markdown syntax, transform the AST based on any number of rules/replacements/special markup syntax, then output valid common mark markdown. Nothing other than that. There do not seem to be too many Rust crates which are capable of this. |
I have a use case where I wish to write a markdown parser that converts
[[Wiki Style Links]]
into valid common mark links E.g.[Wiki Style Links]({generated_source_url}]
.Reading the docs and source code it does not seem possible to parse some Markdown source, do AST processing, and output a new Markdown source at a String/str.
Is my understanding correct? Also perhaps @chrisjsewell might know how to do this as they've written several plugins for this crate over at (https://github.com/chrisjsewell/markdown-it-plugins.rs)
The text was updated successfully, but these errors were encountered: