From 14f093bfee3d0871d9796a0dcaf1648b76010930 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sun, 23 May 2021 22:59:25 +0200 Subject: [PATCH] A few predefined colors for testing --- src/eval/scope.rs | 21 +++++- src/eval/value.rs | 8 +- src/library/font.rs | 9 +-- src/library/mod.rs | 133 +++++++++++++++------------------- tests/typ/code/let.typ | 4 +- tests/typ/library/basic.typ | 2 +- tests/typ/library/circle.typ | 18 ++--- tests/typ/library/ellipse.typ | 6 +- tests/typ/library/font.typ | 4 +- tests/typ/library/pad.typ | 2 +- tests/typ/library/rect.typ | 2 +- tests/typ/library/square.typ | 6 +- tests/typ/library/stack.typ | 4 +- tests/typ/markup/basic.typ | 2 +- 14 files changed, 112 insertions(+), 109 deletions(-) diff --git a/src/eval/scope.rs b/src/eval/scope.rs index 20c183063..a3c9234b2 100644 --- a/src/eval/scope.rs +++ b/src/eval/scope.rs @@ -1,10 +1,10 @@ use std::cell::RefCell; use std::collections::HashMap; -use std::fmt::{self, Debug, Formatter}; +use std::fmt::{self, Debug, Display, Formatter}; use std::iter; use std::rc::Rc; -use super::Value; +use super::{AnyValue, EvalContext, FuncArgs, FuncValue, Type, Value}; /// A slot where a variable is stored. pub type Slot = Rc>; @@ -100,6 +100,23 @@ impl Scope { self.values.insert(var.into(), Rc::new(cell)); } + /// Define a constant function. + pub fn def_func(&mut self, name: impl Into, f: F) + where + F: Fn(&mut EvalContext, &mut FuncArgs) -> Value + 'static, + { + let name = name.into(); + self.def_const(name.clone(), FuncValue::new(Some(name), f)); + } + + /// Define a constant variable with a value of variant `Value::Any`. + pub fn def_any(&mut self, var: impl Into, any: T) + where + T: Type + Debug + Display + Clone + PartialEq + 'static, + { + self.def_const(var, AnyValue::new(any)) + } + /// Define a mutable variable with a value. pub fn def_mut(&mut self, var: impl Into, value: impl Into) { self.values.insert(var.into(), Rc::new(RefCell::new(value.into()))); diff --git a/src/eval/value.rs b/src/eval/value.rs index a69398f09..0d87c28f6 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -6,7 +6,7 @@ use std::ops::Deref; use std::rc::Rc; use super::{EvalContext, NodeMap}; -use crate::color::Color; +use crate::color::{Color, RgbaColor}; use crate::exec::ExecContext; use crate::geom::{Angle, Length, Linear, Relative}; use crate::syntax::{Span, Spanned, Tree}; @@ -622,6 +622,12 @@ impl From<&str> for Value { } } +impl From for Value { + fn from(v: RgbaColor) -> Self { + Self::Color(Color::Rgba(v)) + } +} + impl From for Value { fn from(v: AnyValue) -> Self { Self::Any(v) diff --git a/src/library/font.rs b/src/library/font.rs index 64aec75b8..33a521f53 100644 --- a/src/library/font.rs +++ b/src/library/font.rs @@ -39,16 +39,9 @@ use super::*; /// - `italic` /// - `oblique` /// - Type `font-weight` -/// - `thin` (100) -/// - `extralight` (200) -/// - `light` (300) /// - `regular` (400) -/// - `medium` (500) -/// - `semibold` (600) /// - `bold` (700) -/// - `extrabold` (800) -/// - `black` (900) -/// - coerces from `integer` +/// - coerces from `integer`, between 100 and 900 /// - Type `vertical-font-metric` /// - `ascender` /// - `cap-height` diff --git a/src/library/mod.rs b/src/library/mod.rs index a6628315e..6a46314c7 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -33,9 +33,8 @@ pub use stack::*; use std::fmt::{self, Display, Formatter}; -use crate::eval::{ - AnyValue, EvalContext, FuncArgs, FuncValue, Scope, TemplateValue, Value, -}; +use crate::color::RgbaColor; +use crate::eval::{EvalContext, FuncArgs, Scope, TemplateValue, Value}; use crate::exec::{Exec, FontFamily}; use crate::font::{FontStyle, FontWeight, VerticalFontMetric}; use crate::geom::*; @@ -45,80 +44,68 @@ use crate::syntax::{Node, Spanned}; pub fn new() -> Scope { let mut std = Scope::new(); - macro_rules! func { - ($name:expr, $func:expr) => { - std.def_const($name, FuncValue::new(Some($name.into()), $func)) - }; - } - - macro_rules! constant { - ($var:expr, $any:expr) => { - std.def_const($var, AnyValue::new($any)) - }; - } - // Syntax functions. - func!(Node::LINEBREAK, linebreak); - func!(Node::PARBREAK, parbreak); - func!(Node::STRONG, strong); - func!(Node::EMPH, emph); - func!(Node::HEADING, heading); - func!(Node::RAW, raw); + std.def_func(Node::LINEBREAK, linebreak); + std.def_func(Node::PARBREAK, parbreak); + std.def_func(Node::STRONG, strong); + std.def_func(Node::EMPH, emph); + std.def_func(Node::HEADING, heading); + std.def_func(Node::RAW, raw); // Library functions. - func!("align", align); - func!("circle", circle); - func!("ellipse", ellipse); - func!("font", font); - func!("h", h); - func!("image", image); - func!("lang", lang); - func!("max", max); - func!("min", min); - func!("pad", pad); - func!("page", page); - func!("pagebreak", pagebreak); - func!("par", par); - func!("rect", rect); - func!("repr", repr); - func!("rgb", rgb); - func!("square", square); - func!("stack", stack); - func!("type", type_); - func!("v", v); + std.def_func("align", align); + std.def_func("circle", circle); + std.def_func("ellipse", ellipse); + std.def_func("font", font); + std.def_func("h", h); + std.def_func("image", image); + std.def_func("lang", lang); + std.def_func("max", max); + std.def_func("min", min); + std.def_func("pad", pad); + std.def_func("page", page); + std.def_func("pagebreak", pagebreak); + std.def_func("par", par); + std.def_func("rect", rect); + std.def_func("repr", repr); + std.def_func("rgb", rgb); + std.def_func("square", square); + std.def_func("stack", stack); + std.def_func("type", type_); + std.def_func("v", v); - // Constants. - constant!("start", AlignValue::Start); - constant!("center", AlignValue::Center); - constant!("end", AlignValue::End); - constant!("left", AlignValue::Left); - constant!("right", AlignValue::Right); - constant!("top", AlignValue::Top); - constant!("bottom", AlignValue::Bottom); - constant!("ltr", Dir::LTR); - constant!("rtl", Dir::RTL); - constant!("ttb", Dir::TTB); - constant!("btt", Dir::BTT); - constant!("serif", FontFamily::Serif); - constant!("sans-serif", FontFamily::SansSerif); - constant!("monospace", FontFamily::Monospace); - constant!("normal", FontStyle::Normal); - constant!("italic", FontStyle::Italic); - constant!("oblique", FontStyle::Oblique); - constant!("thin", FontWeight::THIN); - constant!("extralight", FontWeight::EXTRALIGHT); - constant!("light", FontWeight::LIGHT); - constant!("regular", FontWeight::REGULAR); - constant!("medium", FontWeight::MEDIUM); - constant!("semibold", FontWeight::SEMIBOLD); - constant!("bold", FontWeight::BOLD); - constant!("extrabold", FontWeight::EXTRABOLD); - constant!("black", FontWeight::BLACK); - constant!("ascender", VerticalFontMetric::Ascender); - constant!("cap-height", VerticalFontMetric::CapHeight); - constant!("x-height", VerticalFontMetric::XHeight); - constant!("baseline", VerticalFontMetric::Baseline); - constant!("descender", VerticalFontMetric::Descender); + // Colors. + std.def_const("white", RgbaColor::WHITE); + std.def_const("black", RgbaColor::BLACK); + std.def_const("eastern", RgbaColor::new(0x23, 0x9D, 0xAD, 0xFF)); + std.def_const("conifer", RgbaColor::new(0x9f, 0xEB, 0x52, 0xFF)); + std.def_const("forest", RgbaColor::new(0x43, 0xA1, 0x27, 0xFF)); + + // Arbitrary constants. + std.def_any("start", AlignValue::Start); + std.def_any("center", AlignValue::Center); + std.def_any("end", AlignValue::End); + std.def_any("left", AlignValue::Left); + std.def_any("right", AlignValue::Right); + std.def_any("top", AlignValue::Top); + std.def_any("bottom", AlignValue::Bottom); + std.def_any("ltr", Dir::LTR); + std.def_any("rtl", Dir::RTL); + std.def_any("ttb", Dir::TTB); + std.def_any("btt", Dir::BTT); + std.def_any("serif", FontFamily::Serif); + std.def_any("sans-serif", FontFamily::SansSerif); + std.def_any("monospace", FontFamily::Monospace); + std.def_any("normal", FontStyle::Normal); + std.def_any("italic", FontStyle::Italic); + std.def_any("oblique", FontStyle::Oblique); + std.def_any("regular", FontWeight::REGULAR); + std.def_any("bold", FontWeight::BOLD); + std.def_any("ascender", VerticalFontMetric::Ascender); + std.def_any("cap-height", VerticalFontMetric::CapHeight); + std.def_any("x-height", VerticalFontMetric::XHeight); + std.def_any("baseline", VerticalFontMetric::Baseline); + std.def_any("descender", VerticalFontMetric::Descender); std } diff --git a/tests/typ/code/let.typ b/tests/typ/code/let.typ index 4f84aa670..49abec531 100644 --- a/tests/typ/code/let.typ +++ b/tests/typ/code/let.typ @@ -17,8 +17,8 @@ --- // Syntax sugar for function definitions. -#let background = #9feb52 -#let rect(body) = rect(width: 2cm, fill: background, pad(5pt, body)) +#let fill = conifer +#let rect(body) = rect(width: 2cm, fill: fill, pad(5pt, body)) #rect[Hi!] // Error: 13 expected body diff --git a/tests/typ/library/basic.typ b/tests/typ/library/basic.typ index a16215a75..dab0fc172 100644 --- a/tests/typ/library/basic.typ +++ b/tests/typ/library/basic.typ @@ -22,4 +22,4 @@ // Error: 3:11-3:11 missing argument: red component // Error: 2:11-2:11 missing argument: green component // Error: 1:11-1:11 missing argument: blue component -#test(rgb(), #000000) +#test(rgb(), black) diff --git a/tests/typ/library/circle.typ b/tests/typ/library/circle.typ index b395ee2be..d2fa928e4 100644 --- a/tests/typ/library/circle.typ +++ b/tests/typ/library/circle.typ @@ -7,35 +7,35 @@ Auto-sized circle. \ #circle(fill: #eb5278, align(center, center, [But, soft!])) Center-aligned rect in auto-sized circle. -#circle(fill: #43a127)[ +#circle(fill: forest)[ #align(center, center) - #rect(fill: #9feb52, pad(5pt)[But, soft!]) + #rect(fill: conifer, pad(5pt)[But, soft!]) ] 100%-width rect in auto-sized circle. \ -#circle(fill: #43a127, rect(width: 100%, fill: #9feb52)[ +#circle(fill: forest, rect(width: 100%, fill: conifer)[ But, soft! what light through yonder window breaks? ]) Expanded by height. -#circle(fill: #9feb52)[A \ B \ C] +#circle(fill: conifer)[A \ B \ C] --- // Test relative sizing. #rect(width: 100%, height: 50pt, fill: #aaa)[ #align(center, center) #font(color: #fff) - #circle(radius: 10pt, fill: #239DAD)[A] - #circle(height: 60%, fill: #239DAD)[B] - #circle(width: 20% + 20pt, fill: #239DAD)[C] + #circle(radius: 10pt, fill: eastern)[A] + #circle(height: 60%, fill: eastern)[B] + #circle(width: 20% + 20pt, fill: eastern)[C] ] --- // Radius wins over width and height. // Error: 2:23-2:34 unexpected argument // Error: 1:36-1:49 unexpected argument -#circle(radius: 10pt, width: 50pt, height: 100pt, fill: #239DAD) +#circle(radius: 10pt, width: 50pt, height: 100pt, fill: eastern) // Width wins over height. // Error: 22-34 unexpected argument -#circle(width: 20pt, height: 50pt, fill: #239DAD) +#circle(width: 20pt, height: 50pt, fill: eastern) diff --git a/tests/typ/library/ellipse.typ b/tests/typ/library/ellipse.typ index 06d84a114..9b10eded0 100644 --- a/tests/typ/library/ellipse.typ +++ b/tests/typ/library/ellipse.typ @@ -3,14 +3,14 @@ --- 100% rect in 100% ellipse in fixed rect. \ #rect(width: 3cm, height: 2cm, fill: #2a631a)[ - #ellipse(width: 100%, height: 100%, fill: #43a127)[ - #rect(width: 100%, height: 100%, fill: #9feb52)[ + #ellipse(width: 100%, height: 100%, fill: forest)[ + #rect(width: 100%, height: 100%, fill: conifer)[ #align(center, center)[Stuff inside an ellipse!] ] ] ] Auto-sized ellipse. \ -#ellipse(fill: #9feb52)[ +#ellipse(fill: conifer)[ But, soft! what light through yonder window breaks? ] diff --git a/tests/typ/library/font.typ b/tests/typ/library/font.typ index 397452e37..34b08f26c 100644 --- a/tests/typ/library/font.typ +++ b/tests/typ/library/font.typ @@ -32,13 +32,13 @@ Emoji: 🐪, 🌋, 🏞 ] // Colors. -#font(color: #239DAD)[This is #font(color: #FA644B)[way more] colorful.] +#font(color: eastern)[This is #font(color: #FA644B)[way more] colorful.] --- // Test top and bottom edge. #page(width: 170pt) -#let try(top, bottom) = rect(fill: #9feb52)[ +#let try(top, bottom) = rect(fill: conifer)[ #font(top-edge: top, bottom-edge: bottom) `From `#top` to `#bottom ] diff --git a/tests/typ/library/pad.typ b/tests/typ/library/pad.typ index c3d3786ba..3726ce53d 100644 --- a/tests/typ/library/pad.typ +++ b/tests/typ/library/pad.typ @@ -5,7 +5,7 @@ #pad(left: 10pt, [Indented!]) // All sides together. -#rect(fill: #9feb52, +#rect(fill: conifer, pad(10pt, right: 20pt, rect(width: 20pt, height: 20pt, fill: #eb5278))) diff --git a/tests/typ/library/rect.typ b/tests/typ/library/rect.typ index 9acb0975b..f450064a4 100644 --- a/tests/typ/library/rect.typ +++ b/tests/typ/library/rect.typ @@ -6,7 +6,7 @@ #page(width: 150pt) // Fit to text. -#rect(fill: #9feb52)[Textbox] +#rect(fill: conifer)[Textbox] // Empty with fixed width and height. #rect(width: 3cm, height: 12pt, fill: #CB4CED) diff --git a/tests/typ/library/square.typ b/tests/typ/library/square.typ index deb978538..649d31c03 100644 --- a/tests/typ/library/square.typ +++ b/tests/typ/library/square.typ @@ -2,7 +2,7 @@ --- Auto-sized square. \ -#square(fill: #239DAD)[ +#square(fill: eastern)[ #align(center) #pad(5pt)[ #font(color: #fff, weight: bold) @@ -19,13 +19,13 @@ Auto-sized square. \ --- // Test height overflow. #page(width: 75pt, height: 100pt) -#square(fill: #9feb52)[ +#square(fill: conifer)[ But, soft! what light through yonder window breaks? ] --- // Test width overflow. #page(width: 100pt, height: 75pt) -#square(fill: #9feb52)[ +#square(fill: conifer)[ But, soft! what light through yonder window breaks? ] diff --git a/tests/typ/library/stack.typ b/tests/typ/library/stack.typ index c773ec79b..d03a95c8b 100644 --- a/tests/typ/library/stack.typ +++ b/tests/typ/library/stack.typ @@ -4,6 +4,6 @@ #let rect(width, color) = rect(width: width, height: 1cm, fill: color) #stack( rect(2cm, #2a631a), - rect(3cm, #43a127), - rect(1cm, #9feb52), + rect(3cm, forest), + rect(1cm, conifer), ) diff --git a/tests/typ/markup/basic.typ b/tests/typ/markup/basic.typ index bfe3d2cb0..24c23e64d 100644 --- a/tests/typ/markup/basic.typ +++ b/tests/typ/markup/basic.typ @@ -3,7 +3,7 @@ --- #let linebreak() = [ // Inside the old line break definition is still active. - #square(length: 3pt, fill: #000) \ + #square(length: 3pt, fill: black) \ ] A \ B \ C