@scrider/formatter 1.1.0 → 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 CHANGED
@@ -63,6 +63,7 @@ __export(index_exports, {
63
63
  dividerFormat: () => dividerFormat,
64
64
  escapeHtml: () => escapeHtml,
65
65
  extractBoxOpAttributes: () => extractBoxOpAttributes,
66
+ extractTableRegion: () => extractTableRegion,
66
67
  fontFormat: () => fontFormat,
67
68
  footnoteRefFormat: () => footnoteRefFormat,
68
69
  footnotesBlockHandler: () => footnotesBlockHandler,
@@ -77,6 +78,7 @@ __export(index_exports, {
77
78
  isAdapterAvailable: () => isAdapterAvailable,
78
79
  isElement: () => isElement,
79
80
  isRemarkAvailable: () => isRemarkAvailable,
81
+ isTableNewlineOp: () => isTableNewlineOp,
80
82
  isTextNode: () => isTextNode,
81
83
  isValidColor: () => isValidColor,
82
84
  isValidHexColor: () => isValidHexColor,
@@ -89,6 +91,7 @@ __export(index_exports, {
89
91
  markdownToDeltaSync: () => markdownToDeltaSync,
90
92
  nodeAdapter: () => nodeAdapter,
91
93
  normalizeDelta: () => normalizeDelta,
94
+ preloadRemark: () => preloadRemark,
92
95
  sanitizeDelta: () => sanitizeDelta,
93
96
  sizeFormat: () => sizeFormat,
94
97
  slugify: () => slugify,
@@ -3756,7 +3759,8 @@ function deltaToMarkdown(delta, options = {}) {
3756
3759
  embedRenderers = {},
3757
3760
  blockHandlers,
3758
3761
  prettyHtml = false,
3759
- registry
3762
+ registry,
3763
+ trimTrailingNewlines = false
3760
3764
  } = options;
3761
3765
  const useLatexDelimiters = mathSyntax === "latex";
3762
3766
  const lines = splitIntoLines2(delta.ops);
@@ -3854,7 +3858,8 @@ ${code}
3854
3858
  lastIndent = indent;
3855
3859
  lastWasBlockquote = isBlockquote;
3856
3860
  }
3857
- return result.join("\n");
3861
+ const md = result.join("\n");
3862
+ return trimTrailingNewlines ? md.replace(/\n+$/, "") : md;
3858
3863
  }
3859
3864
  function hasBlockFormat(attrs) {
3860
3865
  return !!(attrs.header || attrs.list || attrs.blockquote || attrs["code-block"] || attrs.align || attrs.indent);
@@ -4243,6 +4248,8 @@ var remarkGfm = null;
4243
4248
  var remarkMath = null;
4244
4249
  var unified = null;
4245
4250
  function isRemarkAvailable() {
4251
+ if (unified && remarkParse) return true;
4252
+ if (typeof require === "undefined") return false;
4246
4253
  try {
4247
4254
  require.resolve("unified");
4248
4255
  require.resolve("remark-parse");
@@ -4251,8 +4258,8 @@ function isRemarkAvailable() {
4251
4258
  return false;
4252
4259
  }
4253
4260
  }
4254
- async function loadRemark() {
4255
- if (unified) return;
4261
+ async function preloadRemark() {
4262
+ if (unified && remarkParse && remarkGfm) return true;
4256
4263
  try {
4257
4264
  const [unifiedMod, remarkParseMod, remarkGfmMod] = await Promise.all([
4258
4265
  import("unified"),
@@ -4263,15 +4270,16 @@ async function loadRemark() {
4263
4270
  remarkParse = remarkParseMod.default;
4264
4271
  remarkGfm = remarkGfmMod.default;
4265
4272
  } catch {
4266
- throw new Error(
4267
- "remark is not installed. Install with: pnpm add unified remark-parse remark-gfm"
4268
- );
4273
+ return false;
4269
4274
  }
4270
- try {
4271
- const remarkMathMod = await import("remark-math");
4272
- remarkMath = remarkMathMod.default;
4273
- } catch {
4275
+ if (!remarkMath) {
4276
+ try {
4277
+ const remarkMathMod = await import("remark-math");
4278
+ remarkMath = remarkMathMod.default;
4279
+ } catch {
4280
+ }
4274
4281
  }
4282
+ return true;
4275
4283
  }
4276
4284
  function preprocessMarkdown(markdown, mathBlock) {
4277
4285
  markdown = markdown.replace(/\\\((.+?)\\\)/g, (_match, content) => `$${content}$`);
@@ -4295,9 +4303,11 @@ async function markdownToDelta(markdown, options = {}) {
4295
4303
  nodeHandlers = {}
4296
4304
  } = options;
4297
4305
  markdown = preprocessMarkdown(markdown, mathBlock);
4298
- await loadRemark();
4299
- if (!unified || !remarkParse) {
4300
- throw new Error("Failed to load remark");
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
+ );
4301
4311
  }
4302
4312
  let processor = unified().use(remarkParse);
4303
4313
  if (gfm && remarkGfm) {
@@ -4326,6 +4336,11 @@ function markdownToDeltaSync(markdown, options = {}) {
4326
4336
  } = options;
4327
4337
  markdown = preprocessMarkdown(markdown, mathBlock);
4328
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
+ }
4329
4344
  try {
4330
4345
  const unifiedMod = require("unified");
4331
4346
  const remarkParseMod = require("remark-parse");
@@ -4914,6 +4929,54 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
4914
4929
  }
4915
4930
  return delta;
4916
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
+ }
4917
4980
  // Annotate the CommonJS export names for ESM import in node:
4918
4981
  0 && (module.exports = {
4919
4982
  ALERT_TYPES,
@@ -4948,6 +5011,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
4948
5011
  dividerFormat,
4949
5012
  escapeHtml,
4950
5013
  extractBoxOpAttributes,
5014
+ extractTableRegion,
4951
5015
  fontFormat,
4952
5016
  footnoteRefFormat,
4953
5017
  footnotesBlockHandler,
@@ -4962,6 +5026,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
4962
5026
  isAdapterAvailable,
4963
5027
  isElement,
4964
5028
  isRemarkAvailable,
5029
+ isTableNewlineOp,
4965
5030
  isTextNode,
4966
5031
  isValidColor,
4967
5032
  isValidHexColor,
@@ -4974,6 +5039,7 @@ function astToDelta(tree, customHandlers, mathBlock, mermaidBlock, plantumlBlock
4974
5039
  markdownToDeltaSync,
4975
5040
  nodeAdapter,
4976
5041
  normalizeDelta,
5042
+ preloadRemark,
4977
5043
  sanitizeDelta,
4978
5044
  sizeFormat,
4979
5045
  slugify,