Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export { convertFunction } from './function.js';
export { convertSubscript } from './subscript.js';
export { convertSuperscript } from './superscript.js';
export { convertSubSuperscript } from './sub-superscript.js';
export { convertLowerLimit } from './lower-limit.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { MathObjectConverter } from '../types.js';

const MATHML_NS = 'http://www.w3.org/1998/Math/MathML';

/**
* Convert m:limLow (lower limit) to MathML <munder>.
*
* OMML structure:
* m:limLow → m:limLowPr (optional), m:e (base), m:lim (limit)
*
* MathML output:
* <munder> <mrow>base</mrow> <mrow>limit</mrow> </munder>
*
* Common use: lim_{x→∞}, min, max, sup, inf
*
* @spec ECMA-376 §22.1.2.54
*/
export const convertLowerLimit: MathObjectConverter = (node, doc, convertChildren) => {
const elements = node.elements ?? [];
const base = elements.find((e) => e.name === 'm:e');
const lim = elements.find((e) => e.name === 'm:lim');

const munder = doc.createElementNS(MATHML_NS, 'munder');

const baseRow = doc.createElementNS(MATHML_NS, 'mrow');
baseRow.appendChild(convertChildren(base?.elements ?? []));
munder.appendChild(baseRow);

const limRow = doc.createElementNS(MATHML_NS, 'mrow');
limRow.appendChild(convertChildren(lim?.elements ?? []));
munder.appendChild(limRow);

return munder;
};
Original file line number Diff line number Diff line change
Expand Up @@ -927,3 +927,85 @@ describe('m:func converter', () => {
expect(mis[1]!.textContent).toBe('cos');
});
});

describe('m:limLow converter', () => {
it('converts lim_{x→0} to <munder>', () => {
const omml = {
name: 'm:oMath',
elements: [
{
name: 'm:limLow',
elements: [
{
name: 'm:e',
elements: [{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'lim' }] }] }],
},
{
name: 'm:lim',
elements: [
{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'x' }] }] },
{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: '→' }] }] },
{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: '0' }] }] },
],
},
],
},
],
};
const result = convertOmmlToMathml(omml, doc);
expect(result).not.toBeNull();
const munder = result!.querySelector('munder');
expect(munder).not.toBeNull();
expect(munder!.children[0]!.textContent).toBe('lim');
expect(munder!.children[1]!.textContent).toBe('x→0');
});

it('handles missing m:lim gracefully', () => {
const omml = {
name: 'm:oMath',
elements: [
{
name: 'm:limLow',
elements: [
{
name: 'm:e',
elements: [{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'min' }] }] }],
},
],
},
],
};
const result = convertOmmlToMathml(omml, doc);
expect(result).not.toBeNull();
const munder = result!.querySelector('munder');
expect(munder).not.toBeNull();
expect(munder!.children[0]!.textContent).toBe('min');
});

it('ignores m:limLowPr', () => {
const omml = {
name: 'm:oMath',
elements: [
{
name: 'm:limLow',
elements: [
{ name: 'm:limLowPr', elements: [{ name: 'm:ctrlPr' }] },
{
name: 'm:e',
elements: [{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'sup' }] }] }],
},
{
name: 'm:lim',
elements: [{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'S' }] }] }],
},
],
},
],
};
const result = convertOmmlToMathml(omml, doc);
const munder = result!.querySelector('munder');
expect(munder).not.toBeNull();
expect(munder!.children[0]!.textContent).toBe('sup');
expect(munder!.children[1]!.textContent).toBe('S');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
convertSubscript,
convertSuperscript,
convertSubSuperscript,
convertLowerLimit,
} from './converters/index.js';

export const MATHML_NS = 'http://www.w3.org/1998/Math/MathML';
Expand Down Expand Up @@ -52,7 +53,7 @@ const MATH_OBJECT_REGISTRY: Record<string, MathObjectConverter | null> = {
'm:d': null, // Delimiter (parentheses, brackets, braces)
'm:eqArr': null, // Equation array (vertical array of equations)
'm:groupChr': null, // Group character (overbrace, underbrace)
'm:limLow': null, // Lower limit (e.g., lim)
'm:limLow': convertLowerLimit, // Lower limit (e.g., lim)
'm:limUpp': null, // Upper limit
'm:m': null, // Matrix (grid of elements)
'm:nary': null, // N-ary operator (integral, summation, product)
Expand Down
Loading