diff options
| author | Laurenz <laurmaedje@gmail.com> | 2020-12-21 00:40:09 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2020-12-21 00:40:09 +0100 |
| commit | e59de77f96d43fa675c5c733ccf39ec2c22e949e (patch) | |
| tree | 84d746c1d1ad863b8c8e2e9fda86ed842634a838 /src/library/style.rs | |
| parent | 2b660968aa7e1e8efb7c396e17066a1a98c8c10e (diff) | |
Allow only a few predefined font classes in [font] 🚧
Diffstat (limited to 'src/library/style.rs')
| -rw-r--r-- | src/library/style.rs | 120 |
1 files changed, 72 insertions, 48 deletions
diff --git a/src/library/style.rs b/src/library/style.rs index c641a598..0cc40f94 100644 --- a/src/library/style.rs +++ b/src/library/style.rs @@ -10,34 +10,59 @@ use crate::prelude::*; /// `font`: Configure the font. /// /// # Positional arguments -/// - The font size (optional, length or relative to current font size). -/// - All identifier and string arguments are interpreted as an ordered list of -/// fallback font families. +/// - Font size (optional, `linear` relative to current font size). +/// - Font families ... (optional, variadic, `Family`) /// -/// An example invocation could look like this: +/// # Keyword arguments +/// - `style` (`Style`): The font style. +/// - `weight` (`Weight`): The font weight. +/// - `stretch` (`Stretch`): The font stretch. +/// - `serif` (`Family` or `dict` of type `Family`): The serif family. +/// - `sans-serif` (`Family` or `dict` of type `Family`): The new sansserif family. +/// - `monospace` (`Family` or `dict` of type `Family`): The monospace family. +/// - `emoji` (`Family` or `dict` of type `Family`): The emoji family. +/// - `math` (`Family` or `dict` of type `Family`): The math family. +/// +/// # Examples +/// Set font size and font families. /// ```typst -/// [font: 12pt, Arial, "Noto Sans", sans-serif] +/// [font: 12pt, "Arial", "Noto Sans", sans-serif] /// ``` /// -/// # Keyword arguments -/// - `style` +/// Redefine the default sans-serif family to a single font family. +/// ```typst +/// [font: sans-serif="Source Sans Pro"] +/// ``` +/// +/// Redefine the default emoji family with a fallback. +/// ```typst +/// [font: emoji=("Segoe UI Emoji", "Noto Emoji")] +/// ``` +/// +/// # Enumerations +/// - `Family` +/// - `serif` +/// - `sans-serif` +/// - `monospace` +/// - `emoji` +/// - `math` +/// - any string +/// - `Style` /// - `normal` /// - `italic` /// - `oblique` -/// -/// - `weight` -/// - `thin` or `hairline` (`100`) -/// - `extralight` (`200`) -/// - `light` (`300`) -/// - `regular` (`400`) -/// - `medium` (`500`) -/// - `semibold` (`600`) -/// - `bold` (`700`) -/// - `extrabold` (`800`) -/// - `black` (`900`) -/// - integer between `100` and `900` -/// -/// - `stretch` +/// - `Weight` +/// - `thin` or `hairline` (100) +/// - `extralight` (200) +/// - `light` (300) +/// - `regular` (400) +/// - `medium` (500) +/// - `semibold` (600) +/// - `bold` (700) +/// - `extrabold` (800) +/// - `black` (900) +/// - any integer between 100 and 900 +/// - `Stretch` /// - `ultra-condensed` /// - `extra-condensed` /// - `condensed` @@ -47,17 +72,6 @@ use crate::prelude::*; /// - `expanded` /// - `extra-expanded` /// - `ultra-expanded` -/// -/// - Any other keyword argument whose value is a dictionary of strings defines -/// a fallback class, for example: -/// ```typst -/// [font: serif = ("Source Serif Pro", "Noto Serif")] -/// ``` -/// This class can be used in the fallback list or other fallback classes as -/// long as the resulting fallback tree is acyclic. -/// ```typst -/// [font: "My Serif", serif] -/// ``` pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value { let snapshot = ctx.state.clone(); let body = args.find::<SynTree>(); @@ -71,6 +85,14 @@ pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value { } } + let mut needs_flattening = false; + let list: Vec<_> = args.find_all::<StringLike>().map(|s| s.to_lowercase()).collect(); + + if !list.is_empty() { + Rc::make_mut(&mut ctx.state.font.families).list = list; + needs_flattening = true; + } + if let Some(style) = args.get::<_, FontStyle>(ctx, "style") { ctx.state.font.variant.style = style; } @@ -83,21 +105,23 @@ pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value { ctx.state.font.variant.stretch = stretch; } - let mut needs_flattening = false; - let list: Vec<_> = args.find_all::<StringLike>().map(|s| s.to_lowercase()).collect(); - if !list.is_empty() { - Rc::make_mut(&mut ctx.state.font.families).list = list; - needs_flattening = true; - } + struct FontList(Vec<String>); - for (class, dict) in args.find_all_str::<Spanned<ValueDict>>() { - let fallback = Args(dict) + try_from_match!(FontList["font or list of fonts"] @ span: + Value::Str(v) => Self(vec![v.to_lowercase()]), + Value::Dict(v) => Self(Args(v.span_with(span)) .find_all::<StringLike>() .map(|s| s.to_lowercase()) - .collect(); - - Rc::make_mut(&mut ctx.state.font.families).update_class_list(class, fallback); - needs_flattening = true; + .collect() + ), + ); + + for &class in &["serif", "sans-serif", "monospace", "emoji", "math"] { + if let Some(list) = args.get::<_, FontList>(ctx, class) { + Rc::make_mut(&mut ctx.state.font.families) + .update_class_list(class.to_string(), list.0); + needs_flattening = true; + } } if needs_flattening { @@ -117,10 +141,10 @@ pub fn font(mut args: Args, ctx: &mut EvalContext) -> Value { /// `rgb`: Create an RGB(A) color. /// /// # Positional arguments -/// - The red component (float between 0.0 and 1.0). -/// - The green component (float between 0.0 and 1.0). -/// - The blue component (float between 0.0 and 1.0). -/// - The alpha component (optional, float between 0.0 and 1.0). +/// - Red component (`float` between 0.0 and 1.0). +/// - Green component (`float` between 0.0 and 1.0). +/// - Blue component (`float` between 0.0 and 1.0). +/// - Alpha component (optional, `float` between 0.0 and 1.0). pub fn rgb(mut args: Args, ctx: &mut EvalContext) -> Value { let r = args.need::<_, Spanned<f64>>(ctx, 0, "red component"); let g = args.need::<_, Spanned<f64>>(ctx, 1, "green component"); |
