spoiler tag

This commit is contained in:
polv committed 2026-03-25 06:24:45 +07:00
1 parent 9e8aeb04a1
commit d73dee6410
6 files changed
+301 -33

No files matched your search

+50 -1
View File
@@ -1,4 +1,4 @@
import { defineConfig } from "vitepress";
import { defineConfig, MarkdownOptions } from "vitepress";
// https://vitepress.dev/reference/site-config
export default defineConfig({
@@ -13,4 +13,53 @@ export default defineConfig({
level: "deep",
},
},
markdown: {
config(md) {
const mdInline: MarkdownOptions["config"] = (md) => {
const className = "md";
md.core.ruler.after("inline", "inline_class_md", (state: any) => {
const tokens = state.tokens;
const tagPattern = new RegExp(
`class=(?:\"|')([^\"']*\\b${escapeReg(className)}\\b[^\"']*)(?:\"|')`,
"i",
);
for (let i = 0; i < tokens.length; i++) {
const t = tokens[i];
if (!/^(html_inline|html_block)$/.test(t.type)) continue;
const html = t.content;
// match tags with class including the target class, capture inner content (non-greedy)
const pattern = new RegExp(
`<([a-zA-Z0-9-]+)(\\b[^>]*)?>([\\s\\S]*?)<\\/\\1>`,
"gi",
);
let lastIndex = 0;
let out = "";
let m;
while ((m = pattern.exec(html)) !== null) {
const [full, tagName, attrs = "", inner] = m;
const idx = m.index;
if (idx > lastIndex) out += html.slice(lastIndex, idx);
if (tagPattern.test(attrs)) {
// render inner as inline markdown
out += `<${tagName}${attrs}>${md.renderInline(inner)}</${tagName}>`;
} else {
out += full;
}
lastIndex = idx + full.length;
}
if (lastIndex === 0) continue;
if (lastIndex < html.length) out += html.slice(lastIndex);
t.content = out;
}
});
function escapeReg(s: string) {
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
};
md.use(mdInline);
},
},
});
+5 -1
View File
@@ -1,7 +1,7 @@
<template>
<details>
<summary :class="$style.summary">{{ summary }}</summary>
<blockquote>
<blockquote :class="$style.inner">
<slot />
</blockquote>
</details>
@@ -17,4 +17,8 @@ defineProps<{
.summary {
margin-top: -1em !important;
}
.inner p {
margin: 16px 0;
}
</style>
+3 -2
View File
@@ -1,10 +1,10 @@
<template>
<span>
<span ref="main">
<span ref="main" :class="class">
<slot />
</span>
<span>
<button type="button" @click="playAudio()">▶️</button>
<button type="button" @click="playAudio()">🎤︎︎</button>
</span>
</span>
</template>
@@ -13,6 +13,7 @@
import { useTemplateRef } from "vue";
const { lang = "ko" } = defineProps<{
class?: string;
lang?: string;
}>();
+3
View File
@@ -0,0 +1,3 @@
.spoiler:not(:hover) {
filter: blur(5px);
}
+1
View File
@@ -1,3 +1,4 @@
import "./custom.css";
import "./style.css";
import DefaultTheme from "vitepress/theme";