From e4cb499029eafc5f15709d13881838b6828c3326 Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Tue, 7 Apr 2026 10:18:12 -0400 Subject: [PATCH 1/2] Properly handle margin-left and margin-right specified on the input elements. --- ts/output/common/Wrapper.ts | 29 +++++++++++++++++++++++------ ts/output/svg/Wrapper.ts | 14 ++++++++++++-- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/ts/output/common/Wrapper.ts b/ts/output/common/Wrapper.ts index 3d2844404..4654ad25d 100644 --- a/ts/output/common/Wrapper.ts +++ b/ts/output/common/Wrapper.ts @@ -104,6 +104,7 @@ export const SPACE: StringMap = { * Padding and border data from the style attribute */ export type StyleData = { + margin: [number, number, number, number]; padding: [number, number, number, number]; border: { width: [number, number, number, number]; @@ -596,9 +597,10 @@ export class CommonWrapper< if (!this.styleData) return bbox; const padding = this.styleData.padding; const border = this.styleData.border?.width || [0, 0, 0, 0]; + const margin = this.styleData.margin || [0, 0, 0, 0]; const obox = bbox.copy(); for (const [, i, side] of BBox.boxSides) { - (obox as any)[side] += padding[i] + border[i]; + (obox as any)[side] += padding[i] + border[i] + margin[i]; } return obox; } @@ -748,7 +750,9 @@ export class CommonWrapper< if (!this.styleData) return; const border = this.styleData.border; const padding = this.styleData.padding; - bbox.w += (border?.width?.[3] || 0) + (padding?.[3] || 0); + const margin = this.styleData.margin; + bbox.w += + (border?.width?.[3] || 0) + (padding?.[3] || 0) + (margin?.[3] || 0); } /** @@ -758,8 +762,11 @@ export class CommonWrapper< if (!this.styleData) return; const border = this.styleData.border; const padding = this.styleData.padding; - bbox.h += (border?.width?.[0] || 0) + (padding?.[0] || 0); - bbox.d += (border?.width?.[2] || 0) + (padding?.[2] || 0); + const margin = this.styleData.margin; + bbox.h += + (border?.width?.[0] || 0) + (padding?.[0] || 0) + (margin?.[0] || 0); + bbox.d += + (border?.width?.[2] || 0) + (padding?.[2] || 0) + (margin?.[2] || 0); } /** @@ -769,7 +776,9 @@ export class CommonWrapper< if (!this.styleData) return; const border = this.styleData.border; const padding = this.styleData.padding; - bbox.w += (border?.width?.[1] || 0) + (padding?.[1] || 0); + const margin = this.styleData.margin; + bbox.w += + (border?.width?.[1] || 0) + (padding?.[1] || 0) + (margin?.[1] || 0); } /** @@ -875,11 +884,13 @@ export class CommonWrapper< protected getStyleData() { if (!this.styles) return; const padding = Array(4).fill(0); + const margin = Array(4).fill(0); const width = Array(4).fill(0); const style = Array(4); const color = Array(4); let hasPadding = false; let hasBorder = false; + let hasMargin = false; for (const [name, i] of BBox.boxSides) { const key = 'border' + name; const w = this.styles.get(key + 'Width'); @@ -894,11 +905,17 @@ export class CommonWrapper< hasPadding = true; padding[i] = Math.max(0, this.length2em(p, 1)); } + const m = this.styles.get('margin' + name); + if (m) { + hasMargin = true; + margin[i] = this.length2em(m, 1); + } } this.styleData = - hasPadding || hasBorder + hasPadding || hasBorder || hasMargin ? ({ padding, + margin, border: hasBorder ? { width, style, color } : null, } as StyleData) : null; diff --git a/ts/output/svg/Wrapper.ts b/ts/output/svg/Wrapper.ts index dc4980d94..c5b4d5f74 100644 --- a/ts/output/svg/Wrapper.ts +++ b/ts/output/svg/Wrapper.ts @@ -239,7 +239,7 @@ export class SvgWrapper extends CommonWrapper< * @param {N[]} parents The HTML nodes in which the output is to be placed * @returns {N[]} The roots of the HTML tree for the node's output */ - protected handleHref(parents: N[]) { + protected handleHref(parents: N[]): N[] { const href = this.node.attributes.get('href'); if (!href) return parents; let i = 0; @@ -278,10 +278,17 @@ export class SvgWrapper extends CommonWrapper< ); } const padding = (this.styleData?.padding || [0, 0, 0, 0])[3]; + const margin = (this.styleData?.margin || [0, 0, 0, 0])[3]; const border = (this.styleData?.border?.width || [0, 0, 0, 0])[3]; if (padding || border) { this.dx = padding + border; } + if (margin) { + const transform = `translate(${this.fixed(margin)},0)`; + this.dom.forEach((node) => + this.adaptor.setAttribute(node, 'transform', transform) + ); + } } /** @@ -346,6 +353,7 @@ export class SvgWrapper extends CommonWrapper< protected handleBorder() { const border = this.styleData?.border; if (!border) return; + const margin = this.styleData?.margin ?? [0, 0, 0, 0]; const f = SvgWrapper.borderFuzz; const adaptor = this.adaptor; let k = 0; @@ -355,7 +363,9 @@ export class SvgWrapper extends CommonWrapper< const L = !n || !k ? 1 : 0; const R = !n || k === n ? 1 : 0; const bbox = isEmbellished ? this.getOuterBBox() : this.getLineBBox(k++); - const [h, d, w] = [bbox.h + f, bbox.d + f, bbox.w + f]; + const h = bbox.h - margin[0] + f; + const d = bbox.d - margin[2] + f; + const w = bbox.w - margin[1] - margin[3] + f; const outerRT = [w, h]; const outerLT = [-f, h]; const outerRB = [w, -d]; From ed5a749f202de80e6f62bd4b357f84addfedeb90 Mon Sep 17 00:00:00 2001 From: "Davide P. Cervone" Date: Thu, 9 Apr 2026 08:27:45 -0400 Subject: [PATCH 2/2] Add sideStyleSize() metho as requested in PR. --- ts/output/common/Wrapper.ts | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/ts/output/common/Wrapper.ts b/ts/output/common/Wrapper.ts index 4654ad25d..5277fcc5f 100644 --- a/ts/output/common/Wrapper.ts +++ b/ts/output/common/Wrapper.ts @@ -744,15 +744,22 @@ export class CommonWrapper< } /** - * @param {BBox} bbox The bounding box where left borders are to be added + * @param {number} n The side number (0 to 3) whose size is needed + * @returns {number} The side's size in ems */ - protected addLeftBorders(bbox: BBox) { - if (!this.styleData) return; + protected sideStyleSize(n: number): number { const border = this.styleData.border; const padding = this.styleData.padding; const margin = this.styleData.margin; - bbox.w += - (border?.width?.[3] || 0) + (padding?.[3] || 0) + (margin?.[3] || 0); + return (border?.width?.[n] || 0) + (padding?.[n] || 0) + (margin?.[n] || 0); + } + + /** + * @param {BBox} bbox The bounding box where left borders are to be added + */ + protected addLeftBorders(bbox: BBox) { + if (!this.styleData) return; + bbox.w += this.sideStyleSize(3); } /** @@ -760,13 +767,8 @@ export class CommonWrapper< */ protected addMiddleBorders(bbox: BBox) { if (!this.styleData) return; - const border = this.styleData.border; - const padding = this.styleData.padding; - const margin = this.styleData.margin; - bbox.h += - (border?.width?.[0] || 0) + (padding?.[0] || 0) + (margin?.[0] || 0); - bbox.d += - (border?.width?.[2] || 0) + (padding?.[2] || 0) + (margin?.[2] || 0); + bbox.h += this.sideStyleSize(0); + bbox.d += this.sideStyleSize(2); } /** @@ -774,11 +776,7 @@ export class CommonWrapper< */ protected addRightBorders(bbox: BBox) { if (!this.styleData) return; - const border = this.styleData.border; - const padding = this.styleData.padding; - const margin = this.styleData.margin; - bbox.w += - (border?.width?.[1] || 0) + (padding?.[1] || 0) + (margin?.[1] || 0); + bbox.w += this.sideStyleSize(1); } /**