diff --git a/docs/src/reference/groups.yml b/docs/src/reference/groups.yml index 5d8b330ef..cd85b820b 100644 --- a/docs/src/reference/groups.yml +++ b/docs/src/reference/groups.yml @@ -16,6 +16,16 @@ These functions are distinct from the [`text`]($func/text) function because math fonts contain multiple variants of each letter. +- name: sizes + display: Sizes + functions: ["display", "inline", "script", "sscript"] + description: | + Forced size styles for expressions within formulas. + + These functions allow manual configuration of the size of equation elements + to make them look as in a display/inline equation or as if used in a root or + sub/superscripts. + - name: underover display: Under/Over functions: [ diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs index f0e42e68c..3a067c1b0 100644 --- a/library/src/math/mod.rs +++ b/library/src/math/mod.rs @@ -100,6 +100,11 @@ pub fn module() -> Module { math.define("mono", mono); math.define("bb", bb); + math.define("display", display); + math.define("inline", inline); + math.define("script", script); + math.define("sscript", sscript); + // Text operators. math.define("op", OpElem::func()); op::define(&mut math); diff --git a/library/src/math/style.rs b/library/src/math/style.rs index d65058e6b..e0e1ccadf 100644 --- a/library/src/math/style.rs +++ b/library/src/math/style.rs @@ -178,6 +178,124 @@ pub fn bb( .into() } +/// Forced display style in math. +/// +/// This is the normal size for display equations. +/// +/// ## Example { #example } +/// ```example +/// $sum_i x_i/2 = display(sum_i x/2)$ +/// ``` +/// +/// Display: Display Size +/// Category: math +/// Returns: content +#[func] +pub fn display( + /// The content to size. + body: Content, + /// Whether to impose a height restriction for exponents, like regular sub- + /// and superscripts do. + #[named] + #[default(false)] + cramp: bool, +) -> Value { + MathStyleElem::new(body) + .with_size(Some(MathSize::Display)) + .with_cramp(Some(cramp)) + .pack() + .into() +} + +/// Forced inline (text) style in math. +/// +/// This is the normal size for inline equations. +/// +/// ## Example { #example } +/// ```example +/// $ sum_i x_i/2 +/// = inline(sum_i x_i/2) $ +/// ``` +/// +/// Display: Inline Size +/// Category: math +/// Returns: content +#[func] +pub fn inline( + /// The content to size. + body: Content, + /// Whether to impose a height restriction for exponents, like regular sub- + /// and superscripts do. + #[named] + #[default(false)] + cramp: bool, +) -> Value { + MathStyleElem::new(body) + .with_size(Some(MathSize::Text)) + .with_cramp(Some(cramp)) + .pack() + .into() +} + +/// Forced script style in math. +/// +/// This is the smaller size used in powers or sub- or superscripts. +/// +/// ## Example { #example } +/// ```example +/// $sum_i x_i/2 = script(sum_i x_i/2)$ +/// ``` +/// +/// Display: Script Size +/// Category: math +/// Returns: content +#[func] +pub fn script( + /// The content to size. + body: Content, + /// Whether to impose a height restriction for exponents, like regular sub- + /// and superscripts do. + #[named] + #[default(true)] + cramp: bool, +) -> Value { + MathStyleElem::new(body) + .with_size(Some(MathSize::Script)) + .with_cramp(Some(cramp)) + .pack() + .into() +} + +/// Forced second script style in math. +/// +/// This is the smallest size, used in second-level sub- and superscripts +/// (script of the script). +/// +/// ## Example { #example } +/// ```example +/// $sum_i x_i/2 = sscript(sum_i x_i/2)$ +/// ``` +/// +/// Display: Script-Script Size +/// Category: math +/// Returns: content +#[func] +pub fn sscript( + /// The content to size. + body: Content, + /// Whether to impose a height restriction for exponents, like regular sub- + /// and superscripts do. + #[named] + #[default(true)] + cramp: bool, +) -> Value { + MathStyleElem::new(body) + .with_size(Some(MathSize::ScriptScript)) + .with_cramp(Some(cramp)) + .pack() + .into() +} + /// A font variant in math. /// /// Display: Bold @@ -196,6 +314,12 @@ pub struct MathStyleElem { /// Whether to use italic glyphs. pub italic: Option, + + /// Whether to use forced size + pub size: Option, + + /// Whether to limit height of exponents + pub cramp: Option, } impl LayoutMath for MathStyleElem { @@ -211,6 +335,12 @@ impl LayoutMath for MathStyleElem { if let Some(italic) = self.italic(StyleChain::default()) { style = style.with_italic(italic); } + if let Some(size) = self.size(StyleChain::default()) { + style = style.with_size(size); + } + if let Some(cramped) = self.cramp(StyleChain::default()) { + style = style.with_cramped(cramped); + } ctx.style(style); self.body().layout_math(ctx)?; ctx.unstyle(); @@ -295,7 +425,7 @@ impl MathStyle { /// The size of elements in an equation. /// /// See the TeXbook p. 141. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Cast)] pub enum MathSize { /// Second-level sub- and superscripts. ScriptScript, diff --git a/tests/ref/math/style.png b/tests/ref/math/style.png index c5e722582..39ecc4417 100644 Binary files a/tests/ref/math/style.png and b/tests/ref/math/style.png differ diff --git a/tests/typ/math/style.typ b/tests/typ/math/style.typ index 67a410aff..5ee0636f0 100644 --- a/tests/typ/math/style.typ +++ b/tests/typ/math/style.typ @@ -12,6 +12,12 @@ $A, italic(A), upright(A), bold(A), bold(upright(A)), \ bb("hello") + bold(cal("world")), \ mono("SQRT")(x) wreath mono(123 + 456)$ +--- +// Test forcing math size +$a/b, display(a/b), display(a)/display(b), inline(a/b), script(a/b), sscript(a/b) \ + mono(script(a/b)), script(mono(a/b))\ + script(a^b, cramp: #true), script(a^b, cramp: #false)$ + --- // Test a few style exceptions. $h, bb(N), cal(R), Theta, italic(Theta), sans(Theta), sans(italic(Theta))$