server: extract image title and alt attributes into figure captions

This commit is contained in:
Bill Thiede 2024-08-31 14:43:04 -07:00
parent f77d0776c4
commit 548b5a0ab0
2 changed files with 37 additions and 2 deletions

View File

@ -9,7 +9,10 @@ use async_trait::async_trait;
use css_inline::{CSSInliner, InlineError, InlineOptions}; use css_inline::{CSSInliner, InlineError, InlineOptions};
use linkify::{LinkFinder, LinkKind}; use linkify::{LinkFinder, LinkKind};
use log::{error, info, warn}; use log::{error, info, warn};
use lol_html::{element, errors::RewritingError, rewrite_str, text, RewriteStrSettings}; use lol_html::{
element, errors::RewritingError, html_content::ContentType, rewrite_str, text,
RewriteStrSettings,
};
use maplit::{hashmap, hashset}; use maplit::{hashmap, hashset};
use scraper::{error::SelectorErrorKind, Html, Selector}; use scraper::{error::SelectorErrorKind, Html, Selector};
use thiserror::Error; use thiserror::Error;
@ -129,6 +132,36 @@ impl Transformer for InlineStyle {
} }
} }
/// Frame images will extract any alt or title tags on images and place them as labels below said
/// image.
struct FrameImages;
#[async_trait]
impl Transformer for FrameImages {
async fn transform(&self, link: &Option<Url>, html: &str) -> Result<String, TransformError> {
Ok(rewrite_str(
html,
RewriteStrSettings {
element_content_handlers: vec![element!("img[alt], img[title]", |el| {
info!("found image with alt or title {el:?}");
let src = el
.get_attribute("src")
.unwrap_or("https://placehold.co/600x400".to_string());
let alt = el.get_attribute("alt");
let title = el.get_attribute("title");
let mut frags = vec!["<figure>".to_string(), format!(r#"<img src="{src}">"#)];
alt.map(|t| frags.push(format!("<figcaption>Alt: {t}</figcaption>")));
title.map(|t| frags.push(format!("<figcaption>Title: {t}</figcaption>")));
frags.push("</figure>".to_string());
el.replace(&frags.join("\n"), ContentType::Html);
Ok(())
})],
..RewriteStrSettings::default()
},
)?)
}
}
struct AddOutlink; struct AddOutlink;
#[async_trait] #[async_trait]

View File

@ -15,7 +15,8 @@ use crate::{
compute_offset_limit, compute_offset_limit,
error::ServerError, error::ServerError,
graphql::{Body, Email, Html, Message, NewsPost, Tag, Thread, ThreadSummary}, graphql::{Body, Email, Html, Message, NewsPost, Tag, Thread, ThreadSummary},
AddOutlink, EscapeHtml, InlineStyle, SanitizeHtml, SlurpContents, StripHtml, Transformer, AddOutlink, EscapeHtml, FrameImages, InlineStyle, SanitizeHtml, SlurpContents, StripHtml,
Transformer,
}; };
pub fn is_newsreader_search(query: &str) -> bool { pub fn is_newsreader_search(query: &str) -> bool {
@ -193,6 +194,7 @@ pub async fn thread(pool: &PgPool, thread_id: String) -> Result<Thread, ServerEr
], ],
], ],
}), }),
Box::new(FrameImages),
Box::new(AddOutlink), Box::new(AddOutlink),
Box::new(EscapeHtml), Box::new(EscapeHtml),
Box::new(InlineStyle), Box::new(InlineStyle),