add image sizes to emoji
This commit is contained in:
parent
9bf3409197
commit
e44d5babca
|
@ -1,7 +1,8 @@
|
||||||
use std::{collections::HashMap, ffi::OsStr, fs::File, io::BufReader, path::Path};
|
use std::{collections::HashMap, ffi::OsStr, fs::File, io::BufReader, path::Path};
|
||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use log::debug;
|
use image::ImageError;
|
||||||
|
use log::{debug, error, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
@ -180,32 +181,43 @@ impl Config {
|
||||||
/// Data derived from the config.
|
/// Data derived from the config.
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ConfigDerivedData {
|
pub struct ConfigDerivedData {
|
||||||
pub pic_sizes: HashMap<String, Option<PicSize>>,
|
pub image_sizes: HashMap<String, Option<ImageSize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Picture size. This is useful for emitting <img> elements with a specific size to eliminate layout shifting.
|
/// Image size. This is useful for emitting <img> elements with a specific size to eliminate
|
||||||
|
/// layout shifting.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct PicSize {
|
pub struct ImageSize {
|
||||||
pub width: u32,
|
pub width: u32,
|
||||||
pub height: u32,
|
pub height: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ConfigDerivedData {
|
impl ConfigDerivedData {
|
||||||
fn read_pic_size(config: &Config, pic_id: &str) -> Option<PicSize> {
|
fn read_image_size(filename: &str) -> Option<ImageSize> {
|
||||||
let pic_filename = config.pics.get(pic_id)?;
|
let (width, height) = image::io::Reader::new(BufReader::new(File::open(filename).ok()?))
|
||||||
let (width, height) = image::io::Reader::new(BufReader::new(
|
.with_guessed_format()
|
||||||
File::open(format!("static/pic/{pic_filename}")).ok()?,
|
.map_err(ImageError::from)
|
||||||
))
|
.and_then(|i| i.into_dimensions())
|
||||||
.into_dimensions()
|
// NOTE: Not being able to determine the image size is not the end of the world,
|
||||||
|
// so just warn the user if we couldn't do it.
|
||||||
|
// For example, currently SVG is not supported at all, which causes this to fail.
|
||||||
|
.inspect_err(|e| warn!("cannot read image size of {filename}: {e}"))
|
||||||
.ok()?;
|
.ok()?;
|
||||||
Some(PicSize { width, height })
|
Some(ImageSize { width, height })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pic_size(&mut self, config: &Config, pic_id: &str) -> Option<PicSize> {
|
pub fn image_size(&mut self, filename: &str) -> Option<ImageSize> {
|
||||||
if !self.pic_sizes.contains_key(pic_id) {
|
if !self.image_sizes.contains_key(filename) {
|
||||||
self.pic_sizes
|
self.image_sizes
|
||||||
.insert(pic_id.to_owned(), Self::read_pic_size(config, pic_id));
|
.insert(filename.to_owned(), Self::read_image_size(filename));
|
||||||
}
|
}
|
||||||
self.pic_sizes.get(pic_id).copied().flatten()
|
self.image_sizes.get(filename).copied().flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pic_size(&mut self, config: &Config, pic_id: &str) -> Option<ImageSize> {
|
||||||
|
config
|
||||||
|
.pics
|
||||||
|
.get(pic_id)
|
||||||
|
.and_then(|pic_filename| self.image_size(&format!("static/pic/{pic_filename}")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ use pulldown_cmark::escape::{escape_href, escape_html, StrWrite};
|
||||||
use pulldown_cmark::{Alignment, CodeBlockKind, Event, LinkType, Tag};
|
use pulldown_cmark::{Alignment, CodeBlockKind, Event, LinkType, Tag};
|
||||||
use pulldown_cmark::{CowStr, Event::*};
|
use pulldown_cmark::{CowStr, Event::*};
|
||||||
|
|
||||||
use crate::config::{Config, ConfigDerivedData, PicSize};
|
use crate::config::{Config, ConfigDerivedData, ImageSize};
|
||||||
use crate::html::highlight::highlight;
|
use crate::html::highlight::highlight;
|
||||||
use crate::state::Treehouse;
|
use crate::state::Treehouse;
|
||||||
|
|
||||||
|
@ -281,15 +281,13 @@ where
|
||||||
|
|
||||||
if let LiterateCodeKind::Output { placeholder_pic_id } = kind {
|
if let LiterateCodeKind::Output { placeholder_pic_id } = kind {
|
||||||
if !placeholder_pic_id.is_empty() {
|
if !placeholder_pic_id.is_empty() {
|
||||||
self.write(
|
self.write("<img class=\"placeholder-image\" loading=\"lazy\" src=\"")?;
|
||||||
"<img class=\"placeholder-image\" loading=\"lazy\" src=\"",
|
|
||||||
)?;
|
|
||||||
escape_html(
|
escape_html(
|
||||||
&mut self.writer,
|
&mut self.writer,
|
||||||
&self.config.pic_url(placeholder_pic_id),
|
&self.config.pic_url(placeholder_pic_id),
|
||||||
)?;
|
)?;
|
||||||
self.write("\"")?;
|
self.write("\"")?;
|
||||||
if let Some(PicSize { width, height }) = self
|
if let Some(ImageSize { width, height }) = self
|
||||||
.config_derived_data
|
.config_derived_data
|
||||||
.pic_size(self.config, placeholder_pic_id)
|
.pic_size(self.config, placeholder_pic_id)
|
||||||
{
|
{
|
||||||
|
@ -552,6 +550,7 @@ where
|
||||||
escape_html(&mut self.writer, &branch.attributes.id)?;
|
escape_html(&mut self.writer, &branch.attributes.id)?;
|
||||||
self.writer.write_str("\">")?;
|
self.writer.write_str("\">")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.writer
|
self.writer
|
||||||
.write_str("<img data-cast=\"emoji\" title=\":")?;
|
.write_str("<img data-cast=\"emoji\" title=\":")?;
|
||||||
escape_html(&mut self.writer, name)?;
|
escape_html(&mut self.writer, name)?;
|
||||||
|
@ -561,7 +560,18 @@ where
|
||||||
escape_html(&mut self.writer, filename)?;
|
escape_html(&mut self.writer, filename)?;
|
||||||
self.writer.write_str("\" alt=\"")?;
|
self.writer.write_str("\" alt=\"")?;
|
||||||
escape_html(&mut self.writer, name)?;
|
escape_html(&mut self.writer, name)?;
|
||||||
|
if let Some(image_size) = self
|
||||||
|
.config_derived_data
|
||||||
|
.image_size(&format!("static/emoji/{filename}"))
|
||||||
|
{
|
||||||
|
write!(
|
||||||
|
self.writer,
|
||||||
|
"\" width=\"{}\" height=\"{}",
|
||||||
|
image_size.width, image_size.height
|
||||||
|
)?;
|
||||||
|
}
|
||||||
self.writer.write_str("\">")?;
|
self.writer.write_str("\">")?;
|
||||||
|
|
||||||
if branch_id.is_some() {
|
if branch_id.is_some() {
|
||||||
self.writer.write_str("</a>")?;
|
self.writer.write_str("</a>")?;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue