From 89eb8bae49edb71d9a9279a2210bb1ccaf4dd707 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Sat, 30 Jan 2021 12:09:26 +0100 Subject: [PATCH] =?UTF-8?q?New=20syntax=20=F0=9F=92=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Everything everywhere! - Blocks with curly braces: {} - Templates with brackets: [] - Function templates with hashtag: `#[f]` - Headings with equals sign: `= Introduction` --- src/eval/value.rs | 12 ++-- src/parse/mod.rs | 116 +++++++++++++++++++------------- src/parse/parser.rs | 12 ++-- src/parse/tokens.rs | 89 ++++++++++++------------ src/syntax/expr.rs | 33 +++++---- src/syntax/mod.rs | 25 +++---- src/syntax/node.rs | 6 +- src/syntax/token.rs | 10 +-- tests/full/typ/coma.typ | 16 ++--- tests/lang/ref/bracket-call.png | Bin 22101 -> 22558 bytes tests/lang/ref/headings.png | Bin 7985 -> 7415 bytes tests/lang/typ/bracket-call.typ | 94 +++++++++++++------------- tests/lang/typ/comments.typ | 2 +- tests/lang/typ/emph-strong.typ | 2 +- tests/lang/typ/expressions.typ | 110 +++++++++++++++--------------- tests/lang/typ/headings.typ | 31 ++++----- tests/lang/typ/if.typ | 3 +- tests/lang/typ/let.typ | 20 +++--- tests/lang/typ/raw.typ | 2 +- tests/lang/typ/values.typ | 2 +- tests/library/typ/font.typ | 46 ++++++------- tests/library/typ/hv.typ | 18 ++--- tests/library/typ/image.typ | 30 ++++----- tests/library/typ/page.typ | 53 +++++++-------- tests/library/typ/pagebreak.typ | 4 +- tests/library/typ/rgb.typ | 22 +++--- 26 files changed, 384 insertions(+), 374 deletions(-) diff --git a/src/eval/value.rs b/src/eval/value.rs index 6e838f6ca..860c06348 100644 --- a/src/eval/value.rs +++ b/src/eval/value.rs @@ -8,7 +8,7 @@ use super::{Args, Eval, EvalContext}; use crate::color::Color; use crate::geom::{Angle, Length, Linear, Relative}; use crate::pretty::{pretty, Pretty, Printer}; -use crate::syntax::{Spanned, Tree, WithSpan}; +use crate::syntax::{pretty_template, Spanned, Tree, WithSpan}; /// A computational value. #[derive(Debug, Clone, PartialEq)] @@ -121,11 +121,7 @@ impl Pretty for Value { Value::Str(v) => write!(p, "{:?}", v).unwrap(), Value::Array(v) => v.pretty(p), Value::Dict(v) => v.pretty(p), - Value::Template(v) => { - p.push_str("["); - v.pretty(p); - p.push_str("]"); - } + Value::Template(v) => pretty_template(v, p), Value::Func(v) => v.pretty(p), Value::Any(v) => v.pretty(p), Value::Error => p.push_str("(error)"), @@ -537,8 +533,8 @@ mod tests { // Dictionary. let mut dict = BTreeMap::new(); dict.insert("one".into(), Value::Int(1)); - dict.insert("two".into(), Value::Template(parse("[f]").output)); + dict.insert("two".into(), Value::Template(parse("#[f]").output)); test_pretty(BTreeMap::new(), "(:)"); - test_pretty(dict, "(one: 1, two: [[f]])"); + test_pretty(dict, "(one: 1, two: #[f])"); } } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index ff75a563d..3fc7d483a 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -45,38 +45,33 @@ fn tree(p: &mut Parser) -> Tree { fn node(p: &mut Parser, at_start: &mut bool) -> Option { let token = p.peek()?; let node = match token { - // Bracket call. - Token::LeftBracket => { - return Some(Node::Expr(bracket_call(p)?)); + // Whitespace. + Token::Space(newlines) => { + *at_start |= newlines > 0; + if newlines < 2 { Node::Space } else { Node::Parbreak } } - // Code block. - Token::LeftBrace => { - return Some(Node::Expr(block(p, false)?)); - } + // Text. + Token::Text(text) => Node::Text(text.into()), // Markup. Token::Star => Node::Strong, Token::Underscore => Node::Emph, - Token::Tilde => Node::Text("\u{00A0}".into()), - Token::Hash => { + Token::Eq => { if *at_start { return Some(Node::Heading(heading(p))); } else { Node::Text(p.get(p.peek_span()).into()) } } + Token::Tilde => Node::Text("\u{00A0}".into()), Token::Backslash => Node::Linebreak, - Token::Space(newlines) => { - *at_start |= newlines > 0; - if newlines < 2 { Node::Space } else { Node::Parbreak } - } - Token::Text(text) => Node::Text(text.into()), Token::Raw(t) => Node::Raw(raw(p, t)), Token::UnicodeEscape(t) => Node::Text(unicode_escape(p, t)), // Keywords. Token::Let | Token::If | Token::For => { + *at_start = false; let stmt = token == Token::Let; let group = if stmt { Group::Stmt } else { Group::Expr }; @@ -92,6 +87,24 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option { return expr.map(Node::Expr); } + // Block. + Token::LeftBrace => { + *at_start = false; + return Some(Node::Expr(block(p, false)?)); + } + + // Template. + Token::LeftBracket => { + *at_start = false; + return Some(Node::Expr(template(p))); + } + + // Function template. + Token::HashBracket => { + *at_start = false; + return Some(Node::Expr(bracket_call(p)?)); + } + // Comments. Token::LineComment(_) | Token::BlockComment(_) => { p.eat(); @@ -99,6 +112,7 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option { } _ => { + *at_start = false; p.unexpected(); return None; } @@ -109,12 +123,12 @@ fn node(p: &mut Parser, at_start: &mut bool) -> Option { /// Parse a heading. fn heading(p: &mut Parser) -> NodeHeading { - // Count hashtags. + // Count depth. let mut level = p.span(|p| { - p.assert(Token::Hash); + p.assert(&[Token::Eq]); let mut level = 0u8; - while p.eat_if(Token::Hash) { + while p.eat_if(Token::Eq) { level = level.saturating_add(1); } level @@ -278,33 +292,6 @@ fn expr_with(p: &mut Parser, min_prec: usize) -> Option { /// Parse a primary expression. fn primary(p: &mut Parser) -> Option { let expr = match p.peek() { - // Template. - Some(Token::LeftBracket) => { - return Some(template(p)); - } - - // Nested block. - Some(Token::LeftBrace) => { - return block(p, true); - } - - // Dictionary or just a parenthesized expression. - Some(Token::LeftParen) => { - return Some(parenthesized(p)); - } - - // Function or just ident. - Some(Token::Ident(id)) => { - p.eat(); - let ident = Ident(id.into()); - if p.peek() == Some(Token::LeftParen) { - let name = ident.with_span(p.peek_span()); - return Some(paren_call(p, name)); - } else { - return Some(Expr::Ident(ident)); - } - } - // Basic values. Some(Token::None) => Expr::None, Some(Token::Bool(b)) => Expr::Bool(b), @@ -316,12 +303,45 @@ fn primary(p: &mut Parser) -> Option { Some(Token::Color(color)) => Expr::Color(color), Some(Token::Str(token)) => Expr::Str(string(p, token)), + // Function or identifier. + Some(Token::Ident(id)) => { + p.eat(); + let ident = Ident(id.into()); + if p.peek() == Some(Token::LeftParen) { + let name = ident.with_span(p.peek_span()); + return Some(paren_call(p, name)); + } else { + return Some(Expr::Ident(ident)); + } + } + // Keywords. Some(Token::Let) => return expr_let(p), Some(Token::If) => return expr_if(p), Some(Token::For) => return expr_for(p), - // No value. + // Block. + Some(Token::LeftBrace) => { + return block(p, true); + } + + // Template. + Some(Token::LeftBracket) => { + return Some(template(p)); + } + + // Function template. + Some(Token::HashBracket) => { + let call = p.span_if(bracket_call)?.map(Node::Expr); + return Some(Expr::Template(vec![call])); + } + + // Array, dictionary or parenthesized expression. + Some(Token::LeftParen) => { + return Some(parenthesized(p)); + } + + // Nothing. _ => { p.expected("expression"); return None; @@ -380,7 +400,7 @@ fn string(p: &mut Parser, token: TokenStr) -> String { /// Parse a let expression. fn expr_let(p: &mut Parser) -> Option { - p.assert(Token::Let); + p.assert(&[Token::Let]); let mut expr_let = None; if let Some(pat) = p.span_if(ident) { @@ -397,7 +417,7 @@ fn expr_let(p: &mut Parser) -> Option { /// Parse an if expresion. fn expr_if(p: &mut Parser) -> Option { - p.assert(Token::If); + p.assert(&[Token::If]); let mut expr_if = None; if let Some(condition) = p.span_if(expr) { @@ -420,7 +440,7 @@ fn expr_if(p: &mut Parser) -> Option { /// Parse a for expression. fn expr_for(p: &mut Parser) -> Option { - p.assert(Token::For); + p.assert(&[Token::For]); let mut expr_for = None; if let Some(pat) = p.span_if(for_pattern) { diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 906d9e623..2ca8eb102 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -105,9 +105,9 @@ impl<'s> Parser<'s> { self.repeek(); match group { - Group::Paren => self.assert(Token::LeftParen), - Group::Bracket => self.assert(Token::LeftBracket), - Group::Brace => self.assert(Token::LeftBrace), + Group::Paren => self.assert(&[Token::LeftParen]), + Group::Bracket => self.assert(&[Token::HashBracket, Token::LeftBracket]), + Group::Brace => self.assert(&[Token::LeftBrace]), Group::Subheader => {} Group::Stmt => {} Group::Expr => {} @@ -210,10 +210,10 @@ impl<'s> Parser<'s> { eaten } - /// Consume the next token, debug-asserting that it is the given one. - pub fn assert(&mut self, t: Token) { + /// Consume the next token, debug-asserting that it is one of the given ones. + pub fn assert(&mut self, ts: &[Token]) { let next = self.eat(); - debug_assert_eq!(next, Some(t)); + debug_assert!(next.map_or(false, |n| ts.contains(&n))); } /// Skip whitespace and comment tokens. diff --git a/src/parse/tokens.rs b/src/parse/tokens.rs index 056bbbbb1..4f5d8ab44 100644 --- a/src/parse/tokens.rs +++ b/src/parse/tokens.rs @@ -67,12 +67,15 @@ impl<'s> Iterator for Tokens<'s> { loop { // Common elements. return Some(match c { - // Functions, blocks and terminators. + // Blocks and templates. '[' => Token::LeftBracket, ']' => Token::RightBracket, '{' => Token::LeftBrace, '}' => Token::RightBrace, + // Keywords, function templates, colors. + '#' => self.hash(start), + // Whitespace. c if c.is_whitespace() => self.whitespace(c), @@ -90,8 +93,8 @@ impl<'s> Iterator for Tokens<'s> { // Markup. '*' => Token::Star, '_' => Token::Underscore, + '=' => Token::Eq, '~' => Token::Tilde, - '#' => self.hash(start), '`' => self.raw(), '$' => self.math(), '\\' => self.backslash(), @@ -140,8 +143,7 @@ impl<'s> Iterator for Tokens<'s> { self.number(start, c) } - // Hex values and strings. - '#' => self.hex(start), + // Strings. '"' => self.string(), _ => Token::Invalid(self.s.eaten_from(start)), @@ -151,6 +153,27 @@ impl<'s> Iterator for Tokens<'s> { } impl<'s> Tokens<'s> { + fn hash(&mut self, start: usize) -> Token<'s> { + if self.s.eat_if('[') { + return Token::HashBracket; + } + + self.s.eat_while(is_id_continue); + let read = self.s.eaten_from(start); + + if let Some(keyword) = keyword(read) { + return keyword; + } + + if self.mode == TokenMode::Code { + if let Ok(color) = RgbaColor::from_str(read) { + return Token::Color(color); + } + } + + Token::Invalid(read) + } + fn whitespace(&mut self, first: char) -> Token<'s> { // Fast path for just a single space if first == ' ' && !self.s.check(|c| c.is_whitespace()) { @@ -182,10 +205,10 @@ impl<'s> Tokens<'s> { c if c.is_whitespace() => true, // Comments. '/' if self.s.check(|c| c == '/' || c == '*') => true, - // Parenthesis. - '[' | ']' | '{' | '}' => true, + // Parenthesis and hashtag. + '[' | ']' | '{' | '}' | '#' => true, // Markup. - '*' | '_' | '#' | '~' | '`' | '$' => true, + '*' | '_' | '=' | '~' | '`' | '$' => true, // Escaping. '\\' => true, _ => false, @@ -198,21 +221,6 @@ impl<'s> Tokens<'s> { Token::Text(self.s.eaten_from(start)) } - fn hash(&mut self, start: usize) -> Token<'s> { - if self.s.check(is_id_start) { - self.s.eat(); - self.s.eat_while(is_id_continue); - let read = self.s.eaten_from(start); - if let Some(keyword) = keyword(read) { - keyword - } else { - Token::Invalid(read) - } - } else { - Token::Hash - } - } - fn raw(&mut self) -> Token<'s> { let mut backticks = 1; while self.s.eat_if('`') { @@ -276,10 +284,10 @@ impl<'s> Tokens<'s> { match c { // Backslash and comments. '\\' | '/' | - // Parenthesis. - '[' | ']' | '{' | '}' | + // Parenthesis and hashtag. + '[' | ']' | '{' | '}' | '#' | // Markup. - '*' | '_' | '#' | '~' | '`' | '$' => { + '*' | '_' | '=' | '~' | '`' | '$' => { let start = self.s.index(); self.s.eat_assert(c); Token::Text(&self.s.eaten_from(start)) @@ -367,18 +375,6 @@ impl<'s> Tokens<'s> { } } - fn hex(&mut self, start: usize) -> Token<'s> { - self.s.eat_while(is_id_continue); - let read = self.s.eaten_from(start); - if let Some(keyword) = keyword(read) { - keyword - } else if let Ok(color) = RgbaColor::from_str(read) { - Token::Color(color) - } else { - Token::Invalid(read) - } - } - fn string(&mut self) -> Token<'s> { let mut escaped = false; Token::Str(TokenStr { @@ -596,8 +592,8 @@ mod tests { // Test markup tokens. t!(Markup[" a1"]: "*" => Star); t!(Markup: "_" => Underscore); - t!(Markup[""]: "###" => Hash, Hash, Hash); - t!(Markup["a1/"]: "# " => Hash, Space(0)); + t!(Markup[""]: "===" => Eq, Eq, Eq); + t!(Markup["a1/"]: "= " => Eq, Space(0)); t!(Markup: "~" => Tilde); t!(Markup[" "]: r"\" => Backslash); } @@ -655,10 +651,9 @@ mod tests { ]; for &(s, t) in &both { - t!(Code[" "]: format!("#{}", s) => t); - t!(Markup[" "]: format!("#{}", s) => t); - t!(Markup[" "]: format!("#{0}#{0}", s) => t, t); - t!(Markup[" /"]: format!("# {}", s) => Hash, Space(0), Text(s)); + t!(Both[" "]: format!("#{}", s) => t); + t!(Both[" "]: format!("#{0}#{0}", s) => t, t); + t!(Markup[" /"]: format!("# {}", s) => Token::Invalid("#"), Space(0), Text(s)); } let code = [ @@ -713,7 +708,7 @@ mod tests { // Test code symbols in text. t!(Markup[" /"]: "a():\"b" => Text("a():\"b")); - t!(Markup[" /"]: ";:,=|/+-" => Text(";:,=|/+-")); + t!(Markup[" /"]: ";:,|/+-" => Text(";:,|/+-")); // Test text ends. t!(Markup[""]: "hello " => Text("hello"), Space(0)); @@ -765,17 +760,17 @@ mod tests { t!(Markup: r"\}" => Text("}")); t!(Markup: r"\*" => Text("*")); t!(Markup: r"\_" => Text("_")); - t!(Markup: r"\#" => Text("#")); + t!(Markup: r"\=" => Text("=")); t!(Markup: r"\~" => Text("~")); t!(Markup: r"\`" => Text("`")); t!(Markup: r"\$" => Text("$")); + t!(Markup: r"\#" => Text("#")); // Test unescapable symbols. t!(Markup[" /"]: r"\a" => Text(r"\"), Text("a")); t!(Markup[" /"]: r"\u" => Text(r"\"), Text("u")); t!(Markup[" /"]: r"\1" => Text(r"\"), Text("1")); t!(Markup[" /"]: r"\:" => Text(r"\"), Text(":")); - t!(Markup[" /"]: r"\=" => Text(r"\"), Text("=")); t!(Markup[" /"]: r#"\""# => Text(r"\"), Text("\"")); // Test basic unicode escapes. @@ -947,7 +942,7 @@ mod tests { t!(Code: "1%%" => Percent(1.0), Invalid("%")); // Test invalid keyword. - t!(Markup[" /"]: "#-" => Hash, Text("-")); + t!(Markup[" /"]: "#-" => Invalid("#-")); t!(Markup[" /"]: "#do" => Invalid("#do")); t!(Code[" /"]: r"#letter" => Invalid(r"#letter")); } diff --git a/src/syntax/expr.rs b/src/syntax/expr.rs index ca55bdd0a..7a055cc7a 100644 --- a/src/syntax/expr.rs +++ b/src/syntax/expr.rs @@ -43,7 +43,7 @@ pub enum Expr { Unary(ExprUnary), /// A binary operation: `a + b`. Binary(ExprBinary), - /// An invocation of a function: `foo(...)`, `[foo ...]`. + /// An invocation of a function: `foo(...)`, `#[foo ...]`. Call(ExprCall), /// A let expression: `#let x = 1`. Let(ExprLet), @@ -75,11 +75,7 @@ impl Pretty for Expr { Self::Str(v) => write!(p, "{:?}", &v).unwrap(), Self::Array(v) => v.pretty(p), Self::Dict(v) => v.pretty(p), - Self::Template(v) => { - p.push_str("["); - v.pretty(p); - p.push_str("]"); - } + Self::Template(v) => pretty_template(v, p), Self::Group(v) => { p.push_str("("); v.v.pretty(p); @@ -146,6 +142,17 @@ impl Pretty for Named { /// A template expression: `[*Hi* there!]`. pub type ExprTemplate = Tree; +/// Pretty print a template. +pub fn pretty_template(template: &ExprTemplate, p: &mut Printer) { + if let [Spanned { v: Node::Expr(Expr::Call(call)), .. }] = template.as_slice() { + pretty_func_template(call, p, false) + } else { + p.push_str("["); + template.pretty(p); + p.push_str("]"); + } +} + /// A grouped expression: `(1 + 2)`. pub type ExprGroup = SpanBox; @@ -400,7 +407,7 @@ pub enum Associativity { Right, } -/// An invocation of a function: `foo(...)`, `[foo ...]`. +/// An invocation of a function: `foo(...)`, `#[foo ...]`. #[derive(Debug, Clone, PartialEq)] pub struct ExprCall { /// The callee of the function. @@ -418,12 +425,12 @@ impl Pretty for ExprCall { } } -/// Pretty print a bracketed function call, with body or chaining when possible. -pub fn pretty_bracket_call(call: &ExprCall, p: &mut Printer, chained: bool) { +/// Pretty print a function template, with body or chaining when possible. +pub fn pretty_func_template(call: &ExprCall, p: &mut Printer, chained: bool) { if chained { p.push_str(" | "); } else { - p.push_str("["); + p.push_str("#["); } // Function name. @@ -431,7 +438,7 @@ pub fn pretty_bracket_call(call: &ExprCall, p: &mut Printer, chained: bool) { // Find out whether this can be written with a body or as a chain. // - // Example: Transforms "[v [Hi]]" => "[v][Hi]". + // Example: Transforms "#[v [Hi]]" => "#[v][Hi]". if let [head @ .., Argument::Pos(Spanned { v: Expr::Template(template), .. })] = call.args.v.as_slice() { @@ -443,9 +450,9 @@ pub fn pretty_bracket_call(call: &ExprCall, p: &mut Printer, chained: bool) { // Find out whether this can written as a chain. // - // Example: Transforms "[v][[f]]" => "[v | f]". + // Example: Transforms "#[v][[f]]" => "#[v | f]". if let [Spanned { v: Node::Expr(Expr::Call(call)), .. }] = template.as_slice() { - return pretty_bracket_call(call, p, true); + return pretty_func_template(call, p, true); } else { p.push_str("]["); template.pretty(p); diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index d1fc6b779..41fba1345 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -60,7 +60,7 @@ mod tests { roundtrip("hi"); // Heading. - roundtrip("# *Ok*"); + roundtrip("= *Ok*"); // Raw. roundtrip("`lang 1`"); @@ -94,9 +94,9 @@ mod tests { roundtrip("{(a: 1, b: 2)}"); // Templates. - roundtrip("{[]}"); - roundtrip("{[*Ok*]}"); - roundtrip("{[[f]]}"); + roundtrip("[]"); + roundtrip("[*Ok*]"); + roundtrip("{[f]}"); // Groups. roundtrip("{(1)}"); @@ -105,6 +105,7 @@ mod tests { roundtrip("{}"); roundtrip("{1}"); roundtrip("{ #let x = 1; x += 2; x + 1 }"); + roundtrip("[{}]"); // Operators. roundtrip("{-x}"); @@ -116,14 +117,14 @@ mod tests { roundtrip("{v(1)}"); roundtrip("{v(a: 1, b)}"); - // Bracket calls. - roundtrip("[v]"); - roundtrip("[v 1]"); - roundtrip("[v 1, 2][*Ok*]"); - roundtrip("[v 1 | f 2]"); - roundtrip("{[[v]]}"); - test("[v 1, [[f 2]]]", "[v 1 | f 2]"); - test("[v 1, 2][[f 3]]", "[v 1, 2 | f 3]"); + // Function templates. + roundtrip("#[v]"); + roundtrip("#[v 1]"); + roundtrip("#[v 1, 2][*Ok*]"); + roundtrip("#[v 1 | f 2]"); + roundtrip("{#[v]}"); + test("#[v 1, #[f 2]]", "#[v 1 | f 2]"); + test("#[v 1, 2][#[f 3]]", "#[v 1, 2 | f 3]"); // Keywords. roundtrip("#let x = 1 + 2"); diff --git a/src/syntax/node.rs b/src/syntax/node.rs index db3b65108..d45e59528 100644 --- a/src/syntax/node.rs +++ b/src/syntax/node.rs @@ -36,8 +36,8 @@ impl Pretty for Node { Self::Raw(raw) => raw.pretty(p), Self::Expr(expr) => { if let Expr::Call(call) = expr { - // Format bracket calls appropriately. - pretty_bracket_call(call, p, false) + // Format function templates appropriately. + pretty_func_template(call, p, false) } else { expr.pretty(p); } @@ -58,7 +58,7 @@ pub struct NodeHeading { impl Pretty for NodeHeading { fn pretty(&self, p: &mut Printer) { for _ in 0 ..= self.level.v { - p.push_str("#"); + p.push_str("="); } self.contents.pretty(p); } diff --git a/src/syntax/token.rs b/src/syntax/token.rs index 43797f75d..c4b9ec8fd 100644 --- a/src/syntax/token.rs +++ b/src/syntax/token.rs @@ -6,6 +6,8 @@ use crate::geom::{AngularUnit, LengthUnit}; pub enum Token<'s> { /// A left square bracket: `[`. LeftBracket, + /// A hashtag followed by a left square bracket: `#[`. + HashBracket, /// A right square bracket: `]`. RightBracket, /// A left curly brace: `{`. @@ -20,8 +22,8 @@ pub enum Token<'s> { Star, /// An underscore: `_`. Underscore, - /// A hashtag: `#`. - Hash, + /// A single equals sign: `=`. + Eq, /// A tilde: `~`. Tilde, /// A backslash followed by nothing or whitespace: `\`. @@ -40,8 +42,6 @@ pub enum Token<'s> { Hyph, /// A slash: `/`. Slash, - /// A single equals sign: `=`. - Eq, /// Two equals signs: `==`. EqEq, /// An exclamation mark followed by an equals sign: `!=`. @@ -191,6 +191,7 @@ impl<'s> Token<'s> { pub fn name(self) -> &'static str { match self { Self::LeftBracket => "opening bracket", + Self::HashBracket => "start of function template", Self::RightBracket => "closing bracket", Self::LeftBrace => "opening brace", Self::RightBrace => "closing brace", @@ -198,7 +199,6 @@ impl<'s> Token<'s> { Self::RightParen => "closing paren", Self::Star => "star", Self::Underscore => "underscore", - Self::Hash => "hashtag", Self::Tilde => "tilde", Self::Backslash => "backslash", Self::Comma => "comma", diff --git a/tests/full/typ/coma.typ b/tests/full/typ/coma.typ index b7863fce8..32990997c 100644 --- a/tests/full/typ/coma.typ +++ b/tests/full/typ/coma.typ @@ -1,23 +1,23 @@ -[page width: 450pt, height: 300pt, margins: 1cm] +#[page width: 450pt, height: 300pt, margins: 1cm] -[box][ +#[box][ *Technische Universität Berlin* \ *Fakultät II, Institut for Mathematik* \ Sekretariat MA \ 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/lang/ref/bracket-call.png b/tests/lang/ref/bracket-call.png index e892448424f667f759e88fd4c71e5ec64f97f14e..fe7f24346e676122d93202ffc7a3659bf0d36774 100644 GIT binary patch literal 22558 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%0A}JG{RxbSht*J8Wtjh?XHL@qZsXX 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 C)MKdt diff --git a/tests/lang/ref/headings.png b/tests/lang/ref/headings.png index c8d831650fd520f87def2007ce3243832d210436..b1ad336668b723e40219f7d3b50e1ef88969b818 100644 GIT binary patch literal 7415 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 UQ~kccKYlc|)O2r_s@UTH3!J85NdN!< literal 7985 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 5, false] -[test 5 <= 5, true] -[test 5 <= 4, false] -[test 45deg < 1rad, true] +#[test 13 * 3 < 14 * 4, true] +#[test 5 < 10, true] +#[test 5 > 5, false] +#[test 5 <= 5, true] +#[test 5 <= 4, false] +#[test 45deg < 1rad, true] // Assignment. #let x = "some" #let y = "some" -[test (x = y = "") == none and x == none and y == "", true] +#[test (x = y = "") == none and x == none and y == "", true] // Modify-assign operators. #let x = 0 -{ x = 10 } [test x, 10] -{ x -= 5 } [test x, 5] -{ x += 1 } [test x, 6] -{ x *= x } [test x, 36] -{ x /= 2.0 } [test x, 18.0] -{ x = "some" } [test x, "some"] -{ x += "thing" } [test x, "something"] +{ x = 10 } #[test x, 10] +{ x -= 5 } #[test x, 5] +{ x += 1 } #[test x, 6] +{ x *= x } #[test x, 36] +{ x /= 2.0 } #[test x, 18.0] +{ x = "some" } #[test x, "some"] +{ x += "thing" } #[test x, "something"] // Error: 1:3-1:4 unknown variable { z = 1 } @@ -94,21 +94,21 @@ #let box = ""; { box = "hi" } // Parentheses. -[test (a), 2] -[test (2), 2] -[test (1+2)*3, 9] +#[test (a), 2] +#[test (2), 2] +#[test (1+2)*3, 9] // Error: 1:3-1:3 expected expression {-} -// Error: 1:10-1:10 expected expression -[test {1+}, 1] +// Error: 1:11-1:11 expected expression +#[test {1+}, 1] -// Error: 1:10-1:10 expected expression -[test {2*}, 2] +// Error: 1:11-1:11 expected expression +#[test {2*}, 2] -// Error: 1:7-1:16 cannot apply '-' to boolean -[test -not true, error] +// Error: 1:8-1:17 cannot apply '-' to boolean +#[test -not true, error] // Error: 1:2-1:8 cannot apply 'not' to array {not ()} diff --git a/tests/lang/typ/headings.typ b/tests/lang/typ/headings.typ index e63574ca3..a1bb37537 100644 --- a/tests/lang/typ/headings.typ +++ b/tests/lang/typ/headings.typ @@ -1,48 +1,41 @@ // Test different numbers of hashtags. // Valid levels. -# One -### Three -###### Six += One +=== Three +====== Six // Too many hashtags. // Warning: 1:1-1:8 should not exceed depth 6 -####### Seven +======= Seven --- // Test heading vs. no heading. // Parsed as headings if at start of the context. -/**/ # Heading -{[## Heading]} -[box][### Heading] +/**/ = Heading +{[== Heading]} +#[box][=== Heading] // Not at the start of the context. -Text with # hashtag +Text = with=sign // Escaped. -\# No heading - -// Keyword. -// Error: 1:1-1:6 unexpected invalid token -#nope - -// Not parsed as a keyword, but neither as a heading. -Nr#1 +\= No heading --- // Heading continuation over linebreak. // Code blocks continue heading. -# This { += This { "continues" } // Function call continues heading. -# [box][ += #[box][ This, ] too // Without some kind of block, headings end at a line break. -# This += This not diff --git a/tests/lang/typ/if.typ b/tests/lang/typ/if.typ index ee466a8d9..5fb46320b 100644 --- a/tests/lang/typ/if.typ +++ b/tests/lang/typ/if.typ @@ -52,8 +52,7 @@ a#if x b#if (x)c a#if true [b] #else c // Lone else. -// Error: 2:1-2:6 unexpected keyword `#else` -// Error: 1:8-1:8 expected identifier +// Error: 1:1-1:6 unexpected keyword `#else` #else [] // Condition must be boolean. If it isn't, neither branch is evaluated. diff --git a/tests/lang/typ/let.typ b/tests/lang/typ/let.typ index b3eadeaa2..52545b2f0 100644 --- a/tests/lang/typ/let.typ +++ b/tests/lang/typ/let.typ @@ -1,10 +1,10 @@ // Automatically initialized with `none`. #let x -[test x, none] +#[test x, none] // Initialized with `1`. #let y = 1 -[test y, 1] +#[test y, 1] // Initialize with template, not terminated by semicolon in template. #let v = [Hello; there] @@ -15,10 +15,10 @@ 2, 3, ) -[test x, (1, 2, 3)] +#[test x, (1, 2, 3)] // Multiple bindings in one line. -#let x = "a"; #let y = "b"; [test x + y, "ab"] +#let x = "a"; #let y = "b"; #[test x + y, "ab"] // Invalid name. // Error: 1:6-1:7 expected identifier, found integer @@ -43,24 +43,24 @@ The Fi#let;rst // Terminated with just a line break. #let v = "a" -The Second [test v, "a"] +The Second #[test v, "a"] // Terminated with semicolon + line break. #let v = "a"; -The Third [test v, "a"] +The Third #[test v, "a"] // Terminated with just a semicolon. -The#let v = "a"; Fourth [test v, "a"] +The#let v = "a"; Fourth #[test v, "a"] // Terminated by semicolon even though we are in a paren group. // Error: 2:25-2:25 expected expression // Error: 1:25-1:25 expected closing paren -The#let array = (1, 2 + ;Fifth [test array, (1, 2)] +The#let array = (1, 2 + ;Fifth #[test array, (1, 2)] // Not terminated. // Error: 1:16-1:16 expected semicolon or line break -The#let v = "a"Sixth [test v, "a"] +The#let v = "a"Sixth #[test v, "a"] // Not terminated. // Error: 1:16-1:16 expected semicolon or line break -The#let v = "a" [test v, "a"] Seventh +The#let v = "a" #[test v, "a"] Seventh diff --git a/tests/lang/typ/raw.typ b/tests/lang/typ/raw.typ index 2c0890ba2..a1f796b5c 100644 --- a/tests/lang/typ/raw.typ +++ b/tests/lang/typ/raw.typ @@ -1,4 +1,4 @@ -[font 8pt] +#[font 8pt] // Typst syntax inside. `#let x = 1``[f 1]` diff --git a/tests/lang/typ/values.typ b/tests/lang/typ/values.typ index 55712c4db..53c2ea68c 100644 --- a/tests/lang/typ/values.typ +++ b/tests/lang/typ/values.typ @@ -37,4 +37,4 @@ {"a\n[]\"\u{1F680}string"} \ // Templates. -{[*{"Hi"} [f 1]*]} +{[*{"Hi"} #[f 1]*]} diff --git a/tests/library/typ/font.typ b/tests/library/typ/font.typ index 4be98941c..57761a8fb 100644 --- a/tests/library/typ/font.typ +++ b/tests/library/typ/font.typ @@ -1,37 +1,37 @@ // 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] +#[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] -// Error: 1:7-1:12 unexpected argument -[font false] +// Error: 1:8-1:13 unexpected argument +#[font false] -// Error: 3:14-3:18 expected font style, found font weight -// Error: 2:28-2:34 expected font weight, found string -// Error: 1:43-1:44 expected font family or array of font families, found integer -[font style: bold, weight: "thin", serif: 0] +// Error: 3:15-3:19 expected font style, found font weight +// Error: 2:29-2:35 expected font weight, found string +// Error: 1:44-1:45 expected font family or array of font families, found integer +#[font style: bold, weight: "thin", serif: 0] -// Warning: 1:15-1:19 should be between 100 and 900 -[font weight: 2700] +// Warning: 1:16-1:20 should be between 100 and 900 +#[font weight: 2700] -// Error: 1:7-1:27 unexpected argument -[font something: "invalid"] +// Error: 1:8-1:28 unexpected argument +#[font something: "invalid"] --- // Test font fallback and class definitions. @@ -40,17 +40,17 @@ Emoji: 🏀 // CMU Serif + Noto Emoji. -[font "CMU Serif", "Noto Emoji"][ +#[font "CMU Serif", "Noto Emoji"][ Emoji: 🏀 ] // Class definitions. -[font serif: ("CMU Serif", "Latin Modern Math", "Noto Emoji")] -[font serif][ +#[font serif: ("CMU Serif", "Latin Modern Math", "Noto Emoji")] +#[font serif][ Math: ∫ α + β ➗ 3 ] // Class definition reused. -[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. 🚀 diff --git a/tests/library/typ/hv.typ b/tests/library/typ/hv.typ index 36a6d242d..67c04a12f 100644 --- a/tests/library/typ/hv.typ +++ b/tests/library/typ/hv.typ @@ -1,22 +1,22 @@ // 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. -// Error: 1:11-1:11 missing argument: spacing -Totally [h] ignored +// Error: 1:12-1:12 missing argument: spacing +Totally #[h] ignored // Swapped axes. -[page main-dir: rtl, cross-dir: ttb, height: 80pt][ - 1 [h 1cm] 2 +#[page main-dir: rtl, cross-dir: ttb, height: 80pt][ + 1 #[h 1cm] 2 - 3 [v 1cm] 4 [v -1cm] 5 + 3 #[v 1cm] 4 #[v -1cm] 5 ] diff --git a/tests/library/typ/image.typ b/tests/library/typ/image.typ index 2e7b1eb52..a1e886dd9 100644 --- a/tests/library/typ/image.typ +++ b/tests/library/typ/image.typ @@ -1,39 +1,39 @@ // Test loading different image formats. // Load an RGBA PNG image. -[image "res/rhino.png"] -[pagebreak] +#[image "res/rhino.png"] +#[pagebreak] // Load an RGB JPEG image. -[image "res/tiger.jpg"] +#[image "res/tiger.jpg"] -// Error: 1:8-1:29 failed to load image -[image "path/does/not/exist"] +// Error: 1:9-1:30 failed to load image +#[image "path/does/not/exist"] -// Error: 1:8-1:29 failed to load image -[image "typ/image-error.typ"] +// Error: 1:9-1:30 failed to load image +#[image "typ/image-error.typ"] --- // 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 height: 40pt][ - [image "res/rhino.png"] +#[page height: 40pt][ + #[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", width: 60pt] +#[align bottom, right][ + #[image "res/tiger.jpg", width: 60pt] ] diff --git a/tests/library/typ/page.typ b/tests/library/typ/page.typ index 9eeddc93c..97100ae99 100644 --- a/tests/library/typ/page.typ +++ b/tests/library/typ/page.typ @@ -1,54 +1,53 @@ // Test configuring page sizes and margins. // Set width and height. -[page width: 120pt, height: 120pt] -[page width: 40pt][High] -[page height: 40pt][Wide] +#[page width: 120pt, height: 120pt] +#[page width: 40pt][High] +#[page height: 40pt][Wide] // Set all margins at once. -[page margins: 30pt][ - [align top, left][TL] - [align bottom, right][BR] +#[page margins: 30pt][ + #[align top, left][TL] + #[align bottom, right][BR] ] // Set individual margins. -[page height: 40pt] -[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 height: 40pt] +#[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: 20pt][Overriden] +#[page margins: 0pt, left: 20pt][Overriden] -// Error: 1:7-1:18 unknown variable -[page nonexistant] +// Error: 1:8-1:19 unknown variable +#[page nonexistant] -// Error: 1:17-1:20 aligned axis -[page main-dir: ltr] +// Error: 1:18-1:21 aligned axis +#[page main-dir: ltr] // Flipped predefined paper. -[page "a11", flip: true][Flipped A11] +#[page "a11", flip: true][Flipped A11] // Flipped custom page size. -[page width: 40pt, height: 120pt] -[page flip: true] +#[page width: 40pt, height: 120pt] +#[page flip: true] Wide // Test changing the layouting directions of pages. - -[page height: 50pt, main-dir: btt, cross-dir: rtl] +#[page height: 50pt, main-dir: btt, cross-dir: rtl] Right to left! --- // Test a combination of pages with bodies and normal content. -[page height: 50pt] +#[page height: 50pt] -[page][First] -[page][Second] -[pagebreak] +#[page][First] +#[page][Second] +#[pagebreak] Fourth -[page][] +#[page][] Sixth -[page][Seventh and last] +#[page][Seventh and last] diff --git a/tests/library/typ/pagebreak.typ b/tests/library/typ/pagebreak.typ index 2f539ce00..08dd9c7b7 100644 --- a/tests/library/typ/pagebreak.typ +++ b/tests/library/typ/pagebreak.typ @@ -1,3 +1,3 @@ First of two -[pagebreak] -[page height: 40pt] +#[pagebreak] +#[page height: 40pt] diff --git a/tests/library/typ/rgb.typ b/tests/library/typ/rgb.typ index f778b2d1f..e7b405184 100644 --- a/tests/library/typ/rgb.typ +++ b/tests/library/typ/rgb.typ @@ -1,17 +1,17 @@ // Check the output. -[rgb 0.0, 0.3, 0.7] +#[rgb 0.0, 0.3, 0.7] // Alpha channel. -[rgb 1.0, 0.0, 0.0, 0.5] +#[rgb 1.0, 0.0, 0.0, 0.5] -// Warning: 2:6-2:9 should be between 0.0 and 1.0 -// Warning: 1:11-1:15 should be between 0.0 and 1.0 -[rgb -30, 15.5, 0.5] +// Warning: 2:7-2:10 should be between 0.0 and 1.0 +// Warning: 1:12-1:16 should be between 0.0 and 1.0 +#[rgb -30, 15.5, 0.5] -// Error: 1:6-1:10 missing argument: blue component -[rgb 0, 1] +// Error: 1:7-1:11 missing argument: blue component +#[rgb 0, 1] -// Error: 3:5-3:5 missing argument: red component -// Error: 2:5-2:5 missing argument: green component -// Error: 1:5-1:5 missing argument: blue component -[rgb] +// Error: 3:6-3:6 missing argument: red component +// Error: 2:6-2:6 missing argument: green component +// Error: 1:6-1:6 missing argument: blue component +#[rgb]