add: parse_underline, parse_comment, parse_image_size
This commit is contained in:
parent
f8dac8f491
commit
d8167aa06f
6 changed files with 275 additions and 4 deletions
243
src/markdown.rs
243
src/markdown.rs
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
|||
|
||||
pub fn render_markdown(input: &str) -> String {
|
||||
let html = tetratto_shared::markdown::render_markdown_dirty(&parse_text_color(
|
||||
&parse_highlight(input),
|
||||
&parse_highlight(&parse_underline(&parse_comment(&parse_image_size(input)))),
|
||||
));
|
||||
|
||||
let mut allowed_attributes = HashSet::new();
|
||||
|
@ -151,6 +151,235 @@ fn parse_highlight_line(output: &mut String, buffer: &mut String, line: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_underline_line(output: &mut String, buffer: &mut String, line: &str) {
|
||||
let mut open_1 = false;
|
||||
let mut is_open = false;
|
||||
let mut close_1 = false;
|
||||
|
||||
for char in line.chars() {
|
||||
if open_1 && char != '~' {
|
||||
is_open = false;
|
||||
open_1 = false;
|
||||
buffer.push('!');
|
||||
}
|
||||
|
||||
if close_1 && char != '!' {
|
||||
is_open = false;
|
||||
close_1 = false;
|
||||
buffer.push('~');
|
||||
}
|
||||
|
||||
match char {
|
||||
'~' => {
|
||||
if open_1 {
|
||||
open_1 = false;
|
||||
is_open = true;
|
||||
} else if is_open {
|
||||
// open close
|
||||
close_1 = true;
|
||||
}
|
||||
}
|
||||
'!' => {
|
||||
if close_1 {
|
||||
// close
|
||||
let mut s: Vec<&str> = buffer.split(";").collect();
|
||||
let text = s.pop().unwrap_or(&"").trim();
|
||||
let mut style = String::new();
|
||||
|
||||
for (i, mut x) in s.iter().enumerate() {
|
||||
if i == 0 {
|
||||
// color
|
||||
if x == &"default" {
|
||||
x = &"currentColor";
|
||||
}
|
||||
|
||||
style.push_str(&format!("text-decoration-color: {x};"));
|
||||
} else if i == 1 {
|
||||
// style
|
||||
if x == &"default" {
|
||||
x = &"solid";
|
||||
}
|
||||
|
||||
style.push_str(&format!("text-decoration-style: {x};"));
|
||||
} else if i == 2 {
|
||||
// line
|
||||
if x == &"default" {
|
||||
x = &"underline";
|
||||
}
|
||||
|
||||
style.push_str(&format!("text-decoration-line: {x};"));
|
||||
} else if i == 3 {
|
||||
// thickness
|
||||
if x == &"default" {
|
||||
x = &"1px";
|
||||
}
|
||||
|
||||
style.push_str(&format!("text-decoration-thickness: {x}px;"));
|
||||
}
|
||||
}
|
||||
|
||||
// defaults
|
||||
if s.get(1).is_none() {
|
||||
style.push_str(&format!("text-decoration-style: solid;"));
|
||||
}
|
||||
|
||||
if s.get(2).is_none() {
|
||||
style.push_str(&format!("text-decoration-line: underline;"));
|
||||
}
|
||||
|
||||
if s.get(3).is_none() {
|
||||
style.push_str(&format!("text-decoration-thickness: 1px;"));
|
||||
}
|
||||
|
||||
// ...
|
||||
output.push_str(&format!("<span style=\"{style}\">{text}</span>"));
|
||||
buffer.clear();
|
||||
|
||||
open_1 = false;
|
||||
is_open = false;
|
||||
close_1 = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// open
|
||||
open_1 = true;
|
||||
|
||||
// flush buffer
|
||||
output.push_str(&buffer);
|
||||
buffer.clear();
|
||||
}
|
||||
_ => buffer.push(char),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_comment_line(output: &mut String, _: &mut String, line: &str) {
|
||||
if line.contains("]:") && line.starts_with("[") {
|
||||
return;
|
||||
}
|
||||
|
||||
output.push_str(line);
|
||||
}
|
||||
|
||||
fn parse_image_size_line(output: &mut String, buffer: &mut String, line: &str) {
|
||||
let mut image_possible = false;
|
||||
let mut in_image = false;
|
||||
let mut in_size = false;
|
||||
let mut in_size_rhs = false;
|
||||
|
||||
let mut size_lhs = String::new();
|
||||
let mut size_rhs = String::new();
|
||||
|
||||
if !line.contains("{") {
|
||||
output.push_str(line);
|
||||
return;
|
||||
}
|
||||
|
||||
for char in line.chars() {
|
||||
if image_possible && char != '[' {
|
||||
image_possible = false;
|
||||
output.push('!');
|
||||
}
|
||||
|
||||
match char {
|
||||
'[' => {
|
||||
if image_possible {
|
||||
in_image = true;
|
||||
image_possible = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_image {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
'{' => {
|
||||
if in_image {
|
||||
in_size = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_image {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
':' => {
|
||||
if in_size {
|
||||
in_size_rhs = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_image {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
'}' => {
|
||||
if in_size && in_size_rhs {
|
||||
// end
|
||||
output.push_str(&format!(
|
||||
"<span style=\"width: {}; height: {}\" class=\"img_sizer\">![{buffer}</span>",
|
||||
if size_lhs == "auto" {
|
||||
size_lhs
|
||||
} else {
|
||||
format!("{size_lhs}px")
|
||||
},
|
||||
if size_rhs == "auto" {
|
||||
size_rhs
|
||||
} else {
|
||||
format!("{size_rhs}px")
|
||||
}
|
||||
));
|
||||
|
||||
size_lhs = String::new();
|
||||
size_rhs = String::new();
|
||||
in_image = false;
|
||||
in_size = false;
|
||||
in_size_rhs = false;
|
||||
image_possible = false;
|
||||
|
||||
buffer.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_image {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
'!' => {
|
||||
// flush buffer
|
||||
output.push_str(&buffer);
|
||||
buffer.clear();
|
||||
|
||||
// ...
|
||||
image_possible = true
|
||||
}
|
||||
_ => {
|
||||
if in_image {
|
||||
if in_size {
|
||||
if in_size_rhs {
|
||||
size_rhs.push(char);
|
||||
} else {
|
||||
size_lhs.push(char);
|
||||
}
|
||||
} else {
|
||||
buffer.push(char);
|
||||
}
|
||||
} else {
|
||||
output.push(char)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper macro to quickly allow parsers to ignore fenced code blocks.
|
||||
macro_rules! parser_ignores_pre {
|
||||
($body:ident, $input:ident) => {{
|
||||
|
@ -186,3 +415,15 @@ pub fn parse_text_color(input: &str) -> String {
|
|||
pub fn parse_highlight(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_highlight_line, input)
|
||||
}
|
||||
|
||||
pub fn parse_underline(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_underline_line, input)
|
||||
}
|
||||
|
||||
pub fn parse_comment(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_comment_line, input)
|
||||
}
|
||||
|
||||
pub fn parse_image_size(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_image_size_line, input)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue