@podlite/markdown 0.0.31 → 0.0.33
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.
- package/lib/index.cjs +43 -41
- package/lib/index.cjs.map +3 -3
- package/lib/index.esm.js +352 -33
- package/lib/index.esm.js.map +3 -3
- package/package.json +9 -2
- package/jest.config.js +0 -1
- package/jest.tsconfig.json +0 -1
- package/scripts/build.ts +0 -16
- package/scripts/build_esm.ts +0 -18
- package/src/index.tsx +0 -26
- package/src/tools.ts +0 -224
- package/t/parse.test.ts +0 -1854
- package/t/plugin.test.tsx +0 -232
- package/tsconfig-esm.json +0 -6
- package/tsconfig.json +0 -20
- package/tsconfig.tsbuildinfo +0 -1
package/lib/index.esm.js
CHANGED
|
@@ -25644,7 +25644,7 @@ var require_package = __commonJS({
|
|
|
25644
25644
|
"../podlite-schema/package.json"(exports, module) {
|
|
25645
25645
|
module.exports = {
|
|
25646
25646
|
name: "@podlite/schema",
|
|
25647
|
-
version: "0.0.
|
|
25647
|
+
version: "0.0.40",
|
|
25648
25648
|
description: "AST tools and schema for Podlite markup language \u2014 validate, traverse, and transform document trees",
|
|
25649
25649
|
main: "./src/index.ts",
|
|
25650
25650
|
homepage: "https://podlite.org",
|
|
@@ -27026,6 +27026,245 @@ var plugin_defn_fill_term_default = () => (tree) => {
|
|
|
27026
27026
|
function flattenDeep3(arr) {
|
|
27027
27027
|
return arr.reduce((acc, val) => Array.isArray(val) ? acc.concat(flattenDeep3(val)) : acc.concat(val), []);
|
|
27028
27028
|
}
|
|
27029
|
+
function parseCsv(text4) {
|
|
27030
|
+
const rows = [];
|
|
27031
|
+
let field = "";
|
|
27032
|
+
let row = [];
|
|
27033
|
+
let inQuote = false;
|
|
27034
|
+
let i = 0;
|
|
27035
|
+
while (i < text4.length) {
|
|
27036
|
+
const c = text4[i];
|
|
27037
|
+
if (inQuote) {
|
|
27038
|
+
if (c === '"' && text4[i + 1] === '"') {
|
|
27039
|
+
field += '"';
|
|
27040
|
+
i += 2;
|
|
27041
|
+
continue;
|
|
27042
|
+
}
|
|
27043
|
+
if (c === '"') {
|
|
27044
|
+
inQuote = false;
|
|
27045
|
+
i++;
|
|
27046
|
+
continue;
|
|
27047
|
+
}
|
|
27048
|
+
field += c;
|
|
27049
|
+
i++;
|
|
27050
|
+
continue;
|
|
27051
|
+
}
|
|
27052
|
+
if (c === '"' && field === "") {
|
|
27053
|
+
inQuote = true;
|
|
27054
|
+
i++;
|
|
27055
|
+
continue;
|
|
27056
|
+
}
|
|
27057
|
+
if (c === ",") {
|
|
27058
|
+
row.push(field);
|
|
27059
|
+
field = "";
|
|
27060
|
+
i++;
|
|
27061
|
+
continue;
|
|
27062
|
+
}
|
|
27063
|
+
if (c === "\r") {
|
|
27064
|
+
i++;
|
|
27065
|
+
continue;
|
|
27066
|
+
}
|
|
27067
|
+
if (c === "\n") {
|
|
27068
|
+
row.push(field);
|
|
27069
|
+
rows.push(row);
|
|
27070
|
+
row = [];
|
|
27071
|
+
field = "";
|
|
27072
|
+
i++;
|
|
27073
|
+
continue;
|
|
27074
|
+
}
|
|
27075
|
+
field += c;
|
|
27076
|
+
i++;
|
|
27077
|
+
}
|
|
27078
|
+
if (field !== "" || row.length > 0) {
|
|
27079
|
+
row.push(field);
|
|
27080
|
+
rows.push(row);
|
|
27081
|
+
}
|
|
27082
|
+
return rows.filter((r) => !(r.length === 1 && r[0].trim() === ""));
|
|
27083
|
+
}
|
|
27084
|
+
function parseTsv(text4) {
|
|
27085
|
+
const lines = text4.split(/\r?\n/);
|
|
27086
|
+
const rows = lines.map((line) => line.split(" "));
|
|
27087
|
+
return rows.filter((r) => !(r.length === 1 && r[0].trim() === ""));
|
|
27088
|
+
}
|
|
27089
|
+
function parseMimeType(raw) {
|
|
27090
|
+
if (!raw || typeof raw !== "string")
|
|
27091
|
+
return { type: "", params: {} };
|
|
27092
|
+
const parts = raw.split(";").map((s) => s.trim());
|
|
27093
|
+
const type = (parts.shift() || "").toLowerCase();
|
|
27094
|
+
const params = {};
|
|
27095
|
+
for (const p of parts) {
|
|
27096
|
+
if (!p)
|
|
27097
|
+
continue;
|
|
27098
|
+
const eq = p.indexOf("=");
|
|
27099
|
+
if (eq < 0)
|
|
27100
|
+
continue;
|
|
27101
|
+
const key = p.slice(0, eq).trim().toLowerCase();
|
|
27102
|
+
let value = p.slice(eq + 1).trim();
|
|
27103
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
27104
|
+
value = value.slice(1, -1);
|
|
27105
|
+
}
|
|
27106
|
+
if (key)
|
|
27107
|
+
params[key] = value;
|
|
27108
|
+
}
|
|
27109
|
+
return { type, params };
|
|
27110
|
+
}
|
|
27111
|
+
function findDataBlockByKey(tree, key) {
|
|
27112
|
+
let found = null;
|
|
27113
|
+
const walk = (node) => {
|
|
27114
|
+
if (found)
|
|
27115
|
+
return;
|
|
27116
|
+
if (Array.isArray(node)) {
|
|
27117
|
+
node.forEach(walk);
|
|
27118
|
+
return;
|
|
27119
|
+
}
|
|
27120
|
+
if (!node || typeof node !== "object")
|
|
27121
|
+
return;
|
|
27122
|
+
if (node.type === "block" && node.name === "data") {
|
|
27123
|
+
const attrs = config_default(node, {});
|
|
27124
|
+
if (attrs.getFirstValue("key") === key) {
|
|
27125
|
+
found = node;
|
|
27126
|
+
return;
|
|
27127
|
+
}
|
|
27128
|
+
}
|
|
27129
|
+
if (Array.isArray(node.content))
|
|
27130
|
+
node.content.forEach(walk);
|
|
27131
|
+
};
|
|
27132
|
+
walk(tree);
|
|
27133
|
+
return found;
|
|
27134
|
+
}
|
|
27135
|
+
function extractDataText(dataNode) {
|
|
27136
|
+
if (!dataNode || !Array.isArray(dataNode.content))
|
|
27137
|
+
return "";
|
|
27138
|
+
const verbatim = dataNode.content.find((c) => c && c.type === "verbatim");
|
|
27139
|
+
return verbatim && typeof verbatim.value === "string" ? verbatim.value : "";
|
|
27140
|
+
}
|
|
27141
|
+
function detectSourceReference(tableNode) {
|
|
27142
|
+
const texts = [];
|
|
27143
|
+
const walker = makeTransformer_default({
|
|
27144
|
+
"row:text": (r) => {
|
|
27145
|
+
texts.push(r.value);
|
|
27146
|
+
return r;
|
|
27147
|
+
},
|
|
27148
|
+
"head:text": (h) => {
|
|
27149
|
+
texts.push(h.value);
|
|
27150
|
+
return h;
|
|
27151
|
+
}
|
|
27152
|
+
});
|
|
27153
|
+
walker(tableNode, {});
|
|
27154
|
+
const joined = texts.join("\n").trim();
|
|
27155
|
+
const lines = joined.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
|
|
27156
|
+
if (lines.length !== 1)
|
|
27157
|
+
return null;
|
|
27158
|
+
const m = lines[0].match(/^(data|file):(\S+)$/);
|
|
27159
|
+
if (!m)
|
|
27160
|
+
return null;
|
|
27161
|
+
return { scheme: m[1], target: m[2] };
|
|
27162
|
+
}
|
|
27163
|
+
function buildCellBlock(text4) {
|
|
27164
|
+
return {
|
|
27165
|
+
name: "cell",
|
|
27166
|
+
type: "block",
|
|
27167
|
+
margin: "",
|
|
27168
|
+
content: [{ type: "text", value: text4 }]
|
|
27169
|
+
};
|
|
27170
|
+
}
|
|
27171
|
+
function buildRowBlock(cells, isHeader) {
|
|
27172
|
+
const block = {
|
|
27173
|
+
name: "row",
|
|
27174
|
+
type: "block",
|
|
27175
|
+
margin: "",
|
|
27176
|
+
content: cells
|
|
27177
|
+
};
|
|
27178
|
+
if (isHeader) {
|
|
27179
|
+
block.config = [{ name: "header", value: true, type: "boolean" }];
|
|
27180
|
+
}
|
|
27181
|
+
return block;
|
|
27182
|
+
}
|
|
27183
|
+
function csvToTableContent(csvRows, hasHeader = false) {
|
|
27184
|
+
return csvRows.map((row, i) => {
|
|
27185
|
+
const cells = row.map((v) => buildCellBlock(v.trim()));
|
|
27186
|
+
return buildRowBlock(cells, hasHeader && i === 0);
|
|
27187
|
+
});
|
|
27188
|
+
}
|
|
27189
|
+
function normalizeCellCounts(tableNode, source = "table") {
|
|
27190
|
+
if (!tableNode || !Array.isArray(tableNode.content))
|
|
27191
|
+
return tableNode;
|
|
27192
|
+
const rows = tableNode.content.filter((c) => c && c.type === "block" && c.name === "row");
|
|
27193
|
+
if (rows.length === 0)
|
|
27194
|
+
return tableNode;
|
|
27195
|
+
const cellsOf = (row) => Array.isArray(row.content) ? row.content.filter((c) => c && c.name === "cell") : [];
|
|
27196
|
+
const isHeaderRow = (row) => Array.isArray(row.config) && row.config.some((a) => a.name === "header" && a.value === true);
|
|
27197
|
+
const cellHasSpan = (cell) => Array.isArray(cell.config) && cell.config.some((a) => a.name === "colspan" || a.name === "rowspan");
|
|
27198
|
+
const rowHasSpan = (row) => cellsOf(row).some(cellHasSpan);
|
|
27199
|
+
if (rows.some(rowHasSpan))
|
|
27200
|
+
return tableNode;
|
|
27201
|
+
const headerRow = rows.find(isHeaderRow);
|
|
27202
|
+
const expected = headerRow ? cellsOf(headerRow).length : Math.max(...rows.map((r) => cellsOf(r).length));
|
|
27203
|
+
if (expected === 0)
|
|
27204
|
+
return tableNode;
|
|
27205
|
+
let mutated = false;
|
|
27206
|
+
const newContent = tableNode.content.map((child) => {
|
|
27207
|
+
if (!child || child.type !== "block" || child.name !== "row")
|
|
27208
|
+
return child;
|
|
27209
|
+
const cells = cellsOf(child);
|
|
27210
|
+
if (cells.length === expected)
|
|
27211
|
+
return child;
|
|
27212
|
+
if (cells.length < expected) {
|
|
27213
|
+
const padding = [];
|
|
27214
|
+
for (let i = cells.length; i < expected; i++)
|
|
27215
|
+
padding.push(buildCellBlock(""));
|
|
27216
|
+
console.warn(
|
|
27217
|
+
`[${source}] row has ${cells.length} cells, expected ${expected} \u2014 padded with ${padding.length} empty`
|
|
27218
|
+
);
|
|
27219
|
+
mutated = true;
|
|
27220
|
+
return { ...child, content: [...child.content, ...padding] };
|
|
27221
|
+
}
|
|
27222
|
+
const dropped = cells.length - expected;
|
|
27223
|
+
console.warn(`[${source}] row has ${cells.length} cells, expected ${expected} \u2014 truncated ${dropped}`);
|
|
27224
|
+
mutated = true;
|
|
27225
|
+
let keepCells = expected;
|
|
27226
|
+
const trimmed = [];
|
|
27227
|
+
for (const c of child.content || []) {
|
|
27228
|
+
if (c && c.type === "block" && c.name === "cell") {
|
|
27229
|
+
if (keepCells > 0) {
|
|
27230
|
+
trimmed.push(c);
|
|
27231
|
+
keepCells--;
|
|
27232
|
+
}
|
|
27233
|
+
} else {
|
|
27234
|
+
trimmed.push(c);
|
|
27235
|
+
}
|
|
27236
|
+
}
|
|
27237
|
+
return { ...child, content: trimmed };
|
|
27238
|
+
});
|
|
27239
|
+
return mutated ? { ...tableNode, content: newContent } : tableNode;
|
|
27240
|
+
}
|
|
27241
|
+
function detectMixedSeparators(lines) {
|
|
27242
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27243
|
+
for (const line of lines) {
|
|
27244
|
+
if (!line || typeof line !== "string")
|
|
27245
|
+
continue;
|
|
27246
|
+
if (/\s\|\s/.test(line))
|
|
27247
|
+
seen.add("pipe");
|
|
27248
|
+
else if (/\s\+\s/.test(line))
|
|
27249
|
+
seen.add("plus");
|
|
27250
|
+
else if (line.trim().length > 0)
|
|
27251
|
+
seen.add("whitespace");
|
|
27252
|
+
if (seen.size > 1)
|
|
27253
|
+
break;
|
|
27254
|
+
}
|
|
27255
|
+
if (seen.size > 1) {
|
|
27256
|
+
console.warn(`[table] mixed separator types detected: ${Array.from(seen).join(", ")} \u2014 recommend a single style`);
|
|
27257
|
+
}
|
|
27258
|
+
}
|
|
27259
|
+
function buildCodeFromDataBlock(tableNode, dataBlock) {
|
|
27260
|
+
return {
|
|
27261
|
+
type: "block",
|
|
27262
|
+
name: "code",
|
|
27263
|
+
margin: tableNode.margin || "",
|
|
27264
|
+
content: Array.isArray(dataBlock.content) ? dataBlock.content : [],
|
|
27265
|
+
config: Array.isArray(tableNode.config) ? tableNode.config : []
|
|
27266
|
+
};
|
|
27267
|
+
}
|
|
27029
27268
|
var strbin = (str1, str2, cb) => {
|
|
27030
27269
|
let res = [];
|
|
27031
27270
|
for (let i = 0; str1.length > i; i++) {
|
|
@@ -27036,49 +27275,91 @@ var strbin = (str1, str2, cb) => {
|
|
|
27036
27275
|
var makeMask = (lines, separators) => {
|
|
27037
27276
|
const tmplLength = Math.max(...[...lines, ...separators].map((s) => s.length));
|
|
27038
27277
|
const masks = lines.map((str) => {
|
|
27039
|
-
|
|
27040
|
-
|
|
27278
|
+
const tstr = str + " ".repeat(tmplLength - str.length);
|
|
27279
|
+
const mask = [];
|
|
27041
27280
|
const re = /\s+[+|\s]\s/g;
|
|
27042
27281
|
let match;
|
|
27043
27282
|
while ((match = re.exec(tstr)) != null) {
|
|
27044
27283
|
const tmpMask = "1".repeat(match.index) + "0".repeat(match[0].length);
|
|
27045
27284
|
mask.push(tmpMask + "1".repeat(tmplLength - tmpMask.length));
|
|
27046
27285
|
}
|
|
27047
|
-
return mask.reduce((a, b) =>
|
|
27048
|
-
return strbin(a, b, (i1, i2) => i1 & i2);
|
|
27049
|
-
}, "1".repeat(tmplLength));
|
|
27286
|
+
return mask.reduce((a, b) => strbin(a, b, (i1, i2) => i1 & i2), "1".repeat(tmplLength));
|
|
27050
27287
|
});
|
|
27051
27288
|
const inverted = masks.map((m) => strbin(m, "", (i1) => i1 == 0 ? 1 : 0));
|
|
27052
|
-
|
|
27053
|
-
return strbin(a, b, (i1, i2) => i1 & i2);
|
|
27054
|
-
}, "1".repeat(tmplLength));
|
|
27055
|
-
return columnTemplate;
|
|
27289
|
+
return inverted.reduce((a, b) => strbin(a, b, (i1, i2) => i1 & i2), "1".repeat(tmplLength));
|
|
27056
27290
|
};
|
|
27057
27291
|
var extractColumnsByTemplate = (text4, template) => {
|
|
27058
|
-
const lines = flattenDeep3(
|
|
27059
|
-
text4.split(/\n/).filter((str) => str.length > 0)
|
|
27060
|
-
);
|
|
27292
|
+
const lines = flattenDeep3(text4.split(/\n/).filter((s) => s.length > 0));
|
|
27061
27293
|
const cols = lines.map((line) => {
|
|
27062
27294
|
const re = /((1+|0+))/g;
|
|
27063
|
-
|
|
27295
|
+
const columns = [];
|
|
27064
27296
|
let match;
|
|
27065
27297
|
while ((match = re.exec(template)) != null) {
|
|
27066
|
-
if (match[0][0] == 1)
|
|
27298
|
+
if (match[0][0] == "1")
|
|
27067
27299
|
continue;
|
|
27068
|
-
|
|
27069
|
-
columns.push(s);
|
|
27300
|
+
columns.push(line.substring(match.index, match.index + match[0].length));
|
|
27070
27301
|
}
|
|
27071
27302
|
return columns;
|
|
27072
27303
|
});
|
|
27073
|
-
|
|
27074
|
-
|
|
27304
|
+
const result = [];
|
|
27305
|
+
cols.reduce((a, b) => {
|
|
27075
27306
|
for (let i = 0; i < b.length; i++) {
|
|
27076
27307
|
a[i] = (a[i] === void 0 ? "" : a[i]) + " " + b[i];
|
|
27077
27308
|
}
|
|
27078
27309
|
return a;
|
|
27079
|
-
},
|
|
27310
|
+
}, result);
|
|
27080
27311
|
return result;
|
|
27081
27312
|
};
|
|
27313
|
+
var detectLineSeparator = (line) => {
|
|
27314
|
+
if (/(?:^|\s)\|(?:\s|$)/.test(line))
|
|
27315
|
+
return "pipe";
|
|
27316
|
+
if (/(?:^|\s)\+(?:\s|$)/.test(line))
|
|
27317
|
+
return "plus";
|
|
27318
|
+
return "whitespace";
|
|
27319
|
+
};
|
|
27320
|
+
var trimEdgeEmpty = (cells) => {
|
|
27321
|
+
let start = 0;
|
|
27322
|
+
let end = cells.length;
|
|
27323
|
+
if (cells[start] === "")
|
|
27324
|
+
start++;
|
|
27325
|
+
if (end > start && cells[end - 1] === "")
|
|
27326
|
+
end--;
|
|
27327
|
+
return cells.slice(start, end);
|
|
27328
|
+
};
|
|
27329
|
+
var splitLineByPipe = (line) => trimEdgeEmpty(line.split(/\s*\|\s*/).map((c) => c.trim()));
|
|
27330
|
+
var splitLineByPlus = (line) => trimEdgeEmpty(line.split(/\s*\+\s*/).map((c) => c.trim()));
|
|
27331
|
+
var splitLineByWhitespace = (line) => line.trim().split(/\s{2,}/).filter((c) => c !== "");
|
|
27332
|
+
var splitLineCells = (line) => {
|
|
27333
|
+
const trimmed = line.trim();
|
|
27334
|
+
if (trimmed === "")
|
|
27335
|
+
return [];
|
|
27336
|
+
const kind = detectLineSeparator(line);
|
|
27337
|
+
if (kind === "pipe")
|
|
27338
|
+
return splitLineByPipe(line);
|
|
27339
|
+
if (kind === "plus")
|
|
27340
|
+
return splitLineByPlus(line);
|
|
27341
|
+
return splitLineByWhitespace(line);
|
|
27342
|
+
};
|
|
27343
|
+
var rowToCells = (rowValue) => {
|
|
27344
|
+
const lines = rowValue.split(/\r?\n/).filter((l) => l.trim() !== "");
|
|
27345
|
+
if (lines.length === 0)
|
|
27346
|
+
return [];
|
|
27347
|
+
if (lines.length === 1)
|
|
27348
|
+
return splitLineCells(lines[0]);
|
|
27349
|
+
const kind = detectLineSeparator(lines[0]);
|
|
27350
|
+
const splitFn = kind === "pipe" ? splitLineByPipe : kind === "plus" ? splitLineByPlus : splitLineByWhitespace;
|
|
27351
|
+
const lineCells = lines.map(splitFn);
|
|
27352
|
+
const maxCols = Math.max(...lineCells.map((c) => c.length));
|
|
27353
|
+
const merged = [];
|
|
27354
|
+
for (let i = 0; i < maxCols; i++) {
|
|
27355
|
+
const parts = lineCells.map((line) => {
|
|
27356
|
+
var _a;
|
|
27357
|
+
return (_a = line[i]) != null ? _a : "";
|
|
27358
|
+
}).filter((p) => p !== "");
|
|
27359
|
+
merged.push(parts.join(" "));
|
|
27360
|
+
}
|
|
27361
|
+
return merged;
|
|
27362
|
+
};
|
|
27082
27363
|
var wrapImplicitCells = (rowNode) => {
|
|
27083
27364
|
if (!Array.isArray(rowNode.content) || rowNode.content.length === 0)
|
|
27084
27365
|
return rowNode;
|
|
@@ -27098,13 +27379,42 @@ var isStructured = (tableNode) => Array.isArray(tableNode.content) && tableNode.
|
|
|
27098
27379
|
var plugin_tables_default = () => (tree) => {
|
|
27099
27380
|
const transformer = makeTransformer_default({
|
|
27100
27381
|
table: (node) => {
|
|
27382
|
+
const ref = detectSourceReference(node);
|
|
27383
|
+
if (ref && ref.scheme === "data") {
|
|
27384
|
+
const dataBlock = findDataBlockByKey(tree, ref.target);
|
|
27385
|
+
if (!dataBlock) {
|
|
27386
|
+
console.warn(`[table] no =data block found for data:${ref.target} \u2014 rendered as empty`);
|
|
27387
|
+
return { ...node, content: [] };
|
|
27388
|
+
}
|
|
27389
|
+
const rawMime = config_default(dataBlock, {}).getFirstValue("mime-type");
|
|
27390
|
+
const { type: mimeType, params: mimeParams } = parseMimeType(rawMime);
|
|
27391
|
+
const isCsv = mimeType === "text/csv";
|
|
27392
|
+
const isTsv = mimeType === "text/tab-separated-values";
|
|
27393
|
+
if (isCsv || isTsv) {
|
|
27394
|
+
const text4 = extractDataText(dataBlock);
|
|
27395
|
+
const rows2 = isCsv ? parseCsv(text4) : parseTsv(text4);
|
|
27396
|
+
if (rows2.length === 0) {
|
|
27397
|
+
console.warn(
|
|
27398
|
+
`[table] ${isCsv ? "CSV" : "TSV"} parse produced no rows for data:${ref.target} \u2014 rendered as empty`
|
|
27399
|
+
);
|
|
27400
|
+
return { ...node, content: [] };
|
|
27401
|
+
}
|
|
27402
|
+
const hasHeader = mimeParams.header === "present";
|
|
27403
|
+
const filledNode = { ...node, content: csvToTableContent(rows2, hasHeader) };
|
|
27404
|
+
return normalizeCellCounts(filledNode, `table data:${ref.target}`);
|
|
27405
|
+
}
|
|
27406
|
+
console.warn(
|
|
27407
|
+
`[table] =data :key<${ref.target}> has non-tabular mime-type ${rawMime || "(none)"} \u2014 rendered as =code`
|
|
27408
|
+
);
|
|
27409
|
+
return buildCodeFromDataBlock(node, dataBlock);
|
|
27410
|
+
}
|
|
27101
27411
|
if (isStructured(node)) {
|
|
27102
27412
|
const transformedContent = (node.content || []).map((c) => {
|
|
27103
27413
|
if (c && c.name === "row")
|
|
27104
27414
|
return wrapImplicitCells(c);
|
|
27105
27415
|
return c;
|
|
27106
27416
|
});
|
|
27107
|
-
return { ...node, content: transformedContent };
|
|
27417
|
+
return normalizeCellCounts({ ...node, content: transformedContent }, "table");
|
|
27108
27418
|
}
|
|
27109
27419
|
let rows = [];
|
|
27110
27420
|
const collectValues = (row) => {
|
|
@@ -27123,37 +27433,46 @@ var plugin_tables_default = () => (tree) => {
|
|
|
27123
27433
|
const splitToLines = (row) => row.split(/\n/).filter((str) => str.length > 0);
|
|
27124
27434
|
const lines = flattenDeep3(rows.map(splitToLines));
|
|
27125
27435
|
const separators = flattenDeep3(seps.map(splitToLines));
|
|
27436
|
+
detectMixedSeparators(lines);
|
|
27126
27437
|
let textRows = [];
|
|
27127
27438
|
makeTransformer_default({
|
|
27128
27439
|
"row:text": (row) => {
|
|
27129
27440
|
textRows.push(row.value);
|
|
27130
27441
|
}
|
|
27131
27442
|
})(node);
|
|
27132
|
-
const columnTemplate = makeMask(lines, separators);
|
|
27133
27443
|
const makeBlock = (name, content4, extra = {}) => {
|
|
27134
27444
|
return { ...extra, name, type: "block", content: Array.isArray(content4) ? content4 : [content4] };
|
|
27135
27445
|
};
|
|
27136
27446
|
const makeRow = (cells) => makeBlock("row", cells);
|
|
27137
27447
|
const makeHeaderRow = (cells) => makeBlock("row", cells, { config: [{ name: "header", value: true, type: "boolean" }] });
|
|
27138
27448
|
const makeCell = (text4) => makeBlock("cell", { type: "text", value: text4 });
|
|
27449
|
+
const columnTemplate = makeMask(lines, separators);
|
|
27450
|
+
const seenSeparatorKinds = new Set(lines.map(detectLineSeparator));
|
|
27451
|
+
const hasVisible = seenSeparatorKinds.has("pipe") || seenSeparatorKinds.has("plus");
|
|
27452
|
+
const hasWhitespace = seenSeparatorKinds.has("whitespace");
|
|
27453
|
+
const useMixedSplitting = hasVisible && hasWhitespace;
|
|
27454
|
+
const splitToCells = (rowValue) => {
|
|
27455
|
+
if (useMixedSplitting) {
|
|
27456
|
+
const rowLines = rowValue.split(/\r?\n/).filter((l) => l.trim() !== "");
|
|
27457
|
+
if (rowLines.length <= 1)
|
|
27458
|
+
return rowToCells(rowValue);
|
|
27459
|
+
}
|
|
27460
|
+
return extractColumnsByTemplate(rowValue, columnTemplate);
|
|
27461
|
+
};
|
|
27139
27462
|
const res = makeTransformer_default({
|
|
27140
27463
|
"row:text": (row) => {
|
|
27141
27464
|
if (textRows.length == 1) {
|
|
27142
27465
|
const textRowsLines = flattenDeep3([row.value].map(splitToLines));
|
|
27143
|
-
|
|
27144
|
-
|
|
27145
|
-
|
|
27146
|
-
|
|
27466
|
+
if (useMixedSplitting) {
|
|
27467
|
+
return textRowsLines.map((line) => makeRow(splitLineCells(line).map(makeCell)));
|
|
27468
|
+
}
|
|
27469
|
+
return textRowsLines.map((line) => makeRow(extractColumnsByTemplate(line, columnTemplate).map(makeCell)));
|
|
27147
27470
|
}
|
|
27148
|
-
|
|
27149
|
-
return makeRow(cols.map(makeCell));
|
|
27471
|
+
return makeRow(splitToCells(row.value).map(makeCell));
|
|
27150
27472
|
},
|
|
27151
|
-
"head:text": (head) =>
|
|
27152
|
-
const cols = extractColumnsByTemplate(head.value, columnTemplate);
|
|
27153
|
-
return makeHeaderRow(cols.map(makeCell));
|
|
27154
|
-
}
|
|
27473
|
+
"head:text": (head) => makeHeaderRow(splitToCells(head.value).map(makeCell))
|
|
27155
27474
|
})(node);
|
|
27156
|
-
return res;
|
|
27475
|
+
return normalizeCellCounts(res, "table");
|
|
27157
27476
|
}
|
|
27158
27477
|
});
|
|
27159
27478
|
return transformer(tree, {});
|