vuepress-plugin-md-power 1.0.0-rc.101 → 1.0.0-rc.103

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/lib/node/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // src/node/features/imageSize.ts
1
+ // src/node/enhance/imageSize.ts
2
2
  import { Buffer } from "node:buffer";
3
3
  import http from "node:https";
4
4
  import { URL } from "node:url";
@@ -12,31 +12,31 @@ function resolveAttrs(info) {
12
12
  info = info.trim();
13
13
  if (!info)
14
14
  return { rawAttrs: "", attrs: {} };
15
- const attrs = {};
15
+ const attrs2 = {};
16
16
  const rawAttrs = info;
17
17
  let matched;
18
18
  while (matched = info.match(RE_ATTR_VALUE)) {
19
19
  const { attr, value } = matched.groups || {};
20
- attrs[attr] = value ?? true;
20
+ attrs2[attr] = value ?? true;
21
21
  info = info.slice(matched[0].length);
22
22
  }
23
- Object.keys(attrs).forEach((key) => {
24
- let value = attrs[key];
23
+ Object.keys(attrs2).forEach((key) => {
24
+ let value = attrs2[key];
25
25
  value = typeof value === "string" ? value.trim() : value;
26
26
  if (value === "true")
27
27
  value = true;
28
28
  else if (value === "false")
29
29
  value = false;
30
- attrs[key] = value;
30
+ attrs2[key] = value;
31
31
  if (key.includes("-")) {
32
32
  const _key = key.replace(/-(\w)/g, (_, c) => c.toUpperCase());
33
- attrs[_key] = value;
33
+ attrs2[_key] = value;
34
34
  }
35
35
  });
36
- return { attrs, rawAttrs };
36
+ return { attrs: attrs2, rawAttrs };
37
37
  }
38
38
 
39
- // src/node/features/imageSize.ts
39
+ // src/node/enhance/imageSize.ts
40
40
  var REG_IMG = /!\[.*?\]\(.*?\)/g;
41
41
  var REG_IMG_TAG = /<img(.*?)>/g;
42
42
  var REG_IMG_TAG_SRC = /src(?:set)?=(['"])(.+?)\1/g;
@@ -80,14 +80,14 @@ async function imageSizePlugin(app, md, type2 = false) {
80
80
  return (tokens, idx, options, env, self) => {
81
81
  const token = tokens[idx];
82
82
  token.content = token.content.replace(REG_IMG_TAG, (raw, info) => {
83
- const { attrs } = resolveAttrs(info);
84
- const src = attrs.src || attrs.srcset;
85
- const size = resolveSize(src, attrs.width, attrs.height, env);
83
+ const { attrs: attrs2 } = resolveAttrs(info);
84
+ const src = attrs2.src || attrs2.srcset;
85
+ const size = resolveSize(src, attrs2.width, attrs2.height, env);
86
86
  if (!size)
87
87
  return raw;
88
- attrs.width = size.width;
89
- attrs.height = size.height;
90
- const imgAttrs = Object.entries(attrs).map(([key, value]) => typeof value === "boolean" ? key : `${key}="${value}"`).join(" ");
88
+ attrs2.width = size.width;
89
+ attrs2.height = size.height;
90
+ const imgAttrs = Object.entries(attrs2).map(([key, value]) => typeof value === "boolean" ? key : `${key}="${value}"`).join(" ");
91
91
  return `<img ${imgAttrs}>`;
92
92
  });
93
93
  return rawHtmlRule(tokens, idx, options, env, self);
@@ -209,307 +209,176 @@ async function resolveImageSize(app, url, remote = false) {
209
209
  // src/node/plugin.ts
210
210
  import { addViteOptimizeDepsInclude } from "@vuepress/helper";
211
211
 
212
- // src/node/features/caniuse.ts
213
- import container from "markdown-it-container";
214
- import { customAlphabet } from "nanoid";
212
+ // src/node/container/index.ts
213
+ import { isPlainObject as isPlainObject2 } from "@vuepress/helper";
215
214
 
216
- // src/node/utils/createRuleBlock.ts
217
- function createRuleBlock(md, {
218
- type: type2,
219
- name = type2,
220
- syntaxPattern,
221
- beforeName = "import_code",
222
- ruleOptions = { alt: ["paragraph", "reference", "blockquote", "list"] },
223
- meta,
224
- content
225
- }) {
226
- const MIN_LENGTH = type2.length + 5;
227
- const START_CODES = [64, 91, ...type2.split("").map((c) => c.charCodeAt(0))];
228
- md.block.ruler.before(
229
- beforeName,
230
- name,
231
- (state, startLine, endLine, silent) => {
232
- const pos = state.bMarks[startLine] + state.tShift[startLine];
233
- const max = state.eMarks[startLine];
234
- if (pos + MIN_LENGTH > max)
235
- return false;
236
- for (let i = 0; i < START_CODES.length; i += 1) {
237
- if (state.src.charCodeAt(pos + i) !== START_CODES[i])
238
- return false;
215
+ // src/node/container/align.ts
216
+ import container from "markdown-it-container";
217
+ var alignList = ["left", "center", "right", "justify"];
218
+ function alignPlugin(md) {
219
+ for (const name of alignList) {
220
+ md.use(container, name, {
221
+ validate: (info) => info.trim() === name,
222
+ render: (tokens, idx) => {
223
+ if (tokens[idx].nesting === 1) {
224
+ return `<div style="text-align:${name}">`;
225
+ } else {
226
+ return "</div>";
227
+ }
239
228
  }
240
- const match = state.src.slice(pos, max).match(syntaxPattern);
241
- if (!match)
242
- return false;
243
- if (silent)
244
- return true;
245
- const token = state.push(name, "", 0);
246
- token.meta = meta(match);
247
- token.map = [startLine, startLine + 1];
248
- state.line = startLine + 1;
249
- return true;
250
- },
251
- ruleOptions
252
- );
253
- md.renderer.rules[name] = (tokens, index) => {
254
- const token = tokens[index];
255
- token.content = content(token.meta);
256
- return token.content;
257
- };
258
- }
259
-
260
- // src/node/features/caniuse.ts
261
- var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
262
- var UNDERLINE_RE = /_+/g;
263
- var caniusePlugin = (md, { mode: defaultMode = "embed" } = {}) => {
264
- createRuleBlock(md, {
265
- type: "caniuse",
266
- syntaxPattern: /^@\[caniuse\s*(embed|image)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
267
- meta: ([, mode, versions = "", feature]) => ({
268
- feature,
269
- mode: mode || defaultMode,
270
- versions
271
- }),
272
- content: (meta) => resolveCanIUse(meta)
273
- });
274
- };
275
- function legacyCaniuse(md, { mode = "embed" } = {}) {
276
- const modeMap = ["image", "embed"];
277
- const isMode = (mode2) => modeMap.includes(mode2);
278
- mode = isMode(mode) ? mode : modeMap[0];
279
- const type2 = "caniuse";
280
- const validateReg = new RegExp(`^${type2}`);
281
- const validate = (info) => {
282
- return validateReg.test(info.trim());
283
- };
284
- const render = (tokens, index) => {
285
- const token = tokens[index];
286
- if (token.nesting === 1) {
287
- const info = token.info.trim().slice(type2.length).trim() || "";
288
- const feature = info.split(/\s+/)[0];
289
- const versions = info.match(/\{(.*)\}/)?.[1] || "";
290
- return feature ? resolveCanIUse({ feature, mode, versions }) : "";
291
- } else {
292
- return "";
293
- }
294
- };
295
- md.use(container, type2, { validate, render });
296
- }
297
- function resolveCanIUse({ feature, mode, versions }) {
298
- if (!feature)
299
- return "";
300
- if (mode === "image") {
301
- const link = "https://caniuse.bitsofco.de/image/";
302
- const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`;
303
- return `<ClientOnly><p><picture>
304
- <source type="image/webp" srcset="${link}${feature}.webp">
305
- <source type="image/png" srcset="${link}${feature}.png">
306
- <img src="${link}${feature}.jpg" alt="${alt}" width="100%">
307
- </picture></p></ClientOnly>`;
229
+ });
308
230
  }
309
- feature = feature.replace(UNDERLINE_RE, "_");
310
- const { past, future } = resolveVersions(versions);
311
- const meta = nanoid();
312
- return `<CanIUseViewer feature="${feature}" meta="${meta}" past="${past}" future="${future}" />`;
313
- }
314
- function resolveVersions(versions) {
315
- if (!versions)
316
- return { past: 2, future: 1 };
317
- const list = versions.split(",").map((v) => Number(v.trim())).filter((v) => !Number.isNaN(v) && v >= -5 && v <= 3);
318
- list.push(0);
319
- const uniq = [...new Set(list)].sort((a, b) => b - a);
320
- return {
321
- future: uniq[0],
322
- past: Math.abs(uniq[uniq.length - 1])
323
- };
324
- }
325
-
326
- // src/node/utils/parseRect.ts
327
- function parseRect(str, unit = "px") {
328
- if (Number.parseFloat(str) === Number(str))
329
- return `${str}${unit}`;
330
- return str;
331
231
  }
332
232
 
333
- // src/node/features/codepen.ts
334
- var CODEPEN_LINK = "https://codepen.io/";
335
- var codepenPlugin = (md) => {
336
- createRuleBlock(md, {
337
- type: "codepen",
338
- syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
339
- meta: ([, info = "", source = ""]) => {
340
- const { attrs } = resolveAttrs(info);
341
- const [user, slash] = source.split("/");
342
- return {
343
- width: attrs.width ? parseRect(attrs.width) : "100%",
344
- height: attrs.height ? parseRect(attrs.height) : "400px",
345
- user,
346
- slash,
347
- title: attrs.title,
348
- preview: attrs.preview,
349
- editable: attrs.editable,
350
- tab: attrs.tab ?? "result",
351
- theme: attrs.theme
352
- };
353
- },
354
- content: (meta) => {
355
- const { title = "Codepen", height, width } = meta;
356
- const params = new URLSearchParams();
357
- if (meta.editable) {
358
- params.set("editable", "true");
359
- }
360
- if (meta.tab) {
361
- params.set("default-tab", meta.tab);
362
- }
363
- if (meta.theme) {
364
- params.set("theme-id", meta.theme);
365
- }
366
- const middle = meta.preview ? "/embed/preview/" : "/embed/";
367
- const link = `${CODEPEN_LINK}${meta.user}${middle}${meta.slash}?${params.toString()}`;
368
- const style = `width:${width};height:${height};margin:16px auto;border-radius:5px;`;
369
- return `<iframe class="code-pen-iframe-wrapper" src="${link}" title="${title}" style="${style}" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">See the Pen <a href="${CODEPEN_LINK}${meta.user}/pen/${meta.slash}">${title}</a> by ${meta.user} (<a href="${CODEPEN_LINK}${meta.user}">@${meta.user}</a>) on <a href="${CODEPEN_LINK}">CodePen</a>.</iframe>`;
370
- }
371
- });
372
- };
373
-
374
- // src/node/features/codeSandbox.ts
375
- var codeSandboxPlugin = (md) => {
376
- createRuleBlock(md, {
377
- type: "codesandbox",
378
- syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
379
- meta([, type2, info = "", source = ""]) {
380
- const { attrs } = resolveAttrs(info);
381
- const [profile, filepath2 = ""] = source.split("#");
382
- const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
383
- return {
384
- width: attrs.width ? parseRect(attrs.width) : "100%",
385
- height: attrs.height ? parseRect(attrs.height) : "500px",
386
- user,
387
- id,
388
- title: attrs.title ?? "",
389
- console: attrs.console ?? false,
390
- navbar: attrs.navbar ?? true,
391
- layout: attrs.layout ?? "",
392
- type: type2 || "embed",
393
- filepath: filepath2
394
- };
395
- },
396
- content({ title, height, width, user, id, type: type2, filepath: filepath2, console, navbar, layout }) {
397
- return `<CodeSandboxViewer title="${title}" height="${height}" width="${width}" user="${user}" id="${id}" type="${type2}" filepath="${filepath2}" :console=${console} :navbar=${navbar} layout="${layout}" />`;
398
- }
399
- });
400
- };
401
-
402
- // src/node/features/fileTree/index.ts
403
- import container2 from "markdown-it-container";
233
+ // src/node/container/codeTabs.ts
234
+ import { tab } from "@mdit/plugin-tab";
235
+ import { isPlainObject } from "@vuepress/helper";
404
236
 
405
- // src/node/features/fileTree/definitions.ts
237
+ // src/node/fileIcons/definitions.ts
406
238
  var defaultFolder = "vscode-icons:default-folder";
407
239
  var defaultFile = "vscode-icons:default-file";
408
240
  var definitions = {
409
241
  named: {
410
242
  // package manager
411
- pnpm: "vscode-icons:file-type-light-pnpm",
412
- PNPM: "vscode-icons:file-type-light-pnpm",
413
- npm: "vscode-icons:file-type-npm",
414
- NPM: "vscode-icons:file-type-npm",
415
- yarn: "vscode-icons:file-type-yarn",
416
- Yarn: "vscode-icons:file-type-yarn",
417
- bun: "vscode-icons:file-type-bun",
418
- Bun: "vscode-icons:file-type-bun",
419
- deno: "vscode-icons:file-type-light-deno",
420
- Deno: "vscode-icons:file-type-light-deno",
243
+ "pnpm": "vscode-icons:file-type-light-pnpm",
244
+ "PNPM": "vscode-icons:file-type-light-pnpm",
245
+ "npm": "logos:npm-icon",
246
+ "NPM": "logos:npm-icon",
247
+ "yarn": "vscode-icons:file-type-yarn",
248
+ "Yarn": "vscode-icons:file-type-yarn",
249
+ "bun": "vscode-icons:file-type-bun",
250
+ "Bun": "vscode-icons:file-type-bun",
251
+ "deno": "vscode-icons:file-type-light-deno",
252
+ "Deno": "vscode-icons:file-type-light-deno",
421
253
  // bundlers
422
- rollup: "vscode-icons:file-type-rollup",
423
- Rollup: "vscode-icons:file-type-rollup",
424
- webpack: "vscode-icons:file-type-webpack",
425
- Webpack: "vscode-icons:file-type-webpack",
426
- vite: "vscode-icons:file-type-vite",
427
- Vite: "vscode-icons:file-type-vite",
428
- esbuild: "vscode-icons:file-type-esbuild",
429
- Esbuild: "vscode-icons:file-type-esbuild",
254
+ "rollup": "vscode-icons:file-type-rollup",
255
+ "Rollup": "vscode-icons:file-type-rollup",
256
+ "webpack": "vscode-icons:file-type-webpack",
257
+ "Webpack": "vscode-icons:file-type-webpack",
258
+ "vite": "vscode-icons:file-type-vite",
259
+ "Vite": "vscode-icons:file-type-vite",
260
+ "esbuild": "vscode-icons:file-type-esbuild",
261
+ "Esbuild": "vscode-icons:file-type-esbuild",
430
262
  // frameworks
431
- vue: "vscode-icons:file-type-vue",
432
- Vue: "vscode-icons:file-type-vue",
433
- svelte: "vscode-icons:file-type-svelte",
434
- sveltekit: "vscode-icons:file-type-svelte",
435
- angular: "vscode-icons:file-type-angular",
436
- Angular: "vscode-icons:file-type-angular",
437
- react: "vscode-icons:file-type-reactjs",
438
- React: "vscode-icons:file-type-reactjs",
439
- next: "vscode-icons:file-type-light-next",
440
- Next: "vscode-icons:file-type-light-next",
441
- Nextjs: "vscode-icons:file-type-light-next",
442
- NextJS: "vscode-icons:file-type-light-next",
443
- nuxt: "vscode-icons:file-type-nuxt",
444
- Nuxt: "vscode-icons:file-type-nuxt",
445
- Nuxtjs: "vscode-icons:file-type-nuxt",
446
- NuxtJS: "vscode-icons:file-type-nuxt",
447
- solid: "logos:solidjs-icon",
448
- Solid: "logos:solidjs-icon",
449
- solidjs: "logos:solidjs-icon",
450
- astro: "vscode-icons:file-type-light-astro",
451
- Astro: "vscode-icons:file-type-light-astro",
452
- vitest: "vscode-icons:file-type-vitest",
453
- Vitest: "vscode-icons:file-type-vitest",
454
- playwright: "vscode-icons:file-type-playwright",
455
- Playwright: "vscode-icons:file-type-playwright",
456
- jest: "vscode-icons:file-type-jest",
457
- Jest: "vscode-icons:file-type-jest",
458
- cypress: "vscode-icons:file-type-cypress",
459
- Cypress: "vscode-icons:file-type-cypress",
460
- docker: "vscode-icons:file-type-docker",
461
- Docker: "vscode-icons:file-type-docker",
263
+ "vue": "vscode-icons:file-type-vue",
264
+ "Vue": "vscode-icons:file-type-vue",
265
+ "svelte": "vscode-icons:file-type-svelte",
266
+ "Svelte": "vscode-icons:file-type-svelte",
267
+ "sveltekit": "vscode-icons:file-type-svelte",
268
+ "SvelteKit": "vscode-icons:file-type-svelte",
269
+ "angular": "vscode-icons:file-type-angular",
270
+ "Angular": "vscode-icons:file-type-angular",
271
+ "react": "vscode-icons:file-type-reactjs",
272
+ "React": "vscode-icons:file-type-reactjs",
273
+ "next": "vscode-icons:file-type-light-next",
274
+ "Next": "vscode-icons:file-type-light-next",
275
+ "Nextjs": "vscode-icons:file-type-light-next",
276
+ "NextJS": "vscode-icons:file-type-light-next",
277
+ "nuxt": "vscode-icons:file-type-nuxt",
278
+ "Nuxt": "vscode-icons:file-type-nuxt",
279
+ "Nuxtjs": "vscode-icons:file-type-nuxt",
280
+ "NuxtJS": "vscode-icons:file-type-nuxt",
281
+ "solid": "logos:solidjs-icon",
282
+ "Solid": "logos:solidjs-icon",
283
+ "solidjs": "logos:solidjs-icon",
284
+ "astro": "vscode-icons:file-type-light-astro",
285
+ "Astro": "vscode-icons:file-type-light-astro",
286
+ "vitest": "vscode-icons:file-type-vitest",
287
+ "Vitest": "vscode-icons:file-type-vitest",
288
+ "playwright": "vscode-icons:file-type-playwright",
289
+ "Playwright": "vscode-icons:file-type-playwright",
290
+ "jest": "vscode-icons:file-type-jest",
291
+ "Jest": "vscode-icons:file-type-jest",
292
+ "cypress": "vscode-icons:file-type-cypress",
293
+ "Cypress": "vscode-icons:file-type-cypress",
294
+ "docker": "vscode-icons:file-type-docker",
295
+ "Docker": "vscode-icons:file-type-docker",
462
296
  // TODO: code group title icons
463
297
  // programming languages
464
- html: "vscode-icons:file-type-html",
465
- Html: "vscode-icons:file-type-html",
466
- HTML: "vscode-icons:file-type-html",
467
- javascript: "vscode-icons:file-type-js-official",
468
- Javascript: "vscode-icons:file-type-js-official",
469
- JavaScript: "vscode-icons:file-type-js-official",
470
- js: "vscode-icons:file-type-js-official",
471
- JS: "vscode-icons:file-type-js-official",
472
- typescript: "vscode-icons:file-type-typescript-official",
473
- Typescript: "vscode-icons:file-type-typescript-official",
474
- TypeScript: "vscode-icons:file-type-typescript-official",
475
- ts: "vscode-icons:file-type-typescript-official",
476
- TS: "vscode-icons:file-type-typescript-official",
477
- css: "vscode-icons:file-type-css",
478
- CSS: "vscode-icons:file-type-css",
479
- less: "vscode-icons:file-type-less",
480
- Less: "vscode-icons:file-type-less",
481
- scss: "vscode-icons:file-type-scss",
482
- Scss: "vscode-icons:file-type-scss",
483
- SCSS: "vscode-icons:file-type-scss",
484
- sass: "vscode-icons:file-type-sass",
485
- Sass: "vscode-icons:file-type-sass",
486
- SASS: "vscode-icons:file-type-sass",
487
- stylus: "vscode-icons:file-type-light-stylus",
488
- Stylus: "vscode-icons:file-type-light-stylus",
489
- postcss: "vscode-icons:file-type-postcss",
490
- Postcss: "vscode-icons:file-type-postcss",
491
- PostCSS: "vscode-icons:file-type-postcss",
492
- java: "vscode-icons:file-type-java",
493
- Java: "vscode-icons:file-type-java",
494
- JAVA: "vscode-icons:file-type-java",
495
- php: "vscode-icons:file-type-php3",
496
- PHP: "vscode-icons:file-type-php3",
497
- c: "vscode-icons:file-type-c",
498
- C: "vscode-icons:file-type-c",
499
- python: "vscode-icons:file-type-python",
500
- Python: "vscode-icons:file-type-python",
501
- kotlin: "vscode-icons:file-type-kotlin",
502
- Kotlin: "vscode-icons:file-type-kotlin",
503
- go: "vscode-icons:file-type-go-gopher",
504
- golang: "vscode-icons:file-type-go-gopher",
505
- Go: "vscode-icons:file-type-go-gopher",
506
- GoLang: "vscode-icons:file-type-go-gopher",
507
- rust: "vscode-icons:file-type-rust",
508
- Rust: "vscode-icons:file-type-rust",
509
- zig: "vscode-icons:file-type-zig",
510
- Zig: "vscode-icons:file-type-zig",
511
- swift: "vscode-icons:file-type-swift",
512
- Swift: "vscode-icons:file-type-swift"
298
+ "html": "vscode-icons:file-type-html",
299
+ "Html": "vscode-icons:file-type-html",
300
+ "HTML": "vscode-icons:file-type-html",
301
+ "javascript": "vscode-icons:file-type-js-official",
302
+ "Javascript": "vscode-icons:file-type-js-official",
303
+ "JavaScript": "vscode-icons:file-type-js-official",
304
+ "js": "vscode-icons:file-type-js-official",
305
+ "JS": "vscode-icons:file-type-js-official",
306
+ "typescript": "vscode-icons:file-type-typescript-official",
307
+ "Typescript": "vscode-icons:file-type-typescript-official",
308
+ "TypeScript": "vscode-icons:file-type-typescript-official",
309
+ "ts": "vscode-icons:file-type-typescript-official",
310
+ "TS": "vscode-icons:file-type-typescript-official",
311
+ "css": "vscode-icons:file-type-css",
312
+ "CSS": "vscode-icons:file-type-css",
313
+ "less": "vscode-icons:file-type-less",
314
+ "Less": "vscode-icons:file-type-less",
315
+ "scss": "vscode-icons:file-type-scss",
316
+ "Scss": "vscode-icons:file-type-scss",
317
+ "SCSS": "vscode-icons:file-type-scss",
318
+ "sass": "vscode-icons:file-type-sass",
319
+ "Sass": "vscode-icons:file-type-sass",
320
+ "SASS": "vscode-icons:file-type-sass",
321
+ "stylus": "vscode-icons:file-type-light-stylus",
322
+ "Stylus": "vscode-icons:file-type-light-stylus",
323
+ "postcss": "vscode-icons:file-type-postcss",
324
+ "Postcss": "vscode-icons:file-type-postcss",
325
+ "PostCSS": "vscode-icons:file-type-postcss",
326
+ "sh": "vscode-icons:file-type-shell",
327
+ "shell": "vscode-icons:file-type-shell",
328
+ "Shell": "vscode-icons:file-type-shell",
329
+ "bash": "vscode-icons:file-type-shell",
330
+ "Bash": "vscode-icons:file-type-shell",
331
+ "java": "vscode-icons:file-type-java",
332
+ "Java": "vscode-icons:file-type-java",
333
+ "JAVA": "vscode-icons:file-type-java",
334
+ "php": "vscode-icons:file-type-php3",
335
+ "PHP": "vscode-icons:file-type-php3",
336
+ "c": "vscode-icons:file-type-c",
337
+ "C": "vscode-icons:file-type-c",
338
+ "python": "vscode-icons:file-type-python",
339
+ "Python": "vscode-icons:file-type-python",
340
+ "kotlin": "vscode-icons:file-type-kotlin",
341
+ "Kotlin": "vscode-icons:file-type-kotlin",
342
+ "go": "vscode-icons:file-type-go-gopher",
343
+ "golang": "vscode-icons:file-type-go-gopher",
344
+ "Go": "vscode-icons:file-type-go-gopher",
345
+ "GoLang": "vscode-icons:file-type-go-gopher",
346
+ "rust": "vscode-icons:file-type-rust",
347
+ "Rust": "vscode-icons:file-type-rust",
348
+ "zig": "vscode-icons:file-type-zig",
349
+ "Zig": "vscode-icons:file-type-zig",
350
+ "swift": "vscode-icons:file-type-swift",
351
+ "Swift": "vscode-icons:file-type-swift",
352
+ "c#": "vscode-icons:file-type-csharp",
353
+ "CSharp": "vscode-icons:file-type-csharp",
354
+ "c++": "vscode-icons:file-type-cpp",
355
+ "C++": "vscode-icons:file-type-cpp",
356
+ "ruby": "vscode-icons:file-type-ruby",
357
+ "Ruby": "vscode-icons:file-type-ruby",
358
+ "makefile": "vscode-icons:file-type-makefile",
359
+ "Makefile": "vscode-icons:file-type-makefile",
360
+ "Object-C": "vscode-icons:file-type-objectivec",
361
+ "object-c": "vscode-icons:file-type-objectivec",
362
+ "SQL": "vscode-icons:file-type-sql",
363
+ "sql": "vscode-icons:file-type-sql",
364
+ "mysql": "vscode-icons:file-type-mysql",
365
+ "MySQL": "vscode-icons:file-type-mysql",
366
+ "MySql": "vscode-icons:file-type-mysql",
367
+ "pgsql": "vscode-icons:file-type-pgsql",
368
+ "PostgreSQL": "vscode-icons:file-type-pgsql",
369
+ "PGSQL": "vscode-icons:file-type-pgsql",
370
+ "xml": "vscode-icons:file-type-xml",
371
+ "XML": "vscode-icons:file-type-xml",
372
+ "wasm": "vscode-icons:file-type-wasm",
373
+ "webassembly": "vscode-icons:file-type-wasm",
374
+ "WebAssembly": "vscode-icons:file-type-wasm",
375
+ "WASM": "vscode-icons:file-type-wasm",
376
+ "toml": "vscode-icons:file-type-light-toml",
377
+ "Toml": "vscode-icons:file-type-light-toml",
378
+ "TOML": "vscode-icons:file-type-light-toml",
379
+ "yaml": "vscode-icons:file-type-light-yaml",
380
+ "Yaml": "vscode-icons:file-type-light-yaml",
381
+ "YAML": "vscode-icons:file-type-light-yaml"
513
382
  },
514
383
  folders: {
515
384
  "default": "vscode-icons:default-folder",
@@ -1177,7 +1046,7 @@ var definitions = {
1177
1046
  }
1178
1047
  };
1179
1048
 
1180
- // src/node/features/fileTree/findIcon.ts
1049
+ // src/node/fileIcons/findIcon.ts
1181
1050
  function getFileIcon(fileName, type2 = "file") {
1182
1051
  const name = getFileIconName(fileName, type2);
1183
1052
  if (!name)
@@ -1222,9 +1091,138 @@ function getFileIconTypeFromExtension(fileName) {
1222
1091
  return void 0;
1223
1092
  }
1224
1093
 
1225
- // src/node/features/fileTree/resolveTreeNodeInfo.ts
1094
+ // src/node/utils/stringifyProp.ts
1095
+ function stringifyProp(data) {
1096
+ return JSON.stringify(data).replace(/'/g, "&#39");
1097
+ }
1098
+
1099
+ // src/node/container/codeTabs.ts
1100
+ var codeTabs = (md, options = {}) => {
1101
+ const getIcon = (filename) => {
1102
+ if (options.icon === false)
1103
+ return void 0;
1104
+ const { named, extensions } = isPlainObject(options.icon) ? options.icon : {};
1105
+ if (named === false && definitions.named[filename])
1106
+ return void 0;
1107
+ if (extensions === false && getFileIconTypeFromExtension(filename)) {
1108
+ return void 0;
1109
+ }
1110
+ const hasNamed = named && named.length;
1111
+ const hasExt = extensions && extensions.length;
1112
+ if (hasNamed || hasExt) {
1113
+ if (hasNamed && named.includes(filename))
1114
+ return definitions.named[filename];
1115
+ if (hasExt && extensions.some((ext) => filename.endsWith(ext)))
1116
+ return getFileIconTypeFromExtension(filename);
1117
+ return void 0;
1118
+ }
1119
+ return getFileIconName(filename);
1120
+ };
1121
+ tab(md, {
1122
+ name: "code-tabs",
1123
+ tabsOpenRenderer: ({ active, data }, tokens, index) => {
1124
+ const { meta } = tokens[index];
1125
+ const titles = data.map(({ title }) => md.renderInline(title));
1126
+ const tabsData = data.map((item, dataIndex) => {
1127
+ const { id = titles[dataIndex] } = item;
1128
+ return { id };
1129
+ });
1130
+ const titlesContent = titles.map((title, index2) => {
1131
+ const icon = getIcon(title);
1132
+ return `<template #title${index2}="{ value, isActive }">${icon ? `<VPIcon name="${icon}"/>` : ""}<span>${title}</span></template>`;
1133
+ }).join("");
1134
+ return `<CodeTabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? "" : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id}"` : ""}>${titlesContent}`;
1135
+ },
1136
+ tabsCloseRenderer: () => `</CodeTabs>`,
1137
+ tabOpenRenderer: ({ index }, tokens, tokenIndex) => {
1138
+ let foundFence = false;
1139
+ for (let i = tokenIndex; i < tokens.length; i++) {
1140
+ const { block, type: type2 } = tokens[i];
1141
+ if (block) {
1142
+ if (type2 === "code-tabs_tab_close")
1143
+ break;
1144
+ if ((type2 === "fence" || type2 === "import_code") && !foundFence) {
1145
+ foundFence = true;
1146
+ continue;
1147
+ }
1148
+ tokens[i].type = "code_tab_empty";
1149
+ tokens[i].hidden = true;
1150
+ }
1151
+ }
1152
+ return `<template #tab${index}="{ value, isActive }">`;
1153
+ },
1154
+ tabCloseRenderer: () => `</template>`
1155
+ });
1156
+ };
1157
+
1158
+ // src/node/container/fileTree.ts
1226
1159
  import Token from "markdown-it/lib/token.mjs";
1160
+ import container2 from "markdown-it-container";
1227
1161
  import { removeEndingSlash, removeLeadingSlash } from "vuepress/shared";
1162
+ var type = "file-tree";
1163
+ var closeType = `container_${type}_close`;
1164
+ var componentName = "FileTreeItem";
1165
+ var itemOpen = "file_tree_item_open";
1166
+ var itemClose = "file_tree_item_close";
1167
+ var RE_SIMPLE_ICON = /:simple-icon\b/;
1168
+ var RE_COLORED_ICON = /:colored-icon\b/;
1169
+ function fileTreePlugin(md, options = {}) {
1170
+ const getIcon = (filename, type2, mode) => {
1171
+ mode ||= options.icon || "colored";
1172
+ if (mode === "simple")
1173
+ return type2 === "folder" ? defaultFolder : defaultFile;
1174
+ return getFileIcon(filename, type2);
1175
+ };
1176
+ const validate = (info) => info.trim().startsWith(type);
1177
+ const render = (tokens, idx) => {
1178
+ const mode = getFileIconMode(tokens[idx].info);
1179
+ if (tokens[idx].nesting === 1) {
1180
+ const hasRes = [];
1181
+ for (let i = idx + 1; !(tokens[i].nesting === -1 && tokens[i].type === closeType); ++i) {
1182
+ const token = tokens[i];
1183
+ if (token.type === "list_item_open") {
1184
+ const result = resolveTreeNodeInfo(tokens, token, i);
1185
+ if (result) {
1186
+ hasRes.push(token.level);
1187
+ const [info, inline] = result;
1188
+ const { filename, type: type2, expanded, empty } = info;
1189
+ const icon = getIcon(filename, type2, mode);
1190
+ token.type = itemOpen;
1191
+ token.tag = componentName;
1192
+ token.attrSet("type", type2);
1193
+ token.attrSet(":expanded", expanded ? "true" : "false");
1194
+ token.attrSet(":empty", empty ? "true" : "false");
1195
+ updateInlineToken(inline, info, icon);
1196
+ } else {
1197
+ hasRes.push(-1);
1198
+ }
1199
+ } else if (token.type === "list_item_close") {
1200
+ if (token.level === hasRes.pop()) {
1201
+ token.type = itemClose;
1202
+ token.tag = componentName;
1203
+ }
1204
+ }
1205
+ }
1206
+ const title = resolveTitle(tokens[idx].info);
1207
+ return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ""}`;
1208
+ } else {
1209
+ return "</div>";
1210
+ }
1211
+ };
1212
+ md.use(container2, type, { validate, render });
1213
+ }
1214
+ function getFileIconMode(info) {
1215
+ if (RE_SIMPLE_ICON.test(info))
1216
+ return "simple";
1217
+ if (RE_COLORED_ICON.test(info))
1218
+ return "colored";
1219
+ return void 0;
1220
+ }
1221
+ function resolveTitle(info) {
1222
+ info = info.trim().slice(type.length).trim();
1223
+ info = info.replace(RE_SIMPLE_ICON, "").replace(RE_COLORED_ICON, "");
1224
+ return info.trim();
1225
+ }
1228
1226
  function resolveTreeNodeInfo(tokens, current, idx) {
1229
1227
  let hasInline = false;
1230
1228
  let hasChildren = false;
@@ -1279,17 +1277,19 @@ function updateInlineToken(inline, info, icon) {
1279
1277
  if (token.content.includes(" ")) {
1280
1278
  const [first, ...other] = token.content.split(" ");
1281
1279
  const text = new Token("text", "", 0);
1282
- text.content = first;
1280
+ text.content = removeEndingSlash(first);
1283
1281
  tokens.push(text);
1284
1282
  const comment = new Token("text", "", 0);
1285
1283
  comment.content = other.join(" ");
1286
1284
  children.unshift(comment);
1287
1285
  } else {
1286
+ token.content = removeEndingSlash(token.content);
1288
1287
  tokens.push(token);
1289
1288
  }
1290
1289
  if (!isStrongTag)
1291
1290
  break;
1292
1291
  } else if (token.tag === "strong") {
1292
+ token.content = removeEndingSlash(token.content);
1293
1293
  tokens.push(token);
1294
1294
  if (token.nesting === 1) {
1295
1295
  isStrongTag = true;
@@ -1312,133 +1312,7 @@ function updateInlineToken(inline, info, icon) {
1312
1312
  inline.children = tokens;
1313
1313
  }
1314
1314
 
1315
- // src/node/features/fileTree/index.ts
1316
- var type = "file-tree";
1317
- var closeType = `container_${type}_close`;
1318
- var componentName = "FileTreeItem";
1319
- var itemOpen = "file_tree_item_open";
1320
- var itemClose = "file_tree_item_close";
1321
- function fileTreePlugin(md) {
1322
- const validate = (info) => info.trim().startsWith(type);
1323
- const render = (tokens, idx) => {
1324
- if (tokens[idx].nesting === 1) {
1325
- const hasRes = [];
1326
- for (let i = idx + 1; !(tokens[i].nesting === -1 && tokens[i].type === closeType); ++i) {
1327
- const token = tokens[i];
1328
- if (token.type === "list_item_open") {
1329
- const result = resolveTreeNodeInfo(tokens, token, i);
1330
- if (result) {
1331
- hasRes.push(token.level);
1332
- const [info2, inline] = result;
1333
- const { filename, type: type2, expanded, empty } = info2;
1334
- const icon = getFileIcon(filename, type2);
1335
- token.type = itemOpen;
1336
- token.tag = componentName;
1337
- token.attrSet("type", type2);
1338
- token.attrSet(":expanded", expanded ? "true" : "false");
1339
- token.attrSet(":empty", empty ? "true" : "false");
1340
- updateInlineToken(inline, info2, icon);
1341
- } else {
1342
- hasRes.push(-1);
1343
- }
1344
- } else if (token.type === "list_item_close") {
1345
- if (token.level === hasRes.pop()) {
1346
- token.type = itemClose;
1347
- token.tag = componentName;
1348
- }
1349
- }
1350
- }
1351
- const info = tokens[idx].info.trim();
1352
- const title = info.slice(type.length).trim();
1353
- return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ""}`;
1354
- } else {
1355
- return "</div>";
1356
- }
1357
- };
1358
- md.use(container2, type, { validate, render });
1359
- }
1360
-
1361
- // src/node/features/icons.ts
1362
- var [openTag, endTag] = [":[", "]:"];
1363
- function createTokenizer() {
1364
- return (state, silent) => {
1365
- let found = false;
1366
- const max = state.posMax;
1367
- const start = state.pos;
1368
- if (state.src.slice(start, start + 2) !== openTag)
1369
- return false;
1370
- if (silent)
1371
- return false;
1372
- if (max - start < 5)
1373
- return false;
1374
- state.pos = start + 2;
1375
- while (state.pos < max) {
1376
- if (state.src.slice(state.pos, state.pos + 2) === endTag) {
1377
- found = true;
1378
- break;
1379
- }
1380
- state.md.inline.skipToken(state);
1381
- }
1382
- if (!found || start + 2 === state.pos) {
1383
- state.pos = start;
1384
- return false;
1385
- }
1386
- const content = state.src.slice(start + 2, state.pos);
1387
- if (/^\s|\s$/.test(content)) {
1388
- state.pos = start;
1389
- return false;
1390
- }
1391
- state.posMax = state.pos;
1392
- state.pos = start + 2;
1393
- const [name, options = ""] = content.split(/\s+/);
1394
- const [size, color] = options.split("/");
1395
- const icon = state.push("vp_iconify_open", "VPIcon", 1);
1396
- icon.markup = openTag;
1397
- if (name)
1398
- icon.attrSet("name", name);
1399
- if (size)
1400
- icon.attrSet("size", size);
1401
- if (color)
1402
- icon.attrSet("color", color);
1403
- const close = state.push("vp_iconify_close", "VPIcon", -1);
1404
- close.markup = endTag;
1405
- state.pos = state.posMax + 2;
1406
- state.posMax = max;
1407
- return true;
1408
- };
1409
- }
1410
- var iconsPlugin = (md) => {
1411
- md.inline.ruler.before("emphasis", "iconify", createTokenizer());
1412
- };
1413
-
1414
- // src/node/features/jsfiddle.ts
1415
- var jsfiddlePlugin = (md) => {
1416
- createRuleBlock(md, {
1417
- type: "jsfiddle",
1418
- syntaxPattern: /^@\[jsfiddle([^\]]*)\]\(([^)]*)\)/,
1419
- meta([, info = "", source]) {
1420
- const { attrs } = resolveAttrs(info);
1421
- const [user, id] = source.split("/");
1422
- return {
1423
- width: attrs.width ? parseRect(attrs.width) : "100%",
1424
- height: attrs.height ? parseRect(attrs.height) : "400px",
1425
- user,
1426
- id,
1427
- title: attrs.title || "JS Fiddle",
1428
- tab: attrs.tab?.replace(/\s+/g, "") || "js,css,html,result",
1429
- theme: attrs.theme || "dark"
1430
- };
1431
- },
1432
- content: ({ title = "JS Fiddle", height, width, user, id, tab, theme }) => {
1433
- theme = theme === "dark" ? "/dark/" : "";
1434
- const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab}${theme}`;
1435
- const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
1436
- return `<iframe class="js-fiddle-iframe-wrapper" style="${style}" title="${title}" src="${link}" allowfullscreen="true" allowpaymentrequest="true"></iframe>`;
1437
- }
1438
- });
1439
- };
1440
-
1441
- // src/node/features/langRepl.ts
1315
+ // src/node/container/langRepl.ts
1442
1316
  import container3 from "markdown-it-container";
1443
1317
  import { fs as fs2, getDirname, path as path2 } from "vuepress/utils";
1444
1318
  var RE_INFO = /^(#editable)?(.*)$/;
@@ -1505,92 +1379,271 @@ async function read(file) {
1505
1379
  return void 0;
1506
1380
  }
1507
1381
 
1508
- // src/node/features/pdf.ts
1509
- import { path as path3 } from "vuepress/utils";
1510
- var pdfPlugin = (md) => {
1511
- createRuleBlock(md, {
1512
- type: "pdf",
1513
- // eslint-disable-next-line regexp/no-super-linear-backtracking
1514
- syntaxPattern: /^@\[pdf(?:\s+(\d+))?([^\]]*)\]\(([^)]*)\)/,
1515
- meta([, page, info = "", src = ""]) {
1516
- const { attrs } = resolveAttrs(info);
1382
+ // src/node/container/tabs.ts
1383
+ import { tab as tab2 } from "@mdit/plugin-tab";
1384
+ var tabs = (md) => {
1385
+ tab2(md, {
1386
+ name: "tabs",
1387
+ tabsOpenRenderer: ({ active, data }, tokens, index) => {
1388
+ const { meta } = tokens[index];
1389
+ const titles = data.map(({ title }) => md.renderInline(title));
1390
+ const tabsData = data.map((item, dataIndex) => {
1391
+ const { id = titles[dataIndex] } = item;
1392
+ return { id };
1393
+ });
1394
+ return `<Tabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? "" : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id}"` : ""}>
1395
+ ${titles.map(
1396
+ (title, titleIndex) => `<template #title${titleIndex}="{ value, isActive }">${title}</template>`
1397
+ ).join("")}`;
1398
+ },
1399
+ tabsCloseRenderer: () => `</Tabs>`,
1400
+ tabOpenRenderer: ({ index }) => `<template #tab${index}="{ value, isActive }">`,
1401
+ tabCloseRenderer: () => `</template>`
1402
+ });
1403
+ };
1404
+
1405
+ // src/node/container/index.ts
1406
+ async function containerPlugin(app, md, options) {
1407
+ alignPlugin(md);
1408
+ tabs(md);
1409
+ codeTabs(md, options.codeTabs);
1410
+ if (options.repl)
1411
+ await langReplPlugin(app, md, options.repl);
1412
+ if (options.fileTree) {
1413
+ fileTreePlugin(md, isPlainObject2(options.fileTree) ? options.fileTree : {});
1414
+ }
1415
+ }
1416
+
1417
+ // src/node/embed/caniuse.ts
1418
+ import container4 from "markdown-it-container";
1419
+ import { customAlphabet } from "nanoid";
1420
+
1421
+ // src/node/embed/createEmbedRuleBlock.ts
1422
+ function createEmbedRuleBlock(md, {
1423
+ type: type2,
1424
+ name = type2,
1425
+ syntaxPattern,
1426
+ beforeName = "import_code",
1427
+ ruleOptions = { alt: ["paragraph", "reference", "blockquote", "list"] },
1428
+ meta,
1429
+ content
1430
+ }) {
1431
+ const MIN_LENGTH = type2.length + 5;
1432
+ const START_CODES = [64, 91, ...type2.split("").map((c) => c.charCodeAt(0))];
1433
+ md.block.ruler.before(
1434
+ beforeName,
1435
+ name,
1436
+ (state, startLine, endLine, silent) => {
1437
+ const pos = state.bMarks[startLine] + state.tShift[startLine];
1438
+ const max = state.eMarks[startLine];
1439
+ if (pos + MIN_LENGTH > max)
1440
+ return false;
1441
+ for (let i = 0; i < START_CODES.length; i += 1) {
1442
+ if (state.src.charCodeAt(pos + i) !== START_CODES[i])
1443
+ return false;
1444
+ }
1445
+ const match = state.src.slice(pos, max).match(syntaxPattern);
1446
+ if (!match)
1447
+ return false;
1448
+ if (silent)
1449
+ return true;
1450
+ const token = state.push(name, "", 0);
1451
+ token.meta = meta(match);
1452
+ token.map = [startLine, startLine + 1];
1453
+ state.line = startLine + 1;
1454
+ return true;
1455
+ },
1456
+ ruleOptions
1457
+ );
1458
+ md.renderer.rules[name] = (tokens, index) => {
1459
+ const token = tokens[index];
1460
+ token.content = content(token.meta);
1461
+ return token.content;
1462
+ };
1463
+ }
1464
+
1465
+ // src/node/embed/caniuse.ts
1466
+ var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
1467
+ var UNDERLINE_RE = /_+/g;
1468
+ var caniusePlugin = (md, { mode: defaultMode = "embed" } = {}) => {
1469
+ createEmbedRuleBlock(md, {
1470
+ type: "caniuse",
1471
+ syntaxPattern: /^@\[caniuse\s*(embed|image)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
1472
+ meta: ([, mode, versions = "", feature]) => ({
1473
+ feature,
1474
+ mode: mode || defaultMode,
1475
+ versions
1476
+ }),
1477
+ content: (meta) => resolveCanIUse(meta)
1478
+ });
1479
+ };
1480
+ function legacyCaniuse(md, { mode = "embed" } = {}) {
1481
+ const modeMap = ["image", "embed"];
1482
+ const isMode = (mode2) => modeMap.includes(mode2);
1483
+ mode = isMode(mode) ? mode : modeMap[0];
1484
+ const type2 = "caniuse";
1485
+ const validateReg = new RegExp(`^${type2}`);
1486
+ const validate = (info) => {
1487
+ return validateReg.test(info.trim());
1488
+ };
1489
+ const render = (tokens, index) => {
1490
+ const token = tokens[index];
1491
+ if (token.nesting === 1) {
1492
+ const info = token.info.trim().slice(type2.length).trim() || "";
1493
+ const feature = info.split(/\s+/)[0];
1494
+ const versions = info.match(/\{(.*)\}/)?.[1] || "";
1495
+ return feature ? resolveCanIUse({ feature, mode, versions }) : "";
1496
+ } else {
1497
+ return "";
1498
+ }
1499
+ };
1500
+ md.use(container4, type2, { validate, render });
1501
+ }
1502
+ function resolveCanIUse({ feature, mode, versions }) {
1503
+ if (!feature)
1504
+ return "";
1505
+ if (mode === "image") {
1506
+ const link = "https://caniuse.bitsofco.de/image/";
1507
+ const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`;
1508
+ return `<ClientOnly><p><picture>
1509
+ <source type="image/webp" srcset="${link}${feature}.webp">
1510
+ <source type="image/png" srcset="${link}${feature}.png">
1511
+ <img src="${link}${feature}.jpg" alt="${alt}" width="100%">
1512
+ </picture></p></ClientOnly>`;
1513
+ }
1514
+ feature = feature.replace(UNDERLINE_RE, "_");
1515
+ const { past, future } = resolveVersions(versions);
1516
+ const meta = nanoid();
1517
+ return `<CanIUseViewer feature="${feature}" meta="${meta}" past="${past}" future="${future}" />`;
1518
+ }
1519
+ function resolveVersions(versions) {
1520
+ if (!versions)
1521
+ return { past: 2, future: 1 };
1522
+ const list = versions.split(",").map((v) => Number(v.trim())).filter((v) => !Number.isNaN(v) && v >= -5 && v <= 3);
1523
+ list.push(0);
1524
+ const uniq = [...new Set(list)].sort((a, b) => b - a);
1525
+ return {
1526
+ future: uniq[0],
1527
+ past: Math.abs(uniq[uniq.length - 1])
1528
+ };
1529
+ }
1530
+
1531
+ // src/node/utils/parseRect.ts
1532
+ function parseRect(str, unit = "px") {
1533
+ if (Number.parseFloat(str) === Number(str))
1534
+ return `${str}${unit}`;
1535
+ return str;
1536
+ }
1537
+
1538
+ // src/node/embed/code/codepen.ts
1539
+ var CODEPEN_LINK = "https://codepen.io/";
1540
+ var codepenPlugin = (md) => {
1541
+ createEmbedRuleBlock(md, {
1542
+ type: "codepen",
1543
+ syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
1544
+ meta: ([, info = "", source = ""]) => {
1545
+ const { attrs: attrs2 } = resolveAttrs(info);
1546
+ const [user, slash] = source.split("/");
1517
1547
  return {
1518
- src,
1519
- page: +page || 1,
1520
- noToolbar: Boolean(attrs.noToolbar ?? false),
1521
- zoom: +attrs.zoom || 50,
1522
- width: attrs.width ? parseRect(attrs.width) : "100%",
1523
- height: attrs.height ? parseRect(attrs.height) : "",
1524
- ratio: attrs.ratio ? parseRect(attrs.ratio) : "",
1525
- title: path3.basename(src || "")
1548
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1549
+ height: attrs2.height ? parseRect(attrs2.height) : "400px",
1550
+ user,
1551
+ slash,
1552
+ title: attrs2.title,
1553
+ preview: attrs2.preview,
1554
+ editable: attrs2.editable,
1555
+ tab: attrs2.tab ?? "result",
1556
+ theme: attrs2.theme
1526
1557
  };
1527
1558
  },
1528
- content({ title, src, page, noToolbar, width, height, ratio, zoom }) {
1529
- return `<PDFViewer src="${src}" title="${title}" :page="${page}" :no-toolbar="${noToolbar}" width="${width}" height="${height}" ratio="${ratio}" :zoom="${zoom}" />`;
1559
+ content: (meta) => {
1560
+ const { title = "Codepen", height, width } = meta;
1561
+ const params = new URLSearchParams();
1562
+ if (meta.editable) {
1563
+ params.set("editable", "true");
1564
+ }
1565
+ if (meta.tab) {
1566
+ params.set("default-tab", meta.tab);
1567
+ }
1568
+ if (meta.theme) {
1569
+ params.set("theme-id", meta.theme);
1570
+ }
1571
+ const middle = meta.preview ? "/embed/preview/" : "/embed/";
1572
+ const link = `${CODEPEN_LINK}${meta.user}${middle}${meta.slash}?${params.toString()}`;
1573
+ const style = `width:${width};height:${height};margin:16px auto;border-radius:5px;`;
1574
+ return `<iframe class="code-pen-iframe-wrapper" src="${link}" title="${title}" style="${style}" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">See the Pen <a href="${CODEPEN_LINK}${meta.user}/pen/${meta.slash}">${title}</a> by ${meta.user} (<a href="${CODEPEN_LINK}${meta.user}">@${meta.user}</a>) on <a href="${CODEPEN_LINK}">CodePen</a>.</iframe>`;
1530
1575
  }
1531
1576
  });
1532
1577
  };
1533
1578
 
1534
- // src/node/features/plot.ts
1535
- var [openTag2, endTag2] = ["!!", "!!"];
1536
- function createTokenizer2() {
1537
- return (state, silent) => {
1538
- let found = false;
1539
- const max = state.posMax;
1540
- const start = state.pos;
1541
- if (state.src.slice(start, start + 2) !== openTag2)
1542
- return false;
1543
- if (silent)
1544
- return false;
1545
- if (max - start < 5)
1546
- return false;
1547
- state.pos = start + 2;
1548
- while (state.pos < max) {
1549
- if (state.src.slice(state.pos - 1, state.pos + 1) === endTag2) {
1550
- found = true;
1551
- break;
1552
- }
1553
- state.md.inline.skipToken(state);
1554
- }
1555
- if (!found || start + 2 === state.pos) {
1556
- state.pos = start;
1557
- return false;
1579
+ // src/node/embed/code/codeSandbox.ts
1580
+ var codeSandboxPlugin = (md) => {
1581
+ createEmbedRuleBlock(md, {
1582
+ type: "codesandbox",
1583
+ syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
1584
+ meta([, type2, info = "", source = ""]) {
1585
+ const { attrs: attrs2 } = resolveAttrs(info);
1586
+ const [profile, filepath2 = ""] = source.split("#");
1587
+ const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
1588
+ return {
1589
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1590
+ height: attrs2.height ? parseRect(attrs2.height) : "500px",
1591
+ user,
1592
+ id,
1593
+ title: attrs2.title ?? "",
1594
+ console: attrs2.console ?? false,
1595
+ navbar: attrs2.navbar ?? true,
1596
+ layout: attrs2.layout ?? "",
1597
+ type: type2 || "embed",
1598
+ filepath: filepath2
1599
+ };
1600
+ },
1601
+ content({ title, height, width, user, id, type: type2, filepath: filepath2, console, navbar, layout }) {
1602
+ return `<CodeSandboxViewer title="${title}" height="${height}" width="${width}" user="${user}" id="${id}" type="${type2}" filepath="${filepath2}" :console=${console} :navbar=${navbar} layout="${layout}" />`;
1558
1603
  }
1559
- const content = state.src.slice(start + 2, state.pos - 1);
1560
- if (/^\s|\s$/.test(content)) {
1561
- state.pos = start;
1562
- return false;
1604
+ });
1605
+ };
1606
+
1607
+ // src/node/embed/code/jsfiddle.ts
1608
+ var jsfiddlePlugin = (md) => {
1609
+ createEmbedRuleBlock(md, {
1610
+ type: "jsfiddle",
1611
+ syntaxPattern: /^@\[jsfiddle([^\]]*)\]\(([^)]*)\)/,
1612
+ meta([, info = "", source]) {
1613
+ const { attrs: attrs2 } = resolveAttrs(info);
1614
+ const [user, id] = source.split("/");
1615
+ return {
1616
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1617
+ height: attrs2.height ? parseRect(attrs2.height) : "400px",
1618
+ user,
1619
+ id,
1620
+ title: attrs2.title || "JS Fiddle",
1621
+ tab: attrs2.tab?.replace(/\s+/g, "") || "js,css,html,result",
1622
+ theme: attrs2.theme || "dark"
1623
+ };
1624
+ },
1625
+ content: ({ title = "JS Fiddle", height, width, user, id, tab: tab3, theme }) => {
1626
+ theme = theme === "dark" ? "/dark/" : "";
1627
+ const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab3}${theme}`;
1628
+ const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
1629
+ return `<iframe class="js-fiddle-iframe-wrapper" style="${style}" title="${title}" src="${link}" allowfullscreen="true" allowpaymentrequest="true"></iframe>`;
1563
1630
  }
1564
- state.posMax = state.pos - 1;
1565
- state.pos = start + 2;
1566
- const open = state.push("plot_open", "Plot", 1);
1567
- open.markup = openTag2;
1568
- const text = state.push("text", "", 0);
1569
- text.content = content;
1570
- const close = state.push("plot_close", "Plot", -1);
1571
- close.markup = endTag2;
1572
- state.pos = state.posMax + 2;
1573
- state.posMax = max;
1574
- return true;
1575
- };
1576
- }
1577
- var plotPlugin = (md) => {
1578
- md.inline.ruler.before("emphasis", "plot", createTokenizer2());
1631
+ });
1579
1632
  };
1580
1633
 
1581
- // src/node/features/replit.ts
1634
+ // src/node/embed/code/replit.ts
1582
1635
  var replitPlugin = (md) => {
1583
- createRuleBlock(md, {
1636
+ createEmbedRuleBlock(md, {
1584
1637
  type: "replit",
1585
1638
  syntaxPattern: /^@\[replit([^\]]*)\]\(([^)]*)\)/,
1586
1639
  meta: ([, info = "", source = ""]) => {
1587
- const { attrs } = resolveAttrs(info);
1640
+ const { attrs: attrs2 } = resolveAttrs(info);
1588
1641
  return {
1589
- width: attrs.width ? parseRect(attrs.width) : "100%",
1590
- height: attrs.height ? parseRect(attrs.height) : "450px",
1642
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1643
+ height: attrs2.height ? parseRect(attrs2.height) : "450px",
1591
1644
  source: source.startsWith("@") ? source : `@${source}`,
1592
- title: attrs.title,
1593
- theme: attrs.theme || ""
1645
+ title: attrs2.title,
1646
+ theme: attrs2.theme || ""
1594
1647
  };
1595
1648
  },
1596
1649
  content({ title, height, width, source, theme }) {
@@ -1599,7 +1652,33 @@ var replitPlugin = (md) => {
1599
1652
  });
1600
1653
  };
1601
1654
 
1602
- // src/node/features/video/bilibili.ts
1655
+ // src/node/embed/pdf.ts
1656
+ import { path as path3 } from "vuepress/utils";
1657
+ var pdfPlugin = (md) => {
1658
+ createEmbedRuleBlock(md, {
1659
+ type: "pdf",
1660
+ // eslint-disable-next-line regexp/no-super-linear-backtracking
1661
+ syntaxPattern: /^@\[pdf(?:\s+(\d+))?([^\]]*)\]\(([^)]*)\)/,
1662
+ meta([, page, info = "", src = ""]) {
1663
+ const { attrs: attrs2 } = resolveAttrs(info);
1664
+ return {
1665
+ src,
1666
+ page: +page || 1,
1667
+ noToolbar: Boolean(attrs2.noToolbar ?? false),
1668
+ zoom: +attrs2.zoom || 50,
1669
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1670
+ height: attrs2.height ? parseRect(attrs2.height) : "",
1671
+ ratio: attrs2.ratio ? parseRect(attrs2.ratio) : "",
1672
+ title: path3.basename(src || "")
1673
+ };
1674
+ },
1675
+ content({ title, src, page, noToolbar, width, height, ratio, zoom }) {
1676
+ return `<PDFViewer src="${src}" title="${title}" :page="${page}" :no-toolbar="${noToolbar}" width="${width}" height="${height}" ratio="${ratio}" :zoom="${zoom}" />`;
1677
+ }
1678
+ });
1679
+ };
1680
+
1681
+ // src/node/embed/video/bilibili.ts
1603
1682
  import { URLSearchParams as URLSearchParams2 } from "node:url";
1604
1683
 
1605
1684
  // src/node/utils/timeToSeconds.ts
@@ -1612,16 +1691,16 @@ function timeToSeconds(time) {
1612
1691
  return s + m * 60 + h * 3600;
1613
1692
  }
1614
1693
 
1615
- // src/node/features/video/bilibili.ts
1694
+ // src/node/embed/video/bilibili.ts
1616
1695
  var BILIBILI_LINK = "https://player.bilibili.com/player.html";
1617
1696
  var bilibiliPlugin = (md) => {
1618
- createRuleBlock(md, {
1697
+ createEmbedRuleBlock(md, {
1619
1698
  type: "bilibili",
1620
1699
  name: "video_bilibili",
1621
1700
  // eslint-disable-next-line regexp/no-super-linear-backtracking
1622
1701
  syntaxPattern: /^@\[bilibili(?:\s+p(\d+))?([^\]]*)\]\(([^)]*)\)/,
1623
1702
  meta([, page, info = "", source = ""]) {
1624
- const { attrs } = resolveAttrs(info);
1703
+ const { attrs: attrs2 } = resolveAttrs(info);
1625
1704
  const ids = source.trim().split(/\s+/);
1626
1705
  const bvid = ids.find((id) => id.startsWith("BV"));
1627
1706
  const [aid, cid] = ids.filter((id) => !id.startsWith("BV"));
@@ -1630,12 +1709,12 @@ var bilibiliPlugin = (md) => {
1630
1709
  bvid,
1631
1710
  aid,
1632
1711
  cid,
1633
- autoplay: attrs.autoplay ?? false,
1634
- time: timeToSeconds(attrs.time),
1635
- title: attrs.title,
1636
- width: attrs.width ? parseRect(attrs.width) : "100%",
1637
- height: attrs.height ? parseRect(attrs.height) : "",
1638
- ratio: attrs.ratio ? parseRect(attrs.ratio) : ""
1712
+ autoplay: attrs2.autoplay ?? false,
1713
+ time: timeToSeconds(attrs2.time),
1714
+ title: attrs2.title,
1715
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1716
+ height: attrs2.height ? parseRect(attrs2.height) : "",
1717
+ ratio: attrs2.ratio ? parseRect(attrs2.ratio) : ""
1639
1718
  };
1640
1719
  },
1641
1720
  content(meta) {
@@ -1662,26 +1741,26 @@ var bilibiliPlugin = (md) => {
1662
1741
  });
1663
1742
  };
1664
1743
 
1665
- // src/node/features/video/youtube.ts
1744
+ // src/node/embed/video/youtube.ts
1666
1745
  import { URLSearchParams as URLSearchParams3 } from "node:url";
1667
1746
  var YOUTUBE_LINK = "https://www.youtube.com/embed/";
1668
1747
  var youtubePlugin = (md) => {
1669
- createRuleBlock(md, {
1748
+ createEmbedRuleBlock(md, {
1670
1749
  type: "youtube",
1671
1750
  name: "video_youtube",
1672
1751
  syntaxPattern: /^@\[youtube([^\]]*)\]\(([^)]*)\)/,
1673
1752
  meta([, info = "", id = ""]) {
1674
- const { attrs } = resolveAttrs(info);
1753
+ const { attrs: attrs2 } = resolveAttrs(info);
1675
1754
  return {
1676
1755
  id,
1677
- autoplay: attrs.autoplay ?? false,
1678
- loop: attrs.loop ?? false,
1679
- start: timeToSeconds(attrs.start),
1680
- end: timeToSeconds(attrs.end),
1681
- title: attrs.title,
1682
- width: attrs.width ? parseRect(attrs.width) : "100%",
1683
- height: attrs.height ? parseRect(attrs.height) : "",
1684
- ratio: attrs.ratio ? parseRect(attrs.ratio) : ""
1756
+ autoplay: attrs2.autoplay ?? false,
1757
+ loop: attrs2.loop ?? false,
1758
+ start: timeToSeconds(attrs2.start),
1759
+ end: timeToSeconds(attrs2.end),
1760
+ title: attrs2.title,
1761
+ width: attrs2.width ? parseRect(attrs2.width) : "100%",
1762
+ height: attrs2.height ? parseRect(attrs2.height) : "",
1763
+ ratio: attrs2.ratio ? parseRect(attrs2.ratio) : ""
1685
1764
  };
1686
1765
  },
1687
1766
  content(meta) {
@@ -1704,6 +1783,157 @@ var youtubePlugin = (md) => {
1704
1783
  });
1705
1784
  };
1706
1785
 
1786
+ // src/node/embed/index.ts
1787
+ function embedSyntaxPlugin(md, options) {
1788
+ if (options.caniuse) {
1789
+ const caniuse = options.caniuse === true ? {} : options.caniuse;
1790
+ md.use(caniusePlugin, caniuse);
1791
+ legacyCaniuse(md, caniuse);
1792
+ }
1793
+ if (options.pdf) {
1794
+ md.use(pdfPlugin);
1795
+ }
1796
+ if (options.bilibili) {
1797
+ md.use(bilibiliPlugin);
1798
+ }
1799
+ if (options.youtube) {
1800
+ md.use(youtubePlugin);
1801
+ }
1802
+ if (options.codepen) {
1803
+ md.use(codepenPlugin);
1804
+ }
1805
+ if (options.replit) {
1806
+ md.use(replitPlugin);
1807
+ }
1808
+ if (options.codeSandbox) {
1809
+ md.use(codeSandboxPlugin);
1810
+ }
1811
+ if (options.jsfiddle) {
1812
+ md.use(jsfiddlePlugin);
1813
+ }
1814
+ }
1815
+
1816
+ // src/node/inline/index.ts
1817
+ import { attrs } from "@mdit/plugin-attrs";
1818
+ import { footnote } from "@mdit/plugin-footnote";
1819
+ import { mark } from "@mdit/plugin-mark";
1820
+ import { sub } from "@mdit/plugin-sub";
1821
+ import { sup } from "@mdit/plugin-sup";
1822
+ import { tasklist } from "@mdit/plugin-tasklist";
1823
+ import { isPlainObject as isPlainObject3 } from "@vuepress/helper";
1824
+
1825
+ // src/node/inline/icons.ts
1826
+ var [openTag, endTag] = [":[", "]:"];
1827
+ var iconsPlugin = (md, options = {}) => md.inline.ruler.before("emphasis", "iconify", createTokenizer(options));
1828
+ function createTokenizer(options) {
1829
+ return (state, silent) => {
1830
+ let found = false;
1831
+ const max = state.posMax;
1832
+ const start = state.pos;
1833
+ if (state.src.slice(start, start + 2) !== openTag)
1834
+ return false;
1835
+ if (silent)
1836
+ return false;
1837
+ if (max - start < 5)
1838
+ return false;
1839
+ state.pos = start + 2;
1840
+ while (state.pos < max) {
1841
+ if (state.src.slice(state.pos, state.pos + 2) === endTag) {
1842
+ found = true;
1843
+ break;
1844
+ }
1845
+ state.md.inline.skipToken(state);
1846
+ }
1847
+ if (!found || start + 2 === state.pos) {
1848
+ state.pos = start;
1849
+ return false;
1850
+ }
1851
+ const content = state.src.slice(start + 2, state.pos);
1852
+ if (/^\s|\s$/.test(content)) {
1853
+ state.pos = start;
1854
+ return false;
1855
+ }
1856
+ state.posMax = state.pos;
1857
+ state.pos = start + 2;
1858
+ const [name, opt = ""] = content.split(/\s+/);
1859
+ const [size = options.size, color = options.color] = opt.split("/");
1860
+ const icon = state.push("vp_iconify_open", "VPIcon", 1);
1861
+ icon.markup = openTag;
1862
+ if (name)
1863
+ icon.attrSet("name", name);
1864
+ if (size)
1865
+ icon.attrSet("size", String(size));
1866
+ if (color)
1867
+ icon.attrSet("color", color);
1868
+ const close = state.push("vp_iconify_close", "VPIcon", -1);
1869
+ close.markup = endTag;
1870
+ state.pos = state.posMax + 2;
1871
+ state.posMax = max;
1872
+ return true;
1873
+ };
1874
+ }
1875
+
1876
+ // src/node/inline/plot.ts
1877
+ var [openTag2, endTag2] = ["!!", "!!"];
1878
+ var plotPlugin = (md) => md.inline.ruler.before("emphasis", "plot", createTokenizer2());
1879
+ function createTokenizer2() {
1880
+ return (state, silent) => {
1881
+ let found = false;
1882
+ const max = state.posMax;
1883
+ const start = state.pos;
1884
+ if (state.src.slice(start, start + 2) !== openTag2)
1885
+ return false;
1886
+ if (silent)
1887
+ return false;
1888
+ if (max - start < 5)
1889
+ return false;
1890
+ state.pos = start + 2;
1891
+ while (state.pos < max) {
1892
+ if (state.src.slice(state.pos - 1, state.pos + 1) === endTag2) {
1893
+ found = true;
1894
+ break;
1895
+ }
1896
+ state.md.inline.skipToken(state);
1897
+ }
1898
+ if (!found || start + 2 === state.pos) {
1899
+ state.pos = start;
1900
+ return false;
1901
+ }
1902
+ const content = state.src.slice(start + 2, state.pos - 1);
1903
+ if (/^\s|\s$/.test(content)) {
1904
+ state.pos = start;
1905
+ return false;
1906
+ }
1907
+ state.posMax = state.pos - 1;
1908
+ state.pos = start + 2;
1909
+ const open = state.push("plot_open", "Plot", 1);
1910
+ open.markup = openTag2;
1911
+ const text = state.push("text", "", 0);
1912
+ text.content = content;
1913
+ const close = state.push("plot_close", "Plot", -1);
1914
+ close.markup = endTag2;
1915
+ state.pos = state.posMax + 2;
1916
+ state.posMax = max;
1917
+ return true;
1918
+ };
1919
+ }
1920
+
1921
+ // src/node/inline/index.ts
1922
+ function inlineSyntaxPlugin(md, options) {
1923
+ md.use(attrs);
1924
+ md.use(mark);
1925
+ md.use(sub);
1926
+ md.use(sup);
1927
+ md.use(footnote);
1928
+ md.use(tasklist);
1929
+ if (options.icons) {
1930
+ md.use(iconsPlugin, isPlainObject3(options.icons) ? options.icons : {});
1931
+ }
1932
+ if (options.plot === true || isPlainObject3(options.plot) && options.plot.tag !== false) {
1933
+ md.use(plotPlugin);
1934
+ }
1935
+ }
1936
+
1707
1937
  // src/node/prepareConfigFile.ts
1708
1938
  import { ensureEndingSlash } from "@vuepress/helper";
1709
1939
  import { getDirname as getDirname2, path as path4 } from "vuepress/utils";
@@ -1715,6 +1945,10 @@ var CLIENT_FOLDER = ensureEndingSlash(
1715
1945
  async function prepareConfigFile(app, options) {
1716
1946
  const imports = /* @__PURE__ */ new Set();
1717
1947
  const enhances = /* @__PURE__ */ new Set();
1948
+ imports.add(`import Tabs from '${CLIENT_FOLDER}components/Tabs.vue'`);
1949
+ enhances.add(`app.component('Tabs', Tabs)`);
1950
+ imports.add(`import CodeTabs from '${CLIENT_FOLDER}components/CodeTabs.vue'`);
1951
+ enhances.add(`app.component('CodeTabs', CodeTabs)`);
1718
1952
  if (options.pdf) {
1719
1953
  imports.add(`import PDFViewer from '${CLIENT_FOLDER}components/PDFViewer.vue'`);
1720
1954
  enhances.add(`app.component('PDFViewer', PDFViewer)`);
@@ -1767,63 +2001,23 @@ ${Array.from(enhances.values()).map((item) => ` ${item}`).join("\n")}
1767
2001
 
1768
2002
  // src/node/plugin.ts
1769
2003
  function markdownPowerPlugin(options = {}) {
1770
- return (app) => {
1771
- return {
1772
- name: "vuepress-plugin-md-power",
1773
- clientConfigFile: (app2) => prepareConfigFile(app2, options),
1774
- define: {
1775
- __MD_POWER_INJECT_OPTIONS__: options
1776
- },
1777
- extendsBundlerOptions(bundlerOptions) {
1778
- if (options.repl) {
1779
- addViteOptimizeDepsInclude(
1780
- bundlerOptions,
1781
- app,
1782
- ["shiki/core", "shiki/wasm"]
1783
- );
1784
- }
1785
- },
1786
- extendsMarkdown: async (md, app2) => {
1787
- await imageSizePlugin(app2, md, options.imageSize);
1788
- if (options.caniuse) {
1789
- const caniuse = options.caniuse === true ? {} : options.caniuse;
1790
- md.use(caniusePlugin, caniuse);
1791
- legacyCaniuse(md, caniuse);
1792
- }
1793
- if (options.pdf) {
1794
- md.use(pdfPlugin);
1795
- }
1796
- if (options.icons) {
1797
- md.use(iconsPlugin);
1798
- }
1799
- if (options.bilibili) {
1800
- md.use(bilibiliPlugin);
1801
- }
1802
- if (options.youtube) {
1803
- md.use(youtubePlugin);
1804
- }
1805
- if (options.codepen) {
1806
- md.use(codepenPlugin);
1807
- }
1808
- if (options.replit) {
1809
- md.use(replitPlugin);
1810
- }
1811
- if (options.codeSandbox) {
1812
- md.use(codeSandboxPlugin);
1813
- }
1814
- if (options.jsfiddle) {
1815
- md.use(jsfiddlePlugin);
1816
- }
1817
- if (options.plot === true || typeof options.plot === "object" && options.plot.tag !== false) {
1818
- md.use(plotPlugin);
1819
- }
1820
- if (options.repl)
1821
- await langReplPlugin(app2, md, options.repl);
1822
- if (options.fileTree) {
1823
- fileTreePlugin(md);
1824
- }
2004
+ return {
2005
+ name: "vuepress-plugin-md-power",
2006
+ clientConfigFile: (app) => prepareConfigFile(app, options),
2007
+ define: {
2008
+ __MD_POWER_INJECT_OPTIONS__: options
2009
+ },
2010
+ extendsBundlerOptions(bundlerOptions, app) {
2011
+ if (options.repl) {
2012
+ addViteOptimizeDepsInclude(bundlerOptions, app, ["shiki/core", "shiki/wasm"]);
1825
2013
  }
1826
- };
2014
+ },
2015
+ extendsMarkdown: async (md, app) => {
2016
+ embedSyntaxPlugin(md, options);
2017
+ inlineSyntaxPlugin(md, options);
2018
+ await containerPlugin(app, md, options);
2019
+ await imageSizePlugin(app, md, options.imageSize);
2020
+ }
1827
2021
  };
1828
2022
  }
1829
2023
  export {