Adjust attach() per TeXbook Appendix G 18a (#1129)

This commit is contained in:
Leedehai 2023-05-11 11:38:04 -04:00 committed by GitHub
parent d1dec299a7
commit e8de8a49c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 34 additions and 2 deletions

View File

@ -299,6 +299,7 @@ fn compute_shifts_up_and_down(
let mut shift_up = Abs::zero();
let mut shift_down = Abs::zero();
let is_char_box = is_character_box(base);
for e in [tl, tr].into_iter().flatten() {
let ascent = match &base {
@ -308,13 +309,13 @@ fn compute_shifts_up_and_down(
shift_up = shift_up
.max(sup_shift_up)
.max(ascent - sup_drop_max)
.max(if is_char_box { Abs::zero() } else { ascent - sup_drop_max })
.max(sup_bottom_min + e.descent());
}
for e in [bl, br].into_iter().flatten() {
shift_down = shift_down
.max(sub_shift_down)
.max(base.descent() + sub_drop_min)
.max(if is_char_box { Abs::zero() } else { base.descent() + sub_drop_min })
.max(e.ascent() - sub_top_max);
}
@ -339,6 +340,27 @@ fn compute_shifts_up_and_down(
(shift_up, shift_down)
}
/// Whether the fragment consists of a single character or atomic piece of text.
fn is_character_box(fragment: &MathFragment) -> bool {
match fragment {
MathFragment::Glyph(_) | MathFragment::Variant(_) => {
fragment.class() != Some(MathClass::Large)
}
MathFragment::Frame(fragment) => is_atomic_text_frame(&fragment.frame),
_ => false,
}
}
/// Handles e.g. "sin", "log", "exp", "CustomOperator".
fn is_atomic_text_frame(frame: &Frame) -> bool {
// Meta information isn't visible or renderable, so we exclude it.
let mut iter = frame
.items()
.map(|(_, item)| item)
.filter(|item| !matches!(item, FrameItem::Meta(_, _)));
matches!(iter.next(), Some(FrameItem::Text(_))) && iter.next().is_none()
}
/// Unicode codepoints that should have sub- and superscripts attached as limits.
#[rustfmt::skip]
const LIMITS: &[char] = &[

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -68,6 +68,16 @@ $ sqrt(a_(1/2)^zeta), sqrt(a_alpha^(1/2)), sqrt(a_(1/2)^(3/4)) \
// Test frame base.
$ (-1)^n + (1/2 + 3)^(-1/2) $
---
#set text(size: 8pt)
// Test that the attachments are aligned horizontally.
$ x_1 p_1 frak(p)_1 2_1 dot_1 lg_1 !_1 \\_1 ]_1 "ip"_1 op("iq")_1 \
x^1 b^1 frak(b)^1 2^1 dot^1 lg^1 !^1 \\^1 ]^1 "ib"^1 op("id")^1 \
x_1 y_1 "_"_1 x^1 l^1 "`"^1 attach(I,tl:1,bl:1,tr:1,br:1)
scripts(sum)_1^1 integral_1^1 |1/2|_1^1 \
x^1_1, "("b y")"^1_1 != (b y)^1_1, "[∫]"_1 [integral]_1 $
---
// Test limit.
$ lim_(n->oo \ n "grows") sum_(k=0 \ k in NN)^n k $