Support quotes in HTML output.

This commit is contained in:
Michael Färber 2025-01-09 10:31:49 +01:00
parent 265df6c29f
commit 8b1328de62

View File

@ -2,8 +2,9 @@ use crate::diag::SourceResult;
use crate::engine::Engine; use crate::engine::Engine;
use crate::foundations::{ use crate::foundations::{
cast, elem, Content, Depth, Label, NativeElement, Packed, Show, ShowSet, Smart, cast, elem, Content, Depth, Label, NativeElement, Packed, Show, ShowSet, Smart,
StyleChain, Styles, StyleChain, Styles, TargetElem,
}; };
use crate::html::{tag, HtmlElem};
use crate::introspection::Locatable; use crate::introspection::Locatable;
use crate::layout::{ use crate::layout::{
Alignment, BlockBody, BlockElem, Em, HElem, PadElem, Spacing, VElem, Alignment, BlockBody, BlockElem, Em, HElem, PadElem, Spacing, VElem,
@ -158,6 +159,7 @@ impl Show for Packed<QuoteElem> {
fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> { fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
let mut realized = self.body().clone(); let mut realized = self.body().clone();
let block = self.block(styles); let block = self.block(styles);
let html = TargetElem::target_in(styles).is_html();
if self.quotes(styles) == Smart::Custom(true) || !block { if self.quotes(styles) == Smart::Custom(true) || !block {
let quotes = SmartQuotes::get( let quotes = SmartQuotes::get(
@ -171,49 +173,51 @@ impl Show for Packed<QuoteElem> {
let Depth(depth) = QuoteElem::depth_in(styles); let Depth(depth) = QuoteElem::depth_in(styles);
let double = depth % 2 == 0; let double = depth % 2 == 0;
// Add zero-width weak spacing to make the quotes "sticky". if !html {
let hole = HElem::hole().pack(); // Add zero-width weak spacing to make the quotes "sticky".
let hole = HElem::hole().pack();
realized = Content::sequence([hole.clone(), realized, hole]);
}
realized = Content::sequence([ realized = Content::sequence([
TextElem::packed(quotes.open(double)), TextElem::packed(quotes.open(double)),
hole.clone(),
realized, realized,
hole,
TextElem::packed(quotes.close(double)), TextElem::packed(quotes.close(double)),
]) ])
.styled(QuoteElem::set_depth(Depth(1))); .styled(QuoteElem::set_depth(Depth(1)));
} }
if block { if block {
realized = BlockElem::new() realized = if html {
.with_body(Some(BlockBody::Content(realized))) HtmlElem::new(tag::blockquote).with_body(Some(realized)).pack()
.pack() } else {
.spanned(self.span()); BlockElem::new().with_body(Some(BlockBody::Content(realized))).pack()
}
.spanned(self.span());
if let Some(attribution) = self.attribution(styles).as_ref() { if let Some(attribution) = self.attribution(styles).as_ref() {
let mut seq = vec![TextElem::packed('—'), SpaceElem::shared().clone()]; let attribution = match attribution {
Attribution::Content(content) => content.clone(),
Attribution::Label(label) => CiteElem::new(*label)
.with_form(Some(CitationForm::Prose))
.pack()
.spanned(self.span()),
};
let attribution =
[TextElem::packed('—'), SpaceElem::shared().clone(), attribution];
match attribution { if !html {
Attribution::Content(content) => { // Use v(0.9em, weak: true) to bring the attribution closer
seq.push(content.clone()); // to the quote.
} let gap = Spacing::Rel(Em::new(0.9).into());
Attribution::Label(label) => { let v = VElem::new(gap).with_weak(true).pack();
seq.push( realized += v;
CiteElem::new(*label)
.with_form(Some(CitationForm::Prose))
.pack()
.spanned(self.span()),
);
}
} }
realized += Content::sequence(attribution).aligned(Alignment::END);
// Use v(0.9em, weak: true) bring the attribution closer to the
// quote.
let gap = Spacing::Rel(Em::new(0.9).into());
let v = VElem::new(gap).with_weak(true).pack();
realized += v + Content::sequence(seq).aligned(Alignment::END);
} }
realized = PadElem::new(realized).pack(); if !html {
realized = PadElem::new(realized).pack();
}
} else if let Some(Attribution::Label(label)) = self.attribution(styles) { } else if let Some(Attribution::Label(label)) = self.attribution(styles) {
realized += SpaceElem::shared().clone() realized += SpaceElem::shared().clone()
+ CiteElem::new(*label).pack().spanned(self.span()); + CiteElem::new(*label).pack().spanned(self.span());