vuepress-plugin-md-power 1.0.0-rc.143 → 1.0.0-rc.144
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -10
- package/lib/client/components/CanIUse.vue +4 -4
- package/lib/client/components/FileTreeNode.vue +212 -0
- package/lib/client/composables/demo.js +3 -3
- package/lib/node/index.d.ts +1 -1
- package/lib/node/index.js +427 -440
- package/lib/shared/index.d.ts +1 -1
- package/package.json +11 -11
- package/lib/client/components/FileTreeItem.vue +0 -183
package/lib/node/index.js
CHANGED
|
@@ -816,14 +816,14 @@ var definitions = {
|
|
|
816
816
|
};
|
|
817
817
|
|
|
818
818
|
// src/node/fileIcons/findIcon.ts
|
|
819
|
-
function getFileIcon(fileName,
|
|
820
|
-
const name = getFileIconName(fileName,
|
|
819
|
+
function getFileIcon(fileName, type) {
|
|
820
|
+
const name = getFileIconName(fileName, type);
|
|
821
821
|
if (!name)
|
|
822
|
-
return
|
|
822
|
+
return type !== "folder" ? defaultFile : defaultFolder;
|
|
823
823
|
return name;
|
|
824
824
|
}
|
|
825
|
-
function getFileIconName(fileName,
|
|
826
|
-
if (
|
|
825
|
+
function getFileIconName(fileName, type = "file") {
|
|
826
|
+
if (type === "folder") {
|
|
827
827
|
const icon2 = definitions.folders[fileName];
|
|
828
828
|
if (icon2)
|
|
829
829
|
return icon2;
|
|
@@ -921,10 +921,10 @@ var codeTabs = (md, options = {}) => {
|
|
|
921
921
|
tabOpenRenderer: ({ index }, tokens, tokenIndex) => {
|
|
922
922
|
let foundFence = false;
|
|
923
923
|
for (let i = tokenIndex; i < tokens.length; i++) {
|
|
924
|
-
const { type
|
|
925
|
-
if (
|
|
924
|
+
const { type } = tokens[i];
|
|
925
|
+
if (type === "code-tabs_tab_close")
|
|
926
926
|
break;
|
|
927
|
-
if ((
|
|
927
|
+
if ((type === "fence" || type === "import_code") && !foundFence) {
|
|
928
928
|
foundFence = true;
|
|
929
929
|
continue;
|
|
930
930
|
}
|
|
@@ -946,6 +946,7 @@ import imageSize from "image-size";
|
|
|
946
946
|
import { fs, logger, path } from "vuepress/utils";
|
|
947
947
|
|
|
948
948
|
// src/node/utils/resolveAttrs.ts
|
|
949
|
+
import { camelCase } from "@pengzhanbo/utils";
|
|
949
950
|
var RE_ATTR_VALUE = /(?:^|\s+)(?<attr>[\w-]+)(?:=\s*(?<quote>['"])(?<value>.+?)\k<quote>)?(?:\s+|$)/;
|
|
950
951
|
function resolveAttrs(info) {
|
|
951
952
|
info = info.trim();
|
|
@@ -955,23 +956,15 @@ function resolveAttrs(info) {
|
|
|
955
956
|
const rawAttrs = info;
|
|
956
957
|
let matched;
|
|
957
958
|
while (matched = info.match(RE_ATTR_VALUE)) {
|
|
958
|
-
const { attr, value } = matched.groups;
|
|
959
|
-
|
|
959
|
+
const { attr, value = true } = matched.groups;
|
|
960
|
+
let v = typeof value === "string" ? value.trim() : value;
|
|
961
|
+
if (v === "true")
|
|
962
|
+
v = true;
|
|
963
|
+
else if (v === "false")
|
|
964
|
+
v = false;
|
|
965
|
+
attrs2[camelCase(attr)] = v;
|
|
960
966
|
info = info.slice(matched[0].length);
|
|
961
967
|
}
|
|
962
|
-
Object.keys(attrs2).forEach((key) => {
|
|
963
|
-
let value = attrs2[key];
|
|
964
|
-
value = typeof value === "string" ? value.trim() : value;
|
|
965
|
-
if (value === "true")
|
|
966
|
-
value = true;
|
|
967
|
-
else if (value === "false")
|
|
968
|
-
value = false;
|
|
969
|
-
attrs2[key] = value;
|
|
970
|
-
if (key.includes("-")) {
|
|
971
|
-
const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase());
|
|
972
|
-
attrs2[_key] = value;
|
|
973
|
-
}
|
|
974
|
-
});
|
|
975
968
|
return { attrs: attrs2, rawAttrs };
|
|
976
969
|
}
|
|
977
970
|
|
|
@@ -987,10 +980,10 @@ var BADGE_LIST = [
|
|
|
987
980
|
"https://vercel.com/button"
|
|
988
981
|
];
|
|
989
982
|
var cache = /* @__PURE__ */ new Map();
|
|
990
|
-
async function imageSizePlugin(app, md,
|
|
991
|
-
if (!app.env.isBuild || !
|
|
983
|
+
async function imageSizePlugin(app, md, type = false) {
|
|
984
|
+
if (!app.env.isBuild || !type)
|
|
992
985
|
return;
|
|
993
|
-
if (
|
|
986
|
+
if (type === "all") {
|
|
994
987
|
const start = performance.now();
|
|
995
988
|
try {
|
|
996
989
|
await scanRemoteImageSize(app);
|
|
@@ -1158,17 +1151,63 @@ import { isPlainObject as isPlainObject2 } from "@vuepress/helper";
|
|
|
1158
1151
|
|
|
1159
1152
|
// src/node/container/createContainer.ts
|
|
1160
1153
|
import container from "markdown-it-container";
|
|
1161
|
-
function createContainerPlugin(md,
|
|
1154
|
+
function createContainerPlugin(md, type, { before, after } = {}) {
|
|
1162
1155
|
const render = (tokens, index, options, env) => {
|
|
1163
1156
|
const token = tokens[index];
|
|
1164
|
-
const info = token.info.trim().slice(
|
|
1157
|
+
const info = token.info.trim().slice(type.length).trim() || "";
|
|
1165
1158
|
if (token.nesting === 1) {
|
|
1166
|
-
return before?.(info, tokens, index, options, env)
|
|
1159
|
+
return before?.(info, tokens, index, options, env) ?? `<div class="custom-container ${type}">`;
|
|
1167
1160
|
} else {
|
|
1168
|
-
return after?.(info, tokens, index, options, env)
|
|
1161
|
+
return after?.(info, tokens, index, options, env) ?? "</div>";
|
|
1169
1162
|
}
|
|
1170
1163
|
};
|
|
1171
|
-
md.use(container,
|
|
1164
|
+
md.use(container, type, { render });
|
|
1165
|
+
}
|
|
1166
|
+
function createContainerSyntaxPlugin(md, type, render) {
|
|
1167
|
+
const maker = ":";
|
|
1168
|
+
const markerMinLen = 3;
|
|
1169
|
+
function defineContainer(state, startLine, endLine, silent) {
|
|
1170
|
+
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
1171
|
+
const max = state.eMarks[startLine];
|
|
1172
|
+
let pos = start;
|
|
1173
|
+
if (state.src[pos] !== maker)
|
|
1174
|
+
return false;
|
|
1175
|
+
pos += markerMinLen;
|
|
1176
|
+
for (pos = start + 1; pos <= max; pos++) {
|
|
1177
|
+
if (state.src[pos] !== maker)
|
|
1178
|
+
break;
|
|
1179
|
+
}
|
|
1180
|
+
if (pos - start < markerMinLen)
|
|
1181
|
+
return false;
|
|
1182
|
+
const markup = state.src.slice(start, pos);
|
|
1183
|
+
const info = state.src.slice(pos, max).trim();
|
|
1184
|
+
if (!info.startsWith(type))
|
|
1185
|
+
return false;
|
|
1186
|
+
if (silent)
|
|
1187
|
+
return true;
|
|
1188
|
+
let line = startLine;
|
|
1189
|
+
let content = "";
|
|
1190
|
+
while (++line < endLine) {
|
|
1191
|
+
if (state.src.slice(state.bMarks[line], state.eMarks[line]).trim() === markup) {
|
|
1192
|
+
break;
|
|
1193
|
+
}
|
|
1194
|
+
content += `${state.src.slice(state.bMarks[line], state.eMarks[line])}
|
|
1195
|
+
`;
|
|
1196
|
+
}
|
|
1197
|
+
const token = state.push(`${type}_container`, "", 0);
|
|
1198
|
+
token.meta = resolveAttrs(info.slice(type.length)).attrs;
|
|
1199
|
+
token.content = content;
|
|
1200
|
+
token.markup = `${markup} ${type}`;
|
|
1201
|
+
token.map = [startLine, line + 1];
|
|
1202
|
+
state.line = line + 1;
|
|
1203
|
+
return true;
|
|
1204
|
+
}
|
|
1205
|
+
const defaultRender = (tokens, index) => {
|
|
1206
|
+
const { content } = tokens[index];
|
|
1207
|
+
return `<div class="custom-container ${type}">${content}</div>`;
|
|
1208
|
+
};
|
|
1209
|
+
md.block.ruler.before("fence", `${type}_definition`, defineContainer);
|
|
1210
|
+
md.renderer.rules[`${type}_container`] = render ?? defaultRender;
|
|
1172
1211
|
}
|
|
1173
1212
|
|
|
1174
1213
|
// src/node/container/align.ts
|
|
@@ -1181,13 +1220,37 @@ function alignPlugin(md) {
|
|
|
1181
1220
|
}
|
|
1182
1221
|
}
|
|
1183
1222
|
|
|
1223
|
+
// src/node/utils/stringifyAttrs.ts
|
|
1224
|
+
import { isBoolean, isNull, isNumber, isString, isUndefined, kebabCase } from "@pengzhanbo/utils";
|
|
1225
|
+
function stringifyAttrs(attrs2, withUndefined = false) {
|
|
1226
|
+
const result = Object.entries(attrs2).map(([key, value]) => {
|
|
1227
|
+
const k = kebabCase(key);
|
|
1228
|
+
if (isUndefined(value) || value === "undefined")
|
|
1229
|
+
return withUndefined ? `:${k}="undefined"` : "";
|
|
1230
|
+
if (isNull(value) || value === "null")
|
|
1231
|
+
return withUndefined ? `:${k}="null"` : "";
|
|
1232
|
+
if (value === "true")
|
|
1233
|
+
value = true;
|
|
1234
|
+
if (value === "false")
|
|
1235
|
+
value = false;
|
|
1236
|
+
if (isBoolean(value))
|
|
1237
|
+
return value ? `${k}` : "";
|
|
1238
|
+
if (isNumber(value))
|
|
1239
|
+
return `:${k}="${value}"`;
|
|
1240
|
+
if (isString(value) && (value[0] === "{" || value[0] === "["))
|
|
1241
|
+
return `:${k}="${value.replaceAll('"', "'")}"`;
|
|
1242
|
+
const hasDynamic = key[0] === ":";
|
|
1243
|
+
return `${hasDynamic ? ":" : ""}${k}="${String(value)}"`;
|
|
1244
|
+
}).filter(Boolean).join(" ");
|
|
1245
|
+
return result ? ` ${result}` : "";
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1184
1248
|
// src/node/container/card.ts
|
|
1185
1249
|
function cardPlugin(md) {
|
|
1186
1250
|
createContainerPlugin(md, "card", {
|
|
1187
1251
|
before(info) {
|
|
1188
1252
|
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1189
|
-
|
|
1190
|
-
return `<VPCard${title ? ` title="${title}"` : ""}${icon ? ` icon="${icon}"` : ""}>`;
|
|
1253
|
+
return `<VPCard${stringifyAttrs(attrs2)}>`;
|
|
1191
1254
|
},
|
|
1192
1255
|
after: () => "</VPCard>"
|
|
1193
1256
|
});
|
|
@@ -1198,63 +1261,17 @@ function cardPlugin(md) {
|
|
|
1198
1261
|
createContainerPlugin(md, "card-masonry", {
|
|
1199
1262
|
before: (info) => {
|
|
1200
1263
|
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
return `<VPCardMasonry${cols ? ` :cols="${cols}"` : ""}${gap >= 0 ? ` :gap="${gap}"` : ""}>`;
|
|
1264
|
+
if (attrs2.cols)
|
|
1265
|
+
attrs2.cols = attrs2.cols[0] === "{" ? attrs2.cols : Number.parseInt(`${attrs2.cols}`);
|
|
1266
|
+
if (attrs2.gap)
|
|
1267
|
+
attrs2.gap = Number(attrs2.gap);
|
|
1268
|
+
return `<VPCardMasonry${stringifyAttrs(attrs2)}>`;
|
|
1207
1269
|
},
|
|
1208
1270
|
after: () => "</VPCardMasonry>"
|
|
1209
1271
|
});
|
|
1210
1272
|
}
|
|
1211
1273
|
|
|
1212
1274
|
// src/node/container/chat.ts
|
|
1213
|
-
var chatPlugin = (md) => {
|
|
1214
|
-
md.block.ruler.before("fence", "chat_def", chatDef);
|
|
1215
|
-
md.renderer.rules.chat_container = (tokens, idx, _, env) => {
|
|
1216
|
-
const { meta, content } = tokens[idx];
|
|
1217
|
-
const { title } = meta;
|
|
1218
|
-
const messages = parseChatContent(content);
|
|
1219
|
-
return `<div class="vp-chat">
|
|
1220
|
-
<div class="vp-chat-header">
|
|
1221
|
-
<p class="vp-chat-title">${title || "Chat"}</p>
|
|
1222
|
-
</div>
|
|
1223
|
-
<div class="vp-chat-content">
|
|
1224
|
-
${chatMessagesRender(md, env, messages)}
|
|
1225
|
-
</div>
|
|
1226
|
-
</div>`;
|
|
1227
|
-
};
|
|
1228
|
-
};
|
|
1229
|
-
function chatDef(state, startLine, endLine, silent) {
|
|
1230
|
-
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
1231
|
-
const max = state.eMarks[startLine];
|
|
1232
|
-
let pos = start;
|
|
1233
|
-
if (state.src.slice(pos, pos + 3) !== ":::")
|
|
1234
|
-
return false;
|
|
1235
|
-
pos += 3;
|
|
1236
|
-
const info = state.src.slice(start + 3, max).trim();
|
|
1237
|
-
if (!info.startsWith("chat"))
|
|
1238
|
-
return false;
|
|
1239
|
-
if (silent)
|
|
1240
|
-
return true;
|
|
1241
|
-
let line = startLine;
|
|
1242
|
-
let content = "";
|
|
1243
|
-
while (++line < endLine) {
|
|
1244
|
-
if (state.src.slice(state.bMarks[line], state.eMarks[line]).trim() === ":::") {
|
|
1245
|
-
break;
|
|
1246
|
-
}
|
|
1247
|
-
content += `${state.src.slice(state.bMarks[line], state.eMarks[line])}
|
|
1248
|
-
`;
|
|
1249
|
-
}
|
|
1250
|
-
const token = state.push("chat_container", "", 0);
|
|
1251
|
-
token.meta = resolveAttrs(info).attrs;
|
|
1252
|
-
token.content = content;
|
|
1253
|
-
token.markup = "::: chat";
|
|
1254
|
-
token.map = [startLine, line + 1];
|
|
1255
|
-
state.line = line + 1;
|
|
1256
|
-
return true;
|
|
1257
|
-
}
|
|
1258
1275
|
function chatMessagesRender(md, env, messages) {
|
|
1259
1276
|
let currentDate = "";
|
|
1260
1277
|
return messages.map(({ sender, username, date, content }) => {
|
|
@@ -1303,6 +1320,18 @@ function parseChatContent(content) {
|
|
|
1303
1320
|
}
|
|
1304
1321
|
return messages;
|
|
1305
1322
|
}
|
|
1323
|
+
var chatPlugin = (md) => createContainerSyntaxPlugin(
|
|
1324
|
+
md,
|
|
1325
|
+
"chat",
|
|
1326
|
+
(tokens, idx, _, env) => `<div class="vp-chat">
|
|
1327
|
+
<div class="vp-chat-header">
|
|
1328
|
+
<p class="vp-chat-title">${tokens[idx].meta?.title || "Chat"}</p>
|
|
1329
|
+
</div>
|
|
1330
|
+
<div class="vp-chat-content">
|
|
1331
|
+
${chatMessagesRender(md, env, parseChatContent(tokens[idx].content))}
|
|
1332
|
+
</div>
|
|
1333
|
+
</div>`
|
|
1334
|
+
);
|
|
1306
1335
|
|
|
1307
1336
|
// src/node/container/collapse.ts
|
|
1308
1337
|
function collapsePlugin(md) {
|
|
@@ -1311,14 +1340,14 @@ function collapsePlugin(md) {
|
|
|
1311
1340
|
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1312
1341
|
const idx = parseCollapse(tokens, index, attrs2);
|
|
1313
1342
|
const { accordion } = attrs2;
|
|
1314
|
-
return `<VPCollapse${
|
|
1343
|
+
return `<VPCollapse${stringifyAttrs({ accordion, index: idx })}>`;
|
|
1315
1344
|
},
|
|
1316
1345
|
after: () => `</VPCollapse>`
|
|
1317
1346
|
});
|
|
1318
1347
|
md.renderer.rules.collapse_item_open = (tokens, idx) => {
|
|
1319
1348
|
const token = tokens[idx];
|
|
1320
1349
|
const { expand, index } = token.meta;
|
|
1321
|
-
return `<VPCollapseItem${
|
|
1350
|
+
return `<VPCollapseItem${stringifyAttrs({ expand, index })}>`;
|
|
1322
1351
|
};
|
|
1323
1352
|
md.renderer.rules.collapse_item_close = () => "</VPCollapseItem>";
|
|
1324
1353
|
md.renderer.rules.collapse_item_title_open = () => "<template #title>";
|
|
@@ -1420,180 +1449,116 @@ function demoWrapperPlugin(md) {
|
|
|
1420
1449
|
}
|
|
1421
1450
|
|
|
1422
1451
|
// src/node/container/fileTree.ts
|
|
1423
|
-
import
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1452
|
+
import { removeEndingSlash } from "vuepress/shared";
|
|
1453
|
+
function parseFileTreeRawContent(content) {
|
|
1454
|
+
const root = { info: "", level: -1, children: [] };
|
|
1455
|
+
const stack = [root];
|
|
1456
|
+
const lines = content.trim().split("\n");
|
|
1457
|
+
for (const line of lines) {
|
|
1458
|
+
const match = line.match(/^(\s*)-(.*)$/);
|
|
1459
|
+
if (!match)
|
|
1460
|
+
continue;
|
|
1461
|
+
const level = Math.floor(match[1].length / 2);
|
|
1462
|
+
const info = match[2].trim();
|
|
1463
|
+
while (stack.length > 0 && stack[stack.length - 1].level >= level) {
|
|
1464
|
+
stack.pop();
|
|
1465
|
+
}
|
|
1466
|
+
const parent = stack[stack.length - 1];
|
|
1467
|
+
const node = { info, level, children: [] };
|
|
1468
|
+
parent.children.push(node);
|
|
1469
|
+
stack.push(node);
|
|
1470
|
+
}
|
|
1471
|
+
return root.children;
|
|
1472
|
+
}
|
|
1473
|
+
var RE_FOCUS = /^\*\*(.*)\*\*(?:$|\s+)/;
|
|
1474
|
+
function parseFileTreeNodeInfo(info) {
|
|
1475
|
+
let filename = "";
|
|
1476
|
+
let comment = "";
|
|
1477
|
+
let focus = false;
|
|
1478
|
+
let expanded = true;
|
|
1479
|
+
let type = "file";
|
|
1480
|
+
info = info.replace(RE_FOCUS, (_, matched) => {
|
|
1481
|
+
filename = matched;
|
|
1482
|
+
focus = true;
|
|
1483
|
+
return "";
|
|
1484
|
+
});
|
|
1485
|
+
if (filename === "" && !focus) {
|
|
1486
|
+
const spaceIndex = info.indexOf(" ");
|
|
1487
|
+
filename = info.slice(0, spaceIndex === -1 ? info.length : spaceIndex);
|
|
1488
|
+
info = spaceIndex === -1 ? "" : info.slice(spaceIndex);
|
|
1489
|
+
}
|
|
1490
|
+
comment = info.trim();
|
|
1491
|
+
if (filename.endsWith("/")) {
|
|
1492
|
+
type = "folder";
|
|
1493
|
+
expanded = false;
|
|
1494
|
+
filename = removeEndingSlash(filename);
|
|
1495
|
+
}
|
|
1496
|
+
return { filename, comment, focus, expanded, type };
|
|
1497
|
+
}
|
|
1431
1498
|
function fileTreePlugin(md, options = {}) {
|
|
1432
|
-
const getIcon = (filename,
|
|
1499
|
+
const getIcon = (filename, type, mode) => {
|
|
1433
1500
|
mode ||= options.icon || "colored";
|
|
1434
1501
|
if (mode === "simple")
|
|
1435
|
-
return
|
|
1436
|
-
return getFileIcon(filename,
|
|
1502
|
+
return type === "folder" ? defaultFolder : defaultFile;
|
|
1503
|
+
return getFileIcon(filename, type);
|
|
1437
1504
|
};
|
|
1438
|
-
const
|
|
1439
|
-
const {
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
const title = attrs2.title;
|
|
1468
|
-
return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ""}`;
|
|
1469
|
-
} else {
|
|
1470
|
-
return "</div>";
|
|
1471
|
-
}
|
|
1472
|
-
};
|
|
1473
|
-
md.use(container2, type, { render });
|
|
1474
|
-
}
|
|
1475
|
-
function resolveTreeNodeInfo(tokens, current, idx) {
|
|
1476
|
-
let hasInline = false;
|
|
1477
|
-
let hasChildren = false;
|
|
1478
|
-
let inline;
|
|
1479
|
-
for (let i = idx + 1; !(tokens[i].level === current.level && tokens[i].type === "list_item_close"); ++i) {
|
|
1480
|
-
if (tokens[i].type === "inline" && !hasInline) {
|
|
1481
|
-
inline = tokens[i];
|
|
1482
|
-
hasInline = true;
|
|
1483
|
-
} else if (tokens[i].tag === "ul") {
|
|
1484
|
-
hasChildren = true;
|
|
1485
|
-
}
|
|
1486
|
-
if (hasInline && hasChildren)
|
|
1487
|
-
break;
|
|
1488
|
-
}
|
|
1489
|
-
if (!hasInline)
|
|
1490
|
-
return void 0;
|
|
1491
|
-
const children = inline.children.filter((token) => token.type === "text" && token.content || token.tag === "strong");
|
|
1492
|
-
const filename = children.filter((token) => token.type === "text").map((token) => token.content).join(" ").split(/\s+/)[0];
|
|
1493
|
-
const focus = children[0]?.tag === "strong";
|
|
1494
|
-
const type2 = hasChildren || filename.endsWith("/") ? "folder" : "file";
|
|
1495
|
-
const info = {
|
|
1496
|
-
filename: removeLeadingSlash(removeEndingSlash(filename)),
|
|
1497
|
-
type: type2,
|
|
1498
|
-
focus,
|
|
1499
|
-
empty: !hasChildren,
|
|
1500
|
-
expanded: type2 === "folder" && !filename.endsWith("/")
|
|
1501
|
-
};
|
|
1502
|
-
return [info, inline];
|
|
1503
|
-
}
|
|
1504
|
-
function updateInlineToken(inline, info, icon) {
|
|
1505
|
-
const children = inline.children;
|
|
1506
|
-
const tokens = [];
|
|
1507
|
-
const wrapperOpen = new Token("span_open", "span", 1);
|
|
1508
|
-
const wrapperClose = new Token("span_close", "span", -1);
|
|
1509
|
-
wrapperOpen.attrSet("class", `tree-node ${info.type}`);
|
|
1510
|
-
tokens.push(wrapperOpen);
|
|
1511
|
-
if (info.filename !== "..." && info.filename !== "\u2026") {
|
|
1512
|
-
const iconOpen = new Token("vp_iconify_open", "VPIcon", 1);
|
|
1513
|
-
iconOpen.attrSet("name", icon);
|
|
1514
|
-
const iconClose = new Token("vp_iconify_close", "VPIcon", -1);
|
|
1515
|
-
tokens.push(iconOpen, iconClose);
|
|
1516
|
-
}
|
|
1517
|
-
const fileOpen = new Token("span_open", "span", 1);
|
|
1518
|
-
fileOpen.attrSet("class", `name${info.focus ? " focus" : ""}`);
|
|
1519
|
-
tokens.push(fileOpen);
|
|
1520
|
-
let isStrongTag = false;
|
|
1521
|
-
while (children.length) {
|
|
1522
|
-
const token = children.shift();
|
|
1523
|
-
if (token.type === "text" && token.content) {
|
|
1524
|
-
if (token.content.includes(" ")) {
|
|
1525
|
-
const [first, ...other] = token.content.split(" ");
|
|
1526
|
-
const text = new Token("text", "", 0);
|
|
1527
|
-
text.content = removeEndingSlash(first);
|
|
1528
|
-
tokens.push(text);
|
|
1529
|
-
const comment = new Token("text", "", 0);
|
|
1530
|
-
comment.content = other.join(" ");
|
|
1531
|
-
children.unshift(comment);
|
|
1532
|
-
} else {
|
|
1533
|
-
token.content = removeEndingSlash(token.content);
|
|
1534
|
-
tokens.push(token);
|
|
1535
|
-
}
|
|
1536
|
-
if (!isStrongTag)
|
|
1537
|
-
break;
|
|
1538
|
-
} else if (token.tag === "strong") {
|
|
1539
|
-
token.content = removeEndingSlash(token.content);
|
|
1540
|
-
tokens.push(token);
|
|
1541
|
-
if (token.nesting === 1) {
|
|
1542
|
-
isStrongTag = true;
|
|
1543
|
-
} else {
|
|
1544
|
-
break;
|
|
1545
|
-
}
|
|
1546
|
-
} else {
|
|
1547
|
-
tokens.push(token);
|
|
1505
|
+
const renderFileTree = (nodes, meta) => nodes.map((node) => {
|
|
1506
|
+
const { info, level, children } = node;
|
|
1507
|
+
const { filename, comment, focus, expanded, type } = parseFileTreeNodeInfo(info);
|
|
1508
|
+
const isOmit = filename === "\u2026" || filename === "...";
|
|
1509
|
+
if (children.length === 0 && type === "folder") {
|
|
1510
|
+
children.push({ info: "\u2026", level: level + 1, children: [] });
|
|
1511
|
+
}
|
|
1512
|
+
const nodeType = children.length > 0 ? "folder" : type;
|
|
1513
|
+
const renderedComment = comment ? `<template #comment>${md.renderInline(comment.replaceAll("#", "#"))}</template>` : "";
|
|
1514
|
+
const renderedIcon = !isOmit ? `<template #icon><VPIcon name="${getIcon(filename, nodeType, meta.icon)}" /></template>` : "";
|
|
1515
|
+
const props = {
|
|
1516
|
+
expanded: nodeType === "folder" ? expanded : false,
|
|
1517
|
+
focus,
|
|
1518
|
+
type: nodeType,
|
|
1519
|
+
filename
|
|
1520
|
+
};
|
|
1521
|
+
return `<FileTreeNode${stringifyAttrs(props)}>
|
|
1522
|
+
${renderedIcon}${renderedComment}${children.length > 0 ? renderFileTree(children, meta) : ""}
|
|
1523
|
+
</FileTreeNode>`;
|
|
1524
|
+
}).join("\n");
|
|
1525
|
+
return createContainerSyntaxPlugin(
|
|
1526
|
+
md,
|
|
1527
|
+
"file-tree",
|
|
1528
|
+
(tokens, index) => {
|
|
1529
|
+
const token = tokens[index];
|
|
1530
|
+
const nodes = parseFileTreeRawContent(token.content);
|
|
1531
|
+
const meta = token.meta;
|
|
1532
|
+
return `<div class="vp-file-tree">${meta.title ? `<p class="vp-file-tree-title">${meta.title}</p>` : ""}${renderFileTree(nodes, meta)}</div>
|
|
1533
|
+
`;
|
|
1548
1534
|
}
|
|
1549
|
-
|
|
1550
|
-
const fileClose = new Token("span_close", "span", -1);
|
|
1551
|
-
tokens.push(fileClose);
|
|
1552
|
-
if (children.filter((token) => token.type === "text" && token.content.trim()).length) {
|
|
1553
|
-
const commentOpen = new Token("span_open", "span", 1);
|
|
1554
|
-
commentOpen.attrSet("class", "comment");
|
|
1555
|
-
const commentClose = new Token("span_close", "span", -1);
|
|
1556
|
-
tokens.push(commentOpen, ...children, commentClose);
|
|
1557
|
-
}
|
|
1558
|
-
tokens.push(wrapperClose);
|
|
1559
|
-
inline.children = tokens;
|
|
1535
|
+
);
|
|
1560
1536
|
}
|
|
1561
1537
|
|
|
1562
1538
|
// src/node/container/langRepl.ts
|
|
1563
1539
|
import { promises as fs2 } from "node:fs";
|
|
1564
1540
|
import { resolveModule } from "local-pkg";
|
|
1565
|
-
import container3 from "markdown-it-container";
|
|
1566
1541
|
import { colors, logger as logger2, path as path2 } from "vuepress/utils";
|
|
1567
|
-
var RE_INFO = /^(#editable)?(.*)$/;
|
|
1568
|
-
function createReplContainer(md, lang) {
|
|
1569
|
-
const type2 = `${lang}-repl`;
|
|
1570
|
-
const validate = (info) => info.trim().startsWith(type2);
|
|
1571
|
-
const render = (tokens, index) => {
|
|
1572
|
-
const token = tokens[index];
|
|
1573
|
-
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
1574
|
-
const [, editable, title] = info.match(RE_INFO);
|
|
1575
|
-
if (token.nesting === 1)
|
|
1576
|
-
return `<CodeRepl ${editable ? "editable" : ""} title="${title || `${lang} playground`}">`;
|
|
1577
|
-
else
|
|
1578
|
-
return "</CodeRepl>";
|
|
1579
|
-
};
|
|
1580
|
-
md.use(container3, type2, { validate, render });
|
|
1581
|
-
}
|
|
1582
1542
|
async function langReplPlugin(app, md, {
|
|
1583
1543
|
theme,
|
|
1584
1544
|
go = false,
|
|
1585
1545
|
kotlin = false,
|
|
1586
1546
|
rust = false
|
|
1587
1547
|
}) {
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1548
|
+
const container3 = (lang) => createContainerPlugin(md, `${lang}-repl`, {
|
|
1549
|
+
before(info) {
|
|
1550
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1551
|
+
const { editable, title } = attrs2;
|
|
1552
|
+
return `<CodeRepl${stringifyAttrs({ editable, title: title || `${lang} playground` })}>`;
|
|
1553
|
+
},
|
|
1554
|
+
after: () => "</CodeRepl>"
|
|
1555
|
+
});
|
|
1556
|
+
if (kotlin)
|
|
1557
|
+
container3("kotlin");
|
|
1558
|
+
if (go)
|
|
1559
|
+
container3("go");
|
|
1560
|
+
if (rust)
|
|
1561
|
+
container3("rust");
|
|
1597
1562
|
theme ??= { light: "github-light", dark: "github-dark" };
|
|
1598
1563
|
const data = { grammars: {} };
|
|
1599
1564
|
try {
|
|
@@ -1634,7 +1599,9 @@ async function read(file) {
|
|
|
1634
1599
|
|
|
1635
1600
|
// src/node/container/npmTo.ts
|
|
1636
1601
|
import { isArray } from "@vuepress/helper";
|
|
1637
|
-
import
|
|
1602
|
+
import { colors as colors2 } from "vuepress/utils";
|
|
1603
|
+
|
|
1604
|
+
// src/node/container/npmToPreset.ts
|
|
1638
1605
|
var ALLOW_LIST = ["npm", "pnpm", "yarn", "bun", "deno"];
|
|
1639
1606
|
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"];
|
|
1640
1607
|
var DEFAULT_TABS = ["npm", "pnpm", "yarn"];
|
|
@@ -1818,28 +1785,32 @@ var MANAGERS_CONFIG = {
|
|
|
1818
1785
|
deno: { cli: "deno install --frozen" }
|
|
1819
1786
|
}
|
|
1820
1787
|
};
|
|
1788
|
+
|
|
1789
|
+
// src/node/container/npmTo.ts
|
|
1821
1790
|
function npmToPlugins(md, options = {}) {
|
|
1822
|
-
const type2 = "npm-to";
|
|
1823
1791
|
const opt = isArray(options) ? { tabs: options } : options;
|
|
1824
1792
|
const defaultTabs = opt.tabs?.length ? opt.tabs : DEFAULT_TABS;
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1793
|
+
createContainerPlugin(md, "npm-to", {
|
|
1794
|
+
before: (info, tokens, idx, _opt, env) => {
|
|
1795
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1796
|
+
const tabs2 = attrs2.tabs ? attrs2.tabs.split(/,\s*/) : defaultTabs;
|
|
1829
1797
|
const token = tokens[idx + 1];
|
|
1830
|
-
const info = token.info.trim();
|
|
1831
1798
|
if (token.type === "fence") {
|
|
1832
1799
|
const content = token.content;
|
|
1833
1800
|
token.hidden = true;
|
|
1834
1801
|
token.type = "text";
|
|
1835
1802
|
token.content = "";
|
|
1836
1803
|
const lines = content.split(/(\n|\s*&&\s*)/);
|
|
1837
|
-
return md.render(
|
|
1804
|
+
return md.render(
|
|
1805
|
+
resolveNpmTo(lines, token.info.trim(), idx, tabs2),
|
|
1806
|
+
cleanMarkdownEnv(env)
|
|
1807
|
+
);
|
|
1838
1808
|
}
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1809
|
+
console.warn(`${colors2.yellow("[vuepress-plugin-md-power]")} Invalid npm-to container in ${colors2.gray(env.filePathRelative || env.filePath)}`);
|
|
1810
|
+
return "";
|
|
1811
|
+
},
|
|
1812
|
+
after: () => ""
|
|
1813
|
+
});
|
|
1843
1814
|
}
|
|
1844
1815
|
function resolveNpmTo(lines, info, idx, tabs2) {
|
|
1845
1816
|
tabs2 = validateTabs(tabs2);
|
|
@@ -2017,15 +1988,17 @@ function timelinePlugin(md) {
|
|
|
2017
1988
|
before(info, tokens, index) {
|
|
2018
1989
|
parseTimeline(tokens, index);
|
|
2019
1990
|
const { attrs: attrs2 } = resolveAttrs(info);
|
|
2020
|
-
|
|
2021
|
-
return `<VPTimeline${
|
|
1991
|
+
attrs2.card ??= void 0;
|
|
1992
|
+
return `<VPTimeline${stringifyAttrs(attrs2, true)}>`;
|
|
2022
1993
|
},
|
|
2023
1994
|
after: () => "</VPTimeline>"
|
|
2024
1995
|
});
|
|
2025
1996
|
md.renderer.rules.timeline_item_open = (tokens, idx) => {
|
|
2026
1997
|
const token = tokens[idx];
|
|
2027
|
-
const
|
|
2028
|
-
|
|
1998
|
+
const attrs2 = token.meta;
|
|
1999
|
+
attrs2.card ??= void 0;
|
|
2000
|
+
const icon = attrs2.icon;
|
|
2001
|
+
return `<VPTimelineItem${stringifyAttrs(attrs2, true)}>${icon ? `<template #icon><VPIcon name="${icon}"/></template>` : ""}`;
|
|
2029
2002
|
};
|
|
2030
2003
|
md.renderer.rules.timeline_item_close = () => "</VPTimelineItem>";
|
|
2031
2004
|
md.renderer.rules.timeline_item_title_open = () => "<template #title>";
|
|
@@ -2125,20 +2098,20 @@ async function containerPlugin(app, md, options) {
|
|
|
2125
2098
|
}
|
|
2126
2099
|
|
|
2127
2100
|
// src/node/demo/demo.ts
|
|
2128
|
-
import
|
|
2101
|
+
import container2 from "markdown-it-container";
|
|
2129
2102
|
|
|
2130
2103
|
// src/node/embed/createEmbedRuleBlock.ts
|
|
2131
2104
|
function createEmbedRuleBlock(md, {
|
|
2132
|
-
type
|
|
2133
|
-
name =
|
|
2105
|
+
type,
|
|
2106
|
+
name = type,
|
|
2134
2107
|
syntaxPattern,
|
|
2135
2108
|
beforeName = "import_code",
|
|
2136
2109
|
ruleOptions = { alt: ["paragraph", "reference", "blockquote", "list"] },
|
|
2137
2110
|
meta,
|
|
2138
2111
|
content
|
|
2139
2112
|
}) {
|
|
2140
|
-
const MIN_LENGTH =
|
|
2141
|
-
const START_CODES = [64, 91, ...
|
|
2113
|
+
const MIN_LENGTH = type.length + 5;
|
|
2114
|
+
const START_CODES = [64, 91, ...type.split("").map((c) => c.charCodeAt(0))];
|
|
2142
2115
|
md.block.ruler.before(
|
|
2143
2116
|
beforeName,
|
|
2144
2117
|
name,
|
|
@@ -2219,7 +2192,7 @@ function markdownEmbed(app, md, env, { url, title, desc, codeSetting = "", expan
|
|
|
2219
2192
|
if (!env.demoFiles.some((d) => d.path === filepath2)) {
|
|
2220
2193
|
env.demoFiles.push(demo);
|
|
2221
2194
|
}
|
|
2222
|
-
return `<VPDemoBasic
|
|
2195
|
+
return `<VPDemoBasic${stringifyAttrs({ type: "markdown", title, desc, expanded })}>
|
|
2223
2196
|
${md.render(code, { filepath: env.filePath, filepathRelative: env.filePathRelative })}
|
|
2224
2197
|
<template #code>
|
|
2225
2198
|
${md.render(`\`\`\`md ${codeSetting}
|
|
@@ -2232,7 +2205,7 @@ var markdownContainerRender = {
|
|
|
2232
2205
|
before(app, md, env, meta, codeMap) {
|
|
2233
2206
|
const { title, desc, expanded = false } = meta;
|
|
2234
2207
|
const code = codeMap.md || "";
|
|
2235
|
-
return `<VPDemoBasic
|
|
2208
|
+
return `<VPDemoBasic${stringifyAttrs({ type: "markdown", title, desc, expanded })}>
|
|
2236
2209
|
${md.render(code, { filepath: env.filePath, filepathRelative: env.filePathRelative })}
|
|
2237
2210
|
<template #code>`;
|
|
2238
2211
|
},
|
|
@@ -2269,8 +2242,8 @@ var compiler = {
|
|
|
2269
2242
|
}),
|
|
2270
2243
|
stylus: importer(() => import("stylus"))
|
|
2271
2244
|
};
|
|
2272
|
-
async function compileScript(source,
|
|
2273
|
-
const key = `${
|
|
2245
|
+
async function compileScript(source, type) {
|
|
2246
|
+
const key = `${type}:::${source}`;
|
|
2274
2247
|
if (cache2.has(key))
|
|
2275
2248
|
return cache2.get(key);
|
|
2276
2249
|
const transform = await compiler.script();
|
|
@@ -2278,31 +2251,31 @@ async function compileScript(source, type2) {
|
|
|
2278
2251
|
target: "es2018",
|
|
2279
2252
|
platform: "browser",
|
|
2280
2253
|
format: "cjs",
|
|
2281
|
-
loader:
|
|
2254
|
+
loader: type === "ts" ? "ts" : "js",
|
|
2282
2255
|
sourcemap: false
|
|
2283
2256
|
});
|
|
2284
2257
|
cache2.set(key, res.code);
|
|
2285
2258
|
return res.code;
|
|
2286
2259
|
}
|
|
2287
|
-
async function compileStyle(source,
|
|
2288
|
-
const key = `${
|
|
2260
|
+
async function compileStyle(source, type) {
|
|
2261
|
+
const key = `${type}:::${source}`;
|
|
2289
2262
|
if (cache2.has(key))
|
|
2290
2263
|
return cache2.get(key);
|
|
2291
|
-
if (
|
|
2264
|
+
if (type === "css")
|
|
2292
2265
|
return source;
|
|
2293
|
-
if (
|
|
2266
|
+
if (type === "less") {
|
|
2294
2267
|
const less = await compiler.less();
|
|
2295
2268
|
const res = await less.render(source);
|
|
2296
2269
|
cache2.set(key, res.css);
|
|
2297
2270
|
return res.css;
|
|
2298
2271
|
}
|
|
2299
|
-
if (
|
|
2272
|
+
if (type === "scss") {
|
|
2300
2273
|
const sass = await compiler.sass();
|
|
2301
2274
|
const res = sass.compileString(source);
|
|
2302
2275
|
cache2.set(key, res.css);
|
|
2303
2276
|
return res.css;
|
|
2304
2277
|
}
|
|
2305
|
-
if (
|
|
2278
|
+
if (type === "stylus") {
|
|
2306
2279
|
const stylus = await compiler.stylus();
|
|
2307
2280
|
const res = stylus.render(source);
|
|
2308
2281
|
cache2.set(key, res);
|
|
@@ -2520,7 +2493,7 @@ function normalEmbed(app, md, env, { url, title, desc, codeSetting = "", expande
|
|
|
2520
2493
|
env.demoFiles.push(demo);
|
|
2521
2494
|
insertSetupScript({ ...demo, path: output }, env);
|
|
2522
2495
|
}
|
|
2523
|
-
return `<VPDemoNormal
|
|
2496
|
+
return `<VPDemoNormal${stringifyAttrs({ ":config": name, title, desc, expanded })}>
|
|
2524
2497
|
${codeToHtml(md, source, codeSetting)}
|
|
2525
2498
|
</VPDemoNormal>`;
|
|
2526
2499
|
}
|
|
@@ -2538,7 +2511,7 @@ var normalContainerRender = {
|
|
|
2538
2511
|
}
|
|
2539
2512
|
const source = parseContainerCode(codeMap);
|
|
2540
2513
|
compileCode(source, output);
|
|
2541
|
-
return `<VPDemoNormal
|
|
2514
|
+
return `<VPDemoNormal${stringifyAttrs({ ":config": name, title, desc, expanded })}>`;
|
|
2542
2515
|
},
|
|
2543
2516
|
after: () => "</VPDemoNormal>",
|
|
2544
2517
|
token(token) {
|
|
@@ -2624,7 +2597,7 @@ function vueEmbed(app, md, env, { url, title, desc, codeSetting = "", expanded =
|
|
|
2624
2597
|
env.demoFiles.push(demo);
|
|
2625
2598
|
insertSetupScript(demo, env);
|
|
2626
2599
|
}
|
|
2627
|
-
return `<VPDemoBasic
|
|
2600
|
+
return `<VPDemoBasic${stringifyAttrs({ type: "vue", title, desc, expanded })}>
|
|
2628
2601
|
<${name} />
|
|
2629
2602
|
<template #code>
|
|
2630
2603
|
${md.render(`\`\`\`${ext}${codeSetting}
|
|
@@ -2637,10 +2610,10 @@ var target3 = "md-power/demo/vue";
|
|
|
2637
2610
|
var vueContainerRender = {
|
|
2638
2611
|
before: (app, md, env, meta, codeMap) => {
|
|
2639
2612
|
const { url, title, desc, expanded = false } = meta;
|
|
2640
|
-
const
|
|
2613
|
+
const componentName = `DemoContainer${url}`;
|
|
2641
2614
|
const prefix = (env.filePathRelative || "").replace(/\.md$/, "").replace(/\//g, "-");
|
|
2642
2615
|
env.demoFiles ??= [];
|
|
2643
|
-
const output = app.dir.temp(path6.join(target3, `${prefix}-${
|
|
2616
|
+
const output = app.dir.temp(path6.join(target3, `${prefix}-${componentName}`));
|
|
2644
2617
|
if (codeMap.vue || codeMap.js || codeMap.ts) {
|
|
2645
2618
|
let scriptOutput = output;
|
|
2646
2619
|
let content = "";
|
|
@@ -2655,7 +2628,7 @@ var vueContainerRender = {
|
|
|
2655
2628
|
content = codeMap.js;
|
|
2656
2629
|
}
|
|
2657
2630
|
content = transformImports(content, env.filePath || "");
|
|
2658
|
-
const script = { type: "vue", export:
|
|
2631
|
+
const script = { type: "vue", export: componentName, path: scriptOutput, gitignore: true };
|
|
2659
2632
|
writeFileSync(scriptOutput, content);
|
|
2660
2633
|
if (!env.demoFiles.some((d) => d.path === scriptOutput)) {
|
|
2661
2634
|
env.demoFiles.push(script);
|
|
@@ -2685,8 +2658,8 @@ var vueContainerRender = {
|
|
|
2685
2658
|
insertSetupScript(style, env);
|
|
2686
2659
|
}
|
|
2687
2660
|
}
|
|
2688
|
-
return `<VPDemoBasic
|
|
2689
|
-
<${
|
|
2661
|
+
return `<VPDemoBasic${stringifyAttrs({ type: "vue", title, desc, expanded })}>
|
|
2662
|
+
<${componentName} />
|
|
2690
2663
|
<template #code>
|
|
2691
2664
|
`;
|
|
2692
2665
|
},
|
|
@@ -2716,24 +2689,24 @@ function demoEmbed(app, md) {
|
|
|
2716
2689
|
createEmbedRuleBlock(md, {
|
|
2717
2690
|
type: "demo",
|
|
2718
2691
|
syntaxPattern: /^@\[demo(?:\s(vue|normal|markdown))?\s?(.*)\]\((.*)\)/,
|
|
2719
|
-
meta: ([,
|
|
2720
|
-
type:
|
|
2692
|
+
meta: ([, type, info, url]) => ({
|
|
2693
|
+
type: type || "normal",
|
|
2721
2694
|
url,
|
|
2722
2695
|
...resolveAttrs(info).attrs
|
|
2723
2696
|
}),
|
|
2724
2697
|
content: (meta, content, env) => {
|
|
2725
|
-
const { url, type
|
|
2698
|
+
const { url, type } = meta;
|
|
2726
2699
|
if (!url) {
|
|
2727
2700
|
console.warn("[vuepress-plugin-md-power] Invalid demo url: ", url);
|
|
2728
2701
|
return content;
|
|
2729
2702
|
}
|
|
2730
|
-
if (
|
|
2703
|
+
if (type === "vue") {
|
|
2731
2704
|
return vueEmbed(app, md, env, meta);
|
|
2732
2705
|
}
|
|
2733
|
-
if (
|
|
2706
|
+
if (type === "normal") {
|
|
2734
2707
|
return normalEmbed(app, md, env, meta);
|
|
2735
2708
|
}
|
|
2736
|
-
if (
|
|
2709
|
+
if (type === "markdown") {
|
|
2737
2710
|
return markdownEmbed(app, md, env, meta);
|
|
2738
2711
|
}
|
|
2739
2712
|
return content;
|
|
@@ -2767,7 +2740,7 @@ function demoContainer(app, md) {
|
|
|
2767
2740
|
return res;
|
|
2768
2741
|
}
|
|
2769
2742
|
};
|
|
2770
|
-
md.use(
|
|
2743
|
+
md.use(container2, "demo", { render });
|
|
2771
2744
|
}
|
|
2772
2745
|
function parseCodeMapping(tokens, index, cb) {
|
|
2773
2746
|
const codeMap = {};
|
|
@@ -2781,11 +2754,11 @@ function parseCodeMapping(tokens, index, cb) {
|
|
|
2781
2754
|
return codeMap;
|
|
2782
2755
|
}
|
|
2783
2756
|
function getContainerMeta(info) {
|
|
2784
|
-
const [,
|
|
2757
|
+
const [, type, raw] = (info.trim().slice(4).trim() || "").match(INFO_RE) || [];
|
|
2785
2758
|
const { attrs: attrs2 } = resolveAttrs(raw);
|
|
2786
2759
|
return {
|
|
2787
2760
|
url: "",
|
|
2788
|
-
type:
|
|
2761
|
+
type: type || "normal",
|
|
2789
2762
|
...attrs2
|
|
2790
2763
|
};
|
|
2791
2764
|
}
|
|
@@ -2795,7 +2768,7 @@ function extendsPageWithDemo(page) {
|
|
|
2795
2768
|
const markdownEnv = page.markdownEnv;
|
|
2796
2769
|
const demoFiles = markdownEnv.demoFiles ?? [];
|
|
2797
2770
|
page.deps.push(
|
|
2798
|
-
...demoFiles.filter(({ type
|
|
2771
|
+
...demoFiles.filter(({ type }) => type === "markdown").map(({ path: path9 }) => path9)
|
|
2799
2772
|
);
|
|
2800
2773
|
(page.frontmatter.gitInclude ??= []).push(
|
|
2801
2774
|
...demoFiles.filter(({ gitignore }) => !gitignore).map(({ path: path9 }) => path9)
|
|
@@ -2849,29 +2822,27 @@ var audioReader = (state, silent) => {
|
|
|
2849
2822
|
state.posMax = labelEnd;
|
|
2850
2823
|
const info = state.src.slice(labelStart, labelEnd).trim();
|
|
2851
2824
|
const { attrs: attrs2 } = resolveAttrs(info);
|
|
2852
|
-
const
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
if (attrs2.startTime)
|
|
2856
|
-
tokenOpen.attrs.push([":start-time", attrs2.startTime]);
|
|
2857
|
-
if (attrs2.endTime)
|
|
2858
|
-
tokenOpen.attrs.push([":end-time", attrs2.endTime]);
|
|
2859
|
-
if (attrs2.type)
|
|
2860
|
-
tokenOpen.attrs.push(["type", attrs2.type]);
|
|
2861
|
-
if (attrs2.volume)
|
|
2862
|
-
tokenOpen.attrs.push([":volume", attrs2.volume]);
|
|
2863
|
-
if (attrs2.title)
|
|
2864
|
-
state.push("text", "", 0).content = attrs2.title;
|
|
2865
|
-
state.push("audio_reader_close", "AudioReader", -1);
|
|
2825
|
+
const token = state.push("audio_reader", "AudioReader", 0);
|
|
2826
|
+
token.info = info;
|
|
2827
|
+
token.meta = { src: href, ...attrs2 };
|
|
2866
2828
|
}
|
|
2867
2829
|
state.pos = pos + 1;
|
|
2868
2830
|
state.posMax = max;
|
|
2869
2831
|
return true;
|
|
2870
2832
|
};
|
|
2871
|
-
var audioReaderPlugin = (md) =>
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2833
|
+
var audioReaderPlugin = (md) => {
|
|
2834
|
+
md.renderer.rules.audio_reader = (tokens, idx) => {
|
|
2835
|
+
const meta = tokens[idx].meta ?? {};
|
|
2836
|
+
if (meta.startTime)
|
|
2837
|
+
meta.startTime = Number(meta.startTime);
|
|
2838
|
+
if (meta.endTime)
|
|
2839
|
+
meta.endTime = Number(meta.endTime);
|
|
2840
|
+
if (meta.volume)
|
|
2841
|
+
meta.volume = Number(meta.volume);
|
|
2842
|
+
return `<AudioReader${stringifyAttrs(meta)} />`;
|
|
2843
|
+
};
|
|
2844
|
+
md.inline.ruler.before("link", "audio-reader", audioReader);
|
|
2845
|
+
};
|
|
2875
2846
|
|
|
2876
2847
|
// src/node/utils/nanoid.ts
|
|
2877
2848
|
import { customAlphabet } from "nanoid";
|
|
@@ -2895,23 +2866,14 @@ function legacyCaniuse(md, { mode = "embed" } = {}) {
|
|
|
2895
2866
|
const modeMap = ["image", "embed"];
|
|
2896
2867
|
const isMode = (mode2) => modeMap.includes(mode2);
|
|
2897
2868
|
mode = isMode(mode) ? mode : modeMap[0];
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
const validate = (info) => {
|
|
2901
|
-
return validateReg.test(info.trim());
|
|
2902
|
-
};
|
|
2903
|
-
const render = (tokens, index) => {
|
|
2904
|
-
const token = tokens[index];
|
|
2905
|
-
if (token.nesting === 1) {
|
|
2906
|
-
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
2869
|
+
createContainerPlugin(md, "caniuse", {
|
|
2870
|
+
before: (info) => {
|
|
2907
2871
|
const feature = info.split(/\s+/)[0];
|
|
2908
2872
|
const versions = info.match(/\{(.*)\}/)?.[1] || "";
|
|
2909
2873
|
return feature ? resolveCanIUse({ feature, mode, versions }) : "";
|
|
2910
|
-
}
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
};
|
|
2914
|
-
md.use(container6, type2, { validate, render });
|
|
2874
|
+
},
|
|
2875
|
+
after: () => ""
|
|
2876
|
+
});
|
|
2915
2877
|
}
|
|
2916
2878
|
function resolveCanIUse({ feature, mode, versions }) {
|
|
2917
2879
|
if (!feature)
|
|
@@ -2928,7 +2890,7 @@ function resolveCanIUse({ feature, mode, versions }) {
|
|
|
2928
2890
|
feature = feature.replace(UNDERLINE_RE, "_");
|
|
2929
2891
|
const { past, future } = resolveVersions(versions);
|
|
2930
2892
|
const meta = nanoid();
|
|
2931
|
-
return `<CanIUseViewer
|
|
2893
|
+
return `<CanIUseViewer${stringifyAttrs({ feature, meta, past, future })} />`;
|
|
2932
2894
|
}
|
|
2933
2895
|
function resolveVersions(versions) {
|
|
2934
2896
|
if (!versions)
|
|
@@ -2955,19 +2917,21 @@ var codepenPlugin = (md) => {
|
|
|
2955
2917
|
type: "codepen",
|
|
2956
2918
|
syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
|
|
2957
2919
|
meta: ([, info, source]) => {
|
|
2958
|
-
const { width, height, title, tab: tab3,
|
|
2920
|
+
const { width, height, title, tab: tab3, preview, editable, theme } = resolveAttrs(info).attrs;
|
|
2959
2921
|
const [user, slash] = source.split("/");
|
|
2960
2922
|
return {
|
|
2923
|
+
title: title || "Code Pen",
|
|
2924
|
+
tab: tab3 || "result",
|
|
2961
2925
|
width: width ? parseRect(width) : "100%",
|
|
2962
2926
|
height: height ? parseRect(height) : "400px",
|
|
2963
2927
|
user,
|
|
2964
2928
|
slash,
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2929
|
+
preview,
|
|
2930
|
+
editable,
|
|
2931
|
+
theme
|
|
2968
2932
|
};
|
|
2969
2933
|
},
|
|
2970
|
-
content: (
|
|
2934
|
+
content: (meta) => `<CodePenViewer${stringifyAttrs(meta)} />`
|
|
2971
2935
|
});
|
|
2972
2936
|
};
|
|
2973
2937
|
|
|
@@ -2976,7 +2940,7 @@ var codeSandboxPlugin = (md) => {
|
|
|
2976
2940
|
createEmbedRuleBlock(md, {
|
|
2977
2941
|
type: "codesandbox",
|
|
2978
2942
|
syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
|
|
2979
|
-
meta([,
|
|
2943
|
+
meta([, type, info, source]) {
|
|
2980
2944
|
const { attrs: attrs2 } = resolveAttrs(info);
|
|
2981
2945
|
const [profile, filepath2 = ""] = source.split("#");
|
|
2982
2946
|
const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
|
|
@@ -2989,13 +2953,11 @@ var codeSandboxPlugin = (md) => {
|
|
|
2989
2953
|
console: attrs2.console ?? false,
|
|
2990
2954
|
navbar: attrs2.navbar ?? true,
|
|
2991
2955
|
layout: attrs2.layout ?? "",
|
|
2992
|
-
type:
|
|
2956
|
+
type: type || "embed",
|
|
2993
2957
|
filepath: filepath2
|
|
2994
2958
|
};
|
|
2995
2959
|
},
|
|
2996
|
-
content
|
|
2997
|
-
return `<CodeSandboxViewer title="${title}" height="${height}" width="${width}" user="${user}" id="${id}" type="${type2}" filepath="${filepath2}" :console=${console2} :navbar=${navbar} layout="${layout}" />`;
|
|
2998
|
-
}
|
|
2960
|
+
content: (meta) => `<CodeSandboxViewer${stringifyAttrs(meta)} />`
|
|
2999
2961
|
});
|
|
3000
2962
|
};
|
|
3001
2963
|
|
|
@@ -3015,7 +2977,7 @@ var jsfiddlePlugin = (md) => {
|
|
|
3015
2977
|
theme
|
|
3016
2978
|
};
|
|
3017
2979
|
},
|
|
3018
|
-
content: (
|
|
2980
|
+
content: (meta) => `<JSFiddleViewer${stringifyAttrs(meta)} />`
|
|
3019
2981
|
});
|
|
3020
2982
|
};
|
|
3021
2983
|
|
|
@@ -3034,9 +2996,7 @@ var replitPlugin = (md) => {
|
|
|
3034
2996
|
theme: attrs2.theme || ""
|
|
3035
2997
|
};
|
|
3036
2998
|
},
|
|
3037
|
-
content(
|
|
3038
|
-
return `<ReplitViewer title="${title || ""}" height="${height}" width="${width}" source="${source}" theme="${theme}" />`;
|
|
3039
|
-
}
|
|
2999
|
+
content: (meta) => `<ReplitViewer${stringifyAttrs(meta)} />`
|
|
3040
3000
|
});
|
|
3041
3001
|
};
|
|
3042
3002
|
|
|
@@ -3060,15 +3020,13 @@ var pdfPlugin = (md) => {
|
|
|
3060
3020
|
title: path7.basename(src || "")
|
|
3061
3021
|
};
|
|
3062
3022
|
},
|
|
3063
|
-
content(
|
|
3064
|
-
return `<PDFViewer src="${src}" title="${title}" :page="${page}" :no-toolbar="${noToolbar}" width="${width}" height="${height}" ratio="${ratio}" :zoom="${zoom}" />`;
|
|
3065
|
-
}
|
|
3023
|
+
content: (meta) => `<PDFViewer${stringifyAttrs(meta)} />`
|
|
3066
3024
|
});
|
|
3067
3025
|
};
|
|
3068
3026
|
|
|
3069
3027
|
// src/node/embed/video/artPlayer.ts
|
|
3070
3028
|
import { isPackageExists as isPackageExists2 } from "local-pkg";
|
|
3071
|
-
import { colors as
|
|
3029
|
+
import { colors as colors3 } from "vuepress/utils";
|
|
3072
3030
|
var installed = {
|
|
3073
3031
|
dashjs: isPackageExists2("dashjs"),
|
|
3074
3032
|
hlsjs: isPackageExists2("hls.js"),
|
|
@@ -3085,6 +3043,8 @@ var artPlayerPlugin = (md) => {
|
|
|
3085
3043
|
const url = source.trim();
|
|
3086
3044
|
checkSupportType(attrs2.type ?? url.split(".").pop());
|
|
3087
3045
|
return {
|
|
3046
|
+
url,
|
|
3047
|
+
type: attrs2.type,
|
|
3088
3048
|
autoplay: attrs2.autoplay ?? false,
|
|
3089
3049
|
muted: attrs2.muted ?? attrs2.autoplay ?? false,
|
|
3090
3050
|
autoMini: attrs2.autoMini ?? false,
|
|
@@ -3092,23 +3052,22 @@ var artPlayerPlugin = (md) => {
|
|
|
3092
3052
|
volume: typeof attrs2.volume !== "undefined" ? Number(attrs2.volume) : 0.75,
|
|
3093
3053
|
poster: attrs2.poster,
|
|
3094
3054
|
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
3095
|
-
height: attrs2.height ? parseRect(attrs2.height) :
|
|
3096
|
-
ratio: attrs2.ratio ? parseRect(`${attrs2.ratio}`) :
|
|
3097
|
-
type: attrs2.type,
|
|
3098
|
-
url
|
|
3055
|
+
height: attrs2.height ? parseRect(attrs2.height) : void 0,
|
|
3056
|
+
ratio: attrs2.ratio ? parseRect(`${attrs2.ratio}`) : void 0
|
|
3099
3057
|
};
|
|
3100
3058
|
},
|
|
3101
|
-
content({
|
|
3102
|
-
|
|
3059
|
+
content({ url, ...meta }) {
|
|
3060
|
+
meta.muted = meta.muted || meta.autoplay;
|
|
3061
|
+
return `<ArtPlayer src="${url}" fullscreen flip playback-rate aspect-ratio setting pip${stringifyAttrs(meta)}/>`;
|
|
3103
3062
|
}
|
|
3104
3063
|
});
|
|
3105
3064
|
};
|
|
3106
|
-
function checkSupportType(
|
|
3107
|
-
if (!
|
|
3065
|
+
function checkSupportType(type) {
|
|
3066
|
+
if (!type)
|
|
3108
3067
|
return;
|
|
3109
|
-
if (SUPPORTED_VIDEO_TYPES.includes(
|
|
3068
|
+
if (SUPPORTED_VIDEO_TYPES.includes(type)) {
|
|
3110
3069
|
let name = "";
|
|
3111
|
-
switch (
|
|
3070
|
+
switch (type.toLowerCase()) {
|
|
3112
3071
|
case "m3u8":
|
|
3113
3072
|
case "hls":
|
|
3114
3073
|
name = !installed.hlsjs ? "hls.js" : "";
|
|
@@ -3124,10 +3083,10 @@ function checkSupportType(type2) {
|
|
|
3124
3083
|
break;
|
|
3125
3084
|
}
|
|
3126
3085
|
if (name) {
|
|
3127
|
-
console.warn(`${
|
|
3086
|
+
console.warn(`${colors3.yellow("[vuepress-plugin-md-power] artPlayer: ")} ${colors3.cyan(name)} is not installed, please install it via npm or yarn or pnpm`);
|
|
3128
3087
|
}
|
|
3129
3088
|
} else {
|
|
3130
|
-
console.warn(`${
|
|
3089
|
+
console.warn(`${colors3.yellow("[vuepress-plugin-md-power] artPlayer: ")} unsupported video type: ${colors3.cyan(type)}`);
|
|
3131
3090
|
}
|
|
3132
3091
|
}
|
|
3133
3092
|
|
|
@@ -3166,31 +3125,27 @@ var bilibiliPlugin = (md) => {
|
|
|
3166
3125
|
time: timeToSeconds(attrs2.time),
|
|
3167
3126
|
title: attrs2.title,
|
|
3168
3127
|
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
3169
|
-
height: attrs2.height ? parseRect(attrs2.height) :
|
|
3170
|
-
ratio: attrs2.ratio ? parseRect(attrs2.ratio) :
|
|
3128
|
+
height: attrs2.height ? parseRect(attrs2.height) : void 0,
|
|
3129
|
+
ratio: attrs2.ratio ? parseRect(attrs2.ratio) : void 0
|
|
3171
3130
|
};
|
|
3172
3131
|
},
|
|
3173
3132
|
content(meta) {
|
|
3174
3133
|
const params = new URLSearchParams();
|
|
3175
|
-
if (meta.bvid)
|
|
3134
|
+
if (meta.bvid)
|
|
3176
3135
|
params.set("bvid", meta.bvid);
|
|
3177
|
-
|
|
3178
|
-
if (meta.aid) {
|
|
3136
|
+
if (meta.aid)
|
|
3179
3137
|
params.set("aid", meta.aid);
|
|
3180
|
-
|
|
3181
|
-
if (meta.cid) {
|
|
3138
|
+
if (meta.cid)
|
|
3182
3139
|
params.set("cid", meta.cid);
|
|
3183
|
-
|
|
3184
|
-
if (meta.page) {
|
|
3140
|
+
if (meta.page)
|
|
3185
3141
|
params.set("p", meta.page.toString());
|
|
3186
|
-
|
|
3187
|
-
if (meta.time) {
|
|
3142
|
+
if (meta.time)
|
|
3188
3143
|
params.set("t", meta.time.toString());
|
|
3189
|
-
}
|
|
3190
3144
|
params.set("autoplay", meta.autoplay ? "1" : "0");
|
|
3191
3145
|
params.set("high_quality", "1");
|
|
3192
3146
|
const source = `${BILIBILI_LINK}?${params.toString()}`;
|
|
3193
|
-
|
|
3147
|
+
const { width, height, ratio, title } = meta;
|
|
3148
|
+
return `<VideoBilibili${stringifyAttrs({ src: source, width, height, ratio, title })} />`;
|
|
3194
3149
|
}
|
|
3195
3150
|
});
|
|
3196
3151
|
};
|
|
@@ -3213,26 +3168,23 @@ var youtubePlugin = (md) => {
|
|
|
3213
3168
|
end: timeToSeconds(attrs2.end),
|
|
3214
3169
|
title: attrs2.title,
|
|
3215
3170
|
width: attrs2.width ? parseRect(attrs2.width) : "100%",
|
|
3216
|
-
height: attrs2.height ? parseRect(attrs2.height) :
|
|
3217
|
-
ratio: attrs2.ratio ? parseRect(attrs2.ratio) :
|
|
3171
|
+
height: attrs2.height ? parseRect(attrs2.height) : void 0,
|
|
3172
|
+
ratio: attrs2.ratio ? parseRect(attrs2.ratio) : void 0
|
|
3218
3173
|
};
|
|
3219
3174
|
},
|
|
3220
3175
|
content(meta) {
|
|
3221
3176
|
const params = new URLSearchParams2();
|
|
3222
|
-
if (meta.autoplay)
|
|
3177
|
+
if (meta.autoplay)
|
|
3223
3178
|
params.set("autoplay", "1");
|
|
3224
|
-
|
|
3225
|
-
if (meta.loop) {
|
|
3179
|
+
if (meta.loop)
|
|
3226
3180
|
params.set("loop", "1");
|
|
3227
|
-
|
|
3228
|
-
if (meta.start) {
|
|
3181
|
+
if (meta.start)
|
|
3229
3182
|
params.set("start", meta.start.toString());
|
|
3230
|
-
|
|
3231
|
-
if (meta.end) {
|
|
3183
|
+
if (meta.end)
|
|
3232
3184
|
params.set("end", meta.end.toString());
|
|
3233
|
-
}
|
|
3234
3185
|
const source = `${YOUTUBE_LINK}/${meta.id}?${params.toString()}`;
|
|
3235
|
-
|
|
3186
|
+
const { width, height, ratio, title } = meta;
|
|
3187
|
+
return `<VideoYoutube${stringifyAttrs({ src: source, width, height, ratio, title })} />`;
|
|
3236
3188
|
}
|
|
3237
3189
|
});
|
|
3238
3190
|
};
|
|
@@ -3520,16 +3472,17 @@ var annotationPlugin = (md) => {
|
|
|
3520
3472
|
};
|
|
3521
3473
|
|
|
3522
3474
|
// src/node/inline/icons.ts
|
|
3523
|
-
|
|
3524
|
-
function
|
|
3475
|
+
import { colors as colors4 } from "vuepress/utils";
|
|
3476
|
+
function createIconRule([l1, l2, r1, r2], deprecated) {
|
|
3525
3477
|
return (state, silent) => {
|
|
3526
3478
|
let found = false;
|
|
3527
3479
|
const max = state.posMax;
|
|
3528
3480
|
const start = state.pos;
|
|
3529
|
-
if (state.src.charCodeAt(start) !==
|
|
3481
|
+
if (state.src.charCodeAt(start) !== l1 || state.src.charCodeAt(start + 1) !== l2) {
|
|
3530
3482
|
return false;
|
|
3531
3483
|
}
|
|
3532
|
-
|
|
3484
|
+
const next = state.src.charCodeAt(start + 2);
|
|
3485
|
+
if (next === 32 || next === 58)
|
|
3533
3486
|
return false;
|
|
3534
3487
|
if (silent)
|
|
3535
3488
|
return false;
|
|
@@ -3537,7 +3490,7 @@ function createTokenizer(options) {
|
|
|
3537
3490
|
return false;
|
|
3538
3491
|
state.pos = start + 2;
|
|
3539
3492
|
while (state.pos < max) {
|
|
3540
|
-
if (state.src.charCodeAt(state.pos) ===
|
|
3493
|
+
if (state.src.charCodeAt(state.pos) === r1 && state.src.charCodeAt(state.pos + 1) === r2) {
|
|
3541
3494
|
found = true;
|
|
3542
3495
|
break;
|
|
3543
3496
|
}
|
|
@@ -3547,69 +3500,103 @@ function createTokenizer(options) {
|
|
|
3547
3500
|
state.pos = start;
|
|
3548
3501
|
return false;
|
|
3549
3502
|
}
|
|
3550
|
-
const
|
|
3503
|
+
const info = state.src.slice(start + 2, state.pos);
|
|
3551
3504
|
state.posMax = state.pos;
|
|
3552
3505
|
state.pos = start + 2;
|
|
3553
|
-
const
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
icon.
|
|
3557
|
-
icon.attrs = [["name", name]];
|
|
3558
|
-
if (size || options.size)
|
|
3559
|
-
icon.attrs.push(["size", String(size || options.size)]);
|
|
3560
|
-
if (color)
|
|
3561
|
-
icon.attrs.push(["color", color]);
|
|
3562
|
-
const close = state.push("vp_icon_close", "VPIcon", -1);
|
|
3563
|
-
close.markup = "]:";
|
|
3506
|
+
const icon = state.push("icon", "i", 0);
|
|
3507
|
+
icon.markup = "::";
|
|
3508
|
+
icon.content = info;
|
|
3509
|
+
icon.meta = { deprecated };
|
|
3564
3510
|
state.pos = state.posMax + 2;
|
|
3565
3511
|
state.posMax = max;
|
|
3566
3512
|
return true;
|
|
3567
3513
|
};
|
|
3568
3514
|
}
|
|
3515
|
+
var RE_SIZE = /(?<=\s|^)=(.+?)(?:\s|$)/;
|
|
3516
|
+
var RE_COLOR = /(?<=\s|^)\/(.+?)(?:\s|$)/;
|
|
3517
|
+
function iconRender(content, options) {
|
|
3518
|
+
let size = options.size;
|
|
3519
|
+
let color = options.color;
|
|
3520
|
+
content = content.replace(RE_SIZE, (_, s) => {
|
|
3521
|
+
size = s;
|
|
3522
|
+
return "";
|
|
3523
|
+
}).replace(RE_COLOR, (_, c) => {
|
|
3524
|
+
color = c;
|
|
3525
|
+
return "";
|
|
3526
|
+
}).trim();
|
|
3527
|
+
const [name, ...extra] = content.split(/\s+/);
|
|
3528
|
+
return `<VPIcon${stringifyAttrs({ name, size, color, class: extra.length ? extra.join(" ") : void 0 })} />`;
|
|
3529
|
+
}
|
|
3530
|
+
var iconPlugin = (md, options = {}) => {
|
|
3531
|
+
md.inline.ruler.before(
|
|
3532
|
+
"link",
|
|
3533
|
+
"icon",
|
|
3534
|
+
// : : : :
|
|
3535
|
+
createIconRule([58, 58, 58, 58])
|
|
3536
|
+
);
|
|
3537
|
+
md.inline.ruler.before(
|
|
3538
|
+
"link",
|
|
3539
|
+
"icon_deprecated",
|
|
3540
|
+
// : [ ] :
|
|
3541
|
+
createIconRule([58, 91, 93, 58], true)
|
|
3542
|
+
);
|
|
3543
|
+
md.renderer.rules.icon = (tokens, idx, _, env) => {
|
|
3544
|
+
const { content, meta } = tokens[idx];
|
|
3545
|
+
let icon = content;
|
|
3546
|
+
if (meta.deprecated) {
|
|
3547
|
+
const [name, opt = ""] = content.split(" ");
|
|
3548
|
+
const [size, color] = opt.trim().split("/");
|
|
3549
|
+
icon = `${name}${size ? ` =${size}` : ""}${color ? ` /${color}` : ""}`;
|
|
3550
|
+
console.warn(`The icon syntax of \`${colors4.yellow(`:[${content}]:`)}\` is deprecated, please use \`${colors4.green(`::${icon}::`)}\` instead. (${colors4.gray(env.filePathRelative || env.filePath)})`);
|
|
3551
|
+
}
|
|
3552
|
+
return iconRender(icon, options);
|
|
3553
|
+
};
|
|
3554
|
+
};
|
|
3569
3555
|
|
|
3570
3556
|
// src/node/inline/plot.ts
|
|
3571
|
-
var
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3575
|
-
|
|
3576
|
-
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
3586
|
-
|
|
3587
|
-
state.pos
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
found = true;
|
|
3591
|
-
break;
|
|
3592
|
-
}
|
|
3593
|
-
state.md.inline.skipToken(state);
|
|
3594
|
-
}
|
|
3595
|
-
if (!found || start + 2 === state.pos || state.src.charCodeAt(state.pos - 1) === 32) {
|
|
3596
|
-
state.pos = start;
|
|
3597
|
-
return false;
|
|
3557
|
+
var plotDef = (state, silent) => {
|
|
3558
|
+
let found = false;
|
|
3559
|
+
const max = state.posMax;
|
|
3560
|
+
const start = state.pos;
|
|
3561
|
+
if (state.src.charCodeAt(start) !== 33 || state.src.charCodeAt(start + 1) !== 33) {
|
|
3562
|
+
return false;
|
|
3563
|
+
}
|
|
3564
|
+
const next = state.src.charCodeAt(start + 2);
|
|
3565
|
+
if (next === 32 || next === 33)
|
|
3566
|
+
return false;
|
|
3567
|
+
if (silent)
|
|
3568
|
+
return false;
|
|
3569
|
+
if (max - start < 5)
|
|
3570
|
+
return false;
|
|
3571
|
+
state.pos = start + 2;
|
|
3572
|
+
while (state.pos < max) {
|
|
3573
|
+
if (state.src.charCodeAt(state.pos) === 33 && state.src.charCodeAt(state.pos + 1) === 33) {
|
|
3574
|
+
found = true;
|
|
3575
|
+
break;
|
|
3598
3576
|
}
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3577
|
+
state.md.inline.skipToken(state);
|
|
3578
|
+
}
|
|
3579
|
+
if (!found || start + 2 === state.pos || state.src.charCodeAt(state.pos - 1) === 32) {
|
|
3580
|
+
state.pos = start;
|
|
3581
|
+
return false;
|
|
3582
|
+
}
|
|
3583
|
+
const content = state.src.slice(start + 2, state.pos);
|
|
3584
|
+
state.posMax = state.pos;
|
|
3585
|
+
state.pos = start + 2;
|
|
3586
|
+
const token = state.push("plot_inline", "Plot", 0);
|
|
3587
|
+
token.markup = "!!";
|
|
3588
|
+
token.content = content;
|
|
3589
|
+
state.pos = state.posMax + 2;
|
|
3590
|
+
state.posMax = max;
|
|
3591
|
+
return true;
|
|
3592
|
+
};
|
|
3593
|
+
var plotPlugin = (md) => {
|
|
3594
|
+
md.renderer.rules.plot_inline = (tokens, idx) => {
|
|
3595
|
+
const token = tokens[idx];
|
|
3596
|
+
return `<Plot>${token.content}</Plot>`;
|
|
3611
3597
|
};
|
|
3612
|
-
|
|
3598
|
+
md.inline.ruler.before("emphasis", "plot", plotDef);
|
|
3599
|
+
};
|
|
3613
3600
|
|
|
3614
3601
|
// src/node/inline/index.ts
|
|
3615
3602
|
function inlineSyntaxPlugin(md, options) {
|
|
@@ -3626,7 +3613,7 @@ function inlineSyntaxPlugin(md, options) {
|
|
|
3626
3613
|
md.use(abbrPlugin);
|
|
3627
3614
|
}
|
|
3628
3615
|
if (options.icons) {
|
|
3629
|
-
md.use(
|
|
3616
|
+
md.use(iconPlugin, isPlainObject3(options.icons) ? options.icons : {});
|
|
3630
3617
|
}
|
|
3631
3618
|
if (options.plot === true || isPlainObject3(options.plot) && options.plot.tag !== false) {
|
|
3632
3619
|
md.use(plotPlugin);
|
|
@@ -3689,8 +3676,8 @@ async function prepareConfigFile(app, options) {
|
|
|
3689
3676
|
enhances.add(`app.component('CanIUseViewer', CanIUse)`);
|
|
3690
3677
|
}
|
|
3691
3678
|
if (options.fileTree) {
|
|
3692
|
-
imports.add(`import
|
|
3693
|
-
enhances.add(`app.component('
|
|
3679
|
+
imports.add(`import FileTreeNode from '${CLIENT_FOLDER}components/FileTreeNode.vue'`);
|
|
3680
|
+
enhances.add(`app.component('FileTreeNode', FileTreeNode)`);
|
|
3694
3681
|
}
|
|
3695
3682
|
if (options.artPlayer) {
|
|
3696
3683
|
imports.add(`import ArtPlayer from '${CLIENT_FOLDER}components/ArtPlayer.vue'`);
|