vuepress-plugin-md-power 1.0.0-rc.158 → 1.0.0-rc.160
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,187 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { decodeData } from '@vuepress/helper/client'
|
|
3
|
+
import { useClipboard, useToggle } from '@vueuse/core'
|
|
4
|
+
import { computed, useTemplateRef } from 'vue'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
/** 表格标题 */
|
|
8
|
+
title?: string
|
|
9
|
+
/** 对其方式 */
|
|
10
|
+
align?: 'left' | 'center' | 'right'
|
|
11
|
+
/** 复制为 html/markdown */
|
|
12
|
+
copy?: false | 'all' | 'html' | 'md'
|
|
13
|
+
/** 最大化内容 */
|
|
14
|
+
maxContent?: boolean
|
|
15
|
+
/** @internal */
|
|
16
|
+
markdown?: string
|
|
17
|
+
}>()
|
|
18
|
+
|
|
19
|
+
const tableEl = useTemplateRef('table')
|
|
20
|
+
const rawContent = computed(() => props.markdown ? decodeData(props.markdown) : '')
|
|
21
|
+
|
|
22
|
+
const [isHTMLCopied, toggleHTMLCopy] = useToggle()
|
|
23
|
+
const [isMDCopied, toggleMDCopy] = useToggle()
|
|
24
|
+
const { copy: copyTable } = useClipboard()
|
|
25
|
+
|
|
26
|
+
function onCopy(type: 'html' | 'md') {
|
|
27
|
+
copyTable(type === 'md' ? rawContent.value : tableEl.value?.innerHTML || '')
|
|
28
|
+
type === 'html' ? toggleHTMLCopy(true) : toggleMDCopy(true)
|
|
29
|
+
setTimeout(() => {
|
|
30
|
+
type === 'html' ? toggleHTMLCopy(false) : toggleMDCopy(false)
|
|
31
|
+
}, 1500)
|
|
32
|
+
}
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<div class="vp-table" :class="{ [align || 'left']: true }">
|
|
37
|
+
<div class="table-container">
|
|
38
|
+
<div class="table-content">
|
|
39
|
+
<div v-if="copy" class="table-toolbar">
|
|
40
|
+
<button
|
|
41
|
+
v-if="copy === 'all' || copy === 'html'"
|
|
42
|
+
type="button"
|
|
43
|
+
aria-label="Copy Table as HTML"
|
|
44
|
+
@click="onCopy('html')"
|
|
45
|
+
>
|
|
46
|
+
<span :class="isHTMLCopied ? 'vpi-table-copied' : 'vpi-table-copy'" />
|
|
47
|
+
<span>HTML</span>
|
|
48
|
+
</button>
|
|
49
|
+
<button
|
|
50
|
+
v-if="copy === 'all' || copy === 'md'"
|
|
51
|
+
type="button"
|
|
52
|
+
aria-label="Copy Table as Markdown"
|
|
53
|
+
@click="onCopy('md')"
|
|
54
|
+
>
|
|
55
|
+
<span :class="isMDCopied ? 'vpi-table-copied' : 'vpi-table-copy'" />
|
|
56
|
+
<span>Markdown</span>
|
|
57
|
+
</button>
|
|
58
|
+
</div>
|
|
59
|
+
<div ref="table" :class="{ 'max-content': maxContent }">
|
|
60
|
+
<slot />
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
<p v-if="title" class="table-title">
|
|
64
|
+
{{ title }}
|
|
65
|
+
</p>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
69
|
+
|
|
70
|
+
<style>
|
|
71
|
+
.vp-table {
|
|
72
|
+
display: flex;
|
|
73
|
+
max-width: 100%;
|
|
74
|
+
margin: 16px 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.vp-table.left {
|
|
78
|
+
justify-content: flex-start;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.vp-table.center {
|
|
82
|
+
justify-content: center;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.vp-table.right {
|
|
86
|
+
justify-content: flex-end;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.vp-table .table-container,
|
|
90
|
+
.vp-table .table-content {
|
|
91
|
+
width: fit-content;
|
|
92
|
+
max-width: 100%;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.vp-table .table-content {
|
|
96
|
+
margin: 0 auto;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.vp-table .table-title {
|
|
100
|
+
margin: 8px auto;
|
|
101
|
+
font-weight: 500;
|
|
102
|
+
text-align: center;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.vp-table .table-container table {
|
|
106
|
+
margin: 0;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.vp-table .table-toolbar {
|
|
110
|
+
display: flex;
|
|
111
|
+
gap: 8px;
|
|
112
|
+
justify-content: flex-end;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.vp-table .table-toolbar button {
|
|
116
|
+
display: flex;
|
|
117
|
+
gap: 4px;
|
|
118
|
+
align-items: center;
|
|
119
|
+
font-size: 14px;
|
|
120
|
+
color: var(--vp-c-text-3);
|
|
121
|
+
cursor: pointer;
|
|
122
|
+
transition: var(--vp-t-color);
|
|
123
|
+
transition-property: color;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.vp-table .table-toolbar button:hover {
|
|
127
|
+
color: var(--vp-c-text-2);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.vpi-table-copy {
|
|
131
|
+
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='none' stroke='%23000' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='M20.829 12.861c.171-.413.171-.938.171-1.986s0-1.573-.171-1.986a2.25 2.25 0 0 0-1.218-1.218c-.413-.171-.938-.171-1.986-.171H11.1c-1.26 0-1.89 0-2.371.245a2.25 2.25 0 0 0-.984.984C7.5 9.209 7.5 9.839 7.5 11.1v6.525c0 1.048 0 1.573.171 1.986c.229.551.667.99 1.218 1.218c.413.171.938.171 1.986.171s1.573 0 1.986-.171m7.968-7.968a2.25 2.25 0 0 1-1.218 1.218c-.413.171-.938.171-1.986.171s-1.573 0-1.986.171a2.25 2.25 0 0 0-1.218 1.218c-.171.413-.171.938-.171 1.986s0 1.573-.171 1.986a2.25 2.25 0 0 1-1.218 1.218m7.968-7.968a11.68 11.68 0 0 1-7.75 7.9l-.218.068M16.5 7.5v-.9c0-1.26 0-1.89-.245-2.371a2.25 2.25 0 0 0-.983-.984C14.79 3 14.16 3 12.9 3H6.6c-1.26 0-1.89 0-2.371.245a2.25 2.25 0 0 0-.984.984C3 4.709 3 5.339 3 6.6v6.3c0 1.26 0 1.89.245 2.371c.216.424.56.768.984.984c.48.245 1.111.245 2.372.245H7.5'/%3E%3C/svg%3E");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.vpi-table-copied {
|
|
135
|
+
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath fill='%23000' d='m9 20.42l-6.21-6.21l2.83-2.83L9 14.77l9.88-9.89l2.83 2.83z'/%3E%3C/svg%3E");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.vp-table .table-content .max-content {
|
|
139
|
+
max-width: 100%;
|
|
140
|
+
overflow-x: auto;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.vp-table .table-content .max-content table {
|
|
144
|
+
width: max-content;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* ----- Highlight --------- */
|
|
148
|
+
.vp-table table th.tip,
|
|
149
|
+
.vp-table table td.tip,
|
|
150
|
+
.vp-table table th.note,
|
|
151
|
+
.vp-table table td.note {
|
|
152
|
+
color: var(--vp-c-tip-1);
|
|
153
|
+
background-color: var(--vp-c-tip-soft);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
.vp-table table th.info,
|
|
157
|
+
.vp-table table td.info {
|
|
158
|
+
color: var(--vp-c-default-1);
|
|
159
|
+
background-color: var(--vp-c-default-soft);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.vp-table table th.warning,
|
|
163
|
+
.vp-table table td.warning {
|
|
164
|
+
color: var(--vp-c-warning-1);
|
|
165
|
+
background-color: var(--vp-c-warning-soft);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.vp-table table th.danger,
|
|
169
|
+
.vp-table table td.danger,
|
|
170
|
+
.vp-table table th.caution,
|
|
171
|
+
.vp-table table td.caution {
|
|
172
|
+
color: var(--vp-c-danger-1);
|
|
173
|
+
background-color: var(--vp-c-danger-soft);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.vp-table table th.success,
|
|
177
|
+
.vp-table table td.success {
|
|
178
|
+
color: var(--vp-c-success-1);
|
|
179
|
+
background-color: var(--vp-c-success-soft);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.vp-table table th.important,
|
|
183
|
+
.vp-table table td.important {
|
|
184
|
+
color: var(--vp-c-important-1);
|
|
185
|
+
background-color: var(--vp-c-important-soft);
|
|
186
|
+
}
|
|
187
|
+
</style>
|
|
@@ -152,8 +152,9 @@ function useCodeRepl(el) {
|
|
|
152
152
|
finished.value = false;
|
|
153
153
|
if (pyodide === null) {
|
|
154
154
|
const { loadPyodide, version } = await import(
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
/* webpackChunkName: "pyodide" */
|
|
156
|
+
"pyodide"
|
|
157
|
+
);
|
|
157
158
|
pyodide = await loadPyodide({ indexURL: `https://cdn.jsdelivr.net/pyodide/v${version}/full/` });
|
|
158
159
|
}
|
|
159
160
|
pyodide.setStdout({ batched: (msg) => stdout.value.push(msg) });
|
|
@@ -105,7 +105,7 @@ function useNormalDemo(draw, title, config) {
|
|
|
105
105
|
function createHTMLTemplate(title, id, config) {
|
|
106
106
|
const { cssLib = [], jsLib = [], html, css, script } = config || {};
|
|
107
107
|
const stylesheet = cssLib.map((url) => `<link rel="stylesheet" href="${url}">`).join("");
|
|
108
|
-
const scripts = jsLib.map((url) => `<script src="${url}"
|
|
108
|
+
const scripts = jsLib.map((url) => `<script src="${url}"><\/script>`).join("");
|
|
109
109
|
return `<!DOCTYPE html>
|
|
110
110
|
<html>
|
|
111
111
|
<head>
|
|
@@ -117,7 +117,7 @@ function createHTMLTemplate(title, id, config) {
|
|
|
117
117
|
</head>
|
|
118
118
|
<body>
|
|
119
119
|
${html}
|
|
120
|
-
<script>;(function(){${script}})()
|
|
120
|
+
<script>;(function(){${script}})();<\/script>
|
|
121
121
|
<script>;(function(){
|
|
122
122
|
const height = Math.ceil(document.documentElement.getBoundingClientRect().height)
|
|
123
123
|
window.parent?.postMessage({ type: '${id}', height }, '*')
|
|
@@ -128,7 +128,7 @@ function createHTMLTemplate(title, id, config) {
|
|
|
128
128
|
window.parent?.postMessage({ type: '${id}', height }, '*')
|
|
129
129
|
})
|
|
130
130
|
resizeObserver.observe(document.documentElement)
|
|
131
|
-
})()
|
|
131
|
+
})();<\/script>
|
|
132
132
|
</body>
|
|
133
133
|
</html>`;
|
|
134
134
|
}
|
package/lib/node/index.d.ts
CHANGED
|
@@ -235,6 +235,38 @@ interface ReplEditorData {
|
|
|
235
235
|
};
|
|
236
236
|
}
|
|
237
237
|
//#endregion
|
|
238
|
+
//#region src/shared/table.d.ts
|
|
239
|
+
interface TableContainerOptions {
|
|
240
|
+
/**
|
|
241
|
+
* 表格对齐方式
|
|
242
|
+
* - 'left': 左对齐
|
|
243
|
+
* - 'center': 居中对齐
|
|
244
|
+
* - 'right': 右对齐
|
|
245
|
+
*
|
|
246
|
+
* @default 'left'
|
|
247
|
+
*/
|
|
248
|
+
align?: "left" | "center" | "right";
|
|
249
|
+
/**
|
|
250
|
+
* 表格复制
|
|
251
|
+
* - true: 等同于 `all`,支持复制为 html 和 markdown 格式
|
|
252
|
+
* - 'all': 支持复制为 html 和 markdown 格式
|
|
253
|
+
* - 'html': 只支持复制为 html 格式
|
|
254
|
+
* - 'md': 只支持复制为 markdown 格式
|
|
255
|
+
* - `false`: 禁用复制
|
|
256
|
+
*
|
|
257
|
+
* @default true
|
|
258
|
+
*/
|
|
259
|
+
copy?: boolean | "all" | "html" | "md";
|
|
260
|
+
/**
|
|
261
|
+
* 表格宽度是否为最大内容宽度
|
|
262
|
+
*
|
|
263
|
+
* 最大内容宽度时,行内元素不再自动换行,超出容器宽度时表格显示滚动条
|
|
264
|
+
*
|
|
265
|
+
* @default false
|
|
266
|
+
*/
|
|
267
|
+
maxContent?: boolean;
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
238
270
|
//#region src/shared/plugin.d.ts
|
|
239
271
|
interface MarkdownPowerPluginOptions {
|
|
240
272
|
/**
|
|
@@ -263,7 +295,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
263
295
|
* @default false
|
|
264
296
|
*/
|
|
265
297
|
pdf?: boolean | PDFOptions;
|
|
266
|
-
// new syntax
|
|
267
298
|
/**
|
|
268
299
|
* 是否启用 图标支持
|
|
269
300
|
* - iconify - `::collect:icon_name::` => `<VPIcon name="collect:icon_name" />`
|
|
@@ -346,7 +377,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
346
377
|
* @default false
|
|
347
378
|
*/
|
|
348
379
|
field?: boolean;
|
|
349
|
-
// video embed
|
|
350
380
|
/**
|
|
351
381
|
* 是否启用 acfun 视频嵌入
|
|
352
382
|
*
|
|
@@ -383,7 +413,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
383
413
|
* `@[audioReader](url)`
|
|
384
414
|
*/
|
|
385
415
|
audioReader?: boolean;
|
|
386
|
-
// code embed
|
|
387
416
|
/**
|
|
388
417
|
* 是否启用 codepen 嵌入
|
|
389
418
|
*
|
|
@@ -412,7 +441,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
412
441
|
* @default false
|
|
413
442
|
*/
|
|
414
443
|
jsfiddle?: boolean;
|
|
415
|
-
// container
|
|
416
444
|
/**
|
|
417
445
|
* 是否启用 REPL 容器语法
|
|
418
446
|
*
|
|
@@ -451,7 +479,14 @@ interface MarkdownPowerPluginOptions {
|
|
|
451
479
|
* @default false
|
|
452
480
|
*/
|
|
453
481
|
caniuse?: boolean | CanIUseOptions;
|
|
454
|
-
|
|
482
|
+
/**
|
|
483
|
+
* 是否启用 table 容器语法,为表格提供增强功能
|
|
484
|
+
*
|
|
485
|
+
* - `copy`: 是否启用复制功能,支持复制为 html 格式 和 markdown 格式
|
|
486
|
+
*
|
|
487
|
+
* @default false
|
|
488
|
+
*/
|
|
489
|
+
table?: boolean | TableContainerOptions;
|
|
455
490
|
/**
|
|
456
491
|
* 是否启用 自动填充 图片宽高属性
|
|
457
492
|
*
|
package/lib/node/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { tab } from "@mdit/plugin-tab";
|
|
3
|
-
import { addViteOptimizeDepsInclude, ensureEndingSlash, isArray, isLinkAbsolute, isLinkExternal, isLinkHttp, isPlainObject } from "@vuepress/helper";
|
|
3
|
+
import { addViteOptimizeDepsInclude, encodeData, ensureEndingSlash, isArray, isLinkAbsolute, isLinkExternal, isLinkHttp, isPlainObject } from "@vuepress/helper";
|
|
4
4
|
import { Buffer } from "node:buffer";
|
|
5
5
|
import http from "node:https";
|
|
6
6
|
import { URL, URLSearchParams } from "node:url";
|
|
@@ -1040,12 +1040,16 @@ async function imageSizePlugin(app, md, type = false) {
|
|
|
1040
1040
|
if (!cache$1.has(filepath$1)) return false;
|
|
1041
1041
|
} else if (!cache$1.has(filepath$1)) {
|
|
1042
1042
|
if (!fs.existsSync(filepath$1)) return false;
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1043
|
+
try {
|
|
1044
|
+
const { width: w, height: h } = imageSize(fs.readFileSync(filepath$1));
|
|
1045
|
+
if (!w || !h) return false;
|
|
1046
|
+
cache$1.set(filepath$1, {
|
|
1047
|
+
width: w,
|
|
1048
|
+
height: h
|
|
1049
|
+
});
|
|
1050
|
+
} catch {
|
|
1051
|
+
return false;
|
|
1052
|
+
}
|
|
1049
1053
|
}
|
|
1050
1054
|
const { width: originalWidth, height: originalHeight } = cache$1.get(filepath$1);
|
|
1051
1055
|
const ratio = originalWidth / originalHeight;
|
|
@@ -2430,6 +2434,83 @@ function stepsPlugin(md) {
|
|
|
2430
2434
|
createContainerPlugin(md, "steps", { before: () => "<div class=\"vp-steps\">" });
|
|
2431
2435
|
}
|
|
2432
2436
|
|
|
2437
|
+
//#endregion
|
|
2438
|
+
//#region src/node/container/table.ts
|
|
2439
|
+
/**
|
|
2440
|
+
* 在不破坏表格语法的前提下,通过容器语法将表格包裹起来,为表格提供增强功能
|
|
2441
|
+
*
|
|
2442
|
+
* @example
|
|
2443
|
+
* ```md
|
|
2444
|
+
* ::: table title="表格标题" max-content copy align="center" hl-rows="warning:1,2,3;error:4,5,6" hl-cols="warning:1;error:2,3" hl-cells="warning:(1,2)(2,3);"
|
|
2445
|
+
*
|
|
2446
|
+
* | xx | xx | xx |
|
|
2447
|
+
* | -- | -- | -- |
|
|
2448
|
+
* | xx | xx | xx |
|
|
2449
|
+
* :::
|
|
2450
|
+
* ```
|
|
2451
|
+
*/
|
|
2452
|
+
function tablePlugin(md, options = {}) {
|
|
2453
|
+
createContainerSyntaxPlugin(md, "table", (tokens, index, opt, env) => {
|
|
2454
|
+
const { hlCols = "", hlRows = "", hlCells = "",...meta } = tokens[index].meta;
|
|
2455
|
+
const props = {
|
|
2456
|
+
copy: true,
|
|
2457
|
+
maxContent: false,
|
|
2458
|
+
...options,
|
|
2459
|
+
...meta
|
|
2460
|
+
};
|
|
2461
|
+
const content = tokens[index].content;
|
|
2462
|
+
if (props.copy) {
|
|
2463
|
+
props.copy = props.copy === true ? "all" : props.copy;
|
|
2464
|
+
if (props.copy === "all" || props.copy === "md") props.markdown = encodeData(content.trim());
|
|
2465
|
+
}
|
|
2466
|
+
if (!hlCols && !hlRows && !hlCells) return `<VPTable ${stringifyAttrs(props)}>${md.render(content, env)}</VPTable>`;
|
|
2467
|
+
const rows = parseHl(hlRows);
|
|
2468
|
+
const cols = parseHl(hlCols);
|
|
2469
|
+
const cells = parseHlCells(hlCells);
|
|
2470
|
+
const tableTokens = md.parse(content, env);
|
|
2471
|
+
let isTable = false;
|
|
2472
|
+
let colIndex = 0;
|
|
2473
|
+
let rowIndex = 0;
|
|
2474
|
+
for (const token of tableTokens) {
|
|
2475
|
+
if (token.type === "table_open") isTable = true;
|
|
2476
|
+
if (token.type === "table_close") isTable = false;
|
|
2477
|
+
if (!isTable) continue;
|
|
2478
|
+
if (token.type === "tr_open") {
|
|
2479
|
+
rowIndex++;
|
|
2480
|
+
colIndex = 0;
|
|
2481
|
+
}
|
|
2482
|
+
if (token.type === "th_open" || token.type === "td_open") {
|
|
2483
|
+
colIndex++;
|
|
2484
|
+
const classes = cells[rowIndex]?.[colIndex] || rows[rowIndex] || cols[colIndex];
|
|
2485
|
+
if (classes) token.attrJoin("class", classes);
|
|
2486
|
+
}
|
|
2487
|
+
}
|
|
2488
|
+
return `<VPTable ${stringifyAttrs(props)}>${md.renderer.render(tableTokens, opt, env)}</VPTable>`;
|
|
2489
|
+
});
|
|
2490
|
+
}
|
|
2491
|
+
function parseHl(hl) {
|
|
2492
|
+
const res = {};
|
|
2493
|
+
if (!hl) return res;
|
|
2494
|
+
hl.split(";").forEach((item) => {
|
|
2495
|
+
const [key, value = "1"] = item.split(":");
|
|
2496
|
+
String(value).split(",").forEach((v) => res[v.trim()] = key.trim());
|
|
2497
|
+
});
|
|
2498
|
+
return res;
|
|
2499
|
+
}
|
|
2500
|
+
function parseHlCells(hl) {
|
|
2501
|
+
const res = {};
|
|
2502
|
+
if (!hl) return res;
|
|
2503
|
+
hl.split(";").forEach((item) => {
|
|
2504
|
+
const [key, value = ""] = item.split(":");
|
|
2505
|
+
value.trim().replace(/\s*\((\d+)\s*,\s*(\d+)\)\s*/g, (_, row, col) => {
|
|
2506
|
+
res[row] ??= {};
|
|
2507
|
+
res[row][col] = key.trim();
|
|
2508
|
+
return "";
|
|
2509
|
+
});
|
|
2510
|
+
});
|
|
2511
|
+
return res;
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2433
2514
|
//#endregion
|
|
2434
2515
|
//#region src/node/container/tabs.ts
|
|
2435
2516
|
const tabs = (md) => {
|
|
@@ -2555,6 +2636,7 @@ async function containerPlugin(app, md, options) {
|
|
|
2555
2636
|
if (options.collapse) collapsePlugin(md);
|
|
2556
2637
|
if (options.chat) chatPlugin(md);
|
|
2557
2638
|
if (options.field) fieldPlugin(md);
|
|
2639
|
+
if (options.table) tablePlugin(md, isPlainObject(options.table) ? options.table : {});
|
|
2558
2640
|
}
|
|
2559
2641
|
|
|
2560
2642
|
//#endregion
|
|
@@ -2681,10 +2763,10 @@ function insertSetupScript({ export: name, path: path$3 }, env) {
|
|
|
2681
2763
|
const imports = `import ${name ? `${name} from ` : ""}'${path$3}';`;
|
|
2682
2764
|
const scriptSetup = env.sfcBlocks.scriptSetup ??= {
|
|
2683
2765
|
type: "script",
|
|
2684
|
-
content: "<script setup>\n
|
|
2766
|
+
content: "<script setup>\n<\/script>",
|
|
2685
2767
|
contentStripped: "",
|
|
2686
2768
|
tagOpen: "<script setup>",
|
|
2687
|
-
tagClose: "
|
|
2769
|
+
tagClose: "<\/script>"
|
|
2688
2770
|
};
|
|
2689
2771
|
scriptSetup.contentStripped = `${imports}\n${scriptSetup.contentStripped}`;
|
|
2690
2772
|
scriptSetup.content = scriptSetup.content.replace(SCRIPT_RE$1, (matched) => `${matched}\n${imports}`);
|
|
@@ -3531,10 +3613,9 @@ function checkSupportType(type) {
|
|
|
3531
3613
|
name = !installed.hlsjs ? "hls.js" : "";
|
|
3532
3614
|
break;
|
|
3533
3615
|
case "flv":
|
|
3534
|
-
case "ts":
|
|
3616
|
+
case "ts":
|
|
3535
3617
|
name = !installed.mpegtsjs ? "mpegts.js" : "";
|
|
3536
3618
|
break;
|
|
3537
|
-
}
|
|
3538
3619
|
case "mpd":
|
|
3539
3620
|
case "dash":
|
|
3540
3621
|
name = !installed.dashjs ? "dashjs" : "";
|
|
@@ -4281,6 +4362,10 @@ async function prepareConfigFile(app, options) {
|
|
|
4281
4362
|
imports.add(`import VPField from '${CLIENT_FOLDER}components/VPField.vue'`);
|
|
4282
4363
|
enhances.add(`app.component('VPField', VPField)`);
|
|
4283
4364
|
}
|
|
4365
|
+
if (options.table) {
|
|
4366
|
+
imports.add(`import VPTable from '${CLIENT_FOLDER}components/VPTable.vue'`);
|
|
4367
|
+
enhances.add(`app.component('VPTable', VPTable)`);
|
|
4368
|
+
}
|
|
4284
4369
|
const setupIcon = prepareIcon(imports, options.icon);
|
|
4285
4370
|
return app.writeTemp("md-power/config.js", `\
|
|
4286
4371
|
import { defineClientConfig } from 'vuepress/client'
|
package/lib/shared/index.d.ts
CHANGED
|
@@ -233,6 +233,38 @@ interface ReplEditorData {
|
|
|
233
233
|
};
|
|
234
234
|
}
|
|
235
235
|
//#endregion
|
|
236
|
+
//#region src/shared/table.d.ts
|
|
237
|
+
interface TableContainerOptions {
|
|
238
|
+
/**
|
|
239
|
+
* 表格对齐方式
|
|
240
|
+
* - 'left': 左对齐
|
|
241
|
+
* - 'center': 居中对齐
|
|
242
|
+
* - 'right': 右对齐
|
|
243
|
+
*
|
|
244
|
+
* @default 'left'
|
|
245
|
+
*/
|
|
246
|
+
align?: "left" | "center" | "right";
|
|
247
|
+
/**
|
|
248
|
+
* 表格复制
|
|
249
|
+
* - true: 等同于 `all`,支持复制为 html 和 markdown 格式
|
|
250
|
+
* - 'all': 支持复制为 html 和 markdown 格式
|
|
251
|
+
* - 'html': 只支持复制为 html 格式
|
|
252
|
+
* - 'md': 只支持复制为 markdown 格式
|
|
253
|
+
* - `false`: 禁用复制
|
|
254
|
+
*
|
|
255
|
+
* @default true
|
|
256
|
+
*/
|
|
257
|
+
copy?: boolean | "all" | "html" | "md";
|
|
258
|
+
/**
|
|
259
|
+
* 表格宽度是否为最大内容宽度
|
|
260
|
+
*
|
|
261
|
+
* 最大内容宽度时,行内元素不再自动换行,超出容器宽度时表格显示滚动条
|
|
262
|
+
*
|
|
263
|
+
* @default false
|
|
264
|
+
*/
|
|
265
|
+
maxContent?: boolean;
|
|
266
|
+
}
|
|
267
|
+
//#endregion
|
|
236
268
|
//#region src/shared/plugin.d.ts
|
|
237
269
|
interface MarkdownPowerPluginOptions {
|
|
238
270
|
/**
|
|
@@ -261,7 +293,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
261
293
|
* @default false
|
|
262
294
|
*/
|
|
263
295
|
pdf?: boolean | PDFOptions;
|
|
264
|
-
// new syntax
|
|
265
296
|
/**
|
|
266
297
|
* 是否启用 图标支持
|
|
267
298
|
* - iconify - `::collect:icon_name::` => `<VPIcon name="collect:icon_name" />`
|
|
@@ -344,7 +375,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
344
375
|
* @default false
|
|
345
376
|
*/
|
|
346
377
|
field?: boolean;
|
|
347
|
-
// video embed
|
|
348
378
|
/**
|
|
349
379
|
* 是否启用 acfun 视频嵌入
|
|
350
380
|
*
|
|
@@ -381,7 +411,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
381
411
|
* `@[audioReader](url)`
|
|
382
412
|
*/
|
|
383
413
|
audioReader?: boolean;
|
|
384
|
-
// code embed
|
|
385
414
|
/**
|
|
386
415
|
* 是否启用 codepen 嵌入
|
|
387
416
|
*
|
|
@@ -410,7 +439,6 @@ interface MarkdownPowerPluginOptions {
|
|
|
410
439
|
* @default false
|
|
411
440
|
*/
|
|
412
441
|
jsfiddle?: boolean;
|
|
413
|
-
// container
|
|
414
442
|
/**
|
|
415
443
|
* 是否启用 REPL 容器语法
|
|
416
444
|
*
|
|
@@ -449,7 +477,14 @@ interface MarkdownPowerPluginOptions {
|
|
|
449
477
|
* @default false
|
|
450
478
|
*/
|
|
451
479
|
caniuse?: boolean | CanIUseOptions;
|
|
452
|
-
|
|
480
|
+
/**
|
|
481
|
+
* 是否启用 table 容器语法,为表格提供增强功能
|
|
482
|
+
*
|
|
483
|
+
* - `copy`: 是否启用复制功能,支持复制为 html 格式 和 markdown 格式
|
|
484
|
+
*
|
|
485
|
+
* @default false
|
|
486
|
+
*/
|
|
487
|
+
table?: boolean | TableContainerOptions;
|
|
453
488
|
/**
|
|
454
489
|
* 是否启用 自动填充 图片宽高属性
|
|
455
490
|
*
|
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.160",
|
|
5
5
|
"description": "The Plugin for VuePress 2 - markdown power",
|
|
6
6
|
"author": "pengzhanbo <volodymyr@foxmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"lib"
|
|
32
32
|
],
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"artplayer": "^5.2.
|
|
34
|
+
"artplayer": "^5.2.5",
|
|
35
35
|
"dashjs": "^5.0.3",
|
|
36
36
|
"esbuild": "^0.25.8",
|
|
37
37
|
"hls.js": "^1.6.7",
|
|
@@ -86,22 +86,22 @@
|
|
|
86
86
|
"@mdit/plugin-tasklist": "^0.22.1",
|
|
87
87
|
"@pengzhanbo/utils": "^2.1.0",
|
|
88
88
|
"@vuepress/helper": "2.0.0-rc.112",
|
|
89
|
-
"@vueuse/core": "^13.
|
|
89
|
+
"@vueuse/core": "^13.6.0",
|
|
90
90
|
"chokidar": "4.0.3",
|
|
91
91
|
"image-size": "^2.0.2",
|
|
92
92
|
"local-pkg": "^1.1.1",
|
|
93
93
|
"lru-cache": "^11.1.0",
|
|
94
94
|
"markdown-it-container": "^4.0.0",
|
|
95
95
|
"nanoid": "^5.1.5",
|
|
96
|
-
"shiki": "^3.
|
|
96
|
+
"shiki": "^3.9.1",
|
|
97
97
|
"tinyglobby": "0.2.13",
|
|
98
|
-
"tm-grammars": "^1.24.
|
|
98
|
+
"tm-grammars": "^1.24.1",
|
|
99
99
|
"tm-themes": "^1.10.7",
|
|
100
|
-
"vue": "^3.5.
|
|
100
|
+
"vue": "^3.5.18"
|
|
101
101
|
},
|
|
102
102
|
"devDependencies": {
|
|
103
103
|
"@types/markdown-it": "^14.1.2",
|
|
104
|
-
"artplayer": "^5.2.
|
|
104
|
+
"artplayer": "^5.2.5",
|
|
105
105
|
"dashjs": "^5.0.3",
|
|
106
106
|
"hls.js": "^1.6.7",
|
|
107
107
|
"mpegts.js": "1.7.3"
|