markdown-it-any-block 3.3.2 → 3.3.3

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.
@@ -21,6 +21,7 @@ async function jsdom_init() {
21
21
  global.HTMLScriptElement = dom.window.HTMLScriptElement;
22
22
  dom.window.scrollTo = () => {
23
23
  };
24
+ global.MutationObserver = dom.window.MutationObserver;
24
25
  }
25
26
  var ABConvert_IOEnum = /* @__PURE__ */ ((ABConvert_IOEnum2) => {
26
27
  ABConvert_IOEnum2["text"] = "string";
@@ -88,61 +89,6 @@ class ABConvert {
88
89
  ABConvertManager.getInstance().list_abConvert.splice(index2, 1);
89
90
  }
90
91
  }
91
- /** --------------------------------- 处理器容器管理 (旧) --------------- */
92
- /*
93
- /// 用户注册处理器
94
- public static registerABProcessor(process: ABProcessorSpec| ABProcessorSpecSimp| ABProcessorSpecUser){
95
- ABConvertManager.getInstance().list_abConvert.push(ABProcessorSpec.registerABProcessor_adapt(process));
96
- }
97
-
98
- public static registerABProcessor_adapt(process: ABProcessorSpec| ABProcessorSpecSimp| ABProcessorSpecUser): ABProcessorSpec{
99
- if ('is_disable' in process) { // 严格版 存储版
100
- return process
101
- }
102
- else if ('process' in process) { // 用户版 注册版
103
- return this.registerABProcessor_adapt_simp(process)
104
- }
105
- else { // 别名版 无代码版
106
- return this.registerABProcessor_adapt_user(process)
107
- }
108
- }
109
-
110
- private static registerABProcessor_adapt_simp(sim: ABProcessorSpecSimp):ABProcessorSpec{
111
- //type t_param = Parameters<typeof sim.process>
112
- //type t_return = ReturnType<typeof sim.process>
113
- const abProcessorSpec: ABProcessorSpec = {
114
- id: sim.id,
115
- name: sim.name,
116
- match: sim.match??sim.id,
117
- default: sim.default??(!sim.match||typeof(sim.match)=="string")?sim.id:null,
118
- detail: sim.detail??"",
119
- process_alias: sim.process_alias??"",
120
- process_param: sim.process_param??null,
121
- process_return: sim.process_return??null,
122
- process: sim.process,
123
- is_disable: false,
124
- register_from: "内置",
125
- }
126
- return abProcessorSpec
127
- }
128
-
129
- private static registerABProcessor_adapt_user(sim: ABProcessorSpecUser):ABProcessorSpec{
130
- const abProcessorSpec: ABProcessorSpec = {
131
- id: sim.id,
132
- name: sim.name,
133
- match: /^\//.test(sim.match)?RegExp(sim.match):sim.match,
134
- default: null,
135
- detail: "",
136
- process_alias: sim.process_alias,
137
- process_param: null,
138
- process_return: null,
139
- process: ()=>{},
140
- is_disable: false,
141
- register_from: "用户",
142
- }
143
- return abProcessorSpec
144
- }
145
- */
146
92
  }
147
93
  const ABReg = {
148
94
  /**
@@ -268,7 +214,10 @@ const ABAlias_json_title = [
268
214
  { regex: /\|heading_140lne\|(fakeList|仿列表)\|/, replacement: "|title2list|list2table|addClass(ab-table-fc)|addClass(ab-table-likelist)|" }
269
215
  ];
270
216
  const ABAlias_json_list = [
271
- { regex: "|listXinline|", replacement: "|list2listdata|listdata2list|" },
217
+ // 特殊
218
+ { regex: "|listXinline|", replacement: "|list2listdata|listdata2strict|listdata2list|" },
219
+ { regex: "|list2task|", replacement: "|list2listdata|listdata2task|listdata2list|" },
220
+ { regex: "|task2", replacement: "|list2listdata|listdata2task|listdata2list|list2" },
272
221
  // list - list&title
273
222
  { regex: /\|list_140lne\|2?(timeline|时间线)\|/, replacement: "|list2timeline|" },
274
223
  { regex: /\|list_140lne\|2?(tabs?|标签页?)\||\|list2tabs?\|/, replacement: "|list2c2listdata|c2listdata2tab|" },
@@ -370,7 +319,7 @@ class ABConvertManager {
370
319
  this.list_abConvert = [];
371
320
  this.m_renderMarkdownFn = (markdown, el) => {
372
321
  el.classList.add("markdown-rendered");
373
- console.error("AnyBlockError: 请先制定/重定义md渲染器");
322
+ console.error("Please use renderMarkdownFn redefine render function");
374
323
  };
375
324
  if (typeof obsidian == "undefined" && typeof app == "undefined") {
376
325
  console.log("[environment]: markdown-it, without obsidian");
@@ -414,7 +363,7 @@ class ABConvertManager {
414
363
  * @param selectorName 选择器名,空表示未知
415
364
  * @return 等于el,无用,后面可以删了
416
365
  */
417
- static autoABConvert(el, header, content, selectorName = "") {
366
+ static autoABConvert(el, header, content, selectorName = "", ctx) {
418
367
  let prev_result = content;
419
368
  let prev_type = "string";
420
369
  let prev_type2 = ABConvert_IOEnum.text;
@@ -429,8 +378,8 @@ class ABConvertManager {
429
378
  {
430
379
  header = autoABAlias(header, selectorName, prev_result);
431
380
  let list_header = header.split("|");
432
- prev_result = this.autoABConvert_runConvert(el, list_header, prev2);
433
- this.autoABConvert_last(el, header, selectorName, prev2);
381
+ prev_result = this.autoABConvert_runConvert(el, list_header, prev2, ctx);
382
+ this.autoABConvert_last(el, header, selectorName, prev2, ctx);
434
383
  }
435
384
  }
436
385
  /**
@@ -442,7 +391,7 @@ class ABConvertManager {
442
391
  * @param prev_type2 上次转换后的结果的类型 (接口声明而来, IOEnum类型)
443
392
  * @returns 递归转换后的结果
444
393
  */
445
- static autoABConvert_runConvert(el, list_header, prev2) {
394
+ static autoABConvert_runConvert(el, list_header, prev2, ctx) {
446
395
  for (let item_header of list_header) {
447
396
  for (let abReplaceProcessor of ABConvertManager.getInstance().list_abConvert) {
448
397
  if (typeof abReplaceProcessor.match == "string") {
@@ -464,7 +413,7 @@ class ABConvertManager {
464
413
  alias = alias.replace(RegExp(`%${i}`), matchs[i]);
465
414
  }
466
415
  })();
467
- prev2.prev_result = this.autoABConvert_runConvert(el, alias.split("|"), prev2);
416
+ prev2.prev_result = this.autoABConvert_runConvert(el, alias.split("|"), prev2, ctx);
468
417
  } else if (abReplaceProcessor.process) {
469
418
  if (abReplaceProcessor.process_param != prev2.prev_type2) {
470
419
  if (abReplaceProcessor.process_param == ABConvert_IOEnum.el && prev2.prev_type2 == ABConvert_IOEnum.text) {
@@ -488,7 +437,7 @@ class ABConvertManager {
488
437
  break;
489
438
  }
490
439
  }
491
- prev2.prev_result = abReplaceProcessor.process(el, item_header, prev2.prev_result);
440
+ prev2.prev_result = abReplaceProcessor.process(el, item_header, prev2.prev_result, ctx);
492
441
  prev2.prev_type = typeof prev2.prev_result;
493
442
  prev2.prev_type2 = abReplaceProcessor.process_return;
494
443
  prev2.prev_processor = abReplaceProcessor.process;
@@ -502,7 +451,7 @@ class ABConvertManager {
502
451
  /**
503
452
  * 子函数,后处理/尾处理,主要进行末尾追加指令
504
453
  */
505
- static autoABConvert_last(el, header, selectorName, prev2) {
454
+ static autoABConvert_last(el, header, selectorName, prev2, ctx) {
506
455
  if (prev2.prev_type == "string" && prev2.prev_type2 == ABConvert_IOEnum.text) {
507
456
  const subEl = document.createElement("div");
508
457
  el.appendChild(subEl);
@@ -832,10 +781,12 @@ class ListProcess {
832
781
  return total_comp;
833
782
  }
834
783
  let list_itemInfo = [];
784
+ let m_line_cache = null;
835
785
  const list_text = text2.split("\n");
836
786
  for (let line of list_text) {
837
787
  const m_line = line.match(ABReg.reg_list_noprefix);
838
788
  if (m_line) {
789
+ m_line_cache = m_line;
839
790
  let list_inline = m_line[4].split(ABReg.inline_split);
840
791
  let level_inline = m_line[1].length;
841
792
  let inline_comp = update_inline_comp(level_inline, list_inline.length - 1);
@@ -848,8 +799,13 @@ class ListProcess {
848
799
  } else {
849
800
  let itemInfo = list_itemInfo.pop();
850
801
  if (itemInfo) {
802
+ if (m_line_cache && /^\s*$/.test(line.slice(0, m_line_cache[1].length + 2))) {
803
+ line = line.slice(m_line_cache[1].length + 2);
804
+ } else {
805
+ line = line.trim();
806
+ }
851
807
  list_itemInfo.push({
852
- content: itemInfo.content + "\n" + line.trim(),
808
+ content: itemInfo.content + "\n" + line,
853
809
  level: itemInfo.level
854
810
  });
855
811
  }
@@ -1123,6 +1079,19 @@ class ListProcess {
1123
1079
  }
1124
1080
  return list_itemInfo2;
1125
1081
  }
1082
+ // 修复任务列表转列表结构后,任务项丢失
1083
+ static data2taskData(list_itemInfo) {
1084
+ for (let item of list_itemInfo) {
1085
+ item.content = item.content.split("\n").map((line) => {
1086
+ const match = line.match(/\[.\] /);
1087
+ if (match) {
1088
+ return "- " + line;
1089
+ }
1090
+ return line;
1091
+ }).join("\n");
1092
+ }
1093
+ return list_itemInfo;
1094
+ }
1126
1095
  /** 二层树转多层一叉树
1127
1096
  * example:
1128
1097
  * - 1
@@ -1162,7 +1131,7 @@ class ListProcess {
1162
1131
  static data2list(list_itemInfo) {
1163
1132
  let list_newcontent = [];
1164
1133
  for (let item of list_itemInfo) {
1165
- const str_indent = " ".repeat(item.level);
1134
+ const str_indent = " ".repeat(item.level);
1166
1135
  let list_content = item.content.split("\n");
1167
1136
  for (let i = 0; i < list_content.length; i++) {
1168
1137
  if (i == 0) list_newcontent.push(str_indent + "- " + list_content[i]);
@@ -1267,11 +1236,21 @@ ABConvert.factory({
1267
1236
  name: "listdata严格化",
1268
1237
  process_param: ABConvert_IOEnum.list_stream,
1269
1238
  process_return: ABConvert_IOEnum.list_stream,
1270
- detail: "将列表数据转化为更规范的列表数据。统一缩进符(2空格 4空格 tab混用)、禁止跳等级(h1直接就到h3)",
1239
+ detail: "将列表数据转化为更规范的列表数据。统一缩进符(2空格 4空格 tab混用)为level 1、禁止跳等级(h1直接就到h3)",
1271
1240
  process: (el, header, content) => {
1272
1241
  return ListProcess.data2strict(content);
1273
1242
  }
1274
1243
  });
1244
+ ABConvert.factory({
1245
+ id: "listdata2task",
1246
+ name: "listdata支持任务列表",
1247
+ process_param: ABConvert_IOEnum.list_stream,
1248
+ process_return: ABConvert_IOEnum.list_stream,
1249
+ detail: "当列表中存在任务列表项时,令此列表项支持任务项",
1250
+ process: (el, header, content) => {
1251
+ return ListProcess.data2taskData(content);
1252
+ }
1253
+ });
1275
1254
  ABConvert.factory({
1276
1255
  id: "list2listnode",
1277
1256
  name: "列表到listnode (beta)",
@@ -1519,72 +1498,72 @@ class C2ListProcess {
1519
1498
  * 两列列表数据转标签栏
1520
1499
  */
1521
1500
  static c2data2tab(list_itemInfo, div, modeT) {
1522
- {
1523
- const tab = document.createElement("div");
1524
- div.appendChild(tab);
1525
- tab.classList.add("ab-tab-root");
1526
- if (modeT) tab.setAttribute("modeT", "true");
1527
- const nav = document.createElement("div");
1528
- tab.appendChild(nav);
1529
- nav.classList.add("ab-tab-nav");
1530
- const content = document.createElement("div");
1531
- tab.appendChild(content);
1532
- content.classList.add("ab-tab-content");
1533
- let current_dom = null;
1534
- for (let i = 0; i < list_itemInfo.length; i++) {
1535
- const itemInfo = list_itemInfo[i];
1536
- if (!current_dom) {
1537
- if (itemInfo.level == 0) {
1538
- const nav_item = document.createElement("button");
1539
- nav.appendChild(nav_item);
1540
- nav_item.classList.add("ab-tab-nav-item");
1541
- nav_item.textContent = itemInfo.content.slice(0, 20);
1542
- nav_item.setAttribute("is_activate", i == 0 ? "true" : "false");
1543
- current_dom = document.createElement("div");
1544
- content.appendChild(current_dom);
1545
- current_dom.classList.add("ab-tab-content-item");
1546
- current_dom.setAttribute("style", i == 0 ? "display:block" : "display:none");
1547
- current_dom.setAttribute("is_activate", i == 0 ? "true" : "false");
1501
+ const tab = document.createElement("div");
1502
+ div.appendChild(tab);
1503
+ tab.classList.add("ab-tab-root");
1504
+ if (modeT) tab.setAttribute("modeT", "true");
1505
+ const nav = document.createElement("div");
1506
+ tab.appendChild(nav);
1507
+ nav.classList.add("ab-tab-nav");
1508
+ const content = document.createElement("div");
1509
+ tab.appendChild(content);
1510
+ content.classList.add("ab-tab-content");
1511
+ let current_dom = null;
1512
+ for (let i = 0; i < list_itemInfo.length; i++) {
1513
+ const item = list_itemInfo[i];
1514
+ if (item.level == 0) {
1515
+ const nav_item = document.createElement("button");
1516
+ nav.appendChild(nav_item);
1517
+ nav_item.classList.add("ab-tab-nav-item");
1518
+ nav_item.setAttribute("is_activate", i == 0 ? "true" : "false");
1519
+ nav_item.setAttribute("data_index", i.toString());
1520
+ nav_item.textContent = item.content.slice(0, 20);
1521
+ current_dom = document.createElement("div");
1522
+ content.appendChild(current_dom);
1523
+ current_dom.classList.add("ab-tab-content-item");
1524
+ current_dom.setAttribute("style", i == 0 ? "display:block" : "display:none");
1525
+ current_dom.setAttribute("is_activate", i == 0 ? "true" : "false");
1526
+ } else if (current_dom) {
1527
+ current_dom.setAttribute("data_index", i.toString());
1528
+ ABConvertManager.getInstance().m_renderMarkdownFn(item.content, current_dom);
1529
+ current_dom = null;
1530
+ } else {
1531
+ continue;
1532
+ }
1533
+ }
1534
+ const lis = tab.querySelectorAll(":scope>.ab-tab-nav>.ab-tab-nav-item");
1535
+ const contents2 = tab.querySelectorAll(":scope>.ab-tab-content>.ab-tab-content-item");
1536
+ if (lis.length != contents2.length) console.warn("ab-tab-nav-item和ab-tab-content-item的数量不一致");
1537
+ for (let i = 0; i < lis.length; i++) {
1538
+ if (ABCSetting.env.startsWith("obsidian")) {
1539
+ lis[i].onclick = () => {
1540
+ for (let j = 0; j < contents2.length; j++) {
1541
+ lis[j].setAttribute("is_activate", "false");
1542
+ contents2[j].setAttribute("is_activate", "false");
1543
+ contents2[j].setAttribute("style", "display:none");
1548
1544
  }
1549
- } else {
1550
- ABConvertManager.getInstance().m_renderMarkdownFn(itemInfo.content, current_dom);
1551
- current_dom = null;
1552
- }
1553
- }
1554
- const lis = tab.querySelectorAll(":scope>.ab-tab-nav>.ab-tab-nav-item");
1555
- const contents2 = tab.querySelectorAll(":scope>.ab-tab-content>.ab-tab-content-item");
1556
- if (lis.length != contents2.length) console.warn("ab-tab-nav-item和ab-tab-content-item的数量不一致");
1557
- for (let i = 0; i < lis.length; i++) {
1558
- if (ABCSetting.env == "obsidian" || ABCSetting.env == "obsidian-min") {
1559
- lis[i].onclick = () => {
1560
- for (let j = 0; j < contents2.length; j++) {
1561
- lis[j].setAttribute("is_activate", "false");
1562
- contents2[j].setAttribute("is_activate", "false");
1563
- contents2[j].setAttribute("style", "display:none");
1564
- }
1565
- lis[i].setAttribute("is_activate", "true");
1566
- contents2[i].setAttribute("is_activate", "true");
1567
- contents2[i].setAttribute("style", "display:block");
1568
- };
1569
- } else {
1570
- lis[i].setAttribute("onclick", `
1571
- const i = ${i}
1572
- const tab_current = this
1573
- const tab_nav = this.parentNode
1574
- const tab_root = tab_nav.parentNode
1575
- const tab_content = tab_root.querySelector(":scope>.ab-tab-content")
1576
- const tab_nav_items = tab_nav.querySelectorAll(":scope>.ab-tab-nav-item")
1577
- const tab_content_items = tab_content.querySelectorAll(":scope>.ab-tab-content-item")
1578
- for (let j=0; j<tab_content_items.length; j++){
1579
- tab_nav_items[j].setAttribute("is_activate", "false")
1580
- tab_content_items[j].setAttribute("is_activate", "false")
1581
- tab_content_items[j].setAttribute("style", "display:none")
1582
- }
1583
- tab_current.setAttribute("is_activate", "true")
1584
- tab_content_items[i].setAttribute("is_activate", "true")
1585
- tab_content_items[i].setAttribute("style", "display:block")
1586
- `);
1587
- }
1545
+ lis[i].setAttribute("is_activate", "true");
1546
+ contents2[i].setAttribute("is_activate", "true");
1547
+ contents2[i].setAttribute("style", "display:block");
1548
+ };
1549
+ } else {
1550
+ lis[i].setAttribute("onclick", `
1551
+ const i = ${i}
1552
+ const tab_current = this
1553
+ const tab_nav = this.parentNode
1554
+ const tab_root = tab_nav.parentNode
1555
+ const tab_content = tab_root.querySelector(":scope>.ab-tab-content")
1556
+ const tab_nav_items = tab_nav.querySelectorAll(":scope>.ab-tab-nav-item")
1557
+ const tab_content_items = tab_content.querySelectorAll(":scope>.ab-tab-content-item")
1558
+ for (let j=0; j<tab_content_items.length; j++){
1559
+ tab_nav_items[j].setAttribute("is_activate", "false")
1560
+ tab_content_items[j].setAttribute("is_activate", "false")
1561
+ tab_content_items[j].setAttribute("style", "display:none")
1562
+ }
1563
+ tab_current.setAttribute("is_activate", "true")
1564
+ tab_content_items[i].setAttribute("is_activate", "true")
1565
+ tab_content_items[i].setAttribute("style", "display:block")
1566
+ `);
1588
1567
  }
1589
1568
  }
1590
1569
  return div;
@@ -1604,12 +1583,13 @@ class C2ListProcess {
1604
1583
  el_item.appendChild(el_title);
1605
1584
  el_title.classList.add("ab-items-title");
1606
1585
  ABConvertManager.getInstance().m_renderMarkdownFn(item.content, el_title);
1607
- } else {
1608
- if (!el_item) continue;
1586
+ } else if (el_item) {
1609
1587
  const el_content = document.createElement("div");
1610
1588
  el_item.appendChild(el_content);
1611
1589
  el_content.classList.add("ab-items-content");
1612
1590
  ABConvertManager.getInstance().m_renderMarkdownFn(item.content, el_content);
1591
+ } else {
1592
+ continue;
1613
1593
  }
1614
1594
  }
1615
1595
  return el;
@@ -2039,7 +2019,7 @@ class DirProcess {
2039
2019
  for (let i = 0; i < l_tr.length; i++) {
2040
2020
  const tr = l_tr[i];
2041
2021
  const targetEl = tr.querySelector(":scope>td:first-child") ?? tr;
2042
- if (ABCSetting.env == "obsidian" || ABCSetting.env == "obsidian-min") {
2022
+ if (ABCSetting.env.startsWith("obsidian")) {
2043
2023
  targetEl.onclick = () => {
2044
2024
  const tr_level = Number(tr.getAttribute("tr_level"));
2045
2025
  if (isNaN(tr_level)) return;
@@ -2070,7 +2050,8 @@ class DirProcess {
2070
2050
  const tr2 = l_tr[j]
2071
2051
  const tr_level2 = Number(tr2.getAttribute("tr_level"))
2072
2052
  if (isNaN(tr_level2)) break
2073
- if (tr_level2<=tr_level) break
2053
+ if (tr_level2 <= tr_level) break // 影响所有后代级
2054
+ // if (tr_level2 != tr_level+1) break // 影响下一级的 (话说这里可能有列表规范性问题?)
2074
2055
  (tr_isfold == "true") ? tr2.style.display = "" : tr2.style.display = "none"
2075
2056
  flag_do_fold = true
2076
2057
  }
@@ -2087,35 +2068,23 @@ class DirProcess {
2087
2068
  const svgStr_unfold = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-unfold-vertical-icon lucide-unfold-vertical"><path d="M12 22v-6"/><path d="M12 8V2"/><path d="M4 12H2"/><path d="M10 12H8"/><path d="M16 12h-2"/><path d="M22 12h-2"/><path d="m15 19-3 3-3-3"/><path d="m15 5-3-3-3 3"/></svg>`;
2088
2069
  btn.setAttribute("is_fold", "false");
2089
2070
  btn.innerHTML = svgStr_fold;
2090
- if (ABCSetting.env == "obsidian" || ABCSetting.env == "obsidian-min") {
2071
+ if (ABCSetting.env.startsWith("obsidian")) {
2091
2072
  btn.onclick = () => {
2092
- const l_tr = table.querySelectorAll("tr");
2093
- for (let i = 0; i < l_tr.length; i++) {
2094
- const tr = l_tr[i];
2095
- (() => {
2096
- const tr_level = Number(tr.getAttribute("tr_level"));
2097
- if (isNaN(tr_level)) return;
2098
- const tr_isfold = btn.getAttribute("is_fold");
2099
- if (!tr_isfold) return;
2100
- let flag_do_fold = false;
2101
- for (let j = i + 1; j < l_tr.length; j++) {
2102
- const tr2 = l_tr[j];
2103
- const tr_level2 = Number(tr2.getAttribute("tr_level"));
2104
- if (isNaN(tr_level2)) break;
2105
- if (tr_level2 <= tr_level) break;
2106
- tr_isfold == "true" ? tr2.style.display = "" : tr2.style.display = "none";
2107
- flag_do_fold = true;
2108
- }
2109
- if (flag_do_fold) tr.setAttribute("is_fold", tr_isfold == "true" ? "false" : "true");
2110
- })();
2111
- }
2112
2073
  const is_all_fold = btn.getAttribute("is_fold");
2113
2074
  if (is_all_fold == "true") {
2114
2075
  btn.setAttribute("is_fold", "false");
2115
2076
  btn.innerHTML = svgStr_fold;
2077
+ const btn_subs = table.querySelectorAll("tr[is_fold='true']>td:first-child");
2078
+ btn_subs.forEach((btn_sub) => {
2079
+ btn_sub.click();
2080
+ });
2116
2081
  } else {
2117
2082
  btn.setAttribute("is_fold", "true");
2118
2083
  btn.innerHTML = svgStr_unfold;
2084
+ const btn_subs = table.querySelectorAll("tr[is_fold='false']>td:first-child");
2085
+ btn_subs.forEach((btn_sub) => {
2086
+ btn_sub.click();
2087
+ });
2119
2088
  }
2120
2089
  };
2121
2090
  } else {
@@ -2127,34 +2096,17 @@ class DirProcess {
2127
2096
  const table = btn.parentNode?.querySelector("table");
2128
2097
  if (!table) return;
2129
2098
 
2130
- const l_tr = table.querySelectorAll("tr");
2131
- for (let i=0; i<l_tr.length; i++) {
2132
- const tr = l_tr[i]
2133
- ;(()=>{
2134
- const tr_level = Number(tr.getAttribute("tr_level"))
2135
- if (isNaN(tr_level)) return
2136
- const tr_isfold = btn.getAttribute("is_fold"); // [!code] tr->btn
2137
- if (!tr_isfold) return
2138
- let flag_do_fold = false // 防止折叠最小层
2139
- for (let j=i+1; j<l_tr.length; j++){
2140
- const tr2 = l_tr[j]
2141
- const tr_level2 = Number(tr2.getAttribute("tr_level"))
2142
- if (isNaN(tr_level2)) break
2143
- if (tr_level2<=tr_level) break
2144
- (tr_isfold == "true") ? tr2.style.display = "" : tr2.style.display = "none"
2145
- flag_do_fold = true
2146
- }
2147
- if (flag_do_fold) tr.setAttribute("is_fold", tr_isfold=="true"?"false":"true")
2148
- })()
2149
- }
2150
2099
  const is_all_fold = btn.getAttribute("is_fold")
2151
2100
  if (is_all_fold=="true") {
2152
2101
  btn.setAttribute("is_fold", "false"); btn.innerHTML = svgStr_fold;
2102
+ const btn_subs = table.querySelectorAll("tr[is_fold='true']>td:first-child");
2103
+ btn_subs.forEach((btn_sub) => { btn_sub.click() }) // 注意setAttr版本无断言
2153
2104
  }
2154
2105
  else {
2155
2106
  btn.setAttribute("is_fold", "true"); btn.innerHTML = svgStr_unfold;
2156
- }
2157
- `
2107
+ const btn_subs = table.querySelectorAll("tr[is_fold='false']>td:first-child");
2108
+ btn_subs.forEach((btn_sub) => { btn_sub.click() }) // 注意setAttr版本无断言
2109
+ }`
2158
2110
  );
2159
2111
  }
2160
2112
  }
@@ -2314,7 +2266,7 @@ ABConvert.factory({
2314
2266
  const isListTable = sub_el.classList.contains("ab-list-table-parent");
2315
2267
  const listTable_btn = sub_el.querySelector(".ab-table-fold");
2316
2268
  if (isListTable && listTable_btn) {
2317
- if (ABCSetting.env == "obsidian" || ABCSetting.env == "obsidian-min") {
2269
+ if (ABCSetting.env.startsWith("obsidian")) {
2318
2270
  fn_fold();
2319
2271
  sub_button.textContent = "折叠/展开";
2320
2272
  const fn_fold2 = () => {
@@ -2573,7 +2525,7 @@ ABConvert.factory({
2573
2525
  id: "transposition",
2574
2526
  name: "表格转置",
2575
2527
  match: "transposition",
2576
- detail: "将表格进行转置,就像矩阵转置那样。该版本不支持有跨行跨列单元格",
2528
+ detail: "将表格进行转置,就像矩阵转置那样。该版本不支持有跨行跨列单元格。若复杂表格,请换用trs版本",
2577
2529
  process_param: ABConvert_IOEnum.el,
2578
2530
  process_return: ABConvert_IOEnum.el,
2579
2531
  process: (el, header, content) => {
@@ -2612,72 +2564,21 @@ ABConvert.factory({
2612
2564
  process: (el, header, content) => {
2613
2565
  const origi_table = content.querySelector("table");
2614
2566
  if (!origi_table) return content;
2615
- const origi_rows = origi_table.rows;
2616
- const origi_rowCount = origi_rows.length;
2617
- let origi_colCount = 0;
2618
- for (let relRow = 0; relRow < origi_rowCount; relRow++) {
2619
- let colCount = 0;
2620
- for (const cell of origi_rows[relRow].cells) {
2621
- colCount += cell.colSpan || 1;
2622
- }
2623
- if (colCount > origi_colCount) {
2624
- origi_colCount = colCount;
2625
- }
2626
- }
2627
- const map_table = new Array(origi_rowCount).fill(null).map(() => new Array(origi_colCount).fill(null));
2628
- for (let relRow = 0; relRow < origi_rowCount; relRow++) {
2629
- for (let relCol = 0; relCol < origi_rows[relRow].cells.length; relCol++) {
2630
- const cell = origi_rows[relRow].cells[relCol];
2631
- const rowIndex = relRow;
2632
- let colIndex = relCol;
2633
- while (true) {
2634
- if (colIndex >= map_table[rowIndex].length) {
2635
- console.error("表格解析错误: colIndex超出范围", map_table, rowIndex, colIndex, relRow, relCol);
2636
- return content;
2637
- }
2638
- if (!map_table[rowIndex][colIndex]) {
2639
- break;
2640
- } else colIndex++;
2641
- }
2642
- if (cell.rowSpan > 1) {
2643
- for (let i = 1; i < cell.rowSpan; i++) {
2644
- if (rowIndex + i >= map_table.length) {
2645
- break;
2646
- }
2647
- map_table[rowIndex + i][colIndex] = "^";
2648
- }
2649
- }
2650
- if (cell.colSpan > 1) {
2651
- for (let i = 1; i < cell.rowSpan; i++) {
2652
- if (colIndex + i >= map_table[rowIndex].length) {
2653
- break;
2654
- }
2655
- map_table[rowIndex][colIndex + i] = "<";
2656
- }
2657
- }
2658
- map_table[rowIndex][colIndex] = {
2659
- html: cell,
2660
- rowSpan: cell.rowSpan,
2661
- colSpan: cell.colSpan,
2662
- rowIndex,
2663
- colIndex
2664
- };
2665
- }
2666
- }
2667
- const map_table2 = new Array(origi_colCount).fill(null).map(() => new Array(origi_rowCount).fill(null));
2567
+ let { tableMap, origi_rowCount, origi_colCount } = table2tableMap(origi_table);
2568
+ const tableMap2 = new Array(origi_colCount).fill(null).map(() => new Array(origi_rowCount).fill(null));
2668
2569
  for (let i = 0; i < origi_rowCount; i++) {
2669
2570
  for (let j = 0; j < origi_colCount; j++) {
2670
- const origi_cell = map_table[i][j];
2571
+ const origi_cell = tableMap[i][j];
2671
2572
  if (!origi_cell) continue;
2672
2573
  else if (origi_cell == "<") {
2673
- map_table2[j][i] = "^";
2574
+ tableMap2[j][i] = "^";
2674
2575
  } else if (origi_cell == "^") {
2675
- map_table2[j][i] = "<";
2576
+ tableMap2[j][i] = "<";
2676
2577
  } else {
2677
2578
  let content2 = origi_cell.html;
2678
2579
  if (content2.innerHTML == "<" || content2.innerHTML == "&lt;") content2.innerHTML = "^";
2679
2580
  else if (content2.innerHTML == "^") content2.innerHTML = "<";
2680
- map_table2[j][i] = {
2581
+ tableMap2[j][i] = {
2681
2582
  html: origi_cell.html,
2682
2583
  rowSpan: origi_cell.colSpan || 1,
2683
2584
  colSpan: origi_cell.rowSpan || 1,
@@ -2687,27 +2588,14 @@ ABConvert.factory({
2687
2588
  }
2688
2589
  }
2689
2590
  }
2690
- const trans_table = document.createElement("table");
2691
- origi_table.classList.add("ab-transposition", "ab-table");
2591
+ const tmp = origi_colCount;
2592
+ origi_colCount = origi_rowCount;
2593
+ origi_rowCount = tmp;
2594
+ const trans_table = tableMap2table(tableMap2, origi_rowCount, origi_colCount);
2692
2595
  origi_table.classList.forEach((className) => {
2693
2596
  trans_table.classList.add(className);
2694
2597
  });
2695
- const trans_body = document.createElement("tbody");
2696
- trans_table.appendChild(trans_body);
2697
- for (let i = 0; i < origi_colCount; i++) {
2698
- const newRow = trans_body.insertRow();
2699
- for (let j = 0; j < origi_rowCount; j++) {
2700
- const cell = map_table2[i][j];
2701
- if (!cell) continue;
2702
- if (cell == "<" || cell == "^") continue;
2703
- const newCell = newRow.insertCell();
2704
- newCell.innerHTML = cell.html.innerHTML;
2705
- newCell.rowSpan = cell.rowSpan;
2706
- newCell.colSpan = cell.colSpan;
2707
- newCell.setAttribute("rowIndex", String(cell.rowIndex));
2708
- newCell.setAttribute("colIndex", String(cell.colIndex));
2709
- }
2710
- }
2598
+ trans_table.classList.add("ab-transposition", "ab-table");
2711
2599
  origi_table.innerHTML = trans_table.innerHTML;
2712
2600
  return content;
2713
2601
  }
@@ -2722,53 +2610,107 @@ ABConvert.factory({
2722
2610
  process: (el, header, content) => {
2723
2611
  const origi_table = content.querySelector("table");
2724
2612
  if (!origi_table) return content;
2725
- const origi_rows = origi_table.rows;
2726
- const origi_rowCount = origi_rows.length;
2727
- let origi_colCount = 0;
2613
+ let { tableMap, origi_rowCount, origi_colCount } = table2tableMap(origi_table, true);
2614
+ const map_table2 = tableMap;
2615
+ const trans_table = tableMap2table(map_table2, origi_rowCount, origi_colCount);
2616
+ origi_table.classList.forEach((className) => {
2617
+ trans_table.classList.add(className);
2618
+ });
2619
+ trans_table.classList.add("ab-extable", "ab-table");
2620
+ origi_table.innerHTML = trans_table.innerHTML;
2621
+ return content;
2622
+ }
2623
+ });
2624
+ ABConvert.factory({
2625
+ id: "strictTable",
2626
+ name: "正规化表格",
2627
+ match: "strictTable",
2628
+ detail: "补全表格的尾丢失项,list2table|trs时,可以有效避免bug",
2629
+ process_param: ABConvert_IOEnum.el,
2630
+ process_return: ABConvert_IOEnum.el,
2631
+ process: (el, header, content) => {
2632
+ const origi_table = content.querySelector("table");
2633
+ if (!origi_table) return content;
2634
+ let { tableMap, origi_rowCount, origi_colCount } = table2tableMap(origi_table);
2635
+ for (let i = 0; i < origi_rowCount; i++) {
2636
+ for (let j = 0; j < origi_colCount; j++) {
2637
+ const origi_cell = tableMap[i][j];
2638
+ if (!origi_cell) {
2639
+ tableMap[i][j] = {
2640
+ html: document.createElement("td"),
2641
+ // 空单元格
2642
+ rowSpan: 1,
2643
+ colSpan: 1,
2644
+ rowIndex: i,
2645
+ colIndex: j
2646
+ };
2647
+ }
2648
+ }
2649
+ }
2650
+ const trans_table = tableMap2table(tableMap, origi_rowCount, origi_colCount);
2651
+ origi_table.classList.forEach((className) => {
2652
+ trans_table.classList.add(className);
2653
+ });
2654
+ trans_table.classList.add("ab-extable", "ab-table");
2655
+ origi_table.innerHTML = trans_table.innerHTML;
2656
+ return content;
2657
+ }
2658
+ });
2659
+ function table2tableMap(origi_table, useMergeFlag = false) {
2660
+ const origi_rows = origi_table.rows;
2661
+ let origi_rowCount = origi_rows.length;
2662
+ let origi_colCount = 0;
2663
+ {
2664
+ let map_colCount = [];
2728
2665
  for (let relRow = 0; relRow < origi_rowCount; relRow++) {
2729
- let colCount = 0;
2730
2666
  for (const cell of origi_rows[relRow].cells) {
2731
- colCount += cell.colSpan || 1;
2732
- }
2733
- if (colCount > origi_colCount) {
2734
- origi_colCount = colCount;
2667
+ const colSpan = cell.colSpan || 1;
2668
+ const rowSpan = cell.rowSpan || 1;
2669
+ for (let relRowSpan = relRow; relRowSpan < relRow + rowSpan; relRowSpan++) {
2670
+ if (!map_colCount[relRowSpan]) map_colCount[relRowSpan] = colSpan;
2671
+ else map_colCount[relRowSpan] += colSpan;
2672
+ }
2735
2673
  }
2736
2674
  }
2737
- const map_table = new Array(origi_rowCount).fill(null).map(() => new Array(origi_colCount).fill(null));
2738
- for (let relRow = 0; relRow < origi_rowCount; relRow++) {
2739
- for (let relCol = 0; relCol < origi_rows[relRow].cells.length; relCol++) {
2740
- const cell = origi_rows[relRow].cells[relCol];
2741
- const rowIndex = relRow;
2742
- let colIndex = relCol;
2743
- while (true) {
2744
- if (colIndex >= map_table[rowIndex].length) {
2745
- console.error("表格解析错误: colIndex超出范围", map_table, rowIndex, colIndex, relRow, relCol);
2746
- return content;
2747
- }
2748
- if (!map_table[rowIndex][colIndex]) {
2749
- break;
2750
- } else colIndex++;
2675
+ origi_rowCount = map_colCount.length;
2676
+ origi_colCount = Math.max(...map_colCount);
2677
+ }
2678
+ const tableMap = new Array(origi_rowCount).fill(null).map(() => new Array(origi_colCount).fill(null));
2679
+ for (let relRow = 0; relRow < origi_rowCount; relRow++) {
2680
+ for (let relCol = 0; relCol < origi_rows[relRow].cells.length; relCol++) {
2681
+ const cell = origi_rows[relRow].cells[relCol];
2682
+ const rowIndex = relRow;
2683
+ let colIndex = relCol;
2684
+ while (true) {
2685
+ if (colIndex >= tableMap[rowIndex].length) {
2686
+ console.error(`表格解析错误: colIndex超出范围: [${rowIndex}][${colIndex}] overflow tableMap[${origi_rowCount - 1}][${origi_colCount - 1}]`, tableMap);
2687
+ throw new Error("表格解析错误: colIndex超出范围");
2751
2688
  }
2752
- if (cell.rowSpan > 1) {
2753
- for (let i = 1; i < cell.rowSpan; i++) {
2754
- if (rowIndex + i >= map_table.length) {
2755
- break;
2756
- }
2757
- map_table[rowIndex + i][colIndex] = "^";
2689
+ if (!tableMap[rowIndex][colIndex]) {
2690
+ break;
2691
+ } else colIndex++;
2692
+ }
2693
+ if (cell.rowSpan > 1) {
2694
+ for (let i = 1; i < cell.rowSpan; i++) {
2695
+ if (rowIndex + i >= tableMap.length) {
2696
+ break;
2758
2697
  }
2698
+ tableMap[rowIndex + i][colIndex] = "^";
2759
2699
  }
2760
- if (cell.colSpan > 1) {
2761
- for (let i = 1; i < cell.rowSpan; i++) {
2762
- if (colIndex + i >= map_table[rowIndex].length) {
2763
- break;
2764
- }
2765
- map_table[rowIndex][colIndex + i] = "<";
2700
+ }
2701
+ if (cell.colSpan > 1) {
2702
+ for (let i = 1; i < cell.rowSpan; i++) {
2703
+ if (colIndex + i >= tableMap[rowIndex].length) {
2704
+ break;
2766
2705
  }
2706
+ tableMap[rowIndex][colIndex + i] = "<";
2767
2707
  }
2708
+ }
2709
+ if (useMergeFlag) {
2768
2710
  if (cell.rowSpan == 1 && cell.colSpan == 1 && cell.textContent == "^") {
2769
- map_table[rowIndex][colIndex] = "^";
2711
+ tableMap[rowIndex][colIndex] = "^";
2770
2712
  for (let i = rowIndex - 1; i >= 0; i--) {
2771
- const item = map_table[i][colIndex];
2713
+ const item = tableMap[i][colIndex];
2772
2714
  if (!item) break;
2773
2715
  if (item == "<") break;
2774
2716
  if (item == "^") continue;
@@ -2779,9 +2721,9 @@ ABConvert.factory({
2779
2721
  }
2780
2722
  }
2781
2723
  } else if (cell.rowSpan == 1 && cell.colSpan == 1 && cell.textContent == "<") {
2782
- map_table[rowIndex][colIndex] = "<";
2724
+ tableMap[rowIndex][colIndex] = "<";
2783
2725
  for (let j = colIndex - 1; j >= 0; j--) {
2784
- const item = map_table[rowIndex][j];
2726
+ const item = tableMap[rowIndex][j];
2785
2727
  if (!item) break;
2786
2728
  if (item == "^") break;
2787
2729
  if (item == "<") continue;
@@ -2792,7 +2734,7 @@ ABConvert.factory({
2792
2734
  }
2793
2735
  }
2794
2736
  } else {
2795
- map_table[rowIndex][colIndex] = {
2737
+ tableMap[rowIndex][colIndex] = {
2796
2738
  html: cell,
2797
2739
  rowSpan: cell.rowSpan,
2798
2740
  colSpan: cell.colSpan,
@@ -2800,34 +2742,43 @@ ABConvert.factory({
2800
2742
  colIndex
2801
2743
  };
2802
2744
  }
2745
+ } else {
2746
+ tableMap[rowIndex][colIndex] = {
2747
+ html: cell,
2748
+ rowSpan: cell.rowSpan,
2749
+ colSpan: cell.colSpan,
2750
+ rowIndex,
2751
+ colIndex
2752
+ };
2803
2753
  }
2804
2754
  }
2805
- const map_table2 = map_table;
2806
- const trans_table = document.createElement("table");
2807
- origi_table.classList.add("ab-transposition", "ab-table");
2808
- origi_table.classList.forEach((className) => {
2809
- trans_table.classList.add(className);
2810
- });
2811
- const trans_body = document.createElement("tbody");
2812
- trans_table.appendChild(trans_body);
2813
- for (let i = 0; i < origi_rowCount; i++) {
2814
- const newRow = trans_body.insertRow();
2815
- for (let j = 0; j < origi_colCount; j++) {
2816
- const cell = map_table2[i][j];
2817
- if (!cell) continue;
2818
- if (cell == "<" || cell == "^") continue;
2819
- const newCell = newRow.insertCell();
2820
- newCell.innerHTML = cell.html.innerHTML;
2821
- newCell.rowSpan = cell.rowSpan;
2822
- newCell.colSpan = cell.colSpan;
2823
- newCell.setAttribute("rowIndex", String(cell.rowIndex));
2824
- newCell.setAttribute("colIndex", String(cell.colIndex));
2825
- }
2826
- }
2827
- origi_table.innerHTML = trans_table.innerHTML;
2828
- return content;
2829
2755
  }
2830
- });
2756
+ return {
2757
+ tableMap,
2758
+ origi_rowCount,
2759
+ origi_colCount
2760
+ };
2761
+ }
2762
+ function tableMap2table(tableMap, origi_rowCount, origi_colCount) {
2763
+ const trans_table = document.createElement("table");
2764
+ const trans_body = document.createElement("tbody");
2765
+ trans_table.appendChild(trans_body);
2766
+ for (let i = 0; i < origi_rowCount; i++) {
2767
+ const newRow = trans_body.insertRow();
2768
+ for (let j = 0; j < origi_colCount; j++) {
2769
+ const cell = tableMap[i][j];
2770
+ if (!cell) continue;
2771
+ if (cell == "<" || cell == "^") continue;
2772
+ const newCell = newRow.insertCell();
2773
+ newCell.innerHTML = cell.html.innerHTML;
2774
+ newCell.rowSpan = cell.rowSpan;
2775
+ newCell.colSpan = cell.colSpan;
2776
+ newCell.setAttribute("rowIndex", String(cell.rowIndex));
2777
+ newCell.setAttribute("colIndex", String(cell.colIndex));
2778
+ }
2779
+ }
2780
+ return trans_table;
2781
+ }
2831
2782
  ABConvert.factory({
2832
2783
  id: "faq",
2833
2784
  name: "FAQ",
@@ -2843,7 +2794,7 @@ ABConvert.factory({
2843
2794
  let mode_qa = "";
2844
2795
  let last_content = "";
2845
2796
  for (let line of list_content) {
2846
- const m_line = line.match(/^([a-zA-Z])(: |:)(.*)/);
2797
+ const m_line = line.match(/^([\S]+)(:|:)(.*)/);
2847
2798
  if (!m_line) {
2848
2799
  if (mode_qa) {
2849
2800
  last_content = last_content + "\n" + line;
@@ -7708,8 +7659,9 @@ const KEYWORD_WHILE = "while ";
7708
7659
  const KEYWORD_GROUP = "group ";
7709
7660
  const KEYWORD_PARTITION = "partition ";
7710
7661
  const KEYWORD_LANE = "lane ";
7711
- const KEYWORD_ELSE = "else";
7712
7662
  const KEYWORD_ELIF = "elif ";
7663
+ const KEYWORD_ELSEIF = "else if ";
7664
+ const KEYWORD_ELSE = "else";
7713
7665
  const KEYWORD_DEFAULT = "default";
7714
7666
  const KEYWORD_DEFAULT2 = "case _";
7715
7667
  const KEYWORD_CASE = "case ";
@@ -7754,7 +7706,7 @@ function processBlock(stats, index2, parentLevel) {
7754
7706
  let processed = false;
7755
7707
  for (const [statType, processor] of Object.entries(statementTypes)) {
7756
7708
  if (stat.isStatementOfType(statType)) {
7757
- const { result: processedResult, nextIndex: nextNext } = processor(stats, next2);
7709
+ const { result: processedResult, nextIndex: nextNext } = processor(stats, next2, statType);
7758
7710
  result += processedResult;
7759
7711
  next2 = nextNext;
7760
7712
  processed = true;
@@ -7782,9 +7734,13 @@ function processIfStatement(stats, index2) {
7782
7734
  result += indentContent(result2);
7783
7735
  nextIndex = nextIndex2;
7784
7736
  }
7785
- while (nextIndex < stats.length && stats[nextIndex].level === stat.level && stats[nextIndex].isStatementOfType(KEYWORD_ELIF, KEYWORD_ELSE)) {
7737
+ while (nextIndex < stats.length && stats[nextIndex].level === stat.level && stats[nextIndex].isStatementOfType(KEYWORD_ELIF, KEYWORD_ELSEIF, KEYWORD_ELSE)) {
7786
7738
  const branch = stats[nextIndex];
7787
- if (branch.isStatementOfType(KEYWORD_ELIF)) {
7739
+ if (branch.isStatementOfType(KEYWORD_ELSEIF)) {
7740
+ const condition2 = branch.takeTagOfStat(KEYWORD_ELSEIF);
7741
+ result += `else if(${condition2}) then (yes)
7742
+ `;
7743
+ } else if (branch.isStatementOfType(KEYWORD_ELIF)) {
7788
7744
  const condition2 = branch.takeTagOfStat(KEYWORD_ELIF);
7789
7745
  result += `else if(${condition2}) then (yes)
7790
7746
  `;
@@ -7799,10 +7755,10 @@ function processIfStatement(stats, index2) {
7799
7755
  result += "endif\n";
7800
7756
  return { result, nextIndex };
7801
7757
  }
7802
- function processSwitchStatement(stats, index2) {
7803
- let result = KEYWORD_SWITCH;
7758
+ function processSwitchStatement(stats, index2, statType) {
7759
+ let result = `switch `;
7804
7760
  const stat = stats[index2];
7805
- const condition = stat.takeTagOfStat(KEYWORD_SWITCH);
7761
+ const condition = stat.takeTagOfStat(statType);
7806
7762
  let nextIndex = index2 + 1;
7807
7763
  result += `(${condition})
7808
7764
  `;
@@ -8130,7 +8086,7 @@ async function data2mindmap(list_itemInfo, div) {
8130
8086
  return render_mermaidText(mermaidText, div);
8131
8087
  }
8132
8088
  async function render_mermaidText(mermaidText, div) {
8133
- if ((ABCSetting.env == "obsidian" || ABCSetting.env == "obsidian-min") && ABCSetting.mermaid) {
8089
+ if (ABCSetting.env.startsWith("obsidian") && ABCSetting.mermaid) {
8134
8090
  ABCSetting.mermaid.then(async (mermaid) => {
8135
8091
  const { svg } = await mermaid.render("ab-mermaid-" + getID(), mermaidText);
8136
8092
  div.innerHTML = svg;
@@ -42421,7 +42377,7 @@ ABConvert.factory({
42421
42377
  function list2markmap(markdown, div) {
42422
42378
  const { root: root2, features } = transformer.transform(markdown.trim());
42423
42379
  transformer.getUsedAssets(features);
42424
- if (ABCSetting.env == "obsidian" || ABCSetting.env == "obsidian-min") {
42380
+ if (ABCSetting.env.startsWith("obsidian")) {
42425
42381
  let height_adapt = 30 + markdown.split("\n").length * 15;
42426
42382
  if (height_adapt > 1e3) height_adapt = 1e3;
42427
42383
  const id = Math.random().toString(36).substring(2);