diff options
| author | Laurenz <laurmaedje@gmail.com> | 2024-02-27 11:05:16 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-27 10:05:16 +0000 |
| commit | 145723b1ef4fa23f1f6665b8907dfe79d0bf83cf (patch) | |
| tree | 02a7de661ddd5dafa75dfce3e3c8b45a7333b9dc /tests/typ/meta | |
| parent | e9ee00a7c0df083663ff5ccca162238b88525e14 (diff) | |
New context system (#3497)
Diffstat (limited to 'tests/typ/meta')
| -rw-r--r-- | tests/typ/meta/context-compatibility.typ | 29 | ||||
| -rw-r--r-- | tests/typ/meta/context.typ | 181 | ||||
| -rw-r--r-- | tests/typ/meta/counter.typ | 18 | ||||
| -rw-r--r-- | tests/typ/meta/figure-caption.typ | 2 | ||||
| -rw-r--r-- | tests/typ/meta/query-before-after.typ | 7 | ||||
| -rw-r--r-- | tests/typ/meta/query-figure.typ | 6 | ||||
| -rw-r--r-- | tests/typ/meta/query-header.typ | 20 | ||||
| -rw-r--r-- | tests/typ/meta/state.typ | 26 |
8 files changed, 248 insertions, 41 deletions
diff --git a/tests/typ/meta/context-compatibility.typ b/tests/typ/meta/context-compatibility.typ new file mode 100644 index 00000000..60124255 --- /dev/null +++ b/tests/typ/meta/context-compatibility.typ @@ -0,0 +1,29 @@ +// Test compatibility with the pre-context way of things. +// Ref: false + +--- +#let s = state("x", 0) +#let compute(expr) = [ + #s.update(x => + eval(expr.replace("x", str(x))) + ) + New value is #s.display(). +] + +#locate(loc => { + let elem = query(<here>, loc).first() + test(s.at(elem.location()), 13) +}) + +#compute("10") \ +#compute("x + 3") \ +*Here.* <here> \ +#compute("x * 2") \ +#compute("x - 5") + +--- +#style(styles => measure([it], styles).width < 20pt) + +--- +#counter(heading).update(10) +#counter(heading).display(n => test(n, 10)) diff --git a/tests/typ/meta/context.typ b/tests/typ/meta/context.typ new file mode 100644 index 00000000..729d9fa2 --- /dev/null +++ b/tests/typ/meta/context.typ @@ -0,0 +1,181 @@ +// Test context expressions. +// Ref: false + +--- +// Test that context body is parsed as atomic expression. +#let c = [#context "hello".] +#test(c.children.first().func(), (context none).func()) +#test(c.children.last(), [.]) + +--- +// Test that manual construction is forbidden. +// Error: 2-25 cannot be constructed manually +#(context none).func()() + +--- +// Test that `here()` yields the context element's location. +#context test(query(here()).first().func(), (context none).func()) + +--- +// Test whether context is retained in nested function. +#let translate(..args) = args.named().at(text.lang) +#set text(lang: "de") +#context test(translate(de: "Inhalt", en: "Contents"), "Inhalt") + +--- +// Test whether context is retained in built-in callback. +#set text(lang: "de") +#context test( + ("en", "de", "fr").sorted(key: v => v != text.lang), + ("de", "en", "fr"), +) + +--- +// Test `locate` + `here`. +#context test(here().position().y, 10pt) + +--- +// Test `locate`. +#v(10pt) += Introduction <intro> +#context test(locate(<intro>).position().y, 20pt) + +--- +// Error: 10-25 label `<intro>` does not exist in the document +#context locate(<intro>) + +--- += Introduction <intro> += Introduction <intro> + +// Error: 10-25 label `<intro>` occurs multiple times in the document +#context locate(<intro>) + +--- +#v(10pt) += Introduction <intro> +#context test(locate(heading).position().y, 20pt) + +--- +// Error: 10-25 selector does not match any element +#context locate(heading) + +--- += Introduction <intro> += Introduction <intro> + +// Error: 10-25 selector matches multiple elements +#context locate(heading) + +--- +// Test `counter`. +#let c = counter("heading") +#c.update(2) +#c.update(n => n + 2) +#context test(c.get(), (4,)) +#c.update(n => n - 3) +#context test(c.at(here()), (1,)) + +--- +// Test `state.at` outside of context. +// Error: 2-26 can only be used when context is known +// Hint: 2-26 try wrapping this in a `context` expression +// Hint: 2-26 the `context` expression should wrap everything that depends on this function +#state("key").at(<label>) + +--- +// Test `counter.at` outside of context. +// Error: 2-28 can only be used when context is known +// Hint: 2-28 try wrapping this in a `context` expression +// Hint: 2-28 the `context` expression should wrap everything that depends on this function +#counter("key").at(<label>) + +--- +// Test `measure`. +#let f(lo, hi) = context { + let h = measure[Hello].height + assert(h > lo) + assert(h < hi) +} +#text(10pt, f(6pt, 8pt)) +#text(20pt, f(13pt, 14pt)) + +--- +// Test basic get rule. +#context test(text.lang, "en") +#set text(lang: "de") +#context test(text.lang, "de") +#text(lang: "es", context test(text.lang, "es")) + +--- +// Test folding. +#set rect(stroke: red) +#context { + test(type(rect.stroke), stroke) + test(rect.stroke.paint, red) +} +#[ + #set rect(stroke: 4pt) + #context test(rect.stroke, 4pt + red) +] +#context test(rect.stroke, stroke(red)) + +--- +// We have one collision: `figure.caption` could be both the element and a get +// rule for the `caption` field, which is settable. We always prefer the +// element. It's unfortunate, but probably nobody writes +// `set figure(caption: ..)` anyway. +#test(type(figure.caption), function) +#context test(type(figure.caption), function) + +--- +// Error: 10-31 Assertion failed: "en" != "de" +#context test(text.lang, "de") + +--- +// Error: 15-20 function `text` does not contain field `langs` +#context text.langs + +--- +// Error: 18-22 function `heading` does not contain field `body` +#context heading.body + +--- +// Error: 7-11 can only be used when context is known +// Hint: 7-11 try wrapping this in a `context` expression +// Hint: 7-11 the `context` expression should wrap everything that depends on this function +#text.lang + +--- +// Error: 7-12 function `text` does not contain field `langs` +#text.langs + +--- +// Error: 10-14 function `heading` does not contain field `body` +#heading.body + +--- +// Test that show rule establishes context. +#set heading(numbering: "1.") +#show heading: it => test( + counter(heading).get(), + (intro: (1,), back: (2,)).at(str(it.label)), +) + += Introduction <intro> += Background <back> + +--- +// Test that show rule on non-locatable element allows `query`. +// Error: 18-47 Assertion failed: 2 != 3 +#show emph: _ => test(query(heading).len(), 3) +#show strong: _ => test(query(heading).len(), 2) += Introduction += Background +*Hi* _there_ + +--- +// Test error when captured variable is assigned to. +#let i = 0 +// Error: 11-12 variables from outside the context expression are read-only and cannot be modified +#context (i = 1) diff --git a/tests/typ/meta/counter.typ b/tests/typ/meta/counter.typ index 6b5797de..6d72f246 100644 --- a/tests/typ/meta/counter.typ +++ b/tests/typ/meta/counter.typ @@ -4,21 +4,21 @@ // Count with string key. #let mine = counter("mine!") -Final: #locate(loc => mine.final(loc).at(0)) \ +Final: #context mine.final().at(0) \ #mine.step() -First: #mine.display() \ +First: #context mine.display() \ #mine.update(7) -#mine.display("1 of 1", both: true) \ +#context mine.display("1 of 1", both: true) \ #mine.step() #mine.step() -Second: #mine.display("I") +Second: #context mine.display("I") #mine.update(n => n * 2) #mine.step() --- // Count labels. #let label = <heya> -#let count = counter(label).display() +#let count = context counter(label).display() #let elem(it) = [#box(it) #label] #elem[hey, there!] #count \ @@ -31,17 +31,17 @@ Second: #mine.display("I") #counter(heading).step() = Alpha -In #counter(heading).display() +In #context counter(heading).display() == Beta #set heading(numbering: none) = Gamma #heading(numbering: "I.")[Delta] -At Beta, it was #locate(loc => { - let it = query(heading, loc).find(it => it.body == [Beta]) +At Beta, it was #context { + let it = query(heading).find(it => it.body == [Beta]) numbering(it.numbering, ..counter(heading).at(it.location())) -}) +} --- // Count figures. diff --git a/tests/typ/meta/figure-caption.typ b/tests/typ/meta/figure-caption.typ index 0188ebca..0cdc2bbb 100644 --- a/tests/typ/meta/figure-caption.typ +++ b/tests/typ/meta/figure-caption.typ @@ -45,7 +45,7 @@ #show figure.caption: it => emph[ #it.body (#it.supplement - #it.counter.display(it.numbering)) + #context it.counter.display(it.numbering)) ] #figure( diff --git a/tests/typ/meta/query-before-after.typ b/tests/typ/meta/query-before-after.typ index 3ddc9402..5f134093 100644 --- a/tests/typ/meta/query-before-after.typ +++ b/tests/typ/meta/query-before-after.typ @@ -57,12 +57,11 @@ #set heading(outlined: true, numbering: "1.") -// This is purposefully an empty -#locate(loc => [ +#context [ Non-outlined elements: - #(query(selector(heading).and(heading.where(outlined: false)), loc) + #(query(selector(heading).and(heading.where(outlined: false))) .map(it => it.body).join(", ")) -]) +] #heading("A", outlined: false) #heading("B", outlined: true) diff --git a/tests/typ/meta/query-figure.typ b/tests/typ/meta/query-figure.typ index 0540d65a..590c8e87 100644 --- a/tests/typ/meta/query-figure.typ +++ b/tests/typ/meta/query-figure.typ @@ -11,8 +11,8 @@ #show figure: set image(width: 80%) = List of Figures -#locate(it => { - let elements = query(selector(figure).after(it), it) +#context { + let elements = query(selector(figure).after(here())) for it in elements [ Figure #numbering(it.numbering, @@ -21,7 +21,7 @@ #box(width: 1fr, repeat[.]) #counter(page).at(it.location()).first() \ ] -}) +} #figure( image("/files/glacier.jpg"), diff --git a/tests/typ/meta/query-header.typ b/tests/typ/meta/query-header.typ index dd83c128..5cbaa995 100644 --- a/tests/typ/meta/query-header.typ +++ b/tests/typ/meta/query-header.typ @@ -4,19 +4,17 @@ #set page( paper: "a7", margin: (y: 1cm, x: 0.5cm), - header: { + header: context { smallcaps[Typst Academy] h(1fr) - locate(it => { - let after = query(selector(heading).after(it), it) - let before = query(selector(heading).before(it), it) - let elem = if before.len() != 0 { - before.last() - } else if after.len() != 0 { - after.first() - } - emph(elem.body) - }) + let after = query(selector(heading).after(here())) + let before = query(selector(heading).before(here())) + let elem = if before.len() != 0 { + before.last() + } else if after.len() != 0 { + after.first() + } + emph(elem.body) } ) diff --git a/tests/typ/meta/state.typ b/tests/typ/meta/state.typ index 86dc70a5..3fa8ece7 100644 --- a/tests/typ/meta/state.typ +++ b/tests/typ/meta/state.typ @@ -9,20 +9,20 @@ $ 2 + 3 $ #s.update(double) -Is: #s.display(), -Was: #locate(location => { - let it = query(math.equation, location).first() +Is: #context s.get(), +Was: #context { + let it = query(math.equation).first() s.at(it.location()) -}). +}. --- // Try same key with different initial value. -#state("key", 2).display() +#context state("key", 2).get() #state("key").update(x => x + 1) -#state("key", 2).display() -#state("key", 3).display() +#context state("key", 2).get() +#context state("key", 3).get() #state("key").update(x => x + 1) -#state("key", 2).display() +#context state("key", 2).get() --- #set page(width: 200pt) @@ -30,15 +30,15 @@ Was: #locate(location => { #let ls = state("lorem", lorem(1000).split(".")) #let loremum(count) = { - ls.display(list => list.slice(0, count).join(".").trim() + ".") + context ls.get().slice(0, count).join(".").trim() + "." ls.update(list => list.slice(count)) } #let fs = state("fader", red) #let trait(title) = block[ - #fs.display(color => text(fill: color)[ + #context text(fill: fs.get())[ *#title:* #loremum(1) - ]) + ] #fs.update(color => color.lighten(30%)) ] @@ -52,5 +52,5 @@ Was: #locate(location => { // Warning: layout did not converge within 5 attempts // Hint: check if any states or queries are updating themselves #let s = state("s", 1) -#locate(loc => s.update(s.final(loc) + 1)) -#s.display() +#context s.update(s.final() + 1) +#context s.get() |
