/**
* 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}
`;
}