Skip to content

Commit

Permalink
Merge branch 'datauri_ext' into datauri_support
Browse files Browse the repository at this point in the history
Added support for choosing between data uris and inline image links
  • Loading branch information
sytsereitsma committed Jul 4, 2022
2 parents 7014f28 + 6936637 commit 32175e3
Showing 1 changed file with 128 additions and 9 deletions.
137 changes: 128 additions & 9 deletions src/plantuml_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use sha1::{Digest, Sha1};
use std::cell::RefCell;
use std::fs;
use std::path::{Path, PathBuf};
use std::io::Read;
use base64::encode;

pub trait PlantUMLRendererTrait {
fn render(&self, plantuml_code: &str, rel_img_url: &str, image_format: String) -> String;
Expand Down Expand Up @@ -48,6 +50,7 @@ pub struct PlantUMLRenderer {
cleaner: RefCell<DirCleaner>,
img_root: PathBuf,
clickable_img: bool,
use_data_uri: bool,
}

impl PlantUMLRenderer {
Expand All @@ -57,6 +60,7 @@ impl PlantUMLRenderer {
cleaner: RefCell::new(DirCleaner::new(img_root)),
img_root: img_root.to_path_buf(),
clickable_img: cfg.clickable_img,
use_data_uri: false,
};

renderer
Expand All @@ -75,6 +79,29 @@ impl PlantUMLRenderer {
}
}

fn create_datauri(image_path: &PathBuf) -> String {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs#syntax

let media_type = match image_path.extension().map(|s| s.to_str()).unwrap_or(Some("")) {
Some("jpg") | Some("jpeg") => "image/jpeg",
Some("png") => "image/png",
Some("svg") => "image/svg+xml",
Some("atxt") | Some("utxt") | Some("txt") => "text/plain",
_ => "",
};

let mut image_file = fs::File::open(image_path).unwrap_or_else(|e| panic!("could not open file: {}", e));
let mut image_bytes_buffer = Vec::new();
image_file.read_to_end(&mut image_bytes_buffer).unwrap_or_else(|e| panic!("could not read file: {}", e));
let encoded_value = encode(&image_bytes_buffer);

format!("data:{};base64,{}", media_type, encoded_value)
}

fn create_image_datauri_element(image_path: &PathBuf) -> String {
format!("<img src=\"{}\" />", PlantUMLRenderer::create_datauri(image_path))
}

fn create_inline_image(image_path: &Path) -> String {
log::debug!("Creating inline image from {:?}", image_path);
let raw_source = fs::read(image_path).unwrap();
Expand All @@ -98,7 +125,9 @@ impl PlantUMLRenderer {
let extension = output_file.extension().unwrap_or_default();
if extension == "atxt" || extension == "utxt" {
Self::create_inline_image(&output_file)
} else {
} else if self.use_data_uri {
Self::create_image_datauri_element(&output_file)
} else {
Self::create_md_link(rel_img_url, &output_file, self.clickable_img)
}
}
Expand All @@ -116,6 +145,8 @@ mod tests {
use anyhow::{bail, Result};
use pretty_assertions::assert_eq;
use tempfile::tempdir;
use std::fs::File;
use std::io::Write;

#[test]
fn test_create_md_link() {
Expand All @@ -135,6 +166,58 @@ mod tests {
);
}

#[test]
fn test_create_datauri() {
let temp_directory = tempdir().unwrap();
let content = "test content";


let svg_path = temp_directory.path().join("file.svg");
let mut svg_file = File::create(&svg_path).unwrap();
writeln!(svg_file, "{}", content).unwrap();
drop(svg_file); // Close and flush content to file
assert_eq!(
String::from("data:image/svg+xml;base64,dGVzdCBjb250ZW50Cg=="),
PlantUMLRenderer::create_datauri(&svg_path)
);

let png_path = temp_directory.path().join("file.png");
let mut png_file = File::create(&png_path).unwrap();
writeln!(png_file, "{}", content).unwrap();
drop(png_file); // Close and flush content to file
assert_eq!(
String::from("data:image/png;base64,dGVzdCBjb250ZW50Cg=="),
PlantUMLRenderer::create_datauri(&png_path)
);

let txt_path = temp_directory.path().join("file.txt");
let mut txt_file = File::create(&txt_path).unwrap();
writeln!(txt_file, "{}", content).unwrap();
drop(txt_file); // Close and flush content to file
assert_eq!(
String::from("data:text/plain;base64,dGVzdCBjb250ZW50Cg=="),
PlantUMLRenderer::create_datauri(&txt_path)
);

let jpeg_path = temp_directory.path().join("file.jpeg");
let mut jpeg_file = File::create(&jpeg_path).unwrap();
writeln!(jpeg_file, "{}", content).unwrap();
drop(jpeg_file); // Close and flush content to file
assert_eq!(
String::from("data:image/jpeg;base64,dGVzdCBjb250ZW50Cg=="),
PlantUMLRenderer::create_datauri(&jpeg_path)
);

let jpg_path = temp_directory.path().join("file.jpg");
let mut jpg_file = File::create(&jpg_path).unwrap();
writeln!(jpg_file, "{}", content).unwrap();
drop(jpg_file); // Close and flush content to file
assert_eq!(
String::from("data:image/jpeg;base64,dGVzdCBjb250ZW50Cg=="),
PlantUMLRenderer::create_datauri(&jpg_path)
);
}

struct BackendMock {
is_ok: bool,
}
Expand All @@ -155,13 +238,14 @@ mod tests {
}

#[test]
fn test_rendering() {
fn test_rendering_md_link() {
let output_dir = tempdir().unwrap();
let renderer = PlantUMLRenderer {
backend: Box::new(BackendMock { is_ok: true }),
cleaner: RefCell::new(DirCleaner::new(output_dir.path())),
img_root: output_dir.path().to_path_buf(),
clickable_img: false,
use_data_uri: false,
};

let plantuml_code = "some puml code";
Expand Down Expand Up @@ -194,23 +278,57 @@ mod tests {
}

#[test]
fn test_rendering_clickable() {
fn test_rendering_datauri() {
let output_dir = tempdir().unwrap();
let renderer = PlantUMLRenderer {
backend: Box::new(BackendMock { is_ok: true }),
cleaner: RefCell::new(DirCleaner::new(output_dir.path())),
img_root: output_dir.path().to_path_buf(),
clickable_img: true,
clickable_img: false,
use_data_uri: true,
};

let plantuml_code = "some puml code";
let code_hash = hash_string(plantuml_code);

// svg extension
assert_eq!(
String::from("<img src=\"data:image/svg+xml;base64,c29tZSBwdW1sIGNvZGUKc3Zn\" />"),
renderer.render(
&plantuml_code,
"rel/url",
"svg"
)
);

// png extension
assert_eq!(
String::from("<img src=\"data:image/png;base64,c29tZSBwdW1sIGNvZGUKcG5n\" />"),
renderer.render(
&plantuml_code,
"rel/url",
"png"
)
);

// txt extension
assert_eq!(
String::from("\n```txt\nsome puml code\ntxt```\n"),
renderer.render(
&plantuml_code,
"rel/url",
"txt"
)
);

// utxt extension
assert_eq!(
format!(
"[![](rel/url/{}.svg)](rel/url/{}.svg)\n\n",
code_hash, code_hash
),
renderer.render(plantuml_code, "rel/url", "svg")
String::from("\n```txt\nsome puml code\ntxt```\n"),
renderer.render(
&plantuml_code,
"rel/url",
"txt"
)
);
}

Expand All @@ -222,6 +340,7 @@ mod tests {
cleaner: RefCell::new(DirCleaner::new(output_dir.path())),
img_root: output_dir.path().to_path_buf(),
clickable_img: false,
use_data_uri: false,
};

assert_eq!(
Expand Down

0 comments on commit 32175e3

Please sign in to comment.