mirror of
https://github.com/typst/typst
synced 2025-05-20 03:55:29 +08:00
66 lines
2.1 KiB
Rust
66 lines
2.1 KiB
Rust
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);
|
|
pub(super) const QUAD: Em = Em::new(1.0);
|
|
|
|
/// Hook up all spacings.
|
|
pub(super) fn define(math: &mut Scope) {
|
|
math.define("thin", HNode::strong(THIN).pack());
|
|
math.define("med", HNode::strong(MEDIUM).pack());
|
|
math.define("thick", HNode::strong(THICK).pack());
|
|
math.define("quad", HNode::strong(QUAD).pack());
|
|
}
|
|
|
|
/// Determine 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 {
|
|
use MathClass::*;
|
|
let script = style.size <= MathSize::Script;
|
|
let (Some(l), Some(r)) = (left.class(), right.class()) else {
|
|
return ZERO;
|
|
};
|
|
|
|
match (l, r) {
|
|
// No spacing before punctuation; thin spacing after punctuation, unless
|
|
// in script size.
|
|
(_, Punctuation) => ZERO,
|
|
(Punctuation, _) if !script => THIN,
|
|
|
|
// No spacing after opening delimiters and before closing delimiters.
|
|
(Opening, _) | (_, Closing) => ZERO,
|
|
|
|
// Thick spacing around relations, unless followed by a another relation
|
|
// or in script size.
|
|
(Relation, Relation) => ZERO,
|
|
(Relation, _) | (_, Relation) if !script => THICK,
|
|
|
|
// Medium spacing around binary operators, unless in script size.
|
|
(Binary, _) | (_, Binary) if !script => MEDIUM,
|
|
|
|
// Thin spacing around large operators, unless next to a delimiter.
|
|
(Large, Opening | Fence) | (Closing | Fence, Large) => ZERO,
|
|
(Large, _) | (_, Large) => THIN,
|
|
|
|
// Spacing around spaced frames.
|
|
_ if space && (is_spaced(left) || is_spaced(right)) => space_width,
|
|
|
|
_ => ZERO,
|
|
}
|
|
}
|
|
|
|
/// 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),
|
|
}
|
|
}
|