vuepress-plugin-md-power 1.0.0-rc.113 → 1.0.0-rc.115

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.
@@ -0,0 +1,140 @@
1
+ .vp-doc .demo-wrapper {
2
+ display: flex;
3
+ flex-direction: column;
4
+ min-height: 40px;
5
+ margin: 40px -16px;
6
+ border: solid 1px var(--vp-c-divider);
7
+ border-radius: 8px;
8
+ box-shadow: var(--vp-shadow-2);
9
+ transition: var(--vp-t-color);
10
+ transition-property: border, box-shadow;
11
+ }
12
+
13
+ .vp-doc .demo-wrapper .demo-head {
14
+ display: flex;
15
+ align-items: center;
16
+ justify-content: flex-start;
17
+ min-height: 0;
18
+ border-bottom: solid 1px var(--vp-c-divider);
19
+ transition: border-bottom var(--vp-t-color);
20
+ }
21
+
22
+ .vp-doc .demo-wrapper .demo-container {
23
+ min-height: 0;
24
+ padding: 20px;
25
+ font-size: 14px;
26
+ line-height: 22px;
27
+ background-color: var(--vp-c-bg-alt);
28
+ border-bottom-right-radius: 8px;
29
+ border-bottom-left-radius: 8px;
30
+ transition: background-color var(--vp-t-color);
31
+ }
32
+
33
+ .vp-doc .demo-wrapper.has-title .demo-head {
34
+ border-bottom-color: transparent;
35
+ }
36
+
37
+ .vp-doc .demo-wrapper.only-img {
38
+ overflow: hidden;
39
+ }
40
+
41
+ .vp-doc .demo-wrapper.only-img img {
42
+ display: block;
43
+ }
44
+
45
+ .vp-doc .demo-wrapper.only-img .demo-container,
46
+ .vp-doc .demo-wrapper.no-padding .demo-container {
47
+ padding: 0;
48
+ }
49
+
50
+ .vp-doc .demo-wrapper.has-height .demo-container {
51
+ height: var(--demo-container-height);
52
+ overflow-y: auto;
53
+ }
54
+
55
+ .vp-doc .demo-wrapper .demo-ctrl {
56
+ display: flex;
57
+ gap: 5px;
58
+ align-items: center;
59
+ justify-content: flex-start;
60
+ padding: 5px 0 5px 8px;
61
+ }
62
+
63
+ .vp-doc .demo-wrapper .demo-ctrl i {
64
+ display: inline-block;
65
+ width: 10px;
66
+ height: 10px;
67
+ background-color: #ccc;
68
+ border-radius: 100%;
69
+ transition: background-color var(--vp-t-color);
70
+ }
71
+
72
+ .vp-doc .demo-wrapper .demo-ctrl i:nth-child(1) {
73
+ background-color: var(--vp-c-danger-3);
74
+ }
75
+
76
+ .vp-doc .demo-wrapper .demo-ctrl i:nth-child(2) {
77
+ background-color: var(--vp-c-warning-3);
78
+ }
79
+
80
+ .vp-doc .demo-wrapper .demo-ctrl i:nth-child(3) {
81
+ background-color: var(--vp-c-green-3);
82
+ }
83
+
84
+ .vp-doc .demo-wrapper .demo-title {
85
+ position: relative;
86
+ min-width: 0;
87
+ padding: 0 16px;
88
+ margin: 0 20px -1px;
89
+ font-size: 14px;
90
+ font-weight: 500;
91
+ color: var(--vp-c-text-2);
92
+ background-color: var(--vp-c-bg-alt);
93
+ border-top-left-radius: 8px;
94
+ border-top-right-radius: 8px;
95
+ transition: var(--vp-t-color);
96
+ transition-property: color, background-color;
97
+ }
98
+
99
+ .vp-doc .demo-wrapper .demo-title p {
100
+ max-width: 100%;
101
+ margin: 0;
102
+ overflow: hidden;
103
+ text-overflow: ellipsis;
104
+ text-wrap: nowrap;
105
+ }
106
+
107
+ .vp-doc .demo-wrapper .demo-title::after,
108
+ .vp-doc .demo-wrapper .demo-title::before {
109
+ position: absolute;
110
+ bottom: 0;
111
+ z-index: 1;
112
+ width: 8px;
113
+ height: 8px;
114
+ content: " ";
115
+ transition: background var(--vp-t-color);
116
+ }
117
+
118
+ .vp-doc .demo-wrapper .demo-title::before {
119
+ left: 100%;
120
+ background: radial-gradient(16px at right top, transparent 50%, var(--vp-c-bg-alt) 50%);
121
+ }
122
+
123
+ .vp-doc .demo-wrapper .demo-title::after {
124
+ right: 100%;
125
+ background: radial-gradient(16px at left top, transparent 50%, var(--vp-c-bg-alt) 50%);
126
+ }
127
+
128
+ .vp-doc .demo-wrapper .demo-container > *:first-child {
129
+ margin-top: 0;
130
+ }
131
+
132
+ .vp-doc .demo-wrapper .demo-container > *:last-child {
133
+ margin-bottom: 0;
134
+ }
135
+
136
+ @media (min-width: 419px) {
137
+ .vp-doc .demo-wrapper {
138
+ margin: 40px 0;
139
+ }
140
+ }
@@ -0,0 +1,4 @@
1
+ @charset "UTF-8";
2
+
3
+ @import url("./demo-wrapper.css");
4
+ @import url("./steps.css");
@@ -0,0 +1,69 @@
1
+ .vp-doc .vp-steps {
2
+ margin: 16px 0;
3
+ }
4
+
5
+ .vp-doc .vp-steps > ol,
6
+ .vp-doc .vp-steps > ul {
7
+ padding-inline-start: 0;
8
+ list-style: none;
9
+ }
10
+
11
+ .vp-doc .vp-steps > ol > li,
12
+ .vp-doc .vp-steps > ul > li {
13
+ position: relative;
14
+ min-height: 22px;
15
+ padding-bottom: 1px;
16
+ padding-left: 44px;
17
+ }
18
+
19
+ .vp-doc .vp-steps > ol > li::before,
20
+ .vp-doc .vp-steps > ul > li::before {
21
+ position: absolute;
22
+ inset-inline-start: 0;
23
+ top: 0;
24
+ width: 28px;
25
+ height: 28px;
26
+ font-size: 16px;
27
+ font-weight: 400;
28
+ line-height: 28px;
29
+ color: var(--vp-c-text-1);
30
+ text-align: center;
31
+ content: counter(list-item);
32
+ background-color: var(--vp-c-bg-soft);
33
+ border: solid 1px var(--vp-c-divider);
34
+ border-radius: 100%;
35
+ transition: var(--vp-t-color);
36
+ transition-property: color, background-color, border-color;
37
+ }
38
+
39
+ .vp-doc .vp-steps > ol > li:not(:last-of-type)::after,
40
+ .vp-doc .vp-steps > ul > li:not(:last-of-type)::after {
41
+ position: absolute;
42
+ inset-inline-start: 14px;
43
+ top: 34px;
44
+ bottom: 5px;
45
+ width: 1px;
46
+ content: "";
47
+ background-color: var(--vp-c-divider);
48
+ transition: background-color var(--vp-t-color);
49
+ }
50
+
51
+ .vp-doc .vp-steps > ol > li > :first-child,
52
+ .vp-doc .vp-steps > ul > li > :first-child {
53
+ margin-top: 0;
54
+ }
55
+
56
+ .vp-doc .vp-steps > ol > li > :first-child:where(h1,h2,h3,h4,h5,h6),
57
+ .vp-doc .vp-steps > ul > li > :first-child:where(h1,h2,h3,h4,h5,h6) {
58
+ padding-top: 0;
59
+ border-top: none;
60
+ }
61
+
62
+ .vp-doc .vp-steps > ol > li > :first-child:where(p) {
63
+ line-height: 28px;
64
+ }
65
+
66
+ .vp-doc .vp-steps > ol > li + li,
67
+ .vp-doc .vp-steps > ul > li + li {
68
+ margin-top: 1px;
69
+ }
package/lib/node/index.js CHANGED
@@ -216,24 +216,47 @@ import { addViteOptimizeDepsInclude } from "@vuepress/helper";
216
216
  // src/node/container/index.ts
217
217
  import { isPlainObject as isPlainObject2 } from "@vuepress/helper";
218
218
 
219
- // src/node/container/align.ts
219
+ // src/node/container/createContainer.ts
220
220
  import container from "markdown-it-container";
221
+ function createContainerPlugin(md, type2, options = {}) {
222
+ const render = (tokens, index) => {
223
+ const token = tokens[index];
224
+ const info = token.info.trim().slice(type2.length).trim() || "";
225
+ if (token.nesting === 1) {
226
+ return options.before?.(info, tokens, index) || `<div class="custom-container ${type2}">`;
227
+ } else {
228
+ return options.after?.(info, tokens, index) || "</div>";
229
+ }
230
+ };
231
+ md.use(container, type2, { render });
232
+ }
233
+
234
+ // src/node/container/align.ts
221
235
  var alignList = ["left", "center", "right", "justify"];
222
236
  function alignPlugin(md) {
223
237
  for (const name of alignList) {
224
- md.use(container, name, {
225
- validate: (info) => info.trim() === name,
226
- render: (tokens, idx) => {
227
- if (tokens[idx].nesting === 1) {
228
- return `<div style="text-align:${name}">`;
229
- } else {
230
- return "</div>";
231
- }
232
- }
238
+ createContainerPlugin(md, name, {
239
+ before: () => `<div style="text-align:${name}">`
233
240
  });
234
241
  }
235
242
  }
236
243
 
244
+ // src/node/container/card.ts
245
+ function cardPlugin(md) {
246
+ createContainerPlugin(md, "card", {
247
+ before(info) {
248
+ const { attrs: attrs2 } = resolveAttrs(info);
249
+ const { title, icon } = attrs2;
250
+ return `<VPCard${title ? ` title="${title}"` : ""}${icon ? ` icon="${icon}"` : ""}>`;
251
+ },
252
+ after: () => "</VPCard>"
253
+ });
254
+ createContainerPlugin(md, "card-grid", {
255
+ before: () => "<VPCardGrid>",
256
+ after: () => "</VPCardGrid>"
257
+ });
258
+ }
259
+
237
260
  // src/node/container/codeTabs.ts
238
261
  import { tab } from "@mdit/plugin-tab";
239
262
  import { isPlainObject } from "@vuepress/helper";
@@ -1156,6 +1179,36 @@ var codeTabs = (md, options = {}) => {
1156
1179
  });
1157
1180
  };
1158
1181
 
1182
+ // src/node/container/demoWrapper.ts
1183
+ function demoWrapperPlugin(md) {
1184
+ createContainerPlugin(md, "demo-wrapper", {
1185
+ before: (info) => {
1186
+ const { attrs: attrs2 } = resolveAttrs(info);
1187
+ const wrapperClasses = ["demo-wrapper"];
1188
+ let containerStyle = "";
1189
+ if (attrs2.title)
1190
+ wrapperClasses.push("has-title");
1191
+ if (attrs2.img)
1192
+ wrapperClasses.push("only-img");
1193
+ if (attrs2.noPadding)
1194
+ wrapperClasses.push("no-padding");
1195
+ if (attrs2.height) {
1196
+ const h = Number.parseFloat(attrs2.height) === Number(attrs2.height) ? `${attrs2.height}px` : attrs2.height;
1197
+ containerStyle += `--demo-container-height: ${h};`;
1198
+ wrapperClasses.push("has-height");
1199
+ }
1200
+ return `<div class="${wrapperClasses.join(" ")}">
1201
+ <div class="demo-head">
1202
+ <div class="demo-ctrl"><i></i><i></i><i></i></div>
1203
+ ${attrs2.title ? `<h4 class="demo-title"><p>${attrs2.title}</p></h4>` : ""}
1204
+ </div>
1205
+ <div class="demo-container" ${containerStyle ? `style="${containerStyle}"` : ""}>
1206
+ `;
1207
+ },
1208
+ after: () => "</div></div>"
1209
+ });
1210
+ }
1211
+
1159
1212
  // src/node/container/fileTree.ts
1160
1213
  import Token from "markdown-it/lib/token.mjs";
1161
1214
  import container2 from "markdown-it-container";
@@ -1172,7 +1225,6 @@ function fileTreePlugin(md, options = {}) {
1172
1225
  return type2 === "folder" ? defaultFolder : defaultFile;
1173
1226
  return getFileIcon(filename, type2);
1174
1227
  };
1175
- const validate = (info) => info.trim().startsWith(type);
1176
1228
  const render = (tokens, idx) => {
1177
1229
  const { attrs: attrs2 } = resolveAttrs(tokens[idx].info.slice(type.length - 1));
1178
1230
  if (tokens[idx].nesting === 1) {
@@ -1208,7 +1260,7 @@ function fileTreePlugin(md, options = {}) {
1208
1260
  return "</div>";
1209
1261
  }
1210
1262
  };
1211
- md.use(container2, type, { validate, render });
1263
+ md.use(container2, type, { render });
1212
1264
  }
1213
1265
  function resolveTreeNodeInfo(tokens, current, idx) {
1214
1266
  let hasInline = false;
@@ -1554,7 +1606,6 @@ var MANAGERS_CONFIG = {
1554
1606
  };
1555
1607
  function npmToPlugins(md, options = {}) {
1556
1608
  const type2 = "npm-to";
1557
- const validate = (info) => info.trim().startsWith(type2);
1558
1609
  const opt = isArray(options) ? { tabs: options } : options;
1559
1610
  const defaultTabs = opt.tabs?.length ? opt.tabs : DEFAULT_TABS;
1560
1611
  const render = (tokens, idx) => {
@@ -1574,7 +1625,7 @@ function npmToPlugins(md, options = {}) {
1574
1625
  }
1575
1626
  return "";
1576
1627
  };
1577
- md.use(container4, type2, { validate, render });
1628
+ md.use(container4, type2, { render });
1578
1629
  }
1579
1630
  function resolveNpmTo(lines, info, idx, tabs2) {
1580
1631
  tabs2 = validateTabs(tabs2);
@@ -1712,6 +1763,13 @@ function parseArgs(line) {
1712
1763
  return { cmd: cmd.trim(), args: args.trim(), scriptArgs };
1713
1764
  }
1714
1765
 
1766
+ // src/node/container/steps.ts
1767
+ function stepsPlugin(md) {
1768
+ createContainerPlugin(md, "steps", {
1769
+ before: () => '<div class="vp-steps">'
1770
+ });
1771
+ }
1772
+
1715
1773
  // src/node/container/tabs.ts
1716
1774
  import { tab as tab2 } from "@mdit/plugin-tab";
1717
1775
  var tabs = (md) => {
@@ -1740,6 +1798,9 @@ async function containerPlugin(app, md, options) {
1740
1798
  alignPlugin(md);
1741
1799
  tabs(md);
1742
1800
  codeTabs(md, options.codeTabs);
1801
+ demoWrapperPlugin(md);
1802
+ stepsPlugin(md);
1803
+ cardPlugin(md);
1743
1804
  if (options.npmTo) {
1744
1805
  npmToPlugins(md, typeof options.npmTo === "boolean" ? {} : options.npmTo);
1745
1806
  }
@@ -2149,6 +2210,44 @@ function embedSyntaxPlugin(md, options) {
2149
2210
  }
2150
2211
  }
2151
2212
 
2213
+ // src/node/enhance/docsTitle.ts
2214
+ var REG_HEADING = /^#\s*?([^#\s].*)?\n/;
2215
+ function docsTitlePlugin(md) {
2216
+ const render = md.render;
2217
+ md.render = (source, env) => {
2218
+ if (!env.filePathRelative)
2219
+ return render(source, env);
2220
+ let { matter, content } = parseSource(source.trim());
2221
+ let title = "";
2222
+ content = content.trim().replace(REG_HEADING, (_, match) => {
2223
+ title = match.trim();
2224
+ return "";
2225
+ });
2226
+ source = `${matter}
2227
+ ${content}`;
2228
+ const result = render(source, env);
2229
+ if (title) {
2230
+ env.frontmatter ??= {};
2231
+ env.frontmatter.title ??= title;
2232
+ }
2233
+ return result;
2234
+ };
2235
+ }
2236
+ function parseSource(source) {
2237
+ const char = "---";
2238
+ if (!source.startsWith(char)) {
2239
+ return { matter: "", content: source };
2240
+ } else {
2241
+ const end = source.indexOf(`
2242
+ ${char}`);
2243
+ const len = char.length + 1;
2244
+ return {
2245
+ matter: source.slice(0, end + len),
2246
+ content: source.slice(end + len)
2247
+ };
2248
+ }
2249
+ }
2250
+
2152
2251
  // src/node/inline/index.ts
2153
2252
  import { attrs } from "@mdit/plugin-attrs";
2154
2253
  import { footnote } from "@mdit/plugin-footnote";
@@ -2325,6 +2424,8 @@ async function prepareConfigFile(app, options) {
2325
2424
  `import { defineClientConfig } from 'vuepress/client'
2326
2425
  ${Array.from(imports.values()).join("\n")}
2327
2426
 
2427
+ import '${CLIENT_FOLDER}styles/index.css'
2428
+
2328
2429
  export default defineClientConfig({
2329
2430
  enhance({ router, app }) {
2330
2431
  ${Array.from(enhances.values()).map((item) => ` ${item}`).join("\n")}
@@ -2344,10 +2445,15 @@ function markdownPowerPlugin(options = {}) {
2344
2445
  },
2345
2446
  extendsBundlerOptions(bundlerOptions, app) {
2346
2447
  if (options.repl) {
2347
- addViteOptimizeDepsInclude(bundlerOptions, app, ["shiki/core", "shiki/wasm", "shiki/engine/oniguruma"]);
2448
+ addViteOptimizeDepsInclude(
2449
+ bundlerOptions,
2450
+ app,
2451
+ ["shiki/core", "shiki/wasm", "shiki/engine/oniguruma"]
2452
+ );
2348
2453
  }
2349
2454
  },
2350
2455
  extendsMarkdown: async (md, app) => {
2456
+ docsTitlePlugin(md);
2351
2457
  embedSyntaxPlugin(md, options);
2352
2458
  inlineSyntaxPlugin(md, options);
2353
2459
  await containerPlugin(app, md, options);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vuepress-plugin-md-power",
3
3
  "type": "module",
4
- "version": "1.0.0-rc.113",
4
+ "version": "1.0.0-rc.115",
5
5
  "description": "The Plugin for VuePress 2 - markdown power",
6
6
  "author": "pengzhanbo <volodymyr@foxmail.com>",
7
7
  "license": "MIT",
@@ -47,15 +47,15 @@
47
47
  "@mdit/plugin-sup": "^0.13.1",
48
48
  "@mdit/plugin-tab": "^0.13.2",
49
49
  "@mdit/plugin-tasklist": "^0.13.1",
50
- "@vuepress/helper": "2.0.0-rc.56",
51
- "@vueuse/core": "^11.1.0",
50
+ "@vuepress/helper": "2.0.0-rc.60",
51
+ "@vueuse/core": "^11.2.0",
52
52
  "image-size": "^1.1.1",
53
53
  "local-pkg": "^0.5.0",
54
54
  "markdown-it-container": "^4.0.0",
55
- "nanoid": "^5.0.7",
56
- "shiki": "^1.22.1",
57
- "tm-grammars": "^1.18.5",
58
- "tm-themes": "^1.9.0",
55
+ "nanoid": "^5.0.8",
56
+ "shiki": "^1.22.2",
57
+ "tm-grammars": "^1.19.0",
58
+ "tm-themes": "^1.9.3",
59
59
  "vue": "^3.5.12"
60
60
  },
61
61
  "devDependencies": {