mirror of
https://github.com/typst/typst
synced 2025-08-19 01:18:32 +08:00
Merge 7e418ad1482102e7e53a854f99e6a91283df48a2 into 36ecbb2c8dccc1a31c43fee1466f1425844d8607
This commit is contained in:
commit
d0243ea7f5
@ -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;
|
||||
|
||||
@ -49,6 +51,7 @@ pub fn define(global: &mut Scope) {
|
||||
global.define_elem::<RefElem>();
|
||||
global.define_elem::<LinkElem>();
|
||||
global.define_elem::<OutlineElem>();
|
||||
global.define_elem::<TitleElem>();
|
||||
global.define_elem::<HeadingElem>();
|
||||
global.define_elem::<FigureElem>();
|
||||
global.define_elem::<FootnoteElem>();
|
||||
|
68
crates/typst-library/src/model/title.rs
Normal file
68
crates/typst-library/src/model/title.rs
Normal file
@ -0,0 +1,68 @@
|
||||
use crate::{
|
||||
diag::SourceResult,
|
||||
engine::Engine,
|
||||
foundations::{
|
||||
elem, Content, NativeElement, Packed, Show, ShowSet, Smart, StyleChain, Styles,
|
||||
TargetElem,
|
||||
},
|
||||
html::{tag, HtmlElem},
|
||||
introspection::Locatable,
|
||||
layout::{AlignElem, Alignment, BlockBody, BlockElem, Em},
|
||||
text::{FontWeight, TextElem, TextSize},
|
||||
};
|
||||
|
||||
/// A document title.
|
||||
///
|
||||
/// Should be used to display the main title of the whole document, and should
|
||||
/// occur only once per document.
|
||||
///
|
||||
/// Shows as `h1` in HTML. In contrast, a heading of level 1
|
||||
/// (created with `= Some Heading`) will show as `h2`.
|
||||
///
|
||||
/// # Example
|
||||
/// ```example
|
||||
/// #title[Interstellar Mail Delivery]
|
||||
///
|
||||
/// = Introduction
|
||||
/// In recent years, ...
|
||||
/// ```
|
||||
#[elem(Locatable, Show, ShowSet)]
|
||||
pub struct TitleElem {
|
||||
/// The content of the title.
|
||||
#[required]
|
||||
pub body: Content,
|
||||
}
|
||||
|
||||
impl Show for Packed<TitleElem> {
|
||||
#[typst_macros::time(name = "title", span = self.span())]
|
||||
fn show(&self, _engine: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
|
||||
let html = TargetElem::target_in(styles).is_html();
|
||||
|
||||
let span = self.span();
|
||||
let realized = self.body().clone();
|
||||
|
||||
Ok(if html {
|
||||
HtmlElem::new(tag::h1).with_body(Some(realized)).pack().spanned(span)
|
||||
} else {
|
||||
let realized = BlockBody::Content(realized);
|
||||
BlockElem::new().with_body(Some(realized)).pack().spanned(span)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ShowSet for Packed<TitleElem> {
|
||||
fn show_set(&self, _styles: StyleChain) -> Styles {
|
||||
const SIZE: Em = Em::new(1.6);
|
||||
const ABOVE: Em = Em::new(1.125);
|
||||
const BELOW: Em = Em::new(0.75);
|
||||
|
||||
let mut out = Styles::new();
|
||||
out.set(TextElem::set_size(TextSize(SIZE.into())));
|
||||
out.set(TextElem::set_weight(FontWeight::BOLD));
|
||||
out.set(BlockElem::set_above(Smart::Custom(ABOVE.into())));
|
||||
out.set(BlockElem::set_below(Smart::Custom(BELOW.into())));
|
||||
out.set(BlockElem::set_sticky(true));
|
||||
out.set(AlignElem::set_alignment(Alignment::CENTER));
|
||||
out
|
||||
}
|
||||
}
|
15
tests/ref/html/title-and-heading.html
Normal file
15
tests/ref/html/title-and-heading.html
Normal file
@ -0,0 +1,15 @@
|
||||
<!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>
|
12
tests/ref/html/title-basic.html
Normal file
12
tests/ref/html/title-basic.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!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>
|
BIN
tests/ref/title-and-heading.png
Normal file
BIN
tests/ref/title-and-heading.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 KiB |
BIN
tests/ref/title-basic.png
Normal file
BIN
tests/ref/title-basic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 679 B |
BIN
tests/ref/title-show-rule.png
Normal file
BIN
tests/ref/title-show-rule.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
12
tests/suite/model/title.typ
Normal file
12
tests/suite/model/title.typ
Normal file
@ -0,0 +1,12 @@
|
||||
// Test title element.
|
||||
|
||||
--- title-basic render html ---
|
||||
#title[Some Title]
|
||||
|
||||
--- title-and-heading render html ---
|
||||
#title([A cool title])
|
||||
= Some level one heading
|
||||
|
||||
--- title-show-rule ---
|
||||
#show title: set text(3em)
|
||||
#title[Some Title]
|
Loading…
x
Reference in New Issue
Block a user