Add `title` element (#5618)
Co-authored-by: Laurenz <laurmaedje@gmail.com>
This commit is contained in:
parent
6de2d9586a
commit
d0026093d4
|
|
@ -11,7 +11,7 @@ use typst_library::layout::{OuterVAlignment, Sizing};
|
|||
use typst_library::model::{
|
||||
Attribution, CiteElem, CiteGroup, Destination, EmphElem, EnumElem, FigureCaption,
|
||||
FigureElem, HeadingElem, LinkElem, LinkTarget, ListElem, ParbreakElem, QuoteElem,
|
||||
RefElem, StrongElem, TableCell, TableElem, TermsElem,
|
||||
RefElem, StrongElem, TableCell, TableElem, TermsElem, TitleElem,
|
||||
};
|
||||
use typst_library::text::{
|
||||
HighlightElem, LinebreakElem, OverlineElem, RawElem, RawLine, SmallcapsElem,
|
||||
|
|
@ -32,6 +32,7 @@ pub fn register(rules: &mut NativeRuleMap) {
|
|||
rules.register(Html, ENUM_RULE);
|
||||
rules.register(Html, TERMS_RULE);
|
||||
rules.register(Html, LINK_RULE);
|
||||
rules.register(Html, TITLE_RULE);
|
||||
rules.register(Html, HEADING_RULE);
|
||||
rules.register(Html, FIGURE_RULE);
|
||||
rules.register(Html, FIGURE_CAPTION_RULE);
|
||||
|
|
@ -161,6 +162,12 @@ const LINK_RULE: ShowFn<LinkElem> = |elem, engine, _| {
|
|||
.pack())
|
||||
};
|
||||
|
||||
const TITLE_RULE: ShowFn<TitleElem> = |elem, _, styles| {
|
||||
Ok(HtmlElem::new(tag::h1)
|
||||
.with_body(Some(elem.resolve_body(styles).at(elem.span())?))
|
||||
.pack())
|
||||
};
|
||||
|
||||
const HEADING_RULE: ShowFn<HeadingElem> = |elem, engine, styles| {
|
||||
let span = elem.span();
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use typst_library::model::{
|
|||
Attribution, BibliographyElem, CiteElem, CiteGroup, CslSource, Destination, EmphElem,
|
||||
EnumElem, FigureCaption, FigureElem, FootnoteElem, FootnoteEntry, HeadingElem,
|
||||
LinkElem, ListElem, Outlinable, OutlineElem, OutlineEntry, ParElem, ParbreakElem,
|
||||
QuoteElem, RefElem, StrongElem, TableCell, TableElem, TermsElem, Works,
|
||||
QuoteElem, RefElem, StrongElem, TableCell, TableElem, TermsElem, TitleElem, Works,
|
||||
};
|
||||
use typst_library::pdf::EmbedElem;
|
||||
use typst_library::text::{
|
||||
|
|
@ -47,6 +47,7 @@ pub fn register(rules: &mut NativeRuleMap) {
|
|||
rules.register(Paged, ENUM_RULE);
|
||||
rules.register(Paged, TERMS_RULE);
|
||||
rules.register(Paged, LINK_RULE);
|
||||
rules.register(Paged, TITLE_RULE);
|
||||
rules.register(Paged, HEADING_RULE);
|
||||
rules.register(Paged, FIGURE_RULE);
|
||||
rules.register(Paged, FIGURE_CAPTION_RULE);
|
||||
|
|
@ -216,6 +217,12 @@ const LINK_RULE: ShowFn<LinkElem> = |elem, engine, _| {
|
|||
Ok(body.linked(dest))
|
||||
};
|
||||
|
||||
const TITLE_RULE: ShowFn<TitleElem> = |elem, _, styles| {
|
||||
Ok(BlockElem::new()
|
||||
.with_body(Some(BlockBody::Content(elem.resolve_body(styles).at(elem.span())?)))
|
||||
.pack())
|
||||
};
|
||||
|
||||
const HEADING_RULE: ShowFn<HeadingElem> = |elem, engine, styles| {
|
||||
const SPACING_TO_NUMBERING: Em = Em::new(0.3);
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ mod reference;
|
|||
mod strong;
|
||||
mod table;
|
||||
mod terms;
|
||||
mod title;
|
||||
|
||||
pub use self::bibliography::*;
|
||||
pub use self::cite::*;
|
||||
|
|
@ -39,6 +40,7 @@ pub use self::reference::*;
|
|||
pub use self::strong::*;
|
||||
pub use self::table::*;
|
||||
pub use self::terms::*;
|
||||
pub use self::title::*;
|
||||
|
||||
use crate::foundations::Scope;
|
||||
|
||||
|
|
@ -54,6 +56,7 @@ pub fn define(global: &mut Scope) {
|
|||
global.define_elem::<EnumElem>();
|
||||
global.define_elem::<TermsElem>();
|
||||
global.define_elem::<LinkElem>();
|
||||
global.define_elem::<TitleElem>();
|
||||
global.define_elem::<HeadingElem>();
|
||||
global.define_elem::<FigureElem>();
|
||||
global.define_elem::<QuoteElem>();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
use crate::diag::{Hint, HintedStrResult};
|
||||
use crate::foundations::{Content, Packed, ShowSet, Smart, StyleChain, Styles, elem};
|
||||
use crate::introspection::Locatable;
|
||||
use crate::layout::{BlockElem, Em};
|
||||
use crate::model::DocumentElem;
|
||||
use crate::text::{FontWeight, TextElem, TextSize};
|
||||
|
||||
/// A document title.
|
||||
///
|
||||
/// This should be used to display the main title of the whole document and
|
||||
/// should occur only once per document. In contrast, level 1
|
||||
/// [headings]($heading) are intended to be used for the top-level sections of
|
||||
/// the document.
|
||||
///
|
||||
/// Note that additional frontmatter (like an author list) that should appear
|
||||
/// together with the title does not belong in its body.
|
||||
///
|
||||
/// In HTML export, this shows as a `h1` element while level 1 headings show
|
||||
/// as `h2` elements.
|
||||
///
|
||||
/// # Example
|
||||
/// ```example
|
||||
/// #set document(
|
||||
/// title: [Interstellar Mail Delivery]
|
||||
/// )
|
||||
///
|
||||
/// #title()
|
||||
///
|
||||
/// = Introduction
|
||||
/// In recent years, ...
|
||||
/// ```
|
||||
#[elem(Locatable, ShowSet)]
|
||||
pub struct TitleElem {
|
||||
/// The content of the title.
|
||||
///
|
||||
/// When omitted (or `{auto}`), this will default to [`document.title`]. In
|
||||
/// this case, a document title must have been previously set with
|
||||
/// `{set document(title: [..])}`.
|
||||
///
|
||||
/// ```example
|
||||
/// #set document(title: "Course ABC, Homework 1")
|
||||
/// #title[Homework 1]
|
||||
///
|
||||
/// ...
|
||||
/// ```
|
||||
#[positional]
|
||||
pub body: Smart<Content>,
|
||||
}
|
||||
|
||||
impl TitleElem {
|
||||
pub fn resolve_body(&self, styles: StyleChain) -> HintedStrResult<Content> {
|
||||
match self.body.get_cloned(styles) {
|
||||
Smart::Auto => styles
|
||||
.get_cloned(DocumentElem::title)
|
||||
.ok_or("document title was not set")
|
||||
.hint("set the title with `set document(title: [...])`")
|
||||
.hint("or provide an explicit body with `title[..]`"),
|
||||
Smart::Custom(body) => Ok(body),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ShowSet for Packed<TitleElem> {
|
||||
fn show_set(&self, _styles: StyleChain) -> Styles {
|
||||
const SIZE: Em = Em::new(1.7);
|
||||
const ABOVE: Em = Em::new(1.125);
|
||||
const BELOW: Em = Em::new(0.75);
|
||||
|
||||
let mut out = Styles::new();
|
||||
out.set(TextElem::size, TextSize(SIZE.into()));
|
||||
out.set(TextElem::weight, FontWeight::BOLD);
|
||||
out.set(BlockElem::above, Smart::Custom(ABOVE.into()));
|
||||
out.set(BlockElem::below, Smart::Custom(BELOW.into()));
|
||||
out.set(BlockElem::sticky, true);
|
||||
out
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>A cool title</h1>
|
||||
<h2>Some level one heading</h2>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Some Title</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>My title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My display title</h1>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>My title</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>My title</h1>
|
||||
<h2>A level one heading</h2>
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 615 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
|
|
@ -0,0 +1,24 @@
|
|||
// Test title element.
|
||||
|
||||
--- title render html ---
|
||||
#set document(title: "My title")
|
||||
#title()
|
||||
= A level one heading
|
||||
|
||||
--- title-with-body render html ---
|
||||
#set document(title: "My title")
|
||||
#title[My display title]
|
||||
|
||||
--- title-with-body-auto render ---
|
||||
#set document(title: "My title")
|
||||
#title(auto)
|
||||
|
||||
--- title-show-set ---
|
||||
#show title: set text(blue)
|
||||
#title[A blue title]
|
||||
|
||||
--- title-unset ---
|
||||
// Error: 2-9 document title was not set
|
||||
// Hint: 2-9 set the title with `set document(title: [...])`
|
||||
// Hint: 2-9 or provide an explicit body with `title[..]`
|
||||
#title()
|
||||
Loading…
Reference in New Issue