use codex::styling::MathVariant;
use smallvec::smallvec;
use typst_utils::LazyHash;
use crate::foundations::{Cast, Content, Style, StyleChain, func};
use crate::math::EquationElem;
use crate::text::{FontFeatures, Tag, TextElem};
#[func(keywords = ["mathbf"])]
pub fn bold(
body: Content,
) -> Content {
body.set(EquationElem::bold, true)
}
#[func(keywords = ["mathup"])]
pub fn upright(
body: Content,
) -> Content {
body.set(EquationElem::italic, Some(false))
}
#[func(keywords = ["mathit"])]
pub fn italic(
body: Content,
) -> Content {
body.set(EquationElem::italic, Some(true))
}
#[func(keywords = ["mathrm"])]
pub fn serif(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::Plain))
}
#[func(title = "Sans Serif", keywords = ["mathsf"])]
pub fn sans(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::SansSerif))
}
#[func(title = "Calligraphic", keywords = ["mathcal", "chancery"])]
pub fn cal(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::Chancery))
}
#[func(title = "Script Style", keywords = ["mathscr", "roundhand"])]
pub fn scr(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::Roundhand))
}
#[func(title = "Fraktur", keywords = ["mathfrak"])]
pub fn frak(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::Fraktur))
}
#[func(title = "Monospace", keywords = ["mathtt"])]
pub fn mono(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::Monospace))
}
#[func(title = "Blackboard Bold", keywords = ["mathbb"])]
pub fn bb(
body: Content,
) -> Content {
body.set(EquationElem::variant, Some(MathVariant::DoubleStruck))
}
#[func(title = "Display Size", keywords = ["displaystyle"])]
pub fn display(
body: Content,
#[named]
#[default(false)]
cramped: bool,
) -> Content {
body.set(EquationElem::size, MathSize::Display)
.set(EquationElem::cramped, cramped)
}
#[func(title = "Inline Size", keywords = ["textstyle"])]
pub fn inline(
body: Content,
#[named]
#[default(false)]
cramped: bool,
) -> Content {
body.set(EquationElem::size, MathSize::Text)
.set(EquationElem::cramped, cramped)
}
#[func(title = "Script Size", keywords = ["scriptstyle"])]
pub fn script(
body: Content,
#[named]
#[default(true)]
cramped: bool,
) -> Content {
body.set(EquationElem::size, MathSize::Script)
.set(EquationElem::cramped, cramped)
}
#[func(title = "Script-Script Size", keywords = ["scriptscriptstyle"])]
pub fn sscript(
body: Content,
#[named]
#[default(true)]
cramped: bool,
) -> Content {
body.set(EquationElem::size, MathSize::ScriptScript)
.set(EquationElem::cramped, cramped)
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Cast)]
pub enum MathSize {
ScriptScript,
Script,
Text,
Display,
}
pub fn style_flac() -> LazyHash<Style> {
TextElem::features
.set(FontFeatures(smallvec![(Tag::from_bytes(b"flac"), 1)]))
.wrap()
}
pub fn style_dtls() -> LazyHash<Style> {
TextElem::features
.set(FontFeatures(smallvec![(Tag::from_bytes(b"dtls"), 1)]))
.wrap()
}
pub fn style_cramped() -> LazyHash<Style> {
EquationElem::cramped.set(true).wrap()
}
pub fn style_for_superscript(styles: StyleChain) -> LazyHash<Style> {
EquationElem::size
.set(match styles.get(EquationElem::size) {
MathSize::Display | MathSize::Text => MathSize::Script,
MathSize::Script | MathSize::ScriptScript => MathSize::ScriptScript,
})
.wrap()
}
pub fn style_for_subscript(styles: StyleChain) -> [LazyHash<Style>; 2] {
[style_for_superscript(styles), style_cramped()]
}
pub fn style_for_numerator(styles: StyleChain) -> LazyHash<Style> {
EquationElem::size
.set(match styles.get(EquationElem::size) {
MathSize::Display => MathSize::Text,
MathSize::Text => MathSize::Script,
MathSize::Script | MathSize::ScriptScript => MathSize::ScriptScript,
})
.wrap()
}
pub fn style_for_denominator(styles: StyleChain) -> [LazyHash<Style>; 2] {
[style_for_numerator(styles), style_cramped()]
}