Skip to content

Fix several issues with multi-character stretchy assemblies. (mathjax/MathJax#3528, mathjax/MathJax#3531)#1441

Merged
dpvc merged 3 commits intodevelopfrom
fix/stretchy-assemblies
Mar 29, 2026
Merged

Fix several issues with multi-character stretchy assemblies. (mathjax/MathJax#3528, mathjax/MathJax#3531)#1441
dpvc merged 3 commits intodevelopfrom
fix/stretchy-assemblies

Conversation

@dpvc
Copy link
Copy Markdown
Member

@dpvc dpvc commented Feb 27, 2026

This PR fixes several issues with multi-character stretchy assemblies. There were two main problems:

  1. In Windows with CHTML, the extenders could show gaps due to the overlap between pieces not being big enough.
  2. If an assembly height is requested that is less than the sum of the top and bottom pieces, they need to overlap, but that wasn't happening.

The first is fixed in the ts/output/chtml/FontData.ts file by reducing the line-height by a small fuzz factor. The SVG output was using this, and the value for that (and a horizontal fuzz factor) have been moved to the common FontData.ts file so they can be used by both output formats.

The positioning of the extender is also fixed so that the overlap with the upper glyph is more consistent.

The horizontal extenders in CHTML now uses the HFUZZ value to add a little overlap as well, since glyphs with rounded ends were producing some gaps.

The second issue is addressed in the ts/output/chtml/Wrappers/mo.ts file. It now uses the named VFUZZ and HFUZZ values, but the main change is in the createPart() method, which checks if the requested height is less than the sum of the top and bottom parts (W < 0) in a vertical assembly (nl is not null), and if so, it overrides the top and bottom margins, which are what reserve the space for the top and bottom glyphs, to make the total height be correct. The createAssembly() function is adjusted to add the needed heights to the data that is passed to createPart()

The ts/output/svg/Wrapers/mo.ts file is modified to remove the prettier-ignore comment, and allowing the function to be prettified. That is really the only change, other than moving the definitions of the fuzz values to the common FontData.ts file.

Resolves issues mathjax/MathJax#3528 and mathjax/MathJax#3531.

@dpvc dpvc requested a review from zorkow February 27, 2026 13:32
@dpvc dpvc added this to the v4.2 milestone Feb 27, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Feb 27, 2026

Codecov Report

❌ Patch coverage is 20.43011% with 74 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.45%. Comparing base (5caee44) to head (b16c2b4).
⚠️ Report is 47 commits behind head on develop.

Files with missing lines Patch % Lines
ts/output/svg/Wrappers/mo.ts 22.50% 31 Missing ⚠️
ts/output/chtml/Wrappers/mo.ts 13.33% 26 Missing ⚠️
ts/output/chtml/FontData.ts 5.55% 17 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1441      +/-   ##
===========================================
- Coverage    86.49%   86.45%   -0.05%     
===========================================
  Files          340      340              
  Lines        86044    86106      +62     
  Branches      4833     4834       +1     
===========================================
+ Hits         74425    74439      +14     
- Misses       11595    11643      +48     
  Partials        24       24              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Member

@zorkow zorkow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one formatting issue wrt. the comment alignment.
Otherwise fine.

B: number,
W: number
) {
if (!n) return;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add // prettier-ignore-start here

const s = (1.5 * Y) / (h + d); // // Scale height by 1.5 to avoid bad ends
// // (glyphs with rounded or anti-aliased ends don't stretch well,
// // so this makes for sharper ends)
const y = (s * (h - d) - Y) / 2; // // The bottom point to clip the extender
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add // prettier-ignore-end here.

* @param {number} B The height of the bottom glyph in the delimiter
* @param {number} W The width of the stretched delimiter
*/
/* prettier-ignore */
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prettier-ignore here was probably a bit overkill at the time. But I don't like the double use of // either.
We should just use prettier-ignore-start|end instead. See below.

@dpvc dpvc merged commit da21770 into develop Mar 29, 2026
1 of 3 checks passed
@dpvc dpvc deleted the fix/stretchy-assemblies branch March 29, 2026 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants