xlsx-to-markdown 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +300 -0
  3. package/dist/__tests__/helpers.d.ts +16 -0
  4. package/dist/__tests__/helpers.d.ts.map +1 -0
  5. package/dist/__tests__/helpers.js +63 -0
  6. package/dist/__tests__/helpers.js.map +1 -0
  7. package/dist/cell-formatter.d.ts +16 -0
  8. package/dist/cell-formatter.d.ts.map +1 -0
  9. package/dist/cell-formatter.js +257 -0
  10. package/dist/cell-formatter.js.map +1 -0
  11. package/dist/index.d.ts +21 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +129 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/options.d.ts +3 -0
  16. package/dist/options.d.ts.map +1 -0
  17. package/dist/options.js +20 -0
  18. package/dist/options.js.map +1 -0
  19. package/dist/paragraph-renderer.d.ts +14 -0
  20. package/dist/paragraph-renderer.d.ts.map +1 -0
  21. package/dist/paragraph-renderer.js +85 -0
  22. package/dist/paragraph-renderer.js.map +1 -0
  23. package/dist/region-detector.d.ts +19 -0
  24. package/dist/region-detector.d.ts.map +1 -0
  25. package/dist/region-detector.js +192 -0
  26. package/dist/region-detector.js.map +1 -0
  27. package/dist/sheet-converter.d.ts +7 -0
  28. package/dist/sheet-converter.d.ts.map +1 -0
  29. package/dist/sheet-converter.js +299 -0
  30. package/dist/sheet-converter.js.map +1 -0
  31. package/dist/table-renderer.d.ts +22 -0
  32. package/dist/table-renderer.d.ts.map +1 -0
  33. package/dist/table-renderer.js +236 -0
  34. package/dist/table-renderer.js.map +1 -0
  35. package/dist/types.d.ts +172 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +3 -0
  38. package/dist/types.js.map +1 -0
  39. package/package.json +62 -0
@@ -0,0 +1,299 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.convertSheet = convertSheet;
37
+ const XLSX = __importStar(require("xlsx"));
38
+ const region_detector_js_1 = require("./region-detector.js");
39
+ const table_renderer_js_1 = require("./table-renderer.js");
40
+ const paragraph_renderer_js_1 = require("./paragraph-renderer.js");
41
+ /**
42
+ * Convert a single worksheet to Markdown.
43
+ */
44
+ function convertSheet(ws, sheetName, sheetIndex, opts) {
45
+ const ref = ws["!ref"];
46
+ if (!ref) {
47
+ return { name: sheetName, index: sheetIndex, markdown: "", regions: [] };
48
+ }
49
+ const range = XLSX.utils.decode_range(ref);
50
+ const merges = ws["!merges"] ?? [];
51
+ const mergedCellInfo = buildMergedCellInfo(merges);
52
+ // Excel ListObject tables always have an autofilter; use that range to treat
53
+ // all cells within it as non-empty regardless of their value.
54
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
55
+ const autofilterRef = ws["!autofilter"]?.ref;
56
+ const autofilterRange = autofilterRef ? XLSX.utils.decode_range(autofilterRef) : null;
57
+ // Issue 1: Build sets of hidden row/column indices for use in detection and rendering
58
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59
+ const rowsConfig = ws["!rows"] ?? [];
60
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
61
+ const colsConfig = ws["!cols"] ?? [];
62
+ const hiddenRows = new Set();
63
+ const hiddenCols = new Set();
64
+ for (let r = range.s.r; r <= range.e.r; r++) {
65
+ if (rowsConfig[r]?.hidden)
66
+ hiddenRows.add(r);
67
+ }
68
+ for (let c = range.s.c; c <= range.e.c; c++) {
69
+ if (colsConfig[c]?.hidden)
70
+ hiddenCols.add(c);
71
+ }
72
+ // Collect RowInfo for each row in the sheet.
73
+ // For the blank-separator-column detection (below), we also track two extra
74
+ // per-row sets that are NOT part of the public RowInfo type:
75
+ // borderPromotedCols — columns added to filledCols solely by the LR-border rule
76
+ // borderTopBottomCols — columns that have a top or bottom border in this row
77
+ const rowInfos = [];
78
+ const rowBorderPromotedCols = []; // parallel to rowInfos
79
+ const rowBorderTopBottomCols = []; // parallel to rowInfos
80
+ for (let r = range.s.r; r <= range.e.r; r++) {
81
+ if (hiddenRows.has(r))
82
+ continue; // Issue 1: skip hidden rows
83
+ let filledCount = 0;
84
+ let hasBorder = false;
85
+ let hasVerticalBorder = false;
86
+ const filledCols = new Set();
87
+ const borderPromotedCols = new Set();
88
+ const borderTopBottomCols = new Set();
89
+ for (let c = range.s.c; c <= range.e.c; c++) {
90
+ if (hiddenCols.has(c))
91
+ continue; // Issue 1: skip hidden columns
92
+ const addr = XLSX.utils.encode_cell({ r, c });
93
+ if (mergedCellInfo.childCells.has(addr)) {
94
+ // Issue 2: check master cell's borders for this merged child
95
+ const masterAddr = mergedCellInfo.childToMaster.get(addr);
96
+ if (masterAddr) {
97
+ const masterCell = ws[masterAddr];
98
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
99
+ const style = masterCell?.s;
100
+ if (style?.border) {
101
+ const b = style.border;
102
+ if (b.top?.style || b.bottom?.style || b.left?.style || b.right?.style) {
103
+ hasBorder = true;
104
+ }
105
+ if (b.top?.style || b.bottom?.style) {
106
+ borderTopBottomCols.add(c);
107
+ }
108
+ if (b.left?.style || b.right?.style) {
109
+ hasVerticalBorder = true;
110
+ }
111
+ }
112
+ }
113
+ // Vertical rowspan: the master cell is in a previous row and spans into
114
+ // this row. Count this column as filled so that rows under a rowspan are
115
+ // not penalised in the density check (which would cause the band to be
116
+ // classified as a paragraph instead of a table).
117
+ if (!filledCols.has(c)) {
118
+ const masterAddr = mergedCellInfo.childToMaster.get(addr);
119
+ if (masterAddr) {
120
+ const masterPos = XLSX.utils.decode_cell(masterAddr);
121
+ if (masterPos.r < r) {
122
+ const masterCell = ws[masterAddr];
123
+ const masterHasValue = masterCell !== undefined &&
124
+ masterCell.v !== undefined &&
125
+ masterCell.v !== null &&
126
+ masterCell.v !== "";
127
+ if (masterHasValue) {
128
+ filledCols.add(c);
129
+ filledCount++;
130
+ }
131
+ }
132
+ }
133
+ }
134
+ continue;
135
+ }
136
+ const cell = ws[addr];
137
+ const hasValue = cell !== undefined && cell.v !== undefined && cell.v !== null && cell.v !== "";
138
+ const inAutofilter = autofilterRange !== null &&
139
+ r >= autofilterRange.s.r &&
140
+ r <= autofilterRange.e.r &&
141
+ c >= autofilterRange.s.c &&
142
+ c <= autofilterRange.e.c;
143
+ if (hasValue) {
144
+ filledCols.add(c);
145
+ filledCount++;
146
+ // Issue 6: for horizontally merged master cells, count all spanned
147
+ // columns so that density reflects the visual column footprint
148
+ const colEnd = mergedCellInfo.masterColEnd.get(addr);
149
+ if (colEnd !== undefined) {
150
+ for (let sc = c + 1; sc <= colEnd; sc++) {
151
+ if (hiddenCols.has(sc))
152
+ continue; // Issue 1
153
+ filledCols.add(sc);
154
+ filledCount++;
155
+ }
156
+ }
157
+ }
158
+ else if (inAutofilter && !filledCols.has(c)) {
159
+ // Cells within an Excel table (autofilter) range are treated as non-empty
160
+ // so that empty cells in a ListObject do not break table detection.
161
+ filledCols.add(c);
162
+ filledCount++;
163
+ }
164
+ // Check for borders on any cell (including empty cells)
165
+ if (cell) {
166
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
167
+ const style = cell.s;
168
+ if (style?.border) {
169
+ const b = style.border;
170
+ if (b.top?.style || b.bottom?.style || b.left?.style || b.right?.style) {
171
+ hasBorder = true;
172
+ }
173
+ if (b.top?.style || b.bottom?.style) {
174
+ borderTopBottomCols.add(c);
175
+ }
176
+ if (b.left?.style || b.right?.style) {
177
+ hasVerticalBorder = true;
178
+ // When useBorders is enabled, treat cells with BOTH left and right
179
+ // vertical borders as non-empty so that bordered-but-valueless cells
180
+ // (common in Excel table formatting) contribute to column density.
181
+ // Whether this promotion should be rolled back for blank separator
182
+ // columns is decided after band identification (see below).
183
+ if (opts.tableDetection.useBorders &&
184
+ b.left?.style &&
185
+ b.right?.style &&
186
+ !filledCols.has(c)) {
187
+ filledCols.add(c);
188
+ filledCount++;
189
+ borderPromotedCols.add(c);
190
+ }
191
+ }
192
+ }
193
+ }
194
+ }
195
+ rowInfos.push({
196
+ index: r,
197
+ filledCols,
198
+ minCol: filledCols.size > 0 ? Math.min(...filledCols) : -1,
199
+ maxCol: filledCols.size > 0 ? Math.max(...filledCols) : -1,
200
+ filledCount,
201
+ hasBorder,
202
+ hasVerticalBorder,
203
+ });
204
+ rowBorderPromotedCols.push(borderPromotedCols);
205
+ rowBorderTopBottomCols.push(borderTopBottomCols);
206
+ }
207
+ // --- Blank-separator-column rollback (band-local check) ---
208
+ //
209
+ // ADR-0014 Condition A promotes empty cells with both left and right borders.
210
+ // Exception: if a column qualifies as a "blank separator" within a row-band —
211
+ // meaning no cell in that band has an actual value/autofilter fill AND no cell
212
+ // has a top or bottom border — the promotion is rolled back so the column
213
+ // acts as a visual gap between side-by-side tables.
214
+ //
215
+ // The check is intentionally band-local (not sheet-global) so that a column
216
+ // that is a real table column in one band is not affected by another band where
217
+ // it happens to be empty.
218
+ if (opts.tableDetection.useBorders) {
219
+ // Identify bands: consecutive rowInfos with filledCount > 0.
220
+ let bandStart = 0;
221
+ while (bandStart < rowInfos.length) {
222
+ if (rowInfos[bandStart].filledCount === 0) {
223
+ bandStart++;
224
+ continue;
225
+ }
226
+ let bandEnd = bandStart;
227
+ while (bandEnd + 1 < rowInfos.length && rowInfos[bandEnd + 1].filledCount > 0) {
228
+ bandEnd++;
229
+ }
230
+ // Collect band-local evidence for each column.
231
+ const bandColHasTopBottom = new Set();
232
+ const bandColHasRealFill = new Set();
233
+ for (let bi = bandStart; bi <= bandEnd; bi++) {
234
+ for (const c of rowBorderTopBottomCols[bi])
235
+ bandColHasTopBottom.add(c);
236
+ for (const c of rowInfos[bi].filledCols) {
237
+ if (!rowBorderPromotedCols[bi].has(c))
238
+ bandColHasRealFill.add(c);
239
+ }
240
+ }
241
+ // Roll back border promotion for blank separator columns.
242
+ for (let bi = bandStart; bi <= bandEnd; bi++) {
243
+ const row = rowInfos[bi];
244
+ for (const c of rowBorderPromotedCols[bi]) {
245
+ if (!bandColHasTopBottom.has(c) && !bandColHasRealFill.has(c)) {
246
+ row.filledCols.delete(c);
247
+ row.filledCount--;
248
+ }
249
+ }
250
+ if (rowBorderPromotedCols[bi].size > 0) {
251
+ row.minCol = row.filledCols.size > 0 ? Math.min(...row.filledCols) : -1;
252
+ row.maxCol = row.filledCols.size > 0 ? Math.max(...row.filledCols) : -1;
253
+ }
254
+ }
255
+ bandStart = bandEnd + 1;
256
+ }
257
+ }
258
+ const rawRegions = (0, region_detector_js_1.detectRegions)(rowInfos, opts);
259
+ // Render each region
260
+ const regions = rawRegions.map((raw) => {
261
+ let markdown = "";
262
+ if (raw.type === "table" &&
263
+ !(0, table_renderer_js_1.isSingleCellPerRow)(raw.startRow, raw.endRow, raw.startCol, raw.endCol, merges, hiddenRows, hiddenCols)) {
264
+ markdown = (0, table_renderer_js_1.renderTable)(ws, raw.startRow, raw.endRow, raw.startCol, raw.endCol, merges, opts, hiddenRows, hiddenCols);
265
+ }
266
+ else {
267
+ markdown = (0, paragraph_renderer_js_1.renderParagraph)(ws, raw.startRow, raw.endRow, raw.startCol, raw.endCol, merges, opts, hiddenRows, hiddenCols);
268
+ }
269
+ return { ...raw, markdown };
270
+ });
271
+ const separator = "\n".repeat(opts.blankLinesBetweenRegions + 1);
272
+ const markdown = regions
273
+ .map((r) => r.markdown)
274
+ .filter(Boolean)
275
+ .join(separator);
276
+ return { name: sheetName, index: sheetIndex, markdown, regions };
277
+ }
278
+ function buildMergedCellInfo(merges) {
279
+ const childCells = new Set();
280
+ const childToMaster = new Map();
281
+ const masterColEnd = new Map();
282
+ for (const m of merges) {
283
+ const masterAddr = XLSX.utils.encode_cell({ r: m.s.r, c: m.s.c });
284
+ if (m.e.c > m.s.c) {
285
+ masterColEnd.set(masterAddr, m.e.c);
286
+ }
287
+ for (let r = m.s.r; r <= m.e.r; r++) {
288
+ for (let c = m.s.c; c <= m.e.c; c++) {
289
+ if (r === m.s.r && c === m.s.c)
290
+ continue;
291
+ const childAddr = XLSX.utils.encode_cell({ r, c });
292
+ childCells.add(childAddr);
293
+ childToMaster.set(childAddr, masterAddr);
294
+ }
295
+ }
296
+ }
297
+ return { childCells, childToMaster, masterColEnd };
298
+ }
299
+ //# sourceMappingURL=sheet-converter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet-converter.js","sourceRoot":"","sources":["../src/sheet-converter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import * as XLSX from "xlsx";
2
+ import type { ResolvedOptions } from "./types.js";
3
+ /**
4
+ * Return true if every visible row in the region renders as a single cell.
5
+ * This happens when every row has a colspan that spans the entire column range,
6
+ * leaving no structural tabular information. Such regions should be rendered
7
+ * as paragraphs rather than tables.
8
+ */
9
+ export declare function isSingleCellPerRow(startRow: number, endRow: number, startCol: number, endCol: number, merges: XLSX.Range[], hiddenRows?: Set<number>, hiddenCols?: Set<number>): boolean;
10
+ /**
11
+ * Render a table region as an HTML table with full colspan/rowspan support.
12
+ *
13
+ * @param ws - The worksheet
14
+ * @param startRow - First row (0-based, inclusive)
15
+ * @param endRow - Last row (0-based, inclusive)
16
+ * @param startCol - First column (0-based, inclusive)
17
+ * @param endCol - Last column (0-based, inclusive)
18
+ * @param merges - Merged cell ranges from ws['!merges']
19
+ * @param opts - Resolved options
20
+ */
21
+ export declare function renderTable(ws: XLSX.WorkSheet, startRow: number, endRow: number, startCol: number, endCol: number, merges: XLSX.Range[], opts: ResolvedOptions, hiddenRows?: Set<number>, hiddenCols?: Set<number>): string;
22
+ //# sourceMappingURL=table-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-renderer.d.ts","sourceRoot":"","sources":["../src/table-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,YAAY,CAAC;AAQ5D;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,EACpB,UAAU,GAAE,GAAG,CAAC,MAAM,CAAa,EACnC,UAAU,GAAE,GAAG,CAAC,MAAM,CAAa,GAClC,OAAO,CAwBT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,EAAE,EAAE,IAAI,CAAC,SAAS,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,IAAI,CAAC,KAAK,EAAE,EACpB,IAAI,EAAE,eAAe,EACrB,UAAU,GAAE,GAAG,CAAC,MAAM,CAAa,EACnC,UAAU,GAAE,GAAG,CAAC,MAAM,CAAa,GAClC,MAAM,CA6ER"}
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isSingleCellPerRow = isSingleCellPerRow;
37
+ exports.renderTable = renderTable;
38
+ const XLSX = __importStar(require("xlsx"));
39
+ const cell_formatter_js_1 = require("./cell-formatter.js");
40
+ /**
41
+ * Return true if every visible row in the region renders as a single cell.
42
+ * This happens when every row has a colspan that spans the entire column range,
43
+ * leaving no structural tabular information. Such regions should be rendered
44
+ * as paragraphs rather than tables.
45
+ */
46
+ function isSingleCellPerRow(startRow, endRow, startCol, endCol, merges, hiddenRows = new Set(), hiddenCols = new Set()) {
47
+ // Build the set of merge child addresses inside this region
48
+ const mergeChildSet = new Set();
49
+ for (const m of merges) {
50
+ if (m.s.r < startRow || m.s.r > endRow || m.s.c < startCol || m.s.c > endCol)
51
+ continue;
52
+ for (let r = m.s.r; r <= m.e.r; r++) {
53
+ for (let c = m.s.c; c <= m.e.c; c++) {
54
+ if (r === m.s.r && c === m.s.c)
55
+ continue;
56
+ mergeChildSet.add(XLSX.utils.encode_cell({ r, c }));
57
+ }
58
+ }
59
+ }
60
+ for (let r = startRow; r <= endRow; r++) {
61
+ if (hiddenRows.has(r))
62
+ continue;
63
+ let cellCount = 0;
64
+ for (let c = startCol; c <= endCol; c++) {
65
+ if (hiddenCols.has(c))
66
+ continue;
67
+ if (mergeChildSet.has(XLSX.utils.encode_cell({ r, c })))
68
+ continue;
69
+ cellCount++;
70
+ }
71
+ if (cellCount > 1)
72
+ return false;
73
+ }
74
+ return true;
75
+ }
76
+ /**
77
+ * Render a table region as an HTML table with full colspan/rowspan support.
78
+ *
79
+ * @param ws - The worksheet
80
+ * @param startRow - First row (0-based, inclusive)
81
+ * @param endRow - Last row (0-based, inclusive)
82
+ * @param startCol - First column (0-based, inclusive)
83
+ * @param endCol - Last column (0-based, inclusive)
84
+ * @param merges - Merged cell ranges from ws['!merges']
85
+ * @param opts - Resolved options
86
+ */
87
+ function renderTable(ws, startRow, endRow, startCol, endCol, merges, opts, hiddenRows = new Set(), hiddenCols = new Set()) {
88
+ // Build merge maps for cells inside this table region
89
+ const mergeSpanMap = new Map(); // master address → span
90
+ const mergeChildSet = new Set(); // child addresses to skip
91
+ for (const m of merges) {
92
+ // Only handle merges whose master cell is inside the table region
93
+ if (m.s.r < startRow || m.s.r > endRow || m.s.c < startCol || m.s.c > endCol)
94
+ continue;
95
+ const masterAddr = XLSX.utils.encode_cell({ r: m.s.r, c: m.s.c });
96
+ const colspan = Math.min(m.e.c, endCol) - m.s.c + 1;
97
+ const rowspan = Math.min(m.e.r, endRow) - m.s.r + 1;
98
+ mergeSpanMap.set(masterAddr, { colspan, rowspan });
99
+ for (let r = m.s.r; r <= m.e.r; r++) {
100
+ for (let c = m.s.c; c <= m.e.c; c++) {
101
+ if (r === m.s.r && c === m.s.c)
102
+ continue;
103
+ mergeChildSet.add(XLSX.utils.encode_cell({ r, c }));
104
+ }
105
+ }
106
+ }
107
+ // Infer column alignments from data rows
108
+ const alignments = inferColumnAlignments(ws, startRow, endRow, startCol, endCol, mergeChildSet, opts, hiddenRows, hiddenCols);
109
+ const lines = ["<table>"];
110
+ // --- header row ---
111
+ if (opts.headerRow && !hiddenRows.has(startRow)) {
112
+ lines.push(renderHtmlRow(ws, startRow, startCol, endCol, mergeSpanMap, mergeChildSet, alignments, opts, "th", hiddenCols));
113
+ }
114
+ // --- data rows ---
115
+ const dataStartRow = opts.headerRow ? startRow + 1 : startRow;
116
+ for (let r = dataStartRow; r <= endRow; r++) {
117
+ if (hiddenRows.has(r))
118
+ continue;
119
+ lines.push(renderHtmlRow(ws, r, startCol, endCol, mergeSpanMap, mergeChildSet, alignments, opts, "td", hiddenCols));
120
+ }
121
+ lines.push("</table>");
122
+ return lines.join("\n");
123
+ }
124
+ // ---------------------------------------------------------------------------
125
+ // Helpers
126
+ // ---------------------------------------------------------------------------
127
+ function renderHtmlRow(ws, row, startCol, endCol, mergeSpanMap, mergeChildSet, alignments, opts, tag, hiddenCols = new Set()) {
128
+ const cells = [];
129
+ for (let c = startCol; c <= endCol; c++) {
130
+ if (hiddenCols.has(c))
131
+ continue;
132
+ const addr = XLSX.utils.encode_cell({ r: row, c });
133
+ // Skip child cells of a merge
134
+ if (mergeChildSet.has(addr))
135
+ continue;
136
+ const cell = ws[addr];
137
+ const data = (0, cell_formatter_js_1.extractCellData)(cell, mergeChildSet, addr, opts);
138
+ // Build attribute string
139
+ const attrs = [];
140
+ const span = mergeSpanMap.get(addr);
141
+ if (span) {
142
+ if (span.colspan > 1)
143
+ attrs.push(`colspan="${span.colspan}"`);
144
+ if (span.rowspan > 1)
145
+ attrs.push(`rowspan="${span.rowspan}"`);
146
+ }
147
+ // Alignment: explicit cell alignment takes priority, then column-level inference
148
+ const explicitAlign = data.alignment;
149
+ const colAlign = alignments[c - startCol];
150
+ const align = explicitAlign ?? colAlign;
151
+ if (align && align !== "left") {
152
+ attrs.push(`style="text-align: ${align}"`);
153
+ }
154
+ const attrStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
155
+ const content = formatCellHtml(data, opts);
156
+ cells.push(` <${tag}${attrStr}>${content}</${tag}>`);
157
+ }
158
+ return ` <tr>\n${cells.join("\n")}\n </tr>`;
159
+ }
160
+ /**
161
+ * Format a cell's content as HTML.
162
+ * Uses rawValue so that we apply HTML tags rather than Markdown syntax.
163
+ */
164
+ function formatCellHtml(data, opts) {
165
+ // Inline rich text: use pre-built per-run HTML (ADR-0019)
166
+ if (opts.richText && data.richTextHtml !== undefined) {
167
+ const val = data.richTextHtml;
168
+ if (!val)
169
+ return opts.emptyCell ? (0, cell_formatter_js_1.escapeHtml)(opts.emptyCell) : "";
170
+ return data.hyperlink ? `<a href="${(0, cell_formatter_js_1.escapeHtml)(data.hyperlink)}">${val}</a>` : val;
171
+ }
172
+ let val = (0, cell_formatter_js_1.escapeHtml)(data.rawValue);
173
+ // Newlines inside cells → <br>
174
+ val = val.replace(/\n/g, "<br>");
175
+ if (!val)
176
+ return opts.emptyCell ? (0, cell_formatter_js_1.escapeHtml)(opts.emptyCell) : "";
177
+ if (!opts.richText)
178
+ return val;
179
+ // Apply HTML inline formatting (cell-level bold/italic)
180
+ if (data.bold && data.italic)
181
+ val = `<strong><em>${val}</em></strong>`;
182
+ else if (data.bold)
183
+ val = `<strong>${val}</strong>`;
184
+ else if (data.italic)
185
+ val = `<em>${val}</em>`;
186
+ if (data.hyperlink)
187
+ val = `<a href="${(0, cell_formatter_js_1.escapeHtml)(data.hyperlink)}">${val}</a>`;
188
+ return val;
189
+ }
190
+ /**
191
+ * Infer the best alignment for each column.
192
+ * Priority: explicit cell alignment > all-numeric column content > left (default).
193
+ */
194
+ function inferColumnAlignments(ws, startRow, endRow, startCol, endCol, mergeChildSet, opts, hiddenRows = new Set(), hiddenCols = new Set()) {
195
+ const dataStartRow = opts.headerRow ? startRow + 1 : startRow;
196
+ const colCount = endCol - startCol + 1;
197
+ const result = [];
198
+ for (let ci = 0; ci < colCount; ci++) {
199
+ const c = startCol + ci;
200
+ if (hiddenCols.has(c)) {
201
+ result.push("left");
202
+ continue;
203
+ }
204
+ let explicit;
205
+ let hasValue = false;
206
+ let allNumeric = true;
207
+ for (let r = dataStartRow; r <= endRow; r++) {
208
+ if (hiddenRows.has(r))
209
+ continue;
210
+ const addr = XLSX.utils.encode_cell({ r, c });
211
+ if (mergeChildSet.has(addr))
212
+ continue;
213
+ const cell = ws[addr];
214
+ const data = (0, cell_formatter_js_1.extractCellData)(cell, mergeChildSet, addr, opts);
215
+ if (!explicit && data.alignment)
216
+ explicit = data.alignment;
217
+ const v = data.rawValue.trim();
218
+ if (v) {
219
+ hasValue = true;
220
+ // Use SheetJS cell type as the primary numeric signal so that values
221
+ // displayed with currency symbols (¥1,000, $100) are still right-aligned.
222
+ const numericByType = cell?.t === "n";
223
+ if (!numericByType && !/^-?[\d,]+(\.\d+)?%?$/.test(v))
224
+ allNumeric = false;
225
+ }
226
+ }
227
+ if (explicit) {
228
+ result.push(explicit);
229
+ }
230
+ else {
231
+ result.push(hasValue && allNumeric ? "right" : "left");
232
+ }
233
+ }
234
+ return result;
235
+ }
236
+ //# sourceMappingURL=table-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-renderer.js","sourceRoot":"","sources":["../src/table-renderer.ts"],"names":[],"mappings":"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"}