Make use of wide calls

This commit is contained in:
Laurenz 2021-06-29 13:45:59 +02:00
parent b89cd128ae
commit 32a6b673bc
22 changed files with 90 additions and 111 deletions

View File

@ -72,10 +72,10 @@ impl Exec for syntax::RawNode {
ctx.parbreak();
}
let snapshot = ctx.state.clone();
let snapshot = Rc::clone(&ctx.state.font);
ctx.set_monospace();
ctx.push_text(&self.text);
ctx.state = snapshot;
ctx.state.font = snapshot;
if self.block {
ctx.parbreak();
@ -85,16 +85,17 @@ impl Exec for syntax::RawNode {
impl ExecWithMap for syntax::HeadingNode {
fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) {
ctx.parbreak();
let snapshot = ctx.state.clone();
let font = ctx.state.font_mut();
let upscale = 1.6 - 0.1 * self.level as f64;
font.size *= upscale;
font.strong = true;
self.body.exec_with_map(ctx, map);
ctx.state = snapshot;
ctx.parbreak();
}
}
@ -113,8 +114,6 @@ impl ExecWithMap for syntax::EnumItem {
}
fn exec_item(ctx: &mut ExecContext, label: String, body: &syntax::Tree, map: &ExprMap) {
ctx.parbreak();
let label = ctx.exec_stack(|ctx| ctx.push_text(label));
let body = ctx.exec_tree_stack(body, map);
let stack = StackNode {
@ -128,7 +127,6 @@ fn exec_item(ctx: &mut ExecContext, label: String, body: &syntax::Tree, map: &Ex
};
ctx.push_into_stack(stack);
ctx.parbreak();
}
impl Exec for Value {
@ -172,6 +170,8 @@ impl Exec for TemplateNode {
impl Exec for TemplateFunc {
fn exec(&self, ctx: &mut ExecContext) {
let snapshot = ctx.state.clone();
self(ctx);
ctx.state = snapshot;
}
}

View File

@ -20,7 +20,7 @@ pub fn page(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let right = args.named(ctx, "right");
let bottom = args.named(ctx, "bottom");
let flip = args.named(ctx, "flip");
let body = args.eat::<TemplateValue>(ctx);
let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
let snapshot = ctx.state.clone();
@ -66,13 +66,10 @@ pub fn page(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
ctx.pagebreak(false, true, span);
body.exec(ctx);
if let Some(body) = &body {
// TODO: Restrict body to a single page?
body.exec(ctx);
ctx.state = snapshot;
ctx.pagebreak(true, false, span);
}
ctx.state = snapshot;
ctx.pagebreak(true, false, span);
})
}
@ -111,7 +108,7 @@ pub fn align(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let second = args.eat::<AlignValue>(ctx);
let mut horizontal = args.named::<AlignValue>(ctx, "horizontal");
let mut vertical = args.named::<AlignValue>(ctx, "vertical");
let body = args.eat::<TemplateValue>(ctx);
let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default();
for value in first.into_iter().chain(second) {
match value.axis() {
@ -126,23 +123,19 @@ pub fn align(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
Value::template(move |ctx| {
let snapshot = ctx.state.clone();
if let Some(horizontal) = horizontal {
ctx.state.aligns.cross = horizontal.to_align(ctx.state.lang.dir);
}
if let Some(vertical) = vertical {
ctx.state.aligns.main = vertical.to_align(Dir::TTB);
if ctx.state.aligns.main != snapshot.aligns.main {
let new = vertical.to_align(Dir::TTB);
if ctx.state.aligns.main != new {
ctx.state.aligns.main = new;
ctx.parbreak();
}
}
if let Some(body) = &body {
body.exec(ctx);
ctx.state = snapshot;
}
body.exec(ctx);
})
}

View File

@ -17,10 +17,9 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let serif = args.named(ctx, "serif");
let sans_serif = args.named(ctx, "sans-serif");
let monospace = args.named(ctx, "monospace");
let body = args.eat::<TemplateValue>(ctx);
let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
let snapshot = ctx.state.clone();
let font = ctx.state.font_mut();
if let Some(linear) = size {
@ -67,10 +66,7 @@ pub fn font(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
font.families_mut().monospace = monospace.clone();
}
if let Some(body) = &body {
body.exec(ctx);
ctx.state = snapshot;
}
body.exec(ctx);
})
}
@ -161,6 +157,7 @@ pub fn par(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
let spacing = args.named(ctx, "spacing");
let leading = args.named(ctx, "leading");
let word_spacing = args.named(ctx, "word-spacing");
let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
if let Some(spacing) = spacing {
@ -176,6 +173,7 @@ pub fn par(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
ctx.parbreak();
body.exec(ctx);
})
}
@ -190,6 +188,7 @@ pub fn lang(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
None => None,
};
let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default();
Value::template(move |ctx| {
if let Some(dir) = dir.or(iso) {
@ -197,6 +196,7 @@ pub fn lang(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value {
}
ctx.parbreak();
body.exec(ctx);
})
}
@ -232,7 +232,7 @@ fn line_impl(
let position = args.named(ctx, "position");
let strength = args.named::<Linear>(ctx, "strength");
let extent = args.named(ctx, "extent").unwrap_or_default();
let body = args.eat::<TemplateValue>(ctx);
let body = args.expect::<TemplateValue>(ctx, "body").unwrap_or_default();
// Suppress any existing strikethrough if strength is explicitly zero.
let state = strength.map_or(true, |s| !s.is_zero()).then(|| {
@ -245,13 +245,7 @@ fn line_impl(
});
Value::template(move |ctx| {
let snapshot = ctx.state.clone();
*substate(ctx.state.font_mut()) = state.clone();
if let Some(body) = &body {
body.exec(ctx);
ctx.state = snapshot;
}
body.exec(ctx);
})
}

View File

@ -23,9 +23,6 @@
#let alias = type
#test(alias(alias), "function")
// Library function `font` returns template.
#test(type(font(size: 12pt)), "template")
---
// Callee expressions.
{

View File

@ -1,5 +1,5 @@
// Configuration with `page` and `font` functions.
#page(width: 450pt, margins: 1cm)
#page!(width: 450pt, margins: 1cm)
// There are variables and they can take normal values like strings, ...
#let city = "Berlin"

View File

@ -8,7 +8,7 @@ Auto-sized circle. \
Center-aligned rect in auto-sized circle.
#circle(fill: forest)[
#align(center, center)
#align!(center, center)
#rect(fill: conifer, pad(5pt)[But, soft!])
]
@ -23,8 +23,8 @@ Expanded by height.
---
// Test relative sizing.
#rect(width: 100%, height: 50pt, fill: #aaa)[
#align(center, center)
#font(color: #fff)
#align!(center, center)
#font!(color: #fff)
#circle(radius: 10pt, fill: eastern)[A]
#circle(height: 60%, fill: eastern)[B]
#circle(width: 20% + 20pt, fill: eastern)[C]

View File

@ -3,7 +3,7 @@
---
// Test the `rect` function.
#page(width: 150pt)
#page!(width: 150pt)
// Fit to text.
#rect(fill: conifer)[Textbox]

View File

@ -3,11 +3,8 @@
---
Auto-sized square. \
#square(fill: eastern)[
#align(center)
#pad(5pt)[
#font(color: #fff, weight: bold)
Typst
]
#align!(center)
#pad(5pt, font(color: #fff, weight: bold)[Typst])
]
---
@ -18,14 +15,14 @@ Auto-sized square. \
---
// Test height overflow.
#page(width: 75pt, height: 100pt)
#page!(width: 75pt, height: 100pt)
#square(fill: conifer)[
But, soft! what light through yonder window breaks?
]
---
// Test width overflow.
#page(width: 100pt, height: 75pt)
#page!(width: 100pt, height: 75pt)
#square(fill: conifer)[
But, soft! what light through yonder window breaks?
]

View File

@ -12,7 +12,7 @@ Apart
---
// Test block over multiple pages.
#page(height: 60pt)
#page!(height: 60pt)
First!
#block[

View File

@ -3,7 +3,7 @@
---
#let rect(width, color) = rect(width: width, height: 2cm, fill: color)
#page(width: 100pt, height: 140pt)
#page!(width: 100pt, height: 140pt)
#grid(
columns: (auto, 1fr, 3fr, 0.25cm, 3%, 2mm + 10%),
rect(0.5cm, #2a631a),
@ -33,7 +33,7 @@
)
---
#page(height: 3cm, width: 2cm)
#page!(height: 3cm, width: 2cm)
#grid(
columns: (1fr, 1cm, 1fr, 1fr),
column-dir: ttb,
@ -46,8 +46,8 @@
)
---
#page(height: 3cm, margins: 0pt)
#align(center)
#page!(height: 3cm, margins: 0pt)
#align!(center)
#grid(
columns: (1fr,),
rows: (1fr, auto, 2fr),

View File

@ -1,7 +1,7 @@
// Test using the `grid` function to create a finance table.
---
#page(width: 12cm, height: 2.5cm)
#page!(width: 12cm, height: 2.5cm)
#grid(
columns: 5,
gutter-columns: (2fr, 1fr, 1fr),

View File

@ -1,7 +1,7 @@
// Test grid cells that overflow to the next region.
---
#page(width: 5cm, height: 3cm)
#page!(width: 5cm, height: 3cm)
#grid(
columns: 2,
gutter-rows: 3 * (8pt,),
@ -18,7 +18,7 @@
---
// Test a column that starts overflowing right after another row/column did
// that.
#page(width: 5cm, height: 2cm)
#page!(width: 5cm, height: 2cm)
#grid(
columns: 4 * (1fr,),
gutter-rows: (10pt,),
@ -32,7 +32,7 @@
---
// Test two columns in the same row overflowing by a different amount.
#page(width: 5cm, height: 2cm)
#page!(width: 5cm, height: 2cm)
#grid(
columns: 3 * (1fr,),
gutter-rows: (8pt,),
@ -48,7 +48,7 @@
---
// Test grid within a grid, overflowing.
#page(width: 5cm, height: 2.25cm)
#page!(width: 5cm, height: 2.25cm)
#grid(
columns: 4 * (1fr,),
gutter-rows: (10pt,),
@ -62,7 +62,7 @@
---
// Test partition of `fr` units before and after multi-region layout.
#page(width: 5cm, height: 4cm)
#page!(width: 5cm, height: 4cm)
#grid(
columns: 2 * (1fr,),
rows: (1fr, 2fr, auto, 1fr, 1cm),

View File

@ -29,7 +29,7 @@ Hi #box(pad(left: 10pt)) there
---
// Test that the pad node doesn't consume the whole region.
#page(height: 6cm)
#page!(height: 6cm)
#align(left)[Before]
#pad(10pt, image("../../res/tiger.jpg"))

View File

@ -2,7 +2,7 @@
---
// Set width and height.
#page(width: 120pt, height: 120pt)
#page!(width: 120pt, height: 120pt)
#page(width: 40pt)[High]
#page(height: 40pt)[Wide]
@ -13,7 +13,7 @@
]
// Set individual margins.
#page(height: 40pt)
#page!(height: 40pt)
#page(left: 0pt, align(left)[Left])
#page(right: 0pt, align(right)[Right])
#page(top: 0pt, align(top)[Top])
@ -22,21 +22,21 @@
// Ensure that specific margins override general margins.
#page(margins: 0pt, left: 20pt)[Overriden]
// Error: 7-18 unknown variable
#page(nonexistant)
// Error: 8-19 unknown variable
#page!(nonexistant)
// Flipped predefined paper.
#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 a combination of pages with bodies and normal content.
#page(height: 50pt)
#page!(height: 50pt)
#page[First]
#page[Second]

View File

@ -3,7 +3,7 @@
---
First of two
#pagebreak()
#page(height: 40pt)
#page!(height: 40pt)
---
// Make sure that you can't do page related stuff in a container.
@ -13,8 +13,8 @@ A
// Error: 16 cannot modify page from here
#pagebreak()
// Error: 11-15 cannot modify page from here
#page("a4")
// Error: 12-16 cannot modify page from here
#page!("a4")
]
C

View File

@ -1,7 +1,7 @@
// Test simple text.
---
#page(width: 250pt, height: 110pt)
#page!(width: 250pt, height: 110pt)
But, soft! what light through yonder window breaks? It is the east, and Juliet
is the sun. Arise, fair sun, and kill the envious moon, Who is already sick and

View File

@ -3,54 +3,54 @@
---
// Test reordering with different top-level paragraph directions.
#let text = [Text טֶקסט]
#font(family: ("EB Garamond", "Noto Serif Hebrew"))
#lang("he") {text}
#lang("de") {text}
#font!(family: ("EB Garamond", "Noto Serif Hebrew"))
#lang!("he") {text}
#lang!("de") {text}
---
// Test that consecutive, embedded LTR runs stay LTR.
// Here, we have two runs: "A" and italic "B".
#let text = [أنت A_B_مطرC]
#font(family: ("EB Garamond", "Noto Sans Arabic"))
#lang("ar") {text}
#lang("de") {text}
#font!(family: ("EB Garamond", "Noto Sans Arabic"))
#lang!("ar") {text}
#lang!("de") {text}
---
// Test that consecutive, embedded RTL runs stay RTL.
// Here, we have three runs: "גֶ", bold "שֶׁ", and "ם".
#let text = [Aגֶ*שֶׁ*םB]
#font(family: ("EB Garamond", "Noto Serif Hebrew"))
#lang("he") {text}
#lang("de") {text}
#font!(family: ("EB Garamond", "Noto Serif Hebrew"))
#lang!("he") {text}
#lang!("de") {text}
---
// Test embedding up to level 4 with isolates.
#font(family: ("EB Garamond", "Noto Serif Hebrew", "Twitter Color Emoji"))
#lang(dir: rtl)
#font!(family: ("EB Garamond", "Noto Serif Hebrew", "Twitter Color Emoji"))
#lang!(dir: rtl)
א\u{2066}A\u{2067}Bב\u{2069}?
---
// Test hard line break (leads to two paragraphs in unicode-bidi).
#font(family: ("Noto Sans Arabic", "EB Garamond"))
#lang("ar")
#font!(family: ("Noto Sans Arabic", "EB Garamond"))
#lang!("ar")
Life المطر هو الحياة \
الحياة تمطر is rain.
---
// Test spacing.
#font(family: ("EB Garamond", "Noto Serif Hebrew"))
#font!(family: ("EB Garamond", "Noto Serif Hebrew"))
L #h(1cm) ריווחR \
יווח #h(1cm) R
---
// Test inline object.
#font(family: ("Noto Serif Hebrew", "EB Garamond"))
#lang("he")
#font!(family: ("Noto Serif Hebrew", "EB Garamond"))
#lang!("he")
קרנפיםRh#image("../../res/rhino.png", height: 11pt)inoחיים
---
// Test the `lang` function.
// Ref: false
// Error: 12-15 must be horizontal
#lang(dir: ttb)
// Error: 13-16 must be horizontal
#lang!(dir: ttb)

View File

@ -1,7 +1,7 @@
// Test chinese text from Wikipedia.
---
#font(family: "Noto Serif CJK SC")
#font!(family: "Noto Serif CJK SC")
是美国广播公司电视剧《迷失》第3季的第22和23集也是全剧的第71集和72集
由执行制作人戴蒙·林道夫和卡尔顿·库斯编剧,导演则是另一名执行制作人杰克·本德

View File

@ -35,9 +35,9 @@ Emoji: 🐪, 🌋, 🏞
---
// Test top and bottom edge.
#page(width: 170pt)
#page!(width: 170pt)
#let try(top, bottom) = rect(fill: conifer)[
#font(top-edge: top, bottom-edge: bottom)
#font!(top-edge: top, bottom-edge: bottom)
`From `#top` to `#bottom
]
@ -48,7 +48,7 @@ Emoji: 🐪, 🌋, 🏞
---
// Test class definitions.
#font(sans-serif: "PT Sans")
#font!(sans-serif: "PT Sans")
#font(family: sans-serif)[Sans-serif.] \
#font(family: monospace)[Monospace.] \
#font(family: monospace, monospace: ("Nope", "Latin Modern Math"))[Math.]
@ -57,18 +57,18 @@ Emoji: 🐪, 🌋, 🏞
// Ref: false
// Error: 7-12 unexpected argument
#font(false)
#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 string or array of strings, found integer
#font(style: bold, weight: "thin", serif: 0)
#font(style: bold, weight: "thin", serif: 0)[]
// Warning: 15-19 should be between 100 and 900
#font(weight: 2700)
#font(weight: 2700)[]
// Warning: 16-21 should be between 50% and 200%
#font(stretch: 1000%)
#font(stretch: 1000%)[]
// Error: 7-27 unexpected argument
#font(something: "invalid")
#font(something: "invalid")[]

View File

@ -2,11 +2,11 @@
---
// FIXME: Word spacing doesn't work due to new shaping process.
#par(spacing: 10pt, leading: 25%, word-spacing: 1pt)
#par!(spacing: 10pt, leading: 25%, word-spacing: 1pt)
But, soft! what light through yonder window breaks? It is the east, and Juliet
is the sun.
---
// Test that it finishes an existing paragraph.
Hello #par(word-spacing: 0pt) t h e r e !
Hello #par!(word-spacing: 0pt) t h e r e !

View File

@ -7,11 +7,11 @@
Le fira
// This should just shape nicely.
#font(family: "Noto Sans Arabic")
#font!(family: "Noto Sans Arabic")
دع النص يمطر عليك
// This should form a three-member family.
#font(family: "Twitter Color Emoji")
#font!(family: "Twitter Color Emoji")
👩‍👩‍👦 🤚🏿
// These two shouldn't be affected by a zero-width joiner.
@ -20,7 +20,7 @@ Le fira
---
// Test font fallback.
#font(family: ("EB Garamond", "Noto Sans Arabic", "Twitter Color Emoji"))
#font!(family: ("EB Garamond", "Noto Sans Arabic", "Twitter Color Emoji"))
// Font fallback for emoji.
A😀B
@ -40,6 +40,6 @@ A🐈中文B
---
// Test reshaping.
#font(family: "Noto Serif Hebrew")
#lang("he")
#font!(family: "Noto Serif Hebrew")
#lang!("he")
ס \ טֶ

View File

@ -369,10 +369,8 @@ fn register_helpers(scope: &mut Scope, panics: Rc<RefCell<Vec<Panic>>>) {
let repr = typst::pretty::pretty(args);
args.items.clear();
Value::template(move |ctx| {
let snapshot = ctx.state.clone();
ctx.set_monospace();
ctx.push_text(&repr);
ctx.state = snapshot;
})
}