vuepress-plugin-md-power 1.0.0-rc.123 → 1.0.0-rc.125
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,100 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { useInterval } from '@vueuse/core'
|
|
3
|
+
import { onMounted, toRef, watch } from 'vue'
|
|
4
|
+
import { useAudioPlayer } from '../composables/audio.js'
|
|
5
|
+
|
|
6
|
+
const props = defineProps<{
|
|
7
|
+
src: string
|
|
8
|
+
autoplay?: boolean
|
|
9
|
+
type?: string
|
|
10
|
+
volume?: number
|
|
11
|
+
startTime?: number
|
|
12
|
+
endTime?: number
|
|
13
|
+
}>()
|
|
14
|
+
|
|
15
|
+
const { paused, play, pause, seek, setVolume } = useAudioPlayer(
|
|
16
|
+
toRef(() => props.src),
|
|
17
|
+
{
|
|
18
|
+
type: toRef(() => props.type || ''),
|
|
19
|
+
autoplay: props.autoplay,
|
|
20
|
+
oncanplay: () => {
|
|
21
|
+
if (props.startTime) {
|
|
22
|
+
seek(props.startTime)
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
ontimeupdate: (time) => {
|
|
26
|
+
if (props.endTime && time >= props.endTime) {
|
|
27
|
+
pause()
|
|
28
|
+
if (props.startTime) {
|
|
29
|
+
seek(props.startTime)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
)
|
|
35
|
+
const interval = useInterval(300, { controls: true, immediate: false })
|
|
36
|
+
|
|
37
|
+
watch(paused, () => {
|
|
38
|
+
if (paused.value) {
|
|
39
|
+
interval.pause()
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
function opacity(mo: number) {
|
|
44
|
+
return paused.value ? 1 : (interval.counter.value % 3 >= mo ? 1 : 0)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function toggle() {
|
|
48
|
+
if (paused.value) {
|
|
49
|
+
play()
|
|
50
|
+
interval.reset()
|
|
51
|
+
interval.resume()
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
pause()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
onMounted(() => {
|
|
59
|
+
watch(() => props.volume, (volume) => {
|
|
60
|
+
if (typeof volume !== 'undefined') {
|
|
61
|
+
setVolume(volume)
|
|
62
|
+
}
|
|
63
|
+
}, { immediate: true })
|
|
64
|
+
})
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<template>
|
|
68
|
+
<span class="vp-audio-reader" @click="toggle">
|
|
69
|
+
<slot />
|
|
70
|
+
<span class="icon-audio">
|
|
71
|
+
<svg fill="currentcolor" width="16" height="16" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g stroke="none" stroke-width="1" fill-rule="evenodd"><path d="M24.1538 5.86289C24.8505 5.23954 25.738 4.95724 26.6005 5.00519C27.463 5.05313 28.3137 5.43204 28.9371 6.12878C29.4928 6.74989 29.8 7.55405 29.8 8.38746V46.28C29.8 47.2149 29.4186 48.0645 28.8078 48.6754C28.197 49.2862 27.3474 49.6675 26.4125 49.6675C25.5843 49.6675 24.7848 49.3641 24.1651 48.8147L13.0526 38.9618C12.5285 38.4971 11.8523 38.2405 11.1518 38.2405H5.3875C4.45261 38.2405 3.603 37.8591 2.99218 37.2483C2.38135 36.6375 2 35.7879 2 34.853V19.7719C2 18.837 2.38135 17.9874 2.99218 17.3766C3.603 16.7658 4.45262 16.3844 5.3875 16.3844H11.2991C12.004 16.3844 12.6841 16.1246 13.2095 15.6546L24.1538 5.86289ZM25.8 9.75731L15.8766 18.6356C14.6178 19.7618 12.9881 20.3844 11.2991 20.3844H6V34.2405H11.1518C12.8302 34.2405 14.4505 34.8553 15.7064 35.9688L25.8 44.9184V9.75731Z" /><path :style="{ opacity: opacity(1) }" d="M38.1519 17.8402L36.992 16.2108L33.7333 18.5304L34.8931 20.1598C36.2942 22.1281 37.1487 24.6457 37.1487 27.4131C37.1487 30.1933 36.2862 32.7214 34.8736 34.6937L33.709 36.3197L36.9609 38.6488L38.1255 37.0229C40.0285 34.366 41.1487 31.0221 41.1487 27.4131C41.1487 23.8207 40.0388 20.4911 38.1519 17.8402Z" /><path :style="{ opacity: opacity(2) }" d="M43.617 8.17398L44.9714 9.64556C49.0913 14.1219 51.6179 20.3637 51.6179 27.2257C51.6179 34.0838 49.0943 40.3223 44.9787 44.798L43.6249 46.2702L40.6805 43.5627L42.0343 42.0905C45.4542 38.3714 47.6179 33.1061 47.6179 27.2257C47.6179 21.3419 45.4516 16.0739 42.0282 12.3544L40.6738 10.8828L43.617 8.17398Z" /></g></svg>
|
|
72
|
+
</span>
|
|
73
|
+
</span>
|
|
74
|
+
</template>
|
|
75
|
+
|
|
76
|
+
<style>
|
|
77
|
+
.vp-audio-reader {
|
|
78
|
+
display: inline-block;
|
|
79
|
+
color: currentcolor;
|
|
80
|
+
cursor: pointer;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.vp-audio-reader .icon-audio {
|
|
84
|
+
display: inline-block;
|
|
85
|
+
width: 1.2em;
|
|
86
|
+
height: 1.2em;
|
|
87
|
+
margin-left: 0.2em;
|
|
88
|
+
vertical-align: middle;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.vp-audio-reader,
|
|
92
|
+
.vp-audio-reader .icon-audio {
|
|
93
|
+
transition: color var(--vp-t-color);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.vp-audio-reader:hover,
|
|
97
|
+
.vp-audio-reader:hover .icon-audio {
|
|
98
|
+
color: var(--vp-c-brand-1);
|
|
99
|
+
}
|
|
100
|
+
</style>
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as vue from 'vue';
|
|
2
|
+
import { MaybeRef } from 'vue';
|
|
3
|
+
|
|
4
|
+
interface BufferedRange {
|
|
5
|
+
start: number;
|
|
6
|
+
end: number;
|
|
7
|
+
}
|
|
8
|
+
interface AudioPlayerOptions {
|
|
9
|
+
type?: MaybeRef<string>;
|
|
10
|
+
autoplay?: boolean;
|
|
11
|
+
mutex?: boolean;
|
|
12
|
+
onload?: HTMLAudioElement['onload'];
|
|
13
|
+
onerror?: HTMLAudioElement['onerror'];
|
|
14
|
+
onpause?: HTMLAudioElement['onpause'];
|
|
15
|
+
onplay?: HTMLAudioElement['onplay'];
|
|
16
|
+
onplaying?: HTMLAudioElement['onplaying'];
|
|
17
|
+
onseeked?: HTMLAudioElement['onseeked'];
|
|
18
|
+
onvolume?: (volume: number) => void;
|
|
19
|
+
onend?: HTMLAudioElement['onended'];
|
|
20
|
+
onprogress?: (current: number, total: number) => void;
|
|
21
|
+
oncanplay?: HTMLAudioElement['oncanplay'];
|
|
22
|
+
oncanplaythrough?: HTMLAudioElement['oncanplaythrough'];
|
|
23
|
+
ontimeupdate?: (currentTime: number) => void;
|
|
24
|
+
onwaiting?: HTMLAudioElement['onwaiting'];
|
|
25
|
+
}
|
|
26
|
+
declare function useAudioPlayer(source: MaybeRef<string>, options?: AudioPlayerOptions): {
|
|
27
|
+
isSupported: vue.Ref<boolean, boolean>;
|
|
28
|
+
paused: vue.Ref<boolean, boolean>;
|
|
29
|
+
loaded: vue.Ref<boolean, boolean>;
|
|
30
|
+
currentTime: vue.Ref<number, number>;
|
|
31
|
+
duration: vue.Ref<number, number>;
|
|
32
|
+
player: null;
|
|
33
|
+
destroy: () => void;
|
|
34
|
+
play: () => void;
|
|
35
|
+
pause: () => void | undefined;
|
|
36
|
+
seek(time: number): void;
|
|
37
|
+
setVolume(volume: number): void;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { type AudioPlayerOptions, type BufferedRange, useAudioPlayer };
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
// src/client/composables/audio.ts
|
|
2
|
+
import { onMounted, onUnmounted, ref, toValue, watch } from "vue";
|
|
3
|
+
var mimeTypes = {
|
|
4
|
+
"audio/flac": ["flac", "fla"],
|
|
5
|
+
"audio/mpeg": ["mp3", "mpga"],
|
|
6
|
+
"audio/mp4": ["mp4", "m4a"],
|
|
7
|
+
"audio/ogg": ["ogg", "oga"],
|
|
8
|
+
"audio/aac": ["aac", "adts"],
|
|
9
|
+
"audio/x-ms-wma": ["wma"],
|
|
10
|
+
"audio/x-aiff": ["aiff", "aif", "aifc"],
|
|
11
|
+
"audio/webm": ["webm"]
|
|
12
|
+
};
|
|
13
|
+
var playerList = [];
|
|
14
|
+
function useAudioPlayer(source, options = {}) {
|
|
15
|
+
let player = null;
|
|
16
|
+
let unknownSupport = false;
|
|
17
|
+
const isSupported = ref(false);
|
|
18
|
+
const loaded = ref(false);
|
|
19
|
+
const paused = ref(true);
|
|
20
|
+
const currentTime = ref(0);
|
|
21
|
+
const duration = ref(0);
|
|
22
|
+
const volume = ref(1);
|
|
23
|
+
function initialize() {
|
|
24
|
+
player = document.createElement("audio");
|
|
25
|
+
player.className = "audio-player";
|
|
26
|
+
player.style.display = "none";
|
|
27
|
+
player.preload = options.autoplay ? "auto" : "none";
|
|
28
|
+
player.autoplay = options.autoplay ?? false;
|
|
29
|
+
document.body.appendChild(player);
|
|
30
|
+
playerList.push(player);
|
|
31
|
+
player.onloadedmetadata = () => {
|
|
32
|
+
duration.value = player.duration;
|
|
33
|
+
currentTime.value = player.currentTime;
|
|
34
|
+
volume.value = player.volume;
|
|
35
|
+
loaded.value = true;
|
|
36
|
+
};
|
|
37
|
+
player.oncanplay = (...args) => {
|
|
38
|
+
loaded.value = true;
|
|
39
|
+
if (unknownSupport)
|
|
40
|
+
isSupported.value = true;
|
|
41
|
+
options.oncanplay?.bind(player)(...args);
|
|
42
|
+
};
|
|
43
|
+
player.onplay = (...args) => {
|
|
44
|
+
paused.value = false;
|
|
45
|
+
options.onplay?.bind(player)(...args);
|
|
46
|
+
};
|
|
47
|
+
player.onpause = (...args) => {
|
|
48
|
+
paused.value = true;
|
|
49
|
+
options.onpause?.bind(player)(...args);
|
|
50
|
+
};
|
|
51
|
+
player.ontimeupdate = () => {
|
|
52
|
+
if (isValidDuration(player.duration)) {
|
|
53
|
+
const lastBufferTime = getLastBufferedTime();
|
|
54
|
+
if (lastBufferTime <= player.duration) {
|
|
55
|
+
options.ontimeupdate?.bind(player)(lastBufferTime);
|
|
56
|
+
currentTime.value = lastBufferTime;
|
|
57
|
+
options.onprogress?.bind(player)(lastBufferTime, player.duration);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
player.onvolumechange = () => {
|
|
62
|
+
volume.value = player.volume;
|
|
63
|
+
options.onvolume?.bind(player)(player.volume);
|
|
64
|
+
};
|
|
65
|
+
player.onended = (...args) => {
|
|
66
|
+
paused.value = true;
|
|
67
|
+
options.onend?.bind(player)(...args);
|
|
68
|
+
};
|
|
69
|
+
player.onplaying = options.onplaying;
|
|
70
|
+
player.onload = options.onload;
|
|
71
|
+
player.onerror = options.onerror;
|
|
72
|
+
player.onseeked = options.onseeked;
|
|
73
|
+
player.oncanplaythrough = options.oncanplaythrough;
|
|
74
|
+
player.onwaiting = options.onwaiting;
|
|
75
|
+
isSupported.value = isSupportType();
|
|
76
|
+
player.src = toValue(source);
|
|
77
|
+
player.load();
|
|
78
|
+
}
|
|
79
|
+
function isSupportType() {
|
|
80
|
+
if (!player)
|
|
81
|
+
return false;
|
|
82
|
+
let type = toValue(options.type);
|
|
83
|
+
if (!type) {
|
|
84
|
+
const ext = toValue(source).split(".").pop() || "";
|
|
85
|
+
type = Object.keys(mimeTypes).filter((type2) => mimeTypes[type2].includes(ext))[0];
|
|
86
|
+
}
|
|
87
|
+
if (!type) {
|
|
88
|
+
unknownSupport = true;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const isSupported2 = player.canPlayType(type) !== "";
|
|
92
|
+
if (!isSupported2) {
|
|
93
|
+
console.warn(`The specified type "${type}" is not supported by the browser.`);
|
|
94
|
+
}
|
|
95
|
+
return isSupported2;
|
|
96
|
+
}
|
|
97
|
+
function getBufferedRanges() {
|
|
98
|
+
if (!player)
|
|
99
|
+
return [];
|
|
100
|
+
const ranges = [];
|
|
101
|
+
const seekable = player.buffered || [];
|
|
102
|
+
const offset = 0;
|
|
103
|
+
for (let i = 0, length = seekable.length; i < length; i++) {
|
|
104
|
+
let start = seekable.start(i);
|
|
105
|
+
let end = seekable.end(i);
|
|
106
|
+
if (!isValidDuration(start))
|
|
107
|
+
start = 0;
|
|
108
|
+
if (!isValidDuration(end)) {
|
|
109
|
+
end = 0;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
ranges.push({
|
|
113
|
+
start: start + offset,
|
|
114
|
+
end: end + offset
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return ranges;
|
|
118
|
+
}
|
|
119
|
+
function getLastBufferedTime() {
|
|
120
|
+
const bufferedRanges = getBufferedRanges();
|
|
121
|
+
if (!bufferedRanges.length)
|
|
122
|
+
return 0;
|
|
123
|
+
const buff = bufferedRanges.find(
|
|
124
|
+
(buff2) => buff2.start < player.currentTime && buff2.end > player.currentTime
|
|
125
|
+
);
|
|
126
|
+
if (buff)
|
|
127
|
+
return buff.end;
|
|
128
|
+
const last = bufferedRanges[bufferedRanges.length - 1];
|
|
129
|
+
return last.end;
|
|
130
|
+
}
|
|
131
|
+
function isValidDuration(duration2) {
|
|
132
|
+
if (duration2 && !Number.isNaN(duration2) && duration2 !== Number.POSITIVE_INFINITY && duration2 !== Number.NEGATIVE_INFINITY) {
|
|
133
|
+
return true;
|
|
134
|
+
}
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
function destroy() {
|
|
138
|
+
player?.pause();
|
|
139
|
+
player?.remove();
|
|
140
|
+
playerList.splice(playerList.indexOf(player), 1);
|
|
141
|
+
player = null;
|
|
142
|
+
}
|
|
143
|
+
onMounted(() => {
|
|
144
|
+
initialize();
|
|
145
|
+
watch([source, options.type], () => {
|
|
146
|
+
destroy();
|
|
147
|
+
loaded.value = false;
|
|
148
|
+
paused.value = true;
|
|
149
|
+
currentTime.value = 0;
|
|
150
|
+
duration.value = 0;
|
|
151
|
+
initialize();
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
onUnmounted(() => destroy());
|
|
155
|
+
return {
|
|
156
|
+
isSupported,
|
|
157
|
+
paused,
|
|
158
|
+
loaded,
|
|
159
|
+
currentTime,
|
|
160
|
+
duration,
|
|
161
|
+
player,
|
|
162
|
+
destroy,
|
|
163
|
+
play: () => {
|
|
164
|
+
if (options.mutex ?? true) {
|
|
165
|
+
for (const p of playerList) {
|
|
166
|
+
if (p !== player)
|
|
167
|
+
p.pause();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
player?.play();
|
|
171
|
+
},
|
|
172
|
+
pause: () => player?.pause(),
|
|
173
|
+
seek(time) {
|
|
174
|
+
if (player)
|
|
175
|
+
player.currentTime = time;
|
|
176
|
+
},
|
|
177
|
+
setVolume(volume2) {
|
|
178
|
+
if (player)
|
|
179
|
+
player.volume = Math.min(1, Math.max(0, volume2));
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
export {
|
|
184
|
+
useAudioPlayer
|
|
185
|
+
};
|
package/lib/node/index.d.ts
CHANGED
package/lib/node/index.js
CHANGED
|
@@ -1824,6 +1824,67 @@ async function containerPlugin(app, md, options) {
|
|
|
1824
1824
|
}
|
|
1825
1825
|
}
|
|
1826
1826
|
|
|
1827
|
+
// src/node/embed/audio/reader.ts
|
|
1828
|
+
var audioReader = (state, silent) => {
|
|
1829
|
+
const max = state.posMax;
|
|
1830
|
+
let start = state.pos;
|
|
1831
|
+
let href = "";
|
|
1832
|
+
if (state.src.slice(start, start + 13) !== "@[audioReader")
|
|
1833
|
+
return false;
|
|
1834
|
+
if (max - start < 17)
|
|
1835
|
+
return false;
|
|
1836
|
+
const labelStart = state.pos + 13;
|
|
1837
|
+
const labelEnd = state.md.helpers.parseLinkLabel(state, state.pos + 1, true);
|
|
1838
|
+
if (labelEnd < 0)
|
|
1839
|
+
return false;
|
|
1840
|
+
let pos = labelEnd + 1;
|
|
1841
|
+
if (pos < max && state.src.charCodeAt(pos) === 40) {
|
|
1842
|
+
pos++;
|
|
1843
|
+
const code = state.src.charCodeAt(pos);
|
|
1844
|
+
if (code === 10 || code === 32)
|
|
1845
|
+
return false;
|
|
1846
|
+
start = pos;
|
|
1847
|
+
const res = state.md.helpers.parseLinkDestination(state.src, pos, state.posMax);
|
|
1848
|
+
if (res.ok) {
|
|
1849
|
+
href = state.md.normalizeLink(res.str);
|
|
1850
|
+
if (state.md.validateLink(href)) {
|
|
1851
|
+
pos = res.pos;
|
|
1852
|
+
} else {
|
|
1853
|
+
href = "";
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
if (pos >= max || state.src.charCodeAt(pos) !== 41) {
|
|
1857
|
+
return false;
|
|
1858
|
+
}
|
|
1859
|
+
} else {
|
|
1860
|
+
return false;
|
|
1861
|
+
}
|
|
1862
|
+
if (!silent) {
|
|
1863
|
+
state.pos = labelStart;
|
|
1864
|
+
state.posMax = labelEnd;
|
|
1865
|
+
const info = state.src.slice(labelStart, labelEnd).trim();
|
|
1866
|
+
const { attrs: attrs2 } = resolveAttrs(info);
|
|
1867
|
+
const tokenOpen = state.push("audio_reader_open", "AudioReader", 1);
|
|
1868
|
+
tokenOpen.info = info;
|
|
1869
|
+
tokenOpen.attrs = [["src", href]];
|
|
1870
|
+
if (attrs2.startTime)
|
|
1871
|
+
tokenOpen.attrs.push([":start-time", attrs2.startTime]);
|
|
1872
|
+
if (attrs2.endTime)
|
|
1873
|
+
tokenOpen.attrs.push([":end-time", attrs2.endTime]);
|
|
1874
|
+
if (attrs2.type)
|
|
1875
|
+
tokenOpen.attrs.push(["type", attrs2.type]);
|
|
1876
|
+
if (attrs2.volume)
|
|
1877
|
+
tokenOpen.attrs.push([":volume", attrs2.volume]);
|
|
1878
|
+
if (attrs2.title)
|
|
1879
|
+
state.push("text", "", 0).content = attrs2.title;
|
|
1880
|
+
state.push("audio_reader_close", "AudioReader", -1);
|
|
1881
|
+
}
|
|
1882
|
+
state.pos = pos + 1;
|
|
1883
|
+
state.posMax = max;
|
|
1884
|
+
return true;
|
|
1885
|
+
};
|
|
1886
|
+
var audioReaderPlugin = (md) => md.inline.ruler.before("link", "audio-reader", audioReader);
|
|
1887
|
+
|
|
1827
1888
|
// src/node/embed/caniuse.ts
|
|
1828
1889
|
import container5 from "markdown-it-container";
|
|
1829
1890
|
|
|
@@ -2277,6 +2338,9 @@ function embedSyntaxPlugin(md, options) {
|
|
|
2277
2338
|
if (options.artPlayer) {
|
|
2278
2339
|
md.use(artPlayerPlugin);
|
|
2279
2340
|
}
|
|
2341
|
+
if (options.audioReader) {
|
|
2342
|
+
md.use(audioReaderPlugin);
|
|
2343
|
+
}
|
|
2280
2344
|
if (options.codepen) {
|
|
2281
2345
|
md.use(codepenPlugin);
|
|
2282
2346
|
}
|
|
@@ -2339,14 +2403,16 @@ import { tasklist } from "@mdit/plugin-tasklist";
|
|
|
2339
2403
|
import { isPlainObject as isPlainObject3 } from "@vuepress/helper";
|
|
2340
2404
|
|
|
2341
2405
|
// src/node/inline/icons.ts
|
|
2342
|
-
var [openTag, endTag] = [":[", "]:"];
|
|
2343
2406
|
var iconsPlugin = (md, options = {}) => md.inline.ruler.before("emphasis", "iconify", createTokenizer(options));
|
|
2344
2407
|
function createTokenizer(options) {
|
|
2345
2408
|
return (state, silent) => {
|
|
2346
2409
|
let found = false;
|
|
2347
2410
|
const max = state.posMax;
|
|
2348
2411
|
const start = state.pos;
|
|
2349
|
-
if (state.src.
|
|
2412
|
+
if (state.src.charCodeAt(start) !== 58 || state.src.charCodeAt(start + 1) !== 91) {
|
|
2413
|
+
return false;
|
|
2414
|
+
}
|
|
2415
|
+
if (state.src.charCodeAt(start + 2) === 32)
|
|
2350
2416
|
return false;
|
|
2351
2417
|
if (silent)
|
|
2352
2418
|
return false;
|
|
@@ -2354,34 +2420,30 @@ function createTokenizer(options) {
|
|
|
2354
2420
|
return false;
|
|
2355
2421
|
state.pos = start + 2;
|
|
2356
2422
|
while (state.pos < max) {
|
|
2357
|
-
if (state.src.
|
|
2423
|
+
if (state.src.charCodeAt(state.pos) === 93 && state.src.charCodeAt(state.pos + 1) === 58) {
|
|
2358
2424
|
found = true;
|
|
2359
2425
|
break;
|
|
2360
2426
|
}
|
|
2361
2427
|
state.md.inline.skipToken(state);
|
|
2362
2428
|
}
|
|
2363
|
-
if (!found || start + 2 === state.pos) {
|
|
2429
|
+
if (!found || start + 2 === state.pos || state.src.charCodeAt(state.pos - 1) === 32) {
|
|
2364
2430
|
state.pos = start;
|
|
2365
2431
|
return false;
|
|
2366
2432
|
}
|
|
2367
2433
|
const content = state.src.slice(start + 2, state.pos);
|
|
2368
|
-
if (/^\s|\s$/.test(content)) {
|
|
2369
|
-
state.pos = start;
|
|
2370
|
-
return false;
|
|
2371
|
-
}
|
|
2372
2434
|
state.posMax = state.pos;
|
|
2373
2435
|
state.pos = start + 2;
|
|
2374
|
-
const [name, opt = ""] = content.split(
|
|
2375
|
-
const [size, color = options.color] = opt.split("/");
|
|
2376
|
-
const icon = state.push("
|
|
2377
|
-
icon.markup =
|
|
2378
|
-
icon.
|
|
2436
|
+
const [name, opt = ""] = content.split(" ");
|
|
2437
|
+
const [size, color = options.color] = opt.trim().split("/");
|
|
2438
|
+
const icon = state.push("vp_icon_open", "VPIcon", 1);
|
|
2439
|
+
icon.markup = ":[";
|
|
2440
|
+
icon.attrs = [["name", name]];
|
|
2379
2441
|
if (size || options.size)
|
|
2380
|
-
icon.
|
|
2442
|
+
icon.attrs.push(["size", String(size || options.size)]);
|
|
2381
2443
|
if (color)
|
|
2382
|
-
icon.
|
|
2383
|
-
const close = state.push("
|
|
2384
|
-
close.markup =
|
|
2444
|
+
icon.attrs.push(["color", color]);
|
|
2445
|
+
const close = state.push("vp_icon_close", "VPIcon", -1);
|
|
2446
|
+
close.markup = "]:";
|
|
2385
2447
|
state.pos = state.posMax + 2;
|
|
2386
2448
|
state.posMax = max;
|
|
2387
2449
|
return true;
|
|
@@ -2389,14 +2451,17 @@ function createTokenizer(options) {
|
|
|
2389
2451
|
}
|
|
2390
2452
|
|
|
2391
2453
|
// src/node/inline/plot.ts
|
|
2392
|
-
var [openTag2, endTag2] = ["!!", "!!"];
|
|
2393
2454
|
var plotPlugin = (md) => md.inline.ruler.before("emphasis", "plot", createTokenizer2());
|
|
2394
2455
|
function createTokenizer2() {
|
|
2395
2456
|
return (state, silent) => {
|
|
2396
2457
|
let found = false;
|
|
2397
2458
|
const max = state.posMax;
|
|
2398
2459
|
const start = state.pos;
|
|
2399
|
-
if (state.src.
|
|
2460
|
+
if (state.src.charCodeAt(start) !== 33 || state.src.charCodeAt(start + 1) !== 33) {
|
|
2461
|
+
return false;
|
|
2462
|
+
}
|
|
2463
|
+
const next = state.src.charCodeAt(start + 2);
|
|
2464
|
+
if (next === 32 || next === 33)
|
|
2400
2465
|
return false;
|
|
2401
2466
|
if (silent)
|
|
2402
2467
|
return false;
|
|
@@ -2404,29 +2469,25 @@ function createTokenizer2() {
|
|
|
2404
2469
|
return false;
|
|
2405
2470
|
state.pos = start + 2;
|
|
2406
2471
|
while (state.pos < max) {
|
|
2407
|
-
if (state.src.
|
|
2472
|
+
if (state.src.charCodeAt(state.pos) === 33 && state.src.charCodeAt(state.pos + 1) === 33) {
|
|
2408
2473
|
found = true;
|
|
2409
2474
|
break;
|
|
2410
2475
|
}
|
|
2411
2476
|
state.md.inline.skipToken(state);
|
|
2412
2477
|
}
|
|
2413
|
-
if (!found || start + 2 === state.pos) {
|
|
2414
|
-
state.pos = start;
|
|
2415
|
-
return false;
|
|
2416
|
-
}
|
|
2417
|
-
const content = state.src.slice(start + 2, state.pos - 1);
|
|
2418
|
-
if (/^\s|\s$/.test(content)) {
|
|
2478
|
+
if (!found || start + 2 === state.pos || state.src.charCodeAt(state.pos - 1) === 32) {
|
|
2419
2479
|
state.pos = start;
|
|
2420
2480
|
return false;
|
|
2421
2481
|
}
|
|
2422
|
-
state.
|
|
2482
|
+
const content = state.src.slice(start + 2, state.pos);
|
|
2483
|
+
state.posMax = state.pos;
|
|
2423
2484
|
state.pos = start + 2;
|
|
2424
2485
|
const open = state.push("plot_open", "Plot", 1);
|
|
2425
|
-
open.markup =
|
|
2486
|
+
open.markup = "!!";
|
|
2426
2487
|
const text = state.push("text", "", 0);
|
|
2427
2488
|
text.content = content;
|
|
2428
2489
|
const close = state.push("plot_close", "Plot", -1);
|
|
2429
|
-
close.markup =
|
|
2490
|
+
close.markup = "!!";
|
|
2430
2491
|
state.pos = state.posMax + 2;
|
|
2431
2492
|
state.posMax = max;
|
|
2432
2493
|
return true;
|
|
@@ -2504,6 +2565,10 @@ async function prepareConfigFile(app, options) {
|
|
|
2504
2565
|
imports.add(`import ArtPlayer from '${CLIENT_FOLDER}components/ArtPlayer.vue'`);
|
|
2505
2566
|
enhances.add(`app.component('ArtPlayer', ArtPlayer)`);
|
|
2506
2567
|
}
|
|
2568
|
+
if (options.audioReader) {
|
|
2569
|
+
imports.add(`import AudioReader from '${CLIENT_FOLDER}components/AudioReader.vue'`);
|
|
2570
|
+
enhances.add(`app.component('AudioReader', AudioReader)`);
|
|
2571
|
+
}
|
|
2507
2572
|
return app.writeTemp(
|
|
2508
2573
|
"md-power/config.js",
|
|
2509
2574
|
`import { defineClientConfig } from 'vuepress/client'
|
|
@@ -2560,5 +2625,6 @@ export {
|
|
|
2560
2625
|
markdownPowerPlugin,
|
|
2561
2626
|
resolveImageSize
|
|
2562
2627
|
};
|
|
2628
|
+
/* istanbul ignore else -- @preserve */
|
|
2563
2629
|
/* istanbul ignore if -- @preserve */
|
|
2564
2630
|
/* istanbul ignore next -- @preserve */
|
package/lib/shared/index.d.ts
CHANGED
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.125",
|
|
5
5
|
"description": "The Plugin for VuePress 2 - markdown power",
|
|
6
6
|
"author": "pengzhanbo <volodymyr@foxmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -64,14 +64,14 @@
|
|
|
64
64
|
"@mdit/plugin-tab": "^0.14.0",
|
|
65
65
|
"@mdit/plugin-tasklist": "^0.14.0",
|
|
66
66
|
"@vuepress/helper": "2.0.0-rc.66",
|
|
67
|
-
"@vueuse/core": "^12.
|
|
67
|
+
"@vueuse/core": "^12.2.0",
|
|
68
68
|
"image-size": "^1.2.0",
|
|
69
69
|
"local-pkg": "^0.5.1",
|
|
70
70
|
"markdown-it-container": "^4.0.0",
|
|
71
71
|
"nanoid": "^5.0.9",
|
|
72
72
|
"shiki": "^1.24.4",
|
|
73
|
-
"tm-grammars": "^1.21.
|
|
74
|
-
"tm-themes": "^1.9.
|
|
73
|
+
"tm-grammars": "^1.21.11",
|
|
74
|
+
"tm-themes": "^1.9.6",
|
|
75
75
|
"vue": "^3.5.13"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
@@ -79,7 +79,7 @@
|
|
|
79
79
|
"artplayer": "^5.2.1",
|
|
80
80
|
"dashjs": "^4.7.4",
|
|
81
81
|
"hls.js": "^1.5.18",
|
|
82
|
-
"mpegts.js": "^1.
|
|
82
|
+
"mpegts.js": "^1.8.0"
|
|
83
83
|
},
|
|
84
84
|
"publishConfig": {
|
|
85
85
|
"access": "public"
|
|
@@ -91,9 +91,12 @@
|
|
|
91
91
|
"vuepress-plugin-md-power"
|
|
92
92
|
],
|
|
93
93
|
"scripts": {
|
|
94
|
+
"dev": "pnpm '/(copy|tsup):watch/'",
|
|
94
95
|
"build": "pnpm copy && pnpm tsup",
|
|
95
96
|
"clean": "rimraf --glob ./lib",
|
|
96
97
|
"copy": "cpx \"src/**/*.{d.ts,vue,css,scss,jpg,png}\" lib",
|
|
97
|
-
"
|
|
98
|
+
"copy:watch": "cpx \"src/**/*.{d.ts,vue,css,scss,jpg,png}\" lib -w",
|
|
99
|
+
"tsup": "tsup --config tsup.config.ts",
|
|
100
|
+
"tsup:watch": "tsup --config tsup.config.ts --watch -- -c"
|
|
98
101
|
}
|
|
99
102
|
}
|