typst_library/foundations/
target.rs

1use comemo::Tracked;
2
3use crate::diag::HintedStrResult;
4use crate::foundations::{elem, func, Cast, Context};
5
6/// The export target.
7#[derive(Debug, Default, Copy, Clone, PartialEq, Hash, Cast)]
8pub enum Target {
9    /// The target that is used for paged, fully laid-out content.
10    #[default]
11    Paged,
12    /// The target that is used for HTML export.
13    Html,
14}
15
16impl Target {
17    /// Whether this is the HTML target.
18    pub fn is_html(self) -> bool {
19        self == Self::Html
20    }
21}
22
23/// This element exists solely to host the `target` style chain field.
24/// It is never constructed and not visible to users.
25#[elem]
26pub struct TargetElem {
27    /// The compilation target.
28    pub target: Target,
29}
30
31/// Returns the current export target.
32///
33/// This function returns either
34/// - `{"paged"}` (for PDF, PNG, and SVG export), or
35/// - `{"html"}` (for HTML export).
36///
37/// The design of this function is not yet finalized and for this reason it is
38/// guarded behind the `html` feature. Visit the [HTML documentation
39/// page]($html) for more details.
40///
41/// # When to use it
42/// This function allows you to format your document properly across both HTML
43/// and paged export targets. It should primarily be used in templates and show
44/// rules, rather than directly in content. This way, the document's contents
45/// can be fully agnostic to the export target and content can be shared between
46/// PDF and HTML export.
47///
48/// # Varying targets
49/// This function is [contextual]($context) as the target can vary within a
50/// single compilation: When exporting to HTML, the target will be `{"paged"}`
51/// while within an [`html.frame`].
52///
53/// # Example
54/// ```example
55/// #let kbd(it) = context {
56///   if target() == "html" {
57///     html.elem("kbd", it)
58///   } else {
59///     set text(fill: rgb("#1f2328"))
60///     let r = 3pt
61///     box(
62///       fill: rgb("#f6f8fa"),
63///       stroke: rgb("#d1d9e0b3"),
64///       outset: (y: r),
65///       inset: (x: r),
66///       radius: r,
67///       raw(it)
68///     )
69///   }
70/// }
71///
72/// Press #kbd("F1") for help.
73/// ```
74#[func(contextual)]
75pub fn target(context: Tracked<Context>) -> HintedStrResult<Target> {
76    Ok(TargetElem::target_in(context.styles()?))
77}