summaryrefslogtreecommitdiff
path: root/library/src/math/mod.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-05-22 20:50:15 +0200
committerLaurenz <laurmaedje@gmail.com>2023-05-22 20:56:30 +0200
commitf4fd6855e7fb833a2125d2e81aa3b9f548b18170 (patch)
tree6e3675ca8c4b9f9fae05a598e753e3a410d2cce2 /library/src/math/mod.rs
parent183997d5fe76cf0b41fd26bfa29d166071d239eb (diff)
Fix and simplify reference supplements
- Fixes #873 by properly handling `none` supplement for`ref`. - Fixes #523 by adding a `supplement` parameter to `math.equation` - In the future, we can remove supplement functions in favor of show-set rules with fine-grained selectors. Currently, this is not possible because show-set + synthesis doesn't play well together
Diffstat (limited to 'library/src/math/mod.rs')
-rw-r--r--library/src/math/mod.rs100
1 files changed, 68 insertions, 32 deletions
diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs
index c4c18b87..f0e42e68 100644
--- a/library/src/math/mod.rs
+++ b/library/src/math/mod.rs
@@ -42,8 +42,10 @@ use self::fragment::*;
use self::row::*;
use self::spacing::*;
use crate::layout::{HElem, ParElem, Spacing};
-use crate::meta::Refable;
-use crate::meta::{Count, Counter, CounterUpdate, LocalName, Numbering};
+use crate::meta::Supplement;
+use crate::meta::{
+ Count, Counter, CounterUpdate, LocalName, Numbering, Outlinable, Refable,
+};
use crate::prelude::*;
use crate::text::{
families, variant, FontFamily, FontList, LinebreakElem, SpaceElem, TextElem, TextSize,
@@ -140,7 +142,8 @@ pub fn module() -> Module {
/// Display: Equation
/// Category: math
#[element(
- Locatable, Synthesize, Show, Finalize, Layout, LayoutMath, Count, LocalName, Refable
+ Locatable, Synthesize, Show, Finalize, Layout, LayoutMath, Count, LocalName, Refable,
+ Outlinable
)]
pub struct EquationElem {
/// Whether the equation is displayed as a separate block.
@@ -160,15 +163,44 @@ pub struct EquationElem {
/// ```
pub numbering: Option<Numbering>,
+ /// A supplement for the equation.
+ ///
+ /// For references to equations, this is added before the referenced number.
+ ///
+ /// If a function is specified, it is passed the referenced equation and
+ /// should return content.
+ ///
+ /// ```example
+ /// #set math.equation(numbering: "(1)", supplement: [Eq.])
+ ///
+ /// We define:
+ /// $ phi.alt := (1 + sqrt(5)) / 2 $ <ratio>
+ ///
+ /// With @ratio, we get:
+ /// $ F_n = floor(1 / sqrt(5) phi.alt^n) $
+ /// ```
+ pub supplement: Smart<Option<Supplement>>,
+
/// The contents of the equation.
#[required]
pub body: Content,
}
impl Synthesize for EquationElem {
- fn synthesize(&mut self, _vt: &mut Vt, styles: StyleChain) -> SourceResult<()> {
+ fn synthesize(&mut self, vt: &mut Vt, styles: StyleChain) -> SourceResult<()> {
+ // Resolve the supplement.
+ let supplement = match self.supplement(styles) {
+ Smart::Auto => TextElem::packed(self.local_name_in(styles)),
+ Smart::Custom(None) => Content::empty(),
+ Smart::Custom(Some(supplement)) => {
+ supplement.resolve(vt, [self.clone().into()])?
+ }
+ };
+
self.push_block(self.block(styles));
self.push_numbering(self.numbering(styles));
+ self.push_supplement(Smart::Custom(Some(Supplement::Content(supplement))));
+
Ok(())
}
}
@@ -302,41 +334,45 @@ impl LocalName for EquationElem {
}
impl Refable for EquationElem {
- fn reference(
- &self,
- vt: &mut Vt,
- supplement: Option<Content>,
- lang: Lang,
- region: Option<Region>,
- ) -> SourceResult<Content> {
- // first we create the supplement of the heading
- let mut supplement =
- supplement.unwrap_or_else(|| TextElem::packed(self.local_name(lang, region)));
-
- // we append a space if the supplement is not empty
- if !supplement.is_empty() {
- supplement += TextElem::packed('\u{a0}')
- };
-
- // we check for a numbering
- let Some(numbering) = self.numbering(StyleChain::default()) else {
- bail!(self.span(), "only numbered equations can be referenced");
- };
-
- // we get the counter and display it
- let numbers = Counter::of(Self::func())
- .at(vt, self.0.location().expect("missing location"))?
- .display(vt, &numbering.trimmed())?;
+ fn supplement(&self) -> Content {
+ // After synthesis, this should always be custom content.
+ match self.supplement(StyleChain::default()) {
+ Smart::Custom(Some(Supplement::Content(content))) => content,
+ _ => Content::empty(),
+ }
+ }
- Ok(supplement + numbers)
+ fn counter(&self) -> Counter {
+ Counter::of(Self::func())
}
fn numbering(&self) -> Option<Numbering> {
self.numbering(StyleChain::default())
}
+}
- fn counter(&self) -> Counter {
- Counter::of(Self::func())
+impl Outlinable for EquationElem {
+ fn outline(&self, vt: &mut Vt) -> SourceResult<Option<Content>> {
+ let Some(numbering) = self.numbering(StyleChain::default()) else {
+ return Ok(None);
+ };
+
+ // After synthesis, this should always be custom content.
+ let mut supplement = match self.supplement(StyleChain::default()) {
+ Smart::Custom(Some(Supplement::Content(content))) => content,
+ _ => Content::empty(),
+ };
+
+ if !supplement.is_empty() {
+ supplement += TextElem::packed("\u{a0}");
+ }
+
+ let numbers = self
+ .counter()
+ .at(vt, self.0.location().unwrap())?
+ .display(vt, &numbering)?;
+
+ Ok(Some(supplement + numbers))
}
}