add: parse_image_line, parse_link_line
This commit is contained in:
parent
d8167aa06f
commit
9fe5735127
9 changed files with 234 additions and 25 deletions
205
src/markdown.rs
205
src/markdown.rs
|
@ -2,7 +2,9 @@ use std::collections::HashSet;
|
|||
|
||||
pub fn render_markdown(input: &str) -> String {
|
||||
let html = tetratto_shared::markdown::render_markdown_dirty(&parse_text_color(
|
||||
&parse_highlight(&parse_underline(&parse_comment(&parse_image_size(input)))),
|
||||
&parse_highlight(&parse_link(&parse_image(&parse_image_size(
|
||||
&parse_underline(&parse_comment(input)),
|
||||
)))),
|
||||
));
|
||||
|
||||
let mut allowed_attributes = HashSet::new();
|
||||
|
@ -16,7 +18,13 @@ pub fn render_markdown(input: &str) -> String {
|
|||
allowed_attributes.insert("src");
|
||||
allowed_attributes.insert("style");
|
||||
|
||||
tetratto_shared::markdown::clean_html(html, allowed_attributes)
|
||||
tetratto_shared::markdown::clean_html(
|
||||
html.replace("<style>", "<span>:temp_style")
|
||||
.replace("</style>", "</span>:temp_style"),
|
||||
allowed_attributes,
|
||||
)
|
||||
.replace("<span>:temp_style", "<style>")
|
||||
.replace("</span>:temp_style", "</style>")
|
||||
}
|
||||
|
||||
fn parse_text_color_line(output: &mut String, buffer: &mut String, line: &str) {
|
||||
|
@ -258,6 +266,11 @@ fn parse_comment_line(output: &mut String, _: &mut String, line: &str) {
|
|||
return;
|
||||
}
|
||||
|
||||
if line == "[..]" {
|
||||
output.push_str(" ");
|
||||
return;
|
||||
}
|
||||
|
||||
output.push_str(line);
|
||||
}
|
||||
|
||||
|
@ -323,17 +336,7 @@ fn parse_image_size_line(output: &mut String, buffer: &mut String, line: &str) {
|
|||
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")
|
||||
}
|
||||
"<span style=\"width: {size_lhs}; height: {size_rhs}\" class=\"img_sizer\">![{buffer}</span>"
|
||||
));
|
||||
|
||||
size_lhs = String::new();
|
||||
|
@ -380,6 +383,174 @@ fn parse_image_size_line(output: &mut String, buffer: &mut String, line: &str) {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_image_line(output: &mut String, buffer: &mut String, line: &str) {
|
||||
let mut image_possible = false;
|
||||
let mut in_image = false;
|
||||
let mut in_alt = false;
|
||||
let mut in_src = false;
|
||||
let mut alt = String::new();
|
||||
|
||||
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;
|
||||
in_alt = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_image {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
']' => {
|
||||
if in_alt {
|
||||
in_alt = false;
|
||||
in_src = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
output.push(char);
|
||||
}
|
||||
'(' => {
|
||||
if in_src {
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_image {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
')' => {
|
||||
if in_image {
|
||||
// end
|
||||
output.push_str(&format!(
|
||||
"<img loading=\"lazy\" alt=\"{alt}\" src=\"{buffer}\" />"
|
||||
));
|
||||
|
||||
alt = String::new();
|
||||
in_alt = false;
|
||||
in_src = false;
|
||||
in_image = false;
|
||||
image_possible = false;
|
||||
|
||||
buffer.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
output.push(char);
|
||||
}
|
||||
'!' => {
|
||||
// flush buffer
|
||||
output.push_str(&buffer);
|
||||
buffer.clear();
|
||||
|
||||
// ...
|
||||
image_possible = true;
|
||||
}
|
||||
_ => {
|
||||
if in_image {
|
||||
if in_alt {
|
||||
alt.push(char)
|
||||
} else {
|
||||
buffer.push(char);
|
||||
}
|
||||
} else {
|
||||
output.push(char)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_link_line(output: &mut String, buffer: &mut String, line: &str) {
|
||||
let mut in_link = false;
|
||||
let mut in_text = false;
|
||||
let mut in_src = false;
|
||||
let mut text = String::new();
|
||||
|
||||
for (i, char) in line.chars().enumerate() {
|
||||
match char {
|
||||
'[' => {
|
||||
// flush buffer
|
||||
output.push_str(&buffer);
|
||||
buffer.clear();
|
||||
|
||||
// scan for closing, otherwise quit
|
||||
let haystack = &line[i..];
|
||||
|
||||
if !haystack.contains("]") {
|
||||
output.push('[');
|
||||
continue;
|
||||
}
|
||||
|
||||
// ...
|
||||
in_link = true;
|
||||
in_text = true;
|
||||
}
|
||||
']' => {
|
||||
if in_text {
|
||||
in_text = false;
|
||||
in_src = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
output.push(char);
|
||||
}
|
||||
'(' => {
|
||||
if in_src {
|
||||
continue;
|
||||
}
|
||||
|
||||
if in_link {
|
||||
buffer.push(char);
|
||||
} else {
|
||||
output.push(char);
|
||||
}
|
||||
}
|
||||
')' => {
|
||||
if in_link {
|
||||
// end
|
||||
output.push_str(&format!(
|
||||
"<a href=\"{buffer}\" rel=\"noopener noreferrer\">{text}</a>"
|
||||
));
|
||||
|
||||
text = String::new();
|
||||
in_text = false;
|
||||
in_src = false;
|
||||
in_link = false;
|
||||
|
||||
buffer.clear();
|
||||
continue;
|
||||
}
|
||||
|
||||
output.push(char);
|
||||
}
|
||||
_ => {
|
||||
if in_link {
|
||||
if in_text {
|
||||
text.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) => {{
|
||||
|
@ -427,3 +598,11 @@ pub fn parse_comment(input: &str) -> String {
|
|||
pub fn parse_image_size(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_image_size_line, input)
|
||||
}
|
||||
|
||||
pub fn parse_image(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_image_line, input)
|
||||
}
|
||||
|
||||
pub fn parse_link(input: &str) -> String {
|
||||
parser_ignores_pre!(parse_link_line, input)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue