Paragraph spacing property (#4390)

This commit is contained in:
Laurenz 2024-06-14 10:49:44 +02:00 committed by GitHub
parent 6f9855a8c3
commit 9a45d948f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 155 additions and 99 deletions

View File

@ -10,7 +10,7 @@ use crate::foundations::{
use crate::introspection::Locator; use crate::introspection::Locator;
use crate::layout::{ use crate::layout::{
Abs, Axes, Corners, Em, Fr, Fragment, Frame, FrameKind, Length, Region, Regions, Rel, Abs, Axes, Corners, Em, Fr, Fragment, Frame, FrameKind, Length, Region, Regions, Rel,
Sides, Size, Spacing, VElem, Sides, Size, Spacing,
}; };
use crate::utils::Numeric; use crate::utils::Numeric;
use crate::visualize::{clip_rect, Paint, Stroke}; use crate::visualize::{clip_rect, Paint, Stroke};
@ -385,8 +385,20 @@ pub struct BlockElem {
#[fold] #[fold]
pub outset: Sides<Option<Rel<Length>>>, pub outset: Sides<Option<Rel<Length>>>,
/// The spacing around this block. This is shorthand to set `above` and /// The spacing around the block. When `{auto}`, inherits the paragraph
/// `below` to the same value. /// [`spacing`]($par.spacing).
///
/// For two adjacent blocks, the larger of the first block's `above` and the
/// second block's `below` spacing wins. Moreover, block spacing takes
/// precedence over paragraph [`spacing`]($par.spacing).
///
/// Note that this is only a shorthand to set `above` and `below` to the
/// same value. Since the values for `above` and `below` might differ, a
/// [context] block only provides access to `{block.above}` and
/// `{block.below}`, not to `{block.spacing}` directly.
///
/// This property can be used in combination with a show rule to adjust the
/// spacing around arbitrary block-level elements.
/// ///
/// ```example /// ```example
/// #set align(center) /// #set align(center)
@ -400,35 +412,16 @@ pub struct BlockElem {
#[default(Em::new(1.2).into())] #[default(Em::new(1.2).into())]
pub spacing: Spacing, pub spacing: Spacing,
/// The spacing between this block and its predecessor. Takes precedence /// The spacing between this block and its predecessor.
/// over `spacing`. Can be used in combination with a show rule to adjust
/// the spacing around arbitrary block-level elements.
#[external]
#[default(Em::new(1.2).into())]
pub above: Spacing,
#[internal]
#[parse( #[parse(
let spacing = args.named("spacing")?; let spacing = args.named("spacing")?;
args.named("above")? args.named("above")?.or(spacing)
.map(VElem::block_around)
.or_else(|| spacing.map(VElem::block_spacing))
)] )]
#[default(VElem::block_spacing(Em::new(1.2).into()))] pub above: Smart<Spacing>,
pub above: VElem,
/// The spacing between this block and its successor. Takes precedence /// The spacing between this block and its successor.
/// over `spacing`. #[parse(args.named("below")?.or(spacing))]
#[external] pub below: Smart<Spacing>,
#[default(Em::new(1.2).into())]
pub below: Spacing,
#[internal]
#[parse(
args.named("below")?
.map(VElem::block_around)
.or_else(|| spacing.map(VElem::block_spacing))
)]
#[default(VElem::block_spacing(Em::new(1.2).into()))]
pub below: VElem,
/// Whether to clip the content inside the block. /// Whether to clip the content inside the block.
#[default(false)] #[default(false)]

View File

@ -153,13 +153,13 @@ impl VElem {
Self::new(amount).with_weakness(2).with_attach(true) Self::new(amount).with_weakness(2).with_attach(true)
} }
/// Weak spacing with BlockElem::ABOVE/BELOW weakness. /// Weak spacing with `BlockElem::spacing` weakness.
pub fn block_around(amount: Spacing) -> Self { pub fn block_spacing(amount: Spacing) -> Self {
Self::new(amount).with_weakness(3) Self::new(amount).with_weakness(3)
} }
/// Weak spacing with BlockElem::SPACING weakness. /// Weak spacing with `ParElem::spacing` weakness.
pub fn block_spacing(amount: Spacing) -> Self { pub fn par_spacing(amount: Spacing) -> Self {
Self::new(amount).with_weakness(4) Self::new(amount).with_weakness(4)
} }
} }

View File

@ -231,7 +231,7 @@ impl Show for Packed<BibliographyElem> {
.ok_or("CSL style is not suitable for bibliographies") .ok_or("CSL style is not suitable for bibliographies")
.at(span)?; .at(span)?;
let row_gutter = *BlockElem::below_in(styles).amount(); let row_gutter = ParElem::spacing_in(styles).into();
if references.iter().any(|(prefix, _)| prefix.is_some()) { if references.iter().any(|(prefix, _)| prefix.is_some()) {
let mut cells = vec![]; let mut cells = vec![];
for (prefix, reference) in references { for (prefix, reference) in references {

View File

@ -12,7 +12,7 @@ use crate::foundations::{
use crate::introspection::Locator; use crate::introspection::Locator;
use crate::layout::{ use crate::layout::{
Alignment, Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment, Alignment, Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment,
Length, Regions, Sizing, Spacing, VAlignment, VElem, Length, Regions, Sizing, VAlignment, VElem,
}; };
use crate::model::{Numbering, NumberingPattern, ParElem}; use crate::model::{Numbering, NumberingPattern, ParElem};
use crate::text::TextElem; use crate::text::TextElem;
@ -155,10 +155,12 @@ pub struct EnumElem {
#[default(Em::new(0.5).into())] #[default(Em::new(0.5).into())]
pub body_indent: Length, pub body_indent: Length,
/// The spacing between the items of a wide (non-tight) enumeration. /// The spacing between the items of the enumeration.
/// ///
/// If set to `{auto}`, uses the spacing [below blocks]($block.below). /// If set to `{auto}`, uses paragraph [`leading`]($par.leading) for tight
pub spacing: Smart<Spacing>, /// enumerations and paragraph [`spacing`]($par.spacing) for wide
/// (non-tight) enumerations.
pub spacing: Smart<Length>,
/// The alignment that enum numbers should have. /// The alignment that enum numbers should have.
/// ///
@ -242,12 +244,13 @@ fn layout_enum(
let numbering = elem.numbering(styles); let numbering = elem.numbering(styles);
let indent = elem.indent(styles); let indent = elem.indent(styles);
let body_indent = elem.body_indent(styles); let body_indent = elem.body_indent(styles);
let gutter = if elem.tight(styles) { let gutter = elem.spacing(styles).unwrap_or_else(|| {
if elem.tight(styles) {
ParElem::leading_in(styles).into() ParElem::leading_in(styles).into()
} else { } else {
elem.spacing(styles) ParElem::spacing_in(styles).into()
.unwrap_or_else(|| *BlockElem::below_in(styles).amount()) }
}; });
let mut cells = vec![]; let mut cells = vec![];
let mut locator = locator.split(); let mut locator = locator.split();

View File

@ -9,9 +9,7 @@ use crate::foundations::{
use crate::introspection::{ use crate::introspection::{
Count, Counter, CounterUpdate, Locatable, Locator, LocatorLink, Count, Counter, CounterUpdate, Locatable, Locator, LocatorLink,
}; };
use crate::layout::{ use crate::layout::{Abs, Axes, BlockChild, BlockElem, Em, HElem, Length, Regions};
Abs, Axes, BlockChild, BlockElem, Em, HElem, Length, Regions, VElem,
};
use crate::model::{Numbering, Outlinable, ParElem, Refable, Supplement}; use crate::model::{Numbering, Outlinable, ParElem, Refable, Supplement};
use crate::text::{FontWeight, LocalName, SpaceElem, TextElem, TextSize}; use crate::text::{FontWeight, LocalName, SpaceElem, TextElem, TextSize};
use crate::utils::NonZeroExt; use crate::utils::NonZeroExt;
@ -280,8 +278,8 @@ impl ShowSet for Packed<HeadingElem> {
let mut out = Styles::new(); let mut out = Styles::new();
out.set(TextElem::set_size(TextSize(size.into()))); out.set(TextElem::set_size(TextSize(size.into())));
out.set(TextElem::set_weight(FontWeight::BOLD)); out.set(TextElem::set_weight(FontWeight::BOLD));
out.set(BlockElem::set_above(VElem::block_around(above.into()))); out.set(BlockElem::set_above(Smart::Custom(above.into())));
out.set(BlockElem::set_below(VElem::block_around(below.into()))); out.set(BlockElem::set_below(Smart::Custom(below.into())));
out.set(BlockElem::set_sticky(true)); out.set(BlockElem::set_sticky(true));
out out
} }

View File

@ -9,7 +9,7 @@ use crate::foundations::{
use crate::introspection::Locator; use crate::introspection::Locator;
use crate::layout::{ use crate::layout::{
Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment, Length, Axes, BlockElem, Cell, CellGrid, Em, Fragment, GridLayouter, HAlignment, Length,
Regions, Sizing, Spacing, VAlignment, VElem, Regions, Sizing, VAlignment, VElem,
}; };
use crate::model::ParElem; use crate::model::ParElem;
use crate::text::TextElem; use crate::text::TextElem;
@ -107,10 +107,12 @@ pub struct ListElem {
#[default(Em::new(0.5).into())] #[default(Em::new(0.5).into())]
pub body_indent: Length, pub body_indent: Length,
/// The spacing between the items of a wide (non-tight) list. /// The spacing between the items of the list.
/// ///
/// If set to `{auto}`, uses the spacing [below blocks]($block.below). /// If set to `{auto}`, uses paragraph [`leading`]($par.leading) for tight
pub spacing: Smart<Spacing>, /// lists and paragraph [`spacing`]($par.spacing) for wide (non-tight)
/// lists.
pub spacing: Smart<Length>,
/// The bullet list's children. /// The bullet list's children.
/// ///
@ -165,12 +167,13 @@ fn layout_list(
) -> SourceResult<Fragment> { ) -> SourceResult<Fragment> {
let indent = elem.indent(styles); let indent = elem.indent(styles);
let body_indent = elem.body_indent(styles); let body_indent = elem.body_indent(styles);
let gutter = if elem.tight(styles) { let gutter = elem.spacing(styles).unwrap_or_else(|| {
if elem.tight(styles) {
ParElem::leading_in(styles).into() ParElem::leading_in(styles).into()
} else { } else {
elem.spacing(styles) ParElem::spacing_in(styles).into()
.unwrap_or_else(|| *BlockElem::below_in(styles).amount()) }
}; });
let Depth(depth) = ListElem::depth_in(styles); let Depth(depth) = ListElem::depth_in(styles);
let marker = elem let marker = elem

View File

@ -38,11 +38,38 @@ use crate::realize::StyleVec;
#[elem(title = "Paragraph", Debug, Construct)] #[elem(title = "Paragraph", Debug, Construct)]
pub struct ParElem { pub struct ParElem {
/// The spacing between lines. /// The spacing between lines.
///
/// Leading defines the spacing between the [bottom edge]($text.bottom-edge)
/// of one line and the [top edge]($text.top-edge) of the following line. By
/// default, these two properties are up to the font, but they can also be
/// configured manually with a text set rule.
///
/// By setting top edge, bottom edge, and leading, you can also configure a
/// consistent baseline-to-baseline distance. You could, for instance, set
/// the leading to `{1em}`, the top-edge to `{0.8em}`, and the bottom-edge
/// to `-{0.2em}` to get a baseline gap of exactly `{2em}`. The exact
/// distribution of the top- and bottom-edge values affects the bounds of
/// the first and last line.
#[resolve] #[resolve]
#[ghost] #[ghost]
#[default(Em::new(0.65).into())] #[default(Em::new(0.65).into())]
pub leading: Length, pub leading: Length,
/// The spacing between paragraphs.
///
/// Just like leading, this defines the spacing between the bottom edge of a
/// paragraph's last line and the top edge of the next paragraph's first
/// line.
///
/// When a paragraph is adjacent to a [`block`] that is not a paragraph,
/// that block's [`above`]($block.above) or [`below`]($block.below) property
/// takes precedence over the paragraph spacing. Headings, for instance,
/// reduce the spacing below them by default for a better look.
#[resolve]
#[ghost]
#[default(Em::new(1.2).into())]
pub spacing: Length,
/// Whether to justify text in its line. /// Whether to justify text in its line.
/// ///
/// Hyphenation will be enabled for justified paragraphs if the /// Hyphenation will be enabled for justified paragraphs if the

View File

@ -222,15 +222,14 @@ impl Show for Packed<QuoteElem> {
} }
impl ShowSet for Packed<QuoteElem> { impl ShowSet for Packed<QuoteElem> {
fn show_set(&self, _: StyleChain) -> Styles { fn show_set(&self, styles: StyleChain) -> Styles {
let x = Em::new(1.0).into();
let above = Em::new(2.4).into();
let below = Em::new(1.8).into();
let mut out = Styles::new(); let mut out = Styles::new();
out.set(PadElem::set_left(x)); if self.block(styles) {
out.set(PadElem::set_right(x)); out.set(PadElem::set_left(Em::new(1.0).into()));
out.set(BlockElem::set_above(VElem::block_around(above))); out.set(PadElem::set_right(Em::new(1.0).into()));
out.set(BlockElem::set_below(VElem::block_around(below))); out.set(BlockElem::set_above(Smart::Custom(Em::new(2.4).into())));
out.set(BlockElem::set_below(Smart::Custom(Em::new(1.8).into())));
}
out out
} }
} }

View File

@ -4,9 +4,7 @@ use crate::foundations::{
cast, elem, scope, Array, Content, NativeElement, Packed, Show, Smart, StyleChain, cast, elem, scope, Array, Content, NativeElement, Packed, Show, Smart, StyleChain,
Styles, Styles,
}; };
use crate::layout::{ use crate::layout::{Dir, Em, HElem, Length, Sides, StackChild, StackElem, VElem};
BlockElem, Dir, Em, HElem, Length, Sides, Spacing, StackChild, StackElem, VElem,
};
use crate::model::ParElem; use crate::model::ParElem;
use crate::text::TextElem; use crate::text::TextElem;
use crate::utils::Numeric; use crate::utils::Numeric;
@ -82,10 +80,12 @@ pub struct TermsElem {
#[default(Em::new(2.0).into())] #[default(Em::new(2.0).into())]
pub hanging_indent: Length, pub hanging_indent: Length,
/// The spacing between the items of a wide (non-tight) term list. /// The spacing between the items of the term list.
/// ///
/// If set to `{auto}`, uses the spacing [below blocks]($block.below). /// If set to `{auto}`, uses paragraph [`leading`]($par.leading) for tight
pub spacing: Smart<Spacing>, /// term lists and paragraph [`spacing`]($par.spacing) for wide
/// (non-tight) term lists.
pub spacing: Smart<Length>,
/// The term list's children. /// The term list's children.
/// ///
@ -114,12 +114,13 @@ impl Show for Packed<TermsElem> {
let separator = self.separator(styles); let separator = self.separator(styles);
let indent = self.indent(styles); let indent = self.indent(styles);
let hanging_indent = self.hanging_indent(styles); let hanging_indent = self.hanging_indent(styles);
let gutter = if self.tight(styles) { let gutter = self.spacing(styles).unwrap_or_else(|| {
if self.tight(styles) {
ParElem::leading_in(styles).into() ParElem::leading_in(styles).into()
} else { } else {
self.spacing(styles) ParElem::spacing_in(styles).into()
.unwrap_or_else(|| *BlockElem::below_in(styles).amount()) }
}; });
let pad = hanging_indent + indent; let pad = hanging_indent + indent;
let unpad = (!hanging_indent.is_zero()) let unpad = (!hanging_indent.is_zero())
@ -143,7 +144,7 @@ impl Show for Packed<TermsElem> {
} }
let mut realized = StackElem::new(children) let mut realized = StackElem::new(children)
.with_spacing(Some(gutter)) .with_spacing(Some(gutter.into()))
.pack() .pack()
.padded(padding); .padded(padding);

View File

@ -10,6 +10,8 @@ mod arenas;
mod behaviour; mod behaviour;
mod process; mod process;
use once_cell::unsync::Lazy;
pub use self::arenas::Arenas; pub use self::arenas::Arenas;
pub use self::behaviour::{Behave, BehavedBuilder, Behaviour, StyleVec}; pub use self::behaviour::{Behave, BehavedBuilder, Behaviour, StyleVec};
pub use self::process::process; pub use self::process::process;
@ -19,7 +21,7 @@ use std::mem;
use crate::diag::{bail, SourceResult}; use crate::diag::{bail, SourceResult};
use crate::engine::{Engine, Route}; use crate::engine::{Engine, Route};
use crate::foundations::{ use crate::foundations::{
Content, NativeElement, Packed, SequenceElem, StyleChain, StyledElem, Styles, Content, NativeElement, Packed, SequenceElem, Smart, StyleChain, StyledElem, Styles,
}; };
use crate::introspection::{Locator, SplitLocator, TagElem}; use crate::introspection::{Locator, SplitLocator, TagElem};
use crate::layout::{ use crate::layout::{
@ -407,17 +409,31 @@ impl<'a> FlowBuilder<'a> {
return true; return true;
} }
let par_spacing = Lazy::new(|| {
arenas.store(VElem::par_spacing(ParElem::spacing_in(styles).into()).pack())
});
if let Some(elem) = content.to_packed::<BlockElem>() { if let Some(elem) = content.to_packed::<BlockElem>() {
self.0.push(arenas.store(elem.above(styles).pack()), styles); let above = match elem.above(styles) {
Smart::Auto => *par_spacing,
Smart::Custom(above) => arenas.store(VElem::block_spacing(above).pack()),
};
let below = match elem.below(styles) {
Smart::Auto => *par_spacing,
Smart::Custom(below) => arenas.store(VElem::block_spacing(below).pack()),
};
self.0.push(above, styles);
self.0.push(content, styles); self.0.push(content, styles);
self.0.push(arenas.store(elem.below(styles).pack()), styles); self.0.push(below, styles);
return true; return true;
} }
if content.is::<ParElem>() { if content.is::<ParElem>() {
self.0.push(arenas.store(BlockElem::above_in(styles).pack()), styles); self.0.push(*par_spacing, styles);
self.0.push(content, styles); self.0.push(content, styles);
self.0.push(arenas.store(BlockElem::below_in(styles).pack()), styles); self.0.push(*par_spacing, styles);
return true; return true;
} }

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 967 B

After

Width:  |  Height:  |  Size: 958 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -85,7 +85,7 @@
#set text(size: 12pt, weight: "regular") #set text(size: 12pt, weight: "regular")
#outline( #outline(
title: "Chapter outline", title: none,
indent: true, indent: true,
target: heading target: heading
.where(level: 1) .where(level: 1)

View File

@ -43,13 +43,26 @@ First!
] ]
--- block-spacing-basic --- --- block-spacing-basic ---
#set block(spacing: 10pt) #set par(spacing: 10pt)
Hello Hello
There There
#block(spacing: 20pt)[Further down] #block(spacing: 20pt)[Further down]
--- block-above-below-context ---
#context test(block.above, auto)
#set block(spacing: 20pt)
#context test(block.above, 20pt)
#context test(block.below, 20pt)
--- block-spacing-context ---
// The values for `above` and `below` might be different, so we cannot retrieve
// `spacing` directly
//
// Error: 16-23 function `block` does not contain field `spacing`
#context block.spacing
--- block-spacing-table --- --- block-spacing-table ---
// Test that paragraph spacing loses against block spacing. // Test that paragraph spacing loses against block spacing.
#set block(spacing: 100pt) #set block(spacing: 100pt)

View File

@ -1,7 +1,6 @@
--- justify --- --- justify ---
#set page(width: 180pt) #set page(width: 180pt)
#set block(spacing: 5pt) #set par(justify: true, first-line-indent: 14pt, spacing: 5pt, leading: 5pt)
#set par(justify: true, first-line-indent: 14pt, leading: 5pt)
This text is justified, meaning that spaces are stretched so that the text This text is justified, meaning that spaces are stretched so that the text
forms a "block" with flush edges at both sides. forms a "block" with flush edges at both sides.

View File

@ -129,7 +129,7 @@ More.
--- list-wide-cannot-attach --- --- list-wide-cannot-attach ---
// Test that wide lists cannot be ... // Test that wide lists cannot be ...
#set block(spacing: 15pt) #set par(spacing: 15pt)
Hello Hello
- A - A

View File

@ -118,6 +118,7 @@ Ok ...
} }
#outline(indent: auto) #outline(indent: auto)
#v(1.2em, weak: true)
#set text(8pt) #set text(8pt)
#show heading: set block(spacing: 0.65em) #show heading: set block(spacing: 0.65em)
@ -142,6 +143,7 @@ Ok ...
#counter(page).update(3) #counter(page).update(3)
#outline(indent: auto, fill: repeat[--]) #outline(indent: auto, fill: repeat[--])
#v(1.2em, weak: true)
#set text(8pt) #set text(8pt)
#show heading: set block(spacing: 0.65em) #show heading: set block(spacing: 0.65em)

View File

@ -19,17 +19,19 @@ heaven Would through the airy region stream so bright That birds would sing and
think it were not night. See, how she leans her cheek upon her hand! O, that I think it were not night. See, how she leans her cheek upon her hand! O, that I
were a glove upon that hand, That I might touch that cheek! were a glove upon that hand, That I might touch that cheek!
--- par-leading-and-block-spacing --- --- par-leading-and-spacing ---
// Test changing leading and spacing. // Test changing leading and spacing.
#set block(spacing: 1em) #set par(spacing: 1em, leading: 2pt)
#set par(leading: 2pt)
But, soft! what light through yonder window breaks? But, soft! what light through yonder window breaks?
It is the east, and Juliet is the sun. It is the east, and Juliet is the sun.
--- par-spacing-context ---
#set par(spacing: 10pt)
#context test(par.spacing, 10pt)
--- par-first-line-indent --- --- par-first-line-indent ---
#set par(first-line-indent: 12pt, leading: 5pt) #set par(first-line-indent: 12pt, spacing: 5pt, leading: 5pt)
#set block(spacing: 5pt)
#show heading: set text(size: 10pt) #show heading: set text(size: 10pt)
The first paragraph has no indent. The first paragraph has no indent.

View File

@ -29,7 +29,7 @@ And I quote: #quote(attribution: [René Descartes])[cogito, ergo sum].
#set text(8pt) #set text(8pt)
#quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.] #quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.]
#set text(0pt) #show bibliography: none
#bibliography("/assets/bib/works.bib") #bibliography("/assets/bib/works.bib")
--- quote-cite-format-label-or-numeric --- --- quote-cite-format-label-or-numeric ---
@ -38,7 +38,7 @@ And I quote: #quote(attribution: [René Descartes])[cogito, ergo sum].
#set quote(block: true) #set quote(block: true)
#quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.] #quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.]
#set text(0pt) #show bibliography: none
#bibliography("/assets/bib/works.bib", style: "ieee") #bibliography("/assets/bib/works.bib", style: "ieee")
--- quote-cite-format-note --- --- quote-cite-format-note ---
@ -47,7 +47,7 @@ And I quote: #quote(attribution: [René Descartes])[cogito, ergo sum].
#set quote(block: true) #set quote(block: true)
#quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.] #quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.]
#set text(0pt) #show bibliography: none
#bibliography("/assets/bib/works.bib", style: "chicago-notes") #bibliography("/assets/bib/works.bib", style: "chicago-notes")
--- quote-cite-format-author-date --- --- quote-cite-format-author-date ---
@ -56,7 +56,7 @@ And I quote: #quote(attribution: [René Descartes])[cogito, ergo sum].
#set quote(block: true) #set quote(block: true)
#quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.] #quote(attribution: <tolkien54>)[In a hole in the ground there lived a hobbit.]
#set text(0pt) #show bibliography: none
#bibliography("/assets/bib/works.bib", style: "apa") #bibliography("/assets/bib/works.bib", style: "apa")
--- quote-nesting --- --- quote-nesting ---

View File

@ -21,7 +21,7 @@ Hello *#x*
--- set-text-override --- --- set-text-override ---
// Test that that block spacing and text style are respected from // Test that that block spacing and text style are respected from
// the outside, but the more specific fill is respected. // the outside, but the more specific fill is respected.
#set block(spacing: 4pt) #set par(spacing: 4pt)
#set text(style: "italic", fill: eastern) #set text(style: "italic", fill: eastern)
#let x = [And the forest #parbreak() lay silent!] #let x = [And the forest #parbreak() lay silent!]
#text(fill: forest, x) #text(fill: forest, x)