vuepress-plugin-md-power 1.0.0-rc.101 → 1.0.0-rc.102
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/client/components/CanIUse.vue +2 -6
- package/lib/client/components/CodeEditor.vue +3 -3
- package/lib/client/components/CodeRepl.vue +9 -9
- package/lib/client/components/CodeSandbox.vue +5 -7
- package/lib/client/components/FileTreeItem.vue +7 -7
- package/lib/client/components/Loading.vue +1 -1
- package/lib/client/components/PDFViewer.vue +1 -1
- package/lib/client/components/Plot.vue +4 -4
- package/lib/client/components/Replit.vue +1 -1
- package/lib/node/index.js +426 -417
- package/package.json +4 -4
|
@@ -68,15 +68,11 @@ function parseData(data: string | MessageData): MessageData {
|
|
|
68
68
|
:data-past="past"
|
|
69
69
|
:data-future="future"
|
|
70
70
|
>
|
|
71
|
-
<iframe
|
|
72
|
-
:src="source"
|
|
73
|
-
:style="{ height }"
|
|
74
|
-
:title="`Can I use ${feature}`"
|
|
75
|
-
/>
|
|
71
|
+
<iframe :src="source" :style="{ height }" :title="`Can I use ${feature}`" />
|
|
76
72
|
</div>
|
|
77
73
|
</template>
|
|
78
74
|
|
|
79
|
-
<style
|
|
75
|
+
<style>
|
|
80
76
|
.ciu_embed {
|
|
81
77
|
margin: 16px -24px;
|
|
82
78
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { HighlighterCore } from 'shiki/core'
|
|
2
3
|
import editorData from '@internal/md-power/replEditorData'
|
|
3
|
-
import {
|
|
4
|
+
import { createHighlighterCore } from 'shiki/core'
|
|
4
5
|
import { onMounted, onUnmounted, ref, shallowRef, watch } from 'vue'
|
|
5
|
-
import type { HighlighterCore } from 'shiki/core'
|
|
6
6
|
import { resolveCodeInfo } from '../composables/codeRepl.js'
|
|
7
7
|
|
|
8
8
|
let highlighter: HighlighterCore | null = null
|
|
@@ -17,7 +17,7 @@ const textAreaEl = shallowRef<HTMLTextAreaElement>()
|
|
|
17
17
|
const input = ref('')
|
|
18
18
|
|
|
19
19
|
async function init() {
|
|
20
|
-
highlighter = await
|
|
20
|
+
highlighter = await createHighlighterCore({
|
|
21
21
|
themes: 'light' in theme && 'dark' in theme ? [theme.light, theme.dark] : [theme],
|
|
22
22
|
langs: Object.keys(grammars).map(key => grammars[key]),
|
|
23
23
|
loadWasm: () => import('shiki/wasm'),
|
|
@@ -101,7 +101,7 @@ function runCode() {
|
|
|
101
101
|
padding-top: 6px;
|
|
102
102
|
margin: 0 -1.5rem;
|
|
103
103
|
background-color: var(--vp-code-block-bg);
|
|
104
|
-
transition: background-color var(--t-color);
|
|
104
|
+
transition: background-color var(--vp-t-color);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
.code-repl-title {
|
|
@@ -111,7 +111,7 @@ function runCode() {
|
|
|
111
111
|
margin: 0 -1.5rem;
|
|
112
112
|
background-color: var(--vp-code-block-bg);
|
|
113
113
|
border-bottom: solid 1px var(--vp-c-divider);
|
|
114
|
-
transition: var(--t-color);
|
|
114
|
+
transition: var(--vp-t-color);
|
|
115
115
|
transition-property: background, border;
|
|
116
116
|
}
|
|
117
117
|
|
|
@@ -142,7 +142,7 @@ function runCode() {
|
|
|
142
142
|
line-height: 48px;
|
|
143
143
|
color: var(--vp-code-tab-active-text-color);
|
|
144
144
|
white-space: nowrap;
|
|
145
|
-
transition: color var(--t-color);
|
|
145
|
+
transition: color var(--vp-t-color);
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
.icon-run {
|
|
@@ -156,7 +156,7 @@ function runCode() {
|
|
|
156
156
|
cursor: pointer;
|
|
157
157
|
border: solid 1px var(--vp-c-text-3);
|
|
158
158
|
border-radius: 100%;
|
|
159
|
-
transition: var(--t-color);
|
|
159
|
+
transition: var(--vp-t-color);
|
|
160
160
|
transition-property: color, border;
|
|
161
161
|
}
|
|
162
162
|
|
|
@@ -171,7 +171,7 @@ function runCode() {
|
|
|
171
171
|
justify-content: space-between;
|
|
172
172
|
padding: 4px 10px 4px 20px;
|
|
173
173
|
border-top: solid 2px var(--vp-c-divider);
|
|
174
|
-
transition: border-color var(--t-color);
|
|
174
|
+
transition: border-color var(--vp-t-color);
|
|
175
175
|
}
|
|
176
176
|
|
|
177
177
|
.output-head .title {
|
|
@@ -184,7 +184,7 @@ function runCode() {
|
|
|
184
184
|
.output-head .output-version {
|
|
185
185
|
font-size: 12px;
|
|
186
186
|
color: var(--vp-c-text-3);
|
|
187
|
-
transition: color var(--t-color);
|
|
187
|
+
transition: color var(--vp-t-color);
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
.output-head .icon-close {
|
|
@@ -193,7 +193,7 @@ function runCode() {
|
|
|
193
193
|
margin-left: 20px;
|
|
194
194
|
color: var(--vp-c-text-3);
|
|
195
195
|
cursor: pointer;
|
|
196
|
-
transition: color var(--t-color);
|
|
196
|
+
transition: color var(--vp-t-color);
|
|
197
197
|
}
|
|
198
198
|
|
|
199
199
|
.output-head .icon-close:hover {
|
|
@@ -227,7 +227,7 @@ function runCode() {
|
|
|
227
227
|
.output-content .stderr pre,
|
|
228
228
|
.output-content.rust .stderr pre.error {
|
|
229
229
|
color: var(--vp-c-danger-1, #b8272c);
|
|
230
|
-
transition: color var(--t-color);
|
|
230
|
+
transition: color var(--vp-t-color);
|
|
231
231
|
}
|
|
232
232
|
|
|
233
233
|
.output-content.rust .stderr pre {
|
|
@@ -237,6 +237,6 @@ function runCode() {
|
|
|
237
237
|
.output-content .stderr + .stdout {
|
|
238
238
|
margin-top: 12px;
|
|
239
239
|
border-top: 1px solid var(--vp-c-divider);
|
|
240
|
-
transition: border-color var(--t-color);
|
|
240
|
+
transition: border-color var(--vp-t-color);
|
|
241
241
|
}
|
|
242
242
|
</style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed } from 'vue'
|
|
3
2
|
import type { CodeSandboxTokenMeta } from '../../shared/index.js'
|
|
3
|
+
import { computed } from 'vue'
|
|
4
4
|
|
|
5
5
|
const props = defineProps<CodeSandboxTokenMeta>()
|
|
6
6
|
|
|
@@ -11,19 +11,17 @@ const SANDBOX = 'allow-forms allow-modals allow-popups allow-presentation allow-
|
|
|
11
11
|
|
|
12
12
|
const source = computed(() => {
|
|
13
13
|
const params = new URLSearchParams()
|
|
14
|
-
if (props.filepath)
|
|
14
|
+
if (props.filepath)
|
|
15
15
|
params.set(props.type === 'embed' ? 'module' : 'file', encodeURIComponent(props.filepath))
|
|
16
|
-
}
|
|
17
16
|
|
|
18
17
|
if (props.type === 'embed') {
|
|
19
18
|
params.set('view', props.layout ? props.layout.replace(/,/g, '+') : 'Editor+Preview')
|
|
20
19
|
|
|
21
|
-
if (props.console)
|
|
20
|
+
if (props.console)
|
|
22
21
|
params.set('expanddevtools', '1')
|
|
23
|
-
|
|
24
|
-
if (props.navbar === false)
|
|
22
|
+
|
|
23
|
+
if (props.navbar === false)
|
|
25
24
|
params.set('hidenavigation', '1')
|
|
26
|
-
}
|
|
27
25
|
}
|
|
28
26
|
else {
|
|
29
27
|
params.set('from-embed', '')
|
|
@@ -60,7 +60,7 @@ onUnmounted(() => {
|
|
|
60
60
|
background-color: var(--vp-c-bg-safe);
|
|
61
61
|
border: solid 1px var(--vp-c-divider);
|
|
62
62
|
border-radius: 8px;
|
|
63
|
-
transition: border var(--t-color), background-color var(--t-color);
|
|
63
|
+
transition: border var(--vp-t-color), background-color var(--vp-t-color);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
.vp-file-tree .vp-file-tree-title {
|
|
@@ -69,7 +69,7 @@ onUnmounted(() => {
|
|
|
69
69
|
font-weight: bold;
|
|
70
70
|
color: var(--vp-c-text-1);
|
|
71
71
|
border-bottom: solid 1px var(--vp-c-divider);
|
|
72
|
-
transition: color var(--t-color), border-color var(--t-color);
|
|
72
|
+
transition: color var(--vp-t-color), border-color var(--vp-t-color);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
.vp-file-tree ul {
|
|
@@ -106,7 +106,7 @@ onUnmounted(() => {
|
|
|
106
106
|
.file-tree-item .tree-node.folder > .name {
|
|
107
107
|
color: var(--vp-c-text-1);
|
|
108
108
|
cursor: pointer;
|
|
109
|
-
transition: color var(--t-color);
|
|
109
|
+
transition: color var(--vp-t-color);
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
.file-tree-item .tree-node.folder > .name:hover {
|
|
@@ -130,7 +130,7 @@ onUnmounted(() => {
|
|
|
130
130
|
mask: var(--icon) no-repeat;
|
|
131
131
|
-webkit-mask-size: 100% 100%;
|
|
132
132
|
mask-size: 100% 100%;
|
|
133
|
-
transition: color var(--t-color);
|
|
133
|
+
transition: color var(--vp-t-color);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
.file-tree-item .tree-node .name.focus {
|
|
@@ -141,7 +141,7 @@ onUnmounted(() => {
|
|
|
141
141
|
color: var(--vp-c-bg);
|
|
142
142
|
background-color: var(--vp-c-brand-2);
|
|
143
143
|
border-radius: 4px;
|
|
144
|
-
transition: color var(--t-color), background-color var(--t-color);
|
|
144
|
+
transition: color var(--vp-t-color), background-color var(--vp-t-color);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
.file-tree-item .tree-node .name.focus:hover {
|
|
@@ -153,7 +153,7 @@ onUnmounted(() => {
|
|
|
153
153
|
margin-left: 20px;
|
|
154
154
|
overflow: hidden;
|
|
155
155
|
color: var(--vp-c-text-3);
|
|
156
|
-
transition: color var(--t-color);
|
|
156
|
+
transition: color var(--vp-t-color);
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
.file-tree-item .tree-node [class*="vpi-"] {
|
|
@@ -170,7 +170,7 @@ onUnmounted(() => {
|
|
|
170
170
|
padding-left: 8px !important;
|
|
171
171
|
margin: 0 0 0 6px !important;
|
|
172
172
|
border-left: solid 1px var(--vp-c-divider);
|
|
173
|
-
transition: border-color var(--t-color);
|
|
173
|
+
transition: border-color var(--vp-t-color);
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
.file-tree-item:not(.expanded) > ul {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { PDFTokenMeta } from '../../shared/index.js'
|
|
2
3
|
import { onMounted, toRefs } from 'vue'
|
|
3
4
|
import { usePDF } from '../composables/pdf.js'
|
|
4
5
|
import { useSize } from '../composables/size.js'
|
|
5
|
-
import type { PDFTokenMeta } from '../../shared/index.js'
|
|
6
6
|
|
|
7
7
|
const props = defineProps<PDFTokenMeta>()
|
|
8
8
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { PlotOptions } from '../../shared/index.js'
|
|
2
3
|
import { onClickOutside, useMediaQuery } from '@vueuse/core'
|
|
3
4
|
import { computed, ref, shallowRef } from 'vue'
|
|
4
5
|
import { usePageFrontmatter } from 'vuepress/client'
|
|
5
6
|
import { pluginOptions } from '../options.js'
|
|
6
|
-
import type { PlotOptions } from '../../shared/index.js'
|
|
7
7
|
|
|
8
8
|
const props = defineProps<Omit<PlotOptions, 'tag'>>()
|
|
9
9
|
|
|
@@ -81,7 +81,7 @@ function onClick() {
|
|
|
81
81
|
transition: color ease 0.25s, background-color ease 0.25s;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
[data-theme="dark"] .vp-plot {
|
|
85
85
|
background-color: var(--vp-c-bg-plot-dark, #fff);
|
|
86
86
|
}
|
|
87
87
|
|
|
@@ -90,8 +90,8 @@ function onClick() {
|
|
|
90
90
|
color: var(--vp-c-plot-light, #fff);
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
[data-theme="dark"] .vp-plot.hover:hover,
|
|
94
|
+
[data-theme="dark"] .vp-plot.active {
|
|
95
95
|
color: var(--vp-c-plot-dark, #000);
|
|
96
96
|
}
|
|
97
97
|
</style>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { ReplitTokenMeta } from '../../shared/index.js'
|
|
2
3
|
import { computed, getCurrentInstance, ref } from 'vue'
|
|
3
4
|
import Loading from './Loading.vue'
|
|
4
|
-
import type { ReplitTokenMeta } from '../../shared/index.js'
|
|
5
5
|
|
|
6
6
|
const props = defineProps<ReplitTokenMeta>()
|
|
7
7
|
|
package/lib/node/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/node/
|
|
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";
|
|
@@ -36,7 +36,7 @@ function resolveAttrs(info) {
|
|
|
36
36
|
return { attrs, rawAttrs };
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// src/node/
|
|
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;
|
|
@@ -209,200 +209,10 @@ 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/
|
|
212
|
+
// src/node/container/fileTree/index.ts
|
|
213
213
|
import container from "markdown-it-container";
|
|
214
|
-
import { customAlphabet } from "nanoid";
|
|
215
|
-
|
|
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;
|
|
239
|
-
}
|
|
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>`;
|
|
308
|
-
}
|
|
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
|
-
}
|
|
332
|
-
|
|
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";
|
|
404
214
|
|
|
405
|
-
// src/node/
|
|
215
|
+
// src/node/container/fileTree/definitions.ts
|
|
406
216
|
var defaultFolder = "vscode-icons:default-folder";
|
|
407
217
|
var defaultFile = "vscode-icons:default-file";
|
|
408
218
|
var definitions = {
|
|
@@ -1177,7 +987,7 @@ var definitions = {
|
|
|
1177
987
|
}
|
|
1178
988
|
};
|
|
1179
989
|
|
|
1180
|
-
// src/node/
|
|
990
|
+
// src/node/container/fileTree/findIcon.ts
|
|
1181
991
|
function getFileIcon(fileName, type2 = "file") {
|
|
1182
992
|
const name = getFileIconName(fileName, type2);
|
|
1183
993
|
if (!name)
|
|
@@ -1222,7 +1032,7 @@ function getFileIconTypeFromExtension(fileName) {
|
|
|
1222
1032
|
return void 0;
|
|
1223
1033
|
}
|
|
1224
1034
|
|
|
1225
|
-
// src/node/
|
|
1035
|
+
// src/node/container/fileTree/resolveTreeNodeInfo.ts
|
|
1226
1036
|
import Token from "markdown-it/lib/token.mjs";
|
|
1227
1037
|
import { removeEndingSlash, removeLeadingSlash } from "vuepress/shared";
|
|
1228
1038
|
function resolveTreeNodeInfo(tokens, current, idx) {
|
|
@@ -1312,7 +1122,7 @@ function updateInlineToken(inline, info, icon) {
|
|
|
1312
1122
|
inline.children = tokens;
|
|
1313
1123
|
}
|
|
1314
1124
|
|
|
1315
|
-
// src/node/
|
|
1125
|
+
// src/node/container/fileTree/index.ts
|
|
1316
1126
|
var type = "file-tree";
|
|
1317
1127
|
var closeType = `container_${type}_close`;
|
|
1318
1128
|
var componentName = "FileTreeItem";
|
|
@@ -1355,106 +1165,26 @@ function fileTreePlugin(md) {
|
|
|
1355
1165
|
return "</div>";
|
|
1356
1166
|
}
|
|
1357
1167
|
};
|
|
1358
|
-
md.use(
|
|
1168
|
+
md.use(container, type, { validate, render });
|
|
1359
1169
|
}
|
|
1360
1170
|
|
|
1361
|
-
// src/node/
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
if (
|
|
1373
|
-
return
|
|
1374
|
-
|
|
1375
|
-
|
|
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;
|
|
1171
|
+
// src/node/container/langRepl.ts
|
|
1172
|
+
import container2 from "markdown-it-container";
|
|
1173
|
+
import { fs as fs2, getDirname, path as path2 } from "vuepress/utils";
|
|
1174
|
+
var RE_INFO = /^(#editable)?(.*)$/;
|
|
1175
|
+
function createReplContainer(md, lang) {
|
|
1176
|
+
const type2 = `${lang}-repl`;
|
|
1177
|
+
const validate = (info) => info.trim().startsWith(type2);
|
|
1178
|
+
const render = (tokens, index) => {
|
|
1179
|
+
const token = tokens[index];
|
|
1180
|
+
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
1181
|
+
const [, editable, title] = info.match(RE_INFO) ?? [];
|
|
1182
|
+
if (token.nesting === 1)
|
|
1183
|
+
return `<CodeRepl ${editable ? "editable" : ""} title="${title || `${lang} playground`}">`;
|
|
1184
|
+
else
|
|
1185
|
+
return "</CodeRepl>";
|
|
1408
1186
|
};
|
|
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
|
|
1442
|
-
import container3 from "markdown-it-container";
|
|
1443
|
-
import { fs as fs2, getDirname, path as path2 } from "vuepress/utils";
|
|
1444
|
-
var RE_INFO = /^(#editable)?(.*)$/;
|
|
1445
|
-
function createReplContainer(md, lang) {
|
|
1446
|
-
const type2 = `${lang}-repl`;
|
|
1447
|
-
const validate = (info) => info.trim().startsWith(type2);
|
|
1448
|
-
const render = (tokens, index) => {
|
|
1449
|
-
const token = tokens[index];
|
|
1450
|
-
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
1451
|
-
const [, editable, title] = info.match(RE_INFO) ?? [];
|
|
1452
|
-
if (token.nesting === 1)
|
|
1453
|
-
return `<CodeRepl ${editable ? "editable" : ""} title="${title || `${lang} playground`}">`;
|
|
1454
|
-
else
|
|
1455
|
-
return "</CodeRepl>";
|
|
1456
|
-
};
|
|
1457
|
-
md.use(container3, type2, { validate, render });
|
|
1187
|
+
md.use(container2, type2, { validate, render });
|
|
1458
1188
|
}
|
|
1459
1189
|
async function langReplPlugin(app, md, {
|
|
1460
1190
|
theme,
|
|
@@ -1505,82 +1235,235 @@ async function read(file) {
|
|
|
1505
1235
|
return void 0;
|
|
1506
1236
|
}
|
|
1507
1237
|
|
|
1508
|
-
// src/node/
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1238
|
+
// src/node/container/index.ts
|
|
1239
|
+
async function containerPlugin(app, md, options) {
|
|
1240
|
+
if (options.repl)
|
|
1241
|
+
await langReplPlugin(app, md, options.repl);
|
|
1242
|
+
if (options.fileTree) {
|
|
1243
|
+
fileTreePlugin(md);
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
|
|
1247
|
+
// src/node/embed/caniuse.ts
|
|
1248
|
+
import container3 from "markdown-it-container";
|
|
1249
|
+
import { customAlphabet } from "nanoid";
|
|
1250
|
+
|
|
1251
|
+
// src/node/embed/createEmbedRuleBlock.ts
|
|
1252
|
+
function createEmbedRuleBlock(md, {
|
|
1253
|
+
type: type2,
|
|
1254
|
+
name = type2,
|
|
1255
|
+
syntaxPattern,
|
|
1256
|
+
beforeName = "import_code",
|
|
1257
|
+
ruleOptions = { alt: ["paragraph", "reference", "blockquote", "list"] },
|
|
1258
|
+
meta,
|
|
1259
|
+
content
|
|
1260
|
+
}) {
|
|
1261
|
+
const MIN_LENGTH = type2.length + 5;
|
|
1262
|
+
const START_CODES = [64, 91, ...type2.split("").map((c) => c.charCodeAt(0))];
|
|
1263
|
+
md.block.ruler.before(
|
|
1264
|
+
beforeName,
|
|
1265
|
+
name,
|
|
1266
|
+
(state, startLine, endLine, silent) => {
|
|
1267
|
+
const pos = state.bMarks[startLine] + state.tShift[startLine];
|
|
1268
|
+
const max = state.eMarks[startLine];
|
|
1269
|
+
if (pos + MIN_LENGTH > max)
|
|
1270
|
+
return false;
|
|
1271
|
+
for (let i = 0; i < START_CODES.length; i += 1) {
|
|
1272
|
+
if (state.src.charCodeAt(pos + i) !== START_CODES[i])
|
|
1273
|
+
return false;
|
|
1274
|
+
}
|
|
1275
|
+
const match = state.src.slice(pos, max).match(syntaxPattern);
|
|
1276
|
+
if (!match)
|
|
1277
|
+
return false;
|
|
1278
|
+
if (silent)
|
|
1279
|
+
return true;
|
|
1280
|
+
const token = state.push(name, "", 0);
|
|
1281
|
+
token.meta = meta(match);
|
|
1282
|
+
token.map = [startLine, startLine + 1];
|
|
1283
|
+
state.line = startLine + 1;
|
|
1284
|
+
return true;
|
|
1285
|
+
},
|
|
1286
|
+
ruleOptions
|
|
1287
|
+
);
|
|
1288
|
+
md.renderer.rules[name] = (tokens, index) => {
|
|
1289
|
+
const token = tokens[index];
|
|
1290
|
+
token.content = content(token.meta);
|
|
1291
|
+
return token.content;
|
|
1292
|
+
};
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
// src/node/embed/caniuse.ts
|
|
1296
|
+
var nanoid = customAlphabet("abcdefghijklmnopqrstuvwxyz", 5);
|
|
1297
|
+
var UNDERLINE_RE = /_+/g;
|
|
1298
|
+
var caniusePlugin = (md, { mode: defaultMode = "embed" } = {}) => {
|
|
1299
|
+
createEmbedRuleBlock(md, {
|
|
1300
|
+
type: "caniuse",
|
|
1301
|
+
syntaxPattern: /^@\[caniuse\s*(embed|image)?(?:\{([0-9,\-]*)\})?\]\(([^)]*)\)/,
|
|
1302
|
+
meta: ([, mode, versions = "", feature]) => ({
|
|
1303
|
+
feature,
|
|
1304
|
+
mode: mode || defaultMode,
|
|
1305
|
+
versions
|
|
1306
|
+
}),
|
|
1307
|
+
content: (meta) => resolveCanIUse(meta)
|
|
1308
|
+
});
|
|
1309
|
+
};
|
|
1310
|
+
function legacyCaniuse(md, { mode = "embed" } = {}) {
|
|
1311
|
+
const modeMap = ["image", "embed"];
|
|
1312
|
+
const isMode = (mode2) => modeMap.includes(mode2);
|
|
1313
|
+
mode = isMode(mode) ? mode : modeMap[0];
|
|
1314
|
+
const type2 = "caniuse";
|
|
1315
|
+
const validateReg = new RegExp(`^${type2}`);
|
|
1316
|
+
const validate = (info) => {
|
|
1317
|
+
return validateReg.test(info.trim());
|
|
1318
|
+
};
|
|
1319
|
+
const render = (tokens, index) => {
|
|
1320
|
+
const token = tokens[index];
|
|
1321
|
+
if (token.nesting === 1) {
|
|
1322
|
+
const info = token.info.trim().slice(type2.length).trim() || "";
|
|
1323
|
+
const feature = info.split(/\s+/)[0];
|
|
1324
|
+
const versions = info.match(/\{(.*)\}/)?.[1] || "";
|
|
1325
|
+
return feature ? resolveCanIUse({ feature, mode, versions }) : "";
|
|
1326
|
+
} else {
|
|
1327
|
+
return "";
|
|
1328
|
+
}
|
|
1329
|
+
};
|
|
1330
|
+
md.use(container3, type2, { validate, render });
|
|
1331
|
+
}
|
|
1332
|
+
function resolveCanIUse({ feature, mode, versions }) {
|
|
1333
|
+
if (!feature)
|
|
1334
|
+
return "";
|
|
1335
|
+
if (mode === "image") {
|
|
1336
|
+
const link = "https://caniuse.bitsofco.de/image/";
|
|
1337
|
+
const alt = `Data on support for the ${feature} feature across the major browsers from caniuse.com`;
|
|
1338
|
+
return `<ClientOnly><p><picture>
|
|
1339
|
+
<source type="image/webp" srcset="${link}${feature}.webp">
|
|
1340
|
+
<source type="image/png" srcset="${link}${feature}.png">
|
|
1341
|
+
<img src="${link}${feature}.jpg" alt="${alt}" width="100%">
|
|
1342
|
+
</picture></p></ClientOnly>`;
|
|
1343
|
+
}
|
|
1344
|
+
feature = feature.replace(UNDERLINE_RE, "_");
|
|
1345
|
+
const { past, future } = resolveVersions(versions);
|
|
1346
|
+
const meta = nanoid();
|
|
1347
|
+
return `<CanIUseViewer feature="${feature}" meta="${meta}" past="${past}" future="${future}" />`;
|
|
1348
|
+
}
|
|
1349
|
+
function resolveVersions(versions) {
|
|
1350
|
+
if (!versions)
|
|
1351
|
+
return { past: 2, future: 1 };
|
|
1352
|
+
const list = versions.split(",").map((v) => Number(v.trim())).filter((v) => !Number.isNaN(v) && v >= -5 && v <= 3);
|
|
1353
|
+
list.push(0);
|
|
1354
|
+
const uniq = [...new Set(list)].sort((a, b) => b - a);
|
|
1355
|
+
return {
|
|
1356
|
+
future: uniq[0],
|
|
1357
|
+
past: Math.abs(uniq[uniq.length - 1])
|
|
1358
|
+
};
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// src/node/utils/parseRect.ts
|
|
1362
|
+
function parseRect(str, unit = "px") {
|
|
1363
|
+
if (Number.parseFloat(str) === Number(str))
|
|
1364
|
+
return `${str}${unit}`;
|
|
1365
|
+
return str;
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
// src/node/embed/code/codepen.ts
|
|
1369
|
+
var CODEPEN_LINK = "https://codepen.io/";
|
|
1370
|
+
var codepenPlugin = (md) => {
|
|
1371
|
+
createEmbedRuleBlock(md, {
|
|
1372
|
+
type: "codepen",
|
|
1373
|
+
syntaxPattern: /^@\[codepen([^\]]*)\]\(([^)]*)\)/,
|
|
1374
|
+
meta: ([, info = "", source = ""]) => {
|
|
1516
1375
|
const { attrs } = resolveAttrs(info);
|
|
1376
|
+
const [user, slash] = source.split("/");
|
|
1517
1377
|
return {
|
|
1518
|
-
src,
|
|
1519
|
-
page: +page || 1,
|
|
1520
|
-
noToolbar: Boolean(attrs.noToolbar ?? false),
|
|
1521
|
-
zoom: +attrs.zoom || 50,
|
|
1522
1378
|
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
1523
|
-
height: attrs.height ? parseRect(attrs.height) : "",
|
|
1524
|
-
|
|
1525
|
-
|
|
1379
|
+
height: attrs.height ? parseRect(attrs.height) : "400px",
|
|
1380
|
+
user,
|
|
1381
|
+
slash,
|
|
1382
|
+
title: attrs.title,
|
|
1383
|
+
preview: attrs.preview,
|
|
1384
|
+
editable: attrs.editable,
|
|
1385
|
+
tab: attrs.tab ?? "result",
|
|
1386
|
+
theme: attrs.theme
|
|
1526
1387
|
};
|
|
1527
1388
|
},
|
|
1528
|
-
content(
|
|
1529
|
-
|
|
1389
|
+
content: (meta) => {
|
|
1390
|
+
const { title = "Codepen", height, width } = meta;
|
|
1391
|
+
const params = new URLSearchParams();
|
|
1392
|
+
if (meta.editable) {
|
|
1393
|
+
params.set("editable", "true");
|
|
1394
|
+
}
|
|
1395
|
+
if (meta.tab) {
|
|
1396
|
+
params.set("default-tab", meta.tab);
|
|
1397
|
+
}
|
|
1398
|
+
if (meta.theme) {
|
|
1399
|
+
params.set("theme-id", meta.theme);
|
|
1400
|
+
}
|
|
1401
|
+
const middle = meta.preview ? "/embed/preview/" : "/embed/";
|
|
1402
|
+
const link = `${CODEPEN_LINK}${meta.user}${middle}${meta.slash}?${params.toString()}`;
|
|
1403
|
+
const style = `width:${width};height:${height};margin:16px auto;border-radius:5px;`;
|
|
1404
|
+
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
1405
|
}
|
|
1531
1406
|
});
|
|
1532
1407
|
};
|
|
1533
1408
|
|
|
1534
|
-
// src/node/
|
|
1535
|
-
var
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
return
|
|
1409
|
+
// src/node/embed/code/codeSandbox.ts
|
|
1410
|
+
var codeSandboxPlugin = (md) => {
|
|
1411
|
+
createEmbedRuleBlock(md, {
|
|
1412
|
+
type: "codesandbox",
|
|
1413
|
+
syntaxPattern: /^@\[codesandbox(?:\s+(embed|button))?([^\]]*)\]\(([^)]*)\)/,
|
|
1414
|
+
meta([, type2, info = "", source = ""]) {
|
|
1415
|
+
const { attrs } = resolveAttrs(info);
|
|
1416
|
+
const [profile, filepath2 = ""] = source.split("#");
|
|
1417
|
+
const [user, id] = profile.includes("/") ? profile.split("/") : ["", profile];
|
|
1418
|
+
return {
|
|
1419
|
+
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
1420
|
+
height: attrs.height ? parseRect(attrs.height) : "500px",
|
|
1421
|
+
user,
|
|
1422
|
+
id,
|
|
1423
|
+
title: attrs.title ?? "",
|
|
1424
|
+
console: attrs.console ?? false,
|
|
1425
|
+
navbar: attrs.navbar ?? true,
|
|
1426
|
+
layout: attrs.layout ?? "",
|
|
1427
|
+
type: type2 || "embed",
|
|
1428
|
+
filepath: filepath2
|
|
1429
|
+
};
|
|
1430
|
+
},
|
|
1431
|
+
content({ title, height, width, user, id, type: type2, filepath: filepath2, console, navbar, layout }) {
|
|
1432
|
+
return `<CodeSandboxViewer title="${title}" height="${height}" width="${width}" user="${user}" id="${id}" type="${type2}" filepath="${filepath2}" :console=${console} :navbar=${navbar} layout="${layout}" />`;
|
|
1558
1433
|
}
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1434
|
+
});
|
|
1435
|
+
};
|
|
1436
|
+
|
|
1437
|
+
// src/node/embed/code/jsfiddle.ts
|
|
1438
|
+
var jsfiddlePlugin = (md) => {
|
|
1439
|
+
createEmbedRuleBlock(md, {
|
|
1440
|
+
type: "jsfiddle",
|
|
1441
|
+
syntaxPattern: /^@\[jsfiddle([^\]]*)\]\(([^)]*)\)/,
|
|
1442
|
+
meta([, info = "", source]) {
|
|
1443
|
+
const { attrs } = resolveAttrs(info);
|
|
1444
|
+
const [user, id] = source.split("/");
|
|
1445
|
+
return {
|
|
1446
|
+
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
1447
|
+
height: attrs.height ? parseRect(attrs.height) : "400px",
|
|
1448
|
+
user,
|
|
1449
|
+
id,
|
|
1450
|
+
title: attrs.title || "JS Fiddle",
|
|
1451
|
+
tab: attrs.tab?.replace(/\s+/g, "") || "js,css,html,result",
|
|
1452
|
+
theme: attrs.theme || "dark"
|
|
1453
|
+
};
|
|
1454
|
+
},
|
|
1455
|
+
content: ({ title = "JS Fiddle", height, width, user, id, tab, theme }) => {
|
|
1456
|
+
theme = theme === "dark" ? "/dark/" : "";
|
|
1457
|
+
const link = `https://jsfiddle.net/${user}/${id}/embedded/${tab}${theme}`;
|
|
1458
|
+
const style = `width:${width};height:${height};margin:16px auto;border:none;border-radius:5px;`;
|
|
1459
|
+
return `<iframe class="js-fiddle-iframe-wrapper" style="${style}" title="${title}" src="${link}" allowfullscreen="true" allowpaymentrequest="true"></iframe>`;
|
|
1563
1460
|
}
|
|
1564
|
-
|
|
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());
|
|
1461
|
+
});
|
|
1579
1462
|
};
|
|
1580
1463
|
|
|
1581
|
-
// src/node/
|
|
1464
|
+
// src/node/embed/code/replit.ts
|
|
1582
1465
|
var replitPlugin = (md) => {
|
|
1583
|
-
|
|
1466
|
+
createEmbedRuleBlock(md, {
|
|
1584
1467
|
type: "replit",
|
|
1585
1468
|
syntaxPattern: /^@\[replit([^\]]*)\]\(([^)]*)\)/,
|
|
1586
1469
|
meta: ([, info = "", source = ""]) => {
|
|
@@ -1599,7 +1482,33 @@ var replitPlugin = (md) => {
|
|
|
1599
1482
|
});
|
|
1600
1483
|
};
|
|
1601
1484
|
|
|
1602
|
-
// src/node/
|
|
1485
|
+
// src/node/embed/pdf.ts
|
|
1486
|
+
import { path as path3 } from "vuepress/utils";
|
|
1487
|
+
var pdfPlugin = (md) => {
|
|
1488
|
+
createEmbedRuleBlock(md, {
|
|
1489
|
+
type: "pdf",
|
|
1490
|
+
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
1491
|
+
syntaxPattern: /^@\[pdf(?:\s+(\d+))?([^\]]*)\]\(([^)]*)\)/,
|
|
1492
|
+
meta([, page, info = "", src = ""]) {
|
|
1493
|
+
const { attrs } = resolveAttrs(info);
|
|
1494
|
+
return {
|
|
1495
|
+
src,
|
|
1496
|
+
page: +page || 1,
|
|
1497
|
+
noToolbar: Boolean(attrs.noToolbar ?? false),
|
|
1498
|
+
zoom: +attrs.zoom || 50,
|
|
1499
|
+
width: attrs.width ? parseRect(attrs.width) : "100%",
|
|
1500
|
+
height: attrs.height ? parseRect(attrs.height) : "",
|
|
1501
|
+
ratio: attrs.ratio ? parseRect(attrs.ratio) : "",
|
|
1502
|
+
title: path3.basename(src || "")
|
|
1503
|
+
};
|
|
1504
|
+
},
|
|
1505
|
+
content({ title, src, page, noToolbar, width, height, ratio, zoom }) {
|
|
1506
|
+
return `<PDFViewer src="${src}" title="${title}" :page="${page}" :no-toolbar="${noToolbar}" width="${width}" height="${height}" ratio="${ratio}" :zoom="${zoom}" />`;
|
|
1507
|
+
}
|
|
1508
|
+
});
|
|
1509
|
+
};
|
|
1510
|
+
|
|
1511
|
+
// src/node/embed/video/bilibili.ts
|
|
1603
1512
|
import { URLSearchParams as URLSearchParams2 } from "node:url";
|
|
1604
1513
|
|
|
1605
1514
|
// src/node/utils/timeToSeconds.ts
|
|
@@ -1612,10 +1521,10 @@ function timeToSeconds(time) {
|
|
|
1612
1521
|
return s + m * 60 + h * 3600;
|
|
1613
1522
|
}
|
|
1614
1523
|
|
|
1615
|
-
// src/node/
|
|
1524
|
+
// src/node/embed/video/bilibili.ts
|
|
1616
1525
|
var BILIBILI_LINK = "https://player.bilibili.com/player.html";
|
|
1617
1526
|
var bilibiliPlugin = (md) => {
|
|
1618
|
-
|
|
1527
|
+
createEmbedRuleBlock(md, {
|
|
1619
1528
|
type: "bilibili",
|
|
1620
1529
|
name: "video_bilibili",
|
|
1621
1530
|
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
@@ -1662,11 +1571,11 @@ var bilibiliPlugin = (md) => {
|
|
|
1662
1571
|
});
|
|
1663
1572
|
};
|
|
1664
1573
|
|
|
1665
|
-
// src/node/
|
|
1574
|
+
// src/node/embed/video/youtube.ts
|
|
1666
1575
|
import { URLSearchParams as URLSearchParams3 } from "node:url";
|
|
1667
1576
|
var YOUTUBE_LINK = "https://www.youtube.com/embed/";
|
|
1668
1577
|
var youtubePlugin = (md) => {
|
|
1669
|
-
|
|
1578
|
+
createEmbedRuleBlock(md, {
|
|
1670
1579
|
type: "youtube",
|
|
1671
1580
|
name: "video_youtube",
|
|
1672
1581
|
syntaxPattern: /^@\[youtube([^\]]*)\]\(([^)]*)\)/,
|
|
@@ -1704,6 +1613,142 @@ var youtubePlugin = (md) => {
|
|
|
1704
1613
|
});
|
|
1705
1614
|
};
|
|
1706
1615
|
|
|
1616
|
+
// src/node/embed/index.ts
|
|
1617
|
+
function embedSyntaxPlugin(md, options) {
|
|
1618
|
+
if (options.caniuse) {
|
|
1619
|
+
const caniuse = options.caniuse === true ? {} : options.caniuse;
|
|
1620
|
+
md.use(caniusePlugin, caniuse);
|
|
1621
|
+
legacyCaniuse(md, caniuse);
|
|
1622
|
+
}
|
|
1623
|
+
if (options.pdf) {
|
|
1624
|
+
md.use(pdfPlugin);
|
|
1625
|
+
}
|
|
1626
|
+
if (options.bilibili) {
|
|
1627
|
+
md.use(bilibiliPlugin);
|
|
1628
|
+
}
|
|
1629
|
+
if (options.youtube) {
|
|
1630
|
+
md.use(youtubePlugin);
|
|
1631
|
+
}
|
|
1632
|
+
if (options.codepen) {
|
|
1633
|
+
md.use(codepenPlugin);
|
|
1634
|
+
}
|
|
1635
|
+
if (options.replit) {
|
|
1636
|
+
md.use(replitPlugin);
|
|
1637
|
+
}
|
|
1638
|
+
if (options.codeSandbox) {
|
|
1639
|
+
md.use(codeSandboxPlugin);
|
|
1640
|
+
}
|
|
1641
|
+
if (options.jsfiddle) {
|
|
1642
|
+
md.use(jsfiddlePlugin);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
|
|
1646
|
+
// src/node/inline/icons.ts
|
|
1647
|
+
var [openTag, endTag] = [":[", "]:"];
|
|
1648
|
+
var iconsPlugin = (md) => md.inline.ruler.before("emphasis", "iconify", createTokenizer());
|
|
1649
|
+
function createTokenizer() {
|
|
1650
|
+
return (state, silent) => {
|
|
1651
|
+
let found = false;
|
|
1652
|
+
const max = state.posMax;
|
|
1653
|
+
const start = state.pos;
|
|
1654
|
+
if (state.src.slice(start, start + 2) !== openTag)
|
|
1655
|
+
return false;
|
|
1656
|
+
if (silent)
|
|
1657
|
+
return false;
|
|
1658
|
+
if (max - start < 5)
|
|
1659
|
+
return false;
|
|
1660
|
+
state.pos = start + 2;
|
|
1661
|
+
while (state.pos < max) {
|
|
1662
|
+
if (state.src.slice(state.pos, state.pos + 2) === endTag) {
|
|
1663
|
+
found = true;
|
|
1664
|
+
break;
|
|
1665
|
+
}
|
|
1666
|
+
state.md.inline.skipToken(state);
|
|
1667
|
+
}
|
|
1668
|
+
if (!found || start + 2 === state.pos) {
|
|
1669
|
+
state.pos = start;
|
|
1670
|
+
return false;
|
|
1671
|
+
}
|
|
1672
|
+
const content = state.src.slice(start + 2, state.pos);
|
|
1673
|
+
if (/^\s|\s$/.test(content)) {
|
|
1674
|
+
state.pos = start;
|
|
1675
|
+
return false;
|
|
1676
|
+
}
|
|
1677
|
+
state.posMax = state.pos;
|
|
1678
|
+
state.pos = start + 2;
|
|
1679
|
+
const [name, options = ""] = content.split(/\s+/);
|
|
1680
|
+
const [size, color] = options.split("/");
|
|
1681
|
+
const icon = state.push("vp_iconify_open", "VPIcon", 1);
|
|
1682
|
+
icon.markup = openTag;
|
|
1683
|
+
if (name)
|
|
1684
|
+
icon.attrSet("name", name);
|
|
1685
|
+
if (size)
|
|
1686
|
+
icon.attrSet("size", size);
|
|
1687
|
+
if (color)
|
|
1688
|
+
icon.attrSet("color", color);
|
|
1689
|
+
const close = state.push("vp_iconify_close", "VPIcon", -1);
|
|
1690
|
+
close.markup = endTag;
|
|
1691
|
+
state.pos = state.posMax + 2;
|
|
1692
|
+
state.posMax = max;
|
|
1693
|
+
return true;
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
// src/node/inline/plot.ts
|
|
1698
|
+
var [openTag2, endTag2] = ["!!", "!!"];
|
|
1699
|
+
var plotPlugin = (md) => md.inline.ruler.before("emphasis", "plot", createTokenizer2());
|
|
1700
|
+
function createTokenizer2() {
|
|
1701
|
+
return (state, silent) => {
|
|
1702
|
+
let found = false;
|
|
1703
|
+
const max = state.posMax;
|
|
1704
|
+
const start = state.pos;
|
|
1705
|
+
if (state.src.slice(start, start + 2) !== openTag2)
|
|
1706
|
+
return false;
|
|
1707
|
+
if (silent)
|
|
1708
|
+
return false;
|
|
1709
|
+
if (max - start < 5)
|
|
1710
|
+
return false;
|
|
1711
|
+
state.pos = start + 2;
|
|
1712
|
+
while (state.pos < max) {
|
|
1713
|
+
if (state.src.slice(state.pos - 1, state.pos + 1) === endTag2) {
|
|
1714
|
+
found = true;
|
|
1715
|
+
break;
|
|
1716
|
+
}
|
|
1717
|
+
state.md.inline.skipToken(state);
|
|
1718
|
+
}
|
|
1719
|
+
if (!found || start + 2 === state.pos) {
|
|
1720
|
+
state.pos = start;
|
|
1721
|
+
return false;
|
|
1722
|
+
}
|
|
1723
|
+
const content = state.src.slice(start + 2, state.pos - 1);
|
|
1724
|
+
if (/^\s|\s$/.test(content)) {
|
|
1725
|
+
state.pos = start;
|
|
1726
|
+
return false;
|
|
1727
|
+
}
|
|
1728
|
+
state.posMax = state.pos - 1;
|
|
1729
|
+
state.pos = start + 2;
|
|
1730
|
+
const open = state.push("plot_open", "Plot", 1);
|
|
1731
|
+
open.markup = openTag2;
|
|
1732
|
+
const text = state.push("text", "", 0);
|
|
1733
|
+
text.content = content;
|
|
1734
|
+
const close = state.push("plot_close", "Plot", -1);
|
|
1735
|
+
close.markup = endTag2;
|
|
1736
|
+
state.pos = state.posMax + 2;
|
|
1737
|
+
state.posMax = max;
|
|
1738
|
+
return true;
|
|
1739
|
+
};
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// src/node/inline/index.ts
|
|
1743
|
+
function inlineSyntaxPlugin(md, options) {
|
|
1744
|
+
if (options.icons) {
|
|
1745
|
+
md.use(iconsPlugin);
|
|
1746
|
+
}
|
|
1747
|
+
if (options.plot === true || typeof options.plot === "object" && options.plot.tag !== false) {
|
|
1748
|
+
md.use(plotPlugin);
|
|
1749
|
+
}
|
|
1750
|
+
}
|
|
1751
|
+
|
|
1707
1752
|
// src/node/prepareConfigFile.ts
|
|
1708
1753
|
import { ensureEndingSlash } from "@vuepress/helper";
|
|
1709
1754
|
import { getDirname as getDirname2, path as path4 } from "vuepress/utils";
|
|
@@ -1767,63 +1812,27 @@ ${Array.from(enhances.values()).map((item) => ` ${item}`).join("\n")}
|
|
|
1767
1812
|
|
|
1768
1813
|
// src/node/plugin.ts
|
|
1769
1814
|
function markdownPowerPlugin(options = {}) {
|
|
1770
|
-
return
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
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
|
-
}
|
|
1815
|
+
return {
|
|
1816
|
+
name: "vuepress-plugin-md-power",
|
|
1817
|
+
clientConfigFile: (app) => prepareConfigFile(app, options),
|
|
1818
|
+
define: {
|
|
1819
|
+
__MD_POWER_INJECT_OPTIONS__: options
|
|
1820
|
+
},
|
|
1821
|
+
extendsBundlerOptions(bundlerOptions, app) {
|
|
1822
|
+
if (options.repl) {
|
|
1823
|
+
addViteOptimizeDepsInclude(
|
|
1824
|
+
bundlerOptions,
|
|
1825
|
+
app,
|
|
1826
|
+
["shiki/core", "shiki/wasm"]
|
|
1827
|
+
);
|
|
1825
1828
|
}
|
|
1826
|
-
}
|
|
1829
|
+
},
|
|
1830
|
+
extendsMarkdown: async (md, app) => {
|
|
1831
|
+
embedSyntaxPlugin(md, options);
|
|
1832
|
+
inlineSyntaxPlugin(md, options);
|
|
1833
|
+
await containerPlugin(app, md, options);
|
|
1834
|
+
await imageSizePlugin(app, md, options.imageSize);
|
|
1835
|
+
}
|
|
1827
1836
|
};
|
|
1828
1837
|
}
|
|
1829
1838
|
export {
|
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.
|
|
4
|
+
"version": "1.0.0-rc.102",
|
|
5
5
|
"description": "The Plugin for VuePress 2 - markdown power",
|
|
6
6
|
"author": "pengzhanbo <volodymyr@foxmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -34,14 +34,14 @@
|
|
|
34
34
|
"vuepress": "2.0.0-rc.15"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@vuepress/helper": "2.0.0-rc.
|
|
37
|
+
"@vuepress/helper": "2.0.0-rc.46",
|
|
38
38
|
"@vueuse/core": "^11.1.0",
|
|
39
39
|
"image-size": "^1.1.1",
|
|
40
40
|
"markdown-it-container": "^4.0.0",
|
|
41
41
|
"nanoid": "^5.0.7",
|
|
42
42
|
"shiki": "^1.18.0",
|
|
43
|
-
"tm-grammars": "^1.17.
|
|
44
|
-
"tm-themes": "^1.8.
|
|
43
|
+
"tm-grammars": "^1.17.24",
|
|
44
|
+
"tm-themes": "^1.8.3",
|
|
45
45
|
"vue": "^3.5.7"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|