typst_library/model/
title.rs1use crate::diag::{Hint, HintedStrResult};
2use crate::foundations::{Content, Packed, ShowSet, Smart, StyleChain, Styles, elem};
3use crate::introspection::{Locatable, Tagged};
4use crate::layout::{BlockElem, Em};
5use crate::model::DocumentElem;
6use crate::text::{FontWeight, TextElem, TextSize};
7
8#[elem(Locatable, Tagged, ShowSet)]
33pub struct TitleElem {
34 #[positional]
47 pub body: Smart<Content>,
48}
49
50impl TitleElem {
51 pub fn resolve_body(&self, styles: StyleChain) -> HintedStrResult<Content> {
52 match self.body.get_cloned(styles) {
53 Smart::Auto => styles
54 .get_cloned(DocumentElem::title)
55 .ok_or("document title was not set")
56 .hint("set the title with `set document(title: [...])`")
57 .hint("or provide an explicit body with `title[..]`"),
58 Smart::Custom(body) => Ok(body),
59 }
60 }
61}
62
63impl ShowSet for Packed<TitleElem> {
64 fn show_set(&self, _styles: StyleChain) -> Styles {
65 const SIZE: Em = Em::new(1.7);
66 const ABOVE: Em = Em::new(1.125);
67 const BELOW: Em = Em::new(0.75);
68
69 let mut out = Styles::new();
70 out.set(TextElem::size, TextSize(SIZE.into()));
71 out.set(TextElem::weight, FontWeight::BOLD);
72 out.set(BlockElem::above, Smart::Custom(ABOVE.into()));
73 out.set(BlockElem::below, Smart::Custom(BELOW.into()));
74 out.set(BlockElem::sticky, true);
75 out
76 }
77}