add: near perfect metadata compatibility

This commit is contained in:
trisua 2025-07-21 22:28:43 -04:00
parent b505199492
commit f8dac8f491
8 changed files with 434 additions and 22 deletions

View file

@ -1,3 +1,188 @@
use std::collections::HashSet;
pub fn render_markdown(input: &str) -> String {
tetratto_shared::markdown::render_markdown(input, false)
let html = tetratto_shared::markdown::render_markdown_dirty(&parse_text_color(
&parse_highlight(input),
));
let mut allowed_attributes = HashSet::new();
allowed_attributes.insert("id");
allowed_attributes.insert("class");
allowed_attributes.insert("ref");
allowed_attributes.insert("aria-label");
allowed_attributes.insert("lang");
allowed_attributes.insert("title");
allowed_attributes.insert("align");
allowed_attributes.insert("src");
allowed_attributes.insert("style");
tetratto_shared::markdown::clean_html(html, allowed_attributes)
}
fn parse_text_color_line(output: &mut String, buffer: &mut String, line: &str) {
let mut in_color_buffer = false;
let mut in_main_buffer = false;
let mut color_buffer = String::new();
let mut close_1 = false;
for char in line.chars() {
if close_1 && char != '%' {
// we expected to see another percentage to close the main buffer,
// not getting that means this wasn't meant to be a color
buffer.push('%');
in_main_buffer = false;
close_1 = false;
}
match char {
'%' => {
if in_color_buffer {
in_color_buffer = false;
in_main_buffer = true;
continue;
}
if in_main_buffer {
// ending
if !close_1 {
close_1 = true;
continue;
}
// by this point, we have: !
// %color_buffer%main_buffer%%
output.push_str(&format!(
"<span style=\"color: {color_buffer}\">{buffer}</span>\n"
));
color_buffer.clear();
buffer.clear();
// ...
in_main_buffer = false;
close_1 = false;
continue;
}
// start
// flush buffer
output.push_str(&buffer);
buffer.clear();
// toggle open
in_color_buffer = true;
}
' ' => {
if in_color_buffer == true {
buffer.push_str(&color_buffer);
color_buffer.clear();
}
buffer.push(char);
}
_ => {
if in_color_buffer {
color_buffer.push(char)
} else {
buffer.push(char)
}
}
}
}
}
fn parse_highlight_line(output: &mut String, buffer: &mut String, line: &str) {
let mut open_1 = false;
let mut open_2 = false;
let mut close_1 = false;
let mut is_open = false;
for char in line.chars() {
if close_1 && char != '=' {
buffer.push('=');
close_1 = false;
}
match char {
'=' => {
if !is_open {
// flush buffer
output.push_str(&buffer);
buffer.clear();
// toggle open
open_1 = true;
is_open = true;
} else {
if open_1 {
// this is the second open we've recieved
open_2 = true;
open_1 = false;
continue;
}
if close_1 {
// this is the second close we've received
output.push_str(&format!("<mark>{buffer}</mark>\n"));
buffer.clear();
open_1 = false;
open_2 = false;
close_1 = false;
is_open = false;
continue;
}
close_1 = true;
}
}
_ => {
if open_1 {
open_1 = false;
buffer.push('=');
}
if open_2 && is_open {
open_2 = false;
}
buffer.push(char);
}
}
}
}
/// Helper macro to quickly allow parsers to ignore fenced code blocks.
macro_rules! parser_ignores_pre {
($body:ident, $input:ident) => {{
let mut in_pre_block = false;
let mut output = String::new();
let mut buffer = String::new();
for line in $input.split("\n") {
if line.starts_with("```") {
in_pre_block = !in_pre_block;
output.push_str(&format!("{line}\n"));
continue;
}
if in_pre_block {
output.push_str(&format!("{line}\n"));
continue;
}
$body(&mut output, &mut buffer, line);
output.push_str(&format!("{buffer}\n"));
buffer.clear();
}
output
}};
}
pub fn parse_text_color(input: &str) -> String {
parser_ignores_pre!(parse_text_color_line, input)
}
pub fn parse_highlight(input: &str) -> String {
parser_ignores_pre!(parse_highlight_line, input)
}