@scrider/formatter 1.10.8 → 1.10.10

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
@@ -548,6 +548,9 @@ var LIST_WRAPPER_TAGS = {
548
548
  checked: "ul",
549
549
  unchecked: "ul"
550
550
  };
551
+ function listWrapperFamily(listType) {
552
+ return LIST_WRAPPER_TAGS[listType] || "ul";
553
+ }
551
554
  var EMBED_RENDERERS = {
552
555
  image: (value, attrs) => {
553
556
  const src = typeof value === "string" ? value : "";
@@ -3548,7 +3551,25 @@ function deltaToHtml(delta, options = {}) {
3548
3551
  i += tableLines.length - 1;
3549
3552
  continue;
3550
3553
  }
3551
- const { tag, isList, listType, indent, isCodeBlock } = getBlockInfo(line.attributes);
3554
+ const { tag, isList, listType, indent, isCodeBlock, isBlockquote } = getBlockInfo(
3555
+ line.attributes
3556
+ );
3557
+ if (isBlockquote) {
3558
+ html += closeAllLists(listStack, pretty);
3559
+ listStack = [];
3560
+ counters = [];
3561
+ const quoteLines = collectBlockquoteLines(lines, i);
3562
+ html += renderBlockquote(
3563
+ quoteLines,
3564
+ embedRenderers,
3565
+ pretty,
3566
+ blockHandlers,
3567
+ options,
3568
+ resolvedDocumentPresentation
3569
+ );
3570
+ i += quoteLines.length - 1;
3571
+ continue;
3572
+ }
3552
3573
  if (isCodeBlock) {
3553
3574
  html += closeAllLists(listStack, pretty);
3554
3575
  listStack = [];
@@ -3577,13 +3598,7 @@ function deltaToHtml(delta, options = {}) {
3577
3598
  continue;
3578
3599
  }
3579
3600
  if (isList) {
3580
- html += handleListOpen(
3581
- listStack,
3582
- listType,
3583
- indent,
3584
- pretty,
3585
- resolvedDocumentPresentation
3586
- );
3601
+ html += handleListOpen(listStack, listType, indent, pretty, resolvedDocumentPresentation);
3587
3602
  if (hierarchicalNumbers && listType === "ordered") {
3588
3603
  if (counters.length > indent + 1) {
3589
3604
  counters = counters.slice(0, indent + 1);
@@ -3816,24 +3831,90 @@ function renderTableRow(cells, maxCol, cellTag, embedRenderers, pretty, depth, b
3816
3831
  }
3817
3832
  function getBlockInfo(attributes) {
3818
3833
  if (!attributes) {
3819
- return { tag: "p", isList: false, isCodeBlock: false, listType: void 0, indent: 0 };
3834
+ return {
3835
+ tag: "p",
3836
+ isList: false,
3837
+ isCodeBlock: false,
3838
+ isBlockquote: false,
3839
+ listType: void 0,
3840
+ indent: 0
3841
+ };
3820
3842
  }
3821
3843
  const indent = typeof attributes.indent === "number" ? attributes.indent : 0;
3822
3844
  if (attributes["code-block"]) {
3823
- return { tag: "pre", isList: false, isCodeBlock: true, listType: void 0, indent };
3845
+ return {
3846
+ tag: "pre",
3847
+ isList: false,
3848
+ isCodeBlock: true,
3849
+ isBlockquote: false,
3850
+ listType: void 0,
3851
+ indent
3852
+ };
3824
3853
  }
3825
3854
  if (attributes.list) {
3826
3855
  const listVal = attributes.list;
3827
3856
  const listType = typeof listVal === "string" ? listVal : "bullet";
3828
- return { tag: "li", isList: true, isCodeBlock: false, listType, indent };
3857
+ return { tag: "li", isList: true, isCodeBlock: false, isBlockquote: false, listType, indent };
3858
+ }
3859
+ if (attributes.blockquote) {
3860
+ return {
3861
+ tag: "blockquote",
3862
+ isList: false,
3863
+ isCodeBlock: false,
3864
+ isBlockquote: true,
3865
+ listType: void 0,
3866
+ indent
3867
+ };
3829
3868
  }
3830
3869
  for (const [format, tagOrFn] of Object.entries(BLOCK_FORMAT_TAGS)) {
3831
3870
  if (format in attributes && format !== "list" && format !== "code-block") {
3832
3871
  const tag = typeof tagOrFn === "function" ? tagOrFn(attributes[format]) : tagOrFn;
3833
- return { tag, isList: false, isCodeBlock: false, listType: void 0, indent };
3872
+ return {
3873
+ tag,
3874
+ isList: false,
3875
+ isCodeBlock: false,
3876
+ isBlockquote: false,
3877
+ listType: void 0,
3878
+ indent
3879
+ };
3834
3880
  }
3835
3881
  }
3836
- return { tag: "p", isList: false, isCodeBlock: false, listType: void 0, indent };
3882
+ return {
3883
+ tag: "p",
3884
+ isList: false,
3885
+ isCodeBlock: false,
3886
+ isBlockquote: false,
3887
+ listType: void 0,
3888
+ indent
3889
+ };
3890
+ }
3891
+ function collectBlockquoteLines(lines, startIndex) {
3892
+ const quoteLines = [];
3893
+ for (let i = startIndex; i < lines.length; i++) {
3894
+ const line = lines[i];
3895
+ if (!line || !line.attributes?.blockquote) break;
3896
+ quoteLines.push(line);
3897
+ }
3898
+ return quoteLines;
3899
+ }
3900
+ function renderBlockquote(quoteLines, embedRenderers, pretty, blockHandlers, options, resolvedDocumentPresentation) {
3901
+ const firstAttrs = quoteLines[0]?.attributes;
3902
+ const wrapperIndent = firstAttrs && typeof firstAttrs.indent === "number" && firstAttrs.indent > 0 ? ` style="margin-left: ${firstAttrs.indent * 2}em"` : "";
3903
+ const nl = pretty ? "\n" : "";
3904
+ const innerIndent = pretty ? " " : "";
3905
+ let html = `<blockquote${wrapperIndent}>${nl}`;
3906
+ for (const line of quoteLines) {
3907
+ const content = renderLineContent(line.ops, embedRenderers, blockHandlers, options);
3908
+ html += `${innerIndent}${renderBlockquoteParagraph(content, line.attributes, resolvedDocumentPresentation)}${nl}`;
3909
+ }
3910
+ html += `</blockquote>`;
3911
+ return pretty ? html + "\n" : html;
3912
+ }
3913
+ function renderBlockquoteParagraph(content, attributes, resolvedDocumentPresentation) {
3914
+ const styleSource = attributes ? { ...attributes, indent: void 0 } : void 0;
3915
+ const styleAttr = getBlockStyleAttribute("blockquote", styleSource, resolvedDocumentPresentation);
3916
+ const innerContent = content || "<br>";
3917
+ return `<p${styleAttr}>${innerContent}</p>`;
3837
3918
  }
3838
3919
  function collectCodeBlockLines(lines, startIndex) {
3839
3920
  const codeLines = [];
@@ -3895,7 +3976,7 @@ function handleListOpen(stack, listType, indent, pretty, resolvedDocumentPresent
3895
3976
  }
3896
3977
  }
3897
3978
  const top = stack[stack.length - 1];
3898
- if (top && top.indent === indent && top.type !== listType) {
3979
+ if (top && top.indent === indent && listWrapperFamily(top.type) !== listWrapperFamily(listType)) {
3899
3980
  const closed = stack.pop();
3900
3981
  if (closed) {
3901
3982
  const closeTag = LIST_WRAPPER_TAGS[closed.type] || "ul";
@@ -4084,6 +4165,22 @@ function renderEmbed(value, attributes, renderers, blockHandlers, options) {
4084
4165
 
4085
4166
  // src/conversion/html/html-to-delta.ts
4086
4167
  var import_delta9 = require("@scrider/delta");
4168
+ var BLOCKQUOTE_INNER_BLOCK_TAGS = /* @__PURE__ */ new Set([
4169
+ "p",
4170
+ "div",
4171
+ "h1",
4172
+ "h2",
4173
+ "h3",
4174
+ "h4",
4175
+ "h5",
4176
+ "h6",
4177
+ "ul",
4178
+ "ol",
4179
+ "li",
4180
+ "pre",
4181
+ "blockquote",
4182
+ "table"
4183
+ ]);
4087
4184
  function isCssWideKeyword(value) {
4088
4185
  return /^(inherit|initial|unset|revert|revert-layer)$/i.test(value.trim());
4089
4186
  }
@@ -4336,9 +4433,21 @@ function htmlToDelta(html, options = {}) {
4336
4433
  }
4337
4434
  }
4338
4435
  processChildren(element);
4339
- context.pushNewline();
4436
+ if (!(format.format === "blockquote" && hasBlockChildElement(element))) {
4437
+ context.pushNewline();
4438
+ }
4340
4439
  currentBlockAttributes = prevBlockAttrs;
4341
4440
  }
4441
+ function hasBlockChildElement(element) {
4442
+ const children2 = element.childNodes;
4443
+ for (let i = 0; i < children2.length; i++) {
4444
+ const child = children2[i];
4445
+ if (!child || !isElement(child)) continue;
4446
+ const tag = child.tagName.toLowerCase();
4447
+ if (BLOCKQUOTE_INNER_BLOCK_TAGS.has(tag)) return true;
4448
+ }
4449
+ return false;
4450
+ }
4342
4451
  function processCodeBlockElement(element) {
4343
4452
  const prevBlockAttrs = { ...currentBlockAttributes };
4344
4453
  let language;