summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/env.rs79
-rw-r--r--src/eval/capture.rs5
-rw-r--r--src/eval/mod.rs52
-rw-r--r--src/eval/ops.rs7
-rw-r--r--src/eval/value.rs87
-rw-r--r--src/exec/context.rs49
-rw-r--r--src/exec/mod.rs16
-rw-r--r--src/exec/state.rs2
-rw-r--r--src/font.rs68
-rw-r--r--src/geom/angle.rs2
-rw-r--r--src/geom/mod.rs1
-rw-r--r--src/layout/background.rs12
-rw-r--r--src/layout/fixed.rs11
-rw-r--r--src/layout/frame.rs82
-rw-r--r--src/layout/mod.rs106
-rw-r--r--src/layout/node.rs24
-rw-r--r--src/layout/pad.rs11
-rw-r--r--src/layout/par.rs20
-rw-r--r--src/layout/shaping.rs (renamed from src/shaping.rs)2
-rw-r--r--src/layout/spacing.rs16
-rw-r--r--src/layout/stack.rs20
-rw-r--r--src/layout/text.rs17
-rw-r--r--src/lib.rs14
-rw-r--r--src/library/align.rs4
-rw-r--r--src/library/base.rs6
-rw-r--r--src/library/font.rs5
-rw-r--r--src/library/image.rs12
-rw-r--r--src/library/mod.rs110
-rw-r--r--src/library/pad.rs9
-rw-r--r--src/library/page.rs6
-rw-r--r--src/library/par.rs7
-rw-r--r--src/library/shapes.rs9
-rw-r--r--src/library/spacing.rs9
-rw-r--r--src/main.rs3
-rw-r--r--src/parse/mod.rs78
-rw-r--r--src/parse/resolve.rs12
-rw-r--r--src/parse/tokens.rs18
-rw-r--r--src/prelude.rs16
-rw-r--r--src/pretty.rs84
-rw-r--r--src/syntax/expr.rs78
-rw-r--r--src/syntax/ident.rs2
-rw-r--r--src/syntax/mod.rs2
-rw-r--r--src/syntax/node.rs10
-rw-r--r--src/syntax/span.rs2
-rw-r--r--src/syntax/token.rs24
-rw-r--r--src/syntax/visit.rs34
46 files changed, 622 insertions, 621 deletions
diff --git a/src/env.rs b/src/env.rs
index 66cc5e19..3db71e08 100644
--- a/src/env.rs
+++ b/src/env.rs
@@ -7,11 +7,13 @@ use std::fs;
use std::io::Cursor;
use std::path::{Path, PathBuf};
-use fontdock::fs::FsSource;
+use fontdock::{ContainsChar, FaceFromVec, FaceId, FontSource};
use image::io::Reader as ImageReader;
use image::{DynamicImage, GenericImageView, ImageFormat};
+use ttf_parser::Face;
-use crate::font::FontLoader;
+#[cfg(feature = "fs")]
+use fontdock::fs::{FsIndex, FsSource};
/// Encapsulates all environment dependencies (fonts, resources).
#[derive(Debug)]
@@ -25,13 +27,84 @@ pub struct Env {
impl Env {
/// Create an empty environment for testing purposes.
pub fn blank() -> Self {
+ struct BlankSource;
+
+ impl FontSource for BlankSource {
+ type Face = FaceBuf;
+
+ fn load(&self, _: FaceId) -> Option<Self::Face> {
+ None
+ }
+ }
+
Self {
- fonts: FontLoader::new(Box::new(FsSource::new(vec![])), vec![]),
+ fonts: FontLoader::new(Box::new(BlankSource), vec![]),
resources: ResourceLoader::new(),
}
}
}
+/// A font loader that is backed by a dynamic source.
+pub type FontLoader = fontdock::FontLoader<Box<dyn FontSource<Face = FaceBuf>>>;
+
+/// An owned font face.
+pub struct FaceBuf {
+ data: Box<[u8]>,
+ face: Face<'static>,
+}
+
+impl FaceBuf {
+ /// Get a reference to the underlying face.
+ pub fn get(&self) -> &Face<'_> {
+ // We can't implement Deref because that would leak the internal 'static
+ // lifetime.
+ &self.face
+ }
+
+ /// The raw face data.
+ pub fn data(&self) -> &[u8] {
+ &self.data
+ }
+}
+
+impl FaceFromVec for FaceBuf {
+ fn from_vec(vec: Vec<u8>, i: u32) -> Option<Self> {
+ let data = vec.into_boxed_slice();
+
+ // SAFETY: The slices's location is stable in memory since we don't
+ // touch it and it can't be touched from outside this type.
+ let slice: &'static [u8] =
+ unsafe { std::slice::from_raw_parts(data.as_ptr(), data.len()) };
+
+ Some(Self {
+ data,
+ face: Face::from_slice(slice, i).ok()?,
+ })
+ }
+}
+
+impl ContainsChar for FaceBuf {
+ fn contains_char(&self, c: char) -> bool {
+ self.get().glyph_index(c).is_some()
+ }
+}
+
+/// Simplify font loader construction from an [`FsIndex`].
+#[cfg(feature = "fs")]
+pub trait FsIndexExt {
+ /// Create a font loader backed by a boxed [`FsSource`] which serves all
+ /// indexed font faces.
+ fn into_dynamic_loader(self) -> FontLoader;
+}
+
+#[cfg(feature = "fs")]
+impl FsIndexExt for FsIndex {
+ fn into_dynamic_loader(self) -> FontLoader {
+ let (files, descriptors) = self.into_vecs();
+ FontLoader::new(Box::new(FsSource::new(files)), descriptors)
+ }
+}
+
/// Loads resource from the file system.
pub struct ResourceLoader {
paths: HashMap<PathBuf, ResourceId>,
diff --git a/src/eval/capture.rs b/src/eval/capture.rs
index 182468f7..c0354cd3 100644
--- a/src/eval/capture.rs
+++ b/src/eval/capture.rs
@@ -1,7 +1,8 @@
use std::rc::Rc;
-use super::*;
-use crate::syntax::visit::*;
+use super::{Scope, Scopes, Value};
+use crate::syntax::visit::{visit_expr, Visit};
+use crate::syntax::{Expr, Ident};
/// A visitor that captures variable slots.
#[derive(Debug)]
diff --git a/src/eval/mod.rs b/src/eval/mod.rs
index 524ef43a..6d8edf79 100644
--- a/src/eval/mod.rs
+++ b/src/eval/mod.rs
@@ -13,9 +13,9 @@ pub use value::*;
use std::collections::HashMap;
use std::rc::Rc;
-use super::*;
use crate::color::Color;
-use crate::diag::{Diag, DiagSet};
+use crate::diag::{Diag, DiagSet, Pass};
+use crate::env::Env;
use crate::geom::{Angle, Length, Relative};
use crate::syntax::visit::Visit;
use crate::syntax::*;
@@ -143,16 +143,16 @@ impl Eval for Lit {
}
}
-impl Eval for ExprArray {
- type Output = ValueArray;
+impl Eval for ArrayExpr {
+ type Output = ArrayValue;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
self.items.iter().map(|expr| expr.eval(ctx)).collect()
}
}
-impl Eval for ExprDict {
- type Output = ValueDict;
+impl Eval for DictExpr {
+ type Output = DictValue;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
self.items
@@ -162,7 +162,7 @@ impl Eval for ExprDict {
}
}
-impl Eval for ExprTemplate {
+impl Eval for TemplateExpr {
type Output = TemplateNode;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -172,7 +172,7 @@ impl Eval for ExprTemplate {
}
}
-impl Eval for ExprGroup {
+impl Eval for GroupExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -180,7 +180,7 @@ impl Eval for ExprGroup {
}
}
-impl Eval for ExprBlock {
+impl Eval for BlockExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -201,7 +201,7 @@ impl Eval for ExprBlock {
}
}
-impl Eval for ExprUnary {
+impl Eval for UnaryExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -230,7 +230,7 @@ impl Eval for ExprUnary {
}
}
-impl Eval for ExprBinary {
+impl Eval for BinaryExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -256,7 +256,7 @@ impl Eval for ExprBinary {
}
}
-impl ExprBinary {
+impl BinaryExpr {
/// Apply a basic binary operation.
fn apply<F>(&self, ctx: &mut EvalContext, op: F) -> Value
where
@@ -335,7 +335,7 @@ impl ExprBinary {
}
}
-impl Eval for ExprCall {
+impl Eval for CallExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -361,25 +361,25 @@ impl Eval for ExprCall {
}
}
-impl Eval for ExprArgs {
- type Output = ValueArgs;
+impl Eval for CallArgs {
+ type Output = FuncArgs;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
let items = self.items.iter().map(|arg| arg.eval(ctx)).collect();
- ValueArgs { span: self.span, items }
+ FuncArgs { span: self.span, items }
}
}
-impl Eval for ExprArg {
- type Output = ValueArg;
+impl Eval for CallArg {
+ type Output = FuncArg;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
match self {
- Self::Pos(expr) => ValueArg {
+ Self::Pos(expr) => FuncArg {
name: None,
value: Spanned::new(expr.eval(ctx), expr.span()),
},
- Self::Named(Named { name, expr }) => ValueArg {
+ Self::Named(Named { name, expr }) => FuncArg {
name: Some(Spanned::new(name.string.clone(), name.span)),
value: Spanned::new(expr.eval(ctx), expr.span()),
},
@@ -387,7 +387,7 @@ impl Eval for ExprArg {
}
}
-impl Eval for ExprClosure {
+impl Eval for ClosureExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -402,7 +402,7 @@ impl Eval for ExprClosure {
};
let name = self.name.as_ref().map(|id| id.to_string());
- Value::Func(ValueFunc::new(name, move |ctx, args| {
+ Value::Func(FuncValue::new(name, move |ctx, args| {
// Don't leak the scopes from the call site. Instead, we use the
// scope of captured variables we collected earlier.
let prev = std::mem::take(&mut ctx.scopes);
@@ -422,7 +422,7 @@ impl Eval for ExprClosure {
}
}
-impl Eval for ExprLet {
+impl Eval for LetExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -435,7 +435,7 @@ impl Eval for ExprLet {
}
}
-impl Eval for ExprIf {
+impl Eval for IfExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -461,7 +461,7 @@ impl Eval for ExprIf {
}
}
-impl Eval for ExprWhile {
+impl Eval for WhileExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
@@ -493,7 +493,7 @@ impl Eval for ExprWhile {
}
}
-impl Eval for ExprFor {
+impl Eval for ForExpr {
type Output = Value;
fn eval(&self, ctx: &mut EvalContext) -> Self::Output {
diff --git a/src/eval/ops.rs b/src/eval/ops.rs
index c4adf587..bef4dd58 100644
--- a/src/eval/ops.rs
+++ b/src/eval/ops.rs
@@ -1,4 +1,5 @@
-use super::*;
+use super::{ArrayValue, DictValue, TemplateNode, Value};
+use crate::syntax::Span;
use Value::*;
/// Apply the plus operator to a value.
@@ -189,12 +190,12 @@ fn value_eq(lhs: &Value, rhs: &Value) -> bool {
}
/// Compute whether two arrays are equal.
-fn array_eq(a: &ValueArray, b: &ValueArray) -> bool {
+fn array_eq(a: &ArrayValue, b: &ArrayValue) -> bool {
a.len() == b.len() && a.iter().zip(b).all(|(x, y)| value_eq(x, y))
}
/// Compute whether two dictionaries are equal.
-fn dict_eq(a: &ValueDict, b: &ValueDict) -> bool {
+fn dict_eq(a: &DictValue, b: &DictValue) -> bool {
a.len() == b.len()
&& a.iter().all(|(k, x)| b.get(k).map_or(false, |y| value_eq(x, y)))
}
diff --git a/src/eval/value.rs b/src/eval/value.rs
index 20636917..485829f3 100644
--- a/src/eval/value.rs
+++ b/src/eval/value.rs
@@ -4,11 +4,12 @@ use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Deref;
use std::rc::Rc;
-use super::*;
+use super::{EvalContext, ExprMap};
use crate::color::Color;
+use crate::diag::DiagSet;
use crate::exec::ExecContext;
use crate::geom::{Angle, Length, Linear, Relative};
-use crate::syntax::Tree;
+use crate::syntax::{Span, Spanned, Tree};
/// A computational value.
#[derive(Debug, Clone, PartialEq)]
@@ -34,17 +35,15 @@ pub enum Value {
/// A string: `"string"`.
Str(String),
/// An array value: `(1, "hi", 12cm)`.
- Array(ValueArray),
+ Array(ArrayValue),
/// A dictionary value: `(color: #f79143, pattern: dashed)`.
- Dict(ValueDict),
+ Dict(DictValue),
/// A template value: `[*Hi* there]`.
- Template(ValueTemplate),
+ Template(TemplateValue),
/// An executable function.
- Func(ValueFunc),
- /// Arguments to a function.
- Args(ValueArgs),
+ Func(FuncValue),
/// Any object.
- Any(ValueAny),
+ Any(AnyValue),
/// The result of invalid operations.
Error,
}
@@ -71,11 +70,10 @@ impl Value {
Self::Linear(_) => Linear::TYPE_NAME,
Self::Color(_) => Color::TYPE_NAME,
Self::Str(_) => String::TYPE_NAME,
- Self::Array(_) => ValueArray::TYPE_NAME,
- Self::Dict(_) => ValueDict::TYPE_NAME,
- Self::Template(_) => ValueTemplate::TYPE_NAME,
- Self::Func(_) => ValueFunc::TYPE_NAME,
- Self::Args(_) => ValueArgs::TYPE_NAME,
+ Self::Array(_) => ArrayValue::TYPE_NAME,
+ Self::Dict(_) => DictValue::TYPE_NAME,
+ Self::Template(_) => TemplateValue::TYPE_NAME,
+ Self::Func(_) => FuncValue::TYPE_NAME,
Self::Any(v) => v.type_name(),
Self::Error => "error",
}
@@ -97,13 +95,13 @@ impl Default for Value {
}
/// An array value: `(1, "hi", 12cm)`.
-pub type ValueArray = Vec<Value>;
+pub type ArrayValue = Vec<Value>;
/// A dictionary value: `(color: #f79143, pattern: dashed)`.
-pub type ValueDict = BTreeMap<String, Value>;
+pub type DictValue = BTreeMap<String, Value>;
/// A template value: `[*Hi* there]`.
-pub type ValueTemplate = Vec<TemplateNode>;
+pub type TemplateValue = Vec<TemplateNode>;
/// One chunk of a template.
///
@@ -171,16 +169,16 @@ impl Debug for TemplateFunc {
/// A wrapper around a reference-counted executable function.
#[derive(Clone)]
-pub struct ValueFunc {
+pub struct FuncValue {
name: Option<String>,
- f: Rc<dyn Fn(&mut EvalContext, &mut ValueArgs) -> Value>,
+ f: Rc<dyn Fn(&mut EvalContext, &mut FuncArgs) -> Value>,
}
-impl ValueFunc {
+impl FuncValue {
/// Create a new function value from a rust function or closure.
pub fn new<F>(name: Option<String>, f: F) -> Self
where
- F: Fn(&mut EvalContext, &mut ValueArgs) -> Value + 'static,
+ F: Fn(&mut EvalContext, &mut FuncArgs) -> Value + 'static,
{
Self { name, f: Rc::new(f) }
}
@@ -191,22 +189,22 @@ impl ValueFunc {
}
}
-impl PartialEq for ValueFunc {
+impl PartialEq for FuncValue {
fn eq(&self, _: &Self) -> bool {
// TODO: Figure out what we want here.
false
}
}
-impl Deref for ValueFunc {
- type Target = dyn Fn(&mut EvalContext, &mut ValueArgs) -> Value;
+impl Deref for FuncValue {
+ type Target = dyn Fn(&mut EvalContext, &mut FuncArgs) -> Value;
fn deref(&self) -> &Self::Target {
self.f.as_ref()
}
}
-impl Debug for ValueFunc {
+impl Debug for FuncValue {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_struct("ValueFunc").field("name", &self.name).finish()
}
@@ -214,14 +212,14 @@ impl Debug for ValueFunc {
/// Evaluated arguments to a function.
#[derive(Debug, Clone, PartialEq)]
-pub struct ValueArgs {
+pub struct FuncArgs {
/// The span of the whole argument list.
pub span: Span,
/// The arguments.
- pub items: Vec<ValueArg>,
+ pub items: Vec<FuncArg>,
}
-impl ValueArgs {
+impl FuncArgs {
/// Find and remove the first convertible positional argument.
pub fn find<T>(&mut self, ctx: &mut EvalContext) -> Option<T>
where
@@ -345,14 +343,14 @@ impl ValueArgs {
/// An argument to a function call: `12` or `draw: false`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ValueArg {
+pub struct FuncArg {
/// The name of the argument (`None` for positional arguments).
pub name: Option<Spanned<String>>,
/// The value of the argument.
pub value: Spanned<Value>,
}
-impl ValueArg {
+impl FuncArg {
/// The source code location.
pub fn span(&self) -> Span {
match &self.name {
@@ -363,9 +361,9 @@ impl ValueArg {
}
/// A wrapper around a dynamic value.
-pub struct ValueAny(Box<dyn Bounds>);
+pub struct AnyValue(Box<dyn Bounds>);
-impl ValueAny {
+impl AnyValue {
/// Create a new instance from any value that satisifies the required bounds.
pub fn new<T>(any: T) -> Self
where
@@ -399,25 +397,25 @@ impl ValueAny {
}
}
-impl Clone for ValueAny {
+impl Clone for AnyValue {
fn clone(&self) -> Self {
Self(self.0.dyn_clone())
}
}
-impl PartialEq for ValueAny {
+impl PartialEq for AnyValue {
fn eq(&self, other: &Self) -> bool {
self.0.dyn_eq(other)
}
}
-impl Debug for ValueAny {
+impl Debug for AnyValue {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.debug_tuple("ValueAny").field(&self.0).finish()
}
}
-impl Display for ValueAny {
+impl Display for AnyValue {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Display::fmt(&self.0, f)
}
@@ -426,7 +424,7 @@ impl Display for ValueAny {
trait Bounds: Debug + Display + 'static {
fn as_any(&self) -> &dyn Any;
fn into_any(self: Box<Self>) -> Box<dyn Any>;
- fn dyn_eq(&self, other: &ValueAny) -> bool;
+ fn dyn_eq(&self, other: &AnyValue) -> bool;
fn dyn_clone(&self) -> Box<dyn Bounds>;
fn dyn_type_name(&self) -> &'static str;
}
@@ -443,7 +441,7 @@ where
self
}
- fn dyn_eq(&self, other: &ValueAny) -> bool {
+ fn dyn_eq(&self, other: &AnyValue) -> bool {
if let Some(other) = other.downcast_ref::<Self>() {
self == other
} else {
@@ -584,15 +582,14 @@ primitive! {
}
primitive! { Color: "color", Value::Color }
primitive! { String: "string", Value::Str }
-primitive! { ValueArray: "array", Value::Array }
-primitive! { ValueDict: "dictionary", Value::Dict }
+primitive! { ArrayValue: "array", Value::Array }
+primitive! { DictValue: "dictionary", Value::Dict }
primitive! {
- ValueTemplate: "template",
+ TemplateValue: "template",
Value::Template,
Value::Str(v) => vec![TemplateNode::Str(v)],
}
-primitive! { ValueFunc: "function", Value::Func }
-primitive! { ValueArgs: "arguments", Value::Args }
+primitive! { FuncValue: "function", Value::Func }
impl From<usize> for Value {
fn from(v: usize) -> Self {
@@ -606,8 +603,8 @@ impl From<&str> for Value {
}
}
-impl From<ValueAny> for Value {
- fn from(v: ValueAny) -> Self {
+impl From<AnyValue> for Value {
+ fn from(v: AnyValue) -> Self {
Self::Any(v)
}
}
diff --git a/src/exec/context.rs b/src/exec/context.rs
index 7fd72fe3..311619cc 100644
--- a/src/exec/context.rs
+++ b/src/exec/context.rs
@@ -3,13 +3,16 @@ use std::rc::Rc;
use fontdock::FontStyle;
-use super::*;
-use crate::diag::{Diag, DiagSet};
+use super::{Exec, State};
+use crate::diag::{Diag, DiagSet, Pass};
+use crate::env::Env;
+use crate::eval::TemplateValue;
use crate::geom::{Dir, Gen, Linear, Sides, Size};
use crate::layout::{
- Node, NodePad, NodePages, NodePar, NodeSpacing, NodeStack, NodeText, Tree,
+ Node, PadNode, PageRun, ParNode, SpacingNode, StackNode, TextNode, Tree,
};
use crate::parse::is_newline;
+use crate::syntax::{Span, Spanned};
/// The context for execution.
#[derive(Debug)]
@@ -26,9 +29,9 @@ pub struct ExecContext<'a> {
page: Option<PageInfo>,
/// The content of the active stack. This may be the top-level stack for the
/// page or a lower one created by [`exec`](Self::exec).
- stack: NodeStack,
+ stack: StackNode,
/// The content of the active paragraph.
- par: NodePar,
+ par: ParNode,
}
impl<'a> ExecContext<'a> {
@@ -39,8 +42,8 @@ impl<'a> ExecContext<'a> {
diags: DiagSet::new(),
tree: Tree { runs: vec![] },
page: Some(PageInfo::new(&state, true)),
- stack: NodeStack::new(&state),
- par: NodePar::new(&state),
+ stack: StackNode::new(&state),
+ par: ParNode::new(&state),
state,
}
}
@@ -78,7 +81,7 @@ impl<'a> ExecContext<'a> {
/// Push a layout node into the active paragraph.
///
/// Spacing nodes will be handled according to their
- /// [`softness`](NodeSpacing::softness).
+ /// [`softness`](SpacingNode::softness).
pub fn push(&mut self, node: impl Into<Node>) {
push(&mut self.par.children, node.into());
}
@@ -86,7 +89,7 @@ impl<'a> ExecContext<'a> {
/// Push a word space into the active paragraph.
pub fn push_space(&mut self) {
let em = self.state.font.font_size();
- self.push(NodeSpacing {
+ self.push(SpacingNode {
amount: self.state.par.word_spacing.resolve(em),
softness: 1,
});
@@ -111,7 +114,7 @@ impl<'a> ExecContext<'a> {
/// Apply a forced line break.
pub fn push_linebreak(&mut self) {
let em = self.state.font.font_size();
- self.push_into_stack(NodeSpacing {
+ self.push_into_stack(SpacingNode {
amount: self.state.par.leading.resolve(em),
softness: 2,
});
@@ -120,7 +123,7 @@ impl<'a> ExecContext<'a> {
/// Apply a forced paragraph break.
pub fn push_parbreak(&mut self) {
let em = self.state.font.font_size();
- self.push_into_stack(NodeSpacing {
+ self.push_into_stack(SpacingNode {
amount: self.state.par.spacing.resolve(em),
softness: 1,
});
@@ -134,10 +137,10 @@ impl<'a> ExecContext<'a> {
}
/// Execute a template and return the result as a stack node.
- pub fn exec(&mut self, template: &ValueTemplate) -> NodeStack {
+ pub fn exec(&mut self, template: &TemplateValue) -> StackNode {
let page = self.page.take();
- let stack = mem::replace(&mut self.stack, NodeStack::new(&self.state));
- let par = mem::replace(&mut self.par, NodePar::new(&self.state));
+ let stack = mem::replace(&mut self.stack, StackNode::new(&self.state));
+ let par = mem::replace(&mut self.par, ParNode::new(&self.state));
template.exec(self);
let result = self.finish_stack();
@@ -151,7 +154,7 @@ impl<'a> ExecContext<'a> {
/// Construct a text node from the given string based on the active text
/// state.
- pub fn make_text_node(&self, text: String) -> NodeText {
+ pub fn make_text_node(&self, text: String) -> TextNode {
let mut variant = self.state.font.variant;
if self.state.font.strong {
@@ -166,7 +169,7 @@ impl<'a> ExecContext<'a> {
}
}
- NodeText {
+ TextNode {
text,
dir: self.state.dirs.cross,
aligns: self.state.aligns,
@@ -180,7 +183,7 @@ impl<'a> ExecContext<'a> {
/// Finish the active paragraph.
fn finish_par(&mut self) {
- let mut par = mem::replace(&mut self.par, NodePar::new(&self.state));
+ let mut par = mem::replace(&mut self.par, ParNode::new(&self.state));
trim(&mut par.children);
if !par.children.is_empty() {
@@ -189,10 +192,10 @@ impl<'a> ExecContext<'a> {
}
/// Finish the active stack.
- fn finish_stack(&mut self) -> NodeStack {
+ fn finish_stack(&mut self) -> StackNode {
self.finish_par();
- let mut stack = mem::replace(&mut self.stack, NodeStack::new(&self.state));
+ let mut stack = mem::replace(&mut self.stack, StackNode::new(&self.state));
trim(&mut stack.children);
stack
@@ -205,9 +208,9 @@ impl<'a> ExecContext<'a> {
let stack = self.finish_stack();
if !stack.children.is_empty() || (keep && info.hard) {
- self.tree.runs.push(NodePages {
+ self.tree.runs.push(PageRun {
size: info.size,
- child: NodePad {
+ child: PadNode {
padding: info.padding,
child: stack.into(),
}
@@ -274,7 +277,7 @@ impl PageInfo {
}
}
-impl NodeStack {
+impl StackNode {
fn new(state: &State) -> Self {
Self {
dirs: state.dirs,
@@ -284,7 +287,7 @@ impl NodeStack {
}
}
-impl NodePar {
+impl ParNode {
fn new(state: &State) -> Self {
let em = state.font.font_size();
Self {
diff --git a/src/exec/mod.rs b/src/exec/mod.rs
index 35ffa2b6..90e5a225 100644
--- a/src/exec/mod.rs
+++ b/src/exec/mod.rs
@@ -10,8 +10,8 @@ use std::rc::Rc;
use crate::diag::Pass;
use crate::env::Env;
-use crate::eval::{ExprMap, TemplateFunc, TemplateNode, Value, ValueTemplate};
-use crate::layout::{self, NodeFixed, NodeSpacing, NodeStack};
+use crate::eval::{ExprMap, TemplateFunc, TemplateNode, TemplateValue, Value};
+use crate::layout::{self, FixedNode, SpacingNode, StackNode};
use crate::pretty::pretty;
use crate::syntax::*;
@@ -77,7 +77,7 @@ impl ExecWithMap for Node {
}
}
-impl ExecWithMap for NodeHeading {
+impl ExecWithMap for HeadingNode {
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
let prev = ctx.state.clone();
let upscale = 1.5 - 0.1 * self.level as f64;
@@ -91,7 +91,7 @@ impl ExecWithMap for NodeHeading {
}
}
-impl Exec for NodeRaw {
+impl Exec for RawNode {
fn exec(&self, ctx: &mut ExecContext) {
let prev = Rc::clone(&ctx.state.font.families);
ctx.set_monospace();
@@ -103,7 +103,7 @@ impl Exec for NodeRaw {
let mut newline = false;
for line in &self.lines {
if newline {
- children.push(layout::Node::Spacing(NodeSpacing {
+ children.push(layout::Node::Spacing(SpacingNode {
amount: leading,
softness: 2,
}));
@@ -119,10 +119,10 @@ impl Exec for NodeRaw {
// This is wrapped in a fixed node to make sure the stack fits to its
// content instead of filling the available area.
- ctx.push(NodeFixed {
+ ctx.push(FixedNode {
width: None,
height: None,
- child: NodeStack {
+ child: StackNode {
dirs: ctx.state.dirs,
aligns: ctx.state.aligns,
children,
@@ -159,7 +159,7 @@ impl Exec for Value {
}
}
-impl Exec for ValueTemplate {
+impl Exec for TemplateValue {
fn exec(&self, ctx: &mut ExecContext) {
for node in self {
node.exec(ctx);
diff --git a/src/exec/state.rs b/src/exec/state.rs
index aa2dde1c..6775f394 100644
--- a/src/exec/state.rs
+++ b/src/exec/state.rs
@@ -3,8 +3,8 @@ use std::rc::Rc;
use fontdock::{fallback, FallbackTree, FontStretch, FontStyle, FontVariant, FontWeight};
use crate::geom::*;
+use crate::layout::VerticalFontMetric;
use crate::paper::{Paper, PaperClass, PAPER_A4};
-use crate::shaping::VerticalFontMetric;
/// The evaluation state.
#[derive(Debug, Clone, PartialEq)]
diff --git a/src/font.rs b/src/font.rs
deleted file mode 100644
index e5718331..00000000
--- a/src/font.rs
+++ /dev/null
@@ -1,68 +0,0 @@
-//! Font handling.
-
-use fontdock::{ContainsChar, FaceFromVec, FontSource};
-use ttf_parser::Face;
-
-#[cfg(feature = "fs")]
-use fontdock::fs::{FsIndex, FsSource};
-
-/// A font loader that is backed by a dynamic source.
-pub type FontLoader = fontdock::FontLoader<Box<dyn FontSource<Face = FaceBuf>>>;
-
-/// An owned font face.
-pub struct FaceBuf {
- data: Box<[u8]>,
- face: Face<'static>,
-}
-
-impl FaceBuf {
- /// Get a reference to the underlying face.
- pub fn get(&self) -> &Face<'_> {
- // We can't implement Deref because that would leak the internal 'static
- // lifetime.
- &self.face
- }
-
- /// The raw face data.
- pub fn data(&self) -> &[u8] {
- &self.data
- }
-}
-
-impl FaceFromVec for FaceBuf {
- fn from_vec(vec: Vec<u8>, i: u32) -> Option<Self> {
- let data = vec.into_boxed_slice();
-
- // SAFETY: The slices's location is stable in memory since we don't
- // touch it and it can't be touched from outside this type.
- let slice: &'static [u8] =
- unsafe { std::slice::from_raw_parts(data.as_ptr(), data.len()) };
-
- Some(Self {
- data,
- face: Face::from_slice(slice, i).ok()?,
- })
- }
-}
-
-impl ContainsChar for FaceBuf {
- fn contains_char(&self, c: char) -> bool {
- self.get().glyph_index(c).is_some()
- }
-}
-
-/// Simplify font loader construction from an [`FsIndex`].
-#[cfg(feature = "fs")]
-pub trait FsIndexExt {
- /// Create a font loader backed by a boxed [`FsSource`] which serves all
- /// indexed font faces.
- fn into_dynamic_loader(self) -> FontLoader;
-}
-
-#[cfg(feature = "fs")]
-impl FsIndexExt for FsIndex {
- fn into_dynamic_loader(self) -> FontLoader {
- let (files, descriptors) = self.into_vecs();
- FontLoader::new(Box::new(FsSource::new(files)), descriptors)
- }
-}
diff --git a/src/geom/angle.rs b/src/geom/angle.rs
index 2392efa5..a0e2877a 100644
--- a/src/geom/angle.rs
+++ b/src/geom/angle.rs
@@ -1,5 +1,3 @@
-use std::f64::consts::PI;
-
use super::*;
/// An angle.
diff --git a/src/geom/mod.rs b/src/geom/mod.rs
index e601cb1f..5d906834 100644
--- a/src/geom/mod.rs
+++ b/src/geom/mod.rs
@@ -26,6 +26,7 @@ pub use sides::*;
pub use size::*;
pub use spec::*;
+use std::f64::consts::PI;
use std::fmt::{self, Debug, Display, Formatter};
use std::iter::Sum;
use std::ops::*;
diff --git a/src/layout/background.rs b/src/layout/background.rs
index b331ba3c..bb155073 100644
--- a/src/layout/background.rs
+++ b/src/layout/background.rs
@@ -1,16 +1,16 @@
use super::*;
-/// A node that places a rectangular filled background behind another node.
+/// A node that places a rectangular filled background behind its child.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodeBackground {
+pub struct BackgroundNode {
/// The background fill.
pub fill: Fill,
/// The child node to be filled.
pub child: Node,
}
-impl Layout for NodeBackground {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+impl Layout for BackgroundNode {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
let mut layouted = self.child.layout(ctx, areas);
for frame in layouted.frames_mut() {
@@ -25,8 +25,8 @@ impl Layout for NodeBackground {
}
}
-impl From<NodeBackground> for NodeAny {
- fn from(background: NodeBackground) -> Self {
+impl From<BackgroundNode> for AnyNode {
+ fn from(background: BackgroundNode) -> Self {
Self::new(background)
}
}
diff --git a/src/layout/fixed.rs b/src/layout/fixed.rs
index a9554a07..e3365668 100644
--- a/src/layout/fixed.rs
+++ b/src/layout/fixed.rs
@@ -1,9 +1,8 @@
use super::*;
-use crate::geom::Linear;
/// A node that can fix its child's width and height.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodeFixed {
+pub struct FixedNode {
/// The fixed width, if any.
pub width: Option<Linear>,
/// The fixed height, if any.
@@ -12,8 +11,8 @@ pub struct NodeFixed {
pub child: Node,
}
-impl Layout for NodeFixed {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+impl Layout for FixedNode {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
let Areas { current, full, .. } = areas;
let size = Size::new(
self.width.map(|w| w.resolve(full.width)).unwrap_or(current.width),
@@ -31,8 +30,8 @@ impl Layout for NodeFixed {
}
}
-impl From<NodeFixed> for NodeAny {
- fn from(fixed: NodeFixed) -> Self {
+impl From<FixedNode> for AnyNode {
+ fn from(fixed: FixedNode) -> Self {
Self::new(fixed)
}
}
diff --git a/src/layout/frame.rs b/src/layout/frame.rs
new file mode 100644
index 00000000..c85d7539
--- /dev/null
+++ b/src/layout/frame.rs
@@ -0,0 +1,82 @@
+use super::Shaped;
+use crate::color::Color;
+use crate::env::ResourceId;
+use crate::geom::{Point, Size};
+
+/// A finished layout with elements at fixed positions.
+#[derive(Debug, Clone, PartialEq)]
+pub struct Frame {
+ /// The size of the frame.
+ pub size: Size,
+ /// The elements composing this layout.
+ pub elements: Vec<(Point, Element)>,
+}
+
+impl Frame {
+ /// Create a new, empty frame.
+ pub fn new(size: Size) -> Self {
+ Self { size, elements: vec![] }
+ }
+
+ /// Add an element at a position.
+ pub fn push(&mut self, pos: Point, element: Element) {
+ self.elements.push((pos, element));
+ }
+
+ /// Add all elements of another frame, placing them relative to the given
+ /// position.
+ pub fn push_frame(&mut self, pos: Point, subframe: Self) {
+ for (subpos, element) in subframe.elements {
+ self.push(pos + subpos, element);
+ }
+ }
+}
+
+/// The building block frames are composed of.
+#[derive(Debug, Clone, PartialEq)]
+pub enum Element {
+ /// Shaped text.
+ Text(Shaped),
+ /// A geometric shape.
+ Geometry(Geometry),
+ /// A raster image.
+ Image(Image),
+}
+
+/// A shape with some kind of fill.
+#[derive(Debug, Clone, PartialEq)]
+pub struct Geometry {
+ /// The shape to draw.
+ pub shape: Shape,
+ /// How the shape looks on the inside.
+ //
+ // TODO: This could be made into a Vec<Fill> or something such that
+ // the user can compose multiple fills with alpha values less
+ // than one to achieve cool effects.
+ pub fill: Fill,
+}
+
+/// Some shape.
+#[derive(Debug, Clone, PartialEq)]
+pub enum Shape {
+ /// A rectangle.
+ Rect(Size),
+}
+
+/// The kind of graphic fill to be applied to a [`Shape`].
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub enum Fill {
+ /// The fill is a color.
+ Color(Color),
+ /// The fill is an image.
+ Image(Image),
+}
+
+/// An image element.
+#[derive(Debug, Copy, Clone, PartialEq)]
+pub struct Image {
+ /// The image resource.
+ pub res: ResourceId,
+ /// The size of the image in the document.
+ pub size: Size,
+}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index b5cfb1b0..ae4ab89d 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -2,27 +2,29 @@
mod background;
mod fixed;
+mod frame;
mod node;
mod pad;
mod par;
+mod shaping;
mod spacing;
mod stack;
mod text;
-use crate::color::Color;
-use crate::env::{Env, ResourceId};
-use crate::geom::*;
-use crate::shaping::Shaped;
-
pub use background::*;
pub use fixed::*;
+pub use frame::*;
pub use node::*;
pub use pad::*;
pub use par::*;
+pub use shaping::*;
pub use spacing::*;
pub use stack::*;
pub use text::*;
+use crate::env::Env;
+use crate::geom::*;
+
/// Layout a tree into a collection of frames.
pub fn layout(env: &mut Env, tree: &Tree) -> Vec<Frame> {
tree.layout(&mut LayoutContext { env })
@@ -32,7 +34,7 @@ pub fn layout(env: &mut Env, tree: &Tree) -> Vec<Frame> {
#[derive(Debug, Clone, PartialEq)]
pub struct Tree {
/// Runs of pages with the same properties.
- pub runs: Vec<NodePages>,
+ pub runs: Vec<PageRun>,
}
impl Tree {
@@ -44,15 +46,15 @@ impl Tree {
/// A run of pages that all have the same properties.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodePages {
+pub struct PageRun {
/// The size of each page.
pub size: Size,
/// The layout node that produces the actual pages (typically a
- /// [`NodeStack`]).
+ /// [`StackNode`]).
pub child: Node,
}
-impl NodePages {
+impl PageRun {
/// Layout the page run.
pub fn layout(&self, ctx: &mut LayoutContext) -> Vec<Frame> {
let areas = Areas::repeat(self.size, Spec::uniform(Expand::Fill));
@@ -64,7 +66,7 @@ impl NodePages {
/// Layout a node.
pub trait Layout {
/// Layout the node into the given areas.
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted;
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment;
}
/// The context for layouting.
@@ -74,7 +76,7 @@ pub struct LayoutContext<'a> {
pub env: &'a mut Env,
}
-/// A collection of areas to layout into.
+/// A sequence of areas to layout into.
#[derive(Debug, Clone, PartialEq)]
pub struct Areas {
/// The remaining size of the current area.
@@ -155,7 +157,7 @@ impl Expand {
/// The result of layouting a node.
#[derive(Debug, Clone, PartialEq)]
-pub enum Layouted {
+pub enum Fragment {
/// Spacing that should be added to the parent.
Spacing(Length),
/// A layout that should be added to and aligned in the parent.
@@ -164,7 +166,7 @@ pub enum Layouted {
Frames(Vec<Frame>, LayoutAligns),
}
-impl Layouted {
+impl Fragment {
/// Return a reference to all frames contained in this variant (zero, one or
/// arbitrarily many).
pub fn frames(&self) -> &[Frame] {
@@ -193,81 +195,3 @@ impl Layouted {
}
}
}
-
-/// A finished layout with elements at fixed positions.
-#[derive(Debug, Clone, PartialEq)]
-pub struct Frame {
- /// The size of the frame.
- pub size: Size,
- /// The elements composing this layout.
- pub elements: Vec<(Point, Element)>,
-}
-
-impl Frame {
- /// Create a new, empty frame.
- pub fn new(size: Size) -> Self {
- Self { size, elements: vec![] }
- }
-
- /// Add an element at a position.
- pub fn push(&mut self, pos: Point, element: Element) {
- self.elements.push((pos, element));
- }
-
- /// Add all elements of another frame, placing them relative to the given
- /// position.
- pub fn push_frame(&mut self, pos: Point, subframe: Self) {
- for (subpos, element) in subframe.elements {
- self.push(pos + subpos, element);
- }
- }
-}
-
-/// The building block frames are composed of.
-#[derive(Debug, Clone, PartialEq)]
-pub enum Element {
- /// Shaped text.
- Text(Shaped),
- /// An image.
- Image(Image),
- /// Some shape that could hold another frame.
- Geometry(Geometry),
-}
-
-/// A shape with some kind of fill.
-#[derive(Debug, Clone, PartialEq)]
-pub struct Geometry {
- /// The shape to draw.
- pub shape: Shape,
- /// How the shape looks on the inside.
- //
- // TODO: This could be made into a Vec<Fill> or something such that
- // the user can compose multiple fills with alpha values less
- // than one to achieve cool effects.
- pub fill: Fill,
-}
-
-/// Some shape.
-#[derive(Debug, Clone, PartialEq)]
-pub enum Shape {
- /// A rectangle.
- Rect(Size),
-}
-
-/// The kind of graphic fill to be applied to a [`Shape`].
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub enum Fill {
- /// The fill is a color.
- Color(Color),
- /// The fill is an image.
- Image(Image),
-}
-
-/// An image element.
-#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct Image {
- /// The image resource.
- pub res: ResourceId,
- /// The size of the image in the document.
- pub size: Size,
-}
diff --git a/src/layout/node.rs b/src/layout/node.rs
index fa7fe010..443a96ae 100644
--- a/src/layout/node.rs
+++ b/src/layout/node.rs
@@ -7,15 +7,15 @@ use super::*;
#[derive(Clone, PartialEq)]
pub enum Node {
/// A text node.
- Text(NodeText),
+ Text(TextNode),
/// A spacing node.
- Spacing(NodeSpacing),
+ Spacing(SpacingNode),
/// A dynamic node that can implement custom layouting behaviour.
- Any(NodeAny),
+ Any(AnyNode),
}
impl Layout for Node {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
match self {
Self::Spacing(spacing) => spacing.layout(ctx, areas),
Self::Text(text) => text.layout(ctx, areas),
@@ -35,9 +35,9 @@ impl Debug for Node {
}
/// A wrapper around a dynamic layouting node.
-pub struct NodeAny(Box<dyn Bounds>);
+pub struct AnyNode(Box<dyn Bounds>);
-impl NodeAny {
+impl AnyNode {
/// Create a new instance from any node that satisifies the required bounds.
pub fn new<T>(any: T) -> Self
where
@@ -47,25 +47,25 @@ impl NodeAny {
}
}
-impl Layout for NodeAny {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+impl Layout for AnyNode {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
self.0.layout(ctx, areas)
}
}
-impl Clone for NodeAny {
+impl Clone for AnyNode {
fn clone(&self) -> Self {
Self(self.0.dyn_clone())
}
}
-impl PartialEq for NodeAny {
+impl PartialEq for AnyNode {
fn eq(&self, other: &Self) -> bool {
self.0.dyn_eq(other.0.as_ref())
}
}
-impl Debug for NodeAny {
+impl Debug for AnyNode {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
self.0.fmt(f)
}
@@ -73,7 +73,7 @@ impl Debug for NodeAny {
impl<T> From<T> for Node
where
- T: Into<NodeAny>,
+ T: Into<AnyNode>,
{
fn from(t: T) -> Self {
Self::Any(t.into())
diff --git a/src/layout/pad.rs b/src/layout/pad.rs
index 88ef8828..33ce217d 100644
--- a/src/layout/pad.rs
+++ b/src/layout/pad.rs
@@ -1,17 +1,16 @@
use super::*;
-use crate::geom::Linear;
/// A node that adds padding to its child.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodePad {
+pub struct PadNode {
/// The amount of padding.
pub padding: Sides<Linear>,
/// The child node whose sides to pad.
pub child: Node,
}
-impl Layout for NodePad {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+impl Layout for PadNode {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
let areas = shrink(areas, self.padding);
let mut layouted = self.child.layout(ctx, &areas);
@@ -23,8 +22,8 @@ impl Layout for NodePad {
}
}
-impl From<NodePad> for NodeAny {
- fn from(pad: NodePad) -> Self {
+impl From<PadNode> for AnyNode {
+ fn from(pad: PadNode) -> Self {
Self::new(pad)
}
}
diff --git a/src/layout/par.rs b/src/layout/par.rs
index 8e8f5aac..e9fda015 100644
--- a/src/layout/par.rs
+++ b/src/layout/par.rs
@@ -2,7 +2,7 @@ use super::*;
/// A node that arranges its children into a paragraph.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodePar {
+pub struct ParNode {
/// The `main` and `cross` directions of this paragraph.
///
/// The children are placed in lines along the `cross` direction. The lines
@@ -16,28 +16,28 @@ pub struct NodePar {
pub children: Vec<Node>,
}
-impl Layout for NodePar {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+impl Layout for ParNode {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
let mut layouter = ParLayouter::new(self, areas.clone());
for child in &self.children {
match child.layout(ctx, &layouter.areas) {
- Layouted::Spacing(spacing) => layouter.push_spacing(spacing),
- Layouted::Frame(frame, aligns) => {
+ Fragment::Spacing(spacing) => layouter.push_spacing(spacing),
+ Fragment::Frame(frame, aligns) => {
layouter.push_frame(frame, aligns.cross)
}
- Layouted::Frames(frames, aligns) => {
+ Fragment::Frames(frames, aligns) => {
for frame in frames {
layouter.push_frame(frame, aligns.cross);
}
}
}
}
- Layouted::Frames(layouter.finish(), self.aligns)
+ Fragment::Frames(layouter.finish(), self.aligns)
}
}
-impl From<NodePar> for NodeAny {
- fn from(par: NodePar) -> Self {
+impl From<ParNode> for AnyNode {
+ fn from(par: ParNode) -> Self {
Self::new(par)
}
}
@@ -57,7 +57,7 @@ struct ParLayouter {
}
impl ParLayouter {
- fn new(par: &NodePar, areas: Areas) -> Self {
+ fn new(par: &ParNode, areas: Areas) -> Self {
Self {
main: par.dirs.main.axis(),
cross: par.dirs.cross.axis(),
diff --git a/src/shaping.rs b/src/layout/shaping.rs
index 41119639..141fa10e 100644
--- a/src/shaping.rs
+++ b/src/layout/shaping.rs
@@ -9,7 +9,7 @@ use std::fmt::{self, Debug, Display, Formatter};
use fontdock::{FaceId, FaceQuery, FallbackTree, FontVariant};
use ttf_parser::{Face, GlyphId};
-use crate::font::FontLoader;
+use crate::env::FontLoader;
use crate::geom::{Dir, Length, Point, Size};
use crate::layout::{Element, Frame};
diff --git a/src/layout/spacing.rs b/src/layout/spacing.rs
index 2bcb7ac1..361b03ee 100644
--- a/src/layout/spacing.rs
+++ b/src/layout/spacing.rs
@@ -2,9 +2,9 @@ use std::fmt::{self, Debug, Formatter};
use super::*;
-/// A spacing node.
+/// A node that adds spacing to its parent.
#[derive(Copy, Clone, PartialEq)]
-pub struct NodeSpacing {
+pub struct SpacingNode {
/// The amount of spacing to insert.
pub amount: Length,
/// Defines how spacing interacts with surrounding spacing.
@@ -16,20 +16,20 @@ pub struct NodeSpacing {
pub softness: u8,
}
-impl Layout for NodeSpacing {
- fn layout(&self, _: &mut LayoutContext, _: &Areas) -> Layouted {
- Layouted::Spacing(self.amount)
+impl Layout for SpacingNode {
+ fn layout(&self, _: &mut LayoutContext, _: &Areas) -> Fragment {
+ Fragment::Spacing(self.amount)
}
}
-impl Debug for NodeSpacing {
+impl Debug for SpacingNode {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Spacing({}, {})", self.amount, self.softness)
}
}
-impl From<NodeSpacing> for Node {
- fn from(spacing: NodeSpacing) -> Self {
+impl From<SpacingNode> for Node {
+ fn from(spacing: SpacingNode) -> Self {
Self::Spacing(spacing)
}
}
diff --git a/src/layout/stack.rs b/src/layout/stack.rs
index 8748c5c7..32eba676 100644
--- a/src/layout/stack.rs
+++ b/src/layout/stack.rs
@@ -2,7 +2,7 @@ use super::*;
/// A node that stacks its children.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodeStack {
+pub struct StackNode {
/// The `main` and `cross` directions of this stack.
///
/// The children are stacked along the `main` direction. The `cross`
@@ -14,26 +14,26 @@ pub struct NodeStack {
pub children: Vec<Node>,
}
-impl Layout for NodeStack {
- fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Layouted {
+impl Layout for StackNode {
+ fn layout(&self, ctx: &mut LayoutContext, areas: &Areas) -> Fragment {
let mut layouter = StackLayouter::new(self, areas.clone());
for child in &self.children {
match child.layout(ctx, &layouter.areas) {
- Layouted::Spacing(spacing) => layouter.push_spacing(spacing),
- Layouted::Frame(frame, aligns) => layouter.push_frame(frame, aligns),
- Layouted::Frames(frames, aligns) => {
+ Fragment::Spacing(spacing) => layouter.push_spacing(spacing),
+ Fragment::Frame(frame, aligns) => layouter.push_frame(frame, aligns),
+ Fragment::Frames(frames, aligns) => {
for frame in frames {
layouter.push_frame(frame, aligns);
}
}
}
}
- Layouted::Frames(layouter.finish(), self.aligns)
+ Fragment::Frames(layouter.finish(), self.aligns)
}
}
-impl From<NodeStack> for NodeAny {
- fn from(stack: NodeStack) -> Self {
+impl From<StackNode> for AnyNode {
+ fn from(stack: StackNode) -> Self {
Self::new(stack)
}
}
@@ -49,7 +49,7 @@ struct StackLayouter {
}
impl StackLayouter {
- fn new(stack: &NodeStack, areas: Areas) -> Self {
+ fn new(stack: &StackNode, areas: Areas) -> Self {
Self {
main: stack.dirs.main.axis(),
dirs: stack.dirs,
diff --git a/src/layout/text.rs b/src/layout/text.rs
index 7b4eb08e..7faefa0d 100644
--- a/src/layout/text.rs
+++ b/src/layout/text.rs
@@ -4,11 +4,10 @@ use std::rc::Rc;
use fontdock::{FallbackTree, FontVariant};
use super::*;
-use crate::shaping::{shape, VerticalFontMetric};
-/// A text node.
+/// A consecutive, styled run of text.
#[derive(Clone, PartialEq)]
-pub struct NodeText {
+pub struct TextNode {
/// The text.
pub text: String,
/// The text direction.
@@ -27,9 +26,9 @@ pub struct NodeText {
pub bottom_edge: VerticalFontMetric,
}
-impl Layout for NodeText {
- fn layout(&self, ctx: &mut LayoutContext, _: &Areas) -> Layouted {
- Layouted::Frame(
+impl Layout for TextNode {
+ fn layout(&self, ctx: &mut LayoutContext, _: &Areas) -> Fragment {
+ Fragment::Frame(
shape(
&self.text,
self.dir,
@@ -45,14 +44,14 @@ impl Layout for NodeText {
}
}
-impl Debug for NodeText {
+impl Debug for TextNode {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Text({})", self.text)
}
}
-impl From<NodeText> for Node {
- fn from(text: NodeText) -> Self {
+impl From<TextNode> for Node {
+ fn from(text: TextNode) -> Self {
Self::Text(text)
}
}
diff --git a/src/lib.rs b/src/lib.rs
index d4a73ed4..d2e47c62 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -9,12 +9,13 @@
//! computes the value of each expression in document and stores them in a map
//! from expression-pointers to values.
//! - **Execution:** Now, we can [execute] the parsed and evaluated "script".
-//! This produces a [layout tree], a high-level, fully styled representation.
-//! The nodes of this tree are self-contained and order-independent and thus
-//! much better suited for layouting than the syntax tree.
+//! This produces a [layout tree], a high-level, fully styled representation
+//! of the document. The nodes of this tree are self-contained and
+//! order-independent and thus much better suited for layouting than the
+//! syntax tree.
//! - **Layouting:** Next, the tree is [layouted] into a portable version of the
-//! typeset document. The output of this is a vector of [`Frame`]s
-//! (corresponding to pages), ready for exporting.
+//! typeset document. The output of this is a collection of [`Frame`]s (one
+//! per page), ready for exporting.
//! - **Exporting:** The finished layout can be exported into a supported
//! format. Submodules for these formats are located in the [export] module.
//! Currently, the only supported output format is [_PDF_].
@@ -36,15 +37,12 @@ pub mod color;
pub mod env;
pub mod exec;
pub mod export;
-pub mod font;
pub mod geom;
pub mod layout;
pub mod library;
pub mod paper;
pub mod parse;
-pub mod prelude;
pub mod pretty;
-pub mod shaping;
pub mod syntax;
use crate::diag::Pass;
diff --git a/src/library/align.rs b/src/library/align.rs
index a516ff4c..93c6db0d 100644
--- a/src/library/align.rs
+++ b/src/library/align.rs
@@ -26,12 +26,12 @@ use super::*;
/// - `top`
/// - `bottom`
/// - `center`
-pub fn align(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn align(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let first = args.find(ctx);
let second = args.find(ctx);
let hor = args.get(ctx, "horizontal");
let ver = args.get(ctx, "vertical");
- let body = args.find::<ValueTemplate>(ctx);
+ let body = args.find::<TemplateValue>(ctx);
Value::template("align", move |ctx| {
let snapshot = ctx.state.clone();
diff --git a/src/library/base.rs b/src/library/base.rs
index 4d36b878..22adb1f4 100644
--- a/src/library/base.rs
+++ b/src/library/base.rs
@@ -10,7 +10,7 @@ use super::*;
///
/// # Return value
/// The string representation of the value.
-pub fn repr(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn repr(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
match args.require::<Value>(ctx, "value") {
Some(value) => pretty(&value).into(),
None => Value::Error,
@@ -27,7 +27,7 @@ pub fn repr(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
///
/// # Return value
/// The color with the given components.
-pub fn rgb(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn rgb(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let r = args.require(ctx, "red component");
let g = args.require(ctx, "green component");
let b = args.require(ctx, "blue component");
@@ -57,7 +57,7 @@ pub fn rgb(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
///
/// # Return value
/// The name of the value's type as a string.
-pub fn type_(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn type_(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
match args.require::<Value>(ctx, "value") {
Some(value) => value.type_name().into(),
None => Value::Error,
diff --git a/src/library/font.rs b/src/library/font.rs
index ecc15d96..00fd0e81 100644
--- a/src/library/font.rs
+++ b/src/library/font.rs
@@ -1,7 +1,6 @@
use fontdock::{FontStretch, FontStyle, FontWeight};
use super::*;
-use crate::shaping::VerticalFontMetric;
/// `font`: Configure the font.
///
@@ -55,7 +54,7 @@ use crate::shaping::VerticalFontMetric;
/// - `x-height`
/// - `baseline`
/// - `descender`
-pub fn font(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let size = args.find::<Linear>(ctx);
let list: Vec<_> = args.filter::<FontFamily>(ctx).map(|f| f.to_string()).collect();
let style = args.get(ctx, "style");
@@ -66,7 +65,7 @@ pub fn font(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
let serif = args.get(ctx, "serif");
let sans_serif = args.get(ctx, "sans-serif");
let monospace = args.get(ctx, "monospace");
- let body = args.find::<ValueTemplate>(ctx);
+ let body = args.find::<TemplateValue>(ctx);
Value::template("font", move |ctx| {
let snapshot = ctx.state.clone();
diff --git a/src/library/image.rs b/src/library/image.rs
index c3200e93..8cb09463 100644
--- a/src/library/image.rs
+++ b/src/library/image.rs
@@ -2,7 +2,9 @@ use ::image::GenericImageView;
use super::*;
use crate::env::{ImageResource, ResourceId};
-use crate::layout::*;
+use crate::layout::{
+ AnyNode, Areas, Element, Fragment, Frame, Image, Layout, LayoutContext,
+};
/// `image`: Insert an image.
///
@@ -13,7 +15,7 @@ use crate::layout::*;
///
/// # Return value
/// A template that inserts an image.
-pub fn image(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn image(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let path = args.require::<Spanned<String>>(ctx, "path to image file");
let width = args.get(ctx, "width");
let height = args.get(ctx, "height");
@@ -53,7 +55,7 @@ struct NodeImage {
}
impl Layout for NodeImage {
- fn layout(&self, _: &mut LayoutContext, areas: &Areas) -> Layouted {
+ fn layout(&self, _: &mut LayoutContext, areas: &Areas) -> Fragment {
let Areas { current, full, .. } = areas;
let pixel_width = self.dimensions.0 as f64;
@@ -84,11 +86,11 @@ impl Layout for NodeImage {
let mut frame = Frame::new(size);
frame.push(Point::ZERO, Element::Image(Image { res: self.res, size }));
- Layouted::Frame(frame, self.aligns)
+ Fragment::Frame(frame, self.aligns)
}
}
-impl From<NodeImage> for NodeAny {
+impl From<NodeImage> for AnyNode {
fn from(image: NodeImage) -> Self {
Self::new(image)
}
diff --git a/src/library/mod.rs b/src/library/mod.rs
index e813a138..d0920cf1 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -27,68 +27,72 @@ use std::fmt::{self, Display, Formatter};
use fontdock::{FontStyle, FontWeight};
-use crate::eval::{Scope, ValueAny, ValueFunc};
-use crate::layout::*;
-use crate::prelude::*;
-use crate::shaping::VerticalFontMetric;
+use crate::eval::{AnyValue, FuncValue, Scope};
+use crate::eval::{EvalContext, FuncArgs, TemplateValue, Value};
+use crate::exec::{Exec, ExecContext};
+use crate::geom::*;
+use crate::layout::VerticalFontMetric;
+use crate::syntax::Spanned;
/// Construct a scope containing all standard library definitions.
pub fn new() -> Scope {
let mut std = Scope::new();
- macro_rules! set {
- (func: $name:expr, $func:expr) => {
- std.def_const($name, ValueFunc::new(Some($name.into()), $func))
+
+ macro_rules! func {
+ ($name:expr, $func:expr) => {
+ std.def_const($name, FuncValue::new(Some($name.into()), $func))
};
- (any: $var:expr, $any:expr) => {
- std.def_const($var, ValueAny::new($any))
+ }
+
+ macro_rules! constant {
+ ($var:expr, $any:expr) => {
+ std.def_const($var, AnyValue::new($any))
};
}
- // Functions.
- set!(func: "align", align);
- set!(func: "font", font);
- set!(func: "h", h);
- set!(func: "image", image);
- set!(func: "pad", pad);
- set!(func: "page", page);
- set!(func: "pagebreak", pagebreak);
- set!(func: "paragraph", paragraph);
- set!(func: "rect", rect);
- set!(func: "repr", repr);
- set!(func: "rgb", rgb);
- set!(func: "type", type_);
- set!(func: "v", v);
+ func!("align", align);
+ func!("font", font);
+ func!("h", h);
+ func!("image", image);
+ func!("pad", pad);
+ func!("page", page);
+ func!("pagebreak", pagebreak);
+ func!("paragraph", par);
+ func!("rect", rect);
+ func!("repr", repr);
+ func!("rgb", rgb);
+ func!("type", type_);
+ func!("v", v);
- // Constants.
- set!(any: "left", AlignValue::Left);
- set!(any: "center", AlignValue::Center);
- set!(any: "right", AlignValue::Right);
- set!(any: "top", AlignValue::Top);
- set!(any: "bottom", AlignValue::Bottom);
- set!(any: "ltr", Dir::LTR);
- set!(any: "rtl", Dir::RTL);
- set!(any: "ttb", Dir::TTB);
- set!(any: "btt", Dir::BTT);
- set!(any: "serif", FontFamily::Serif);
- set!(any: "sans-serif", FontFamily::SansSerif);
- set!(any: "monospace", FontFamily::Monospace);
- set!(any: "normal", FontStyle::Normal);
- set!(any: "italic", FontStyle::Italic);
- set!(any: "oblique", FontStyle::Oblique);
- set!(any: "thin", FontWeight::THIN);
- set!(any: "extralight", FontWeight::EXTRALIGHT);
- set!(any: "light", FontWeight::LIGHT);
- set!(any: "regular", FontWeight::REGULAR);
- set!(any: "medium", FontWeight::MEDIUM);
- set!(any: "semibold", FontWeight::SEMIBOLD);
- set!(any: "bold", FontWeight::BOLD);
- set!(any: "extrabold", FontWeight::EXTRABOLD);
- set!(any: "black", FontWeight::BLACK);
- set!(any: "ascender", VerticalFontMetric::Ascender);
- set!(any: "cap-height", VerticalFontMetric::CapHeight);
- set!(any: "x-height", VerticalFontMetric::XHeight);
- set!(any: "baseline", VerticalFontMetric::Baseline);
- set!(any: "descender", VerticalFontMetric::Descender);
+ constant!("left", AlignValue::Left);
+ constant!("center", AlignValue::Center);
+ 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);
std
}
diff --git a/src/library/pad.rs b/src/library/pad.rs
index 5d59f2b3..9f05f7ce 100644
--- a/src/library/pad.rs
+++ b/src/library/pad.rs
@@ -1,4 +1,5 @@
use super::*;
+use crate::layout::PadNode;
/// `pad`: Pad content at the sides.
///
@@ -14,13 +15,13 @@ use super::*;
///
/// # Return value
/// A template that pads the body at the sides.
-pub fn pad(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn pad(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let all = args.find(ctx);
let left = args.get(ctx, "left");
let top = args.get(ctx, "top");
let right = args.get(ctx, "right");
let bottom = args.get(ctx, "bottom");
- let body = args.require::<ValueTemplate>(ctx, "body").unwrap_or_default();
+ let body = args.require::<TemplateValue>(ctx, "body").unwrap_or_default();
let padding = Sides::new(
left.or(all).unwrap_or_default(),
@@ -31,10 +32,8 @@ pub fn pad(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
Value::template("pad", move |ctx| {
let snapshot = ctx.state.clone();
-
let child = ctx.exec(&body).into();
- ctx.push(NodePad { padding, child });
-
+ ctx.push(PadNode { padding, child });
ctx.state = snapshot;
})
}
diff --git a/src/library/page.rs b/src/library/page.rs
index f7d76eaf..067258f5 100644
--- a/src/library/page.rs
+++ b/src/library/page.rs
@@ -30,7 +30,7 @@ use crate::paper::{Paper, PaperClass};
/// - `rtl` (right to left)
/// - `ttb` (top to bottom)
/// - `btt` (bottom to top)
-pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn page(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let paper = args.find::<Spanned<String>>(ctx).and_then(|name| {
Paper::from_name(&name.v).or_else(|| {
ctx.diag(error!(name.span, "invalid paper name"));
@@ -48,7 +48,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
let flip = args.get(ctx, "flip");
let main = args.get(ctx, "main-dir");
let cross = args.get(ctx, "cross-dir");
- let body = args.find::<ValueTemplate>(ctx);
+ let body = args.find::<TemplateValue>(ctx);
let span = args.span;
Value::template("page", move |ctx| {
@@ -110,7 +110,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
///
/// # Return value
/// A template that starts a new page.
-pub fn pagebreak(_: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn pagebreak(_: &mut EvalContext, args: &mut FuncArgs) -> Value {
let span = args.span;
Value::template("pagebreak", move |ctx| {
ctx.finish_page(true, true, span);
diff --git a/src/library/par.rs b/src/library/par.rs
index 8242bfdc..a7db46de 100644
--- a/src/library/par.rs
+++ b/src/library/par.rs
@@ -2,6 +2,9 @@ use super::*;
/// `paragraph`: Configure paragraphs.
///
+/// # Positional parameters
+/// - Body: optional, of type `template`.
+///
/// # Named parameters
/// - Paragraph spacing: `spacing`, of type `linear` relative to current font size.
/// - Line leading: `leading`, of type `linear` relative to current font size.
@@ -10,11 +13,11 @@ use super::*;
/// # Return value
/// A template that configures paragraph properties. The effect is scoped to the
/// body if present.
-pub fn paragraph(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn par(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let spacing = args.get(ctx, "spacing");
let leading = args.get(ctx, "leading");
let word_spacing = args.get(ctx, "word-spacing");
- let body = args.find::<ValueTemplate>(ctx);
+ let body = args.find::<TemplateValue>(ctx);
Value::template("paragraph", move |ctx| {
let snapshot = ctx.state.clone();
diff --git a/src/library/shapes.rs b/src/library/shapes.rs
index 48bc7ebd..211a4f2e 100644
--- a/src/library/shapes.rs
+++ b/src/library/shapes.rs
@@ -1,4 +1,5 @@
use super::*;
+use crate::layout::{BackgroundNode, Fill, FixedNode};
/// `rect`: Create a rectangular box.
///
@@ -21,13 +22,13 @@ use super::*;
/// - `rtl` (right to left)
/// - `ttb` (top to bottom)
/// - `btt` (bottom to top)
-pub fn rect(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn rect(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let width = args.get(ctx, "width");
let height = args.get(ctx, "height");
let main = args.get(ctx, "main-dir");
let cross = args.get(ctx, "cross-dir");
let fill = args.get(ctx, "fill");
- let body = args.find::<ValueTemplate>(ctx).unwrap_or_default();
+ let body = args.find::<TemplateValue>(ctx).unwrap_or_default();
Value::template("box", move |ctx| {
let snapshot = ctx.state.clone();
@@ -35,9 +36,9 @@ pub fn rect(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
ctx.set_dirs(Gen::new(main, cross));
let child = ctx.exec(&body).into();
- let fixed = NodeFixed { width, height, child };
+ let fixed = FixedNode { width, height, child };
if let Some(color) = fill {
- ctx.push(NodeBackground {
+ ctx.push(BackgroundNode {
fill: Fill::Color(color),
child: fixed.into(),
});
diff --git a/src/library/spacing.rs b/src/library/spacing.rs
index 4965a220..fee802fa 100644
--- a/src/library/spacing.rs
+++ b/src/library/spacing.rs
@@ -1,4 +1,5 @@
use super::*;
+use crate::layout::SpacingNode;
/// `h`: Add horizontal spacing.
///
@@ -7,7 +8,7 @@ use super::*;
///
/// # Return value
/// A template that adds horizontal spacing.
-pub fn h(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn h(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
spacing(ctx, args, SpecAxis::Horizontal)
}
@@ -18,17 +19,17 @@ pub fn h(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
///
/// # Return value
/// A template that adds vertical spacing.
-pub fn v(ctx: &mut EvalContext, args: &mut ValueArgs) -> Value {
+pub fn v(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
spacing(ctx, args, SpecAxis::Vertical)
}
/// Apply spacing along a specific axis.
-fn spacing(ctx: &mut EvalContext, args: &mut ValueArgs, axis: SpecAxis) -> Value {
+fn spacing(ctx: &mut EvalContext, args: &mut FuncArgs, axis: SpecAxis) -> Value {
let spacing: Option<Linear> = args.require(ctx, "spacing");
Value::template("spacing", move |ctx| {
if let Some(linear) = spacing {
let amount = linear.resolve(ctx.state.font.font_size());
- let spacing = NodeSpacing { amount, softness: 0 };
+ let spacing = SpacingNode { amount, softness: 0 };
if axis == ctx.state.dirs.main.axis() {
ctx.push_into_stack(spacing);
} else {
diff --git a/src/main.rs b/src/main.rs
index ae655253..8b56512d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,10 +5,9 @@ use anyhow::{anyhow, bail, Context};
use fontdock::fs::FsIndex;
use typst::diag::Pass;
-use typst::env::{Env, ResourceLoader};
+use typst::env::{Env, FsIndexExt, ResourceLoader};
use typst::exec::State;
use typst::export::pdf;
-use typst::font::FsIndexExt;
use typst::library;
use typst::parse::LineMap;
use typst::typeset;
diff --git a/src/parse/mod.rs b/src/parse/mod.rs
index f23f1978..ceb8a206 100644
--- a/src/parse/mod.rs
+++ b/src/parse/mod.rs
@@ -136,11 +136,11 @@ fn heading(p: &mut Parser) -> Node {
contents.extend(node(p, &mut false));
}
- Node::Heading(NodeHeading { level, contents })
+ Node::Heading(HeadingNode { level, contents })
}
/// Handle a raw block.
-fn raw(p: &mut Parser, token: TokenRaw) -> Node {
+fn raw(p: &mut Parser, token: RawToken) -> Node {
let raw = resolve::resolve_raw(token.text, token.backticks, p.start());
if !token.terminated {
p.diag(error!(p.peek_span().end, "expected backtick(s)"));
@@ -149,7 +149,7 @@ fn raw(p: &mut Parser, token: TokenRaw) -> Node {
}
/// Handle a unicode escape sequence.
-fn unicode_escape(p: &mut Parser, token: TokenUnicodeEscape) -> String {
+fn unicode_escape(p: &mut Parser, token: UnicodeEscapeToken) -> String {
let span = p.peek_span();
let text = if let Some(c) = resolve::resolve_hex(token.sequence) {
c.to_string()
@@ -184,7 +184,7 @@ fn expr_with(p: &mut Parser, atomic: bool, min_prec: usize) -> Option<Expr> {
Some(op) => {
let prec = op.precedence();
let expr = Box::new(expr_with(p, atomic, prec)?);
- Expr::Unary(ExprUnary { span: p.span(start), op, expr })
+ Expr::Unary(UnaryExpr { span: p.span(start), op, expr })
}
None => primary(p, atomic)?,
};
@@ -225,7 +225,7 @@ fn expr_with(p: &mut Parser, atomic: bool, min_prec: usize) -> Option<Expr> {
};
let span = lhs.span().join(rhs.span());
- lhs = Expr::Binary(ExprBinary { span, lhs: Box::new(lhs), op, rhs });
+ lhs = Expr::Binary(BinaryExpr { span, lhs: Box::new(lhs), op, rhs });
}
Some(lhs)
@@ -248,7 +248,7 @@ fn primary(p: &mut Parser, atomic: bool) -> Option<Expr> {
// Arrow means this is a closure's lone parameter.
Some(if !atomic && p.eat_if(Token::Arrow) {
let body = expr(p)?;
- Expr::Closure(ExprClosure {
+ Expr::Closure(ClosureExpr {
span: id.span.join(body.span()),
name: None,
params: Rc::new(vec![id]),
@@ -306,7 +306,7 @@ fn literal(p: &mut Parser) -> Option<Expr> {
/// - Dictionary literal
/// - Parenthesized expression
/// - Parameter list of closure expression
-pub fn parenthesized(p: &mut Parser) -> Option<Expr> {
+fn parenthesized(p: &mut Parser) -> Option<Expr> {
p.start_group(Group::Paren, TokenMode::Code);
let colon = p.eat_if(Token::Colon);
let (items, has_comma) = collection(p);
@@ -321,7 +321,7 @@ pub fn parenthesized(p: &mut Parser) -> Option<Expr> {
if p.eat_if(Token::Arrow) {
let params = params(p, items);
let body = expr(p)?;
- return Some(Expr::Closure(ExprClosure {
+ return Some(Expr::Closure(ClosureExpr {
span: span.join(body.span()),
name: None,
params: Rc::new(params),
@@ -332,21 +332,21 @@ pub fn parenthesized(p: &mut Parser) -> Option<Expr> {
// Find out which kind of collection this is.
Some(match items.as_slice() {
[] => array(p, items, span),
- [ExprArg::Pos(_)] if !has_comma => match items.into_iter().next() {
- Some(ExprArg::Pos(expr)) => {
- Expr::Group(ExprGroup { span, expr: Box::new(expr) })
+ [CallArg::Pos(_)] if !has_comma => match items.into_iter().next() {
+ Some(CallArg::Pos(expr)) => {
+ Expr::Group(GroupExpr { span, expr: Box::new(expr) })
}
_ => unreachable!(),
},
- [ExprArg::Pos(_), ..] => array(p, items, span),
- [ExprArg::Named(_), ..] => dict(p, items, span),
+ [CallArg::Pos(_), ..] => array(p, items, span),
+ [CallArg::Named(_), ..] => dict(p, items, span),
})
}
/// Parse a collection.
///
/// Returns whether the literal contained any commas.
-fn collection(p: &mut Parser) -> (Vec<ExprArg>, bool) {
+fn collection(p: &mut Parser) -> (Vec<CallArg>, bool) {
let mut items = vec![];
let mut has_comma = false;
let mut missing_coma = None;
@@ -376,52 +376,52 @@ fn collection(p: &mut Parser) -> (Vec<ExprArg>, bool) {
}
/// Parse an expression or a named pair.
-fn item(p: &mut Parser) -> Option<ExprArg> {
+fn item(p: &mut Parser) -> Option<CallArg> {
let first = expr(p)?;
if p.eat_if(Token::Colon) {
if let Expr::Ident(name) = first {
- Some(ExprArg::Named(Named { name, expr: expr(p)? }))
+ Some(CallArg::Named(Named { name, expr: expr(p)? }))
} else {
p.diag(error!(first.span(), "expected identifier"));
expr(p);
None
}
} else {
- Some(ExprArg::Pos(first))
+ Some(CallArg::Pos(first))
}
}
/// Convert a collection into an array, producing errors for named items.
-fn array(p: &mut Parser, items: Vec<ExprArg>, span: Span) -> Expr {
+fn array(p: &mut Parser, items: Vec<CallArg>, span: Span) -> Expr {
let items = items.into_iter().filter_map(|item| match item {
- ExprArg::Pos(expr) => Some(expr),
- ExprArg::Named(_) => {
+ CallArg::Pos(expr) => Some(expr),
+ CallArg::Named(_) => {
p.diag(error!(item.span(), "expected expression, found named pair"));
None
}
});
- Expr::Array(ExprArray { span, items: items.collect() })
+ Expr::Array(ArrayExpr { span, items: items.collect() })
}
/// Convert a collection into a dictionary, producing errors for expressions.
-fn dict(p: &mut Parser, items: Vec<ExprArg>, span: Span) -> Expr {
+fn dict(p: &mut Parser, items: Vec<CallArg>, span: Span) -> Expr {
let items = items.into_iter().filter_map(|item| match item {
- ExprArg::Named(named) => Some(named),
- ExprArg::Pos(_) => {
+ CallArg::Named(named) => Some(named),
+ CallArg::Pos(_) => {
p.diag(error!(item.span(), "expected named pair, found expression"));
None
}
});
- Expr::Dict(ExprDict { span, items: items.collect() })
+ Expr::Dict(DictExpr { span, items: items.collect() })
}
/// Convert a collection into a parameter list, producing errors for anything
/// other than identifiers.
-fn params(p: &mut Parser, items: Vec<ExprArg>) -> Vec<Ident> {
+fn params(p: &mut Parser, items: Vec<CallArg>) -> Vec<Ident> {
let items = items.into_iter().filter_map(|item| match item {
- ExprArg::Pos(Expr::Ident(id)) => Some(id),
+ CallArg::Pos(Expr::Ident(id)) => Some(id),
_ => {
p.diag(error!(item.span(), "expected identifier"));
None
@@ -435,7 +435,7 @@ fn template(p: &mut Parser) -> Expr {
p.start_group(Group::Bracket, TokenMode::Markup);
let tree = Rc::new(tree(p));
let span = p.end_group();
- Expr::Template(ExprTemplate { span, tree })
+ Expr::Template(TemplateExpr { span, tree })
}
/// Parse a block expression: `{...}`.
@@ -454,7 +454,7 @@ fn block(p: &mut Parser, scoping: bool) -> Expr {
p.skip_white();
}
let span = p.end_group();
- Expr::Block(ExprBlock { span, exprs, scoping })
+ Expr::Block(BlockExpr { span, exprs, scoping })
}
/// Parse a function call.
@@ -466,7 +466,7 @@ fn call(p: &mut Parser, callee: Expr) -> Expr {
p.end_group();
args
}
- _ => ExprArgs {
+ _ => CallArgs {
span: Span::at(callee.span().end),
items: vec![],
},
@@ -474,10 +474,10 @@ fn call(p: &mut Parser, callee: Expr) -> Expr {
if p.peek_direct() == Some(Token::LeftBracket) {
let body = template(p);
- args.items.push(ExprArg::Pos(body));
+ args.items.push(CallArg::Pos(body));
}
- Expr::Call(ExprCall {
+ Expr::Call(CallExpr {
span: p.span(callee.span().start),
callee: Box::new(callee),
args,
@@ -485,10 +485,10 @@ fn call(p: &mut Parser, callee: Expr) -> Expr {
}
/// Parse the arguments to a function call.
-fn args(p: &mut Parser) -> ExprArgs {
+fn args(p: &mut Parser) -> CallArgs {
let start = p.start();
let items = collection(p).0;
- ExprArgs { span: p.span(start), items }
+ CallArgs { span: p.span(start), items }
}
/// Parse a let expression.
@@ -518,7 +518,7 @@ fn expr_let(p: &mut Parser) -> Option<Expr> {
// Rewrite into a closure expression if it's a function definition.
if let Some(params) = parameters {
let body = init?;
- init = Some(Expr::Closure(ExprClosure {
+ init = Some(Expr::Closure(ClosureExpr {
span: binding.span.join(body.span()),
name: Some(binding.clone()),
params: Rc::new(params),
@@ -526,7 +526,7 @@ fn expr_let(p: &mut Parser) -> Option<Expr> {
}));
}
- expr_let = Some(Expr::Let(ExprLet {
+ expr_let = Some(Expr::Let(LetExpr {
span: p.span(start),
binding,
init: init.map(Box::new),
@@ -555,7 +555,7 @@ fn expr_if(p: &mut Parser) -> Option<Expr> {
else_body = body(p);
}
- expr_if = Some(Expr::If(ExprIf {
+ expr_if = Some(Expr::If(IfExpr {
span: p.span(start),
condition: Box::new(condition),
if_body: Box::new(if_body),
@@ -575,7 +575,7 @@ fn expr_while(p: &mut Parser) -> Option<Expr> {
let mut expr_while = None;
if let Some(condition) = expr(p) {
if let Some(body) = body(p) {
- expr_while = Some(Expr::While(ExprWhile {
+ expr_while = Some(Expr::While(WhileExpr {
span: p.span(start),
condition: Box::new(condition),
body: Box::new(body),
@@ -596,7 +596,7 @@ fn expr_for(p: &mut Parser) -> Option<Expr> {
if p.expect(Token::In) {
if let Some(iter) = expr(p) {
if let Some(body) = body(p) {
- expr_for = Some(Expr::For(ExprFor {
+ expr_for = Some(Expr::For(ForExpr {
span: p.span(start),
pattern,
iter: Box::new(iter),
diff --git a/src/parse/resolve.rs b/src/parse/resolve.rs
index 88e11784..1f33198a 100644
--- a/src/parse/resolve.rs
+++ b/src/parse/resolve.rs
@@ -1,5 +1,5 @@
use super::{is_newline, Scanner};
-use crate::syntax::{Ident, NodeRaw, Pos};
+use crate::syntax::{Ident, Pos, RawNode};
/// Resolve all escape sequences in a string.
pub fn resolve_string(string: &str) -> String {
@@ -47,17 +47,17 @@ pub fn resolve_hex(sequence: &str) -> Option<char> {
}
/// Resolve the language tag and trims the raw text.
-pub fn resolve_raw(text: &str, backticks: usize, start: Pos) -> NodeRaw {
+pub fn resolve_raw(text: &str, backticks: usize, start: Pos) -> RawNode {
if backticks > 1 {
let (tag, inner) = split_at_lang_tag(text);
let (lines, had_newline) = trim_and_split_raw(inner);
- NodeRaw {
+ RawNode {
lang: Ident::new(tag, start .. start + tag.len()),
lines,
block: had_newline,
}
} else {
- NodeRaw {
+ RawNode {
lang: None,
lines: split_lines(text),
block: false,
@@ -105,7 +105,7 @@ fn trim_and_split_raw(mut raw: &str) -> (Vec<String>, bool) {
/// Split a string into a vector of lines
/// (respecting Unicode, Unix, Mac and Windows line breaks).
-pub fn split_lines(text: &str) -> Vec<String> {
+fn split_lines(text: &str) -> Vec<String> {
let mut s = Scanner::new(text);
let mut line = String::new();
let mut lines = Vec::new();
@@ -174,7 +174,7 @@ mod tests {
lines: &[&str],
block: bool,
) {
- Span::without_cmp(|| assert_eq!(resolve_raw(raw, backticks, Pos(0)), NodeRaw {
+ Span::without_cmp(|| assert_eq!(resolve_raw(raw, backticks, Pos(0)), RawNode {
lang: lang.and_then(|id| Ident::new(id, 0)),
lines: lines.iter().map(ToString::to_string).collect(),
block,
diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs
index a1457c22..a57db93b 100644
--- a/src/parse/tokens.rs
+++ b/src/parse/tokens.rs
@@ -232,7 +232,7 @@ impl<'s> Tokens<'s> {
// Special case for empty inline block.
if backticks == 2 {
- return Token::Raw(TokenRaw { text: "", backticks: 1, terminated: true });
+ return Token::Raw(RawToken { text: "", backticks: 1, terminated: true });
}
let start = self.s.index();
@@ -249,7 +249,7 @@ impl<'s> Tokens<'s> {
let terminated = found == backticks;
let end = self.s.index() - if terminated { found } else { 0 };
- Token::Raw(TokenRaw {
+ Token::Raw(RawToken {
text: self.s.get(start .. end),
backticks,
terminated,
@@ -286,7 +286,7 @@ impl<'s> Tokens<'s> {
(true, true) => 2,
};
- Token::Math(TokenMath {
+ Token::Math(MathToken {
formula: self.s.get(start .. end),
display,
terminated,
@@ -309,7 +309,7 @@ impl<'s> Tokens<'s> {
'u' if self.s.peek_nth(1) == Some('{') => {
self.s.eat_assert('u');
self.s.eat_assert('{');
- Token::UnicodeEscape(TokenUnicodeEscape {
+ Token::UnicodeEscape(UnicodeEscapeToken {
// Allow more than `ascii_hexdigit` for better error recovery.
sequence: self.s.eat_while(|c| c.is_ascii_alphanumeric()),
terminated: self.s.eat_if('}'),
@@ -391,7 +391,7 @@ impl<'s> Tokens<'s> {
fn string(&mut self) -> Token<'s> {
let mut escaped = false;
- Token::Str(TokenStr {
+ Token::Str(StrToken {
string: self.s.eat_until(|c| {
if c == '"' && !escaped {
true
@@ -470,19 +470,19 @@ mod tests {
use TokenMode::{Code, Markup};
const fn Raw(text: &str, backticks: usize, terminated: bool) -> Token {
- Token::Raw(TokenRaw { text, backticks, terminated })
+ Token::Raw(RawToken { text, backticks, terminated })
}
const fn Math(formula: &str, display: bool, terminated: bool) -> Token {
- Token::Math(TokenMath { formula, display, terminated })
+ Token::Math(MathToken { formula, display, terminated })
}
const fn UnicodeEscape(sequence: &str, terminated: bool) -> Token {
- Token::UnicodeEscape(TokenUnicodeEscape { sequence, terminated })
+ Token::UnicodeEscape(UnicodeEscapeToken { sequence, terminated })
}
const fn Str(string: &str, terminated: bool) -> Token {
- Token::Str(TokenStr { string, terminated })
+ Token::Str(StrToken { string, terminated })
}
const fn Color(r: u8, g: u8, b: u8, a: u8) -> Token<'static> {
diff --git a/src/prelude.rs b/src/prelude.rs
deleted file mode 100644
index 33542ad3..00000000
--- a/src/prelude.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-//! A prelude for building custom functions.
-
-pub use crate::diag::{Diag, Pass};
-#[doc(no_inline)]
-pub use crate::eval::{
- CastResult, Eval, EvalContext, TemplateFunc, TemplateNode, Value, ValueAny,
- ValueArgs, ValueArray, ValueDict, ValueTemplate,
-};
-#[doc(no_inline)]
-pub use crate::exec::{Exec, ExecContext};
-pub use crate::geom::*;
-#[doc(no_inline)]
-pub use crate::layout::Node;
-#[doc(no_inline)]
-pub use crate::syntax::{Span, Spanned};
-pub use crate::{error, typify, warning};
diff --git a/src/pretty.rs b/src/pretty.rs
index 963157c0..1db54d10 100644
--- a/src/pretty.rs
+++ b/src/pretty.rs
@@ -138,7 +138,7 @@ impl PrettyWithMap for Node {
}
}
-impl PrettyWithMap for NodeHeading {
+impl PrettyWithMap for HeadingNode {
fn pretty_with_map(&self, p: &mut Printer, map: Option<&ExprMap>) {
for _ in 0 ..= self.level {
p.push('=');
@@ -147,7 +147,7 @@ impl PrettyWithMap for NodeHeading {
}
}
-impl Pretty for NodeRaw {
+impl Pretty for RawNode {
fn pretty(&self, p: &mut Printer) {
// Find out how many backticks we need.
let mut backticks = 1;
@@ -250,7 +250,7 @@ impl Pretty for LitKind {
}
}
-impl Pretty for ExprArray {
+impl Pretty for ArrayExpr {
fn pretty(&self, p: &mut Printer) {
p.push('(');
p.join(&self.items, ", ", |item, p| item.pretty(p));
@@ -261,7 +261,7 @@ impl Pretty for ExprArray {
}
}
-impl Pretty for ExprDict {
+impl Pretty for DictExpr {
fn pretty(&self, p: &mut Printer) {
p.push('(');
if self.items.is_empty() {
@@ -281,7 +281,7 @@ impl Pretty for Named {
}
}
-impl Pretty for ExprTemplate {
+impl Pretty for TemplateExpr {
fn pretty(&self, p: &mut Printer) {
p.push('[');
self.tree.pretty_with_map(p, None);
@@ -289,7 +289,7 @@ impl Pretty for ExprTemplate {
}
}
-impl Pretty for ExprGroup {
+impl Pretty for GroupExpr {
fn pretty(&self, p: &mut Printer) {
p.push('(');
self.expr.pretty(p);
@@ -297,7 +297,7 @@ impl Pretty for ExprGroup {
}
}
-impl Pretty for ExprBlock {
+impl Pretty for BlockExpr {
fn pretty(&self, p: &mut Printer) {
p.push('{');
if self.exprs.len() > 1 {
@@ -311,7 +311,7 @@ impl Pretty for ExprBlock {
}
}
-impl Pretty for ExprUnary {
+impl Pretty for UnaryExpr {
fn pretty(&self, p: &mut Printer) {
self.op.pretty(p);
if self.op == UnOp::Not {
@@ -327,7 +327,7 @@ impl Pretty for UnOp {
}
}
-impl Pretty for ExprBinary {
+impl Pretty for BinaryExpr {
fn pretty(&self, p: &mut Printer) {
self.lhs.pretty(p);
p.push(' ');
@@ -343,11 +343,11 @@ impl Pretty for BinOp {
}
}
-impl Pretty for ExprCall {
+impl Pretty for CallExpr {
fn pretty(&self, p: &mut Printer) {
self.callee.pretty(p);
- let mut write_args = |items: &[ExprArg]| {
+ let mut write_args = |items: &[CallArg]| {
p.push('(');
p.join(items, ", ", |item, p| item.pretty(p));
p.push(')');
@@ -357,7 +357,7 @@ impl Pretty for ExprCall {
// This can be moved behind the arguments.
//
// Example: Transforms "#v(a, [b])" => "#v(a)[b]".
- [head @ .., ExprArg::Pos(Expr::Template(template))] => {
+ [head @ .., CallArg::Pos(Expr::Template(template))] => {
if !head.is_empty() {
write_args(head);
}
@@ -369,13 +369,13 @@ impl Pretty for ExprCall {
}
}
-impl Pretty for ExprArgs {
+impl Pretty for CallArgs {
fn pretty(&self, p: &mut Printer) {
p.join(&self.items, ", ", |item, p| item.pretty(p));
}
}
-impl Pretty for ExprArg {
+impl Pretty for CallArg {
fn pretty(&self, p: &mut Printer) {
match self {
Self::Pos(expr) => expr.pretty(p),
@@ -384,7 +384,7 @@ impl Pretty for ExprArg {
}
}
-impl Pretty for ExprClosure {
+impl Pretty for ClosureExpr {
fn pretty(&self, p: &mut Printer) {
p.push('(');
p.join(self.params.iter(), ", ", |item, p| item.pretty(p));
@@ -393,7 +393,7 @@ impl Pretty for ExprClosure {
}
}
-impl Pretty for ExprLet {
+impl Pretty for LetExpr {
fn pretty(&self, p: &mut Printer) {
p.push_str("let ");
self.binding.pretty(p);
@@ -404,7 +404,7 @@ impl Pretty for ExprLet {
}
}
-impl Pretty for ExprIf {
+impl Pretty for IfExpr {
fn pretty(&self, p: &mut Printer) {
p.push_str("if ");
self.condition.pretty(p);
@@ -418,7 +418,7 @@ impl Pretty for ExprIf {
}
}
-impl Pretty for ExprWhile {
+impl Pretty for WhileExpr {
fn pretty(&self, p: &mut Printer) {
p.push_str("while ");
self.condition.pretty(p);
@@ -427,7 +427,7 @@ impl Pretty for ExprWhile {
}
}
-impl Pretty for ExprFor {
+impl Pretty for ForExpr {
fn pretty(&self, p: &mut Printer) {
p.push_str("for ");
self.pattern.pretty(p);
@@ -475,14 +475,13 @@ impl Pretty for Value {
Value::Dict(v) => v.pretty(p),
Value::Template(v) => v.pretty(p),
Value::Func(v) => v.pretty(p),
- Value::Args(v) => v.pretty(p),
Value::Any(v) => v.pretty(p),
Value::Error => p.push_str("<error>"),
}
}
}
-impl Pretty for ValueArray {
+impl Pretty for ArrayValue {
fn pretty(&self, p: &mut Printer) {
p.push('(');
p.join(self, ", ", |item, p| item.pretty(p));
@@ -493,7 +492,7 @@ impl Pretty for ValueArray {
}
}
-impl Pretty for ValueDict {
+impl Pretty for DictValue {
fn pretty(&self, p: &mut Printer) {
p.push('(');
if self.is_empty() {
@@ -509,7 +508,7 @@ impl Pretty for ValueDict {
}
}
-impl Pretty for ValueTemplate {
+impl Pretty for TemplateValue {
fn pretty(&self, p: &mut Printer) {
p.push('[');
for part in self {
@@ -537,7 +536,7 @@ impl Pretty for TemplateFunc {
}
}
-impl Pretty for ValueFunc {
+impl Pretty for FuncValue {
fn pretty(&self, p: &mut Printer) {
p.push_str("<function");
if let Some(name) = self.name() {
@@ -548,7 +547,7 @@ impl Pretty for ValueFunc {
}
}
-impl Pretty for ValueArgs {
+impl Pretty for FuncArgs {
fn pretty(&self, p: &mut Printer) {
p.push('(');
p.join(&self.items, ", ", |item, p| item.pretty(p));
@@ -556,7 +555,7 @@ impl Pretty for ValueArgs {
}
}
-impl Pretty for ValueArg {
+impl Pretty for FuncArg {
fn pretty(&self, p: &mut Printer) {
if let Some(name) = &self.name {
p.push_str(&name.v);
@@ -613,7 +612,7 @@ pretty_display! {
Linear,
RgbaColor,
Color,
- ValueAny,
+ AnyValue,
}
#[cfg(test)]
@@ -622,9 +621,7 @@ mod tests {
use std::rc::Rc;
use super::*;
- use crate::color::RgbaColor;
use crate::env::Env;
- use crate::eval::eval;
use crate::parse::parse;
#[track_caller]
@@ -796,34 +793,37 @@ mod tests {
);
// Function.
- test_value(ValueFunc::new(None, |_, _| Value::None), "<function>");
+ test_value(FuncValue::new(None, |_, _| Value::None), "<function>");
test_value(
- ValueFunc::new(Some("nil".into()), |_, _| Value::None),
+ FuncValue::new(Some("nil".into()), |_, _| Value::None),
"<function nil>",
);
+ // Any.
+ test_value(AnyValue::new(1), "1");
+
+ // Error.
+ test_value(Value::Error, "<error>");
+ }
+
+ #[test]
+ fn test_pretty_print_args() {
// Arguments.
- test_value(
- ValueArgs {
+ assert_eq!(
+ pretty(&FuncArgs {
span: Span::ZERO,
items: vec![
- ValueArg {
+ FuncArg {
name: Some(Spanned::zero("a".into())),
value: Spanned::zero(Value::Int(1)),
},
- ValueArg {
+ FuncArg {
name: None,
value: Spanned::zero(Value::Int(2)),
},
],
- },
+ }),
"(a: 1, 2)",
);
-
- // Any.
- test_value(ValueAny::new(1), "1");
-
- // Error.
- test_value(Value::Error, "<error>");
}
}
diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs
index 5d10349b..2c631991 100644
--- a/src/syntax/expr.rs
+++ b/src/syntax/expr.rs
@@ -7,36 +7,36 @@ use crate::geom::{AngularUnit, LengthUnit};
/// An expression.
#[derive(Debug, Clone, PartialEq)]
pub enum Expr {
- /// A literal.
+ /// A literal, like `11pt` or `"hi"`.
Lit(Lit),
/// An identifier: `left`.
Ident(Ident),
/// An array expression: `(1, "hi", 12cm)`.
- Array(ExprArray),
+ Array(ArrayExpr),
/// A dictionary expression: `(color: #f79143, pattern: dashed)`.
- Dict(ExprDict),
+ Dict(DictExpr),
/// A template expression: `[*Hi* there!]`.
- Template(ExprTemplate),
+ Template(TemplateExpr),
/// A grouped expression: `(1 + 2)`.
- Group(ExprGroup),
+ Group(GroupExpr),
/// A block expression: `{ let x = 1; x + 2 }`.
- Block(ExprBlock),
+ Block(BlockExpr),
/// A unary operation: `-x`.
- Unary(ExprUnary),
+ Unary(UnaryExpr),
/// A binary operation: `a + b`.
- Binary(ExprBinary),
+ Binary(BinaryExpr),
/// An invocation of a function: `f(x, y)`.
- Call(ExprCall),
+ Call(CallExpr),
/// A closure expression: `(x, y) => z`.
- Closure(ExprClosure),
+ Closure(ClosureExpr),
/// A let expression: `let x = 1`.
- Let(ExprLet),
- /// An if expression: `if x { y } else { z }`.
- If(ExprIf),
- /// A while expression: `while x { y }`.
- While(ExprWhile),
- /// A for expression: `for x in y { z }`.
- For(ExprFor),
+ Let(LetExpr),
+ /// An if-else expression: `if x { y } else { z }`.
+ If(IfExpr),
+ /// A while loop expression: `while x { y }`.
+ While(WhileExpr),
+ /// A for loop expression: `for x in y { z }`.
+ For(ForExpr),
}
impl Expr {
@@ -74,7 +74,7 @@ impl Expr {
}
}
-/// A literal.
+/// A literal, like `11pt` or `"hi"`.
#[derive(Debug, Clone, PartialEq)]
pub struct Lit {
/// The source code location.
@@ -111,7 +111,7 @@ pub enum LitKind {
/// An array expression: `(1, "hi", 12cm)`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprArray {
+pub struct ArrayExpr {
/// The source code location.
pub span: Span,
/// The entries of the array.
@@ -120,7 +120,7 @@ pub struct ExprArray {
/// A dictionary expression: `(color: #f79143, pattern: dashed)`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprDict {
+pub struct DictExpr {
/// The source code location.
pub span: Span,
/// The named dictionary entries.
@@ -145,7 +145,7 @@ impl Named {
/// A template expression: `[*Hi* there!]`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprTemplate {
+pub struct TemplateExpr {
/// The source code location.
pub span: Span,
/// The contents of the template.
@@ -154,7 +154,7 @@ pub struct ExprTemplate {
/// A grouped expression: `(1 + 2)`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprGroup {
+pub struct GroupExpr {
/// The source code location.
pub span: Span,
/// The wrapped expression.
@@ -163,7 +163,7 @@ pub struct ExprGroup {
/// A block expression: `{ let x = 1; x + 2 }`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprBlock {
+pub struct BlockExpr {
/// The source code location.
pub span: Span,
/// The list of expressions contained in the block.
@@ -174,7 +174,7 @@ pub struct ExprBlock {
/// A unary operation: `-x`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprUnary {
+pub struct UnaryExpr {
/// The source code location.
pub span: Span,
/// The operator: `-`.
@@ -225,7 +225,7 @@ impl UnOp {
/// A binary operation: `a + b`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprBinary {
+pub struct BinaryExpr {
/// The source code location.
pub span: Span,
/// The left-hand side of the operation: `a`.
@@ -374,13 +374,13 @@ pub enum Associativity {
/// An invocation of a function: `foo(...)`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprCall {
+pub struct CallExpr {
/// The source code location.
pub span: Span,
/// The callee of the function.
pub callee: Box<Expr>,
/// The arguments to the function.
- pub args: ExprArgs,
+ pub args: CallArgs,
}
/// The arguments to a function: `12, draw: false`.
@@ -388,23 +388,23 @@ pub struct ExprCall {
/// In case of a bracketed invocation with a body, the body is _not_
/// included in the span for the sake of clearer error messages.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprArgs {
+pub struct CallArgs {
/// The source code location.
pub span: Span,
/// The positional and named arguments.
- pub items: Vec<ExprArg>,
+ pub items: Vec<CallArg>,
}
/// An argument to a function call: `12` or `draw: false`.
#[derive(Debug, Clone, PartialEq)]
-pub enum ExprArg {
+pub enum CallArg {
/// A positional argument.
Pos(Expr),
/// A named argument.
Named(Named),
}
-impl ExprArg {
+impl CallArg {
/// The source code location.
pub fn span(&self) -> Span {
match self {
@@ -416,7 +416,7 @@ impl ExprArg {
/// A closure expression: `(x, y) => z`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprClosure {
+pub struct ClosureExpr {
/// The source code location.
pub span: Span,
/// The name of the closure.
@@ -431,7 +431,7 @@ pub struct ExprClosure {
/// A let expression: `let x = 1`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprLet {
+pub struct LetExpr {
/// The source code location.
pub span: Span,
/// The binding to assign to.
@@ -440,9 +440,9 @@ pub struct ExprLet {
pub init: Option<Box<Expr>>,
}
-/// An if expression: `if x { y } else { z }`.
+/// An if-else expression: `if x { y } else { z }`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprIf {
+pub struct IfExpr {
/// The source code location.
pub span: Span,
/// The condition which selects the body to evaluate.
@@ -453,9 +453,9 @@ pub struct ExprIf {
pub else_body: Option<Box<Expr>>,
}
-/// A while expression: `while x { y }`.
+/// A while loop expression: `while x { y }`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprWhile {
+pub struct WhileExpr {
/// The source code location.
pub span: Span,
/// The condition which selects whether to evaluate the body.
@@ -464,9 +464,9 @@ pub struct ExprWhile {
pub body: Box<Expr>,
}
-/// A for expression: `for x in y { z }`.
+/// A for loop expression: `for x in y { z }`.
#[derive(Debug, Clone, PartialEq)]
-pub struct ExprFor {
+pub struct ForExpr {
/// The source code location.
pub span: Span,
/// The pattern to assign to.
diff --git a/src/syntax/ident.rs b/src/syntax/ident.rs
index 26c46b98..a46ad232 100644
--- a/src/syntax/ident.rs
+++ b/src/syntax/ident.rs
@@ -4,7 +4,7 @@ use unicode_xid::UnicodeXID;
use super::Span;
-/// An Unicode identifier with a few extra permissible characters.
+/// An unicode identifier with a few extra permissible characters.
///
/// In addition to what is specified in the [Unicode Standard][uax31], we allow:
/// - `_` as a starting character,
diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs
index 09c445b0..9426090c 100644
--- a/src/syntax/mod.rs
+++ b/src/syntax/mod.rs
@@ -14,4 +14,6 @@ pub use span::*;
pub use token::*;
/// The abstract syntax tree.
+///
+/// This type can represent a full parsed document.
pub type Tree = Vec<Node>;
diff --git a/src/syntax/node.rs b/src/syntax/node.rs
index 19fdfa50..c94ee5b0 100644
--- a/src/syntax/node.rs
+++ b/src/syntax/node.rs
@@ -16,23 +16,23 @@ pub enum Node {
/// Plain text.
Text(String),
/// A section heading.
- Heading(NodeHeading),
+ Heading(HeadingNode),
/// An optionally syntax-highlighted raw block.
- Raw(NodeRaw),
+ Raw(RawNode),
/// An expression.
Expr(Expr),
}
/// A section heading: `= Introduction`.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodeHeading {
+pub struct HeadingNode {
/// The section depth (numer of equals signs minus 1).
pub level: usize,
/// The contents of the heading.
pub contents: Tree,
}
-/// A raw block with optional syntax highlighting: `` `raw` ``.
+/// A raw block with optional syntax highlighting: `` `...` ``.
///
/// Raw blocks start with 1 or 3+ backticks and end with the same number of
/// backticks.
@@ -96,7 +96,7 @@ pub struct NodeHeading {
/// Note that with these rules you can always force leading or trailing
/// whitespace simply by adding more spaces.
#[derive(Debug, Clone, PartialEq)]
-pub struct NodeRaw {
+pub struct RawNode {
/// An optional identifier specifying the language to syntax-highlight in.
pub lang: Option<Ident>,
/// The lines of raw text, determined as the raw string between the
diff --git a/src/syntax/span.rs b/src/syntax/span.rs
index d939ed28..d3683c1a 100644
--- a/src/syntax/span.rs
+++ b/src/syntax/span.rs
@@ -32,7 +32,7 @@ impl<T> Spanned<T> {
Spanned { v: &self.v, span: self.span }
}
- /// Map the value using a function while keeping the span.
+ /// Map the value using a function keeping the span.
pub fn map<F, U>(self, f: F) -> Spanned<U>
where
F: FnOnce(T) -> U,
diff --git a/src/syntax/token.rs b/src/syntax/token.rs
index e57620af..832c923d 100644
--- a/src/syntax/token.rs
+++ b/src/syntax/token.rs
@@ -99,13 +99,13 @@ pub enum Token<'s> {
Text(&'s str),
/// An arbitrary number of backticks followed by inner contents, terminated
/// with the same number of backticks: `` `...` ``.
- Raw(TokenRaw<'s>),
+ Raw(RawToken<'s>),
/// One or two dollar signs followed by inner contents, terminated with the
/// same number of dollar signs.
- Math(TokenMath<'s>),
+ Math(MathToken<'s>),
/// A slash and the letter "u" followed by a hexadecimal unicode entity
/// enclosed in curly braces: `\u{1F5FA}`.
- UnicodeEscape(TokenUnicodeEscape<'s>),
+ UnicodeEscape(UnicodeEscapeToken<'s>),
/// An identifier: `center`.
Ident(&'s str),
/// A boolean: `true`, `false`.
@@ -126,7 +126,7 @@ pub enum Token<'s> {
/// A color value: `#20d82a`.
Color(RgbaColor),
/// A quoted string: `"..."`.
- Str(TokenStr<'s>),
+ Str(StrToken<'s>),
/// Two slashes followed by inner contents, terminated with a newline:
/// `//<str>\n`.
LineComment(&'s str),
@@ -139,9 +139,9 @@ pub enum Token<'s> {
Invalid(&'s str),
}
-/// A quoted string: `"..."`.
+/// A quoted string token: `"..."`.
#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct TokenStr<'s> {
+pub struct StrToken<'s> {
/// The string inside the quotes.
///
/// _Note_: If the string contains escape sequences these are not yet
@@ -152,9 +152,9 @@ pub struct TokenStr<'s> {
pub terminated: bool,
}
-/// A raw block: `` `...` ``.
+/// A raw block token: `` `...` ``.
#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct TokenRaw<'s> {
+pub struct RawToken<'s> {
/// The raw text between the backticks.
pub text: &'s str,
/// The number of opening backticks.
@@ -163,9 +163,9 @@ pub struct TokenRaw<'s> {
pub terminated: bool,
}
-/// A math formula: `$2pi + x$`, `$$f'(x) = x^2$$`.
+/// A math formula token: `$2pi + x$` or `$[f'(x) = x^2]$`.
#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct TokenMath<'s> {
+pub struct MathToken<'s> {
/// The formula between the dollars.
pub formula: &'s str,
/// Whether the formula is display-level, that is, it is surrounded by
@@ -175,9 +175,9 @@ pub struct TokenMath<'s> {
pub terminated: bool,
}
-/// A unicode escape sequence: `\u{1F5FA}`.
+/// A unicode escape sequence token: `\u{1F5FA}`.
#[derive(Debug, Copy, Clone, PartialEq)]
-pub struct TokenUnicodeEscape<'s> {
+pub struct UnicodeEscapeToken<'s> {
/// The escape sequence between the braces.
pub sequence: &'s str,
/// Whether the closing brace was present.
diff --git a/src/syntax/visit.rs b/src/syntax/visit.rs
index 15613233..04546c5d 100644
--- a/src/syntax/visit.rs
+++ b/src/syntax/visit.rs
@@ -82,29 +82,29 @@ visit! {
}
}
- fn visit_array(v, node: &ExprArray) {
+ fn visit_array(v, node: &ArrayExpr) {
for expr in &node.items {
v.visit_expr(&expr);
}
}
- fn visit_dict(v, node: &ExprDict) {
+ fn visit_dict(v, node: &DictExpr) {
for named in &node.items {
v.visit_expr(&named.expr);
}
}
- fn visit_template(v, node: &ExprTemplate) {
+ fn visit_template(v, node: &TemplateExpr) {
v.visit_enter();
v.visit_tree(&node.tree);
v.visit_exit();
}
- fn visit_group(v, node: &ExprGroup) {
+ fn visit_group(v, node: &GroupExpr) {
v.visit_expr(&node.expr);
}
- fn visit_block(v, node: &ExprBlock) {
+ fn visit_block(v, node: &BlockExpr) {
if node.scoping {
v.visit_enter();
}
@@ -116,48 +116,48 @@ visit! {
}
}
- fn visit_binary(v, node: &ExprBinary) {
+ fn visit_binary(v, node: &BinaryExpr) {
v.visit_expr(&node.lhs);
v.visit_expr(&node.rhs);
}
- fn visit_unary(v, node: &ExprUnary) {
+ fn visit_unary(v, node: &UnaryExpr) {
v.visit_expr(&node.expr);
}
- fn visit_call(v, node: &ExprCall) {
+ fn visit_call(v, node: &CallExpr) {
v.visit_expr(&node.callee);
v.visit_args(&node.args);
}
- fn visit_closure(v, node: &ExprClosure) {
+ fn visit_closure(v, node: &ClosureExpr) {
for param in node.params.iter() {
v.visit_binding(param);
}
v.visit_expr(&node.body);
}
- fn visit_args(v, node: &ExprArgs) {
+ fn visit_args(v, node: &CallArgs) {
for arg in &node.items {
v.visit_arg(arg);
}
}
- fn visit_arg(v, node: &ExprArg) {
+ fn visit_arg(v, node: &CallArg) {
match node {
- ExprArg::Pos(expr) => v.visit_expr(&expr),
- ExprArg::Named(named) => v.visit_expr(&named.expr),
+ CallArg::Pos(expr) => v.visit_expr(&expr),
+ CallArg::Named(named) => v.visit_expr(&named.expr),
}
}
- fn visit_let(v, node: &ExprLet) {
+ fn visit_let(v, node: &LetExpr) {
v.visit_binding(&node.binding);
if let Some(init) = &node.init {
v.visit_expr(&init);
}
}
- fn visit_if(v, node: &ExprIf) {
+ fn visit_if(v, node: &IfExpr) {
v.visit_expr(&node.condition);
v.visit_expr(&node.if_body);
if let Some(body) = &node.else_body {
@@ -165,12 +165,12 @@ visit! {
}
}
- fn visit_while(v, node: &ExprWhile) {
+ fn visit_while(v, node: &WhileExpr) {
v.visit_expr(&node.condition);
v.visit_expr(&node.body);
}
- fn visit_for(v, node: &ExprFor) {
+ fn visit_for(v, node: &ForExpr) {
match &node.pattern {
ForPattern::Value(value) => v.visit_binding(value),
ForPattern::KeyValue(key, value) => {