diff options
Diffstat (limited to 'library/src/math/spacing.rs')
| -rw-r--r-- | library/src/math/spacing.rs | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/library/src/math/spacing.rs b/library/src/math/spacing.rs index fad1c863..17267238 100644 --- a/library/src/math/spacing.rs +++ b/library/src/math/spacing.rs @@ -1,6 +1,5 @@ use super::*; -pub(super) const ZERO: Em = Em::zero(); pub(super) const THIN: Em = Em::new(1.0 / 6.0); pub(super) const MEDIUM: Em = Em::new(2.0 / 9.0); pub(super) const THICK: Em = Em::new(5.0 / 18.0); @@ -14,49 +13,48 @@ pub(super) fn define(math: &mut Scope) { math.define("quad", HNode::strong(QUAD).pack()); } -/// Determine the spacing between two fragments in a given style. +/// Create the spacing between two fragments in a given style. pub(super) fn spacing( - left: &MathFragment, - right: &MathFragment, - style: MathStyle, - space: bool, - space_width: Em, -) -> Em { + l: &MathFragment, + space: Option<MathFragment>, + r: &MathFragment, +) -> Option<MathFragment> { use MathClass::*; - let script = style.size <= MathSize::Script; - let class = |frag: &MathFragment| frag.class().unwrap_or(Special); - match (class(left), class(right)) { + + let class = |f: &MathFragment| f.class().unwrap_or(Special); + let resolve = |v: Em, f: &MathFragment| { + Some(MathFragment::Spacing(f.font_size().map_or(Abs::zero(), |size| v.at(size)))) + }; + let script = + |f: &MathFragment| f.style().map_or(false, |s| s.size <= MathSize::Script); + + match (class(l), class(r)) { // No spacing before punctuation; thin spacing after punctuation, unless // in script size. - (_, Punctuation) => ZERO, - (Punctuation, _) if !script => THIN, + (_, Punctuation) => None, + (Punctuation, _) if !script(l) => resolve(THIN, l), // No spacing after opening delimiters and before closing delimiters. - (Opening, _) | (_, Closing) => ZERO, + (Opening, _) | (_, Closing) => None, // Thick spacing around relations, unless followed by a another relation // or in script size. - (Relation, Relation) => ZERO, - (Relation, _) | (_, Relation) if !script => THICK, + (Relation, Relation) => None, + (Relation, _) if !script(l) => resolve(THICK, l), + (_, Relation) if !script(r) => resolve(THICK, r), // Medium spacing around binary operators, unless in script size. - (Binary, _) | (_, Binary) if !script => MEDIUM, + (Binary, _) if !script(l) => resolve(MEDIUM, l), + (_, Binary) if !script(r) => resolve(MEDIUM, r), // Thin spacing around large operators, unless next to a delimiter. - (Large, Opening | Fence) | (Closing | Fence, Large) => ZERO, - (Large, _) | (_, Large) => THIN, + (Large, Opening | Fence) | (Closing | Fence, Large) => None, + (Large, _) => resolve(THIN, l), + (_, Large) => resolve(THIN, r), // Spacing around spaced frames. - _ if space && (is_spaced(left) || is_spaced(right)) => space_width, - - _ => ZERO, - } -} + _ if (l.is_spaced() || r.is_spaced()) => space, -/// Whether this fragment should react to adjacent spaces. -fn is_spaced(fragment: &MathFragment) -> bool { - match fragment { - MathFragment::Frame(frame) => frame.spaced, - _ => fragment.class() == Some(MathClass::Fence), + _ => None, } } |
