Skip to content

feat(math): implement m:d delimiter converter (SD-2380)#2710

Open
andrewsrigom wants to merge 2 commits intosuperdoc-dev:mainfrom
andrewsrigom:feat/math-delimiter-converter
Open

feat(math): implement m:d delimiter converter (SD-2380)#2710
andrewsrigom wants to merge 2 commits intosuperdoc-dev:mainfrom
andrewsrigom:feat/math-delimiter-converter

Conversation

@andrewsrigom
Copy link
Copy Markdown
Contributor

@andrewsrigom andrewsrigom commented Apr 2, 2026

Summary

  • implement the m:d OMML -> MathML converter
  • register the converter in the OMML converter registry
  • add tests covering default delimiters, custom separators, and empty-expression handling

Testing

  • pnpm exec vitest run packages/layout-engine/painters/dom/src/features/math/omml-to-mathml.test.ts
  • validated manually in the dev app with the issue test document

Closes #2611

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f2079a7a82

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@andrewsrigom andrewsrigom force-pushed the feat/math-delimiter-converter branch from f2079a7 to 804c4d3 Compare April 2, 2026 22:15
Copy link
Copy Markdown
Contributor

@caio-pizzol caio-pizzol left a comment

Choose a reason for hiding this comment

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

@andrewsrigom clean implementation, follows the existing converter pattern nicely.

two issues to fix — both confirmed by comparing SuperDoc rendering against Word (test file + screenshots below).

1. element present without m:val should mean "no character" — right now <m:begChr/> (no attribute) behaves the same as the element being absent, so it renders (. the spec says it should render nothing. same applies to endChr and sepChr.

2. wrong default separator — should be \u2502 (box drawing vertical) not ASCII |, per §22.1.2.95.

tests look good. you'll want to add one for the no-val case after fixing #1. left inline comments with fixes.

💡 tip: you can look up any ECMA-376 section directly using the ooxml.dev MCP server — handy for checking defaults and edge cases in the spec.


test file: attached .docx with 21 cases covering every m:dPr property. cases 5, 8, 9, 12 show the bugs:
SD-2380-delimiter-spec-tests.docx

Case 5<m:begChr/> should hide the opening delimiter:
SuperDoc:
image
Word:
image

Case 8<m:endChr/> should hide the closing delimiter:
SuperDoc:
image
Word:
image

Case 9 — both present without val, should show no delimiters:
SuperDoc:
image
Word:
image

Case 12<m:sepChr/> should hide the separator:
SuperDoc:
image
Word:
image

Comment on lines +10 to +11
const property = properties?.elements?.find((element) => element.name === name);
return property?.attributes?.['m:val'] ?? fallback;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

the spec treats "element missing" and "element present without m:val" differently. missing → use default char, present without val → no character. right now both return the default because property.attributes is undefined in both cases.

Suggested change
const property = properties?.elements?.find((element) => element.name === name);
return property?.attributes?.['m:val'] ?? fallback;
const property = properties?.elements?.find((element) => element.name === name);
if (!property) return fallback;
return property.attributes?.['m:val'] ?? '';


const DEFAULT_BEGIN_DELIMITER = '(';
const DEFAULT_END_DELIMITER = ')';
const DEFAULT_SEPARATOR_DELIMITER = '|';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

spec says the default separator is U+2502, not ASCII | (§22.1.2.95). they look similar but are different characters.

Suggested change
const DEFAULT_SEPARATOR_DELIMITER = '|';
const DEFAULT_SEPARATOR_DELIMITER = '\u2502'; // U+2502 BOX DRAWINGS LIGHT VERTICAL (ECMA-376 §22.1.2.95)

@caio-pizzol
Copy link
Copy Markdown
Contributor

@andrewsrigom let me know if you have any questions here! thanks for you work ❤️

@caio-pizzol caio-pizzol self-assigned this Apr 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Math: implement m:d delimiter converter (community)

2 participants