vuepress-plugin-md-power 1.0.0-rc.106 → 1.0.0-rc.108

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.
@@ -81,6 +81,11 @@ interface JSFiddleTokenMeta extends SizeOptions {
81
81
  tab?: string;
82
82
  }
83
83
 
84
+ type NpmToPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'deno';
85
+ type NpmToOptions = NpmToPackageManager[] | {
86
+ tabs?: NpmToPackageManager[];
87
+ };
88
+
84
89
  type PDFEmbedType = 'iframe' | 'embed' | 'pdfjs';
85
90
  interface PDFTokenMeta extends SizeOptions {
86
91
  page?: number;
@@ -98,7 +103,7 @@ interface PDFOptions {
98
103
 
99
104
  interface PlotOptions {
100
105
  /**
101
- * 是否启用 `=| |=` markdown (该标记为非标准标记,脱离插件将不生效)
106
+ * 是否启用 `!! !!` markdown (该标记为非标准标记,脱离插件将不生效)
102
107
  * @default true
103
108
  */
104
109
  tag?: boolean;
@@ -151,6 +156,10 @@ interface MarkdownPowerPluginOptions {
151
156
  * 配置代码块分组
152
157
  */
153
158
  codeTabs?: CodeTabsOptions;
159
+ /**
160
+ * 是否启用 npm-to 容器
161
+ */
162
+ npmTo?: boolean | NpmToOptions;
154
163
  /**
155
164
  * 是否启用 PDF 嵌入语法
156
165
  *
@@ -295,4 +304,4 @@ declare function resolveImageSize(app: App, url: string, remote?: boolean): Prom
295
304
 
296
305
  declare function markdownPowerPlugin(options?: MarkdownPowerPluginOptions): Plugin;
297
306
 
298
- export { type BilibiliTokenMeta, type CanIUseMode, type CanIUseOptions, type CanIUseTokenMeta, type CodeSandboxTokenMeta, type CodeTabsOptions, type CodepenTokenMeta, type FileTreeIconMode, type FileTreeOptions, type IconsOptions, type JSFiddleTokenMeta, type MarkdownPowerPluginOptions, type PDFEmbedType, type PDFOptions, type PDFTokenMeta, type PlotOptions, type ReplEditorData, type ReplOptions, type ReplitTokenMeta, type SizeOptions, type ThemeOptions, type VideoOptions, type YoutubeTokenMeta, markdownPowerPlugin, resolveImageSize };
307
+ export { type BilibiliTokenMeta, type CanIUseMode, type CanIUseOptions, type CanIUseTokenMeta, type CodeSandboxTokenMeta, type CodeTabsOptions, type CodepenTokenMeta, type FileTreeIconMode, type FileTreeOptions, type IconsOptions, type JSFiddleTokenMeta, type MarkdownPowerPluginOptions, type NpmToOptions, type NpmToPackageManager, type PDFEmbedType, type PDFOptions, type PDFTokenMeta, type PlotOptions, type ReplEditorData, type ReplOptions, type ReplitTokenMeta, type SizeOptions, type ThemeOptions, type VideoOptions, type YoutubeTokenMeta, markdownPowerPlugin, resolveImageSize };
package/lib/node/index.js CHANGED
@@ -16,7 +16,7 @@ function resolveAttrs(info) {
16
16
  const rawAttrs = info;
17
17
  let matched;
18
18
  while (matched = info.match(RE_ATTR_VALUE)) {
19
- const { attr, value } = matched.groups || {};
19
+ const { attr, value } = matched.groups;
20
20
  attrs2[attr] = value ?? true;
21
21
  info = info.slice(matched[0].length);
22
22
  }
@@ -1051,10 +1051,10 @@ var definitions = {
1051
1051
  };
1052
1052
 
1053
1053
  // src/node/fileIcons/findIcon.ts
1054
- function getFileIcon(fileName, type2 = "file") {
1054
+ function getFileIcon(fileName, type2) {
1055
1055
  const name = getFileIconName(fileName, type2);
1056
1056
  if (!name)
1057
- return type2 === "file" ? defaultFile : defaultFolder;
1057
+ return type2 !== "folder" ? defaultFile : defaultFolder;
1058
1058
  return name;
1059
1059
  }
1060
1060
  function getFileIconName(fileName, type2 = "file") {
@@ -1069,7 +1069,7 @@ function getFileIconName(fileName, type2 = "file") {
1069
1069
  let icon = definitions.named[fileName] || definitions.files[fileName];
1070
1070
  if (icon)
1071
1071
  return icon;
1072
- icon = getFileIconTypeFromExtension(fileName);
1072
+ icon = getFileIconTypeFromExtension(fileName) || void 0;
1073
1073
  if (icon)
1074
1074
  return icon;
1075
1075
  for (const [partial, partialIcon] of Object.entries(definitions.partials)) {
@@ -1092,7 +1092,6 @@ function getFileIconTypeFromExtension(fileName) {
1092
1092
  return;
1093
1093
  extension = extension.slice(nextDotIndex);
1094
1094
  }
1095
- return void 0;
1096
1095
  }
1097
1096
 
1098
1097
  // src/node/utils/stringifyProp.ts
@@ -1141,17 +1140,15 @@ var codeTabs = (md, options = {}) => {
1141
1140
  tabOpenRenderer: ({ index }, tokens, tokenIndex) => {
1142
1141
  let foundFence = false;
1143
1142
  for (let i = tokenIndex; i < tokens.length; i++) {
1144
- const { block, type: type2 } = tokens[i];
1145
- if (block) {
1146
- if (type2 === "code-tabs_tab_close")
1147
- break;
1148
- if ((type2 === "fence" || type2 === "import_code") && !foundFence) {
1149
- foundFence = true;
1150
- continue;
1151
- }
1152
- tokens[i].type = "code_tab_empty";
1153
- tokens[i].hidden = true;
1143
+ const { type: type2 } = tokens[i];
1144
+ if (type2 === "code-tabs_tab_close")
1145
+ break;
1146
+ if ((type2 === "fence" || type2 === "import_code") && !foundFence) {
1147
+ foundFence = true;
1148
+ continue;
1154
1149
  }
1150
+ tokens[i].type = "code_tab_empty";
1151
+ tokens[i].hidden = true;
1155
1152
  }
1156
1153
  return `<template #tab${index}="{ value, isActive }">`;
1157
1154
  },
@@ -1244,7 +1241,7 @@ function resolveTreeNodeInfo(tokens, current, idx) {
1244
1241
  }
1245
1242
  function updateInlineToken(inline, info, icon) {
1246
1243
  const children = inline.children;
1247
- if (!children)
1244
+ if (!children || children.length === 0)
1248
1245
  return;
1249
1246
  const tokens = [];
1250
1247
  const wrapperOpen = new Token("span_open", "span", 1);
@@ -1369,6 +1366,352 @@ async function read(file) {
1369
1366
  return void 0;
1370
1367
  }
1371
1368
 
1369
+ // src/node/container/npmTo.ts
1370
+ import { isArray } from "@vuepress/helper";
1371
+ import container4 from "markdown-it-container";
1372
+ var ALLOW_LIST = ["npm", "pnpm", "yarn", "bun", "deno"];
1373
+ var BOOL_FLAGS = ["--no-save", "-B", "--save-bundle", "--save-dev", "-D", "--save-prod", "-P", "--save-peer", "-O", "--save-optional", "-E", "--save-exact", "-y", "--yes", "-g", "--global"];
1374
+ var DEFAULT_TABS = ["npm", "pnpm", "yarn"];
1375
+ var MANAGERS_CONFIG = {
1376
+ install: {
1377
+ pattern: /(?:^|\s)npm\s+(?:install|i)$/,
1378
+ pnpm: { cli: "pnpm install" },
1379
+ yarn: { cli: "yarn" },
1380
+ bun: { cli: "bun install" },
1381
+ deno: { cli: "deno install" }
1382
+ },
1383
+ add: {
1384
+ pattern: /(?:^|\s)npm\s+(?:install|i|add)(?:\s|$)/,
1385
+ pnpm: {
1386
+ cli: "pnpm add",
1387
+ flags: {
1388
+ "--no-save": "",
1389
+ // unsupported
1390
+ "-B": "",
1391
+ // unsupported
1392
+ "--save-bundle": ""
1393
+ // unsupported
1394
+ }
1395
+ },
1396
+ yarn: {
1397
+ cli: "yarn add",
1398
+ flags: {
1399
+ "--save-dev": "--dev",
1400
+ "--save-prod": "--prod",
1401
+ "-P": "",
1402
+ // in npm, `-P` same as `--save-prod`. but in yarn, `-P` same as `--peer`
1403
+ "--save-peer": "--peer",
1404
+ "--save-optional": "--optional",
1405
+ "--no-save": "",
1406
+ // unsupported
1407
+ "--save-exact": "--exact",
1408
+ "-B": "",
1409
+ // unsupported
1410
+ "--save-bundle": ""
1411
+ // unsupported
1412
+ }
1413
+ },
1414
+ bun: {
1415
+ cli: "bun add",
1416
+ flags: {
1417
+ "--save-dev": "--development",
1418
+ "-P": "",
1419
+ // it's default
1420
+ "--save-prod": "",
1421
+ // it's default
1422
+ "--save-peer": "",
1423
+ // unsupported
1424
+ "-O": "--optional",
1425
+ "--save-optional": "--optional",
1426
+ "--no-save": "",
1427
+ // unsupported
1428
+ "--save-exact": "--exact",
1429
+ "-B": "",
1430
+ // unsupported
1431
+ "--save-bundle": ""
1432
+ // unsupported
1433
+ }
1434
+ },
1435
+ deno: {
1436
+ cli: "deno add",
1437
+ flags: {
1438
+ "-g": "",
1439
+ // unsupported
1440
+ "--global": "",
1441
+ // unsupported
1442
+ "--save-dev": "--dev",
1443
+ "-P": "",
1444
+ // unsupported
1445
+ "--save-prod": "",
1446
+ // unsupported
1447
+ "--save-peer": "",
1448
+ // unsupported
1449
+ "-O": "",
1450
+ // unsupported
1451
+ "--save-optional": "",
1452
+ // unsupported
1453
+ "--no-save": "",
1454
+ // unsupported
1455
+ "-E": "",
1456
+ // unsupported
1457
+ "--save-exact": "",
1458
+ // unsupported
1459
+ "-B": "",
1460
+ // unsupported
1461
+ "--save-bundle": ""
1462
+ // unsupported
1463
+ }
1464
+ }
1465
+ },
1466
+ run: {
1467
+ pattern: /(?:^|\s)npm\s+(?:run|run-script|rum|urn)(?:\s|$)/,
1468
+ pnpm: {
1469
+ cli: "pnpm",
1470
+ flags: {
1471
+ "-w": "-F",
1472
+ // same as `--workspace`
1473
+ "--workspace": "--filter",
1474
+ // filter by workspaces
1475
+ "--": ""
1476
+ // scripts flags
1477
+ }
1478
+ },
1479
+ yarn: {
1480
+ cli: "yarn",
1481
+ flags: {
1482
+ "-w": "",
1483
+ // unsupported
1484
+ "--workspace": ""
1485
+ // unsupported
1486
+ }
1487
+ },
1488
+ bun: {
1489
+ cli: "bun run",
1490
+ flags: {
1491
+ "-w": "--filter",
1492
+ // same as `--workspace`
1493
+ "--workspace": "--filter"
1494
+ // filter by workspaces
1495
+ }
1496
+ },
1497
+ deno: {
1498
+ cli: "deno run",
1499
+ flags: {
1500
+ "-w": "",
1501
+ // unsupported
1502
+ "--workspace": ""
1503
+ // unsupported
1504
+ }
1505
+ }
1506
+ },
1507
+ create: {
1508
+ pattern: /(?:^|\s)npm\s+create\s/,
1509
+ pnpm: { cli: "pnpm create", flags: { "-y": "", "--yes": "" } },
1510
+ yarn: { cli: "yarn create", flags: { "-y": "", "--yes": "" } },
1511
+ bun: { cli: "bun create", flags: { "-y": "", "--yes": "" } },
1512
+ deno: { cli: "deno run -A ", flags: { "-y": "", "--yes": "" } }
1513
+ },
1514
+ init: {
1515
+ pattern: /(?:^|\s)npm\s+init/,
1516
+ pnpm: { cli: "pnpm init", flags: { "-y": "", "--yes": "" } },
1517
+ yarn: { cli: "yarn init", flags: { "-y": "", "--yes": "" } },
1518
+ bun: { cli: "bun init", flags: { "-y": "", "--yes": "" } },
1519
+ deno: { cli: "deno init", flags: { "-y": "", "--yes": "" } }
1520
+ },
1521
+ npx: {
1522
+ pattern: /(?:^|\s)npx\s+/,
1523
+ pnpm: { cli: "pnpm dlx" },
1524
+ yarn: { cli: "yarn dlx" },
1525
+ bun: { cli: "bunx" },
1526
+ deno: { cli: "deno run -A" }
1527
+ },
1528
+ remove: {
1529
+ pattern: /(?:^|\s)npm\s+(?:uninstall|r|rm|remove|unlink|un)(?:\s|$)/,
1530
+ pnpm: {
1531
+ cli: "pnpm remove",
1532
+ flags: { "--no-save": "", "--save": "", "-S": "" }
1533
+ },
1534
+ yarn: {
1535
+ cli: "yarn remove",
1536
+ flags: { "--save-dev": "--dev", "--save": "", "-S": "", "-g": "", "--global": "" }
1537
+ },
1538
+ bun: {
1539
+ cli: "bun remove",
1540
+ flags: { "--save-dev": "--development", "--save": "", "-S": "", "-g": "", "--global": "" }
1541
+ },
1542
+ deno: {
1543
+ cli: "deno uninstall",
1544
+ flags: { "--save-dev": "--dev", "--save": "", "-S": "" }
1545
+ }
1546
+ },
1547
+ ci: {
1548
+ pattern: /(?:^|\s)npm\s+ci$/,
1549
+ pnpm: { cli: "pnpm install --frozen-lockfile" },
1550
+ yarn: { cli: "yarn install --immutable" },
1551
+ bun: { cli: "bun install --frozen-lockfile" },
1552
+ deno: { cli: "deno install --frozen" }
1553
+ }
1554
+ };
1555
+ function npmToPlugins(md, options = {}) {
1556
+ const type2 = "npm-to";
1557
+ const validate = (info) => info.trim().startsWith(type2);
1558
+ const opt = isArray(options) ? { tabs: options } : options;
1559
+ const defaultTabs = opt.tabs?.length ? opt.tabs : DEFAULT_TABS;
1560
+ const render = (tokens, idx) => {
1561
+ const { attrs: attrs2 } = resolveAttrs(tokens[idx].info.trim().slice(type2.length));
1562
+ const tabs2 = attrs2.tabs ? attrs2.tabs.split(/,\s*/) : defaultTabs;
1563
+ if (tokens[idx].nesting === 1) {
1564
+ const token = tokens[idx + 1];
1565
+ const info = token.info.trim();
1566
+ if (token.type === "fence" && (info.startsWith("sh") || info.startsWith("bash") || info.startsWith("shell"))) {
1567
+ const content = token.content;
1568
+ token.hidden = true;
1569
+ token.type = "text";
1570
+ token.content = "";
1571
+ const lines = content.split(/(\n|\s*&&\s*)/);
1572
+ return md.render(resolveNpmTo(lines, info, idx, tabs2), {});
1573
+ }
1574
+ }
1575
+ return "";
1576
+ };
1577
+ md.use(container4, type2, { validate, render });
1578
+ }
1579
+ function resolveNpmTo(lines, info, idx, tabs2) {
1580
+ tabs2 = validateTabs(tabs2);
1581
+ const res = [];
1582
+ const map = {};
1583
+ for (const tab3 of tabs2) {
1584
+ const newLines = [];
1585
+ for (const line of lines) {
1586
+ const config = findConfig(line);
1587
+ if (config && config[tab3]) {
1588
+ const parsed = map[line] ??= parseLine(line);
1589
+ const { cli, flags } = config[tab3];
1590
+ let newLine = `${parsed.env ? `${parsed.env} ` : ""}${cli}`;
1591
+ if (parsed.args && flags) {
1592
+ let args = parsed.args;
1593
+ for (const [key, value] of Object.entries(flags)) {
1594
+ args = args.replaceAll(key, value);
1595
+ }
1596
+ newLine += ` ${args.replace(/\s+-/g, " -").trim()}`;
1597
+ }
1598
+ if (parsed.cmd)
1599
+ newLine += ` ${parsed.cmd}`;
1600
+ if (parsed.scriptArgs)
1601
+ newLine += ` ${parsed.scriptArgs}`;
1602
+ newLines.push(newLine.trim());
1603
+ } else {
1604
+ newLines.push(line);
1605
+ }
1606
+ }
1607
+ res.push(`@tab ${tab3}
1608
+ \`\`\`${info}
1609
+ ${newLines.join("")}
1610
+ \`\`\``);
1611
+ }
1612
+ return `:::code-tabs#npm-to-${idx}
1613
+ ${res.join("\n")}
1614
+ :::`;
1615
+ }
1616
+ function findConfig(line) {
1617
+ for (const { pattern, ...config } of Object.values(MANAGERS_CONFIG)) {
1618
+ if (pattern.test(line)) {
1619
+ return config;
1620
+ }
1621
+ }
1622
+ return void 0;
1623
+ }
1624
+ function validateTabs(tabs2) {
1625
+ tabs2 = tabs2.filter((tab3) => ALLOW_LIST.includes(tab3));
1626
+ if (tabs2.length === 0) {
1627
+ return DEFAULT_TABS;
1628
+ }
1629
+ return tabs2;
1630
+ }
1631
+ var LINE_REG = /(.*)(npm|npx)\s+(.*)/;
1632
+ function parseLine(line) {
1633
+ const match = line.match(LINE_REG);
1634
+ if (!match)
1635
+ return false;
1636
+ const [, env, cli, rest] = match;
1637
+ const idx = rest.trim().indexOf(" ");
1638
+ if (cli === "npx") {
1639
+ let cmd = "";
1640
+ let scriptArgs = "";
1641
+ if (idx !== -1) {
1642
+ cmd = rest.slice(0, idx);
1643
+ scriptArgs = rest.slice(idx + 1).trim();
1644
+ } else {
1645
+ cmd = rest;
1646
+ }
1647
+ return { env, cli, cmd, scriptArgs };
1648
+ }
1649
+ if (idx === -1)
1650
+ return { env, cli: `${cli} ${rest.trim()}`, cmd: "" };
1651
+ return { env, cli: `${cli} ${rest.slice(0, idx)}`, ...parseArgs(rest.slice(idx + 1)) };
1652
+ }
1653
+ function parseArgs(line) {
1654
+ line = line?.trim();
1655
+ const [npmArgs, scriptArgs] = line.split(/\s+--\s+/);
1656
+ let cmd = "";
1657
+ let args = "";
1658
+ if (npmArgs[0] !== "-") {
1659
+ if (npmArgs[0] === '"' || npmArgs[0] === "'") {
1660
+ const idx = npmArgs.slice(1).indexOf(npmArgs[0]);
1661
+ cmd = npmArgs.slice(0, idx + 2);
1662
+ args = npmArgs.slice(idx + 2);
1663
+ } else {
1664
+ const idx = npmArgs.indexOf(" -");
1665
+ if (idx === -1) {
1666
+ cmd = npmArgs;
1667
+ } else {
1668
+ cmd = npmArgs.slice(0, idx);
1669
+ args = npmArgs.slice(idx + 1);
1670
+ }
1671
+ }
1672
+ } else {
1673
+ let newLine = "";
1674
+ let value = "";
1675
+ let isQuote = false;
1676
+ let isBool = false;
1677
+ let isNextValue = false;
1678
+ let quote = "";
1679
+ for (let i = 0; i < npmArgs.length; i++) {
1680
+ const v = npmArgs[i];
1681
+ if (!isQuote && (v === '"' || v === "'")) {
1682
+ quote = v;
1683
+ isQuote = true;
1684
+ value += v;
1685
+ } else if (isQuote && v === quote) {
1686
+ isQuote = false;
1687
+ value += v;
1688
+ } else if ((v === " " || v === "=" || i === npmArgs.length - 1) && !isQuote && value) {
1689
+ if (i === npmArgs.length - 1) {
1690
+ value += v;
1691
+ }
1692
+ const isKey = value[0] === "-";
1693
+ if (isKey) {
1694
+ isBool = BOOL_FLAGS.includes(value);
1695
+ isNextValue = !isBool;
1696
+ }
1697
+ if (!isKey && !isNextValue) {
1698
+ cmd += `${value}`;
1699
+ } else {
1700
+ newLine += `${value}${i !== npmArgs.length - 1 ? v : ""}`;
1701
+ if (!isKey && isNextValue) {
1702
+ isNextValue = false;
1703
+ }
1704
+ }
1705
+ value = "";
1706
+ } else {
1707
+ value += v;
1708
+ }
1709
+ }
1710
+ args = newLine;
1711
+ }
1712
+ return { cmd: cmd.trim(), args: args.trim(), scriptArgs };
1713
+ }
1714
+
1372
1715
  // src/node/container/tabs.ts
1373
1716
  import { tab as tab2 } from "@mdit/plugin-tab";
1374
1717
  var tabs = (md) => {
@@ -1397,6 +1740,9 @@ async function containerPlugin(app, md, options) {
1397
1740
  alignPlugin(md);
1398
1741
  tabs(md);
1399
1742
  codeTabs(md, options.codeTabs);
1743
+ if (options.npmTo) {
1744
+ npmToPlugins(md, typeof options.npmTo === "boolean" ? {} : options.npmTo);
1745
+ }
1400
1746
  if (options.repl)
1401
1747
  await langReplPlugin(app, md, options.repl);
1402
1748
  if (options.fileTree) {
@@ -1405,8 +1751,11 @@ async function containerPlugin(app, md, options) {
1405
1751
  }
1406
1752
 
1407
1753
  // src/node/embed/caniuse.ts
1408
- import container4 from "markdown-it-container";
1754
+ import container5 from "markdown-it-container";
1755
+
1756
+ // src/node/utils/nanoid.ts
1409
1757
  import { customAlphabet } from "nanoid";
1758
+ var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
1410
1759
 
1411
1760
  // src/node/embed/createEmbedRuleBlock.ts
1412
1761
  function createEmbedRuleBlock(md, {
@@ -1453,7 +1802,6 @@ function createEmbedRuleBlock(md, {
1453
1802
  }
1454
1803
 
1455
1804
  // src/node/embed/caniuse.ts
1456
- var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
1457
1805
  var UNDERLINE_RE = /_+/g;
1458
1806
  var caniusePlugin = (md, { mode: defaultMode = "embed" } = {}) => {
1459
1807
  createEmbedRuleBlock(md, {
@@ -1487,7 +1835,7 @@ function legacyCaniuse(md, { mode = "embed" } = {}) {
1487
1835
  return "";
1488
1836
  }
1489
1837
  };
1490
- md.use(container4, type2, { validate, render });
1838
+ md.use(container5, type2, { validate, render });
1491
1839
  }
1492
1840
  function resolveCanIUse({ feature, mode, versions }) {
1493
1841
  if (!feature)
@@ -1531,7 +1879,7 @@ var codepenPlugin = (md) => {
1531
1879
  createEmbedRuleBlock(md, {
1532
1880
  type: "codepen",
1533
1881
  syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
1534
- meta: ([, info = "", source = ""]) => {
1882
+ meta: ([, info, source]) => {
1535
1883
  const { attrs: attrs2 } = resolveAttrs(info);
1536
1884
  const [user, slash] = source.split("/");
1537
1885
  return {
@@ -1542,7 +1890,7 @@ var codepenPlugin = (md) => {
1542
1890
  title: attrs2.title,
1543
1891
  preview: attrs2.preview,
1544
1892
  editable: attrs2.editable,
1545
- tab: attrs2.tab ?? "result",
1893
+ tab: attrs2.tab || "result",
1546
1894
  theme: attrs2.theme
1547
1895
  };
1548
1896
  },
@@ -1552,9 +1900,7 @@ var codepenPlugin = (md) => {
1552
1900
  if (meta.editable) {
1553
1901
  params.set("editable", "true");
1554
1902
  }
1555
- if (meta.tab) {
1556
- params.set("default-tab", meta.tab);
1557
- }
1903
+ params.set("default-tab", meta.tab);
1558
1904
  if (meta.theme) {
1559
1905
  params.set("theme-id", meta.theme);
1560
1906
  }
@@ -1571,7 +1917,7 @@ var codeSandboxPlugin = (md) => {
1571
1917
  createEmbedRuleBlock(md, {
1572
1918
  type: "codesandbox",
1573
1919
  syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
1574
- meta([, type2, info = "", source = ""]) {
1920
+ meta([, type2, info, source]) {
1575
1921
  const { attrs: attrs2 } = resolveAttrs(info);
1576
1922
  const [profile, filepath2 = ""] = source.split("#");
1577
1923
  const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
@@ -1599,7 +1945,7 @@ var jsfiddlePlugin = (md) => {
1599
1945
  createEmbedRuleBlock(md, {
1600
1946
  type: "jsfiddle",
1601
1947
  syntaxPattern: /^@\[jsfiddle([^\]]*)\]\(([^)]*)\)/,
1602
- meta([, info = "", source]) {
1948
+ meta([, info, source]) {
1603
1949
  const { attrs: attrs2 } = resolveAttrs(info);
1604
1950
  const [user, id] = source.split("/");
1605
1951
  return {
@@ -1612,7 +1958,7 @@ var jsfiddlePlugin = (md) => {
1612
1958
  theme: attrs2.theme || "dark"
1613
1959
  };
1614
1960
  },
1615
- content: ({ title = "JS Fiddle", height, width, user, id, tab: tab3, theme }) => {
1961
+ content: ({ title, height, width, user, id, tab: tab3, theme }) => {
1616
1962
  theme = theme === "dark" ? "/dark/" : "";
1617
1963
  const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab3}${theme}`;
1618
1964
  const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
@@ -1649,7 +1995,7 @@ var pdfPlugin = (md) => {
1649
1995
  type: "pdf",
1650
1996
  // eslint-disable-next-line regexp/no-super-linear-backtracking
1651
1997
  syntaxPattern: /^@\[pdf(?:\s+(\d+))?([^\]]*)\]\(([^)]*)\)/,
1652
- meta([, page, info = "", src = ""]) {
1998
+ meta([, page, info, src]) {
1653
1999
  const { attrs: attrs2 } = resolveAttrs(info);
1654
2000
  return {
1655
2001
  src,
@@ -1677,7 +2023,7 @@ function timeToSeconds(time) {
1677
2023
  return 0;
1678
2024
  if (Number.parseFloat(time) === Number(time))
1679
2025
  return Number(time);
1680
- const [s, m, h] = time.split(":").reverse().map((n) => Number(n) || 0);
2026
+ const [s, m, h = 0] = time.split(/\s*:\s*/).reverse().map((n) => Number(n) || 0);
1681
2027
  return s + m * 60 + h * 3600;
1682
2028
  }
1683
2029
 
@@ -1689,13 +2035,13 @@ var bilibiliPlugin = (md) => {
1689
2035
  name: "video_bilibili",
1690
2036
  // eslint-disable-next-line regexp/no-super-linear-backtracking
1691
2037
  syntaxPattern: /^@\[bilibili(?:\s+p(\d+))?([^\]]*)\]\(([^)]*)\)/,
1692
- meta([, page, info = "", source = ""]) {
2038
+ meta([, page, info, source]) {
1693
2039
  const { attrs: attrs2 } = resolveAttrs(info);
1694
2040
  const ids = source.trim().split(/\s+/);
1695
2041
  const bvid = ids.find((id) => id.startsWith("BV"));
1696
2042
  const [aid, cid] = ids.filter((id) => !id.startsWith("BV"));
1697
2043
  return {
1698
- page: +page || 1,
2044
+ page: +page,
1699
2045
  bvid,
1700
2046
  aid,
1701
2047
  cid,
@@ -1739,7 +2085,7 @@ var youtubePlugin = (md) => {
1739
2085
  type: "youtube",
1740
2086
  name: "video_youtube",
1741
2087
  syntaxPattern: /^@\[youtube([^\]]*)\]\(([^)]*)\)/,
1742
- meta([, info = "", id = ""]) {
2088
+ meta([, info, id]) {
1743
2089
  const { attrs: attrs2 } = resolveAttrs(info);
1744
2090
  return {
1745
2091
  id,
@@ -1846,13 +2192,12 @@ function createTokenizer(options) {
1846
2192
  state.posMax = state.pos;
1847
2193
  state.pos = start + 2;
1848
2194
  const [name, opt = ""] = content.split(/\s+/);
1849
- const [size = options.size, color = options.color] = opt.split("/");
2195
+ const [size, color = options.color] = opt.split("/");
1850
2196
  const icon = state.push("vp_iconify_open", "VPIcon", 1);
1851
2197
  icon.markup = openTag;
1852
- if (name)
1853
- icon.attrSet("name", name);
1854
- if (size)
1855
- icon.attrSet("size", String(size));
2198
+ icon.attrSet("name", name);
2199
+ if (size || options.size)
2200
+ icon.attrSet("size", String(size || options.size));
1856
2201
  if (color)
1857
2202
  icon.attrSet("color", color);
1858
2203
  const close = state.push("vp_iconify_close", "VPIcon", -1);
@@ -79,6 +79,11 @@ interface JSFiddleTokenMeta extends SizeOptions {
79
79
  tab?: string;
80
80
  }
81
81
 
82
+ type NpmToPackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun' | 'deno';
83
+ type NpmToOptions = NpmToPackageManager[] | {
84
+ tabs?: NpmToPackageManager[];
85
+ };
86
+
82
87
  type PDFEmbedType = 'iframe' | 'embed' | 'pdfjs';
83
88
  interface PDFTokenMeta extends SizeOptions {
84
89
  page?: number;
@@ -96,7 +101,7 @@ interface PDFOptions {
96
101
 
97
102
  interface PlotOptions {
98
103
  /**
99
- * 是否启用 `=| |=` markdown (该标记为非标准标记,脱离插件将不生效)
104
+ * 是否启用 `!! !!` markdown (该标记为非标准标记,脱离插件将不生效)
100
105
  * @default true
101
106
  */
102
107
  tag?: boolean;
@@ -149,6 +154,10 @@ interface MarkdownPowerPluginOptions {
149
154
  * 配置代码块分组
150
155
  */
151
156
  codeTabs?: CodeTabsOptions;
157
+ /**
158
+ * 是否启用 npm-to 容器
159
+ */
160
+ npmTo?: boolean | NpmToOptions;
152
161
  /**
153
162
  * 是否启用 PDF 嵌入语法
154
163
  *
@@ -285,4 +294,4 @@ interface YoutubeTokenMeta extends SizeOptions {
285
294
  end?: string | number;
286
295
  }
287
296
 
288
- export type { BilibiliTokenMeta, CanIUseMode, CanIUseOptions, CanIUseTokenMeta, CodeSandboxTokenMeta, CodeTabsOptions, CodepenTokenMeta, FileTreeIconMode, FileTreeOptions, IconsOptions, JSFiddleTokenMeta, MarkdownPowerPluginOptions, PDFEmbedType, PDFOptions, PDFTokenMeta, PlotOptions, ReplEditorData, ReplOptions, ReplitTokenMeta, SizeOptions, ThemeOptions, VideoOptions, YoutubeTokenMeta };
297
+ export type { BilibiliTokenMeta, CanIUseMode, CanIUseOptions, CanIUseTokenMeta, CodeSandboxTokenMeta, CodeTabsOptions, CodepenTokenMeta, FileTreeIconMode, FileTreeOptions, IconsOptions, JSFiddleTokenMeta, MarkdownPowerPluginOptions, NpmToOptions, NpmToPackageManager, PDFEmbedType, PDFOptions, PDFTokenMeta, PlotOptions, ReplEditorData, ReplOptions, ReplitTokenMeta, SizeOptions, ThemeOptions, VideoOptions, YoutubeTokenMeta };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vuepress-plugin-md-power",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.106",
4
+ "version": "1.0.0-rc.108",
5
5
  "description": "The Plugin for VuePress 2 - markdown power",
6
6
  "author": "pengzhanbo <volodymyr@foxmail.com>",
7
7
  "license": "MIT",
@@ -31,8 +31,14 @@
31
31
  "lib"
32
32
  ],
33
33
  "peerDependencies": {
34
+ "markdown-it": "^14.0.0",
34
35
  "vuepress": "2.0.0-rc.17"
35
36
  },
37
+ "peerDependenciesMeta": {
38
+ "markdown-it": {
39
+ "optional": true
40
+ }
41
+ },
36
42
  "dependencies": {
37
43
  "@mdit/plugin-attrs": "^0.13.1",
38
44
  "@mdit/plugin-footnote": "^0.13.1",
@@ -46,10 +52,10 @@
46
52
  "image-size": "^1.1.1",
47
53
  "markdown-it-container": "^4.0.0",
48
54
  "nanoid": "^5.0.7",
49
- "shiki": "^1.21.0",
50
- "tm-grammars": "^1.17.28",
51
- "tm-themes": "^1.8.6",
52
- "vue": "^3.5.10"
55
+ "shiki": "^1.22.0",
56
+ "tm-grammars": "^1.18.2",
57
+ "tm-themes": "^1.8.8",
58
+ "vue": "^3.5.12"
53
59
  },
54
60
  "devDependencies": {
55
61
  "@types/markdown-it": "^14.1.2"