summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/library')
-rw-r--r--src/library/graphics.rs42
-rw-r--r--src/library/mod.rs27
2 files changed, 59 insertions, 10 deletions
diff --git a/src/library/graphics.rs b/src/library/graphics.rs
new file mode 100644
index 00000000..779d78b5
--- /dev/null
+++ b/src/library/graphics.rs
@@ -0,0 +1,42 @@
+use std::fs::File;
+use std::io::BufReader;
+
+use image::io::Reader;
+
+use crate::layout::Image;
+use crate::prelude::*;
+
+/// `image`: Include an image.
+///
+/// # Positional arguments
+/// - The path to the image (string)
+pub fn image(mut args: Args, ctx: &mut EvalContext) -> Value {
+ let path = args.need::<_, Spanned<String>>(ctx, 0, "path");
+ let width = args.get::<_, Linear>(ctx, "width");
+ let height = args.get::<_, Linear>(ctx, "height");
+
+ if let Some(path) = path {
+ if let Ok(file) = File::open(path.v) {
+ match Reader::new(BufReader::new(file))
+ .with_guessed_format()
+ .map_err(|err| err.into())
+ .and_then(|reader| reader.decode())
+ .map(|img| img.into_rgba8())
+ {
+ Ok(buf) => {
+ ctx.push(Image {
+ buf,
+ width,
+ height,
+ align: ctx.state.align,
+ });
+ }
+ Err(err) => ctx.diag(error!(path.span, "invalid image: {}", err)),
+ }
+ } else {
+ ctx.diag(error!(path.span, "failed to open image file"));
+ }
+ }
+
+ Value::None
+}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index af23d050..e59201dc 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -4,6 +4,7 @@ mod align;
mod boxed;
mod color;
mod font;
+mod graphics;
mod page;
mod spacing;
@@ -11,29 +12,35 @@ pub use align::*;
pub use boxed::*;
pub use color::*;
pub use font::*;
+pub use graphics::*;
pub use page::*;
pub use spacing::*;
use crate::eval::{Scope, ValueFunc};
macro_rules! std {
- ($($name:literal => $func:expr),* $(,)?) => {
+ ($($func:expr $(=> $name:expr)?),* $(,)?) => {
/// Create a scope with all standard library functions.
pub fn _std() -> Scope {
let mut std = Scope::new();
- $(std.set($name, ValueFunc::new($func));)*
+ $(
+ let _name = stringify!($func);
+ $(let _name = $name;)?
+ std.set(_name, ValueFunc::new($func));
+ )*
std
}
};
}
std! {
- "align" => align,
- "box" => boxed,
- "font" => font,
- "h" => h,
- "page" => page,
- "pagebreak" => pagebreak,
- "rgb" => rgb,
- "v" => v,
+ align,
+ boxed => "box",
+ font,
+ h,
+ image,
+ page,
+ pagebreak,
+ rgb,
+ v,
}