Skip to content

Commit

Permalink
Update markdown crate and use = version specifier
Browse files Browse the repository at this point in the history
Also clean up some formatting in conversion code.
  • Loading branch information
Bromeon committed Sep 24, 2024
1 parent eeec4d1 commit d8264bd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 16 deletions.
2 changes: 1 addition & 1 deletion godot-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ proc-macro2 = "1.0.80" # Literal::c_string() added in 1.0.80.
quote = "1.0.29"

# Enabled by `docs`
markdown = { version = "1.0.0-alpha.19", optional = true }
markdown = { version = "=1.0.0-alpha.21", optional = true }
venial = "0.6"

[build-dependencies]
Expand Down
47 changes: 32 additions & 15 deletions godot-macros/src/docs/markdown_converter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,53 @@

//! Converts [Markdown](https://en.wikipedia.org/wiki/Markdown) to [BBCode](https://en.wikipedia.org/wiki/BBCode).

use markdown::mdast::Node;
use markdown::mdast as md;
use markdown::{to_mdast, ParseOptions};
use std::collections::HashMap;

pub fn to_bbcode(md: &str) -> String {
// to_mdast() never errors with normal arkdown, so unwrap is safe.
// to_mdast() never errors with normal Markdown, so unwrap is safe.
let n = to_mdast(md, &ParseOptions::gfm()).unwrap();

let definitions = n
.children()
.unwrap() // root node always has children
.iter()
.filter_map(|n| match n {
Node::Definition(definition) => Some((&*definition.identifier, &*definition.url)),
md::Node::Definition(def) => Some((&*def.identifier, &*def.url)),
_ => None,
})
.collect::<HashMap<_, _>>();

walk_node(&n, &definitions).unwrap_or_default()
}

fn walk_node(node: &Node, definitions: &HashMap<&str, &str>) -> Option<String> {
use Node::*;
fn walk_node(node: &md::Node, definitions: &HashMap<&str, &str>) -> Option<String> {
use md::Node::*;

let bbcode = match node {
Root(root) => walk_nodes(&root.children, definitions, "[br][br]"),
InlineCode(markdown::mdast::InlineCode { value, .. }) => format!("[code]{value}[/code]"),

InlineCode(md::InlineCode { value, .. }) => format!("[code]{value}[/code]"),

Delete(delete) => format!("[s]{}[/s]", walk_nodes(&delete.children, definitions, "")),

Emphasis(emphasis) => format!("[i]{}[/i]", walk_nodes(&emphasis.children, definitions, "")),
Image(markdown::mdast::Image { url, .. }) => format!("[img]{url}[/img]",),

Image(md::Image { url, .. }) => format!("[img]{url}[/img]",),

ImageReference(image) => {
format!(
"[img]{}[/img]",
definitions.get(&&*image.identifier).unwrap()
)
}
Link(markdown::mdast::Link { url, children, .. }) => {

Link(md::Link { url, children, .. }) => {
format!("[url={url}]{}[/url]", walk_nodes(children, definitions, ""))
}
LinkReference(markdown::mdast::LinkReference {

LinkReference(md::LinkReference {
identifier,
children,
..
Expand All @@ -53,23 +62,31 @@ fn walk_node(node: &Node, definitions: &HashMap<&str, &str>) -> Option<String> {
definitions.get(&&**identifier).unwrap(),
walk_nodes(children, definitions, "")
),

Strong(strong) => format!("[b]{}[/b]", walk_nodes(&strong.children, definitions, "")),

Text(text) => text.value.clone(),

// TODO: more langs?
Code(markdown::mdast::Code { value, .. }) => format!("[codeblock]{value}[/codeblock]"),
Code(md::Code { value, .. }) => format!("[codeblock]{value}[/codeblock]"),

Paragraph(paragraph) => walk_nodes(&paragraph.children, definitions, ""),
// bbcode supports lists but docs dont
List(_) | BlockQuote(_) | FootnoteReference(_) | FootnoteDefinition(_) | Table(_) => {
"".into()

// BBCode supports lists, but docs don't.
List(_) | Blockquote(_) | FootnoteReference(_) | FootnoteDefinition(_) | Table(_) => {
String::new()
}

Html(html) => html.value.clone(),

_ => walk_nodes(&node.children()?, definitions, ""),
};

Some(bbcode)
}

/// Calls [`walk_node`] over every node its given, joining them with the supplied separator.
fn walk_nodes(nodes: &[Node], definitions: &HashMap<&str, &str>, separator: &str) -> String {
/// Calls [`walk_node`] over every node it receives, joining them with the supplied separator.
fn walk_nodes(nodes: &[md::Node], definitions: &HashMap<&str, &str>, separator: &str) -> String {
nodes
.iter()
.filter_map(|n| walk_node(n, definitions))
Expand Down

0 comments on commit d8264bd

Please sign in to comment.