@anyblock/remark-any-block 3.4.11 → 3.5.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.
@@ -451,17 +451,21 @@ const ABAlias_json_mdit = [
451
451
  { regex: /\|:::_140lne\|(?:mdit2|2)?(puml)?(plantuml|mindmap|脑图|思维导图)\|/, replacement: "|mdit2list|list2pumlMindmap|" },
452
452
  { regex: /\|:::_140lne\|(?:mdit2|2)?(markmap|mdMindmap|md脑图|md思维导图)\|/, replacement: "|mdit2list|list2markmap|" },
453
453
  { regex: /\|:::_140lne\|(?:mdit2|2)?(wbs|(工作)?分解(图|结构))\|/, replacement: "|mdit2list|list2pumlWBS|" },
454
- { regex: /\|:::_140lne\|(?:mdit2|2)?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|mdit2list|list2table|" },
454
+ { regex: /\|:::_140lne\|(?:mdit2|2)?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|mdit2Listdata|listdata2strict|listdata2table|" },
455
455
  // list - lt树 (属于多层一叉树)
456
456
  { regex: /\|:::_140lne\|(?:mdit2|2)?(lt|listTable|treeTable|listGrid|treeGrid|列表格|树形表格?)\|/, replacement: "|mdit2list|list2lt|" },
457
- { regex: /\|:::_140lne\|(?:mdit2|2)?(list|列表)\|/, replacement: "|mdit2list|list2lt|addClass(ab-listtable-likelist)|" },
457
+ { regex: /\|:::_140lne\|2?(list|列表)\|/, replacement: "|mdit2list|list2lt|addClass(ab-listtable-likelist)|" },
458
458
  { regex: /\|:::_140lne\|(?:mdit2|2)?(dir|dirTree|目录树?|目录结构)\|/, replacement: "|mdit2list|list2dt|" },
459
459
  // list - 二层树
460
460
  { regex: /\|:::_140lne\|(fakeList|仿列表)\|/, replacement: "|mdit2list|list2table|addClass(ab-table-fc)|addClass(ab-table-likelist)|" },
461
461
  // 至后
462
- { regex: "|mdit2list|", replacement: "|mdit2listdata|listdata2strict|listdata2list|" }
462
+ { regex: "|mdit2list|", replacement: "|mdit2listdata|listdata2strict|listdata2list|" },
463
+ { regex: "|mdit2List|", replacement: "|mdit2Listdata|listdata2strict|listdata2list|" }
463
464
  ];
464
465
  const ABAlias_json_title = [
466
+ // 至前,特殊
467
+ { regex: "|heading2", replacement: "|title2" },
468
+ { regex: "|h2", replacement: "|title2" },
465
469
  // title - list&title
466
470
  { regex: /\|heading_140lne\|2?(timeline|时间线)\|/, replacement: "|title2timeline|" },
467
471
  { regex: /\|heading_140lne\|2?(tabs?|标签页?)\||\|title2tabs?\|/, replacement: "|title2c2listdata|c2listdata2tab|" },
@@ -474,7 +478,7 @@ const ABAlias_json_title = [
474
478
  { regex: /\|heading_140lne\|2?(puml)?(plantuml|mindmap|脑图|思维导图)\|/, replacement: "|title2list|list2pumlMindmap|" },
475
479
  { regex: /\|heading_140lne\|2?(markmap|mdMindmap|md脑图|md思维导图)\|/, replacement: "|title2list|list2markmap|" },
476
480
  { regex: /\|heading_140lne\|2?(wbs|(工作)?分解(图|结构))\|/, replacement: "|title2list|list2pumlWBS|" },
477
- { regex: /\|heading_140lne\|2?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|title2list|list2table|" },
481
+ { regex: /\|heading_140lne\|2?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|title2Listdata|listdata2strict|listdata2table|" },
478
482
  // list - lt树 (属于多层一叉树)
479
483
  { regex: /\|heading_140lne\|2?(lt|listTable|treeTable|listGrid|treeGrid|列表格|树形表格?)\|/, replacement: "|title2list|list2lt|" },
480
484
  { regex: /\|heading_140lne\|2?(list|列表)\|/, replacement: "|title2list|list2lt|addClass(ab-listtable-likelist)|" },
@@ -1208,8 +1212,12 @@ class ListProcess {
1208
1212
  * 3. 列表等级, = `(.*)-`个数+1, 取值[0]
1209
1213
  *
1210
1214
  * (比较旧版是正文+10,列表+11,后来允许标题等级为负数。这样方便很多)
1215
+ *
1216
+ * @fine_mode 精细拆分模式
1217
+ * - true: 会将正文和列表拆分成多个节点
1218
+ * - false: 会将标题+正文+列表合并成一个节点
1211
1219
  */
1212
- static title2data(text2) {
1220
+ static title2data(text2, fine_mode = true) {
1213
1221
  let list_itemInfo = [];
1214
1222
  const list_text = text2.split("\n");
1215
1223
  let mul_mode = "";
@@ -1218,14 +1226,17 @@ class ListProcess {
1218
1226
  if (codeBlockFlag == "") {
1219
1227
  const match2 = line.match(ABReg.reg_code);
1220
1228
  if (match2 && match2[3]) {
1221
- if (mul_mode === "heading" || mul_mode === "") {
1229
+ codeBlockFlag = match2[1] + match2[3];
1230
+ if (!fine_mode && list_itemInfo.length > 0) {
1231
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1232
+ } else if (mul_mode === "heading" || mul_mode === "") {
1233
+ removeTailBlank();
1222
1234
  list_itemInfo.push({
1223
1235
  content: line,
1224
1236
  level: 0
1225
1237
  });
1226
1238
  mul_mode = "para";
1227
1239
  } else {
1228
- codeBlockFlag = match2[1] + match2[3];
1229
1240
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1230
1241
  }
1231
1242
  continue;
@@ -1240,10 +1251,14 @@ class ListProcess {
1240
1251
  if (match_heading && !match_heading[1]) {
1241
1252
  removeTailBlank();
1242
1253
  list_itemInfo.push({
1243
- content: match_heading[4],
1254
+ content: fine_mode ? match_heading[4] : line,
1255
+ // 可选是否把标题标志也放进去
1244
1256
  level: match_heading[3].length - 1 - 10
1245
1257
  });
1246
1258
  mul_mode = "heading";
1259
+ } else if (!fine_mode && list_itemInfo.length > 0) {
1260
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1261
+ continue;
1247
1262
  } else if (match_list) {
1248
1263
  removeTailBlank();
1249
1264
  list_itemInfo.push({
@@ -1251,19 +1266,23 @@ class ListProcess {
1251
1266
  level: match_list[1].length + 1
1252
1267
  });
1253
1268
  mul_mode = "list";
1254
- } else if (/^\S/.test(line) && mul_mode == "list") {
1255
- list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1269
+ } else if (mul_mode == "list" && /^\s/.test(line)) {
1270
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line.trimStart();
1271
+ continue;
1256
1272
  } else {
1257
1273
  if (mul_mode == "para") {
1258
1274
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1275
+ continue;
1259
1276
  } else if (/^\s*$/.test(line)) {
1260
1277
  continue;
1261
1278
  } else {
1279
+ removeTailBlank();
1262
1280
  list_itemInfo.push({
1263
1281
  content: line,
1264
1282
  level: 0
1265
1283
  });
1266
1284
  mul_mode = "para";
1285
+ continue;
1267
1286
  }
1268
1287
  }
1269
1288
  }
@@ -1281,41 +1300,20 @@ class ListProcess {
1281
1300
  * @detail
1282
1301
  * 与 title2data 的逻辑基本相同
1283
1302
  *
1284
- * 这里要将Mdit标识 (@xxx)、正文、列表 的等级合为一块,所以存在偏移值:
1285
- *
1286
- * 1. Mdit等级, = `@<数字>`-100,
1287
- * 2. 正文等级, = 0, 取值[+1,+Infi]
1288
- * 3. 列表等级, = `(.*)-`个数+1, 取值[0]
1289
- *
1290
- * 例如:
1303
+ * 有很多写法变型和语法糖,所以逻辑比较复杂。
1304
+ * 具体设计详见 "docs/docs/dev docs/其他层级表示法.md"
1291
1305
  *
1292
- * :::
1306
+ * 支持:
1293
1307
  *
1294
- * @1 AAA
1308
+ * - 单行标题模式
1309
+ * - 多行标题模式
1310
+ * - 缺少分割标题模式
1295
1311
  *
1296
- * aaa
1297
- *
1298
- * @2 BBB
1299
- *
1300
- * @2 B22
1301
- *
1302
- * ccc
1303
- * ddd
1304
- *
1305
- * @1 A22
1306
- *
1307
- * :::
1308
- *
1309
- * 会被转化为
1310
- *
1311
- * - AAA
1312
- * - BBB
1313
- * - B22
1314
- * - ccc
1315
- * ddd
1316
- * - A22
1317
- */
1318
- static mdit2data(text2) {
1312
+ * @fine_mode 精细拆分模式
1313
+ * - true: 会将正文和列表拆分成多个节点
1314
+ * - false: 会将标题+正文+列表合并成一个节点
1315
+ */
1316
+ static mdit2data(text2, fine_mode = true) {
1319
1317
  let list_itemInfo = [];
1320
1318
  const list_text = text2.split("\n");
1321
1319
  let mul_mode = "";
@@ -1324,14 +1322,17 @@ class ListProcess {
1324
1322
  if (codeBlockFlag == "") {
1325
1323
  const match2 = line.match(ABReg.reg_code);
1326
1324
  if (match2 && match2[3]) {
1327
- if (mul_mode === "mdit" || mul_mode === "") {
1325
+ codeBlockFlag = match2[1] + match2[3];
1326
+ if (!fine_mode && list_itemInfo.length > 0) {
1327
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1328
+ } else if (mul_mode === "mdit" || mul_mode === "") {
1329
+ removeTailBlank();
1328
1330
  list_itemInfo.push({
1329
1331
  content: line,
1330
1332
  level: 0
1331
1333
  });
1332
1334
  mul_mode = "para";
1333
1335
  } else {
1334
- codeBlockFlag = match2[1] + match2[3];
1335
1336
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1336
1337
  }
1337
1338
  continue;
@@ -1341,15 +1342,18 @@ class ListProcess {
1341
1342
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1342
1343
  continue;
1343
1344
  }
1344
- const match_mdit = line.match(/^(\s*)@(\d+)\s+(.*)$/);
1345
+ const match_mdit = line.match(/^(\s*)@(\d+)(?:\s+(.*))?$/);
1345
1346
  const match_list = line.match(ABReg.reg_list_noprefix);
1346
1347
  if (match_mdit && !match_mdit[1]) {
1347
1348
  removeTailBlank();
1348
1349
  list_itemInfo.push({
1349
- content: match_mdit[3],
1350
+ content: match_mdit[3] ?? "",
1350
1351
  level: Number(match_mdit[2]) - 100
1351
1352
  });
1352
1353
  mul_mode = "mdit";
1354
+ } else if (!fine_mode && list_itemInfo.length > 0) {
1355
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1356
+ continue;
1353
1357
  } else if (match_list) {
1354
1358
  removeTailBlank();
1355
1359
  list_itemInfo.push({
@@ -1357,19 +1361,23 @@ class ListProcess {
1357
1361
  level: match_list[1].length + 1
1358
1362
  });
1359
1363
  mul_mode = "list";
1360
- } else if (/^\S/.test(line) && mul_mode == "list") {
1361
- list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1364
+ } else if (mul_mode == "list" && /^\s/.test(line)) {
1365
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line.trimStart();
1366
+ continue;
1362
1367
  } else {
1363
1368
  if (mul_mode == "para") {
1364
1369
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1370
+ continue;
1365
1371
  } else if (/^\s*$/.test(line)) {
1366
1372
  continue;
1367
1373
  } else {
1374
+ removeTailBlank();
1368
1375
  list_itemInfo.push({
1369
1376
  content: line,
1370
1377
  level: 0
1371
1378
  });
1372
1379
  mul_mode = "para";
1380
+ continue;
1373
1381
  }
1374
1382
  }
1375
1383
  }
@@ -1588,7 +1596,7 @@ const abc_list2listdata = ABConvert.factory({
1588
1596
  process_param: ABConvert_IOEnum.text,
1589
1597
  process_return: ABConvert_IOEnum.list_stream,
1590
1598
  detail: "列表到listdata",
1591
- process: (el, header, content) => {
1599
+ process: (_el, _header, content) => {
1592
1600
  return ListProcess.list2data(content);
1593
1601
  }
1594
1602
  });
@@ -1597,9 +1605,19 @@ const abc_title2listdata = ABConvert.factory({
1597
1605
  name: "标题到listdata",
1598
1606
  process_param: ABConvert_IOEnum.text,
1599
1607
  process_return: ABConvert_IOEnum.list_stream,
1600
- detail: "标题到listdata",
1601
- process: (el, header, content) => {
1602
- return ListProcess.title2data(content);
1608
+ detail: "标题到listdata。细粒度版本,列表会拆分成多个节点",
1609
+ process: (_el, _header, content) => {
1610
+ return ListProcess.title2data(content, true);
1611
+ }
1612
+ });
1613
+ ABConvert.factory({
1614
+ id: "title2Listdata",
1615
+ name: "标题到Listdata",
1616
+ process_param: ABConvert_IOEnum.text,
1617
+ process_return: ABConvert_IOEnum.list_stream,
1618
+ detail: "标题到Listdata。粗粒度版本,列表为一个节点,不会拆分",
1619
+ process: (_el, _header, content) => {
1620
+ return ListProcess.title2data(content, false);
1603
1621
  }
1604
1622
  });
1605
1623
  ABConvert.factory({
@@ -1607,9 +1625,19 @@ ABConvert.factory({
1607
1625
  name: "mdit到listdata",
1608
1626
  process_param: ABConvert_IOEnum.text,
1609
1627
  process_return: ABConvert_IOEnum.list_stream,
1610
- detail: "mdit到listdata",
1611
- process: (el, header, content) => {
1612
- return ListProcess.mdit2data(content);
1628
+ detail: "mdit到listdata。细粒度版本,列表会拆分成多个节点",
1629
+ process: (_el, _header, content) => {
1630
+ return ListProcess.mdit2data(content, true);
1631
+ }
1632
+ });
1633
+ ABConvert.factory({
1634
+ id: "mdit2Listdata",
1635
+ name: "mdit到Listdata",
1636
+ process_param: ABConvert_IOEnum.text,
1637
+ process_return: ABConvert_IOEnum.list_stream,
1638
+ detail: "mdit到Listdata。粗粒度版本,列表为一个节点,不会拆分",
1639
+ process: (_el, _header, content) => {
1640
+ return ListProcess.mdit2data(content, false);
1613
1641
  }
1614
1642
  });
1615
1643
  ABConvert.factory({
@@ -1618,7 +1646,7 @@ ABConvert.factory({
1618
1646
  process_param: ABConvert_IOEnum.list_stream,
1619
1647
  process_return: ABConvert_IOEnum.text,
1620
1648
  detail: "listdata到列表",
1621
- process: (el, header, content) => {
1649
+ process: (_el, _header, content) => {
1622
1650
  return ListProcess.data2list(content);
1623
1651
  }
1624
1652
  });
@@ -1628,17 +1656,18 @@ ABConvert.factory({
1628
1656
  process_param: ABConvert_IOEnum.list_stream,
1629
1657
  process_return: ABConvert_IOEnum.el,
1630
1658
  detail: "listdata到节点图",
1631
- process: (el, header, content) => {
1659
+ process: (el, _header, content) => {
1632
1660
  return ListProcess.data2nodes(content, el);
1633
1661
  }
1634
1662
  });
1635
1663
  ABConvert.factory({
1636
1664
  id: "listdata2strict",
1637
1665
  name: "listdata严格化",
1666
+ match: /listdata2strict|listdata2lint/,
1638
1667
  process_param: ABConvert_IOEnum.list_stream,
1639
1668
  process_return: ABConvert_IOEnum.list_stream,
1640
1669
  detail: "将列表数据转化为更规范的列表数据。统一缩进符(2空格 4空格 tab混用)为level 1、禁止跳等级(h1直接就到h3)",
1641
- process: (el, header, content) => {
1670
+ process: (_el, _header, content) => {
1642
1671
  return ListProcess.data2strict(content);
1643
1672
  }
1644
1673
  });
@@ -1648,7 +1677,7 @@ ABConvert.factory({
1648
1677
  process_param: ABConvert_IOEnum.list_stream,
1649
1678
  process_return: ABConvert_IOEnum.list_stream,
1650
1679
  detail: "当列表中存在任务列表项时,令此列表项支持任务项",
1651
- process: (el, header, content) => {
1680
+ process: (_el, _header, content) => {
1652
1681
  return ListProcess.data2taskData(content);
1653
1682
  }
1654
1683
  });
@@ -1658,7 +1687,7 @@ ABConvert.factory({
1658
1687
  process_param: ABConvert_IOEnum.text,
1659
1688
  process_return: ABConvert_IOEnum.json,
1660
1689
  detail: "列表到listnode",
1661
- process: (el, header, content) => {
1690
+ process: (_el, _header, content) => {
1662
1691
  const data2 = ListProcess.list2listnode(content);
1663
1692
  return JSON.stringify(data2, null, 2);
1664
1693
  }
@@ -1669,7 +1698,7 @@ ABConvert.factory({
1669
1698
  process_param: ABConvert_IOEnum.text,
1670
1699
  process_return: ABConvert_IOEnum.json,
1671
1700
  detail: "列表到json",
1672
- process: (el, header, content) => {
1701
+ process: (_el, _header, content) => {
1673
1702
  const data2 = ListProcess.list2json(content);
1674
1703
  return JSON.stringify(data2, null, 2);
1675
1704
  }
@@ -2182,6 +2211,19 @@ ABConvert.factory({
2182
2211
  return el = TableProcess.data2table(data2, el, matchs[2] == "T");
2183
2212
  }
2184
2213
  });
2214
+ ABConvert.factory({
2215
+ id: "listdata2table",
2216
+ name: "列表数据转表格",
2217
+ match: /listdata2(md)?table(T)?/,
2218
+ default: "listdata2table",
2219
+ process_param: ABConvert_IOEnum.list_stream,
2220
+ process_return: ABConvert_IOEnum.el,
2221
+ process: (el, header, content) => {
2222
+ const matchs = header.match(/listdata2(md)?table(T)?/);
2223
+ if (!matchs) return el;
2224
+ return el = TableProcess.data2table(content, el, matchs[2] == "T");
2225
+ }
2226
+ });
2185
2227
  ABConvert.factory({
2186
2228
  id: "list2c2t",
2187
2229
  name: "列表转二列表格",
@@ -427,17 +427,21 @@ const ABAlias_json_mdit = [
427
427
  { regex: /\|:::_140lne\|(?:mdit2|2)?(puml)?(plantuml|mindmap|脑图|思维导图)\|/, replacement: "|mdit2list|list2pumlMindmap|" },
428
428
  { regex: /\|:::_140lne\|(?:mdit2|2)?(markmap|mdMindmap|md脑图|md思维导图)\|/, replacement: "|mdit2list|list2markmap|" },
429
429
  { regex: /\|:::_140lne\|(?:mdit2|2)?(wbs|(工作)?分解(图|结构))\|/, replacement: "|mdit2list|list2pumlWBS|" },
430
- { regex: /\|:::_140lne\|(?:mdit2|2)?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|mdit2list|list2table|" },
430
+ { regex: /\|:::_140lne\|(?:mdit2|2)?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|mdit2Listdata|listdata2strict|listdata2table|" },
431
431
  // list - lt树 (属于多层一叉树)
432
432
  { regex: /\|:::_140lne\|(?:mdit2|2)?(lt|listTable|treeTable|listGrid|treeGrid|列表格|树形表格?)\|/, replacement: "|mdit2list|list2lt|" },
433
- { regex: /\|:::_140lne\|(?:mdit2|2)?(list|列表)\|/, replacement: "|mdit2list|list2lt|addClass(ab-listtable-likelist)|" },
433
+ { regex: /\|:::_140lne\|2?(list|列表)\|/, replacement: "|mdit2list|list2lt|addClass(ab-listtable-likelist)|" },
434
434
  { regex: /\|:::_140lne\|(?:mdit2|2)?(dir|dirTree|目录树?|目录结构)\|/, replacement: "|mdit2list|list2dt|" },
435
435
  // list - 二层树
436
436
  { regex: /\|:::_140lne\|(fakeList|仿列表)\|/, replacement: "|mdit2list|list2table|addClass(ab-table-fc)|addClass(ab-table-likelist)|" },
437
437
  // 至后
438
- { regex: "|mdit2list|", replacement: "|mdit2listdata|listdata2strict|listdata2list|" }
438
+ { regex: "|mdit2list|", replacement: "|mdit2listdata|listdata2strict|listdata2list|" },
439
+ { regex: "|mdit2List|", replacement: "|mdit2Listdata|listdata2strict|listdata2list|" }
439
440
  ];
440
441
  const ABAlias_json_title = [
442
+ // 至前,特殊
443
+ { regex: "|heading2", replacement: "|title2" },
444
+ { regex: "|h2", replacement: "|title2" },
441
445
  // title - list&title
442
446
  { regex: /\|heading_140lne\|2?(timeline|时间线)\|/, replacement: "|title2timeline|" },
443
447
  { regex: /\|heading_140lne\|2?(tabs?|标签页?)\||\|title2tabs?\|/, replacement: "|title2c2listdata|c2listdata2tab|" },
@@ -450,7 +454,7 @@ const ABAlias_json_title = [
450
454
  { regex: /\|heading_140lne\|2?(puml)?(plantuml|mindmap|脑图|思维导图)\|/, replacement: "|title2list|list2pumlMindmap|" },
451
455
  { regex: /\|heading_140lne\|2?(markmap|mdMindmap|md脑图|md思维导图)\|/, replacement: "|title2list|list2markmap|" },
452
456
  { regex: /\|heading_140lne\|2?(wbs|(工作)?分解(图|结构))\|/, replacement: "|title2list|list2pumlWBS|" },
453
- { regex: /\|heading_140lne\|2?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|title2list|list2table|" },
457
+ { regex: /\|heading_140lne\|2?(table|multiWayTable|multiCrossTable|表格?|多叉表格?|跨行表格?)\|/, replacement: "|title2Listdata|listdata2strict|listdata2table|" },
454
458
  // list - lt树 (属于多层一叉树)
455
459
  { regex: /\|heading_140lne\|2?(lt|listTable|treeTable|listGrid|treeGrid|列表格|树形表格?)\|/, replacement: "|title2list|list2lt|" },
456
460
  { regex: /\|heading_140lne\|2?(list|列表)\|/, replacement: "|title2list|list2lt|addClass(ab-listtable-likelist)|" },
@@ -1184,8 +1188,12 @@ class ListProcess {
1184
1188
  * 3. 列表等级, = `(.*)-`个数+1, 取值[0]
1185
1189
  *
1186
1190
  * (比较旧版是正文+10,列表+11,后来允许标题等级为负数。这样方便很多)
1191
+ *
1192
+ * @fine_mode 精细拆分模式
1193
+ * - true: 会将正文和列表拆分成多个节点
1194
+ * - false: 会将标题+正文+列表合并成一个节点
1187
1195
  */
1188
- static title2data(text2) {
1196
+ static title2data(text2, fine_mode = true) {
1189
1197
  let list_itemInfo = [];
1190
1198
  const list_text = text2.split("\n");
1191
1199
  let mul_mode = "";
@@ -1194,14 +1202,17 @@ class ListProcess {
1194
1202
  if (codeBlockFlag == "") {
1195
1203
  const match2 = line.match(ABReg.reg_code);
1196
1204
  if (match2 && match2[3]) {
1197
- if (mul_mode === "heading" || mul_mode === "") {
1205
+ codeBlockFlag = match2[1] + match2[3];
1206
+ if (!fine_mode && list_itemInfo.length > 0) {
1207
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1208
+ } else if (mul_mode === "heading" || mul_mode === "") {
1209
+ removeTailBlank();
1198
1210
  list_itemInfo.push({
1199
1211
  content: line,
1200
1212
  level: 0
1201
1213
  });
1202
1214
  mul_mode = "para";
1203
1215
  } else {
1204
- codeBlockFlag = match2[1] + match2[3];
1205
1216
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1206
1217
  }
1207
1218
  continue;
@@ -1216,10 +1227,14 @@ class ListProcess {
1216
1227
  if (match_heading && !match_heading[1]) {
1217
1228
  removeTailBlank();
1218
1229
  list_itemInfo.push({
1219
- content: match_heading[4],
1230
+ content: fine_mode ? match_heading[4] : line,
1231
+ // 可选是否把标题标志也放进去
1220
1232
  level: match_heading[3].length - 1 - 10
1221
1233
  });
1222
1234
  mul_mode = "heading";
1235
+ } else if (!fine_mode && list_itemInfo.length > 0) {
1236
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1237
+ continue;
1223
1238
  } else if (match_list) {
1224
1239
  removeTailBlank();
1225
1240
  list_itemInfo.push({
@@ -1227,19 +1242,23 @@ class ListProcess {
1227
1242
  level: match_list[1].length + 1
1228
1243
  });
1229
1244
  mul_mode = "list";
1230
- } else if (/^\S/.test(line) && mul_mode == "list") {
1231
- list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1245
+ } else if (mul_mode == "list" && /^\s/.test(line)) {
1246
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line.trimStart();
1247
+ continue;
1232
1248
  } else {
1233
1249
  if (mul_mode == "para") {
1234
1250
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1251
+ continue;
1235
1252
  } else if (/^\s*$/.test(line)) {
1236
1253
  continue;
1237
1254
  } else {
1255
+ removeTailBlank();
1238
1256
  list_itemInfo.push({
1239
1257
  content: line,
1240
1258
  level: 0
1241
1259
  });
1242
1260
  mul_mode = "para";
1261
+ continue;
1243
1262
  }
1244
1263
  }
1245
1264
  }
@@ -1257,41 +1276,20 @@ class ListProcess {
1257
1276
  * @detail
1258
1277
  * 与 title2data 的逻辑基本相同
1259
1278
  *
1260
- * 这里要将Mdit标识 (@xxx)、正文、列表 的等级合为一块,所以存在偏移值:
1261
- *
1262
- * 1. Mdit等级, = `@<数字>`-100,
1263
- * 2. 正文等级, = 0, 取值[+1,+Infi]
1264
- * 3. 列表等级, = `(.*)-`个数+1, 取值[0]
1265
- *
1266
- * 例如:
1279
+ * 有很多写法变型和语法糖,所以逻辑比较复杂。
1280
+ * 具体设计详见 "docs/docs/dev docs/其他层级表示法.md"
1267
1281
  *
1268
- * :::
1282
+ * 支持:
1269
1283
  *
1270
- * @1 AAA
1284
+ * - 单行标题模式
1285
+ * - 多行标题模式
1286
+ * - 缺少分割标题模式
1271
1287
  *
1272
- * aaa
1273
- *
1274
- * @2 BBB
1275
- *
1276
- * @2 B22
1277
- *
1278
- * ccc
1279
- * ddd
1280
- *
1281
- * @1 A22
1282
- *
1283
- * :::
1284
- *
1285
- * 会被转化为
1286
- *
1287
- * - AAA
1288
- * - BBB
1289
- * - B22
1290
- * - ccc
1291
- * ddd
1292
- * - A22
1293
- */
1294
- static mdit2data(text2) {
1288
+ * @fine_mode 精细拆分模式
1289
+ * - true: 会将正文和列表拆分成多个节点
1290
+ * - false: 会将标题+正文+列表合并成一个节点
1291
+ */
1292
+ static mdit2data(text2, fine_mode = true) {
1295
1293
  let list_itemInfo = [];
1296
1294
  const list_text = text2.split("\n");
1297
1295
  let mul_mode = "";
@@ -1300,14 +1298,17 @@ class ListProcess {
1300
1298
  if (codeBlockFlag == "") {
1301
1299
  const match2 = line.match(ABReg.reg_code);
1302
1300
  if (match2 && match2[3]) {
1303
- if (mul_mode === "mdit" || mul_mode === "") {
1301
+ codeBlockFlag = match2[1] + match2[3];
1302
+ if (!fine_mode && list_itemInfo.length > 0) {
1303
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1304
+ } else if (mul_mode === "mdit" || mul_mode === "") {
1305
+ removeTailBlank();
1304
1306
  list_itemInfo.push({
1305
1307
  content: line,
1306
1308
  level: 0
1307
1309
  });
1308
1310
  mul_mode = "para";
1309
1311
  } else {
1310
- codeBlockFlag = match2[1] + match2[3];
1311
1312
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1312
1313
  }
1313
1314
  continue;
@@ -1317,15 +1318,18 @@ class ListProcess {
1317
1318
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1318
1319
  continue;
1319
1320
  }
1320
- const match_mdit = line.match(/^(\s*)@(\d+)\s+(.*)$/);
1321
+ const match_mdit = line.match(/^(\s*)@(\d+)(?:\s+(.*))?$/);
1321
1322
  const match_list = line.match(ABReg.reg_list_noprefix);
1322
1323
  if (match_mdit && !match_mdit[1]) {
1323
1324
  removeTailBlank();
1324
1325
  list_itemInfo.push({
1325
- content: match_mdit[3],
1326
+ content: match_mdit[3] ?? "",
1326
1327
  level: Number(match_mdit[2]) - 100
1327
1328
  });
1328
1329
  mul_mode = "mdit";
1330
+ } else if (!fine_mode && list_itemInfo.length > 0) {
1331
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1332
+ continue;
1329
1333
  } else if (match_list) {
1330
1334
  removeTailBlank();
1331
1335
  list_itemInfo.push({
@@ -1333,19 +1337,23 @@ class ListProcess {
1333
1337
  level: match_list[1].length + 1
1334
1338
  });
1335
1339
  mul_mode = "list";
1336
- } else if (/^\S/.test(line) && mul_mode == "list") {
1337
- list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1340
+ } else if (mul_mode == "list" && /^\s/.test(line)) {
1341
+ list_itemInfo[list_itemInfo.length - 1].content += "\n" + line.trimStart();
1342
+ continue;
1338
1343
  } else {
1339
1344
  if (mul_mode == "para") {
1340
1345
  list_itemInfo[list_itemInfo.length - 1].content += "\n" + line;
1346
+ continue;
1341
1347
  } else if (/^\s*$/.test(line)) {
1342
1348
  continue;
1343
1349
  } else {
1350
+ removeTailBlank();
1344
1351
  list_itemInfo.push({
1345
1352
  content: line,
1346
1353
  level: 0
1347
1354
  });
1348
1355
  mul_mode = "para";
1356
+ continue;
1349
1357
  }
1350
1358
  }
1351
1359
  }
@@ -1564,7 +1572,7 @@ const abc_list2listdata = ABConvert.factory({
1564
1572
  process_param: ABConvert_IOEnum.text,
1565
1573
  process_return: ABConvert_IOEnum.list_stream,
1566
1574
  detail: "列表到listdata",
1567
- process: (el, header, content) => {
1575
+ process: (_el, _header, content) => {
1568
1576
  return ListProcess.list2data(content);
1569
1577
  }
1570
1578
  });
@@ -1573,9 +1581,19 @@ const abc_title2listdata = ABConvert.factory({
1573
1581
  name: "标题到listdata",
1574
1582
  process_param: ABConvert_IOEnum.text,
1575
1583
  process_return: ABConvert_IOEnum.list_stream,
1576
- detail: "标题到listdata",
1577
- process: (el, header, content) => {
1578
- return ListProcess.title2data(content);
1584
+ detail: "标题到listdata。细粒度版本,列表会拆分成多个节点",
1585
+ process: (_el, _header, content) => {
1586
+ return ListProcess.title2data(content, true);
1587
+ }
1588
+ });
1589
+ ABConvert.factory({
1590
+ id: "title2Listdata",
1591
+ name: "标题到Listdata",
1592
+ process_param: ABConvert_IOEnum.text,
1593
+ process_return: ABConvert_IOEnum.list_stream,
1594
+ detail: "标题到Listdata。粗粒度版本,列表为一个节点,不会拆分",
1595
+ process: (_el, _header, content) => {
1596
+ return ListProcess.title2data(content, false);
1579
1597
  }
1580
1598
  });
1581
1599
  ABConvert.factory({
@@ -1583,9 +1601,19 @@ ABConvert.factory({
1583
1601
  name: "mdit到listdata",
1584
1602
  process_param: ABConvert_IOEnum.text,
1585
1603
  process_return: ABConvert_IOEnum.list_stream,
1586
- detail: "mdit到listdata",
1587
- process: (el, header, content) => {
1588
- return ListProcess.mdit2data(content);
1604
+ detail: "mdit到listdata。细粒度版本,列表会拆分成多个节点",
1605
+ process: (_el, _header, content) => {
1606
+ return ListProcess.mdit2data(content, true);
1607
+ }
1608
+ });
1609
+ ABConvert.factory({
1610
+ id: "mdit2Listdata",
1611
+ name: "mdit到Listdata",
1612
+ process_param: ABConvert_IOEnum.text,
1613
+ process_return: ABConvert_IOEnum.list_stream,
1614
+ detail: "mdit到Listdata。粗粒度版本,列表为一个节点,不会拆分",
1615
+ process: (_el, _header, content) => {
1616
+ return ListProcess.mdit2data(content, false);
1589
1617
  }
1590
1618
  });
1591
1619
  ABConvert.factory({
@@ -1594,7 +1622,7 @@ ABConvert.factory({
1594
1622
  process_param: ABConvert_IOEnum.list_stream,
1595
1623
  process_return: ABConvert_IOEnum.text,
1596
1624
  detail: "listdata到列表",
1597
- process: (el, header, content) => {
1625
+ process: (_el, _header, content) => {
1598
1626
  return ListProcess.data2list(content);
1599
1627
  }
1600
1628
  });
@@ -1604,17 +1632,18 @@ ABConvert.factory({
1604
1632
  process_param: ABConvert_IOEnum.list_stream,
1605
1633
  process_return: ABConvert_IOEnum.el,
1606
1634
  detail: "listdata到节点图",
1607
- process: (el, header, content) => {
1635
+ process: (el, _header, content) => {
1608
1636
  return ListProcess.data2nodes(content, el);
1609
1637
  }
1610
1638
  });
1611
1639
  ABConvert.factory({
1612
1640
  id: "listdata2strict",
1613
1641
  name: "listdata严格化",
1642
+ match: /listdata2strict|listdata2lint/,
1614
1643
  process_param: ABConvert_IOEnum.list_stream,
1615
1644
  process_return: ABConvert_IOEnum.list_stream,
1616
1645
  detail: "将列表数据转化为更规范的列表数据。统一缩进符(2空格 4空格 tab混用)为level 1、禁止跳等级(h1直接就到h3)",
1617
- process: (el, header, content) => {
1646
+ process: (_el, _header, content) => {
1618
1647
  return ListProcess.data2strict(content);
1619
1648
  }
1620
1649
  });
@@ -1624,7 +1653,7 @@ ABConvert.factory({
1624
1653
  process_param: ABConvert_IOEnum.list_stream,
1625
1654
  process_return: ABConvert_IOEnum.list_stream,
1626
1655
  detail: "当列表中存在任务列表项时,令此列表项支持任务项",
1627
- process: (el, header, content) => {
1656
+ process: (_el, _header, content) => {
1628
1657
  return ListProcess.data2taskData(content);
1629
1658
  }
1630
1659
  });
@@ -1634,7 +1663,7 @@ ABConvert.factory({
1634
1663
  process_param: ABConvert_IOEnum.text,
1635
1664
  process_return: ABConvert_IOEnum.json,
1636
1665
  detail: "列表到listnode",
1637
- process: (el, header, content) => {
1666
+ process: (_el, _header, content) => {
1638
1667
  const data2 = ListProcess.list2listnode(content);
1639
1668
  return JSON.stringify(data2, null, 2);
1640
1669
  }
@@ -1645,7 +1674,7 @@ ABConvert.factory({
1645
1674
  process_param: ABConvert_IOEnum.text,
1646
1675
  process_return: ABConvert_IOEnum.json,
1647
1676
  detail: "列表到json",
1648
- process: (el, header, content) => {
1677
+ process: (_el, _header, content) => {
1649
1678
  const data2 = ListProcess.list2json(content);
1650
1679
  return JSON.stringify(data2, null, 2);
1651
1680
  }
@@ -2158,6 +2187,19 @@ ABConvert.factory({
2158
2187
  return el = TableProcess.data2table(data2, el, matchs[2] == "T");
2159
2188
  }
2160
2189
  });
2190
+ ABConvert.factory({
2191
+ id: "listdata2table",
2192
+ name: "列表数据转表格",
2193
+ match: /listdata2(md)?table(T)?/,
2194
+ default: "listdata2table",
2195
+ process_param: ABConvert_IOEnum.list_stream,
2196
+ process_return: ABConvert_IOEnum.el,
2197
+ process: (el, header, content) => {
2198
+ const matchs = header.match(/listdata2(md)?table(T)?/);
2199
+ if (!matchs) return el;
2200
+ return el = TableProcess.data2table(content, el, matchs[2] == "T");
2201
+ }
2202
+ });
2161
2203
  ABConvert.factory({
2162
2204
  id: "list2c2t",
2163
2205
  name: "列表转二列表格",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anyblock/remark-any-block",
3
- "version": "3.4.11",
3
+ "version": "3.5.0",
4
4
  "description": "You can flexibility to create a 'Block' by many means. It also provides many useful features, like `list to table`.",
5
5
  "types": "@types/index_remark.d.ts",
6
6
  "type": "module",