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)]
32pub struct TitleElem {
33 #[positional]
46 pub body: Smart<Content>,
47}
48
49impl TitleElem {
50 pub fn resolve_body(&self, styles: StyleChain) -> HintedStrResult<Content> {
51 match self.body.get_cloned(styles) {
52 Smart::Auto => styles
53 .get_cloned(DocumentElem::title)
54 .ok_or("document title was not set")
55 .hint("set the title with `set document(title: [...])`")
56 .hint("or provide an explicit body with `title[..]`"),
57 Smart::Custom(body) => Ok(body),
58 }
59 }
60}
61
62impl ShowSet for Packed<TitleElem> {
63 fn show_set(&self, _styles: StyleChain) -> Styles {
64 const SIZE: Em = Em::new(1.7);
65 const ABOVE: Em = Em::new(1.125);
66 const BELOW: Em = Em::new(0.75);
67
68 let mut out = Styles::new();
69 out.set(TextElem::size, TextSize(SIZE.into()));
70 out.set(TextElem::weight, FontWeight::BOLD);
71 out.set(BlockElem::above, Smart::Custom(ABOVE.into()));
72 out.set(BlockElem::below, Smart::Custom(BELOW.into()));
73 out.set(BlockElem::sticky, true);
74 out
75 }
76}