summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-08-14 15:24:59 +0200
committerLaurenz <laurmaedje@gmail.com>2021-08-14 15:55:39 +0200
commit6ae6d86b9c6fefe6c5379ac1b20ea90634c09c81 (patch)
tree2504c3b46807be148b9efbadf9b23e57bb77b8f3 /src/library
parentfcb4e451186067cdf6efe3c14cbfa7561b366a6c (diff)
Separate type for string values
Diffstat (limited to 'src/library')
-rw-r--r--src/library/elements.rs12
-rw-r--r--src/library/layout.rs24
-rw-r--r--src/library/mod.rs3
-rw-r--r--src/library/text.rs18
-rw-r--r--src/library/utility.rs44
5 files changed, 47 insertions, 54 deletions
diff --git a/src/library/elements.rs b/src/library/elements.rs
index f0e36994..1ad56a81 100644
--- a/src/library/elements.rs
+++ b/src/library/elements.rs
@@ -10,8 +10,8 @@ use crate::layout::{
};
/// `image`: An image.
-pub fn image(ctx: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
- let path = args.expect::<Spanned<EcoString>>("path to image file")?;
+pub fn image(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
+ let path = args.expect::<Spanned<Str>>("path to image file")?;
let width = args.named("width")?;
let height = args.named("height")?;
@@ -29,7 +29,7 @@ pub fn image(ctx: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `rect`: A rectangle with optional content.
-pub fn rect(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn rect(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
let fill = args.named("fill")?;
@@ -38,7 +38,7 @@ pub fn rect(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `square`: A square with optional content.
-pub fn square(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn square(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let length = args.named::<Length>("length")?.map(Linear::from);
let width = match length {
Some(length) => Some(length),
@@ -80,7 +80,7 @@ fn rect_impl(
}
/// `ellipse`: An ellipse with optional content.
-pub fn ellipse(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn ellipse(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
let fill = args.named("fill")?;
@@ -89,7 +89,7 @@ pub fn ellipse(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `circle`: A circle with optional content.
-pub fn circle(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn circle(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let diameter = args.named("radius")?.map(|r: Length| 2.0 * Linear::from(r));
let width = match diameter {
None => args.named("width")?,
diff --git a/src/library/layout.rs b/src/library/layout.rs
index 53e3a450..20673c4a 100644
--- a/src/library/layout.rs
+++ b/src/library/layout.rs
@@ -3,8 +3,8 @@ use crate::layout::{FixedNode, GridNode, PadNode, StackChild, StackNode, TrackSi
use crate::paper::{Paper, PaperClass};
/// `page`: Configure pages.
-pub fn page(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
- let paper = match args.eat::<Spanned<EcoString>>() {
+pub fn page(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
+ let paper = match args.eat::<Spanned<Str>>() {
Some(name) => match Paper::from_name(&name.v) {
None => bail!(name.span, "invalid paper name"),
paper => paper,
@@ -74,21 +74,21 @@ pub fn page(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `pagebreak`: Start a new page.
-pub fn pagebreak(_: &mut EvalContext, _: &mut FuncArgs) -> TypResult<Value> {
+pub fn pagebreak(_: &mut EvalContext, _: &mut Arguments) -> TypResult<Value> {
Ok(Value::template(move |ctx| ctx.pagebreak(true, true)))
}
/// `h`: Horizontal spacing.
-pub fn h(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn h(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
spacing_impl(args, GenAxis::Cross)
}
/// `v`: Vertical spacing.
-pub fn v(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn v(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
spacing_impl(args, GenAxis::Main)
}
-fn spacing_impl(args: &mut FuncArgs, axis: GenAxis) -> TypResult<Value> {
+fn spacing_impl(args: &mut Arguments, axis: GenAxis) -> TypResult<Value> {
let spacing = args.expect::<Linear>("spacing")?;
Ok(Value::template(move |ctx| {
// TODO: Should this really always be font-size relative?
@@ -98,7 +98,7 @@ fn spacing_impl(args: &mut FuncArgs, axis: GenAxis) -> TypResult<Value> {
}
/// `align`: Configure the alignment along the layouting axes.
-pub fn align(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn align(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let mut horizontal = args.named("horizontal")?;
let mut vertical = args.named("vertical")?;
let first = args.eat::<Align>();
@@ -132,7 +132,7 @@ pub fn align(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `box`: Place content in a rectangular box.
-pub fn boxed(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn boxed(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let width = args.named("width")?;
let height = args.named("height")?;
let body = args.eat().unwrap_or_default();
@@ -143,7 +143,7 @@ pub fn boxed(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `block`: Place content in a block.
-pub fn block(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn block(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let body = args.expect("body")?;
Ok(Value::template(move |ctx| {
let block = ctx.exec_template_stack(&body);
@@ -152,7 +152,7 @@ pub fn block(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `pad`: Pad content at the sides.
-pub fn pad(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn pad(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let all = args.eat();
let left = args.named("left")?;
let top = args.named("top")?;
@@ -174,7 +174,7 @@ pub fn pad(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `stack`: Stack children along an axis.
-pub fn stack(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn stack(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let dir = args.named("dir")?;
let children: Vec<_> = args.all().collect();
@@ -200,7 +200,7 @@ pub fn stack(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `grid`: Arrange children into a grid.
-pub fn grid(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn grid(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let columns = args.named("columns")?.unwrap_or_default();
let rows = args.named("rows")?.unwrap_or_default();
diff --git a/src/library/mod.rs b/src/library/mod.rs
index 3591e742..f1134282 100644
--- a/src/library/mod.rs
+++ b/src/library/mod.rs
@@ -18,12 +18,11 @@ use std::rc::Rc;
use crate::color::{Color, RgbaColor};
use crate::diag::TypResult;
-use crate::eval::{EvalContext, FuncArgs, Scope, Template, Type, Value};
+use crate::eval::{Arguments, EvalContext, Scope, Str, Template, Value};
use crate::exec::Exec;
use crate::font::{FontFamily, FontStretch, FontStyle, FontWeight, VerticalFontMetric};
use crate::geom::*;
use crate::syntax::Spanned;
-use crate::util::EcoString;
/// Construct a scope containing all standard library definitions.
pub fn new() -> Scope {
diff --git a/src/library/text.rs b/src/library/text.rs
index 55cabd15..9ffb182a 100644
--- a/src/library/text.rs
+++ b/src/library/text.rs
@@ -4,7 +4,7 @@ use crate::layout::Paint;
use super::*;
/// `font`: Configure the font.
-pub fn font(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn font(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let size = args.named::<Linear>("size")?.or_else(|| args.eat());
let style = args.named("style")?;
let weight = args.named("weight")?;
@@ -98,13 +98,13 @@ castable! {
values
.into_iter()
.filter_map(|v| v.cast().ok())
- .map(|string: EcoString| string.to_lowercase())
+ .map(|string: Str| string.to_lowercase())
.collect()
)),
}
/// `par`: Configure paragraphs.
-pub fn par(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn par(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let par_spacing = args.named("spacing")?;
let line_spacing = args.named("leading")?;
let body = args.expect::<Template>("body")?;
@@ -126,8 +126,8 @@ pub fn par(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `lang`: Configure the language.
-pub fn lang(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
- let iso = args.eat::<EcoString>();
+pub fn lang(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
+ let iso = args.eat::<Str>();
let dir = if let Some(dir) = args.named::<Spanned<Dir>>("dir")? {
if dir.v.axis() == SpecAxis::Horizontal {
Some(dir.v)
@@ -160,22 +160,22 @@ fn lang_dir(iso: &str) -> Dir {
}
/// `strike`: Enable striken-through text.
-pub fn strike(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn strike(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
line_impl(args, |font| &mut font.strikethrough)
}
/// `underline`: Enable underlined text.
-pub fn underline(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn underline(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
line_impl(args, |font| &mut font.underline)
}
/// `overline`: Add an overline above text.
-pub fn overline(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn overline(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
line_impl(args, |font| &mut font.overline)
}
fn line_impl(
- args: &mut FuncArgs,
+ args: &mut Arguments,
substate: fn(&mut FontState) -> &mut Option<Rc<LineState>>,
) -> TypResult<Value> {
let stroke = args.named("stroke")?.or_else(|| args.eat());
diff --git a/src/library/utility.rs b/src/library/utility.rs
index 20d10830..84f1d7ab 100644
--- a/src/library/utility.rs
+++ b/src/library/utility.rs
@@ -2,37 +2,34 @@ use std::cmp::Ordering;
use std::str::FromStr;
use crate::color::{Color, RgbaColor};
-use crate::pretty::pretty;
use super::*;
/// `type`: The name of a value's type.
-pub fn type_(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
- let value = args.expect::<Value>("value")?;
- Ok(value.type_name().into())
+pub fn type_(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
+ Ok(args.expect::<Value>("value")?.type_name().into())
}
/// `repr`: The string representation of a value.
-pub fn repr(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
- let value = args.expect::<Value>("value")?;
- Ok(pretty(&value).into())
+pub fn repr(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
+ Ok(args.expect::<Value>("value")?.to_string().into())
}
/// `len`: The length of a string, an array or a dictionary.
-pub fn len(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn len(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let Spanned { v, span } = args.expect("collection")?;
- Ok(match v {
- Value::Str(v) => Value::Int(v.len() as i64),
- Value::Array(v) => Value::Int(v.len()),
- Value::Dict(v) => Value::Int(v.len()),
+ Ok(Value::Int(match v {
+ Value::Str(v) => v.len(),
+ Value::Array(v) => v.len(),
+ Value::Dict(v) => v.len(),
_ => bail!(span, "expected string, array or dictionary"),
- })
+ }))
}
/// `rgb`: Create an RGB(A) color.
-pub fn rgb(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn rgb(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
Ok(Value::Color(Color::Rgba(
- if let Some(string) = args.eat::<Spanned<EcoString>>() {
+ if let Some(string) = args.eat::<Spanned<Str>>() {
match RgbaColor::from_str(&string.v) {
Ok(color) => color,
Err(_) => bail!(string.span, "invalid color"),
@@ -49,35 +46,32 @@ pub fn rgb(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
}
/// `min`: The minimum of a sequence of values.
-pub fn min(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn min(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
minmax(args, Ordering::Less)
}
/// `max`: The maximum of a sequence of values.
-pub fn max(_: &mut EvalContext, args: &mut FuncArgs) -> TypResult<Value> {
+pub fn max(_: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
minmax(args, Ordering::Greater)
}
/// Find the minimum or maximum of a sequence of values.
-fn minmax(args: &mut FuncArgs, goal: Ordering) -> TypResult<Value> {
- let span = args.span;
-
+fn minmax(args: &mut Arguments, goal: Ordering) -> TypResult<Value> {
let mut extremum = args.expect::<Value>("value")?;
- for value in args.all::<Value>() {
- match value.partial_cmp(&extremum) {
+ for Spanned { v, span } in args.all::<Spanned<Value>>() {
+ match v.partial_cmp(&extremum) {
Some(ordering) => {
if ordering == goal {
- extremum = value;
+ extremum = v;
}
}
None => bail!(
span,
"cannot compare {} with {}",
extremum.type_name(),
- value.type_name(),
+ v.type_name(),
),
}
}
-
Ok(extremum)
}