diff --git a/src/library/layout.rs b/src/library/layout.rs index 10389779e..27b2e743b 100644 --- a/src/library/layout.rs +++ b/src/library/layout.rs @@ -210,6 +210,26 @@ castable! { AlignValue: "alignment", } +/// ´box`: Place content in a rectangular box. +pub fn boxed(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { + let width = args.named(ctx, "width"); + let height = args.named(ctx, "height"); + let body = args.eat(ctx).unwrap_or_default(); + Value::template(move |ctx| { + let child = ctx.exec_template_stack(&body).into(); + ctx.push_into_par(FixedNode { width, height, child }); + }) +} + +/// block`: Place content in a block. +pub fn block(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { + let body = args.eat(ctx).unwrap_or_default(); + Value::template(move |ctx| { + let block = ctx.exec_template_stack(&body); + ctx.push_into_stack(block); + }) +} + /// `pad`: Pad content at the sides. pub fn pad(ctx: &mut EvalContext, args: &mut FuncArgs) -> Value { let all = args.eat(ctx); diff --git a/src/library/mod.rs b/src/library/mod.rs index 5f0430b2f..92ee9faaa 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -41,6 +41,8 @@ pub fn new() -> Scope { std.def_func("h", h); std.def_func("v", v); std.def_func("align", align); + std.def_func("box", boxed); + std.def_func("block", block); std.def_func("pad", pad); std.def_func("stack", stack); std.def_func("grid", grid); diff --git a/tests/ref/layout/containers.png b/tests/ref/layout/containers.png new file mode 100644 index 000000000..4548e2f5a Binary files /dev/null and b/tests/ref/layout/containers.png differ diff --git a/tests/ref/layout/fixed.png b/tests/ref/layout/fixed.png deleted file mode 100644 index 5ee9c4ff4..000000000 Binary files a/tests/ref/layout/fixed.png and /dev/null differ diff --git a/tests/ref/layout/pad.png b/tests/ref/layout/pad.png index 645c8db47..fa877d52c 100644 Binary files a/tests/ref/layout/pad.png and b/tests/ref/layout/pad.png differ diff --git a/tests/typ/coma.typ b/tests/typ/coma.typ index 810d61b8f..b1eefc9f1 100644 --- a/tests/typ/coma.typ +++ b/tests/typ/coma.typ @@ -10,10 +10,10 @@ #let university = [*Technische Universität {city}*] #let faculty = [*Fakultät II, Institut for Mathematik*] -// The `rect` function just places content into a rectangular container. When +// 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])`). -#rect[ +#box[ // Backslash adds a forced line break. #university \ #faculty \ @@ -21,7 +21,7 @@ Dr. Max Mustermann \ Ola Nordmann, John Doe ] -#align(right, rect[*WiSe 2019/2020* \ Woche 3]) +#align(right, box[*WiSe 2019/2020* \ Woche 3]) // Adds vertical spacing. #v(6mm) diff --git a/tests/typ/layout/containers.typ b/tests/typ/layout/containers.typ new file mode 100644 index 000000000..b2835b5e4 --- /dev/null +++ b/tests/typ/layout/containers.typ @@ -0,0 +1,42 @@ +// Test the `box` and `block` containers. + +--- +// Test box in paragraph. +A #box[B \ C] D. + +// Test box with height. +Spaced \ +#box(height: 0.5cm) \ +Apart + +--- +// Test block over multiple pages. + +#page(height: 60pt) + +First! +#block[ + But, soft! what light through yonder window breaks? It is the east, and Juliet + is the sun. +] + +--- +// Test shrink-to-fit vs expand. + +// Top-level paragraph fills page +L #align(right)[R] + +// Block also fills page. +#block[ + L #align(right)[R] +] + +// Boxed paragraph respects width. +#box(width: 50pt)[ + L #align(right)[R] +] + +// Boxed paragraph without width doesn't expand. +#box[ + L #align(right)[R] +] diff --git a/tests/typ/layout/fixed.typ b/tests/typ/layout/fixed.typ deleted file mode 100644 index 51646eaa4..000000000 --- a/tests/typ/layout/fixed.typ +++ /dev/null @@ -1,14 +0,0 @@ -// Test shrink-to-fit vs expand. - ---- -#let right(body) = align(right, body) -#let pad(body) = pad(left: 10pt, right: 10pt, body) - -// Top-level paragraph fills page, boxed paragraph only when the width is set. -L #right[R] \ -#rect(width: 50pt)[L #right[R]] \ -#rect[L #right[R]] - -// Pad inherits expansion behaviour. -#rect(pad[PL #right[PR]]) -#pad[PL #right[PR]] diff --git a/tests/typ/layout/pad.typ b/tests/typ/layout/pad.typ index 8c23549a8..142ae4a90 100644 --- a/tests/typ/layout/pad.typ +++ b/tests/typ/layout/pad.typ @@ -11,13 +11,26 @@ ] ] -// Error: 14-24 missing argument: body -Hi #rect(pad(left: 10pt)) there +// Error: 13-23 missing argument: body +Hi #box(pad(left: 10pt)) there + +--- +#let pad(body) = pad(left: 10pt, right: 10pt, body) + +// Pad inherits expansion behaviour from stack .... +#pad[PL #align(right)[PR]] + +// ... block ... +#block(pad[PL #align(right)[PR]]) + +// ... and box. +#box(pad[PL #align(right)[PR]]) --- // Test that the pad node doesn't consume the whole region. -#page(width: 4cm, height: 5cm) +#page(height: 6cm) + #align(left)[Before] #pad(10pt, image("../../res/tiger.jpg")) #align(right)[After] diff --git a/tests/typ/layout/pagebreak.typ b/tests/typ/layout/pagebreak.typ index bb7013ab2..dedf1ce61 100644 --- a/tests/typ/layout/pagebreak.typ +++ b/tests/typ/layout/pagebreak.typ @@ -6,9 +6,9 @@ First of two #page(height: 40pt) --- -// Make sure that you can't do page related stuff in a shape. +// Make sure that you can't do page related stuff in a container. A -#rect[ +#box[ B // Error: 16 cannot modify page from here #pagebreak() diff --git a/tests/typ/markup/emph.typ b/tests/typ/markup/emph.typ index 048097a1c..77ac2c72b 100644 --- a/tests/typ/markup/emph.typ +++ b/tests/typ/markup/emph.typ @@ -8,4 +8,4 @@ _Emphasized!_ Partly em_phas_ized. // Scoped to body. -#rect[_Scoped] to body. +#box[_Scoped] to body. diff --git a/tests/typ/markup/heading.typ b/tests/typ/markup/heading.typ index cffa6ed4f..8787d959a 100644 --- a/tests/typ/markup/heading.typ +++ b/tests/typ/markup/heading.typ @@ -18,7 +18,7 @@ // Parsed as headings if at start of the context. /**/ # Level 1 {[## Level 2]} -#rect[### Level 3] +#box[### Level 3] // Not at the start of the context. No # heading diff --git a/tests/typ/markup/strong.typ b/tests/typ/markup/strong.typ index 36695c480..d396cc2d0 100644 --- a/tests/typ/markup/strong.typ +++ b/tests/typ/markup/strong.typ @@ -8,4 +8,4 @@ Partly str*ength*ened. // Scoped to body. -#rect[*Scoped] to body. +#box[*Scoped] to body. diff --git a/tests/typ/text/align.typ b/tests/typ/text/align.typ index 27c650a49..2ffe1b4c2 100644 --- a/tests/typ/text/align.typ +++ b/tests/typ/text/align.typ @@ -2,7 +2,7 @@ --- // Test that alignment depends on the paragraph's full width. -#rect[ +#box[ Hello World \ #align(right)[World] ] @@ -10,7 +10,7 @@ --- // Test that a line with multiple alignments respects the paragraph's full // width. -#rect[ +#box[ Hello #align(center)[World] \ Hello from the World ] diff --git a/tests/typeset.rs b/tests/typeset.rs index 8fc7712a0..c5f31e61f 100644 --- a/tests/typeset.rs +++ b/tests/typeset.rs @@ -224,6 +224,9 @@ fn test_part( state.page.size = Size::new(Length::pt(120.0), Length::inf()); state.page.margins = Sides::splat(Some(Length::pt(10.0).into())); + // Clear cache between tests (for now). + cache.layout.clear(); + let mut pass = typst::typeset(loader, cache, Some(src_path), &src, &scope, state); if !compare_ref { @@ -315,7 +318,7 @@ fn register_helpers(scope: &mut Scope, panics: Rc>>) { pub fn args(_: &mut EvalContext, args: &mut FuncArgs) -> Value { let repr = typst::pretty::pretty(args); args.items.clear(); - Value::template("args", move |ctx| { + Value::template(move |ctx| { let snapshot = ctx.state.clone(); ctx.set_monospace(); ctx.push_text(&repr);