/** * MathML to OMML Converter * * Uses 'mathml2omml' library to convert MathML to Office Math Markup Language (OMML). * This is a pure JavaScript implementation and does not require external XSLT files. * * @see https://github.com/fiduswriter/mathml2omml */ import { mml2omml } from 'mathml2omml'; /** * Cleans up OMML output from mathml2omml to fix known library issues. * These are workarounds for bugs in mathml2omml that produce invalid OMML. * * @param omml Raw OMML string from mathml2omml * @returns Cleaned OMML string compatible with Microsoft Word */ function cleanOmml(omml: string): string { return omml // Fix: m:sty m:val="undefined" is invalid (library bug with mathvariant="normal") .replace(//g, '') // Remove empty control properties that cause parsing issues in some Word versions .replace(//g, '') .replace(//g, '') // Remove inline namespace declarations (will use wrapper's namespaces) .replace(/ xmlns:m="[^"]*"/g, '') .replace(/ xmlns:w="[^"]*"/g, ''); } /** * Converts MathML string to OMML string using mathml2omml library. * * @param mathml The MathML content string * @returns Promise resolving to cleaned OMML string * @see https://github.com/fiduswriter/mathml2omml */ export async function convertMathmlToOmml(mathml: string): Promise { try { // Convert using mml2omml function const omml = mml2omml(mathml); // Apply fixes for known library issues return cleanOmml(omml); } catch (error) { console.error('MathML to OMML conversion failed:', error); return ''; } } /** * Wraps OMML for clipboard/paste into Microsoft Word. * Uses Office Open XML namespaces (Office 2007+). * * @param omml Cleaned OMML string from convertMathmlToOmml * @returns XML string ready for clipboard */ export function wrapOmmlForClipboard(omml: string): string { // Extract inner content from tags to avoid nesting const innerContent = omml .replace(/]*>/g, '') .replace(/<\/m:oMath>/g, ''); // Return with proper Office Open XML structure return ` ${innerContent} `; }