Markdown upgrades
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
use emojis::Emoji;
|
||||
use markdown_it::parser::inline::{InlineRule, InlineState};
|
||||
use markdown_it::{Node, NodeValue, Renderer};
|
||||
use maud::{Markup, PreEscaped, Render};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::components::fa::FAIcon;
|
||||
use crate::components::mangle::{MangledBetaEmail, MangledGoogleEmail};
|
||||
|
||||
pub struct Markdown<'a>(pub &'a str);
|
||||
|
||||
@@ -26,11 +29,11 @@ impl Render for Markdown<'_> {
|
||||
//
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InlineEmote(&'static Emoji);
|
||||
pub struct InlineEmote(String);
|
||||
|
||||
impl NodeValue for InlineEmote {
|
||||
fn render(&self, _node: &Node, fmt: &mut dyn Renderer) {
|
||||
fmt.text(self.0.as_str());
|
||||
fmt.text_raw(self.0.as_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,9 +48,21 @@ impl InlineRule for InlineEmote {
|
||||
}
|
||||
|
||||
let end_idx = input[1..].find(':')? + 1;
|
||||
let emote = emojis::get_by_shortcode(&input[1..end_idx])?;
|
||||
let code = &input[1..end_idx];
|
||||
|
||||
Some((Node::new(InlineEmote(emote)), end_idx + 1))
|
||||
let mut emote = None;
|
||||
|
||||
if emote.is_none()
|
||||
&& let Some(code) = code.strip_prefix("fa-")
|
||||
{
|
||||
emote = FAIcon::from_str(code).ok().map(|x| x.render().0)
|
||||
}
|
||||
|
||||
if emote.is_none() {
|
||||
emote = emojis::get_by_shortcode(code).map(|x| x.to_string());
|
||||
}
|
||||
|
||||
Some((Node::new(InlineEmote(emote?)), end_idx + 1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,6 +75,10 @@ impl NodeValue for InlineMdx {
|
||||
return;
|
||||
}
|
||||
|
||||
if mdx_include(&self.0, node, fmt) {
|
||||
return;
|
||||
}
|
||||
|
||||
fmt.open("code", &[]);
|
||||
fmt.text(&self.0);
|
||||
fmt.close("code");
|
||||
@@ -101,35 +120,39 @@ impl InlineRule for InlineMdx {
|
||||
}
|
||||
|
||||
fn mdx_style(mdx: &str, _node: &Node, fmt: &mut dyn Renderer) -> bool {
|
||||
let mdx = mdx.trim();
|
||||
|
||||
if !mdx.starts_with("style(") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let skip = 6;
|
||||
let mut balance = 1;
|
||||
let mut end = skip;
|
||||
for i in mdx[skip..].bytes() {
|
||||
match i {
|
||||
b')' => balance -= 1,
|
||||
b'(' => balance += 1,
|
||||
_ => {}
|
||||
// Parse inside of mdx: `style(<style>) <content>`
|
||||
let (style, content) = {
|
||||
let mdx = mdx.trim();
|
||||
if !mdx.starts_with("style(") {
|
||||
return false;
|
||||
}
|
||||
|
||||
if balance == 0 {
|
||||
break;
|
||||
let skip = 6;
|
||||
let mut balance = 1;
|
||||
let mut end = skip;
|
||||
for i in mdx[skip..].bytes() {
|
||||
match i {
|
||||
b')' => balance -= 1,
|
||||
b'(' => balance += 1,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if balance == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
end += 1;
|
||||
}
|
||||
|
||||
end += 1;
|
||||
}
|
||||
if balance != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
if balance != 0 {
|
||||
return false;
|
||||
}
|
||||
let style = mdx[skip..end].trim();
|
||||
let content = mdx[end + 1..].trim();
|
||||
|
||||
let style = &mdx[skip..end].trim();
|
||||
let content = &mdx[end + 1..].trim();
|
||||
(style, content)
|
||||
};
|
||||
|
||||
let mut style_str = String::new();
|
||||
|
||||
@@ -162,9 +185,60 @@ fn mdx_style(mdx: &str, _node: &Node, fmt: &mut dyn Renderer) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
// Only works with text, could be reworked to do basic md styling
|
||||
// (italics, bold, tab, code)
|
||||
fmt.open("span", &[("style", style_str)]);
|
||||
fmt.text(&content);
|
||||
fmt.close("span");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
fn mdx_include(mdx: &str, _node: &Node, fmt: &mut dyn Renderer) -> bool {
|
||||
// Parse inside of mdx: `include(<args>)`
|
||||
let args = {
|
||||
let mdx = mdx.trim();
|
||||
if !mdx.starts_with("include(") {
|
||||
return false;
|
||||
}
|
||||
|
||||
let skip = 8;
|
||||
let mut balance = 1;
|
||||
let mut end = skip;
|
||||
for i in mdx[skip..].bytes() {
|
||||
match i {
|
||||
b')' => balance -= 1,
|
||||
b'(' => balance += 1,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if balance == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
end += 1;
|
||||
}
|
||||
|
||||
if balance != 0 {
|
||||
return false;
|
||||
}
|
||||
|
||||
let args = mdx[skip..end].trim();
|
||||
let trail = mdx[end + 1..].trim();
|
||||
if trail != "" {
|
||||
return false;
|
||||
}
|
||||
|
||||
args
|
||||
};
|
||||
|
||||
let str = match args {
|
||||
"email_beta" => MangledBetaEmail {}.render().0,
|
||||
"email_goog" => MangledGoogleEmail {}.render().0,
|
||||
_ => return false,
|
||||
};
|
||||
|
||||
fmt.text_raw(&str);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user