Skip to content
Merged
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 @@ -80,4 +80,34 @@ describe('handleMathBlockNode', () => {
handleMathBlockNode(makeNode({ textContent: 'b' }) as any, context);
expect(blocks[0].id).not.toBe(blocks[1].id);
});

it('resolves paragraph spacing from paragraphProperties', () => {
const { context, blocks } = makeContext();
const node = makeNode({
textContent: 'x',
paragraphProperties: { spacing: { before: 240, after: 160, line: 276, lineRule: 'auto' } },
});

handleMathBlockNode(node as any, context);

const block = blocks[0] as ParagraphBlock;
expect(block.attrs?.spacing).toBeDefined();
expect(block.attrs?.spacing?.before).toBeGreaterThan(0);
expect(block.attrs?.spacing?.after).toBeGreaterThan(0);
});

it('falls back to paragraph alignment when justification is unknown', () => {
const { context, blocks } = makeContext();
const node = makeNode({
textContent: 'x',
justification: 'unknown',
paragraphProperties: { justification: 'right' },
});

handleMathBlockNode(node as any, context);

const block = blocks[0] as ParagraphBlock;
// When math justification is unknown, falls back to paragraphAttrs alignment
expect(block.attrs?.alignment).toBeDefined();
});
});
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { ParagraphBlock, MathRun } from '@superdoc/contracts';
import type { PMNode, NodeHandlerContext } from '../types.js';
import { estimateMathDimensions } from './math-constants.js';
import { computeParagraphAttrs } from '../attributes/index.js';

const JUSTIFICATION_TO_ALIGN: Record<string, 'left' | 'center' | 'right'> = {
center: 'center',
Expand Down Expand Up @@ -32,12 +33,17 @@ export function handleMathBlockNode(node: PMNode, context: NodeHandlerContext):
pmEnd: pos?.end,
};

// Resolve paragraph spacing from the parent w:p's properties (carried via paragraphProperties attr).
// This ensures display math paragraphs get the same spacing as their containing paragraph.
const { paragraphAttrs } = computeParagraphAttrs(node, context.converterContext);

const block: ParagraphBlock = {
kind: 'paragraph',
id: nextBlockId('paragraph'),
runs: [mathRun],
attrs: {
alignment: JUSTIFICATION_TO_ALIGN[justification] ?? 'center',
...paragraphAttrs,
alignment: JUSTIFICATION_TO_ALIGN[justification] ?? paragraphAttrs.alignment ?? 'center',
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,15 @@ const handleMathPara = (params) => {
const originalXml = carbonCopy(xmlNode);
const textContent = extractMathText(xmlNode);
const justification = extractJustification(xmlNode);
// Use raw inline properties (not resolved) to match how regular paragraphs work.
// The style-engine resolves them at render time via computeParagraphAttrs.
const paragraphProperties = params.extraParams?.inlineParagraphProperties ?? null;

return {
nodes: [
{
type: 'mathBlock',
attrs: { originalXml, textContent, justification },
attrs: { originalXml, textContent, justification, paragraphProperties },
marks: [],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,41 @@ describe('mathNodeHandler', () => {
const result = handler({ nodes: [oMathParaNode] });
expect(result.nodes[0].attrs.justification).toBe('centerGroup');
});

it('captures paragraphProperties from extraParams', () => {
const oMathParaNode = {
name: 'm:oMathPara',
elements: [
{
name: 'm:oMath',
elements: [{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'z' }] }] }],
},
],
};

const spacing = { before: 240, after: 160 };
const result = handler({
nodes: [oMathParaNode],
extraParams: { inlineParagraphProperties: { spacing } },
});

expect(result.nodes[0].attrs.paragraphProperties).toEqual({ spacing });
});

it('sets paragraphProperties to null when extraParams is absent', () => {
const oMathParaNode = {
name: 'm:oMathPara',
elements: [
{
name: 'm:oMath',
elements: [{ name: 'm:r', elements: [{ name: 'm:t', elements: [{ type: 'text', text: 'w' }] }] }],
},
],
};

const result = handler({ nodes: [oMathParaNode] });
expect(result.nodes[0].attrs.paragraphProperties).toBeNull();
});
});

describe('non-math elements', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export const handleParagraphNode = (params) => {
extraParams: {
...params.extraParams,
paragraphProperties: resolvedParagraphProperties,
inlineParagraphProperties,
numberingDefinedInline: Boolean(inlineParagraphProperties.numberingProperties),
},
path: [...(params.path || []), node],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export const MathBlock = Node.create({
default: 'centerGroup',
rendered: false,
},
paragraphProperties: {
default: null,
rendered: false,
},
};
},
});
Loading