add: near perfect metadata compatibility
This commit is contained in:
parent
b505199492
commit
f8dac8f491
8 changed files with 434 additions and 22 deletions
187
src/markdown.rs
187
src/markdown.rs
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue