diff options
| author | Martin Haug <mhaug@live.de> | 2021-06-10 23:08:52 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-06-10 23:15:51 +0200 |
| commit | c28708aa196eaca247cdab6b5e8af9751b4f1dad (patch) | |
| tree | e390e84d1a7a1eb2789680a39141c804ff3f85a1 /src/library | |
| parent | 5611c26577c4cf6d52b9b66b7b1a32253aa23ec1 (diff) | |
Text decorations
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/decorations.rs | 84 | ||||
| -rw-r--r-- | src/library/font.rs | 2 | ||||
| -rw-r--r-- | src/library/mod.rs | 5 |
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. |
