2025-12-26 15:53:11 +08:00
|
|
|
/**
|
|
|
|
|
* 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.
|
2025-12-27 21:59:22 +08:00
|
|
|
*
|
|
|
|
|
* @see https://github.com/fiduswriter/mathml2omml
|
2025-12-26 15:53:11 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
import { mml2omml } from 'mathml2omml';
|
|
|
|
|
|
2025-12-27 21:59:22 +08:00
|
|
|
/**
|
|
|
|
|
* 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(/<m:sty m:val="undefined"\/>/g, '')
|
|
|
|
|
// Remove empty control properties that cause parsing issues in some Word versions
|
|
|
|
|
.replace(/<m:ctrlPr\/>/g, '')
|
|
|
|
|
.replace(/<w:rPr\/>/g, '')
|
|
|
|
|
// Remove inline namespace declarations (will use wrapper's namespaces)
|
|
|
|
|
.replace(/ xmlns:m="[^"]*"/g, '')
|
|
|
|
|
.replace(/ xmlns:w="[^"]*"/g, '');
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-26 15:53:11 +08:00
|
|
|
/**
|
|
|
|
|
* Converts MathML string to OMML string using mathml2omml library.
|
2025-12-27 21:59:22 +08:00
|
|
|
*
|
2025-12-26 15:53:11 +08:00
|
|
|
* @param mathml The MathML content string
|
2025-12-27 21:59:22 +08:00
|
|
|
* @returns Promise resolving to cleaned OMML string
|
|
|
|
|
* @see https://github.com/fiduswriter/mathml2omml
|
2025-12-26 15:53:11 +08:00
|
|
|
*/
|
|
|
|
|
export async function convertMathmlToOmml(mathml: string): Promise<string> {
|
|
|
|
|
try {
|
2025-12-27 21:59:22 +08:00
|
|
|
// Convert using mml2omml function
|
2025-12-26 15:53:11 +08:00
|
|
|
const omml = mml2omml(mathml);
|
2025-12-27 21:59:22 +08:00
|
|
|
|
|
|
|
|
// Apply fixes for known library issues
|
|
|
|
|
return cleanOmml(omml);
|
2025-12-26 15:53:11 +08:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('MathML to OMML conversion failed:', error);
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-27 21:59:22 +08:00
|
|
|
* 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
|
2025-12-26 15:53:11 +08:00
|
|
|
*/
|
|
|
|
|
export function wrapOmmlForClipboard(omml: string): string {
|
2025-12-27 21:59:22 +08:00
|
|
|
// Extract inner content from <m:oMath> tags to avoid nesting
|
|
|
|
|
const innerContent = omml
|
|
|
|
|
.replace(/<m:oMath[^>]*>/g, '')
|
|
|
|
|
.replace(/<\/m:oMath>/g, '');
|
2025-12-26 15:53:11 +08:00
|
|
|
|
2025-12-27 21:59:22 +08:00
|
|
|
// Return with proper Office Open XML structure
|
|
|
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
|
<m:oMath xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
|
|
|
|
|
${innerContent}
|
|
|
|
|
</m:oMath>`;
|
2025-12-26 15:53:11 +08:00
|
|
|
}
|