summaryrefslogtreecommitdiff
path: root/library/src/math/spacing.rs
diff options
context:
space:
mode:
Diffstat (limited to 'library/src/math/spacing.rs')
-rw-r--r--library/src/math/spacing.rs56
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,
}
}