summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
Diffstat (limited to 'src/library')
-rw-r--r--src/library/decorations.rs84
-rw-r--r--src/library/font.rs2
-rw-r--r--src/library/mod.rs5
3 files changed, 90 insertions, 1 deletions
diff --git a/src/library/decorations.rs b/src/library/decorations.rs
new file mode 100644
index 00000000..ef9afd37
--- /dev/null
+++ b/src/library/decorations.rs
@@ -0,0 +1,84 @@
+use crate::exec::{FontState, LineState};
+use crate::layout::Fill;
+
+use super::*;
+
+/// `strike`: Enable striken-through text.
+///
+/// # Named parameters
+/// - Color: `color`, of type `color`.
+/// - Baseline offset: `position`, of type `linear`.
+/// - Strength: `strength`, of type `linear`.
+/// - Extent that is applied on either end of the line: `extent`, of type
+/// `linear`.
+///
+/// # Return value
+/// A template that enables striken-through text. The effect is scoped to the
+/// body if present.
+pub fn strike(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
+ line_impl("strike", ctx, args, |font| &mut font.strikethrough)
+}
+
+/// `underline`: Enable underlined text.
+///
+/// # Named parameters
+/// - Color: `color`, of type `color`.
+/// - Baseline offset: `position`, of type `linear`.
+/// - Strength: `strength`, of type `linear`.
+/// - Extent that is applied on either end of the line: `extent`, of type
+/// `linear`.
+///
+/// # Return value
+/// A template that enables underlined text. The effect is scoped to the body if
+/// present.
+pub fn underline(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
+ line_impl("underline", ctx, args, |font| &mut font.underline)
+}
+
+/// `overline`: Add an overline above text.
+///
+/// # Named parameters
+/// - Color: `color`, of type `color`.
+/// - Baseline offset: `position`, of type `linear`.
+/// - Strength: `strength`, of type `linear`.
+/// - Extent that is applied on either end of the line: `extent`, of type
+/// `linear`.
+///
+/// # Return value
+/// A template that adds an overline above text. The effect is scoped to the
+/// body if present.
+pub fn overline(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
+ line_impl("overline", ctx, args, |font| &mut font.overline)
+}
+
+fn line_impl(
+ name: &str,
+ ctx: &mut EvalContext,
+ args: &mut FuncArgs,
+ substate: impl Fn(&mut FontState) -> &mut Option<LineState> + 'static,
+) -> Value {
+ let color = args.eat_named(ctx, "color");
+ let position = args.eat_named(ctx, "position");
+ let strength = args.eat_named::<Linear>(ctx, "strength");
+ let extent = args.eat_named(ctx, "extent").unwrap_or_default();
+ let body = args.eat::<TemplateValue>(ctx);
+
+ // Suppress any existing strikethrough if strength is explicitly zero.
+ let state = strength.map_or(true, |s| !s.is_zero()).then(|| LineState {
+ fill: color.map(Fill::Color),
+ strength,
+ position,
+ extent,
+ });
+
+ Value::template(name, move |ctx| {
+ let snapshot = ctx.state.clone();
+
+ *substate(&mut ctx.state.font) = state;
+
+ if let Some(body) = &body {
+ body.exec(ctx);
+ ctx.state = snapshot;
+ }
+ })
+}
diff --git a/src/library/font.rs b/src/library/font.rs
index b3b037cd..a3fe6c13 100644
--- a/src/library/font.rs
+++ b/src/library/font.rs
@@ -99,7 +99,7 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
if let Some(color) = color {
- ctx.state.font.color = Fill::Color(color);
+ ctx.state.font.fill = Fill::Color(color);
}
if let Some(FontFamilies(serif)) = &serif {
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 8caddc4c..553b39e6 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -5,6 +5,7 @@
mod align;
mod basic;
+mod decorations;
mod font;
mod grid;
mod image;
@@ -20,6 +21,7 @@ mod stack;
pub use self::image::*;
pub use align::*;
pub use basic::*;
+pub use decorations::*;
pub use font::*;
pub use grid::*;
pub use lang::*;
@@ -55,6 +57,7 @@ pub fn new() -> Scope {
std.def_func("lang", lang);
std.def_func("max", max);
std.def_func("min", min);
+ std.def_func("overline", overline);
std.def_func("pad", pad);
std.def_func("page", page);
std.def_func("pagebreak", pagebreak);
@@ -64,7 +67,9 @@ pub fn new() -> Scope {
std.def_func("rgb", rgb);
std.def_func("square", square);
std.def_func("stack", stack);
+ std.def_func("strike", strike);
std.def_func("type", type_);
+ std.def_func("underline", underline);
std.def_func("v", v);
// Colors.