Cleaning 🧹

This commit is contained in:
Laurenz 2021-02-12 22:55:26 +01:00
parent a2fcc1bf28
commit 790dc9e667
20 changed files with 167 additions and 193 deletions

View File

@ -8,7 +8,6 @@ use super::*;
use crate::color::Color;
use crate::exec::ExecContext;
use crate::geom::{Angle, Length, Linear, Relative};
use crate::pretty::{Pretty, Printer};
use crate::syntax::Tree;
/// A computational value.
@ -103,22 +102,6 @@ pub type ValueArray = Vec<Value>;
/// A dictionary value: `(color: #f79143, pattern: dashed)`.
pub type ValueDict = BTreeMap<String, Value>;
impl Pretty for ValueDict {
fn pretty(&self, p: &mut Printer) {
p.push('(');
if self.is_empty() {
p.push(':');
} else {
p.join(self, ", ", |(key, value), p| {
p.push_str(key);
p.push_str(": ");
value.pretty(p);
});
}
p.push(')');
}
}
/// A template value: `[*Hi* there]`.
pub type ValueTemplate = Vec<TemplateNode>;
@ -156,7 +139,6 @@ impl TemplateAny {
Self { name: name.into(), f: Rc::new(f) }
}
/// The name of the template node.
pub fn name(&self) -> &str {
&self.name
@ -358,13 +340,6 @@ impl ValueArgs {
}
}
// This is a workaround because `-> impl Trait + 'a + 'b` does not work.
//
// See also: https://github.com/rust-lang/rust/issues/49431
#[doc(hidden)]
pub trait Captures<'a> {}
impl<'a, T: ?Sized> Captures<'a> for T {}
/// An argument to a function call: `12` or `draw: false`.
#[derive(Debug, Clone, PartialEq)]
pub struct ValueArg {
@ -681,80 +656,3 @@ macro_rules! typify {
}
};
}
#[cfg(test)]
mod tests {
use super::*;
use crate::color::RgbaColor;
use crate::pretty::pretty;
#[track_caller]
fn test_pretty(value: impl Into<Value>, exp: &str) {
assert_eq!(pretty(&value.into()), exp);
}
#[test]
fn test_pretty_print_value() {
// Simple values.
test_pretty(Value::None, "none");
test_pretty(false, "false");
test_pretty(12, "12");
test_pretty(3.14, "3.14");
test_pretty(Length::pt(5.5), "5.5pt");
test_pretty(Angle::deg(90.0), "90.0deg");
test_pretty(Relative::ONE / 2.0, "50.0%");
test_pretty(Relative::new(0.3) + Length::cm(2.0), "30.0% + 2.0cm");
test_pretty(Color::Rgba(RgbaColor::new(1, 1, 1, 0xff)), "#010101");
test_pretty("hello", r#""hello""#);
// Array.
test_pretty(Value::Array(vec![]), "()");
test_pretty(vec![Value::None], "(none,)");
test_pretty(vec![Value::Int(1), Value::Int(2)], "(1, 2)");
// Dictionary.
let mut dict = BTreeMap::new();
test_pretty(dict.clone(), "(:)");
dict.insert("one".into(), Value::Int(1));
test_pretty(dict.clone(), "(one: 1)");
dict.insert("two".into(), Value::Bool(false));
test_pretty(dict, "(one: 1, two: false)");
// Template.
test_pretty(
vec![
TemplateNode::Tree {
tree: Rc::new(vec![Node::Strong]),
map: HashMap::new(),
},
TemplateNode::Any(TemplateAny::new("example", |_| {})),
],
"[*<example>]",
);
// Function and arguments.
test_pretty(ValueFunc::new("nil", |_, _| Value::None), "<nil>");
test_pretty(
ValueArgs {
span: Span::ZERO,
items: vec![
ValueArg {
name: Some(Spanned::zero("a".into())),
value: Spanned::zero(Value::Int(1)),
},
ValueArg {
name: None,
value: Spanned::zero(Value::Int(2)),
},
],
},
"<a: 1, 2>",
);
// Any.
test_pretty(ValueAny::new(1), "1");
// Error.
test_pretty(Value::Error, "<error>");
}
}

View File

@ -145,8 +145,8 @@ impl Exec for Value {
impl Exec for ValueTemplate {
fn exec(&self, ctx: &mut ExecContext) {
for part in self {
part.exec(ctx);
for node in self {
node.exec(ctx);
}
}
}

View File

@ -44,8 +44,8 @@ pub struct PageSettings {
pub size: Size,
/// Whether the expand the pages to the `size` or to fit the content.
pub expand: Spec<Expansion>,
/// The amount of white space in the order [left, top, right, bottom]. If a
/// side is set to `None`, the default for the paper class is used.
/// The amount of white space on each side of the page. If a side is set to
/// `None`, the default for the paper class is used.
pub margins: Sides<Option<Linear>>,
}

View File

@ -107,7 +107,7 @@ impl Display for Length {
use LengthUnit::*;
// Format with the unit that yields the shortest output, preferring
// larger / metrics units when tied.
// larger / metric units when tied.
let mut buf = ryu::Buffer::new();
let unit = [Cm, Mm, In, Pt]
.iter()

View File

@ -1,11 +1,11 @@
use super::*;
/// A node that represents a rectangular box.
/// A node that places a rectangular filled background behind another node.
#[derive(Debug, Clone, PartialEq)]
pub struct NodeBackground {
/// The background fill.
pub fill: Fill,
/// The child node to be filled in.
/// The child node to be filled.
pub child: Node,
}
@ -13,17 +13,12 @@ impl Layout for NodeBackground {
fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
let mut layouted = self.child.layout(ctx, areas);
if let Some(first) = layouted.frames_mut().first_mut() {
first.elements.insert(
0,
(
Point::ZERO,
Element::Geometry(Geometry {
shape: Shape::Rect(first.size),
fill: self.fill.clone(),
}),
),
)
for frame in layouted.frames_mut() {
let element = Element::Geometry(Geometry {
shape: Shape::Rect(frame.size),
fill: self.fill.clone(),
});
frame.elements.insert(0, (Point::ZERO, element))
}
layouted

View File

@ -293,6 +293,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
None
})
});
let width = args.get(ctx, "width");
let height = args.get(ctx, "height");
let margins = args.get(ctx, "margins");
@ -352,7 +353,6 @@ pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
std::mem::swap(&mut page.expand.horizontal, &mut page.expand.vertical);
}
ctx.set_dirs(Gen::new(main, cross));
let mut softness = ctx.end_page_group(|_| false);

View File

@ -508,6 +508,22 @@ impl Pretty for ValueArray {
}
}
impl Pretty for ValueDict {
fn pretty(&self, p: &mut Printer) {
p.push('(');
if self.is_empty() {
p.push(':');
} else {
p.join(self, ", ", |(key, value), p| {
p.push_str(key);
p.push_str(": ");
value.pretty(p);
});
}
p.push(')');
}
}
impl Pretty for ValueTemplate {
fn pretty(&self, p: &mut Printer) {
p.push('[');
@ -529,7 +545,7 @@ impl Pretty for TemplateNode {
impl Pretty for TemplateAny {
fn pretty(&self, p: &mut Printer) {
p.push('<');
p.push_str("<node ");
p.push_str(self.name());
p.push('>');
}
@ -537,7 +553,7 @@ impl Pretty for TemplateAny {
impl Pretty for ValueFunc {
fn pretty(&self, p: &mut Printer) {
p.push('<');
p.push_str("<function ");
p.push_str(self.name());
p.push('>');
}
@ -545,9 +561,9 @@ impl Pretty for ValueFunc {
impl Pretty for ValueArgs {
fn pretty(&self, p: &mut Printer) {
p.push('<');
p.push('(');
p.join(&self.items, ", ", |item, p| item.pretty(p));
p.push('>');
p.push(')');
}
}
@ -613,13 +629,22 @@ pretty_display! {
#[cfg(test)]
mod tests {
use std::collections::{BTreeMap, HashMap};
use std::rc::Rc;
use super::*;
use crate::color::RgbaColor;
use crate::env::Env;
use crate::eval::eval;
use crate::parse::parse;
#[track_caller]
fn test(src: &str, exp: &str) {
fn roundtrip(src: &str) {
test_parse(src, src);
}
#[track_caller]
fn test_parse(src: &str, exp: &str) {
let tree = parse(src).output;
let found = pretty(&tree);
if exp != found {
@ -631,8 +656,8 @@ mod tests {
}
#[track_caller]
fn roundtrip(src: &str) {
test(src, src);
fn test_value(value: impl Into<Value>, exp: &str) {
assert_eq!(pretty(&value.into()), exp);
}
#[test]
@ -659,11 +684,11 @@ mod tests {
roundtrip("```\n`\n```");
roundtrip("``` ` ```");
roundtrip("````\n```\n```\n````");
test("```lang```", "```lang ```");
test("```1 ```", "``");
test("``` 1```", "`1`");
test("``` 1 ```", "`1 `");
test("```` ` ````", "``` ` ```");
test_parse("```lang```", "```lang ```");
test_parse("```1 ```", "``");
test_parse("``` 1```", "`1`");
test_parse("``` 1 ```", "`1 `");
test_parse("```` ` ````", "``` ` ```");
}
#[test]
@ -679,7 +704,7 @@ mod tests {
roundtrip("{20.0%}");
roundtrip("{#abcdef}");
roundtrip(r#"{"hi"}"#);
test(r#"{"let's \" go"}"#, r#"{"let's \" go"}"#);
test_parse(r#"{"let's \" go"}"#, r#"{"let's \" go"}"#);
// Arrays.
roundtrip("{()}");
@ -720,8 +745,8 @@ mod tests {
roundtrip("#[v 1]");
roundtrip("#[v 1, 2][*Ok*]");
roundtrip("#[v 1 | f 2]");
test("{#[v]}", "{v()}");
test("#[v 1, #[f 2]]", "#[v 1 | f 2]");
test_parse("{#[v]}", "{v()}");
test_parse("#[v 1, #[f 2]]", "#[v 1 | f 2]");
// Keywords.
roundtrip("#let x = 1 + 2");
@ -738,9 +763,70 @@ mod tests {
}
#[test]
fn test_pretty_print_str() {
assert_eq!(pretty("\n"), r#""\n""#);
assert_eq!(pretty("\\"), r#""\\""#);
assert_eq!(pretty("\""), r#""\"""#);
fn test_pretty_print_value() {
// Simple values.
test_value(Value::None, "none");
test_value(false, "false");
test_value(12, "12");
test_value(3.14, "3.14");
test_value(Length::pt(5.5), "5.5pt");
test_value(Angle::deg(90.0), "90.0deg");
test_value(Relative::ONE / 2.0, "50.0%");
test_value(Relative::new(0.3) + Length::cm(2.0), "30.0% + 2.0cm");
test_value(Color::Rgba(RgbaColor::new(1, 1, 1, 0xff)), "#010101");
test_value("hello", r#""hello""#);
test_value("\n", r#""\n""#);
test_value("\\", r#""\\""#);
test_value("\"", r#""\"""#);
// Array.
test_value(Value::Array(vec![]), "()");
test_value(vec![Value::None], "(none,)");
test_value(vec![Value::Int(1), Value::Int(2)], "(1, 2)");
// Dictionary.
let mut dict = BTreeMap::new();
test_value(dict.clone(), "(:)");
dict.insert("one".into(), Value::Int(1));
test_value(dict.clone(), "(one: 1)");
dict.insert("two".into(), Value::Bool(false));
test_value(dict, "(one: 1, two: false)");
// Template.
test_value(
vec![
TemplateNode::Tree {
tree: Rc::new(vec![Node::Strong]),
map: HashMap::new(),
},
TemplateNode::Any(TemplateAny::new("example", |_| {})),
],
"[*<node example>]",
);
// Function and arguments.
test_value(ValueFunc::new("nil", |_, _| Value::None), "<function nil>");
test_value(
ValueArgs {
span: Span::ZERO,
items: vec![
ValueArg {
name: Some(Spanned::zero("a".into())),
value: Spanned::zero(Value::Int(1)),
},
ValueArg {
name: None,
value: Spanned::zero(Value::Int(2)),
},
],
},
"(a: 1, 2)",
);
// Any.
test_value(ValueAny::new(1), "1");
// Error.
test_value(Value::Error, "<error>");
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -1,11 +1,11 @@
// Test bracketed function calls.
---
// Whitespace insignificant.
#[f], #[ f ]
// Whitespace is insignificant.
#[ f ]
// Body and no body.
#[f][#[f]]
// Alternatives for embedding.
#[f f()], #[f #[f]], #[f][#[f]],
// Tight functions.
#[f]#[f]
@ -16,3 +16,33 @@
Second
]
---
// Chained once.
#[f | f]
// Chained twice.
#[f|f|f]
// With body.
// Error: 7-8 expected identifier, found integer
#[f | 1 | box][💕]
// With actual functions.
#[box width: 1cm | image "res/rhino.png"]
---
// Error: 8-8 expected identifier
#[f 1 |]
// Error: 4-4 expected identifier
#[ | f true]
// Error: 2:3-2:3 expected identifier
// Error: 1:4-1:4 expected identifier
#[|][Nope]
// Pipe wins over parens.
// Error: 2:6-2:6 expected closing paren
// Error: 1:9-1:10 expected expression, found closing paren
#[f (|f )]

View File

@ -1,31 +0,0 @@
// Test bracket call chaining.
---
// Chained once.
#[f | f]
// Chained twice.
#[f|f|f]
// With body.
// Error: 7-8 expected identifier, found integer
#[f | 1 | box][💕]
// With actual functions.
#[box width: 1cm | image "res/rhino.png"]
---
// Error: 8-8 expected identifier
#[f 1 |]
// Error: 4-4 expected identifier
#[ | f true]
// Error: 2:3-2:3 expected identifier
// Error: 1:4-1:4 expected identifier
#[|][Nope]
// Pipe wins over parens.
// Error: 2:6-2:6 expected closing paren
// Error: 1:9-1:10 expected expression, found closing paren
#[f (|f )]

View File

@ -11,8 +11,8 @@ C/*
*/D
// Works in code.
#[f /*1*/ a: "b" //
, 1]
#[test type /*1*/ (1) //
, "integer"]
---
// End should not appear without start.

View File

@ -54,7 +54,6 @@
}
}
// Make sure length, relative and linear
// - can all be added to / subtracted from each other,
// - multiplied with integers and floats,

View File

@ -44,4 +44,4 @@
---
// Templates.
{[*{"Hi"} #[f 1]*]}
{[*{"H" + "i"} there*]}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1,23 +1,20 @@
#[page "a5", flip: true]
#[page "a7", flip: true]
// Rectangle with width, should have paragraph height
#[box width: 2cm, color: #9650D6][aa]
// Box with fixed width, should have text height.
#[box width: 2cm, color: #9650D6][A]
Sometimes there is no box
Sometimes there is no box.
// Rectangle with height, should span line
#[box height: 2cm, width: 100%, color: #734CED][bb]
// Box with fixed height, should span line.
#[box height: 2cm, width: 100%, color: #734CED][B]
// Empty rectangle with width and height
// Empty box with fixed width and height.
#[box width: 6cm, height: 12pt, color: #CB4CED]
// This empty rectangle should not be displayed
// Not visiblem, but creates a gap between the boxes above and below.
#[box width: 2in, color: #ff0000]
// This one should be
#[box height: 15mm, width: 100%, color: #494DE3]
// These are in a row!
#[box width: 2in, height: 10pt, color: #D6CD67]
#[box width: 2in, height: 10pt, color: #EDD466]
#[box width: 2in, height: 10pt, color: #E3BE62]
#[box width: 1in, height: 10pt, color: #D6CD67]
#[box width: 1in, height: 10pt, color: #EDD466]
#[box width: 1in, height: 10pt, color: #E3BE62]