A few predefined colors for testing

This commit is contained in:
Laurenz 2021-05-23 22:59:25 +02:00
parent cd25b40281
commit 14f093bfee
14 changed files with 112 additions and 109 deletions

View File

@ -1,10 +1,10 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt::{self, Debug, Formatter}; use std::fmt::{self, Debug, Display, Formatter};
use std::iter; use std::iter;
use std::rc::Rc; use std::rc::Rc;
use super::Value; use super::{AnyValue, EvalContext, FuncArgs, FuncValue, Type, Value};
/// A slot where a variable is stored. /// A slot where a variable is stored.
pub type Slot = Rc<RefCell<Value>>; pub type Slot = Rc<RefCell<Value>>;
@ -100,6 +100,23 @@ impl Scope {
self.values.insert(var.into(), Rc::new(cell)); self.values.insert(var.into(), Rc::new(cell));
} }
/// Define a constant function.
pub fn def_func<F>(&mut self, name: impl Into<String>, 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<T>(&mut self, var: impl Into<String>, any: T)
where
T: Type + Debug + Display + Clone + PartialEq + 'static,
{
self.def_const(var, AnyValue::new(any))
}
/// Define a mutable variable with a value. /// Define a mutable variable with a value.
pub fn def_mut(&mut self, var: impl Into<String>, value: impl Into<Value>) { pub fn def_mut(&mut self, var: impl Into<String>, value: impl Into<Value>) {
self.values.insert(var.into(), Rc::new(RefCell::new(value.into()))); self.values.insert(var.into(), Rc::new(RefCell::new(value.into())));

View File

@ -6,7 +6,7 @@ use std::ops::Deref;
use std::rc::Rc; use std::rc::Rc;
use super::{EvalContext, NodeMap}; use super::{EvalContext, NodeMap};
use crate::color::Color; use crate::color::{Color, RgbaColor};
use crate::exec::ExecContext; use crate::exec::ExecContext;
use crate::geom::{Angle, Length, Linear, Relative}; use crate::geom::{Angle, Length, Linear, Relative};
use crate::syntax::{Span, Spanned, Tree}; use crate::syntax::{Span, Spanned, Tree};
@ -622,6 +622,12 @@ impl From<&str> for Value {
} }
} }
impl From<RgbaColor> for Value {
fn from(v: RgbaColor) -> Self {
Self::Color(Color::Rgba(v))
}
}
impl From<AnyValue> for Value { impl From<AnyValue> for Value {
fn from(v: AnyValue) -> Self { fn from(v: AnyValue) -> Self {
Self::Any(v) Self::Any(v)

View File

@ -39,16 +39,9 @@ use super::*;
/// - `italic` /// - `italic`
/// - `oblique` /// - `oblique`
/// - Type `font-weight` /// - Type `font-weight`
/// - `thin` (100)
/// - `extralight` (200)
/// - `light` (300)
/// - `regular` (400) /// - `regular` (400)
/// - `medium` (500)
/// - `semibold` (600)
/// - `bold` (700) /// - `bold` (700)
/// - `extrabold` (800) /// - coerces from `integer`, between 100 and 900
/// - `black` (900)
/// - coerces from `integer`
/// - Type `vertical-font-metric` /// - Type `vertical-font-metric`
/// - `ascender` /// - `ascender`
/// - `cap-height` /// - `cap-height`

View File

@ -33,9 +33,8 @@ pub use stack::*;
use std::fmt::{self, Display, Formatter}; use std::fmt::{self, Display, Formatter};
use crate::eval::{ use crate::color::RgbaColor;
AnyValue, EvalContext, FuncArgs, FuncValue, Scope, TemplateValue, Value, use crate::eval::{EvalContext, FuncArgs, Scope, TemplateValue, Value};
};
use crate::exec::{Exec, FontFamily}; use crate::exec::{Exec, FontFamily};
use crate::font::{FontStyle, FontWeight, VerticalFontMetric}; use crate::font::{FontStyle, FontWeight, VerticalFontMetric};
use crate::geom::*; use crate::geom::*;
@ -45,80 +44,68 @@ use crate::syntax::{Node, Spanned};
pub fn new() -> Scope { pub fn new() -> Scope {
let mut std = Scope::new(); 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. // Syntax functions.
func!(Node::LINEBREAK, linebreak); std.def_func(Node::LINEBREAK, linebreak);
func!(Node::PARBREAK, parbreak); std.def_func(Node::PARBREAK, parbreak);
func!(Node::STRONG, strong); std.def_func(Node::STRONG, strong);
func!(Node::EMPH, emph); std.def_func(Node::EMPH, emph);
func!(Node::HEADING, heading); std.def_func(Node::HEADING, heading);
func!(Node::RAW, raw); std.def_func(Node::RAW, raw);
// Library functions. // Library functions.
func!("align", align); std.def_func("align", align);
func!("circle", circle); std.def_func("circle", circle);
func!("ellipse", ellipse); std.def_func("ellipse", ellipse);
func!("font", font); std.def_func("font", font);
func!("h", h); std.def_func("h", h);
func!("image", image); std.def_func("image", image);
func!("lang", lang); std.def_func("lang", lang);
func!("max", max); std.def_func("max", max);
func!("min", min); std.def_func("min", min);
func!("pad", pad); std.def_func("pad", pad);
func!("page", page); std.def_func("page", page);
func!("pagebreak", pagebreak); std.def_func("pagebreak", pagebreak);
func!("par", par); std.def_func("par", par);
func!("rect", rect); std.def_func("rect", rect);
func!("repr", repr); std.def_func("repr", repr);
func!("rgb", rgb); std.def_func("rgb", rgb);
func!("square", square); std.def_func("square", square);
func!("stack", stack); std.def_func("stack", stack);
func!("type", type_); std.def_func("type", type_);
func!("v", v); std.def_func("v", v);
// Constants. // Colors.
constant!("start", AlignValue::Start); std.def_const("white", RgbaColor::WHITE);
constant!("center", AlignValue::Center); std.def_const("black", RgbaColor::BLACK);
constant!("end", AlignValue::End); std.def_const("eastern", RgbaColor::new(0x23, 0x9D, 0xAD, 0xFF));
constant!("left", AlignValue::Left); std.def_const("conifer", RgbaColor::new(0x9f, 0xEB, 0x52, 0xFF));
constant!("right", AlignValue::Right); std.def_const("forest", RgbaColor::new(0x43, 0xA1, 0x27, 0xFF));
constant!("top", AlignValue::Top);
constant!("bottom", AlignValue::Bottom); // Arbitrary constants.
constant!("ltr", Dir::LTR); std.def_any("start", AlignValue::Start);
constant!("rtl", Dir::RTL); std.def_any("center", AlignValue::Center);
constant!("ttb", Dir::TTB); std.def_any("end", AlignValue::End);
constant!("btt", Dir::BTT); std.def_any("left", AlignValue::Left);
constant!("serif", FontFamily::Serif); std.def_any("right", AlignValue::Right);
constant!("sans-serif", FontFamily::SansSerif); std.def_any("top", AlignValue::Top);
constant!("monospace", FontFamily::Monospace); std.def_any("bottom", AlignValue::Bottom);
constant!("normal", FontStyle::Normal); std.def_any("ltr", Dir::LTR);
constant!("italic", FontStyle::Italic); std.def_any("rtl", Dir::RTL);
constant!("oblique", FontStyle::Oblique); std.def_any("ttb", Dir::TTB);
constant!("thin", FontWeight::THIN); std.def_any("btt", Dir::BTT);
constant!("extralight", FontWeight::EXTRALIGHT); std.def_any("serif", FontFamily::Serif);
constant!("light", FontWeight::LIGHT); std.def_any("sans-serif", FontFamily::SansSerif);
constant!("regular", FontWeight::REGULAR); std.def_any("monospace", FontFamily::Monospace);
constant!("medium", FontWeight::MEDIUM); std.def_any("normal", FontStyle::Normal);
constant!("semibold", FontWeight::SEMIBOLD); std.def_any("italic", FontStyle::Italic);
constant!("bold", FontWeight::BOLD); std.def_any("oblique", FontStyle::Oblique);
constant!("extrabold", FontWeight::EXTRABOLD); std.def_any("regular", FontWeight::REGULAR);
constant!("black", FontWeight::BLACK); std.def_any("bold", FontWeight::BOLD);
constant!("ascender", VerticalFontMetric::Ascender); std.def_any("ascender", VerticalFontMetric::Ascender);
constant!("cap-height", VerticalFontMetric::CapHeight); std.def_any("cap-height", VerticalFontMetric::CapHeight);
constant!("x-height", VerticalFontMetric::XHeight); std.def_any("x-height", VerticalFontMetric::XHeight);
constant!("baseline", VerticalFontMetric::Baseline); std.def_any("baseline", VerticalFontMetric::Baseline);
constant!("descender", VerticalFontMetric::Descender); std.def_any("descender", VerticalFontMetric::Descender);
std std
} }

View File

@ -17,8 +17,8 @@
--- ---
// Syntax sugar for function definitions. // Syntax sugar for function definitions.
#let background = #9feb52 #let fill = conifer
#let rect(body) = rect(width: 2cm, fill: background, pad(5pt, body)) #let rect(body) = rect(width: 2cm, fill: fill, pad(5pt, body))
#rect[Hi!] #rect[Hi!]
// Error: 13 expected body // Error: 13 expected body

View File

@ -22,4 +22,4 @@
// Error: 3:11-3:11 missing argument: red component // Error: 3:11-3:11 missing argument: red component
// Error: 2:11-2:11 missing argument: green component // Error: 2:11-2:11 missing argument: green component
// Error: 1:11-1:11 missing argument: blue component // Error: 1:11-1:11 missing argument: blue component
#test(rgb(), #000000) #test(rgb(), black)

View File

@ -7,35 +7,35 @@ Auto-sized circle. \
#circle(fill: #eb5278, align(center, center, [But, soft!])) #circle(fill: #eb5278, align(center, center, [But, soft!]))
Center-aligned rect in auto-sized circle. Center-aligned rect in auto-sized circle.
#circle(fill: #43a127)[ #circle(fill: forest)[
#align(center, center) #align(center, center)
#rect(fill: #9feb52, pad(5pt)[But, soft!]) #rect(fill: conifer, pad(5pt)[But, soft!])
] ]
100%-width rect in auto-sized circle. \ 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? But, soft! what light through yonder window breaks?
]) ])
Expanded by height. Expanded by height.
#circle(fill: #9feb52)[A \ B \ C] #circle(fill: conifer)[A \ B \ C]
--- ---
// Test relative sizing. // Test relative sizing.
#rect(width: 100%, height: 50pt, fill: #aaa)[ #rect(width: 100%, height: 50pt, fill: #aaa)[
#align(center, center) #align(center, center)
#font(color: #fff) #font(color: #fff)
#circle(radius: 10pt, fill: #239DAD)[A] #circle(radius: 10pt, fill: eastern)[A]
#circle(height: 60%, fill: #239DAD)[B] #circle(height: 60%, fill: eastern)[B]
#circle(width: 20% + 20pt, fill: #239DAD)[C] #circle(width: 20% + 20pt, fill: eastern)[C]
] ]
--- ---
// Radius wins over width and height. // Radius wins over width and height.
// Error: 2:23-2:34 unexpected argument // Error: 2:23-2:34 unexpected argument
// Error: 1:36-1:49 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. // Width wins over height.
// Error: 22-34 unexpected argument // Error: 22-34 unexpected argument
#circle(width: 20pt, height: 50pt, fill: #239DAD) #circle(width: 20pt, height: 50pt, fill: eastern)

View File

@ -3,14 +3,14 @@
--- ---
100% rect in 100% ellipse in fixed rect. \ 100% rect in 100% ellipse in fixed rect. \
#rect(width: 3cm, height: 2cm, fill: #2a631a)[ #rect(width: 3cm, height: 2cm, fill: #2a631a)[
#ellipse(width: 100%, height: 100%, fill: #43a127)[ #ellipse(width: 100%, height: 100%, fill: forest)[
#rect(width: 100%, height: 100%, fill: #9feb52)[ #rect(width: 100%, height: 100%, fill: conifer)[
#align(center, center)[Stuff inside an ellipse!] #align(center, center)[Stuff inside an ellipse!]
] ]
] ]
] ]
Auto-sized ellipse. \ Auto-sized ellipse. \
#ellipse(fill: #9feb52)[ #ellipse(fill: conifer)[
But, soft! what light through yonder window breaks? But, soft! what light through yonder window breaks?
] ]

View File

@ -32,13 +32,13 @@ Emoji: 🐪, 🌋, 🏞
] ]
// Colors. // 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. // Test top and bottom edge.
#page(width: 170pt) #page(width: 170pt)
#let try(top, bottom) = rect(fill: #9feb52)[ #let try(top, bottom) = rect(fill: conifer)[
#font(top-edge: top, bottom-edge: bottom) #font(top-edge: top, bottom-edge: bottom)
`From `#top` to `#bottom `From `#top` to `#bottom
] ]

View File

@ -5,7 +5,7 @@
#pad(left: 10pt, [Indented!]) #pad(left: 10pt, [Indented!])
// All sides together. // All sides together.
#rect(fill: #9feb52, #rect(fill: conifer,
pad(10pt, right: 20pt, pad(10pt, right: 20pt,
rect(width: 20pt, height: 20pt, fill: #eb5278))) rect(width: 20pt, height: 20pt, fill: #eb5278)))

View File

@ -6,7 +6,7 @@
#page(width: 150pt) #page(width: 150pt)
// Fit to text. // Fit to text.
#rect(fill: #9feb52)[Textbox] #rect(fill: conifer)[Textbox]
// Empty with fixed width and height. // Empty with fixed width and height.
#rect(width: 3cm, height: 12pt, fill: #CB4CED) #rect(width: 3cm, height: 12pt, fill: #CB4CED)

View File

@ -2,7 +2,7 @@
--- ---
Auto-sized square. \ Auto-sized square. \
#square(fill: #239DAD)[ #square(fill: eastern)[
#align(center) #align(center)
#pad(5pt)[ #pad(5pt)[
#font(color: #fff, weight: bold) #font(color: #fff, weight: bold)
@ -19,13 +19,13 @@ Auto-sized square. \
--- ---
// Test height overflow. // Test height overflow.
#page(width: 75pt, height: 100pt) #page(width: 75pt, height: 100pt)
#square(fill: #9feb52)[ #square(fill: conifer)[
But, soft! what light through yonder window breaks? But, soft! what light through yonder window breaks?
] ]
--- ---
// Test width overflow. // Test width overflow.
#page(width: 100pt, height: 75pt) #page(width: 100pt, height: 75pt)
#square(fill: #9feb52)[ #square(fill: conifer)[
But, soft! what light through yonder window breaks? But, soft! what light through yonder window breaks?
] ]

View File

@ -4,6 +4,6 @@
#let rect(width, color) = rect(width: width, height: 1cm, fill: color) #let rect(width, color) = rect(width: width, height: 1cm, fill: color)
#stack( #stack(
rect(2cm, #2a631a), rect(2cm, #2a631a),
rect(3cm, #43a127), rect(3cm, forest),
rect(1cm, #9feb52), rect(1cm, conifer),
) )

View File

@ -3,7 +3,7 @@
--- ---
#let linebreak() = [ #let linebreak() = [
// Inside the old line break definition is still active. // Inside the old line break definition is still active.
#square(length: 3pt, fill: #000) \ #square(length: 3pt, fill: black) \
] ]
A \ B \ C A \ B \ C