mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
parent
e2fb1c10e8
commit
dc42be6035
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -56,6 +56,7 @@
|
||||
"vue"
|
||||
],
|
||||
"cSpell.words": [
|
||||
"acfun",
|
||||
"bilibili",
|
||||
"bumpp",
|
||||
"caniuse",
|
||||
|
||||
@ -109,6 +109,7 @@ export const themeGuide: ThemeNote = defineNoteConfig({
|
||||
items: [
|
||||
'pdf',
|
||||
'bilibili',
|
||||
'acfun',
|
||||
'youtube',
|
||||
'artplayer',
|
||||
'audioReader',
|
||||
|
||||
@ -35,6 +35,7 @@ export const theme: Theme = plumeTheme({
|
||||
imageSize: 'all',
|
||||
pdf: true,
|
||||
caniuse: true,
|
||||
acfun: true,
|
||||
bilibili: true,
|
||||
youtube: true,
|
||||
artPlayer: true,
|
||||
|
||||
@ -29,6 +29,7 @@ export default defineUserConfig({
|
||||
// demo: true, // :::demo
|
||||
// pdf: true, // @[pdf](url) 嵌入 PDF 文件
|
||||
// bilibili: true, // @[bilibili](bvid) 嵌入 bilibili 视频
|
||||
// acfun: true, // @[acfun](id) 嵌入 AcFun 视屏
|
||||
// youtube: true, // @[youtube](id) 嵌入 youtube 视频
|
||||
// codepen: true, // @[codepen](user/slash) 嵌入 codepen
|
||||
// replit: true, // @[replit](user/repl-name) 嵌入 Replit
|
||||
@ -86,6 +87,18 @@ __语法:__
|
||||
|
||||
请查看 [完整使用文档](../../guide/embed/bilibili.md)
|
||||
|
||||
### AcFun 视频
|
||||
|
||||
插件默认不启用该功能,你需要手动设置 `acfun` 为 `true`
|
||||
|
||||
__语法:__
|
||||
|
||||
```md
|
||||
@[acfun](id)
|
||||
```
|
||||
|
||||
请查看 [完整使用文档](../../guide/embed/video/acfun.md)
|
||||
|
||||
### youtube 视频
|
||||
|
||||
插件默认不启用该功能,你需要手动设置 `youtube` 为 `true`
|
||||
|
||||
62
docs/notes/theme/guide/embed/acfun.md
Normal file
62
docs/notes/theme/guide/embed/acfun.md
Normal file
@ -0,0 +1,62 @@
|
||||
---
|
||||
title: AcFun 视频
|
||||
icon: lets-icons:video-fill
|
||||
createTime: 2025/06/28 10:57:45
|
||||
permalink: /guide/embed/video/acfun/
|
||||
badge: 新
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
主题提供了 嵌入 AcFun 视频 的功能。
|
||||
|
||||
该功能由 [vuepress-plugin-md-power](../../config/plugins/markdown-power.md) 提供支持。
|
||||
|
||||
## 配置
|
||||
|
||||
该功能默认不启用。你需要在主题配置中开启。
|
||||
|
||||
```ts title=".vuepress/config.ts"
|
||||
export default defineUserConfig({
|
||||
theme: plumeTheme({
|
||||
markdown: {
|
||||
acfun: true, // [!code ++]
|
||||
},
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## 语法
|
||||
|
||||
简单的语法:
|
||||
|
||||
```md
|
||||
@[acfun](id)
|
||||
```
|
||||
|
||||
更多选项:
|
||||
|
||||
```md
|
||||
@[acfun width="100%" height="400px" ratio="16:9"](id)
|
||||
```
|
||||
|
||||
**选项说明:**
|
||||
|
||||
- id: 视频 ID
|
||||
- width: 视频宽度
|
||||
- height: 视频高度
|
||||
- ratio: 视频比例,默认 `16:9`
|
||||
|
||||
## 示例
|
||||
|
||||
### 宽频视频
|
||||
|
||||
输入:
|
||||
|
||||
```md
|
||||
@[acfun](ac47431669)
|
||||
```
|
||||
|
||||
输出:
|
||||
|
||||
@[acfun](ac47431669)
|
||||
@ -0,0 +1,10 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`acfunPlugin > should not work 1`] = `
|
||||
"<VPVideoEmbed src="https://www.acfun.cn/player/" width="100%" ratio="16:10" title="AcFun" type="acfun" /><p>@[acfun]xxx</p>
|
||||
<p>@[ acfun]123456</p>
|
||||
<p>@<a href="123456"> acfun</a></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`acfunPlugin > should work 1`] = `"<VPVideoEmbed src="https://www.acfun.cn/player/123456" width="100%" ratio="16:10" title="AcFun" type="acfun" /><VPVideoEmbed src="https://www.acfun.cn/player/123456" width="100%" ratio="16:10" title="test" type="acfun" /><VPVideoEmbed src="https://www.acfun.cn/player/123456" width="100%" height="600px" ratio="16:10" title="AcFun" type="acfun" /><VPVideoEmbed src="https://www.acfun.cn/player/123456" width="100%" ratio="16:9" title="AcFun" type="acfun" />"`;
|
||||
@ -1,10 +1,10 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`bilibiliPlugin > should not work 1`] = `
|
||||
"<VideoBilibili src="https://player.bilibili.com/player.html?autoplay=0&high_quality=1" width="100%" /><p>@[bilibili]xxx</p>
|
||||
"<VPVideoEmbed src="https://player.bilibili.com/player.html?autoplay=0&high_quality=1" width="100%" title="Bilibili" type="bilibili" /><p>@[bilibili]xxx</p>
|
||||
<p>@[ bilibili]BV12345</p>
|
||||
<p>@[bilibili](BV12345</p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`bilibiliPlugin > should work 1`] = `"<VideoBilibili src="https://player.bilibili.com/player.html?bvid=BV12345&autoplay=0&high_quality=1" width="100%" /><VideoBilibili src="https://player.bilibili.com/player.html?aid=12432&cid=12345&autoplay=0&high_quality=1" width="100%" /><VideoBilibili src="https://player.bilibili.com/player.html?bvid=BV12345&aid=12343&cid=45678&autoplay=0&high_quality=1" width="100%" /><VideoBilibili src="https://player.bilibili.com/player.html?bvid=BV12345&p=1&t=1&autoplay=1&high_quality=1" width="100%" /><VideoBilibili src="https://player.bilibili.com/player.html?bvid=BV12345&p=1&autoplay=1&high_quality=1" width="100%" height="600px" /><VideoBilibili src="https://player.bilibili.com/player.html?bvid=BV12345&p=1&autoplay=1&high_quality=1" width="100%" ratio="16:9" />"`;
|
||||
exports[`bilibiliPlugin > should work 1`] = `"<VPVideoEmbed src="https://player.bilibili.com/player.html?bvid=BV12345&autoplay=0&high_quality=1" width="100%" title="Bilibili" type="bilibili" /><VPVideoEmbed src="https://player.bilibili.com/player.html?aid=12432&cid=12345&autoplay=0&high_quality=1" width="100%" title="Bilibili" type="bilibili" /><VPVideoEmbed src="https://player.bilibili.com/player.html?bvid=BV12345&aid=12343&cid=45678&autoplay=0&high_quality=1" width="100%" title="Bilibili" type="bilibili" /><VPVideoEmbed src="https://player.bilibili.com/player.html?bvid=BV12345&p=1&t=1&autoplay=1&high_quality=1" width="100%" title="Bilibili" type="bilibili" /><VPVideoEmbed src="https://player.bilibili.com/player.html?bvid=BV12345&p=1&autoplay=1&high_quality=1" width="100%" height="600px" title="Bilibili" type="bilibili" /><VPVideoEmbed src="https://player.bilibili.com/player.html?bvid=BV12345&p=1&autoplay=1&high_quality=1" width="100%" ratio="16:9" title="Bilibili" type="bilibili" />"`;
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`youtubePlugin > should not work 1`] = `
|
||||
"<VideoYoutube src="https://www.youtube.com/embed//?" width="100%" /><p>@[youtube]xxx</p>
|
||||
"<VPVideoEmbed src="https://www.youtube.com/embed//?" width="100%" title="YouTube" type="youtube" /><p>@[youtube]xxx</p>
|
||||
<p>@[ youtube]123456</p>
|
||||
<p>@<a href="123456"> youtube</a></p>
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`youtubePlugin > should work 1`] = `"<VideoYoutube src="https://www.youtube.com/embed//123456?" width="100%" /><VideoYoutube src="https://www.youtube.com/embed//123456?autoplay=1&loop=1" width="100%" title="test" /><VideoYoutube src="https://www.youtube.com/embed//123456?autoplay=1&start=40&end=80" width="100%" /><VideoYoutube src="https://www.youtube.com/embed//123456?" width="100%" height="600px" /><VideoYoutube src="https://www.youtube.com/embed//123456?" width="100%" ratio="16:9" />"`;
|
||||
exports[`youtubePlugin > should work 1`] = `"<VPVideoEmbed src="https://www.youtube.com/embed//123456?" width="100%" title="YouTube" type="youtube" /><VPVideoEmbed src="https://www.youtube.com/embed//123456?autoplay=1&loop=1" width="100%" title="test" type="youtube" /><VPVideoEmbed src="https://www.youtube.com/embed//123456?autoplay=1&start=40&end=80" width="100%" title="YouTube" type="youtube" /><VPVideoEmbed src="https://www.youtube.com/embed//123456?" width="100%" height="600px" title="YouTube" type="youtube" /><VPVideoEmbed src="https://www.youtube.com/embed//123456?" width="100%" ratio="16:9" title="YouTube" type="youtube" />"`;
|
||||
|
||||
42
plugins/plugin-md-power/__test__/acfunPlugin.spec.ts
Normal file
42
plugins/plugin-md-power/__test__/acfunPlugin.spec.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import MarkdownIt from 'markdown-it'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { acfunPlugin } from '../src/node/embed/video/acfun.js'
|
||||
|
||||
function createMarkdown() {
|
||||
return MarkdownIt().use((md) => {
|
||||
md.block.ruler.before('code', 'import_code', () => false)
|
||||
md.renderer.rules.import_code = () => ''
|
||||
}).use(acfunPlugin)
|
||||
}
|
||||
|
||||
describe('acfunPlugin', () => {
|
||||
it('should work', () => {
|
||||
const md = createMarkdown()
|
||||
const code = `\
|
||||
@[acfun](123456)
|
||||
|
||||
@[acfun title="test"](123456)
|
||||
|
||||
@[acfun width="100%" height="600px"](123456)
|
||||
|
||||
@[acfun width="100%" ratio="16:9"](123456)
|
||||
`
|
||||
|
||||
expect(md.render(code)).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should not work', () => {
|
||||
const md = createMarkdown()
|
||||
const code = `\
|
||||
@[acfun]()
|
||||
|
||||
@[acfun]xxx
|
||||
|
||||
@[ acfun]123456
|
||||
|
||||
@[ acfun](123456)
|
||||
`
|
||||
|
||||
expect(md.render(code)).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
@ -1,45 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
import { useSize } from '../composables/size.js'
|
||||
|
||||
const props = defineProps<{
|
||||
src: string
|
||||
title: string
|
||||
width?: string
|
||||
height?: string
|
||||
ratio?: string
|
||||
}>()
|
||||
|
||||
const IFRAME_ALLOW = 'accelerometer; autoplay; clipboard-write; encrypted-media; fullscreen; gyroscope; picture-in-picture'
|
||||
|
||||
const options = toRefs(props)
|
||||
|
||||
const { el, width, height, resize } = useSize(options)
|
||||
|
||||
function onLoad() {
|
||||
resize()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientOnly>
|
||||
<iframe
|
||||
ref="el"
|
||||
class="video_bilibili_iframe"
|
||||
:src="src"
|
||||
:title="title || 'Bilibili'"
|
||||
:style="{ width, height }"
|
||||
:allow="IFRAME_ALLOW"
|
||||
@load="onLoad"
|
||||
/>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.video_bilibili_iframe {
|
||||
width: 100%;
|
||||
margin: 16px auto;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
</style>
|
||||
@ -5,6 +5,7 @@ import { useSize } from '../composables/size.js'
|
||||
const props = defineProps<{
|
||||
src: string
|
||||
title: string
|
||||
type?: string
|
||||
width?: string
|
||||
height?: string
|
||||
ratio?: string
|
||||
@ -21,9 +22,9 @@ const { el, width, height, resize } = useSize(options)
|
||||
<ClientOnly>
|
||||
<iframe
|
||||
ref="el"
|
||||
class="video-youtube-iframe"
|
||||
class="video-iframe" :class="type"
|
||||
:src="src"
|
||||
:title="title || 'Youtube'"
|
||||
:title="title || type"
|
||||
:style="{ width, height }"
|
||||
:allow="IFRAME_ALLOW"
|
||||
@load="resize"
|
||||
@ -32,7 +33,7 @@ const { el, width, height, resize } = useSize(options)
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.video-youtube-iframe {
|
||||
.video-iframe {
|
||||
width: 100%;
|
||||
margin: 16px auto;
|
||||
border: none;
|
||||
@ -7,6 +7,7 @@ import { codeSandboxPlugin } from './code/codeSandbox.js'
|
||||
import { jsfiddlePlugin } from './code/jsfiddle.js'
|
||||
import { replitPlugin } from './code/replit.js'
|
||||
import { pdfPlugin } from './pdf.js'
|
||||
import { acfunPlugin } from './video/acfun.js'
|
||||
import { artPlayerPlugin } from './video/artPlayer.js'
|
||||
import { bilibiliPlugin } from './video/bilibili.js'
|
||||
import { youtubePlugin } from './video/youtube.js'
|
||||
@ -25,6 +26,11 @@ export function embedSyntaxPlugin(md: Markdown, options: MarkdownPowerPluginOpti
|
||||
md.use(pdfPlugin)
|
||||
}
|
||||
|
||||
if (options.acfun) {
|
||||
// @[acfun](id)
|
||||
md.use(acfunPlugin)
|
||||
}
|
||||
|
||||
if (options.bilibili) {
|
||||
// @[bilibili](bvid aid cid)
|
||||
md.use(bilibiliPlugin)
|
||||
|
||||
35
plugins/plugin-md-power/src/node/embed/video/acfun.ts
Normal file
35
plugins/plugin-md-power/src/node/embed/video/acfun.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @[acfun](acid)
|
||||
*/
|
||||
import type { PluginWithOptions } from 'markdown-it'
|
||||
import type { AcFunTokenMeta } from '../../../shared/index.js'
|
||||
import { parseRect } from '../../utils/parseRect.js'
|
||||
import { resolveAttrs } from '../../utils/resolveAttrs.js'
|
||||
import { stringifyAttrs } from '../../utils/stringifyAttrs.js'
|
||||
import { createEmbedRuleBlock } from '../createEmbedRuleBlock.js'
|
||||
|
||||
const AC_FUN_LINK = 'https://www.acfun.cn/player'
|
||||
|
||||
export const acfunPlugin: PluginWithOptions<never> = (md) => {
|
||||
createEmbedRuleBlock<AcFunTokenMeta>(md, {
|
||||
type: 'acfun',
|
||||
name: 'video_acfun',
|
||||
syntaxPattern: /^@\[acfun([^\]]*)\]\(([^)]*)\)/,
|
||||
meta([, info, id]) {
|
||||
const { attrs } = resolveAttrs(info)
|
||||
|
||||
return {
|
||||
id,
|
||||
title: attrs.title || 'AcFun',
|
||||
width: attrs.width ? parseRect(attrs.width) : '100%',
|
||||
height: attrs.height ? parseRect(attrs.height) : undefined,
|
||||
ratio: attrs.ratio ?? '16:10',
|
||||
}
|
||||
},
|
||||
content(meta) {
|
||||
const { id, width, height, ratio, title } = meta
|
||||
const src = `${AC_FUN_LINK}/${id}`
|
||||
return `<VPVideoEmbed${stringifyAttrs({ src, width, height, ratio, title, type: 'acfun' })} />`
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -34,10 +34,10 @@ export const bilibiliPlugin: PluginWithOptions<never> = (md) => {
|
||||
cid,
|
||||
autoplay: attrs.autoplay ?? false,
|
||||
time: timeToSeconds(attrs.time),
|
||||
title: attrs.title,
|
||||
title: attrs.title || 'Bilibili',
|
||||
width: attrs.width ? parseRect(attrs.width) : '100%',
|
||||
height: attrs.height ? parseRect(attrs.height) : undefined,
|
||||
ratio: attrs.ratio ? parseRect(attrs.ratio) : undefined,
|
||||
ratio: attrs.ratio,
|
||||
}
|
||||
},
|
||||
content(meta) {
|
||||
@ -61,10 +61,10 @@ export const bilibiliPlugin: PluginWithOptions<never> = (md) => {
|
||||
params.set('autoplay', meta.autoplay ? '1' : '0')
|
||||
params.set('high_quality', '1')
|
||||
|
||||
const source = `${BILIBILI_LINK}?${params.toString()}`
|
||||
const src = `${BILIBILI_LINK}?${params.toString()}`
|
||||
const { width, height, ratio, title } = meta
|
||||
|
||||
return `<VideoBilibili${stringifyAttrs({ src: source, width, height, ratio, title })} />`
|
||||
return `<VPVideoEmbed${stringifyAttrs({ src, width, height, ratio, title, type: 'bilibili' })} />`
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -26,10 +26,10 @@ export const youtubePlugin: PluginWithOptions<never> = (md) => {
|
||||
loop: attrs.loop ?? false,
|
||||
start: timeToSeconds(attrs.start),
|
||||
end: timeToSeconds(attrs.end),
|
||||
title: attrs.title,
|
||||
title: attrs.title || 'YouTube',
|
||||
width: attrs.width ? parseRect(attrs.width) : '100%',
|
||||
height: attrs.height ? parseRect(attrs.height) : undefined,
|
||||
ratio: attrs.ratio ? parseRect(attrs.ratio) : undefined,
|
||||
ratio: attrs.ratio,
|
||||
}
|
||||
},
|
||||
content(meta) {
|
||||
@ -47,10 +47,10 @@ export const youtubePlugin: PluginWithOptions<never> = (md) => {
|
||||
if (meta.end)
|
||||
params.set('end', meta.end.toString())
|
||||
|
||||
const source = `${YOUTUBE_LINK}/${meta.id}?${params.toString()}`
|
||||
const src = `${YOUTUBE_LINK}/${meta.id}?${params.toString()}`
|
||||
const { width, height, ratio, title } = meta
|
||||
|
||||
return `<VideoYoutube${stringifyAttrs({ src: source, width, height, ratio, title })} />`
|
||||
return `<VPVideoEmbed${stringifyAttrs({ src, width, height, ratio, title, type: 'youtube' })} />`
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@ -26,14 +26,9 @@ export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOp
|
||||
enhances.add(`app.component('PDFViewer', PDFViewer)`)
|
||||
}
|
||||
|
||||
if (options.bilibili) {
|
||||
imports.add(`import Bilibili from '${CLIENT_FOLDER}components/Bilibili.vue'`)
|
||||
enhances.add(`app.component('VideoBilibili', Bilibili)`)
|
||||
}
|
||||
|
||||
if (options.youtube) {
|
||||
imports.add(`import Youtube from '${CLIENT_FOLDER}components/Youtube.vue'`)
|
||||
enhances.add(`app.component('VideoYoutube', Youtube)`)
|
||||
if (options.acfun || options.bilibili || options.youtube) {
|
||||
imports.add(`import VPVideoEmbed from '${CLIENT_FOLDER}components/VPVideoEmbed.vue'`)
|
||||
enhances.add(`app.component('VPVideoEmbed', VPVideoEmbed)`)
|
||||
}
|
||||
|
||||
if (options.codepen) {
|
||||
|
||||
@ -128,6 +128,14 @@ export interface MarkdownPowerPluginOptions {
|
||||
*/
|
||||
field?: boolean
|
||||
// video embed
|
||||
/**
|
||||
* 是否启用 acfun 视频嵌入
|
||||
*
|
||||
* `@[acfun](acid)`
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
acfun?: boolean
|
||||
/**
|
||||
* 是否启用 bilibili 视频嵌入
|
||||
*
|
||||
|
||||
@ -5,6 +5,11 @@ export interface VideoOptions {
|
||||
youtube?: boolean
|
||||
}
|
||||
|
||||
export interface AcFunTokenMeta extends SizeOptions {
|
||||
title?: string
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface BilibiliTokenMeta extends SizeOptions {
|
||||
title?: string
|
||||
bvid?: string
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user