Skip to content

Fix mfenced separators in canonicalization - #895

Merged
NSoiffer merged 3 commits into
daisy:mainfrom
dkager:fix-mfenced-separators
Oct 23, 2026
Merged

NSoiffer merged 3 commits into
daisy:mainfrom
dkager:fix-mfenced-separators

Conversation

@dkager

@dkager dkager commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

convert_mfenced_to_mrow in src/canonicalize.rs did not follow the MathML 3 rules for the separators attribute of mfenced, as described in section 3.3.8.2 Attributes. This PR fixes three cases. Each case has a small unit test.

1. Too few separators

"If separator characters are given, but there are too few, the last one is repeated as necessary."

Earlier, MathCAT used a comma as the fallback separator. Perhaps the confusion arose from what the spec says next:

"Thus, the default value of separators="," is equivalent to separators=",,", separators=",,,", etc."

The existing test mfenced_with_separators expected the old behavior, so its golden was changed.

2. Empty separators

"If there are no separator characters provided but some are needed, for example if separators=" " or "" and there is more than one argument, then no separator elements are inserted at all ..."

Again, in this case the comma was inserted as default/fallback. Dedicon's braille rules ran into this case (mfenced_empty_separators), which admittedly is an edge case, but does occur in production.

Note that if the separators attribute is not provided, its default is the comma. We test this too.

3. Whitespace in separators

"Any whitespace within separators is ignored."

Whitespace is now stripped. This has some interesting relations with other rules, e.g. separators=" " yields no separators, because whitespace is ignored.

dkager and others added 2 commits October 23, 2026 21:29
convert_mfenced_to_mrow did not follow the MathML rules for the separators attribute:

- separators="" inserted a comma between all children instead of no separators
- with too few separators a comma was used instead of repeating the last separator
- whitespace in separators was used as a separator instead of being ignored

Each case has a unit test. The expected output of mfenced_with_separators is corrected
to repeat the last separator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Linux library size: 0.59 MiB (+0.06%)
Revision Release liblibmathcat.so
Base (b3050fb) 0.59 MiB (614,664 bytes)
PR (cf4a444) 0.59 MiB (615,008 bytes)
Change +344 bytes (+0.06%)

Built with default features, Rust 1.96.0, and Ubuntu 24.04. Workflow run.

Small tweak for more efficient code/more idiomatic code:
`.or(separators.last())` => `or_else(|| separators.last())`

This avoids evaluating `separators.last()` when `separators.get(i)` is already `Some`.
@NSoiffer

Copy link
Copy Markdown
Collaborator

Thanks for spotting the bug and providing a fix. I tweaked the fix, but it is basically what you provided.

@NSoiffer
NSoiffer merged commit 93fe64f into daisy:main Oct 23, 2026
@github-project-automation github-project-automation Bot moved this from Triage to Done in MathCAT Project Board Oct 23, 2026
@dkager

dkager commented Oct 24, 2026

Copy link
Copy Markdown
Contributor Author

Thank you for the refactor, that helps me to learn more too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants