nmd_core/utility/
image_utility.rs

1use oxipng::Options;
2use crate::{codex::{modifier::ModifiersBucket, Codex}, compilable_text::{compilable_text_part::CompilableTextPart, CompilableText}, compilation::{compilable::Compilable, compilation_configuration::{compilation_configuration_overlay::CompilationConfigurationOverLay, CompilationConfiguration}, compilation_error::CompilationError, compilation_outcome::CompilationOutcome}, output_format::OutputFormat, resource::{image_resource::ImageResource, source::Source, ResourceError}};
3use super::{nmd_unique_identifier::NmdUniqueIdentifier, text_utility};
4
5
6pub fn set_image_base64_embed_src(image: &mut ImageResource, compression: bool) -> Result<(), ResourceError> {
7
8    let src = image.src().clone();
9
10    let src = src.try_into_bytes()?;
11
12    if let Source::Bytes { mut bytes } = src {
13
14        if compression {
15    
16            let original_log_level = log::max_level();
17            log::set_max_level(log::LevelFilter::Warn);
18    
19            let options = Options::max_compression();
20    
21            let optimized_png = oxipng::optimize_from_memory(&bytes, &options);
22    
23            log::set_max_level(original_log_level);
24    
25            match optimized_png {
26                Ok(image) => bytes = image,
27                Err(err) => return Err(ResourceError::ElaborationError(format!("image compression error: {}", err)))
28            }
29    
30        }
31
32        let src = Source::Bytes { bytes };
33
34        image.set_src(src.try_into_base64()?);
35
36        return Ok(())
37    }
38
39    unreachable!("'try_into_bytes' must return bytes type")
40}
41
42
43pub fn compile_image_resource_in_html(image: &ImageResource, img_classes: Vec<&str>, nuid: Option<&NmdUniqueIdentifier>, codex: &Codex, compilation_configuration: &CompilationConfiguration, compilation_configuration_overlay: CompilationConfigurationOverLay) -> Result<CompilationOutcome, CompilationError> {
44    
45    let mut outcome = String::new();
46    
47    let id_attr: String;
48
49    if let Some(id) = image.id() {
50        id_attr = format!(r#"id="{}""#, id.build_without_internal_sharp());
51    } else {
52        id_attr = String::new();
53    }
54
55    let styles: String;
56    let classes: String;
57
58    if let Some(style) = image.style() {
59
60        let (s, c) = text_utility::split_styles_and_classes(style);
61
62        styles = s.unwrap_or(String::new());
63        classes = c.unwrap_or(String::new());
64    
65    } else {
66
67        styles = String::new();
68        classes = String::new();
69    }
70
71    outcome.push_str(&format!(r#"<figure class="figure {}" style="{}" {} {}>"#, classes, styles, id_attr, text_utility::html_nuid_tag_or_nothing(nuid)));
72
73    let src: String = match image.src() {
74        Source::Remote { url: _ } | Source::Local { path: _ } => image.src().to_string(),
75        Source::Base64String { base64 } => {
76            if image.mime_type().is_none() {
77
78                panic!("base64 image without mime type")
79            }
80
81            format!("data:{};base64,{}", image.mime_type().as_ref().unwrap(), base64)
82        },
83        Source::Bytes { bytes: _ } => {
84
85            let base64 = image.src().try_to_base64()?;
86
87            if image.mime_type().is_none() {
88
89                panic!("base64 image without mime type")
90            }
91
92            format!("data:{};base64,{}", image.mime_type().as_ref().unwrap(), base64)
93        },
94    };
95
96    outcome.push_str(&format!(r#"<img src="{}" class="{}" />"#, src, img_classes.join(" ")));
97
98
99    if let Some(caption) = image.caption() {
100
101        outcome.push_str(r#"<figcaption class="image-caption">"#);
102
103        let mut compilable_text = CompilableText::from(CompilableTextPart::new_compilable(caption.clone(), ModifiersBucket::None));
104
105        outcome.push_str(&compilable_text.compile(&OutputFormat::Html, codex, compilation_configuration, compilation_configuration_overlay.clone())?.content());
106        
107        outcome.push_str(r#"</figcaption>"#);
108    }
109
110    outcome.push_str("</figure>");
111
112    Ok(CompilationOutcome::from(outcome))
113}