From 03314b16156592ead0f020ea873550af89b8a3ee Mon Sep 17 00:00:00 2001 From: alemi Date: Fri, 7 Jun 2024 06:29:50 +0200 Subject: [PATCH] feat(mdhtml): allow setting media proxy for imgs --- utils/mdhtml/Cargo.toml | 2 +- utils/mdhtml/lib.rs | 36 +++++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/utils/mdhtml/Cargo.toml b/utils/mdhtml/Cargo.toml index e75eba92..39683a8b 100644 --- a/utils/mdhtml/Cargo.toml +++ b/utils/mdhtml/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mdhtml" -version = "0.1.0" +version = "0.1.1" edition = "2021" authors = [ "alemi " ] description = "Parse and display a markdown-like HTML subset" diff --git a/utils/mdhtml/lib.rs b/utils/mdhtml/lib.rs index a7a03683..6b89cf40 100644 --- a/utils/mdhtml/lib.rs +++ b/utils/mdhtml/lib.rs @@ -4,7 +4,10 @@ use comrak::{markdown_to_html, Options}; /// In our case, our sink only contains a tokens vector #[derive(Debug, Clone, Default)] -struct Sink(String); +struct Sink { + pub media_proxy: Option, + pub buffer: String, +} impl TokenSink for Sink { type Handle = (); @@ -22,21 +25,28 @@ impl TokenSink for Sink { | "img" | "a" ) { return TokenSinkResult::Continue } // skip this tag - self.0.push('<'); + self.buffer.push('<'); if !tag.self_closing && matches!(tag.kind, TagKind::EndTag) { - self.0.push('/'); + self.buffer.push('/'); } - self.0.push_str(tag.name.as_ref()); + self.buffer.push_str(tag.name.as_ref()); if !matches!(tag.kind, TagKind::EndTag) { match tag.name.as_ref() { "img" => for attr in tag.attrs { match attr.name.local.as_ref() { - "src" => self.0.push_str(&format!(" src=\"{}\"", attr.value.as_ref())), - "title" => self.0.push_str(&format!(" title=\"{}\"", attr.value.as_ref())), - "alt" => self.0.push_str(&format!(" alt=\"{}\"", attr.value.as_ref())), + "src" => { + let src = if let Some(ref proxy) = self.media_proxy { + format!("{proxy}{}", attr.value.as_ref()) + } else { + attr.value.to_string() + }; + self.buffer.push_str(&format!(" src=\"{src}\"")) + }, + "title" => self.buffer.push_str(&format!(" title=\"{}\"", attr.value.as_ref())), + "alt" => self.buffer.push_str(&format!(" alt=\"{}\"", attr.value.as_ref())), _ => {}, } }, @@ -44,13 +54,13 @@ impl TokenSink for Sink { let any_attr = !tag.attrs.is_empty(); for attr in tag.attrs { match attr.name.local.as_ref() { - "href" => self.0.push_str(&format!(" href=\"{}\"", attr.value.as_ref())), - "title" => self.0.push_str(&format!(" title=\"{}\"", attr.value.as_ref())), + "href" => self.buffer.push_str(&format!(" href=\"{}\"", attr.value.as_ref())), + "title" => self.buffer.push_str(&format!(" title=\"{}\"", attr.value.as_ref())), _ => {}, } } if any_attr { - self.0.push_str(" rel=\"nofollow noreferrer\" target=\"_blank\""); + self.buffer.push_str(" rel=\"nofollow noreferrer\" target=\"_blank\""); } }, _ => {}, @@ -58,12 +68,12 @@ impl TokenSink for Sink { } if tag.self_closing { - self.0.push('/'); + self.buffer.push('/'); } - self.0.push('>'); + self.buffer.push('>'); }, - Token::CharacterTokens(txt) => self.0.push_str(txt.as_ref()), + Token::CharacterTokens(txt) => self.buffer.push_str(txt.as_ref()), Token::CommentToken(_) => {}, Token::DoctypeToken(_) => {}, Token::NullCharacterToken => {},