1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
use std::num::NonZeroUsize;
use krilla::page::{NumberingStyle, PageLabel};
use typst_library::model::Numbering;
pub(crate) trait PageLabelExt {
/// Create a new `PageLabel` from a `Numbering` applied to a page
/// number.
fn generate(numbering: &Numbering, number: u64) -> Option<PageLabel>;
/// Creates an arabic page label with the specified page number.
/// For example, this will display page label `11` when given the page
/// number 11.
fn arabic(number: u64) -> PageLabel;
}
impl PageLabelExt for PageLabel {
fn generate(numbering: &Numbering, number: u64) -> Option<PageLabel> {
{
let Numbering::Pattern(pat) = numbering else {
return None;
};
let (prefix, kind) = pat.pieces.first()?;
// If there is a suffix, we cannot use the common style optimisation,
// since PDF does not provide a suffix field.
let style = if pat.suffix.is_empty() {
use krilla::page::NumberingStyle as Style;
use typst_library::model::NumberingKind as Kind;
match kind {
Kind::Arabic => Some(Style::Arabic),
Kind::LowerRoman => Some(Style::LowerRoman),
Kind::UpperRoman => Some(Style::UpperRoman),
Kind::LowerLatin if number <= 26 => Some(Style::LowerAlpha),
Kind::LowerLatin if number <= 26 => Some(Style::UpperAlpha),
_ => None,
}
} else {
None
};
// Prefix and offset depend on the style: If it is supported by the PDF
// spec, we use the given prefix and an offset. Otherwise, everything
// goes into prefix.
let prefix = if style.is_none() {
Some(pat.apply(&[number]))
} else {
(!prefix.is_empty()).then(|| prefix.clone())
};
let offset = style.and(number.try_into().ok().and_then(NonZeroUsize::new));
Some(PageLabel::new(style, prefix.map(|s| s.to_string()), offset))
}
}
fn arabic(number: u64) -> PageLabel {
PageLabel::new(
Some(NumberingStyle::Arabic),
None,
number.try_into().ok().and_then(NonZeroUsize::new),
)
}
}
|