@scrider/formatter 1.10.9 → 1.10.11

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.d.cts CHANGED
@@ -93,6 +93,16 @@ interface ScriderDocumentMetadata {
93
93
  textIndentCm?: number;
94
94
  /** Extra left indent in cm on top-level `<ul>`/`<ol>` (shifts marker + text). */
95
95
  listBlockIndentCm?: number;
96
+ /**
97
+ * GFM-style extra left indent for list markers (em of the document size).
98
+ * Default on when omitted. `false` aligns markers with paragraph text.
99
+ */
100
+ listLeftIndent?: boolean;
101
+ /**
102
+ * Extra space above/below a list block (beyond body line-height).
103
+ * Default on when omitted.
104
+ */
105
+ listTopPadding?: boolean;
96
106
  /** Document heading horizontal alignment policy. Presence = policy on. */
97
107
  headingAlign?: 'left' | 'center' | 'right';
98
108
  /** Document heading bold policy. `true` = force bold on `h1`–`h6`. */
package/dist/index.d.ts CHANGED
@@ -93,6 +93,16 @@ interface ScriderDocumentMetadata {
93
93
  textIndentCm?: number;
94
94
  /** Extra left indent in cm on top-level `<ul>`/`<ol>` (shifts marker + text). */
95
95
  listBlockIndentCm?: number;
96
+ /**
97
+ * GFM-style extra left indent for list markers (em of the document size).
98
+ * Default on when omitted. `false` aligns markers with paragraph text.
99
+ */
100
+ listLeftIndent?: boolean;
101
+ /**
102
+ * Extra space above/below a list block (beyond body line-height).
103
+ * Default on when omitted.
104
+ */
105
+ listTopPadding?: boolean;
96
106
  /** Document heading horizontal alignment policy. Presence = policy on. */
97
107
  headingAlign?: 'left' | 'center' | 'right';
98
108
  /** Document heading bold policy. `true` = force bold on `h1`–`h6`. */
package/dist/index.js CHANGED
@@ -405,6 +405,9 @@ var LIST_WRAPPER_TAGS = {
405
405
  checked: "ul",
406
406
  unchecked: "ul"
407
407
  };
408
+ function listWrapperFamily(listType) {
409
+ return LIST_WRAPPER_TAGS[listType] || "ul";
410
+ }
408
411
  var EMBED_RENDERERS = {
409
412
  image: (value, attrs) => {
410
413
  const src = typeof value === "string" ? value : "";
@@ -3830,7 +3833,7 @@ function handleListOpen(stack, listType, indent, pretty, resolvedDocumentPresent
3830
3833
  }
3831
3834
  }
3832
3835
  const top = stack[stack.length - 1];
3833
- if (top && top.indent === indent && top.type !== listType) {
3836
+ if (top && top.indent === indent && listWrapperFamily(top.type) !== listWrapperFamily(listType)) {
3834
3837
  const closed = stack.pop();
3835
3838
  if (closed) {
3836
3839
  const closeTag = LIST_WRAPPER_TAGS[closed.type] || "ul";
@@ -4276,6 +4279,7 @@ function htmlToDelta(html, options = {}) {
4276
4279
  if (align) {
4277
4280
  currentBlockAttributes.align = align;
4278
4281
  }
4282
+ applyBlockIndentFromMargin(element);
4279
4283
  if (format.format === "header") {
4280
4284
  const id = element.getAttribute("id");
4281
4285
  if (id) {
@@ -4694,6 +4698,7 @@ function htmlToDelta(html, options = {}) {
4694
4698
  if (align) {
4695
4699
  currentBlockAttributes.align = align;
4696
4700
  }
4701
+ applyBlockIndentFromMargin(element);
4697
4702
  const children2 = element.childNodes;
4698
4703
  const firstChild = children2[0];
4699
4704
  const isBrOnlyParagraph = children2.length === 1 && firstChild !== void 0 && isElement(firstChild) && firstChild.tagName.toLowerCase() === "br" && !firstChild.hasAttribute("data-scrider-embed");
@@ -4710,6 +4715,26 @@ function htmlToDelta(html, options = {}) {
4710
4715
  }
4711
4716
  return null;
4712
4717
  }
4718
+ function parseIndentEm(raw) {
4719
+ if (!raw) return null;
4720
+ const match = raw.trim().match(/^(-?[\d.]+)em$/i);
4721
+ if (!match) return null;
4722
+ const em = Number.parseFloat(match[1]);
4723
+ if (!Number.isFinite(em) || em <= 0) return null;
4724
+ const level = Math.round(em / 2);
4725
+ if (level < 1 || level > 8) return null;
4726
+ return level;
4727
+ }
4728
+ function getIndentFromMarginLeft(element) {
4729
+ const fromAttr = (element.getAttribute?.("style") ?? "").match(/(?:^|;)\s*margin-left:\s*([^;]+)/i)?.[1];
4730
+ const fromStyle = element.style?.getPropertyValue?.("margin-left");
4731
+ return parseIndentEm(fromAttr) ?? parseIndentEm(fromStyle);
4732
+ }
4733
+ function applyBlockIndentFromMargin(element) {
4734
+ if (currentBlockAttributes.list != null) return;
4735
+ const indent = getIndentFromMarginLeft(element);
4736
+ if (indent != null) currentBlockAttributes.indent = indent;
4737
+ }
4713
4738
  const children = fragment.childNodes;
4714
4739
  for (let i = 0; i < children.length; i++) {
4715
4740
  const child = children[i];