@scrider/formatter 1.0.1 → 1.2.0
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/dist/index.cjs +136 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +127 -3
- package/dist/index.d.ts +127 -3
- package/dist/index.js +131 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,8 @@ __export(index_exports, {
|
|
|
63
63
|
dividerFormat: () => dividerFormat,
|
|
64
64
|
escapeHtml: () => escapeHtml,
|
|
65
65
|
extractBoxOpAttributes: () => extractBoxOpAttributes,
|
|
66
|
+
extractTableRegion: () => extractTableRegion,
|
|
67
|
+
fontFormat: () => fontFormat,
|
|
66
68
|
footnoteRefFormat: () => footnoteRefFormat,
|
|
67
69
|
footnotesBlockHandler: () => footnotesBlockHandler,
|
|
68
70
|
formulaFormat: () => formulaFormat,
|
|
@@ -76,6 +78,7 @@ __export(index_exports, {
|
|
|
76
78
|
isAdapterAvailable: () => isAdapterAvailable,
|
|
77
79
|
isElement: () => isElement,
|
|
78
80
|
isRemarkAvailable: () => isRemarkAvailable,
|
|
81
|
+
isTableNewlineOp: () => isTableNewlineOp,
|
|
79
82
|
isTextNode: () => isTextNode,
|
|
80
83
|
isValidColor: () => isValidColor,
|
|
81
84
|
isValidHexColor: () => isValidHexColor,
|
|
@@ -88,7 +91,9 @@ __export(index_exports, {
|
|
|
88
91
|
markdownToDeltaSync: () => markdownToDeltaSync,
|
|
89
92
|
nodeAdapter: () => nodeAdapter,
|
|
90
93
|
normalizeDelta: () => normalizeDelta,
|
|
94
|
+
preloadRemark: () => preloadRemark,
|
|
91
95
|
sanitizeDelta: () => sanitizeDelta,
|
|
96
|
+
sizeFormat: () => sizeFormat,
|
|
92
97
|
slugify: () => slugify,
|
|
93
98
|
slugifyWithDedup: () => slugifyWithDedup,
|
|
94
99
|
strikeFormat: () => strikeFormat,
|
|
@@ -1663,6 +1668,15 @@ var colorFormat = {
|
|
|
1663
1668
|
}
|
|
1664
1669
|
};
|
|
1665
1670
|
|
|
1671
|
+
// src/schema/formats/inline/font.ts
|
|
1672
|
+
var fontFormat = {
|
|
1673
|
+
name: "font",
|
|
1674
|
+
scope: "inline",
|
|
1675
|
+
validate(value) {
|
|
1676
|
+
return typeof value === "string" && value.length > 0;
|
|
1677
|
+
}
|
|
1678
|
+
};
|
|
1679
|
+
|
|
1666
1680
|
// src/schema/formats/inline/italic.ts
|
|
1667
1681
|
var italicFormat = {
|
|
1668
1682
|
name: "italic",
|
|
@@ -1720,6 +1734,15 @@ var markFormat = {
|
|
|
1720
1734
|
}
|
|
1721
1735
|
};
|
|
1722
1736
|
|
|
1737
|
+
// src/schema/formats/inline/size.ts
|
|
1738
|
+
var sizeFormat = {
|
|
1739
|
+
name: "size",
|
|
1740
|
+
scope: "inline",
|
|
1741
|
+
validate(value) {
|
|
1742
|
+
return typeof value === "string" && value.length > 0;
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
|
|
1723
1746
|
// src/schema/formats/inline/strike.ts
|
|
1724
1747
|
var strikeFormat = {
|
|
1725
1748
|
name: "strike",
|
|
@@ -1927,7 +1950,9 @@ var INLINE_FORMAT_ORDER = [
|
|
|
1927
1950
|
];
|
|
1928
1951
|
var INLINE_STYLE_FORMATS = {
|
|
1929
1952
|
color: "color",
|
|
1930
|
-
background: "background-color"
|
|
1953
|
+
background: "background-color",
|
|
1954
|
+
font: "font-family",
|
|
1955
|
+
size: "font-size"
|
|
1931
1956
|
};
|
|
1932
1957
|
var BLOCK_FORMAT_TAGS = {
|
|
1933
1958
|
header: (value) => `h${String(value)}`,
|
|
@@ -2312,6 +2337,8 @@ var defaultInlineFormats = [
|
|
|
2312
2337
|
linkFormat,
|
|
2313
2338
|
colorFormat,
|
|
2314
2339
|
backgroundFormat,
|
|
2340
|
+
fontFormat,
|
|
2341
|
+
sizeFormat,
|
|
2315
2342
|
markFormat,
|
|
2316
2343
|
kbdFormat
|
|
2317
2344
|
];
|
|
@@ -3342,6 +3369,14 @@ function htmlToDelta(html, options = {}) {
|
|
|
3342
3369
|
if (bg) {
|
|
3343
3370
|
currentAttributes.background = bg;
|
|
3344
3371
|
}
|
|
3372
|
+
const fontFamily = element.style?.fontFamily || element.style?.getPropertyValue?.("font-family");
|
|
3373
|
+
if (fontFamily) {
|
|
3374
|
+
currentAttributes.font = fontFamily.replace(/^["']|["']$/g, "");
|
|
3375
|
+
}
|
|
3376
|
+
const fontSize = element.style?.fontSize || element.style?.getPropertyValue?.("font-size");
|
|
3377
|
+
if (fontSize) {
|
|
3378
|
+
currentAttributes.size = fontSize;
|
|
3379
|
+
}
|
|
3345
3380
|
processChildren(element);
|
|
3346
3381
|
flushText();
|
|
3347
3382
|
currentAttributes = prevAttrs;
|
|
@@ -3724,7 +3759,8 @@ function deltaToMarkdown(delta, options = {}) {
|
|
|
3724
3759
|
embedRenderers = {},
|
|
3725
3760
|
blockHandlers,
|
|
3726
3761
|
prettyHtml = false,
|
|
3727
|
-
registry
|
|
3762
|
+
registry,
|
|
3763
|
+
trimTrailingNewlines = false
|
|
3728
3764
|
} = options;
|
|
3729
3765
|
const useLatexDelimiters = mathSyntax === "latex";
|
|
3730
3766
|
const lines = splitIntoLines2(delta.ops);
|
|
@@ -3822,7 +3858,8 @@ ${code}
|
|
|
3822
3858
|
lastIndent = indent;
|
|
3823
3859
|
lastWasBlockquote = isBlockquote;
|
|
3824
3860
|
}
|
|
3825
|
-
|
|
3861
|
+
const md = result.join("\n");
|
|
3862
|
+
return trimTrailingNewlines ? md.replace(/\n+$/, "") : md;
|
|
3826
3863
|
}
|
|
3827
3864
|
function hasBlockFormat(attrs) {
|
|
3828
3865
|
return !!(attrs.header || attrs.list || attrs.blockquote || attrs["code-block"] || attrs.align || attrs.indent);
|
|
@@ -4043,11 +4080,14 @@ function renderInlineText2(text, attributes) {
|
|
|
4043
4080
|
if (link) {
|
|
4044
4081
|
result = renderLink(result, link);
|
|
4045
4082
|
}
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4083
|
+
const styleProps = [];
|
|
4084
|
+
if (typeof attributes.color === "string") styleProps.push(`color: ${attributes.color}`);
|
|
4085
|
+
if (typeof attributes.background === "string")
|
|
4086
|
+
styleProps.push(`background-color: ${attributes.background}`);
|
|
4087
|
+
if (typeof attributes.font === "string") styleProps.push(`font-family: ${attributes.font}`);
|
|
4088
|
+
if (typeof attributes.size === "string") styleProps.push(`font-size: ${attributes.size}`);
|
|
4089
|
+
if (styleProps.length > 0) {
|
|
4090
|
+
result = `<span style="${styleProps.join("; ")}">${result}</span>`;
|
|
4051
4091
|
}
|
|
4052
4092
|
return result;
|
|
4053
4093
|
}
|
|
@@ -4208,6 +4248,8 @@ var remarkGfm = null;
|
|
|
4208
4248
|
var remarkMath = null;
|
|
4209
4249
|
var unified = null;
|
|
4210
4250
|
function isRemarkAvailable() {
|
|
4251
|
+
if (unified && remarkParse) return true;
|
|
4252
|
+
if (typeof require === "undefined") return false;
|
|
4211
4253
|
try {
|
|
4212
4254
|
require.resolve("unified");
|
|
4213
4255
|
require.resolve("remark-parse");
|
|
@@ -4216,8 +4258,8 @@ function isRemarkAvailable() {
|
|
|
4216
4258
|
return false;
|
|
4217
4259
|
}
|
|
4218
4260
|
}
|
|
4219
|
-
async function
|
|
4220
|
-
if (unified) return;
|
|
4261
|
+
async function preloadRemark() {
|
|
4262
|
+
if (unified && remarkParse && remarkGfm) return true;
|
|
4221
4263
|
try {
|
|
4222
4264
|
const [unifiedMod, remarkParseMod, remarkGfmMod] = await Promise.all([
|
|
4223
4265
|
import("unified"),
|
|
@@ -4228,15 +4270,16 @@ async function loadRemark() {
|
|
|
4228
4270
|
remarkParse = remarkParseMod.default;
|
|
4229
4271
|
remarkGfm = remarkGfmMod.default;
|
|
4230
4272
|
} catch {
|
|
4231
|
-
|
|
4232
|
-
"remark is not installed. Install with: pnpm add unified remark-parse remark-gfm"
|
|
4233
|
-
);
|
|
4273
|
+
return false;
|
|
4234
4274
|
}
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4275
|
+
if (!remarkMath) {
|
|
4276
|
+
try {
|
|
4277
|
+
const remarkMathMod = await import("remark-math");
|
|
4278
|
+
remarkMath = remarkMathMod.default;
|
|
4279
|
+
} catch {
|
|
4280
|
+
}
|
|
4239
4281
|
}
|
|
4282
|
+
return true;
|
|
4240
4283
|
}
|
|
4241
4284
|
function preprocessMarkdown(markdown, mathBlock) {
|
|
4242
4285
|
markdown = markdown.replace(/\\\((.+?)\\\)/g, (_match, content) => `$${content}$`);
|
|
@@ -4260,9 +4303,11 @@ async function markdownToDelta(markdown, options = {}) {
|
|
|
4260
4303
|
nodeHandlers = {}
|
|
4261
4304
|
} = options;
|
|
4262
4305
|
markdown = preprocessMarkdown(markdown, mathBlock);
|
|
4263
|
-
await
|
|
4264
|
-
if (!unified || !remarkParse) {
|
|
4265
|
-
throw new Error(
|
|
4306
|
+
const loaded = await preloadRemark();
|
|
4307
|
+
if (!loaded || !unified || !remarkParse) {
|
|
4308
|
+
throw new Error(
|
|
4309
|
+
"remark is not installed. Install with: pnpm add unified remark-parse remark-gfm"
|
|
4310
|
+
);
|
|
4266
4311
|
}
|
|
4267
4312
|
let processor = unified().use(remarkParse);
|
|
4268
4313
|
if (gfm && remarkGfm) {
|
|
@@ -4291,6 +4336,11 @@ function markdownToDeltaSync(markdown, options = {}) {
|
|
|
4291
4336
|
} = options;
|
|
4292
4337
|
markdown = preprocessMarkdown(markdown, mathBlock);
|
|
4293
4338
|
if (!unified || !remarkParse) {
|
|
4339
|
+
if (typeof require === "undefined") {
|
|
4340
|
+
throw new Error(
|
|
4341
|
+
"markdownToDeltaSync requires remark to be preloaded in this environment. `require()` is not available (likely browser ESM). Call `await preloadRemark()` once on application startup before using the sync API, or use the async `markdownToDelta()` instead."
|
|
4342
|
+
);
|
|
4343
|
+
}
|
|
4294
4344
|
try {
|
|
4295
4345
|
const unifiedMod = require("unified");
|
|
4296
4346
|
const remarkParseMod = require("remark-parse");
|
|
@@ -4789,6 +4839,19 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4789
4839
|
currentInlineAttrs = { ...currentInlineAttrs, background: bgMatch[1].trim() };
|
|
4790
4840
|
addedKeys.push("background");
|
|
4791
4841
|
}
|
|
4842
|
+
const fontMatch = style.match(/(?:^|;)\s*font-family\s*:\s*([^;]+)/i);
|
|
4843
|
+
if (fontMatch) {
|
|
4844
|
+
currentInlineAttrs = {
|
|
4845
|
+
...currentInlineAttrs,
|
|
4846
|
+
font: fontMatch[1].trim().replace(/^["']|["']$/g, "")
|
|
4847
|
+
};
|
|
4848
|
+
addedKeys.push("font");
|
|
4849
|
+
}
|
|
4850
|
+
const sizeMatch = style.match(/(?:^|;)\s*font-size\s*:\s*([^;]+)/i);
|
|
4851
|
+
if (sizeMatch) {
|
|
4852
|
+
currentInlineAttrs = { ...currentInlineAttrs, size: sizeMatch[1].trim() };
|
|
4853
|
+
addedKeys.push("size");
|
|
4854
|
+
}
|
|
4792
4855
|
spanAttrStack.push(addedKeys);
|
|
4793
4856
|
return;
|
|
4794
4857
|
}
|
|
@@ -4866,6 +4929,54 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4866
4929
|
}
|
|
4867
4930
|
return delta;
|
|
4868
4931
|
}
|
|
4932
|
+
|
|
4933
|
+
// src/conversion/markdown/table-region.ts
|
|
4934
|
+
var import_delta11 = require("@scrider/delta");
|
|
4935
|
+
function isTableNewlineOp(op) {
|
|
4936
|
+
if (!op || !(0, import_delta11.isInsert)(op) || !(0, import_delta11.isTextInsert)(op)) return false;
|
|
4937
|
+
if (!op.insert.includes("\n")) return false;
|
|
4938
|
+
return !!op.attributes && "table-row" in op.attributes;
|
|
4939
|
+
}
|
|
4940
|
+
function extractTableRegion(ops, hintOpIdx) {
|
|
4941
|
+
if (hintOpIdx < 0 || hintOpIdx >= ops.length) return null;
|
|
4942
|
+
let probeIdx = -1;
|
|
4943
|
+
for (let i = hintOpIdx; i < ops.length; i++) {
|
|
4944
|
+
const op = ops[i];
|
|
4945
|
+
if (!op || !(0, import_delta11.isInsert)(op)) continue;
|
|
4946
|
+
if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n")) {
|
|
4947
|
+
probeIdx = i;
|
|
4948
|
+
break;
|
|
4949
|
+
}
|
|
4950
|
+
}
|
|
4951
|
+
if (probeIdx < 0) return null;
|
|
4952
|
+
if (!isTableNewlineOp(ops[probeIdx])) return null;
|
|
4953
|
+
let endOpIdx = probeIdx;
|
|
4954
|
+
for (let i = probeIdx + 1; i < ops.length; i++) {
|
|
4955
|
+
const op = ops[i];
|
|
4956
|
+
if (!op || !(0, import_delta11.isInsert)(op)) break;
|
|
4957
|
+
if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n")) {
|
|
4958
|
+
if (isTableNewlineOp(op)) {
|
|
4959
|
+
endOpIdx = i;
|
|
4960
|
+
} else {
|
|
4961
|
+
break;
|
|
4962
|
+
}
|
|
4963
|
+
}
|
|
4964
|
+
}
|
|
4965
|
+
let startOpIdx = 0;
|
|
4966
|
+
for (let i = probeIdx - 1; i >= 0; i--) {
|
|
4967
|
+
const op = ops[i];
|
|
4968
|
+
if (!op || !(0, import_delta11.isInsert)(op)) {
|
|
4969
|
+
startOpIdx = i + 1;
|
|
4970
|
+
break;
|
|
4971
|
+
}
|
|
4972
|
+
if ((0, import_delta11.isTextInsert)(op) && op.insert.includes("\n") && !isTableNewlineOp(op)) {
|
|
4973
|
+
startOpIdx = i + 1;
|
|
4974
|
+
break;
|
|
4975
|
+
}
|
|
4976
|
+
}
|
|
4977
|
+
const regionOps = ops.slice(startOpIdx, endOpIdx + 1);
|
|
4978
|
+
return { startOpIdx, endOpIdx, ops: regionOps };
|
|
4979
|
+
}
|
|
4869
4980
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4870
4981
|
0 && (module.exports = {
|
|
4871
4982
|
ALERT_TYPES,
|
|
@@ -4900,6 +5011,8 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4900
5011
|
dividerFormat,
|
|
4901
5012
|
escapeHtml,
|
|
4902
5013
|
extractBoxOpAttributes,
|
|
5014
|
+
extractTableRegion,
|
|
5015
|
+
fontFormat,
|
|
4903
5016
|
footnoteRefFormat,
|
|
4904
5017
|
footnotesBlockHandler,
|
|
4905
5018
|
formulaFormat,
|
|
@@ -4913,6 +5026,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4913
5026
|
isAdapterAvailable,
|
|
4914
5027
|
isElement,
|
|
4915
5028
|
isRemarkAvailable,
|
|
5029
|
+
isTableNewlineOp,
|
|
4916
5030
|
isTextNode,
|
|
4917
5031
|
isValidColor,
|
|
4918
5032
|
isValidHexColor,
|
|
@@ -4925,7 +5039,9 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
|
|
|
4925
5039
|
markdownToDeltaSync,
|
|
4926
5040
|
nodeAdapter,
|
|
4927
5041
|
normalizeDelta,
|
|
5042
|
+
preloadRemark,
|
|
4928
5043
|
sanitizeDelta,
|
|
5044
|
+
sizeFormat,
|
|
4929
5045
|
slugify,
|
|
4930
5046
|
slugifyWithDedup,
|
|
4931
5047
|
strikeFormat,
|