diff --git a/src/color.rs b/src/color.rs index b676be7c3..da26d2e24 100644 --- a/src/color.rs +++ b/src/color.rs @@ -6,7 +6,7 @@ use std::str::FromStr; /// A color in a dynamic format. #[derive(Copy, Clone, Eq, PartialEq)] pub enum Color { - /// An 8-bit RGBA color. + /// An 8-bit RGBA color: `#423abaff`. Rgba(RgbaColor), } @@ -18,13 +18,7 @@ impl Debug for Color { } } -/// An 8-bit RGBA color. -/// -/// # Example -/// ```typst -/// [page: background=#423abaff] -/// ^^^^^^^^ -/// ``` +/// An 8-bit RGBA color: `#423abaff`. #[derive(Copy, Clone, Eq, PartialEq)] pub struct RgbaColor { /// Red channel. diff --git a/src/eval/args.rs b/src/eval/args.rs index 765ae09c5..b379b9751 100644 --- a/src/eval/args.rs +++ b/src/eval/args.rs @@ -86,7 +86,7 @@ impl Args { }) } - /// Retrieve and remove all matching keyword arguments. + /// Retrieve and remove all matching named arguments. pub fn find_all_str(&mut self) -> impl Iterator + '_ where T: TryFromValue, diff --git a/src/eval/dict.rs b/src/eval/dict.rs index 1374c8405..efa5cb373 100644 --- a/src/eval/dict.rs +++ b/src/eval/dict.rs @@ -160,11 +160,9 @@ impl Debug for Dict { if self.0 { f.write_str("\"")?; } - if f.alternate() { - f.write_str(" = ")?; - } else { - f.write_str("=")?; - } + + f.write_str(": ")?; + self.2.fmt(f) } } @@ -511,13 +509,13 @@ mod tests { dict.insert("sp ace", "quotes"); assert_eq!( format!("{:?}", dict), - r#"(10="hello", "sp ace"="quotes", twenty="there")"#, + r#"(10: "hello", "sp ace": "quotes", twenty: "there")"#, ); assert_eq!(format!("{:#?}", dict).lines().collect::>(), [ "(", - r#" 10 = "hello","#, - r#" "sp ace" = "quotes","#, - r#" twenty = "there","#, + r#" 10: "hello","#, + r#" "sp ace": "quotes","#, + r#" twenty: "there","#, ")", ]); } diff --git a/src/eval/value.rs b/src/eval/value.rs index a27e9aa9a..f15ae0c50 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -36,7 +36,7 @@ pub enum Value { Color(Color), /// A string: `"string"`. Str(String), - /// A dictionary value: `(false, 12cm, greeting="hi")`. + /// A dictionary value: `(false, 12cm, greeting: "hi")`. Dict(ValueDict), /// A content value: `{*Hi* there}`. Content(SynTree), @@ -125,7 +125,7 @@ impl Debug for Value { /// /// # Example /// ```typst -/// (false, 12cm, greeting="hi") +/// (false, 12cm, greeting: "hi") /// ``` pub type ValueDict = Dict>; diff --git a/src/library/layout.rs b/src/library/layout.rs index c014cc349..c888ea185 100644 --- a/src/library/layout.rs +++ b/src/library/layout.rs @@ -12,7 +12,7 @@ use crate::prelude::*; /// - first (optional, `Alignment`): An alignment for any of the two axes. /// - second (optional, `Alignment`): An alignment for the other axis. /// -/// # Keyword arguments +/// # Named arguments /// - `horizontal` (`Alignment`): An alignment for the horizontal axis. /// - `vertical` (`Alignment`): An alignment for the vertical axis. /// @@ -188,7 +188,7 @@ impl Display for SpecAlign { /// `box`: Layout content into a box. /// -/// # Keyword arguments +/// # Named arguments /// - `width` (`linear` relative to parent width): The width of the box. /// - `height` (`linear` relative to parent height): The height of the box. pub fn boxed(mut args: Args, ctx: &mut EvalContext) -> Value { @@ -268,7 +268,7 @@ fn spacing(mut args: Args, ctx: &mut EvalContext, axis: SpecAxis) -> Value { /// # Positional arguments /// - Paper name (optional, `Paper`). /// -/// # Keyword arguments +/// # Named arguments /// - `width` (`length`): The width of pages. /// - `height` (`length`): The height of pages. /// - `margins` (`linear` relative to sides): The margins for all sides. diff --git a/src/library/style.rs b/src/library/style.rs index 8b8d9f26e..8571dac69 100644 --- a/src/library/style.rs +++ b/src/library/style.rs @@ -2,9 +2,9 @@ use std::rc::Rc; use fontdock::{FontStretch, FontStyle, FontWeight}; +use crate::color::{Color, RgbaColor}; use crate::eval::StringLike; use crate::geom::Linear; -use crate::color::{Color, RgbaColor}; use crate::prelude::*; /// `font`: Configure the font. @@ -13,7 +13,7 @@ use crate::prelude::*; /// - Font size (optional, `linear` relative to current font size). /// - Font families ... (optional, variadic, `Family`) /// -/// # Keyword arguments +/// # Named arguments /// - `style` (`Style`): The font style. /// - `weight` (`Weight`): The font weight. /// - `stretch` (`Stretch`): The font stretch. @@ -26,17 +26,17 @@ use crate::prelude::*; /// # Examples /// Set font size and font families. /// ```typst -/// [font: 12pt, "Arial", "Noto Sans", sans-serif] +/// [font 12pt, "Arial", "Noto Sans", sans-serif] /// ``` /// /// Redefine the default sans-serif family to a single font family. /// ```typst -/// [font: sans-serif="Source Sans Pro"] +/// [font sans-serif: "Source Sans Pro"] /// ``` /// /// Redefine the default emoji family with a fallback. /// ```typst -/// [font: emoji=("Segoe UI Emoji", "Noto Emoji")] +/// [font emoji: ("Segoe UI Emoji", "Noto Emoji")] /// ``` /// /// # Enumerations diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 04a9de584..3f647b12b 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -154,7 +154,7 @@ fn bracket_call(p: &mut Parser) -> ExprCall { let mut outer = vec![]; let mut inner = p.span(|p| bracket_subheader(p)); - while p.eat_if(Token::Chain) { + while p.eat_if(Token::Pipe) { outer.push(inner); inner = p.span(|p| bracket_subheader(p)); } @@ -186,28 +186,17 @@ fn bracket_subheader(p: &mut Parser) -> ExprCall { p.skip_white(); let name = p.span(|p| ident(p)).transpose().unwrap_or_else(|| { + let what = "function name"; if p.eof() { - p.diag_expected_at("function name", start); + p.diag_expected_at(what, start); } else { - p.diag_expected("function name"); + p.diag_expected(what); } Ident(String::new()).span_with(start) }); p.skip_white(); - let args = if p.eat_if(Token::Colon) { - p.skip_white(); - p.span(|p| dict_contents(p).0) - } else { - // Ignore the rest if there's no colon. - p.span(|p| { - if !p.eof() { - p.diag_expected_at("colon", p.pos()); - } - p.eat_while(|_| true); - LitDict::new() - }) - }; + let args = p.span(|p| dict_contents(p).0); p.end_group(); ExprCall { name, args } @@ -285,8 +274,8 @@ fn dict_entry(p: &mut Parser) -> Option { p.skip_white(); match p.peek() { // Key-value pair. - Some(Token::Equals) => { - p.eat_assert(Token::Equals); + Some(Token::Colon) => { + p.eat_assert(Token::Colon); p.skip_white(); if let Some(expr) = expr(p) { Some(LitDictEntry { @@ -463,7 +452,7 @@ fn content(p: &mut Parser) -> SynTree { tree } -/// Parse a parenthesized expression: `(a + b)`, `(1, key="value"). +/// Parse a parenthesized expression: `(a + b)`, `(1, name: "value"). fn parenthesized(p: &mut Parser) -> Expr { p.start_group(Group::Paren); let (dict, coercible) = dict_contents(p); diff --git a/src/parse/parser.rs b/src/parse/parser.rs index a8e5883a3..d23aec3f9 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -40,24 +40,24 @@ impl<'s> Parser<'s> { /// Eat the next token and add a diagnostic that it is not the expected /// `thing`. - pub fn diag_expected(&mut self, thing: &str) { + pub fn diag_expected(&mut self, what: &str) { let before = self.pos(); if let Some(found) = self.eat() { let after = self.pos(); self.diag(error!( before .. after, "expected {}, found {}", - thing, + what, found.name(), )); } else { - self.diag_expected_at(thing, self.pos()); + self.diag_expected_at(what, self.pos()); } } /// Add a diagnostic that the `thing` was expected at the given position. - pub fn diag_expected_at(&mut self, thing: &str, pos: Pos) { - self.diag(error!(pos, "expected {}", thing)); + pub fn diag_expected_at(&mut self, what: &str, pos: Pos) { + self.diag(error!(pos, "expected {}", what)); } /// Eat the next token and add a diagnostic that it is unexpected. @@ -220,7 +220,7 @@ impl<'s> Parser<'s> { Token::RightParen => Group::Paren, Token::RightBracket => Group::Bracket, Token::RightBrace => Group::Brace, - Token::Chain => Group::Subheader, + Token::Pipe => Group::Subheader, _ => return Some(token), }; diff --git a/src/parse/tests.rs b/src/parse/tests.rs index 1b6df74b3..95d049282 100644 --- a/src/parse/tests.rs +++ b/src/parse/tests.rs @@ -164,7 +164,7 @@ macro_rules! test { // Test expressions. macro_rules! v { ($src:expr => $($tts:tt)*) => { - t!(concat!("[val: ", $src, "]") => F!("val"; $($tts)*)); + t!(concat!("[val ", $src, "]") => F!("val"; $($tts)*)); } } @@ -233,7 +233,7 @@ fn test_parse_groups() { e!("[)" => s(1, 2, "expected function name, found closing paren"), s(2, 2, "expected closing bracket")); - e!("[v:{]}" => s(4, 4, "expected closing brace"), + e!("[v {]}" => s(4, 4, "expected closing brace"), s(5, 6, "unexpected closing brace")); } @@ -250,9 +250,9 @@ fn test_parse_simple_nodes() { t!("\n\n\nhello" => P, T("hello")); t!(r"a\ b" => T("a"), L, S, T("b")); - e!("\\u{d421c809}" => s(0, 12, "invalid unicode escape sequence")); - e!("\\u{abc" => s(6, 6, "expected closing brace")); - t!("💜\n\n 🌍" => T("💜"), P, T("🌍")); + e!("\\u{d421c809}" => s(0, 12, "invalid unicode escape sequence")); + e!("\\u{abc" => s(6, 6, "expected closing brace")); + t!("💜\n\n 🌍" => T("💜"), P, T("🌍")); ts!("hi" => s(0, 2, T("hi"))); ts!("*Hi*" => s(0, 1, B), s(1, 3, T("Hi")), s(3, 4, B)); @@ -296,10 +296,10 @@ fn test_parse_comments() { e!("🌎\n*/n" => s(5, 7, "unexpected end of block comment")); // In header. - t!("[val:/*12pt*/]" => F!("val")); - t!("[val \n /* \n */:]" => F!("val")); - e!("[val \n /* \n */:]" => ); - e!("[val : 12, /* \n */ 14]" => ); + t!("[val /*12pt*/]" => F!("val")); + t!("[val \n /* \n */]" => F!("val")); + e!("[val \n /* \n */]" => ); + e!("[val 12, /* \n */ 14]" => ); } #[test] @@ -357,40 +357,23 @@ fn test_parse_function_names() { #[test] fn test_parse_chaining() { // Things the parser has to make sense of - t!("[hi: (5.0, 2.1 >> you]" => F!("hi"; Dict![Float(5.0), Float(2.1)], Tree![F!("you")])); - t!("[box >> pad: 1pt][Hi]" => F!("box"; Tree![ + t!("[hi (5.0, 2.1 | you]" => F!("hi"; Dict![Float(5.0), Float(2.1)], Tree![F!("you")])); + t!("[box | pad: 1pt][Hi]" => F!("box"; Tree![ F!("pad"; Length(1.0, Pt), Tree!(T("Hi"))) ])); - t!("[bold: 400, >> emph >> sub: 1cm]" => F!("bold"; Int(400), Tree![ + t!("[bold 400, | emph | sub: 1cm]" => F!("bold"; Int(400), Tree![ F!("emph"; Tree!(F!("sub"; Length(1.0, Cm)))) ])); // Errors for unclosed / empty predecessor groups - e!("[hi: (5.0, 2.1 >> you]" => s(15, 15, "expected closing paren")); - e!("[>> abc]" => s(1, 1, "expected function name")); - e!("[box >>][Hi]" => s(7, 7, "expected function name")); -} - -#[test] -fn test_parse_colon_starting_func_args() { - // Just colon without args. - e!("[val:]" => ); - - // Wrong token. - t!("[val=]" => F!("val")); - e!("[val=]" => s(4, 4, "expected colon")); - e!("[val/🌎:$]" => s(4, 4, "expected colon")); - - // String in invalid header without colon still parsed as string - // _Note_: No "expected quote" error because not even the string was - // expected. - e!("[val/\"]" => s(4, 4, "expected colon"), - s(7, 7, "expected closing bracket")); + e!("[hi (5.0, 2.1 | you]" => s(14, 14, "expected closing paren")); + e!("[| abc]" => s(1, 1, "expected function name")); + e!("[box |][Hi]" => s(6, 6, "expected function name")); } #[test] fn test_parse_function_bodies() { - t!("[val: 1][*Hi*]" => F!("val"; Int(1), Tree![B, T("Hi"), B])); + t!("[val 1][*Hi*]" => F!("val"; Int(1), Tree![B, T("Hi"), B])); e!(" [val][ */]" => s(8, 10, "unexpected end of block comment")); // Raw in body. @@ -431,24 +414,24 @@ fn test_parse_values() { // Content. v!("{_hi_}" => Tree![E, T("hi"), E]); - e!("[val: {_hi_}]" => ); + e!("[val {_hi_}]" => ); v!("[hi]" => Tree![F!("hi")]); - e!("[val: [hi]]" => ); + e!("[val [hi]]" => ); // Healed colors. v!("#12345" => Color(RgbaColor::new(0, 0, 0, 0xff))); - e!("[val: #12345]" => s(6, 12, "invalid color")); - e!("[val: #a5]" => s(6, 9, "invalid color")); - e!("[val: #14b2ah]" => s(6, 13, "invalid color")); - e!("[val: #f075ff011]" => s(6, 16, "invalid color")); + e!("[val #12345]" => s(5, 11, "invalid color")); + e!("[val #a5]" => s(5, 8, "invalid color")); + e!("[val #14b2ah]" => s(5, 12, "invalid color")); + e!("[val #f075ff011]" => s(5, 15, "invalid color")); // Unclosed string. v!("\"hello" => Str("hello]")); - e!("[val: \"hello]" => s(13, 13, "expected quote"), - s(13, 13, "expected closing bracket")); + e!("[val \"hello]" => s(12, 12, "expected quote"), + s(12, 12, "expected closing bracket")); // Spanned. - ts!("[val: 1.4]" => s(0, 10, F!(s(1, 4, "val"), 6 .. 9; s(6, 9, Float(1.4))))); + ts!("[val 1.4]" => s(0, 9, F!(s(1, 4, "val"), 5 .. 8; s(5, 8, Float(1.4))))); } #[test] @@ -485,24 +468,24 @@ fn test_parse_expressions() { v!("3/4*5" => Binary(Mul, Binary(Div, Int(3), Int(4)), Int(5))); // Spanned. - ts!("[val: 1 + 3]" => s(0, 12, F!( - s(1, 4, "val"), 6 .. 11; s(6, 11, Binary( - s(8, 9, Add), - s(6, 7, Int(1)), - s(10, 11, Int(3)) + ts!("[val 1 + 3]" => s(0, 11, F!( + s(1, 4, "val"), 5 .. 10; s(5, 10, Binary( + s(7, 8, Add), + s(5, 6, Int(1)), + s(9, 10, Int(3)) )) ))); // Span of parenthesized expression contains parens. - ts!("[val: (1)]" => s(0, 10, F!(s(1, 4, "val"), 6 .. 9; s(6, 9, Int(1))))); + ts!("[val (1)]" => s(0, 9, F!(s(1, 4, "val"), 5 .. 8; s(5, 8, Int(1))))); // Invalid expressions. - v!("4pt--" => Length(4.0, Pt)); - e!("[val: 4pt--]" => s(10, 11, "missing factor"), - s(6, 10, "missing right summand")); + v!("4pt--" => Length(4.0, Pt)); + e!("[val 4pt--]" => s(9, 10, "missing factor"), + s(5, 9, "missing right summand")); - v!("3mm+4pt*" => Binary(Add, Length(3.0, Mm), Length(4.0, Pt))); - e!("[val: 3mm+4pt*]" => s(10, 14, "missing right factor")); + v!("3mm+4pt*" => Binary(Add, Length(3.0, Mm), Length(4.0, Pt))); + e!("[val 3mm+4pt*]" => s(9, 13, "missing right factor")); } #[test] @@ -511,25 +494,25 @@ fn test_parse_dicts() { v!("()" => Dict![]); v!("(false)" => Bool(false)); v!("(true,)" => Dict![Bool(true)]); - v!("(key=val)" => Dict!["key" => Id("val")]); + v!("(key: val)" => Dict!["key" => Id("val")]); v!("(1, 2)" => Dict![Int(1), Int(2)]); - v!("(1, key=\"value\")" => Dict![Int(1), "key" => Str("value")]); + v!("(1, key: \"value\")" => Dict![Int(1), "key" => Str("value")]); // Decorations. - d!("[val: key=hi]" => s(6, 9, DictKey)); - d!("[val: (key=hi)]" => s(7, 10, DictKey)); - d!("[val: f(key=hi)]" => s(8, 11, DictKey)); + d!("[val key: hi]" => s(5, 8, DictKey)); + d!("[val (key: hi)]" => s(6, 9, DictKey)); + d!("[val f(key: hi)]" => s(7, 10, DictKey)); - // Spanned with spacing around keyword arguments. - ts!("[val: \n hi \n = /* //\n */ \"s\n\"]" => s(0, 30, F!( + // Spanned with spacing around named arguments. + ts!("[val \n hi \n : /* //\n */ \"s\n\"]" => s(0, 30, F!( s(1, 4, "val"), 8 .. 29; s(8, 10, "hi") => s(25, 29, Str("s\n")) ))); - e!("[val: \n hi \n = /* //\n */ \"s\n\"]" => ); + e!("[val \n hi \n : /* //\n */ \"s\n\"]" => ); } #[test] -fn test_parse_dicts_compute_func_calls() { +fn test_parse_dicts_paren_func_calls() { v!("empty()" => Call!("empty")); v!("add ( 1 , 2 )" => Call!("add"; Int(1), Int(2))); v!("items(\"fire\", #f93a6d)" => Call!("items"; @@ -537,25 +520,25 @@ fn test_parse_dicts_compute_func_calls() { )); // More complex. - v!("css(1pt, rgb(90, 102, 254), \"solid\")" => Call!( + v!(r#"css(1pt, color: rgb(90, 102, 254), stroke: "solid")"# => Call!( "css"; Length(1.0, Pt), - Call!("rgb"; Int(90), Int(102), Int(254)), - Str("solid"), + "color" => Call!("rgb"; Int(90), Int(102), Int(254)), + "stroke" => Str("solid"), )); // Unclosed. - v!("lang(中文]" => Call!("lang"; Id("中文"))); - e!("[val: lang(中文]" => s(17, 17, "expected closing paren")); + v!("lang(中文]" => Call!("lang"; Id("中文"))); + e!("[val lang(中文]" => s(16, 16, "expected closing paren")); // Invalid name. - v!("👠(\"abc\", 13e-5)" => Dict!(Str("abc"), Float(13.0e-5))); - e!("[val: 👠(\"abc\", 13e-5)]" => s(6, 10, "invalid token")); + v!("👠(\"abc\", 13e-5)" => Dict!(Str("abc"), Float(13.0e-5))); + e!("[val 👠(\"abc\", 13e-5)]" => s(5, 9, "invalid token")); } #[test] fn test_parse_dicts_nested() { - v!("(1, ( ab=(), d = (3, 14pt) )), false" => + v!("(1, ( ab:(), d : (3, 14pt) )), false" => Dict![ Int(1), Dict!( @@ -570,28 +553,28 @@ fn test_parse_dicts_nested() { #[test] fn test_parse_dicts_errors() { // Expected value. - e!("[val: (=)]" => s(7, 8, "unexpected equals sign")); - e!("[val: (,)]" => s(7, 8, "unexpected comma")); - v!("(\x07 abc,)" => Dict![Id("abc")]); - e!("[val: (\x07 abc,)]" => s(7, 8, "invalid token")); - e!("[val: (key=,)]" => s(11, 12, "expected value, found comma")); - e!("[val: hi,)]" => s(9, 10, "unexpected closing paren")); + e!("[val (:)]" => s(6, 7, "unexpected colon")); + e!("[val (,)]" => s(6, 7, "unexpected comma")); + v!("(\x07 abc,)" => Dict![Id("abc")]); + e!("[val (\x07 abc,)]" => s(6, 7, "invalid token")); + e!("[val (key:,)]" => s(10, 11, "expected value, found comma")); + e!("[val hi,)]" => s(8, 9, "unexpected closing paren")); // Expected comma. - v!("(true false)" => Dict![Bool(true), Bool(false)]); - e!("[val: (true false)]" => s(11, 11, "expected comma")); + v!("(true false)" => Dict![Bool(true), Bool(false)]); + e!("[val (true false)]" => s(10, 10, "expected comma")); // Expected closing paren. - e!("[val: (#000]" => s(11, 11, "expected closing paren")); - e!("[val: (key]" => s(10, 10, "expected closing paren")); - e!("[val: (key=]" => s(11, 11, "expected value"), - s(11, 11, "expected closing paren")); + e!("[val (#000]" => s(10, 10, "expected closing paren")); + e!("[val (key]" => s(9, 9, "expected closing paren")); + e!("[val (key:]" => s(10, 10, "expected value"), + s(10, 10, "expected closing paren")); // Bad key. - v!("true=you" => Bool(true), Id("you")); - e!("[val: true=you]" => s(10, 11, "unexpected equals sign")); + v!("true:you" => Bool(true), Id("you")); + e!("[val true:you]" => s(9, 10, "unexpected colon")); - // Unexpected equals sign. - v!("z=y=4" => "z" => Id("y"), Int(4)); - e!("[val: z=y=4]" => s(9, 10, "unexpected equals sign")); + // Unexpected colon. + v!("z:y:4" => "z" => Id("y"), Int(4)); + e!("[val z:y:4]" => s(8, 9, "unexpected colon")); } diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index 3dcc64604..c9e159f18 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -109,8 +109,7 @@ impl<'s> Iterator for Tokens<'s> { ')' => Token::RightParen, ':' => Token::Colon, ',' => Token::Comma, - '=' => Token::Equals, - '>' if self.s.eat_if('>') => Token::Chain, + '|' => Token::Pipe, '+' => Token::Plus, '-' => Token::Hyphen, '*' => Token::Star, @@ -567,7 +566,7 @@ mod tests { t!(Body[" "]: r"\" => Backslash); // Test header symbols. - t!(Body[" /"]: ":,=>>/+-" => T(":,=>>/+-")); + t!(Body[" /"]: ":,=|/+-" => T(":,=|/+-")); } #[test] @@ -652,8 +651,7 @@ mod tests { // Test structural tokens. t!(Header: ":" => Colon); t!(Header: "," => Comma); - t!(Header: "=" => Equals); - t!(Header: ">>" => Chain); + t!(Header: "|" => Pipe); t!(Header: "+" => Plus); t!(Header: "-" => Hyphen); t!(Header[" a1"]: "*" => Star); diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index 09729f522..91f4053c7 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -7,7 +7,7 @@ use super::*; pub enum Expr { /// A literal: `true`, `1cm`, `"hi"`, `{_Hey!_}`. Lit(Lit), - /// An invocation of a function: `[foo: ...]`, `foo(...)`. + /// An invocation of a function: `[foo ...]`, `foo(...)`. Call(ExprCall), /// A unary operation: `-x`. Unary(ExprUnary), @@ -15,7 +15,7 @@ pub enum Expr { Binary(ExprBinary), } -/// An invocation of a function: `[foo: ...]`, `foo(...)`. +/// An invocation of a function: `[foo ...]`, `foo(...)`. #[derive(Debug, Clone, PartialEq)] pub struct ExprCall { /// The name of the function. diff --git a/src/syntax/lit.rs b/src/syntax/lit.rs index e86479650..84d5c6f4d 100644 --- a/src/syntax/lit.rs +++ b/src/syntax/lit.rs @@ -27,17 +27,17 @@ pub enum Lit { Color(RgbaColor), /// A string literal: `"hello!"`. Str(String), - /// A dictionary literal: `(false, 12cm, greeting = "hi")`. + /// A dictionary literal: `(false, 12cm, greeting: "hi")`. Dict(LitDict), /// A content literal: `{*Hello* there!}`. Content(SynTree), } -/// A dictionary literal: `(false, 12cm, greeting = "hi")`. +/// A dictionary literal: `(false, 12cm, greeting: "hi")`. #[derive(Debug, Default, Clone, PartialEq)] pub struct LitDict(pub Vec); -/// An entry in a dictionary literal: `false` or `greeting = "hi"`. +/// An entry in a dictionary literal: `false` or `greeting: "hi"`. #[derive(Debug, Clone, PartialEq)] pub struct LitDictEntry { /// The key of the entry if there was one: `greeting`. diff --git a/src/syntax/token.rs b/src/syntax/token.rs index e105ad2fb..12f4d10d0 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -54,10 +54,8 @@ pub enum Token<'s> { Colon, /// A comma: `,`. Comma, - /// An equals sign: `=`. - Equals, - /// A double forward chevron: `>>`. - Chain, + /// A pipe: `|`. + Pipe, /// A plus: `+`. Plus, /// A hyphen: `-`. @@ -150,8 +148,7 @@ impl<'s> Token<'s> { Self::Colon => "colon", Self::Comma => "comma", - Self::Equals => "equals sign", - Self::Chain => "function chaining operator", + Self::Pipe => "pipe", Self::Plus => "plus sign", Self::Hyphen => "minus sign", Self::Slash => "slash", diff --git a/tests/typ/example-coma.typ b/tests/typ/example-coma.typ index d41032c1f..d559a6fbc 100644 --- a/tests/typ/example-coma.typ +++ b/tests/typ/example-coma.typ @@ -1,6 +1,6 @@ // Test integration of syntax, page setup, box layout and alignment. -[page: width=450pt, height=300pt, margins=1cm] +[page width: 450pt, height: 300pt, margins: 1cm] [box][ *Technische Universität Berlin* \ @@ -9,17 +9,17 @@ Dr. Max Mustermann \ Ola Nordmann, John Doe ] -[align: right >> box][*WiSe 2019/2020* \ Woche 3] +[align right | box][*WiSe 2019/2020* \ Woche 3] -[v: 6mm] +[v 6mm] -[align: center][ - #### 3. Übungsblatt Computerorientierte Mathematik II [v: 2mm] - *Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) [v: 2mm] +[align center][ + #### 3. Übungsblatt Computerorientierte Mathematik II [v 2mm] + *Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) [v 2mm] *Alle Antworten sind zu beweisen.* ] -*1. Aufgabe* [align: right][(1 + 1 + 2 Punkte)] +*1. Aufgabe* [align right][(1 + 1 + 2 Punkte)] Ein _Binärbaum_ ist ein Wurzelbaum, in dem jeder Knoten ≤ 2 Kinder hat. Die Tiefe eines Knotens _v_ ist die Länge des eindeutigen Weges von der Wurzel diff --git a/tests/typ/func-font-error.typ b/tests/typ/func-font-error.typ index 8de754ae5..492ef9df1 100644 --- a/tests/typ/func-font-error.typ +++ b/tests/typ/func-font-error.typ @@ -1,17 +1,17 @@ // Test error cases of the `font` function. // Not one of the valid things for positional arguments. -[font: false] +[font false] // Wrong types. -[font: style=bold, weight="thin", emoji=0] +[font style: bold, weight: "thin", serif: 0] // Non-existing argument. -[font: something="invalid"] +[font something: "invalid"] // compare-ref: false -// error: 4:8-4:13 unexpected argument +// error: 4:7-4:12 unexpected argument // error: 7:14-7:18 invalid font style -// error: 7:27-7:33 expected font weight, found string -// error: 7:41-7:42 expected family or list of families, found integer -// error: 10:8-10:27 unexpected argument +// error: 7:28-7:34 expected font weight, found string +// error: 7:43-7:44 expected family or list of families, found integer +// error: 10:7-10:27 unexpected argument diff --git a/tests/typ/func-font-fallback.typ b/tests/typ/func-font-fallback.typ index b6509e624..9b60d46c0 100644 --- a/tests/typ/func-font-fallback.typ +++ b/tests/typ/func-font-fallback.typ @@ -4,15 +4,15 @@ Emoji: 🏀 // CMU Serif + Noto Emoji. -[font: "CMU Serif", "Noto Emoji"][Emoji: 🏀] +[font "CMU Serif", "Noto Emoji"][Emoji: 🏀] // Class definitions. -[font: math=("CMU Serif", "Latin Modern Math", "Noto Emoji")] -[font: math][Math: ∫ α + β ➗ 3] +[font math: ("CMU Serif", "Latin Modern Math", "Noto Emoji")] +[font math][Math: ∫ α + β ➗ 3] // Class redefinition. -[font: sans-serif="Noto Emoji"] -[font: sans-serif=("Archivo", sans-serif)] +[font sans-serif: "Noto Emoji"] +[font sans-serif: ("Archivo", sans-serif)] New sans-serif. 🚀 // TODO: Add tests for other scripts. diff --git a/tests/typ/func-font-properties.typ b/tests/typ/func-font-properties.typ index 78093e989..af8b88914 100644 --- a/tests/typ/func-font-properties.typ +++ b/tests/typ/func-font-properties.typ @@ -1,20 +1,20 @@ // Test configuring font properties. -[font: "PT Sans", 10pt] +[font "PT Sans", 10pt] // Set same font size in three different ways. -[font: 20pt][A] -[font: 200%][A] -[font: 15pt + 50%][A] +[font 20pt][A] +[font 200%][A] +[font 15pt + 50%][A] // Do nothing. [font][Normal] // Set style (is available). -[font: style=italic][Italic] +[font style: italic][Italic] // Set weight (is available). -[font: weight=bold][Bold] +[font weight: bold][Bold] // Set stretch (not available, matching closest). -[font: stretch=ultra-condensed][Condensed] +[font stretch: ultra-condensed][Condensed] diff --git a/tests/typ/func-h-and-v.typ b/tests/typ/func-h-and-v.typ index 9c6d57306..0587b3eda 100644 --- a/tests/typ/func-h-and-v.typ +++ b/tests/typ/func-h-and-v.typ @@ -1,25 +1,25 @@ // Test the `h` and `v` functions. // Ends paragraphs. -Tightly [v: -5pt] packed +Tightly [v -5pt] packed // Eating up soft spacing. -Inv [h: 0pt] isible +Inv [h 0pt] isible // Multiple spacings in a row. -Add [h: 10pt] [h: 10pt] up +Add [h 10pt] [h 10pt] up // Relative to font size. -Relative [h: 100%] spacing +Relative [h 100%] spacing // Missing spacing. Totally [h] ignored // Swapped axes. -[page: main-dir=rtl, cross-dir=ttb][ - 1 [h: 1cm] 2 +[page main-dir: rtl, cross-dir: ttb][ + 1 [h 1cm] 2 - 3 [v: 1cm] 4 [v: -1cm] 5 + 3 [v 1cm] 4 [v -1cm] 5 ] // error: 16:11-16:11 missing argument: spacing diff --git a/tests/typ/func-image-error.typ b/tests/typ/func-image-error.typ index e6a989cac..155534200 100644 --- a/tests/typ/func-image-error.typ +++ b/tests/typ/func-image-error.typ @@ -1,11 +1,11 @@ // Test error cases of the `image` function. // File does not exist. -[image: "path/does/not/exist"] +[image "path/does/not/exist"] // File exists, but is no image. -[image: "typ/image-error.typ"] +[image "typ/image-error.typ"] // compare-ref: false -// error: 4:9-4:30 failed to load image -// error: 7:9-7:30 failed to load image +// error: 4:8-4:29 failed to load image +// error: 7:8-7:29 failed to load image diff --git a/tests/typ/func-image-fit.typ b/tests/typ/func-image-fit.typ index eca7c1e45..a9855aa4f 100644 --- a/tests/typ/func-image-fit.typ +++ b/tests/typ/func-image-fit.typ @@ -1,23 +1,23 @@ // Test configuring the size and fitting behaviour of images. // Fit to width of page. -[image: "res/rhino.png"] +[image "res/rhino.png"] // Fit to height of page. -[page: width=270pt][ - [image: "res/rhino.png"] +[page width: 270pt][ + [image "res/rhino.png"] ] // Set width explicitly. -[image: "res/rhino.png", width=50pt] +[image "res/rhino.png", width: 50pt] // Set height explicitly. -[image: "res/rhino.png", height=50pt] +[image "res/rhino.png", height: 50pt] // Set width and height explicitly and force stretching. -[image: "res/rhino.png", width=25pt, height=50pt] +[image "res/rhino.png", width: 25pt, height: 50pt] // Make sure the bounding-box of the image is correct. -[align: bottom, right][ - [image: "res/tiger.jpg"] +[align bottom, right][ + [image "res/tiger.jpg"] ] diff --git a/tests/typ/func-image-formats.typ b/tests/typ/func-image-formats.typ index 36b991d01..c12e36398 100644 --- a/tests/typ/func-image-formats.typ +++ b/tests/typ/func-image-formats.typ @@ -1,8 +1,8 @@ // Test loading different image formats. // Load an RGBA PNG image. -[image: "res/rhino.png"] +[image "res/rhino.png"] [pagebreak] // Load an RGB JPEG image. -[image: "res/tiger.jpg"] +[image "res/tiger.jpg"] diff --git a/tests/typ/func-page-body.typ b/tests/typ/func-page-body.typ index 78e72d12b..bfa9775d2 100644 --- a/tests/typ/func-page-body.typ +++ b/tests/typ/func-page-body.typ @@ -1,6 +1,6 @@ // Test a combination of pages with bodies and normal content. -[page: height=50pt] +[page height: 50pt] [page][First] [page][Second] diff --git a/tests/typ/func-page-dirs.typ b/tests/typ/func-page-dirs.typ index 09ba4e9e8..47e8ae157 100644 --- a/tests/typ/func-page-dirs.typ +++ b/tests/typ/func-page-dirs.typ @@ -1,5 +1,5 @@ // Test changing the layouting directions of pages. -[page: main-dir=btt, cross-dir=rtl] +[page main-dir: btt, cross-dir: rtl] Right to left! diff --git a/tests/typ/func-page-error.typ b/tests/typ/func-page-error.typ index e259a04e4..1b2db60df 100644 --- a/tests/typ/func-page-error.typ +++ b/tests/typ/func-page-error.typ @@ -1,11 +1,11 @@ // Test error cases of the `page` function. // Invalid paper. -[page: nonexistant] +[page nonexistant] // Aligned axes. -[page: main-dir=ltr] +[page main-dir: ltr] // compare-ref: false -// error: 4:8-4:19 invalid paper +// error: 4:7-4:18 invalid paper // error: 7:17-7:20 aligned axis diff --git a/tests/typ/func-page-metrics.typ b/tests/typ/func-page-metrics.typ index 6c7bd4611..7e0bc2f84 100644 --- a/tests/typ/func-page-metrics.typ +++ b/tests/typ/func-page-metrics.typ @@ -1,25 +1,25 @@ // Test configuring page sizes and margins. // Set width. -[page: width=50pt][High] +[page width: 50pt][High] // Set height. -[page: height=50pt][Wide] +[page height: 50pt][Wide] // Set all margins at once. -[page: margins=40pt][ - [align: top, left][TL] - [align: bottom, right][BR] +[page margins: 40pt][ + [align top, left][TL] + [align bottom, right][BR] ] // Set individual margins. -[page: left=0pt >> align: left][Left] -[page: right=0pt >> align: right][Right] -[page: top=0pt >> align: top][Top] -[page: bottom=0pt >> align: bottom][Bottom] +[page left: 0pt | align left][Left] +[page right: 0pt | align right][Right] +[page top: 0pt | align top][Top] +[page bottom: 0pt | align bottom][Bottom] // Ensure that specific margins override general margins. -[page: margins=0pt, left=40pt][Overriden] +[page margins: 0pt, left: 40pt][Overriden] // Flip the page. -[page: a10, flip=true][Flipped] +[page a10, flip: true][Flipped] diff --git a/tests/typ/func-pagebreak.typ b/tests/typ/func-pagebreak.typ index 7fd9aae2c..603e11d41 100644 --- a/tests/typ/func-pagebreak.typ +++ b/tests/typ/func-pagebreak.typ @@ -2,4 +2,4 @@ First of two [pagebreak] -[page: height=40pt] +[page height: 40pt] diff --git a/tests/typ/func-rgb.typ b/tests/typ/func-rgb.typ index 44d878192..b47039a28 100644 --- a/tests/typ/func-rgb.typ +++ b/tests/typ/func-rgb.typ @@ -1,24 +1,24 @@ // Test the `rgb` function. // Check the output. -[rgb: 0.0, 0.3, 0.7] [val: #004db3] +[rgb 0.0, 0.3, 0.7] [val #004db3] // Alpha channel. -[rgb: 1.0, 0.0, 0.0, 0.5] +[rgb 1.0, 0.0, 0.0, 0.5] // Value smaller than 0.0 and larger than 1.0 -[rgb: -30, 15.5, 0.5] +[rgb -30, 15.5, 0.5] // Missing blue component. -[rgb: 0, 1] +[rgb 0, 1] // Missing all components. [rgb] -// error: 4:23-4:26 unknown function -// error: 10:7-10:10 should be between 0.0 and 1.0 -// error: 10:12-10:16 should be between 0.0 and 1.0 -// error: 13:7-13:11 missing argument: blue component +// error: 4:22-4:25 unknown function +// error: 10:6-10:9 should be between 0.0 and 1.0 +// error: 10:11-10:15 should be between 0.0 and 1.0 +// error: 13:6-13:10 missing argument: blue component // error: 16:5-16:5 missing argument: red component // error: 16:5-16:5 missing argument: green component // error: 16:5-16:5 missing argument: blue component