@8btc/mditor 0.0.3 → 0.0.4

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.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vditor v0.0.1 - A markdown editor written in TypeScript.
2
+ * Vditor v0.0.3 - A markdown editor written in TypeScript.
3
3
  *
4
4
  * MIT License
5
5
  *
@@ -25,7 +25,7 @@
25
25
  *
26
26
  */
27
27
  /*!
28
- * Vditor v0.0.1 - A markdown editor written in TypeScript.
28
+ * Vditor v0.0.3 - A markdown editor written in TypeScript.
29
29
  *
30
30
  * MIT License
31
31
  *
@@ -1809,19 +1809,27 @@
1809
1809
  .vditor-sv__marker--strong {
1810
1810
  font-weight: bold;
1811
1811
  }
1812
- .vditor--linenumber .vditor-reset > ul [data-linenumber]:before,
1813
- .vditor--linenumber .vditor-reset ol [data-linenumber]:before {
1814
- margin-left: -4.5rem !important;
1812
+ .vditor--linenumber .vditor-reset > ul [data-linenumber]:after,
1813
+ .vditor--linenumber .vditor-reset ol [data-linenumber]:after {
1814
+ margin-left: -5rem !important;
1815
+ }
1816
+ .vditor--linenumber .vditor-reset > ul ul [data-linenumber]:after,
1817
+ .vditor--linenumber .vditor-reset ol ul [data-linenumber]:after,
1818
+ .vditor--linenumber .vditor-reset > ul ol [data-linenumber]:after,
1819
+ .vditor--linenumber .vditor-reset ol ol [data-linenumber]:after {
1820
+ margin-left: -7rem !important;
1815
1821
  }
1816
1822
  .vditor--linenumber .vditor-reset [data-linenumber] {
1817
1823
  position: relative;
1818
1824
  }
1819
- .vditor--linenumber .vditor-reset [data-linenumber]:before {
1825
+ .vditor--linenumber .vditor-reset [data-linenumber]:after {
1820
1826
  content: attr(data-linenumber);
1821
1827
  float: left;
1822
1828
  padding-right: 0.25rem;
1823
- margin-left: -2.5rem;
1824
- width: 2em;
1829
+ margin-left: -3rem;
1830
+ position: absolute;
1831
+ top: 0;
1832
+ width: 3em;
1825
1833
  text-align: right;
1826
1834
  color: var(--second-color);
1827
1835
  font-size: 0.75rem;
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * Vditor v0.0.1 - A markdown editor written in TypeScript.
2
+ * Vditor v0.0.3 - A markdown editor written in TypeScript.
3
3
  *
4
4
  * MIT License
5
5
  *
@@ -2791,7 +2791,7 @@ var Vditor = /** @class */ (function () {
2791
2791
  /* harmony export */ "H": () => (/* binding */ _VDITOR_VERSION),
2792
2792
  /* harmony export */ "g": () => (/* binding */ Constants)
2793
2793
  /* harmony export */ });
2794
- var _VDITOR_VERSION = "0.0.1";
2794
+ var _VDITOR_VERSION = "0.0.3";
2795
2795
 
2796
2796
  var Constants = /** @class */ (function () {
2797
2797
  function Constants() {
@@ -3093,7 +3093,7 @@ var Constants = /** @class */ (function () {
3093
3093
  "c#",
3094
3094
  "bat",
3095
3095
  ];
3096
- Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.1");
3096
+ Constants.CDN = "https://webcdn.wujieai.com/vditor@".concat("0.0.3");
3097
3097
  Constants.MARKDOWN_OPTIONS = {
3098
3098
  autoSpace: false,
3099
3099
  gfmAutoLink: true,
@@ -8678,14 +8678,9 @@ var highlightToolbarIR = function (vditor) {
8678
8678
 
8679
8679
  ;// CONCATENATED MODULE: ./src/ts/util/attachLineNumbers.ts
8680
8680
  /**
8681
- * 为编辑区域中所有包含 `data-block` 的块级节点添加 `data-linenumber` 属性。
8682
- * 通过解析传入的 Markdown 源文本,建立块内容到源文件行号的映射,
8683
- * 并在 DOM 上写入对应的行号,兼顾多行文本、重复内容以及空白/特殊字符。
8681
+ * 预处理 Markdown:构建块、无序列表、有序列表的行号索引。
8684
8682
  */
8685
- var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
8686
- if (!root || !sourceMarkdown) {
8687
- return;
8688
- }
8683
+ var prepareLineNumberIndex = function (sourceMarkdown) {
8689
8684
  var ZWSP = "\u200b";
8690
8685
  var normalize = function (text) {
8691
8686
  return text
@@ -8695,23 +8690,30 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
8695
8690
  .replace(/\u2006/g, "")
8696
8691
  .replace(/[\t\f\v ]+/g, " ");
8697
8692
  };
8698
- var srcNorm = normalize(sourceMarkdown);
8699
- var srcLines = srcNorm.split("\n");
8700
8693
  var stripInlineMD = function (text) {
8701
- return (text
8694
+ return text
8702
8695
  .replace(/\\([*_`~])/g, "$1")
8703
8696
  .replace(/\*\*|__/g, "")
8704
8697
  .replace(/\*|_/g, "")
8705
8698
  .replace(/~~/g, "")
8706
8699
  .replace(/`+/g, "")
8707
- // 数学行内分隔符:保留内容,仅移除分隔符
8708
8700
  .replace(/\\\(/g, "(")
8709
8701
  .replace(/\\\)/g, ")")
8710
8702
  .replace(/\\\[/g, "[")
8711
8703
  .replace(/\\\]/g, "]")
8712
8704
  .replace(/\$/g, "")
8713
- .trim());
8705
+ .trim();
8706
+ };
8707
+ var stripInlineForList = function (text) {
8708
+ return stripInlineMD(text)
8709
+ .replace(/\$(?:\\.|[^$])*\$/g, "")
8710
+ .replace(/\\\([^)]*\\\)/g, "")
8711
+ .replace(/\\\[[^\]]*\\\]/g, "")
8712
+ .replace(/\\[a-zA-Z]+/g, "")
8713
+ .replace(/[{}]/g, "")
8714
+ .trim();
8714
8715
  };
8716
+ var srcLines = normalize(sourceMarkdown).split("\n");
8715
8717
  var strippedLines = srcLines.map(function (l) { return stripInlineMD(l); });
8716
8718
  var lineLookup = new Map();
8717
8719
  for (var i = 0; i < strippedLines.length; i++) {
@@ -8723,6 +8725,115 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
8723
8725
  lineLookup.get(key).push(i + 1);
8724
8726
  }
8725
8727
  }
8728
+ var unorderedEntries = [];
8729
+ var unorderedLookup = new Map();
8730
+ for (var i = 0; i < srcLines.length; i++) {
8731
+ var raw = srcLines[i];
8732
+ var m = raw.match(/^\s*[*+-]\s+(?:\[(?: |x|X)\]\s+)?(.*)$/);
8733
+ if (m && typeof m[1] === "string") {
8734
+ var contentStripped = stripInlineForList(m[1]);
8735
+ unorderedEntries.push({ ln: i + 1, content: contentStripped });
8736
+ if (!unorderedLookup.has(contentStripped)) {
8737
+ unorderedLookup.set(contentStripped, [i + 1]);
8738
+ }
8739
+ else {
8740
+ unorderedLookup.get(contentStripped).push(i + 1);
8741
+ }
8742
+ }
8743
+ }
8744
+ var orderedEntries = [];
8745
+ var orderedLookup = new Map();
8746
+ var ORDERED_RE = /\s*\d+(?:[.)、.。]|[\uFF0E\uFF09\u3001])\s+(?:\[(?: |x|X)\]\s+)?(.*)/;
8747
+ for (var i = 0; i < srcLines.length; i++) {
8748
+ var raw = srcLines[i];
8749
+ var m = raw.match(new RegExp("^".concat(ORDERED_RE.source, "$")));
8750
+ if (m && typeof m[1] === "string") {
8751
+ var contentStripped = stripInlineForList(m[1]);
8752
+ orderedEntries.push({ ln: i + 1, content: contentStripped });
8753
+ if (!orderedLookup.has(contentStripped)) {
8754
+ orderedLookup.set(contentStripped, [i + 1]);
8755
+ }
8756
+ else {
8757
+ orderedLookup.get(contentStripped).push(i + 1);
8758
+ }
8759
+ }
8760
+ }
8761
+ var orderedGroups = [];
8762
+ for (var i = 0; i < srcLines.length;) {
8763
+ var raw = srcLines[i];
8764
+ if (new RegExp("^".concat(ORDERED_RE.source, "$")).test(raw)) {
8765
+ var group = [];
8766
+ while (i < srcLines.length &&
8767
+ new RegExp("^".concat(ORDERED_RE.source, "$")).test(srcLines[i])) {
8768
+ group.push(i + 1);
8769
+ i++;
8770
+ }
8771
+ if (group.length > 0) {
8772
+ orderedGroups.push(group);
8773
+ }
8774
+ }
8775
+ else {
8776
+ i++;
8777
+ }
8778
+ }
8779
+ return {
8780
+ srcLines: srcLines,
8781
+ strippedLines: strippedLines,
8782
+ lineLookup: lineLookup,
8783
+ unorderedEntries: unorderedEntries,
8784
+ unorderedLookup: unorderedLookup,
8785
+ orderedEntries: orderedEntries,
8786
+ orderedLookup: orderedLookup,
8787
+ orderedGroups: orderedGroups,
8788
+ };
8789
+ };
8790
+ var attachLineNumbersToBlocks = function (root, sourceMarkdownOrIndex) {
8791
+ if (!root || !sourceMarkdownOrIndex) {
8792
+ return;
8793
+ }
8794
+ var ZWSP = "\u200b";
8795
+ var normalize = function (text) {
8796
+ return text
8797
+ .replace(/\r\n|\r/g, "\n")
8798
+ .replace(new RegExp(ZWSP, "g"), "")
8799
+ .replace(/\u00a0/g, " ")
8800
+ .replace(/\u2006/g, "")
8801
+ .replace(/[\t\f\v ]+/g, " ");
8802
+ };
8803
+ var index = typeof sourceMarkdownOrIndex === "string"
8804
+ ? prepareLineNumberIndex(sourceMarkdownOrIndex)
8805
+ : sourceMarkdownOrIndex;
8806
+ var srcLines = index.srcLines;
8807
+ var stripInlineMD = function (text) {
8808
+ return (text
8809
+ .replace(/\\([*_`~])/g, "$1")
8810
+ .replace(/\*\*|__/g, "")
8811
+ .replace(/\*|_/g, "")
8812
+ .replace(/~~/g, "")
8813
+ .replace(/`+/g, "")
8814
+ // 数学行内分隔符:保留内容,仅移除分隔符
8815
+ .replace(/\\\(/g, "(")
8816
+ .replace(/\\\)/g, ")")
8817
+ .replace(/\\\[/g, "[")
8818
+ .replace(/\\\]/g, "]")
8819
+ .replace(/\$/g, "")
8820
+ .trim());
8821
+ };
8822
+ var stripInlineForList = function (text) {
8823
+ return (stripInlineMD(text)
8824
+ // 移除 $...$(行内公式整体)
8825
+ .replace(/\$(?:\\.|[^$])*\$/g, "")
8826
+ // 移除 \(...\)、\[...\](行内/行间公式整体)
8827
+ .replace(/\\\([^)]*\\\)/g, "")
8828
+ .replace(/\\\[[^\]]*\\\]/g, "")
8829
+ // 去除通用 TeX 命令,如 \alpha、\mathbf 等
8830
+ .replace(/\\[a-zA-Z]+/g, "")
8831
+ // 去除多余大括号
8832
+ .replace(/[{}]/g, "")
8833
+ .trim());
8834
+ };
8835
+ var strippedLines = index.strippedLines;
8836
+ var lineLookup = index.lineLookup;
8726
8837
  var usedLines = new Set();
8727
8838
  var pickFirstUnused = function (candidates) {
8728
8839
  if (!candidates || candidates.length === 0)
@@ -8748,92 +8859,125 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
8748
8859
  }
8749
8860
  return -1;
8750
8861
  };
8862
+ /**
8863
+ * 无序列表行号索引
8864
+ */
8865
+ var usedUnorderedLines = new Set();
8866
+ var unorderedListEntries = index.unorderedEntries;
8867
+ var unorderedLookup = index.unorderedLookup;
8868
+ /**
8869
+ * 从无序列表候选行中为给定文本选择一个行号。
8870
+ * 优先精确匹配(去标记后完全相同),否则回退到包含匹配。
8871
+ */
8872
+ var pickFirstUnusedUnordered = function (candidates) {
8873
+ if (!candidates || candidates.length === 0)
8874
+ return -1;
8875
+ for (var _i = 0, candidates_2 = candidates; _i < candidates_2.length; _i++) {
8876
+ var ln = candidates_2[_i];
8877
+ if (!usedUnorderedLines.has(ln))
8878
+ return ln;
8879
+ }
8880
+ return -1;
8881
+ };
8882
+ var findUnorderedListLineNumber = function (text) {
8883
+ var stripped = stripInlineForList(text);
8884
+ // 先尝试精确匹配
8885
+ var exact = pickFirstUnusedUnordered(unorderedLookup.get(stripped));
8886
+ if (exact !== -1)
8887
+ return exact;
8888
+ // 回退到包含匹配
8889
+ for (var i = 0; i < unorderedListEntries.length; i++) {
8890
+ var entry = unorderedListEntries[i];
8891
+ if (usedUnorderedLines.has(entry.ln))
8892
+ continue;
8893
+ if (!stripped)
8894
+ continue;
8895
+ if (entry.content.indexOf(stripped) !== -1 ||
8896
+ stripped.indexOf(entry.content) !== -1) {
8897
+ return entry.ln;
8898
+ }
8899
+ }
8900
+ return -1;
8901
+ };
8902
+ /**
8903
+ * 有序列表行号索引
8904
+ */
8905
+ var usedOrderedLines = new Set();
8906
+ var orderedListEntries = index.orderedEntries;
8907
+ var orderedLookup = index.orderedLookup;
8908
+ var orderedGroups = index.orderedGroups;
8909
+ console.debug("[LineNumber][ol:index]", {
8910
+ total: orderedListEntries.length,
8911
+ });
8912
+ /**
8913
+ * 为给定文本在有序列表候选中选择行号,精确匹配优先,包含匹配回退。
8914
+ */
8915
+ var pickFirstUnusedOrdered = function (candidates) {
8916
+ if (!candidates || candidates.length === 0)
8917
+ return -1;
8918
+ for (var _i = 0, candidates_3 = candidates; _i < candidates_3.length; _i++) {
8919
+ var ln = candidates_3[_i];
8920
+ if (!usedOrderedLines.has(ln))
8921
+ return ln;
8922
+ }
8923
+ return -1;
8924
+ };
8925
+ var findOrderedListLineNumber = function (text) {
8926
+ var stripped = stripInlineForList(text);
8927
+ var exact = pickFirstUnusedOrdered(orderedLookup.get(stripped));
8928
+ if (exact !== -1)
8929
+ return exact;
8930
+ for (var i = 0; i < orderedListEntries.length; i++) {
8931
+ var entry = orderedListEntries[i];
8932
+ if (usedOrderedLines.has(entry.ln))
8933
+ continue;
8934
+ if (!stripped)
8935
+ continue;
8936
+ if (entry.content.indexOf(stripped) !== -1 ||
8937
+ stripped.indexOf(entry.content) !== -1) {
8938
+ return entry.ln;
8939
+ }
8940
+ }
8941
+ return -1;
8942
+ };
8943
+ /**
8944
+ * 获取 `li` 的直接内容文本:仅拼接其直系子节点中的文本,排除嵌套的 `UL/OL` 列表。
8945
+ * 以便在嵌套列表场景下准确定位每个条目对应的源行。
8946
+ */
8947
+ var getImmediateLiText = function (li) {
8948
+ var buf = "";
8949
+ li.childNodes.forEach(function (node) {
8950
+ var _a;
8951
+ if (node.nodeType === 3) {
8952
+ buf += node.data;
8953
+ }
8954
+ else if (node.tagName !== "UL" &&
8955
+ node.tagName !== "OL" &&
8956
+ !((_a = node.classList) === null || _a === void 0 ? void 0 : _a.contains("katex"))) {
8957
+ buf += node.textContent || "";
8958
+ }
8959
+ });
8960
+ return buf;
8961
+ };
8751
8962
  var blocks = root.querySelectorAll("[data-block]");
8752
8963
  blocks.forEach(function (el) {
8753
8964
  try {
8754
- var text = el.textContent || "";
8965
+ var container = el;
8966
+ var dataType = container.getAttribute("data-type") || "";
8967
+ if (dataType === "math-block" || dataType === "code-block") {
8968
+ // container.setAttribute("data-linenumber", "");
8969
+ return;
8970
+ }
8971
+ var text = container.textContent || "";
8755
8972
  var normText = normalize(text);
8756
8973
  // 跳过纯空白块
8757
8974
  if (!normText.trim()) {
8758
- el.setAttribute("data-linenumber", "");
8975
+ // container.setAttribute("data-linenumber", "");
8759
8976
  return;
8760
8977
  }
8761
8978
  var lineNumber = -1;
8762
- var tag_1 = el.tagName;
8763
- if (tag_1 === "UL" || tag_1 === "OL") {
8764
- var listEl = el;
8765
- var items = Array.from(listEl.querySelectorAll(":scope > li"));
8766
- var cursor_1 = 0;
8767
- items.forEach(function (liEl) {
8768
- var raw = normalize(liEl.textContent || "");
8769
- if (!raw.trim()) {
8770
- liEl.setAttribute("data-linenumber", "");
8771
- return;
8772
- }
8773
- var firstLine = raw.split("\n").find(function (l) { return l.trim().length > 0; }) || raw;
8774
- var strippedLi = stripInlineMD(firstLine);
8775
- var ln = -1;
8776
- if (tag_1 === "UL") {
8777
- for (var i = Math.max(0, cursor_1); i < srcLines.length; i++) {
8778
- if (usedLines.has(i + 1))
8779
- continue;
8780
- var s = srcLines[i];
8781
- if (/^\s*[-*+]\s+/.test(s)) {
8782
- var content = stripInlineMD(s.replace(/^\s*[-*+]\s+(\[[ xX]\]\s+)?/, ""));
8783
- if (content.indexOf(strippedLi) !== -1) {
8784
- ln = i + 1;
8785
- cursor_1 = i + 1;
8786
- break;
8787
- }
8788
- }
8789
- }
8790
- }
8791
- else {
8792
- for (var i = Math.max(0, cursor_1); i < srcLines.length; i++) {
8793
- if (usedLines.has(i + 1))
8794
- continue;
8795
- var s = srcLines[i];
8796
- if (/^\s*\d+\.\s+/.test(s)) {
8797
- var content = stripInlineMD(s.replace(/^\s*\d+\.\s+/, ""));
8798
- if (content.indexOf(strippedLi) !== -1) {
8799
- ln = i + 1;
8800
- cursor_1 = i + 1;
8801
- break;
8802
- }
8803
- }
8804
- }
8805
- }
8806
- if (ln === -1) {
8807
- for (var i = 0; i < srcLines.length; i++) {
8808
- if (usedLines.has(i + 1))
8809
- continue;
8810
- var s = srcLines[i];
8811
- var isListLine = tag_1 === "UL"
8812
- ? /^\s*[-*+]\s+/.test(s)
8813
- : /^\s*\d+\.\s+/.test(s);
8814
- if (!isListLine)
8815
- continue;
8816
- var content = stripInlineMD(tag_1 === "UL"
8817
- ? s.replace(/^\s*[-*+]\s+(\[[ xX]\]\s+)?/, "")
8818
- : s.replace(/^\s*\d+\.\s+/, ""));
8819
- if (content.indexOf(strippedLi) !== -1) {
8820
- ln = i + 1;
8821
- cursor_1 = i + 1;
8822
- break;
8823
- }
8824
- }
8825
- }
8826
- if (ln !== -1) {
8827
- usedLines.add(ln);
8828
- liEl.setAttribute("data-linenumber", String(ln));
8829
- }
8830
- else {
8831
- liEl.setAttribute("data-linenumber", "");
8832
- }
8833
- });
8834
- return;
8835
- }
8836
- else if (tag_1 === "BLOCKQUOTE") {
8979
+ var tag = container.tagName;
8980
+ if (tag === "BLOCKQUOTE") {
8837
8981
  var firstLine = normText.split("\n").find(function (l) { return l.trim().length > 0; }) ||
8838
8982
  normText;
8839
8983
  var stripped = stripInlineMD(firstLine);
@@ -8856,10 +9000,150 @@ var attachLineNumbersToBlocks = function (root, sourceMarkdown) {
8856
9000
  }
8857
9001
  if (lineNumber !== -1) {
8858
9002
  usedLines.add(lineNumber);
8859
- el.setAttribute("data-linenumber", String(lineNumber));
9003
+ container.setAttribute("data-linenumber", String(lineNumber));
8860
9004
  }
8861
- else {
8862
- el.setAttribute("data-linenumber", "");
9005
+ }
9006
+ catch (_a) {
9007
+ void 0;
9008
+ }
9009
+ });
9010
+ /**
9011
+ * 为所有 `ul` 下的每个直接 `li` 子元素追加 `data-linenumber`,不修改 `ul` 本身。
9012
+ * 支持多层嵌套与非文本起始节点(如加粗/行内代码)。
9013
+ */
9014
+ var ulElements = root.querySelectorAll("ul");
9015
+ ulElements.forEach(function (ul) {
9016
+ try {
9017
+ var children = Array.from(ul.children);
9018
+ for (var _i = 0, children_1 = children; _i < children_1.length; _i++) {
9019
+ var child = children_1[_i];
9020
+ if (child.tagName !== "LI")
9021
+ continue;
9022
+ var li = child;
9023
+ var rawText = getImmediateLiText(li);
9024
+ var norm = normalize(rawText);
9025
+ var firstLine = norm.split("\n").find(function (l) { return l.trim().length > 0; }) || norm;
9026
+ var ln = findUnorderedListLineNumber(firstLine);
9027
+ if (ln !== -1) {
9028
+ usedUnorderedLines.add(ln);
9029
+ li.setAttribute("data-linenumber", String(ln));
9030
+ }
9031
+ else {
9032
+ li.setAttribute("data-linenumber", "");
9033
+ }
9034
+ }
9035
+ }
9036
+ catch (_a) {
9037
+ void 0;
9038
+ }
9039
+ });
9040
+ /**
9041
+ * 为所有 `ol` 下的每个直接 `li` 子元素追加 `data-linenumber`,不修改 `ol` 本身。
9042
+ */
9043
+ var olElements = root.querySelectorAll("ol");
9044
+ olElements.forEach(function (ol) {
9045
+ try {
9046
+ var currentGroupIdx = -1;
9047
+ var lastAssigned_1 = -1;
9048
+ var children = Array.from(ol.children);
9049
+ for (var _i = 0, children_2 = children; _i < children_2.length; _i++) {
9050
+ var child = children_2[_i];
9051
+ if (child.tagName !== "LI")
9052
+ continue;
9053
+ var li = child;
9054
+ var rawText = getImmediateLiText(li);
9055
+ var norm = normalize(rawText);
9056
+ var firstLine = norm.split("\n").find(function (l) { return l.trim().length > 0; }) || norm;
9057
+ var stripped0 = stripInlineForList(firstLine);
9058
+ var stripped = stripped0 || stripInlineMD(firstLine);
9059
+ var candidates = orderedLookup.get(stripped) || [];
9060
+ var available = candidates.filter(function (n) { return !usedOrderedLines.has(n); });
9061
+ var ln = findOrderedListLineNumber(firstLine);
9062
+ if (ln !== -1) {
9063
+ usedOrderedLines.add(ln);
9064
+ li.setAttribute("data-linenumber", String(ln));
9065
+ // 成功映射日志
9066
+ console.debug("[LineNumber][ol>li]", {
9067
+ text: firstLine,
9068
+ stripped: stripped,
9069
+ line: ln,
9070
+ });
9071
+ // 记录当前组
9072
+ for (var gi = 0; gi < orderedGroups.length; gi++) {
9073
+ if (orderedGroups[gi].includes(ln)) {
9074
+ currentGroupIdx = gi;
9075
+ break;
9076
+ }
9077
+ }
9078
+ lastAssigned_1 = ln;
9079
+ }
9080
+ else {
9081
+ // 顺序回退:基于当前组或猜测组,按序分配下一未使用行
9082
+ var assigned = -1;
9083
+ var pickNextFromGroup = function (gi) {
9084
+ if (gi < 0 || gi >= orderedGroups.length)
9085
+ return -1;
9086
+ var lines = orderedGroups[gi];
9087
+ // 优先从上次分配后续查找
9088
+ var startIdx = 0;
9089
+ if (lastAssigned_1 !== -1) {
9090
+ var idx = lines.indexOf(lastAssigned_1);
9091
+ startIdx = idx >= 0 ? idx + 1 : 0;
9092
+ }
9093
+ for (var k = startIdx; k < lines.length; k++) {
9094
+ var cand = lines[k];
9095
+ if (!usedOrderedLines.has(cand))
9096
+ return cand;
9097
+ }
9098
+ for (var k = 0; k < startIdx; k++) {
9099
+ var cand = lines[k];
9100
+ if (!usedOrderedLines.has(cand))
9101
+ return cand;
9102
+ }
9103
+ return -1;
9104
+ };
9105
+ if (currentGroupIdx !== -1) {
9106
+ assigned = pickNextFromGroup(currentGroupIdx);
9107
+ }
9108
+ if (assigned === -1) {
9109
+ // 猜测组:选择拥有可用行的首个组
9110
+ for (var gi = 0; gi < orderedGroups.length && assigned === -1; gi++) {
9111
+ var cand = pickNextFromGroup(gi);
9112
+ if (cand !== -1) {
9113
+ currentGroupIdx = gi;
9114
+ assigned = cand;
9115
+ }
9116
+ }
9117
+ }
9118
+ if (assigned !== -1) {
9119
+ usedOrderedLines.add(assigned);
9120
+ li.setAttribute("data-linenumber", String(assigned));
9121
+ console.debug("[LineNumber][ol>li][fallback-seq]", {
9122
+ text: firstLine,
9123
+ stripped: stripped,
9124
+ line: assigned,
9125
+ group: currentGroupIdx,
9126
+ });
9127
+ lastAssigned_1 = assigned;
9128
+ }
9129
+ else {
9130
+ li.setAttribute("data-linenumber", "");
9131
+ // 失败诊断日志
9132
+ console.warn("[LineNumber][ol>li][missing]", {
9133
+ text: firstLine,
9134
+ stripped: stripped,
9135
+ candidates: candidates,
9136
+ available: available,
9137
+ reason: !stripped0
9138
+ ? "empty-after-strip"
9139
+ : candidates.length === 0
9140
+ ? "no-index-candidates"
9141
+ : available.length === 0
9142
+ ? "all-candidates-consumed"
9143
+ : "fallback-no-match",
9144
+ });
9145
+ }
9146
+ }
8863
9147
  }
8864
9148
  }
8865
9149
  catch (_a) {
@@ -8906,7 +9190,8 @@ var afterRenderEvent = function (vditor, options) {
8906
9190
  vditor.undo.addToUndoStack(vditor);
8907
9191
  }
8908
9192
  try {
8909
- attachLineNumbersToBlocks(vditor.wysiwyg.element, text);
9193
+ var lnIndex = vditor.lineNumberIndex || prepareLineNumberIndex(text);
9194
+ attachLineNumbersToBlocks(vditor.wysiwyg.element, lnIndex);
8910
9195
  }
8911
9196
  catch (_a) {
8912
9197
  void 0;
@@ -11535,7 +11820,8 @@ var processAfterRender = function (vditor, options) {
11535
11820
  vditor.undo.addToUndoStack(vditor);
11536
11821
  }
11537
11822
  try {
11538
- attachLineNumbersToBlocks(vditor.sv.element, text);
11823
+ var lnIndex = vditor.lineNumberIndex || prepareLineNumberIndex(text);
11824
+ attachLineNumbersToBlocks(vditor.sv.element, lnIndex);
11539
11825
  }
11540
11826
  catch (_a) {
11541
11827
  void 0;
@@ -12644,12 +12930,25 @@ var isHeadingMD = function (text) {
12644
12930
  }
12645
12931
  return false;
12646
12932
  };
12933
+
12934
+
12647
12935
  var execAfterRender = function (vditor, options) {
12648
12936
  if (options === void 0) { options = {
12649
12937
  enableAddUndoStack: true,
12650
12938
  enableHint: false,
12651
12939
  enableInput: true,
12652
12940
  }; }
12941
+ try {
12942
+ var md = getMarkdown(vditor);
12943
+ var cached = vditor.lineNumberIndex;
12944
+ var same = cached &&
12945
+ Array.isArray(cached.srcLines) &&
12946
+ cached.srcLines.join("\n") === md;
12947
+ vditor.lineNumberIndex = same ? cached : prepareLineNumberIndex(md);
12948
+ }
12949
+ catch (_a) {
12950
+ vditor.lineNumberIndex = undefined;
12951
+ }
12653
12952
  if (vditor.currentMode === "wysiwyg") {
12654
12953
  afterRenderEvent(vditor, options);
12655
12954
  }
@@ -13978,7 +14277,8 @@ var process_processAfterRender = function (vditor, options) {
13978
14277
  vditor.undo.addToUndoStack(vditor);
13979
14278
  }
13980
14279
  try {
13981
- attachLineNumbersToBlocks(vditor.ir.element, text);
14280
+ var lnIndex = vditor.lineNumberIndex || prepareLineNumberIndex(text);
14281
+ attachLineNumbersToBlocks(vditor.ir.element, lnIndex);
13982
14282
  }
13983
14283
  catch (_a) {
13984
14284
  void 0;
@@ -17990,6 +18290,7 @@ var src_extends = (undefined && undefined.__extends) || (function () {
17990
18290
 
17991
18291
 
17992
18292
 
18293
+
17993
18294
 
17994
18295
 
17995
18296
  /**
@@ -18283,6 +18584,12 @@ var Vditor = /** @class */ (function (_super) {
18283
18584
  Vditor.prototype.setValue = function (markdown, clearStack) {
18284
18585
  var _this = this;
18285
18586
  if (clearStack === void 0) { clearStack = false; }
18587
+ try {
18588
+ this.vditor.lineNumberIndex = prepareLineNumberIndex(markdown);
18589
+ }
18590
+ catch (_a) {
18591
+ this.vditor.lineNumberIndex = undefined;
18592
+ }
18286
18593
  if (this.vditor.currentMode === "sv") {
18287
18594
  this.vditor.sv.element.innerHTML = "<div data-block='0'>".concat(this.vditor.lute.SpinVditorSVDOM(markdown), "</div>");
18288
18595
  processAfterRender(this.vditor, {