typst_library/model/
emph.rs

1use crate::diag::SourceResult;
2use crate::engine::Engine;
3use crate::foundations::{
4    elem, Content, NativeElement, Packed, Show, StyleChain, TargetElem,
5};
6use crate::html::{tag, HtmlElem};
7use crate::text::{ItalicToggle, TextElem};
8
9/// Emphasizes content by toggling italics.
10///
11/// - If the current [text style]($text.style) is `{"normal"}`, this turns it
12///   into `{"italic"}`.
13/// - If it is already `{"italic"}` or `{"oblique"}`, it turns it back to
14///   `{"normal"}`.
15///
16/// # Example
17/// ```example
18/// This is _emphasized._ \
19/// This is #emph[too.]
20///
21/// #show emph: it => {
22///   text(blue, it.body)
23/// }
24///
25/// This is _emphasized_ differently.
26/// ```
27///
28/// # Syntax
29/// This function also has dedicated syntax: To emphasize content, simply
30/// enclose it in underscores (`_`). Note that this only works at word
31/// boundaries. To emphasize part of a word, you have to use the function.
32#[elem(title = "Emphasis", keywords = ["italic"], Show)]
33pub struct EmphElem {
34    /// The content to emphasize.
35    #[required]
36    pub body: Content,
37}
38
39impl Show for Packed<EmphElem> {
40    #[typst_macros::time(name = "emph", span = self.span())]
41    fn show(&self, _: &mut Engine, styles: StyleChain) -> SourceResult<Content> {
42        let body = self.body.clone();
43        Ok(if TargetElem::target_in(styles).is_html() {
44            HtmlElem::new(tag::em)
45                .with_body(Some(body))
46                .pack()
47                .spanned(self.span())
48        } else {
49            body.styled(TextElem::set_emph(ItalicToggle(true)))
50        })
51    }
52}