diff options
Diffstat (limited to 'tests/typ')
41 files changed, 1346 insertions, 0 deletions
diff --git a/tests/typ/comment.typ b/tests/typ/comment.typ new file mode 100644 index 00000000..25180211 --- /dev/null +++ b/tests/typ/comment.typ @@ -0,0 +1,23 @@ +// Test line and block comments. + +--- +// Line comment acts as spacing. +A// you +B + +// Block comment does not act as spacing. +C/* + /* */ +*/D + +// Works in code. +#test(type(/*1*/ 1) // +, "integer") + +--- +// End should not appear without start. +// Error: 1:7-1:9 unexpected end of block comment +/* */ */ + +// Unterminated is okay. +/* diff --git a/tests/typ/control/for-invalid.typ b/tests/typ/control/for-invalid.typ new file mode 100644 index 00000000..c8bdebdd --- /dev/null +++ b/tests/typ/control/for-invalid.typ @@ -0,0 +1,32 @@ +// Test invalid for loop syntax. + +--- +// Error: 5-5 expected identifier +#for + +// Error: 7-7 expected keyword `in` +#for v + +// Error: 10-10 expected expression +#for v in + +// Error: 15-15 expected body +#for v in iter + +--- +// Should output `v in iter`. +// Error: 5 expected identifier +#for +v in iter {} + +// Should output `A thing`. +// Error: 7-10 expected identifier, found string +A#for "v" thing. + +// Should output `in iter`. +// Error: 6-9 expected identifier, found string +#for "v" in iter {} + +// Should output `+ b in iter`. +// Error: 7 expected keyword `in` +#for a + b in iter {} diff --git a/tests/typ/control/for-pattern.typ b/tests/typ/control/for-pattern.typ new file mode 100644 index 00000000..38253b33 --- /dev/null +++ b/tests/typ/control/for-pattern.typ @@ -0,0 +1,30 @@ +// Test for loop patterns. +// Ref: false + +--- +#let out = () + +// Values of array. +#for v in (1, 2, 3) { + out += (v,) +} + +// Values of dictionary. +#for v in (a: 4, b: 5) { + out += (v,) +} + +// Keys and values of dictionary. +#for k, v in (a: 6, b: 7) { + out += (k,) + out += (v,) +} + +#test(out, (1, 2, 3, 4, 5, "a", 6, "b", 7)) + +--- +// Keys and values of array. +// Error: 6-10 mismatched pattern +#for k, v in (-1, -2, -3) { + dont-care +} diff --git a/tests/typ/control/for-value.typ b/tests/typ/control/for-value.typ new file mode 100644 index 00000000..3ab80716 --- /dev/null +++ b/tests/typ/control/for-value.typ @@ -0,0 +1,20 @@ +// Test return value of for loops. + +--- +// Template body yields template. +// Should output `234`. +#for v in (1, 2, 3, 4) [#if v >= 2 [{v}]] + +--- +// Block body yields template. +// Should output `[1st, 2nd, 3rd, 4th, 5th, 6th]`. +{ + "[" + for v in (1, 2, 3, 4, 5, 6) { + (if v > 1 [, ] + + [{v}] + + if v == 1 [st] + + if v == 2 [nd] + + if v == 3 [rd] + + if v >= 4 [th]) + } + "]" +} diff --git a/tests/typ/control/for.typ b/tests/typ/control/for.typ new file mode 100644 index 00000000..294345b5 --- /dev/null +++ b/tests/typ/control/for.typ @@ -0,0 +1,52 @@ +// Test for loops. +// Ref: false + +--- +// Array. + +#for x in () {} + +#let sum = 0 +#for x in (1, 2, 3, 4, 5) { + sum += x +} + +#test(sum, 15) + +--- +// Dictionary. +// Ref: true +(\ #for k, v in (name: "Typst", age: 2) [ + #h(0.5cm) {k}: {v}, \ +]) + +--- +// String. +{ + let out = "" + let first = true + for c in "abc" { + if not first { + out += ", " + } + first = false + out += c + } + test(out, "a, b, c") +} + +--- +// Uniterable expression. +// Error: 11-15 cannot loop over boolean +#for v in true {} + +// Make sure that we don't complain twice. +// Error: 11-18 cannot add integer and string +#for v in 1 + "2" {} + +// Error: 14-17 cannot apply '-' to string +#let error = -"" +#let result = for v in (1, 2, 3) { + if v < 2 [Ok] else {error} +} +#test(result, error) diff --git a/tests/typ/control/if-invalid.typ b/tests/typ/control/if-invalid.typ new file mode 100644 index 00000000..6d2deab1 --- /dev/null +++ b/tests/typ/control/if-invalid.typ @@ -0,0 +1,28 @@ +// Test invalid if syntax. + +--- +// Error: 4 expected expression +#if + +// Error: 4 expected expression +{if} + +// Error: 6 expected body +#if x + +// Error: 1-6 unexpected keyword `else` +#else {} + +--- +// Should output `x`. +// Error: 4 expected expression +#if +x {} + +// Should output `something`. +// Error: 6 expected body +#if x something + +// Should output `A thing.` +// Error: 20 expected body +A#if false {} #else thing diff --git a/tests/typ/control/if-value.typ b/tests/typ/control/if-value.typ new file mode 100644 index 00000000..d7124255 --- /dev/null +++ b/tests/typ/control/if-value.typ @@ -0,0 +1,21 @@ +// Test return value of if expressions. +// Ref: false + +--- +{ + let x = 1 + let y = 2 + let z + + // Returns if branch. + z = if x < y { "ok" } + test(z, "ok") + + // Returns else branch. + z = if x > y { "bad" } else { "ok" } + test(z, "ok") + + // Missing else evaluates to none. + z = if x > y { "bad" } + test(z, none) +} diff --git a/tests/typ/control/if.typ b/tests/typ/control/if.typ new file mode 100644 index 00000000..4ed6b649 --- /dev/null +++ b/tests/typ/control/if.typ @@ -0,0 +1,45 @@ +// Test if-else expressions. + +--- +// Test condition evaluation. +#if 1 < 2 [ + Ok. +] + +#if true == false [ + Bad, but we {dont-care}! +] + +--- +// Brace in condition. +#if {true} [ + Ok. +] + +// Multi-line condition with parens. +#if ( + 1 + 1 + == 1 +) { + nope +} #else { + "Ok." +} + +// Multiline. +#if false [ + Bad. +] #else { + let pt = "." + "Ok" + pt +} + +--- +// Condition must be boolean. +// If it isn't, neither branch is evaluated. +// Error: 5-14 expected boolean, found string +#if "a" + "b" { nope } #else { nope } + +// Make sure that we don't complain twice. +// Error: 5-12 cannot add integer and string +#if 1 + "2" {} diff --git a/tests/typ/control/let-invalid.typ b/tests/typ/control/let-invalid.typ new file mode 100644 index 00000000..f29353ed --- /dev/null +++ b/tests/typ/control/let-invalid.typ @@ -0,0 +1,20 @@ +// Test invalid let binding syntax. + +--- +// Error: 5 expected identifier +#let + +// Error: 6-9 expected identifier, found string +#let "v" + +// Should output `1`. +// Error: 7 expected semicolon or line break +#let v 1 + +// Error: 9 expected expression +#let v = + +--- +// Should output `= 1`. +// Error: 6-9 expected identifier, found string +#let "v" = 1 diff --git a/tests/typ/control/let-terminated.typ b/tests/typ/control/let-terminated.typ new file mode 100644 index 00000000..623265e0 --- /dev/null +++ b/tests/typ/control/let-terminated.typ @@ -0,0 +1,28 @@ +// Test termination of let statements. + +--- +// Terminated by line break. +#let v1 = 1 +One + +// Terminated by semicolon. +#let v2 = 2; Two + +// Terminated by semicolon and line break. +#let v3 = 3; +Three + +// Terminated because expression ends. +// Error: 12 expected semicolon or line break +#let v4 = 4 Four + +// Terminated by semicolon even though we are in a paren group. +// Error: 2:19 expected expression +// Error: 1:19 expected closing paren +#let v5 = (1, 2 + ; Five + +#test(v1, 1) +#test(v2, 2) +#test(v3, 3) +#test(v4, 4) +#test(v5, (1, 2)) diff --git a/tests/typ/control/let.typ b/tests/typ/control/let.typ new file mode 100644 index 00000000..e609d3a9 --- /dev/null +++ b/tests/typ/control/let.typ @@ -0,0 +1,11 @@ +// Test let bindings. +// Ref: false + +--- +// Automatically initialized with none. +#let x +#test(x, none) + +// Manually initialized with one. +#let x = 1 +#test(x, 1) diff --git a/tests/typ/empty.typ b/tests/typ/empty.typ new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/tests/typ/empty.typ diff --git a/tests/typ/expr/array.typ b/tests/typ/expr/array.typ new file mode 100644 index 00000000..c9383501 --- /dev/null +++ b/tests/typ/expr/array.typ @@ -0,0 +1,43 @@ +// Test arrays. + +--- +// Empty. +{()} + +// Not an array, just a parenthesized expression. +{(1)} + +// One item and trailing comma. +{(-1,)} + +// No trailing comma. +{(true, false)} + +// Multiple lines and items and trailing comma. +{("1" + , #002 + ,)} + +// Error: 3 expected closing paren +{(} + +// Error: 2-3 expected expression, found closing paren +{)} + +// Error: 2:4 expected comma +// Error: 1:4-1:6 expected expression, found end of block comment +{(1*/2)} + +// Error: 6-8 expected expression, found invalid token +{(1, 1u 2)} + +// Error: 3-4 expected expression, found comma +{(,1)} + +// Missing expression makes named pair incomplete, making this an empty array. +// Error: 5 expected expression +{(a:)} + +// Named pair after this is already identified as an array. +// Error: 6-10 expected expression, found named pair +{(1, b: 2)} diff --git a/tests/typ/expr/assoc.typ b/tests/typ/expr/assoc.typ new file mode 100644 index 00000000..19c56951 --- /dev/null +++ b/tests/typ/expr/assoc.typ @@ -0,0 +1,18 @@ +// Test operator associativity. +// Ref: false + +--- +// Math operators are left-associative. +#test(10 / 2 / 2 == (10 / 2) / 2, true) +#test(10 / 2 / 2 == 10 / (2 / 2), false) +#test(1 / 2 * 3, 1.5) + +--- +// Assignment is right-associative. +{ + let x = 1 + let y = 2 + x = y = "ok" + test(x, none) + test(y, "ok") +} diff --git a/tests/typ/expr/block-invalid.typ b/tests/typ/expr/block-invalid.typ new file mode 100644 index 00000000..d98bf06b --- /dev/null +++ b/tests/typ/expr/block-invalid.typ @@ -0,0 +1,37 @@ +// Test invalid code block syntax. + +--- +// Multiple unseparated expressions in one line. + +// Error: 2-4 expected expression, found invalid token +{1u} + +// Should output `1`. +// Error: 3 expected semicolon or line break +{0 1} + +// Should output `2`. +// Error: 2:12 expected semicolon or line break +// Error: 1:22 expected semicolon or line break +{let x = -1 let y = 3 x + y} + +// Should output `3`. +{ + // Error: 9-12 expected identifier, found string + for "v" + + // Error: 10 expected keyword `in` + for v let z = 1 + 2 + + z +} + +--- +// Ref: false +// Error: 3:1 expected closing brace +{ + +--- +// Ref: false +// Error: 1-2 unexpected closing brace +} diff --git a/tests/typ/expr/block-scoping.typ b/tests/typ/expr/block-scoping.typ new file mode 100644 index 00000000..7bb98969 --- /dev/null +++ b/tests/typ/expr/block-scoping.typ @@ -0,0 +1,35 @@ +// Test scoping with blocks. +// Ref: false + +--- +// Block in template does not create a scope. +{ let x = 1 } +#test(x, 1) + +--- +// Block in expression does create a scope. +#let a = { + let b = 1 + b +} + +#test(a, 1) + +// Error: 2-3 unknown variable +{b} + +--- +// Multiple nested scopes. +{ + let a = "a1" + { + let a = "a2" + { + test(a, "a2") + let a = "a3" + test(a, "a3") + } + test(a, "a2") + } + test(a, "a1") +} diff --git a/tests/typ/expr/block.typ b/tests/typ/expr/block.typ new file mode 100644 index 00000000..196e6c14 --- /dev/null +++ b/tests/typ/expr/block.typ @@ -0,0 +1,38 @@ +// Test code blocks. + +--- +All none + +// Nothing evaluates to none. +{} + +// Let evaluates to none. +{ let v = 0 } + +// Trailing none evaluates to none. +{ + type("") + none +} + +--- +// Evaluates to single expression. +{ "Hello" } + +// Evaluates to trailing expression. +{ let x = "Hel"; x + "lo" } + +// Evaluates to concatenation of for loop bodies. +{ + let parts = ("Hel", "lo") + for s in parts [{s}] +} + +--- +// Works the same way in code environment. +// Ref: false +#test(3, { + let x = 1 + let y = 2 + x + y +}) diff --git a/tests/typ/expr/call-invalid.typ b/tests/typ/expr/call-invalid.typ new file mode 100644 index 00000000..0ed5246f --- /dev/null +++ b/tests/typ/expr/call-invalid.typ @@ -0,0 +1,44 @@ +// Test invalid function calls. + +--- +// Error: 1-2 unexpected invalid token +# + +--- +// Error: 7-8 expected expression, found colon +#args(:) + +// Error: 10-12 expected expression, found end of block comment +#args(a:1*/) + +// Error: 8 expected comma +#args(1 2) + +// Error: 2:7-2:8 expected identifier +// Error: 1:9 expected expression +#args(1:) + +// Error: 7-8 expected identifier +#args(1:2) + +// Error: 7-10 expected identifier +{args((x):1)} + +--- +#let x = "string" + +// Error: 1-3 expected function, found string +#x() + +--- +// Error: 3:1 expected closing bracket +#args[`a]` + +--- +// Error: 7 expected closing paren +{args(} + +--- +// Error: 3:1 expected quote +// Error: 2:1 expected closing paren +#args("] diff --git a/tests/typ/expr/call.typ b/tests/typ/expr/call.typ new file mode 100644 index 00000000..213d5554 --- /dev/null +++ b/tests/typ/expr/call.typ @@ -0,0 +1,40 @@ +// Test function calls. + +--- +// One argument. +#args(bold) + +// One argument and trailing comma. +#args(1,) + +// One named argument. +#args(a:2) + +// Mixed arguments. +{args(1, b: "2", 3)} + +--- +// Different forms of template arguments. +// Ref: true + +#let a = "a" + +#args[a] \ +#args(a) \ +#args(a, [b]) \ +#args(a)[b] \ + +// Template can be argument or body depending on whitespace. +#if "template" == type[b] [Sure ] +#if "template" == type [Nope.] #else [thing.] + +// Should output `<function args> (Okay.)`. +#args (Okay.) + +--- +// Call function assigned to variable. +#let alias = type +#test(alias(alias), "function") + +// Library function `font` returns template. +#test(type(font(12pt)), "template") diff --git a/tests/typ/expr/dict.typ b/tests/typ/expr/dict.typ new file mode 100644 index 00000000..655a3299 --- /dev/null +++ b/tests/typ/expr/dict.typ @@ -0,0 +1,20 @@ +// Test dictionaries. + +--- +// Empty +{(:)} + +// Two pairs. +{(a1: 1, a2: 2)} + +--- +// Simple expression after already being identified as a dictionary. +// Error: 9-10 expected named pair, found expression +{(a: 1, b)} + +// Identified as dictionary due to initial colon. +// Error: 4:4-4:5 expected named pair, found expression +// Error: 3:5 expected comma +// Error: 2:12-2:16 expected identifier +// Error: 1:17-1:18 expected expression, found colon +{(:1 b:[], true::)} diff --git a/tests/typ/expr/ops-invalid.typ b/tests/typ/expr/ops-invalid.typ new file mode 100644 index 00000000..f760ae31 --- /dev/null +++ b/tests/typ/expr/ops-invalid.typ @@ -0,0 +1,59 @@ +// Test invalid expressions. +// Ref: false + +--- +// Missing expressions. + +// Error: 3 expected expression +{-} + +// Error: 10 expected expression +#test({1+}, 1) + +// Error: 10 expected expression +#test({2*}, 2) + +--- +// Mismatched types. + +// Error: 2-12 cannot apply '+' to template +{+([] + [])} + +// Error: 2-5 cannot apply '-' to string +{-""} + +// Error: 2-8 cannot apply 'not' to array +{not ()} + +// Error: 1:2-1:12 cannot apply '<=' to relative and relative +{30% <= 40%} + +// Special messages for +, -, * and /. +// Error: 4:03-4:10 cannot add integer and string +// Error: 3:12-3:19 cannot subtract integer from relative +// Error: 2:21-2:29 cannot multiply integer with boolean +// Error: 1:31-1:39 cannot divide integer by length +{(1 + "2", 40% - 1, 2 * true, 3 / 12pt)} + +// Error: 14-22 cannot apply '+=' to integer and string +{ let x = 1; x += "2" } + +--- +// Bad left-hand sides of assignment. + +// Error: 3-6 cannot assign to this expression +{ (x) = "" } + +// Error: 3-8 cannot assign to this expression +{ 1 + 2 += 3 } + +// Error: 3-4 unknown variable +{ z = 1 } + +// Error: 3-6 cannot assign to a constant +{ box = "hi" } + +// Works if we define box beforehand +// (since then it doesn't resolve to the standard library version anymore). +#let box = "" +{ box = "hi" } diff --git a/tests/typ/expr/ops.typ b/tests/typ/expr/ops.typ new file mode 100644 index 00000000..2390b7b4 --- /dev/null +++ b/tests/typ/expr/ops.typ @@ -0,0 +1,150 @@ +// Test binary expressions. +// Ref: false + +--- +// Test template addition. +// Ref: true +{[*Hello ] + [world!*]} + +--- +// Test math operators. + +// Test plus and minus. +#for v in (1, 3.14, 12pt, 45deg, 90%, 13% + 10pt) { + // Test plus. + test(+v, v) + + // Test minus. + test(-v, -1 * v) + test(--v, v) + + // Test combination. + test(-++ --v, -v) +} + +#test(-(4 + 2), 6-12) + +// Addition. +#test(2 + 4, 6) +#test("a" + "b", "ab") +#test((1, 2) + (3, 4), (1, 2, 3, 4)) +#test((a: 1) + (b: 2, c: 3), (a: 1, b: 2, c: 3)) + +// Subtraction. +#test(1-4, 3*-1) +#test(4cm - 2cm, 2cm) +#test(1e+2-1e-2, 99.99) + +// Multiplication. +#test(2 * 4, 8) + +// Division. +#test(12pt/.4, 30pt) +#test(7 / 2, 3.5) + +// Combination. +#test(3-4 * 5 < -10, true) +#test({ let x; x = 1 + 4*5 >= 21 and { x = "a"; x + "b" == "ab" }; x }, true) + +// Mathematical identities. +#let nums = (1, 3.14, 12pt, 45deg, 90%, 13% + 10pt) +#for v in nums { + // Test plus and minus. + test(v + v - v, v) + test(v - v - v, -v) + + // Test plus/minus and multiplication. + test(v - v, 0 * v) + test(v + v, 2 * v) + + // Integer addition does not give a float. + if type(v) != "integer" { + test(v + v, 2.0 * v) + } + + // Linears cannot be divided by themselves. + if type(v) != "linear" { + test(v / v, 1.0) + test(v / v == 1, true) + } +} + +// Make sure length, relative and linear +// - can all be added to / subtracted from each other, +// - multiplied with integers and floats, +// - divided by floats. +#let dims = (10pt, 30%, 50% + 3cm) +#for a in dims { + for b in dims { + test(type(a + b), type(a - b)) + } + + for b in (7, 3.14) { + test(type(a * b), type(a)) + test(type(b * a), type(a)) + test(type(a / b), type(a)) + } +} + +--- +// Test boolean operators. + +// Test not. +#test(not true, false) +#test(not false, true) + +// And. +#test(false and false, false) +#test(false and true, false) +#test(true and false, false) +#test(true and true, true) + +// Or. +#test(false or false, false) +#test(false or true, true) +#test(true or false, true) +#test(true or true, true) + +// Short-circuiting. +#test(false and dont-care, false) +#test(true or dont-care, true) + +--- +// Test equality operators. + +#test(1 == "hi", false) +#test(1 == 1.0, true) +#test(30% == 30% + 0cm, true) +#test(1in == 0% + 72pt, true) +#test(30% == 30% + 1cm, false) +#test("ab" == "a" + "b", true) +#test(() == (1,), false) +#test((1, 2, 3) == (1, 2.0) + (3,), true) +#test((:) == (a: 1), false) +#test((a: 2 - 1.0, b: 2) == (b: 2, a: 1), true) +#test([*Hi*] == [*Hi*], true) + +#test("a" != "a", false) +#test([*] != [_], true) + +--- +// Test comparison operators. + +#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) + +--- +// Test assignment 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") diff --git a/tests/typ/expr/prec.typ b/tests/typ/expr/prec.typ new file mode 100644 index 00000000..e64e583c --- /dev/null +++ b/tests/typ/expr/prec.typ @@ -0,0 +1,30 @@ +// Test operator precedence. +// Ref: false + +--- +// Multiplication binds stronger than addition. +#test(1+2*-3, -5) + +// Subtraction binds stronger than comparison. +#test(3 == 5 - 2, true) + +// Boolean operations bind stronger than '=='. +#test("a" == "a" and 2 < 3, true) +#test(not "b" == "b", false) + +// Assignment binds stronger than boolean operations. +// Error: 2-7 cannot assign to this expression +{not x = "a"} + +--- +// Parentheses override precedence. +#test((1), 1) +#test((1+2)*-3, -9) + +// Error: 14 expected closing paren +#test({(1 + 1}, 2) + +--- +// Precedence doesn't matter for chained unary operators. +// Error: 2-11 cannot apply '-' to boolean +{-not true} diff --git a/tests/typ/full/coma.typ b/tests/typ/full/coma.typ new file mode 100644 index 00000000..03f6dcc3 --- /dev/null +++ b/tests/typ/full/coma.typ @@ -0,0 +1,50 @@ +// Configuration with `page` and `font` functions. +#page(width: 450pt, height: 380pt, margins: 1cm) +#font("CMU Serif") + +// There are variables and they can take normal values like strings, ... +#let city = "Berlin" + +// ... but also "template" values. While these contain markup, +// they are also values and can be summed, stored in arrays etc. +// There are also more standard control flow structures, like #if and #for. +#let university = [*Technische Universität {city}*] +#let faculty = [*Fakultät II, Institut for Mathematik*] + +// The `box` function just places content into a rectangular container. When +// the only argument to a function is a template, the parentheses can be omitted +// (i.e. `f[a]` is the same as `f([a])`). +#box[ + // Backslash adds a forced line break. + #university \ + #faculty \ + Sekretariat MA \ + Dr. Max Mustermann \ + Ola Nordmann, John Doe +] +#align(right, box([*WiSe 2019/2020* \ Woche 3])) + +// Adds vertical spacing. +#v(6mm) + +// If the last argument to a function is a template, we can also place it behind +// the parentheses. +#align(center)[ + // Markdown-like syntax for headings. + ==== 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)] + +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 +zu _v_, und die Höhe von _v_ ist die Länge eines längsten (absteigenden) Weges +von _v_ zu einem Blatt. Die Höhe des Baumes ist die Höhe der Wurzel. + +#v(6mm) + +// The `image` function returns a "template" value of the same type as +// the `[...]` literals. +#align(center, image("res/graph.png", width: 75%)) diff --git a/tests/typ/library/box.typ b/tests/typ/library/box.typ new file mode 100644 index 00000000..57763f12 --- /dev/null +++ b/tests/typ/library/box.typ @@ -0,0 +1,20 @@ +#page("a7", flip: true) + +// Box with fixed width, should have text height. +#box(width: 2cm, color: #9650D6)[A] + +Sometimes there is no box. + +// Box with fixed height, should span line. +#box(height: 2cm, width: 100%, color: #734CED)[B] + +// Empty box with fixed width and height. +#box(width: 6cm, height: 12pt, color: #CB4CED) + +// Not visiblem, but creates a gap between the boxes above and below. +#box(width: 2in, color: #ff0000) + +// These are in a row! +#box(width: 1in, height: 10pt, color: #D6CD67) +#box(width: 1in, height: 10pt, color: #EDD466) +#box(width: 1in, height: 10pt, color: #E3BE62) diff --git a/tests/typ/library/font.typ b/tests/typ/library/font.typ new file mode 100644 index 00000000..7f13e8a6 --- /dev/null +++ b/tests/typ/library/font.typ @@ -0,0 +1,56 @@ +// Test configuring font properties. + +#font("PT Sans", 10pt) + +// Set same font size in three different ways. +#font(20pt)[A] +#font(200%)[A] +#font(15pt + 50%)[A] + +// Do nothing. +#font[Normal] + +// Set style (is available). +#font(style: italic)[Italic] + +// Set weight (is available). +#font(weight: bold)[Bold] + +// Set stretch (not available, matching closest). +#font(stretch: ultra-condensed)[Condensed] + +// Error: 7-12 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) + +// Warning: 15-19 should be between 100 and 900 +#font(weight: 2700) + +// Error: 7-27 unexpected argument +#font(something: "invalid") + +--- +// Test font fallback and class definitions. + +// Source Sans Pro + Segoe UI Emoji. +Emoji: 🏀 + +// CMU Serif + Noto Emoji. +#font("CMU Serif", "Noto Emoji")[ + Emoji: 🏀 +] + +// Class definitions. +#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)) +New sans-serif. 🚀 diff --git a/tests/typ/library/hv.typ b/tests/typ/library/hv.typ new file mode 100644 index 00000000..154445cf --- /dev/null +++ b/tests/typ/library/hv.typ @@ -0,0 +1,22 @@ +// Ends paragraphs. +Tightly #v(-5pt) packed + +// Eating up soft spacing. +Inv #h(0pt) isible + +// Multiple spacings in a row. +Add #h(10pt) #h(10pt) up + +// Relative to font size. +Relative #h(100%) spacing + +// Missing spacing. +// Error: 12 missing argument: spacing +Totally #h() ignored + +// Swapped axes. +#page(main-dir: rtl, cross-dir: ttb, height: 80pt)[ + 1 #h(1cm) 2 + + 3 #v(1cm) 4 #v(-1cm) 5 +] diff --git a/tests/typ/library/image.typ b/tests/typ/library/image.typ new file mode 100644 index 00000000..9c3cd4fe --- /dev/null +++ b/tests/typ/library/image.typ @@ -0,0 +1,35 @@ +// Test loading different image formats. + +// Load an RGBA PNG image. +#image("res/rhino.png") +#pagebreak() + +// Load an RGB JPEG image. +#image("res/tiger.jpg") + +// Error: 8-29 failed to load image +#image("path/does/not/exist") + +// Error: 8-29 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") + +// Fit to height of page. +#page(height: 40pt, image("res/rhino.png")) + +// Set width explicitly. +#image("res/rhino.png", width: 50pt) + +// Set height explicitly. +#image("res/rhino.png", height: 50pt) + +// Set width and height explicitly and force stretching. +#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)) diff --git a/tests/typ/library/page.typ b/tests/typ/library/page.typ new file mode 100644 index 00000000..b7ac0348 --- /dev/null +++ b/tests/typ/library/page.typ @@ -0,0 +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] + +// Set all margins at once. +#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]) + +// Ensure that specific margins override general margins. +#page(margins: 0pt, left: 20pt)[Overriden] + +// Error: 7-18 unknown variable +#page(nonexistant) + +// Error: 17-20 aligned axis +#page(main-dir: ltr) + +// Flipped predefined paper. +#page("a11", flip: true)[Flipped A11] + +// Flipped custom page size. +#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) +Right to left! + +--- +// Test a combination of pages with bodies and normal content. + +#page(height: 50pt) + +#page[First] +#page[Second] +#pagebreak() +Fourth +#page[] +Sixth +#page[Seventh and last] diff --git a/tests/typ/library/pagebreak.typ b/tests/typ/library/pagebreak.typ new file mode 100644 index 00000000..dc3e5682 --- /dev/null +++ b/tests/typ/library/pagebreak.typ @@ -0,0 +1,3 @@ +First of two +#pagebreak() +#page(height: 40pt) diff --git a/tests/typ/library/rgb.typ b/tests/typ/library/rgb.typ new file mode 100644 index 00000000..b962bbc0 --- /dev/null +++ b/tests/typ/library/rgb.typ @@ -0,0 +1,17 @@ +// Check the output. +#rgb(0.0, 0.3, 0.7) + +// Alpha channel. +#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) + +// Error: 6-10 missing argument: blue component +#rgb(0, 1) + +// 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() diff --git a/tests/typ/markup/emph.typ b/tests/typ/markup/emph.typ new file mode 100644 index 00000000..772e15ab --- /dev/null +++ b/tests/typ/markup/emph.typ @@ -0,0 +1,14 @@ +// Test emphasis toggle. + +--- +// Basic. +_Emphasized!_ + +// Inside of words. +Partly em_phas_ized. + +// Scoped to body. +#box[_Scoped] to body. + +// Unterminated is fine. +_The End diff --git a/tests/typ/markup/escape.typ b/tests/typ/markup/escape.typ new file mode 100644 index 00000000..eeac4997 --- /dev/null +++ b/tests/typ/markup/escape.typ @@ -0,0 +1,30 @@ +// Test escape sequences. + +--- +// Escapable symbols. +\\ \/ \[ \] \{ \} \# \* \_ \= \~ \` \$ + +// No need to escape. +( ) ; < > + +// Unescapable. +\a \: \; \( \) + +// Escaped comments. +\// +\/\* \*\/ +\/* \*/ * + +// Unicode escape sequence. +\u{1F3D5} == 🏕 + +// Escaped escape sequence. +\u{41} vs. \\u\{41\} + +// Unicode codepoint does not exist. +// Error: 1-11 invalid unicode escape sequence +\u{FFFFFF} + +// Unterminated. +// Error: 6 expected closing brace +\u{41*Bold* diff --git a/tests/typ/markup/heading.typ b/tests/typ/markup/heading.typ new file mode 100644 index 00000000..8497ec8f --- /dev/null +++ b/tests/typ/markup/heading.typ @@ -0,0 +1,44 @@ +// Test headings. + +--- +// Different number of hashtags. + +// Valid levels. +=1 +===2 +======6 + +// Too many hashtags. +// Warning: 1-8 should not exceed depth 6 +=======7 + +--- +// Heading continuation over linebreak. + +// Code blocks continue heading. += A{ + "B" +} + +// Function call continues heading. += #box[ + A +] B + +// Without some kind of block, headings end at a line break. += A +B + +--- +// Heading vs. no heading. + +// Parsed as headings if at start of the context. +/**/ = Ok +{[== Ok]} +#box[=== Ok] + +// Not at the start of the context. +No = heading + +// Escaped. +\= No heading diff --git a/tests/typ/markup/linebreak.typ b/tests/typ/markup/linebreak.typ new file mode 100644 index 00000000..e6392992 --- /dev/null +++ b/tests/typ/markup/linebreak.typ @@ -0,0 +1,23 @@ +// Test forced line breaks. + +--- +// Directly after word. +Line\ Break + +// Spaces around. +Line \ Break + +// Directly before word does not work. +No \Break + +--- +// Leading line break. +\ Leading + +// Trailing before paragraph break. +Trailing 1 \ + +Trailing 2 + +// Trailing before end of document. +Trailing 3 \ diff --git a/tests/typ/markup/nbsp.typ b/tests/typ/markup/nbsp.typ new file mode 100644 index 00000000..5af6c84f --- /dev/null +++ b/tests/typ/markup/nbsp.typ @@ -0,0 +1,5 @@ +// Test the non breaking space. + +--- +// Parsed correctly, but not actually doing anything at the moment. +The non-breaking~space does not work. diff --git a/tests/typ/markup/raw.typ b/tests/typ/markup/raw.typ new file mode 100644 index 00000000..f5074c8e --- /dev/null +++ b/tests/typ/markup/raw.typ @@ -0,0 +1,51 @@ +// Test raw blocks. + +--- +// No extra space. +`A``B` + +--- +// Typst syntax inside. +`#let x = 1` \ +`#[f 1]` + +--- +// Multiline block splits paragraphs. + +First +``` +Second +``` +Third + +--- +// Lots of backticks inside. +```` +```backticks``` +```` + +--- +// Trimming. + +// Space between "rust" and "let" is trimmed. +The keyword ```rust let```. + +// Trimming depends on number backticks. +<``> \ +<` untrimmed `> \ +<``` trimmed` ```> \ +<``` trimmed ```> \ +<``` trimmed```> + +// Multiline trimming. +```py +import this + +def hi(): + print("Hi!") +``` + +--- +// Unterminated. +// Error: 2:1 expected backtick(s) +`endless diff --git a/tests/typ/markup/strong.typ b/tests/typ/markup/strong.typ new file mode 100644 index 00000000..b02a55a5 --- /dev/null +++ b/tests/typ/markup/strong.typ @@ -0,0 +1,14 @@ +// Test strong toggle. + +--- +// Basic. +*Strong!* + +// Inside of words. +Partly str*ength*ened. + +// Scoped to body. +#box[*Scoped] to body. + +// Unterminated is fine. +*The End diff --git a/tests/typ/repr.typ b/tests/typ/repr.typ new file mode 100644 index 00000000..666db428 --- /dev/null +++ b/tests/typ/repr.typ @@ -0,0 +1,50 @@ +// Test representation of values in the document. + +--- +// Variables. + +#let name = "Typst" +#let ke-bab = "Kebab!" +#let α = "Alpha" + +{name} \ +{ke-bab} \ +{α} \ + +// Error: 2-3 unknown variable +{_} + +--- +// Literal values. +{none} (empty) \ +{true} \ +{false} \ + +--- +// Numerical values. +{1} \ +{1.0e-4} \ +{3.15} \ +{1e-10} \ +{50.368%} \ +{0.0000012345pt} \ +{4.5cm} \ +{12e1pt} \ +{2.5rad} \ +{45deg} \ + +// Not in monospace via repr. +#repr(45deg) + +--- +// Colors. +{#f7a20500} \ + +--- +// Strings and escaping. +{"hi"} \ +{"a\n[]\"\u{1F680}string"} \ + +--- +// Templates. +{[*{"H" + "i"} there*]} diff --git a/tests/typ/spacing.typ b/tests/typ/spacing.typ new file mode 100644 index 00000000..d44cd84c --- /dev/null +++ b/tests/typ/spacing.typ @@ -0,0 +1,27 @@ +// Test spacing around control flow structures. + +--- +// Spacing around let. + +// Error: 6 expected identifier +A#let;B \ +A#let x = 1;B #test(x, 1) \ +A #let x = 2;B #test(x, 2) \ +A#let x = 3; B #test(x, 3) \ + +--- +// Spacing around if-else. + +A#if true[B]C \ +A#if true[B] C \ +A #if true{"B"}C \ +A #if true{"B"} C \ +A#if false [] #else [B]C \ +A#if true [B] #else [] C \ + +--- +// Spacing around for loop. + +A#for _ in (none,) [B]C \ +A#for _ in (none,) [B] C \ +A #for _ in (none,) [B]C \ diff --git a/tests/typ/text.typ b/tests/typ/text.typ new file mode 100644 index 00000000..d86f4895 --- /dev/null +++ b/tests/typ/text.typ @@ -0,0 +1,8 @@ +// Test simple text. + +--- +Hello 🌏! + +--- +// Some code stuff in text. +let f() , ; : | + - /= == 12 "string" |
