diff options
Diffstat (limited to 'tests/suite/text')
| -rw-r--r-- | tests/suite/text/case.typ | 11 | ||||
| -rw-r--r-- | tests/suite/text/coma.typ | 26 | ||||
| -rw-r--r-- | tests/suite/text/copy-paste.typ | 8 | ||||
| -rw-r--r-- | tests/suite/text/deco.typ | 85 | ||||
| -rw-r--r-- | tests/suite/text/edge.typ | 39 | ||||
| -rw-r--r-- | tests/suite/text/em.typ | 33 | ||||
| -rw-r--r-- | tests/suite/text/font.typ | 66 | ||||
| -rw-r--r-- | tests/suite/text/lang.typ | 74 | ||||
| -rw-r--r-- | tests/suite/text/lorem.typ | 32 | ||||
| -rw-r--r-- | tests/suite/text/raw.typ | 630 | ||||
| -rw-r--r-- | tests/suite/text/shift.typ | 19 | ||||
| -rw-r--r-- | tests/suite/text/smallcaps.typ | 3 | ||||
| -rw-r--r-- | tests/suite/text/smartquote.typ | 122 | ||||
| -rw-r--r-- | tests/suite/text/space.typ | 60 |
14 files changed, 1208 insertions, 0 deletions
diff --git a/tests/suite/text/case.typ b/tests/suite/text/case.typ new file mode 100644 index 00000000..2bf68bc3 --- /dev/null +++ b/tests/suite/text/case.typ @@ -0,0 +1,11 @@ +// Test the `upper` and `lower` functions. + +--- lower-and-upper --- +#let memes = "ArE mEmEs gReAt?"; +#test(lower(memes), "are memes great?") +#test(upper(memes), "ARE MEMES GREAT?") +#test(upper("Ελλάδα"), "ΕΛΛΆΔΑ") + +--- upper-bad-type --- +// Error: 8-9 expected string or content, found integer +#upper(1) diff --git a/tests/suite/text/coma.typ b/tests/suite/text/coma.typ new file mode 100644 index 00000000..df757633 --- /dev/null +++ b/tests/suite/text/coma.typ @@ -0,0 +1,26 @@ +--- coma --- +// LARGE +#set page(width: 450pt, margin: 1cm) + +*Technische Universität Berlin* #h(1fr) *WiSe 2019/2020* \ +*Fakultät II, Institut for Mathematik* #h(1fr) Woche 3 \ +Sekretariat MA \ +Dr. Max Mustermann \ +Ola Nordmann, John Doe + +#v(3mm) +#align(center)[ + #set par(leading: 3mm) + #text(1.2em)[*3. Übungsblatt Computerorientierte Mathematik II*] \ + *Abgabe: 03.05.2019* (bis 10:10 Uhr in MA 001) \ + *Alle Antworten sind zu beweisen.* +] + +*1. Aufgabe* #h(1fr) (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. + +#align(center, image("/assets/images/graph.png", width: 75%)) diff --git a/tests/suite/text/copy-paste.typ b/tests/suite/text/copy-paste.typ new file mode 100644 index 00000000..ff6da893 --- /dev/null +++ b/tests/suite/text/copy-paste.typ @@ -0,0 +1,8 @@ +// Test copy-paste and search in PDF with ligatures +// and Arabic test. Must be tested manually! + +--- text-copy-paste-ligatures --- +The after fira 🏳️🌈! + +#set text(lang: "ar", font: "Noto Sans Arabic") +مرحبًا diff --git a/tests/suite/text/deco.typ b/tests/suite/text/deco.typ new file mode 100644 index 00000000..07fdb6c1 --- /dev/null +++ b/tests/suite/text/deco.typ @@ -0,0 +1,85 @@ +// Test text decorations. + +--- underline-overline-strike --- +#let red = rgb("fc0030") + +// Basic strikethrough. +#strike[Statements dreamt up by the utterly deranged.] + +// Move underline down. +#underline(offset: 5pt)[Further below.] + +// Different color. +#underline(stroke: red, evade: false)[Critical information is conveyed here.] + +// Inherits font color. +#text(fill: red, underline[Change with the wind.]) + +// Both over- and underline. +#overline(underline[Running amongst the wolves.]) + +--- strike-with --- +#let redact = strike.with(stroke: 10pt, extent: 0.05em) +#let highlight-custom = strike.with(stroke: 10pt + rgb("abcdef88"), extent: 0.05em) + +// Abuse thickness and transparency for redacting and highlighting stuff. +Sometimes, we work #redact[in secret]. +There might be #highlight-custom[redacted] things. + +--- underline-stroke-folding --- +// Test stroke folding. +#set underline(stroke: 2pt, offset: 2pt) +#underline(text(red, [DANGER!])) + +--- underline-background --- +// Test underline background +#set underline(background: true, stroke: (thickness: 0.5em, paint: red, cap: "round")) +#underline[This is in the background] + +--- overline-background --- +// Test overline background +#set overline(background: true, stroke: (thickness: 0.5em, paint: red, cap: "round")) +#overline[This is in the background] + +--- strike-background --- +// Test strike background +#set strike(background: true, stroke: 5pt + red) +#strike[This is in the background] + +--- highlight --- +// Test highlight. +This is the built-in #highlight[highlight with default color]. +We can also specify a customized value +#highlight(fill: green.lighten(80%))[to highlight]. + +--- highlight-bounds --- +// Test default highlight bounds. +#highlight[ace], +#highlight[base], +#highlight[super], +#highlight[phone #sym.integral] + +--- highlight-edges --- +// Test a tighter highlight. +#set highlight(top-edge: "x-height", bottom-edge: "baseline") +#highlight[ace], +#highlight[base], +#highlight[super], +#highlight[phone #sym.integral] + +--- highlight-edges-bounds --- +// Test a bounds highlight. +#set highlight(top-edge: "bounds", bottom-edge: "bounds") +#highlight[abc] +#highlight[abc #sym.integral] + +--- highlight-radius --- +// Test highlight radius +#highlight(radius: 3pt)[abc], +#highlight(radius: 1em)[#lorem(5)] + +--- highlight-stroke --- +// Test highlight stroke +#highlight(stroke: 2pt + blue)[abc] +#highlight(stroke: (top: blue, left: red, bottom: green, right: orange))[abc] +#highlight(stroke: 1pt, radius: 3pt)[#lorem(5)] diff --git a/tests/suite/text/edge.typ b/tests/suite/text/edge.typ new file mode 100644 index 00000000..57732156 --- /dev/null +++ b/tests/suite/text/edge.typ @@ -0,0 +1,39 @@ +// Test top and bottom text edge. + +--- text-edge --- +#set page(width: 160pt) +#set text(size: 8pt) + +#let try(top, bottom) = rect(inset: 0pt, fill: conifer)[ + #set text(font: "IBM Plex Mono", top-edge: top, bottom-edge: bottom) + From #top to #bottom +] + +#let try-bounds(top, bottom) = rect(inset: 0pt, fill: conifer)[ + #set text(font: "IBM Plex Mono", top-edge: top, bottom-edge: bottom) + #top to #bottom: "yay, Typst" +] + +#try("ascender", "descender") +#try("ascender", "baseline") +#try("cap-height", "baseline") +#try("x-height", "baseline") +#try-bounds("cap-height", "baseline") +#try-bounds("bounds", "baseline") +#try-bounds("bounds", "bounds") +#try-bounds("x-height", "bounds") + +#try(4pt, -2pt) +#try(1pt + 0.3em, -0.15em) + +--- text-edge-bad-type --- +// Error: 21-23 expected "ascender", "cap-height", "x-height", "baseline", "bounds", or length, found array +#set text(top-edge: ()) + +--- text-edge-bad-value --- +// Error: 24-26 expected "baseline", "descender", "bounds", or length +#set text(bottom-edge: "") + +--- text-edge-wrong-edge --- +// Error: 24-36 expected "baseline", "descender", "bounds", or length +#set text(bottom-edge: "cap-height") diff --git a/tests/suite/text/em.typ b/tests/suite/text/em.typ new file mode 100644 index 00000000..be7e3428 --- /dev/null +++ b/tests/suite/text/em.typ @@ -0,0 +1,33 @@ +// Test font-relative sizing. + +--- text-size-em-nesting --- +#set text(size: 5pt) +A // 5pt +#[ + #set text(size: 2em) + B // 10pt + #[ + #set text(size: 1.5em + 1pt) + C // 16pt + #text(size: 2em)[D] // 32pt + E // 16pt + ] + F // 10pt +] +G // 5pt + +--- text-size-em --- +// Test using ems in arbitrary places. +#set text(size: 5pt) +#set text(size: 2em) +#set square(fill: red) + +#let size = { + let size = 0.25em + 1pt + for _ in range(3) { + size *= 2 + } + size - 3pt +} + +#stack(dir: ltr, spacing: 1fr, square(size: size), square(size: 25pt)) diff --git a/tests/suite/text/font.typ b/tests/suite/text/font.typ new file mode 100644 index 00000000..47ec6419 --- /dev/null +++ b/tests/suite/text/font.typ @@ -0,0 +1,66 @@ +// Test configuring font properties. + +--- text-font-properties --- +// Set same font size in three different ways. +#text(20pt)[A] +#text(2em)[A] +#text(size: 15pt + 0.5em)[A] + +// Do nothing. +#text()[Normal] + +// Set style (is available). +#text(style: "italic")[Italic] + +// Set weight (is available). +#text(weight: "bold")[Bold] + +// Set stretch (not available, matching closest). +#text(stretch: 50%)[Condensed] + +// Set font family. +#text(font: "IBM Plex Serif")[Serif] + +// Emoji. +Emoji: 🐪, 🌋, 🏞 + +// Colors. +#[ + #set text(fill: eastern) + This is #text(rgb("FA644B"))[way more] colorful. +] + +// Transparency. +#block(fill: green)[ + #set text(fill: rgb("FF000080")) + This text is transparent. +] + +// Disable font fallback beyond the user-specified list. +// Without disabling, New Computer Modern Math would come to the rescue. +#set text(font: ("PT Sans", "Twitter Color Emoji"), fallback: false) +2π = 𝛼 + 𝛽. ✅ + +--- text-call-body --- +// Test string body. +#text("Text") \ +#text(red, "Text") \ +#text(font: "Ubuntu", blue, "Text") \ +#text([Text], teal, font: "IBM Plex Serif") \ +#text(forest, font: "New Computer Modern", [Text]) \ + +--- text-bad-argument --- +// Error: 11-16 unexpected argument +#set text(false) + +--- text-style-bad --- +// Error: 18-24 expected "normal", "italic", or "oblique" +#set text(style: "bold", weight: "thin") + +--- text-bad-extra-argument --- +// Error: 23-27 unexpected argument +#set text(size: 10pt, 12pt) + +--- text-bad-named-argument --- +// Error: 11-31 unexpected argument: something +#set text(something: "invalid") diff --git a/tests/suite/text/lang.typ b/tests/suite/text/lang.typ new file mode 100644 index 00000000..74f70140 --- /dev/null +++ b/tests/suite/text/lang.typ @@ -0,0 +1,74 @@ +// Test setting the document language. + +--- text-lang --- +// without any region +#set text(font: "Noto Serif CJK TC", lang: "zh") +#outline() + +--- text-lang-unknown-region --- +// with unknown region configured +#set text(font: "Noto Serif CJK TC", lang: "zh", region: "XX") +#outline() + +--- text-lang-region --- +// with region configured +#set text(font: "Noto Serif CJK TC", lang: "zh", region: "TW") +#outline() + +--- text-lang-hyphenate --- +// Ensure that setting the language does have effects. +#set text(hyphenate: true) +#grid( + columns: 2 * (20pt,), + gutter: 1fr, + text(lang: "en")["Eingabeaufforderung"], + text(lang: "de")["Eingabeaufforderung"], +) + +--- text-lang-shaping --- +// Test that the language passed to the shaper has an effect. +#set text(font: "Ubuntu") + +// Some lowercase letters are different in Serbian Cyrillic compared to other +// Cyrillic languages. Since there is only one set of Unicode codepoints for +// Cyrillic, these can only be seen when setting the language to Serbian and +// selecting one of the few fonts that support these letterforms. +Бб +#text(lang: "uk")[Бб] +#text(lang: "sr")[Бб] + +--- text-lang-script-shaping --- +// Verify that writing script/language combination has an effect +#{ + set text(size:20pt) + set text(script: "latn", lang: "en") + [Ş ] + set text(script: "latn", lang: "ro") + [Ş ] + set text(script: "grek", lang: "ro") + [Ş ] +} + +--- text-script-bad-type --- +// Error: 19-23 expected string or auto, found none +#set text(script: none) + +--- text-script-bad-value --- +// Error: 19-23 expected three or four letter script code (ISO 15924 or 'math') +#set text(script: "ab") + +--- text-lang-bad-type --- +// Error: 17-21 expected string, found none +#set text(lang: none) + +--- text-lang-bad-value --- +// Error: 17-20 expected two or three letter language code (ISO 639-1/2/3) +#set text(lang: "ӛ") + +--- text-lang-bad-value-emoji --- +// Error: 17-20 expected two or three letter language code (ISO 639-1/2/3) +#set text(lang: "😃") + +--- text-region-bad-value --- +// Error: 19-24 expected two letter region code (ISO 3166-1 alpha-2) +#set text(region: "hey") diff --git a/tests/suite/text/lorem.typ b/tests/suite/text/lorem.typ new file mode 100644 index 00000000..1524e2a3 --- /dev/null +++ b/tests/suite/text/lorem.typ @@ -0,0 +1,32 @@ +// Test blind text. + +--- lorem --- +// Test basic call. +#lorem(19) + +--- lorem-pars --- +// Test custom paragraphs with user code. +#set text(8pt) + +#{ + let sentences = lorem(59) + .split(".") + .filter(s => s != "") + .map(s => s + ".") + + let used = 0 + for s in sentences { + if used < 2 { + used += 1 + } else { + parbreak() + used = 0 + } + s.trim() + [ ] + } +} + +--- lorem-missing-words --- +// Error: 2-9 missing argument: words +#lorem() diff --git a/tests/suite/text/raw.typ b/tests/suite/text/raw.typ new file mode 100644 index 00000000..dce77fdb --- /dev/null +++ b/tests/suite/text/raw.typ @@ -0,0 +1,630 @@ +// Test raw blocks. + +--- raw-empty --- +// Empty raw block. +Empty raw block:``. + +--- raw-consecutive-single-backticks --- +// No extra space. +`A``B` + +--- raw-typst-lang --- +// Typst syntax inside. +```typ #let x = 1``` \ +```typ #f(1)``` + +--- raw-block-no-parbreaks --- +// Multiline block splits paragraphs. + +Text +```rust +fn code() {} +``` +Text + +--- raw-more-backticks --- +// Lots of backticks inside. +```` +```backticks``` +```` + +--- raw-trimming --- +// Trimming. + +// Space between "rust" and "let" is trimmed. +The keyword ```rust let```. + +// Trimming depends on number backticks. +(``) \ +(` untrimmed `) \ +(``` trimmed` ```) \ +(``` trimmed ```) \ +(``` trimmed```) \ + +--- raw-single-backtick-lang --- +// Single ticks should not have a language. +`rust let` + +--- raw-dedent-first-line --- +// First line is not dedented and leading space is still possible. + ``` A + B + C + ``` + +--- raw-dedent-empty-line --- +// Do not take empty lines into account when computing dedent. +``` + A + + B +``` + +--- raw-dedent-last-line --- +// Take last line into account when computing dedent. +``` + A + + B + ``` + +--- raw-tab-size --- +#set raw(tab-size: 8) + +```tsv +Year Month Day +2000 2 3 +2001 2 1 +2002 3 10 +``` + +--- raw-syntaxes --- +#set page(width: 180pt) +#set text(6pt) +#set raw(syntaxes: "/assets/syntaxes/SExpressions.sublime-syntax") + +```sexp +(defun factorial (x) + (if (zerop x) + ; with a comment + 1 + (* x (factorial (- x 1))))) +``` + + +--- raw-theme --- +// Test code highlighting with custom theme. +#set page(width: 180pt) +#set text(6pt) +#set raw(theme: "/assets/themes/halcyon.tmTheme") +#show raw: it => { + set text(fill: rgb("a2aabc")) + rect( + width: 100%, + inset: (x: 4pt, y: 5pt), + radius: 4pt, + fill: rgb("1d2433"), + place(right, text(luma(240), it.lang)) + it, + ) +} + +```typ += Chapter 1 +#lorem(100) + +#let hi = "Hello World" +#show heading: emph +``` + +--- raw-show-set --- +// Text show rule +#show raw: set text(font: "Roboto") +`Roboto` + +--- raw-align-default --- +// Text inside raw block should be unaffected by outer alignment by default. +#set align(center) +#set page(width: 180pt) +#set text(6pt) + +#lorem(20) + +```py +def something(x): + return x + +a = 342395823859823958329 +b = 324923 +``` + +#lorem(20) + +--- raw-align-specified --- +// Text inside raw block should follow the specified alignment. +#set page(width: 180pt) +#set text(6pt) + +#lorem(20) +#align(center, raw( + lang: "typ", + block: true, + align: right, + "#let f(x) = x\n#align(center, line(length: 1em))", +)) +#lorem(20) + +--- raw-align-invalid --- +// Error: 17-20 expected `start`, `left`, `center`, `right`, or `end`, found top +#set raw(align: top) + +--- raw-highlight-typ --- +// LARGE +#set page(width: auto) + +```typ +#set hello() +#set hello() +#set hello.world() +#set hello.my.world() +#let foo(x) = x * 2 +#show heading: func +#show module.func: func +#show module.func: it => {} +#foo(ident: ident) +#hello +#hello() +#box[] +#hello.world +#hello.world() +#hello().world() +#hello.my.world +#hello.my.world() +#hello.my().world +#hello.my().world() +#{ hello } +#{ hello() } +#{ hello.world() } +$ hello $ +$ hello() $ +$ box[] $ +$ hello.world $ +$ hello.world() $ +$ hello.my.world() $ +$ f_zeta(x), f_zeta(x)/1 $ +$ emph(hello.my.world()) $ +$ emph(hello.my().world) $ +$ emph(hello.my().world()) $ +$ #hello $ +$ #hello() $ +$ #hello.world $ +$ #hello.world() $ +$ #box[] $ +#if foo [] +``` + +--- raw-highlight --- +#set page(width: 180pt) +#set text(6pt) +#show raw: it => rect( + width: 100%, + inset: (x: 4pt, y: 5pt), + radius: 4pt, + fill: rgb(239, 241, 243), + place(right, text(luma(110), it.lang)) + it, +) + +```typ += Chapter 1 +#lorem(100) + +#let hi = "Hello World" +#show heading: emph +``` + +```rust +/// A carefully designed state machine. +#[derive(Debug)] +enum State<'a> { A(u8), B(&'a str) } + +fn advance(state: State<'_>) -> State<'_> { + unimplemented!("state machine") +} +``` + +```py +import this + +def hi(): + print("Hi!") +``` + +```cpp +#include <iostream> + +int main() { + std::cout << "Hello, world!"; +} +``` + +```julia +# Add two numbers +function add(x, y) + return x * y +end +``` + + // Try with some indent. + ```html + <!DOCTYPE html> + <html> + <head> + <meta charset="utf-8"> + </head> + <body> + <h1>Topic</h1> + <p>The Hypertext Markup Language.</p> + <script> + function foo(a, b) { + return a + b + "string"; + } + </script> + </body> + </html> + ``` + +--- raw-inline-multiline --- +#set page(width: 180pt) +#set text(6pt) +#set raw(lang:"python") + +Inline raws, multiline e.g. `for i in range(10): + # Only this line is a comment. + print(i)` or otherwise e.g. `print(j)`, are colored properly. + +Inline raws, multiline e.g. ` +# Appears blocky due to linebreaks at the boundary. +for i in range(10): + print(i) +` or otherwise e.g. `print(j)`, are colored properly. + +--- raw-blocky --- +// Test various raw parsing edge cases. +#let empty = ( + name: "empty", + input: ``, + text: "", +) + +#let backtick = ( + name: "backtick", + input: ``` ` ```, + text: "`", + block: false, +) + +#let lang-backtick = ( + name: "lang-backtick", + input: ```js ` ```, + lang: "js", + text: "`", + block: false, +) + +// The language tag stops on space +#let lang-space = ( + name: "lang-space", + input: ```js test ```, + lang: "js", + text: "test ", + block: false, +) + +// The language tag stops on newline +#let lang-newline = ( + name: "lang-newline", + input: ```js +test +```, + lang: "js", + text: "test", + block: true, +) + +// The first line and the last line are ignored +#let blocky = ( + name: "blocky", + input: { +``` +test +``` +}, + text: "test", + block: true, +) + +// A blocky raw should handle dedents +#let blocky-dedent = ( + name: "blocky-dedent", + input: { +``` + test + ``` + }, + text: "test", + block: true, +) + +// When there is content in the first line, it should exactly eat a whitespace char. +#let blocky-dedent-firstline = ( + name: "blocky-dedent-firstline", + input: ``` test + ```, + text: "test", + block: true, +) + +// When there is content in the first line, it should exactly eat a whitespace char. +#let blocky-dedent-firstline2 = ( + name: "blocky-dedent-firstline2", + input: ``` test +```, + text: "test", + block: true, +) + +// The first line is not affected by dedent, and the middle lines don't consider the whitespace prefix of the first line. +#let blocky-dedent-firstline3 = ( + name: "blocky-dedent-firstline3", + input: ``` test + test2 + ```, + text: "test\n test2", + block: true, +) + +// The first line is not affected by dedent, and the middle lines don't consider the whitespace prefix of the first line. +#let blocky-dedent-firstline4 = ( + name: "blocky-dedent-firstline4", + input: ``` test + test2 + ```, + text: " test\ntest2", + block: true, +) + +#let blocky-dedent-lastline = ( + name: "blocky-dedent-lastline", + input: ``` + test + ```, + text: " test", + block: true, +) + +#let blocky-dedent-lastline2 = ( + name: "blocky-dedent-lastline2", + input: ``` + test + ```, + text: "test", + block: true, +) + +#let blocky-tab = ( + name: "blocky-tab", + input: { +``` + test +``` +}, + text: "\ttest", + block: true, +) + +// This one is a bit problematic because there is a trailing tab below "test" +// which the editor constantly wants to remove. +#let blocky-tab-dedent = ( + name: "blocky-tab-dedent", + input: eval("```\n\ttest\n \n ```"), + text: "test\n ", + block: true, +) + +#let cases = ( + empty, + backtick, + lang-backtick, + lang-space, + lang-newline, + blocky, + blocky-dedent, + blocky-dedent-firstline, + blocky-dedent-firstline2, + blocky-dedent-firstline3, + blocky-dedent-lastline, + blocky-dedent-lastline2, + blocky-tab, + blocky-tab-dedent, +) + +#for c in cases { + assert.eq(c.text, c.input.text, message: "in point " + c.name + ", expect " + repr(c.text) + ", got " + repr(c.input.text) + "") + let block = c.at("block", default: false) + assert.eq(block, c.input.block, message: "in point " + c.name + ", expect " + repr(block) + ", got " + repr(c.input.block) + "") +} + +--- raw-line --- +#set page(width: 200pt) + +```rs +fn main() { + println!("Hello, world!"); +} +``` + +#show raw.line: it => { + box(stack( + dir: ltr, + box(width: 15pt)[#it.number], + it.body, + )) + linebreak() +} + +```rs +fn main() { + println!("Hello, world!"); +} +``` + +--- raw-line-alternating-fill --- +#set page(width: 200pt) +#show raw: it => stack(dir: ttb, ..it.lines) +#show raw.line: it => { + box( + width: 100%, + height: 1.75em, + inset: 0.25em, + fill: if calc.rem(it.number, 2) == 0 { + luma(90%) + } else { + white + }, + align(horizon, stack( + dir: ltr, + box(width: 15pt)[#it.number], + it.body, + )) + ) +} + +```typ +#show raw.line: block.with( + fill: luma(60%) +); + +Hello, world! + += A heading for good measure +``` + +--- raw-line-text-fill --- +#set page(width: 200pt) +#show raw.line: set text(fill: red) + +```py +import numpy as np + +def f(x): + return x**2 + +x = np.linspace(0, 10, 100) +y = f(x) + +print(x) +print(y) +``` + +--- raw-line-scripting --- + +// Test line extraction works. + +#show raw: code => { + for i in code.lines { + test(i.count, 10) + } + + test(code.lines.at(0).text, "import numpy as np") + test(code.lines.at(1).text, "") + test(code.lines.at(2).text, "def f(x):") + test(code.lines.at(3).text, " return x**2") + test(code.lines.at(4).text, "") + test(code.lines.at(5).text, "x = np.linspace(0, 10, 100)") + test(code.lines.at(6).text, "y = f(x)") + test(code.lines.at(7).text, "") + test(code.lines.at(8).text, "print(x)") + test(code.lines.at(9).text, "print(y)") + test(code.lines.at(10, default: none), none) +} + +```py +import numpy as np + +def f(x): + return x**2 + +x = np.linspace(0, 10, 100) +y = f(x) + +print(x) +print(y) +``` + +--- issue-3601-empty-raw --- +// Test that empty raw block with `typ` language doesn't cause a crash. +```typ +``` + +--- issue-3841-tabs-in-raw-type-code --- +// Tab chars were not rendered in raw blocks with lang: "typ(c)" +#raw("#if true {\n\tf()\t// typ\n}", lang: "typ") + +#raw("if true {\n\tf()\t// typc\n}", lang: "typc") + +```typ +#if true { + // tabs around f() + f() // typ +} +``` + +```typc +if true { + // tabs around f() + f() // typc +} +``` + +--- issue-2259-raw-color-overwrite --- +// Test that the color of a raw block is not overwritten +#show raw: set text(fill: blue) + +`Hello, World!` + +```rs +fn main() { + println!("Hello, World!"); +} +``` + +--- issue-3191-raw-indent-shrink --- +// Spaces in raw blocks should not be shrunk as it would mess up the indentation +// of code. +#set par(justify: true) + +#show raw.where(block: true): block.with( + fill: luma(240), + inset: 10pt, +) + +#block( + width: 60%, + ```py + for x in xs: + print("x=",x) + ``` +) + +--- issue-3191-raw-normal-paragraphs-still-shrink --- +// In normal paragraphs, spaces should still be shrunk. +// The first line here serves as a reference, while the second +// uses non-breaking spaces to create an overflowing line +// (which should shrink). +~~~~No shrinking here + +~~~~The~spaces~on~this~line~shrink + +--- raw-unclosed --- +// Unterminated. +// Error: 1-2:1 unclosed raw text +`endless diff --git a/tests/suite/text/shift.typ b/tests/suite/text/shift.typ new file mode 100644 index 00000000..090f6ee8 --- /dev/null +++ b/tests/suite/text/shift.typ @@ -0,0 +1,19 @@ +// Test sub- and superscipt shifts. + +--- sub-super --- +#table( + columns: 3, + [Typo.], [Fallb.], [Synth], + [x#super[1]], [x#super[5n]], [x#super[2 #box(square(size: 6pt))]], + [x#sub[1]], [x#sub[5n]], [x#sub[2 #box(square(size: 6pt))]], +) + +--- sub-super-non-typographic --- +#set super(typographic: false, baseline: -0.25em, size: 0.7em) +n#super[1], n#sub[2], ... n#super[N] + +--- super-underline --- +#set underline(stroke: 0.5pt, offset: 0.15em) +#underline[The claim#super[\[4\]]] has been disputed. \ +The claim#super[#underline[\[4\]]] has been disputed. \ +It really has been#super(box(text(baseline: 0pt, underline[\[4\]]))) \ diff --git a/tests/suite/text/smallcaps.typ b/tests/suite/text/smallcaps.typ new file mode 100644 index 00000000..6f977244 --- /dev/null +++ b/tests/suite/text/smallcaps.typ @@ -0,0 +1,3 @@ +--- smallcaps --- +// Test smallcaps. +#smallcaps[Smallcaps] diff --git a/tests/suite/text/smartquote.typ b/tests/suite/text/smartquote.typ new file mode 100644 index 00000000..28fcba5b --- /dev/null +++ b/tests/suite/text/smartquote.typ @@ -0,0 +1,122 @@ +--- smartquote --- +// LARGE +#set page(width: 250pt) + +// Test simple quotations in various languages. +#set text(lang: "en") +"The horse eats no cucumber salad" was the first sentence ever uttered on the 'telephone.' + +#set text(lang: "de") +"Das Pferd frisst keinen Gurkensalat" war der erste jemals am 'Fernsprecher' gesagte Satz. + +#set text(lang: "de", region: "CH") +"Das Pferd frisst keinen Gurkensalat" war der erste jemals am 'Fernsprecher' gesagte Satz. + +#set text(lang: "es", region: none) +"El caballo no come ensalada de pepino" fue la primera frase pronunciada por 'teléfono'. + +#set text(lang: "es", region: "MX") +"El caballo no come ensalada de pepino" fue la primera frase pronunciada por 'teléfono'. + +#set text(lang: "fr", region: none) +"Le cheval ne mange pas de salade de concombres" est la première phrase jamais prononcée au 'téléphone'. + +#set text(lang: "fi") +"Hevonen ei syö kurkkusalaattia" oli ensimmäinen koskaan 'puhelimessa' lausuttu lause. + +#set text(lang: "gr") +"Το άλογο δεν τρώει αγγουροσαλάτα" ήταν η πρώτη πρόταση που ειπώθηκε στο 'τηλέφωνο'. + +#set text(lang: "he") +"הסוס לא אוכל סלט מלפפונים" היה המשפט ההראשון שנאמר ב 'טלפון'. + +#set text(lang: "ro") +"Calul nu mănâncă salată de castraveți" a fost prima propoziție rostită vreodată la 'telefon'. + +#set text(lang: "ru") +"Лошадь не ест салат из огурцов" - это была первая фраза, сказанная по 'телефону'. + +--- smartquote-empty --- +// Test single pair of quotes. +"" + +--- smartquote-apostrophe --- +// Test sentences with numbers and apostrophes. +The 5'11" 'quick' brown fox jumps over the "lazy" dog's ear. + +He said "I'm a big fella." + +--- smartquote-escape --- +// Test escape sequences. +The 5\'11\" 'quick\' brown fox jumps over the \"lazy" dog\'s ear. + +--- smartquote-disable --- +// Test turning smart quotes off. +He's told some books contain questionable "example text". + +#set smartquote(enabled: false) +He's told some books contain questionable "example text". + +--- smartquote-disabled-temporarily --- +// Test changing properties within text. +"She suddenly started speaking french: #text(lang: "fr")['Je suis une banane.']" Roman told me. + +Some people's thought on this would be #[#set smartquote(enabled: false); "strange."] + +--- smartquote-nesting --- +// Test nested double and single quotes. +"'test statement'" \ +"'test' statement" \ +"statement 'test'" + +--- smartquote-custom --- +// Use language quotes for missing keys, allow partial reset +#set smartquote(quotes: "«»") +"Double and 'Single' Quotes" + +#set smartquote(quotes: (double: auto, single: "«»")) +"Double and 'Single' Quotes" + +--- smartquote-custom-complex --- +// Allow 2 graphemes +#set smartquote(quotes: "a\u{0301}a\u{0301}") +"Double and 'Single' Quotes" + +#set smartquote(quotes: (single: "a\u{0301}a\u{0301}")) +"Double and 'Single' Quotes" + +--- smartquote-custom-bad-string --- +// Error: 25-28 expected 2 characters, found 1 character +#set smartquote(quotes: "'") + +--- smartquote-custom-bad-array --- +// Error: 25-35 expected 2 quotes, found 4 quotes +#set smartquote(quotes: ("'",) * 4) + +--- smartquote-custom-bad-dict --- +// Error: 25-45 expected 2 quotes, found 4 quotes +#set smartquote(quotes: (single: ("'",) * 4)) + +--- issue-3662-pdf-smartquotes --- +// Smart quotes were not appearing in the PDF outline, because they didn't +// implement `PlainText`. += It's "Unnormal Heading" += It’s “Normal Heading” + +#set smartquote(enabled: false) += It's "Unnormal Heading" += It's 'single quotes' += It’s “Normal Heading” + +--- issue-1041-smartquotes-in-outline --- +#set page(width: 15em) +#outline() + += "This" "is" "a" "test" + +--- issue-1540-smartquotes-across-newlines --- +// Test that smart quotes are inferred correctly across newlines. +"test"#linebreak()"test" + +"test"\ +"test" diff --git a/tests/suite/text/space.typ b/tests/suite/text/space.typ new file mode 100644 index 00000000..97541e38 --- /dev/null +++ b/tests/suite/text/space.typ @@ -0,0 +1,60 @@ +// Test whitespace handling. + +--- space-collapsing --- +// Spacing around code constructs. +A#let x = 1;B #test(x, 1) \ +C #let x = 2;D #test(x, 2) \ +E#if true [F]G \ +H #if true{"I"} J \ +K #if true [L] else []M \ +#let c = true; N#while c [#(c = false)O] P \ +#let c = true; Q #while c { c = false; "R" } S \ +T#for _ in (none,) {"U"}V +#let foo = "A" ; \ +#foo;B \ +#foo; B \ +#foo ;B + +--- space-collapsing-comments --- +// Test spacing with comments. +A/**/B/**/C \ +A /**/ B/**/C \ +A /**/B/**/ C + +--- space-collapsing-with-h --- +// Test spacing collapsing before spacing. +#set align(right) +A #h(0pt) B #h(0pt) \ +A B \ +A #h(-1fr) B + +--- text-font-just-a-space --- +// Test that a run consisting only of whitespace isn't trimmed. +A#text(font: "IBM Plex Serif")[ ]B + +--- text-font-change-after-space --- +// Test font change after space. +Left #text(font: "IBM Plex Serif")[Right]. + +--- space-collapsing-linebreaks --- +// Test that linebreak consumed surrounding spaces. +#align(center)[A \ B \ C] + +--- space-collapsing-stringy-linebreak --- +// Test that space at start of non-backslash-linebreak line isn't trimmed. +A#"\n" B + +--- space-trailing-linebreak --- +// Test that trailing space does not force a line break. +LLLLLLLLLLLLLLLLLL R _L_ + +--- space-ideographic-kept --- +// Test that ideographic spaces are preserved. +#set text(lang: "ja", font: "Noto Serif CJK JP") + +だろうか? 何のために! 私は、 + +--- space-thin-kept --- +// Test that thin spaces are preserved. +| | U+0020 regular space \ +| | U+2009 thin space |
