feat(theme)!: migrate plugin-md-enhance to official plugins (#206)
* feat(theme)!: migrate `plugin-markdown-hint` * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * chore: tweak * fix(theme): improve `home-blog` styles in mobile, close #210 * chore: tweak * chore: tweak
This commit is contained in:
parent
6a3c64326a
commit
49672724eb
@ -66,6 +66,9 @@ export async function createPackageJson(
|
||||
if (bundler === 'webpack' && !pkg.dependencies?.['sass-loader'] && !pkg.devDependencies['sass-loader'])
|
||||
deps.push('sass-loader')
|
||||
|
||||
if (!pkg.dependencies?.['sass-embedded'] && !pkg.devDependencies['sass-embedded'])
|
||||
deps.push('sass-embedded')
|
||||
|
||||
const dv = await getDependenciesVersion(deps)
|
||||
|
||||
for (const [d, v] of Object.entries(dv))
|
||||
|
||||
@ -252,6 +252,9 @@ function foo() {
|
||||
}
|
||||
```
|
||||
|
||||
::: tip 仅标题
|
||||
:::
|
||||
|
||||
::: note 注释
|
||||
注释内容 [link](https://github.com/pengzhanbo) `inline code`
|
||||
|
||||
@ -318,6 +321,11 @@ const c = a + b
|
||||
|
||||
:::
|
||||
|
||||
::: details 详细标题
|
||||
|
||||
这里是内容。
|
||||
:::
|
||||
|
||||
**GFM alert:**
|
||||
|
||||
> [!note]
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
"vuepress": "2.0.0-rc.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iconify/json": "^2.2.251",
|
||||
"@iconify/json": "^2.2.252",
|
||||
"@simonwep/pickr": "^1.9.1",
|
||||
"@vuepress/bundler-vite": "2.0.0-rc.15",
|
||||
"chart.js": "^4.4.4",
|
||||
@ -20,8 +20,9 @@
|
||||
"flowchart.ts": "^3.0.1",
|
||||
"http-server": "^14.1.1",
|
||||
"mermaid": "^11.2.1",
|
||||
"sass-embedded": "^1.79.3",
|
||||
"swiper": "^11.1.14",
|
||||
"vue": "^3.5.7",
|
||||
"vue": "^3.5.8",
|
||||
"vuepress-theme-plume": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
"vuepress": "2.0.0-rc.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.5.7"
|
||||
"vue": "^3.5.8"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -40,15 +40,22 @@
|
||||
"vuepress": "2.0.0-rc.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vuepress/helper": "2.0.0-rc.46",
|
||||
"@mdit/plugin-attrs": "^0.13.1",
|
||||
"@mdit/plugin-footnote": "^0.13.1",
|
||||
"@mdit/plugin-mark": "^0.13.1",
|
||||
"@mdit/plugin-sub": "^0.13.1",
|
||||
"@mdit/plugin-sup": "^0.13.1",
|
||||
"@mdit/plugin-tab": "^0.13.1",
|
||||
"@mdit/plugin-tasklist": "^0.13.1",
|
||||
"@vuepress/helper": "2.0.0-rc.47",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"image-size": "^1.1.1",
|
||||
"markdown-it-container": "^4.0.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"shiki": "^1.18.0",
|
||||
"tm-grammars": "^1.17.24",
|
||||
"tm-themes": "^1.8.3",
|
||||
"vue": "^3.5.7"
|
||||
"tm-themes": "^1.8.4",
|
||||
"vue": "^3.5.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/markdown-it": "^14.1.2"
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { defineAsyncComponent, shallowRef } from 'vue'
|
||||
import { useCodeRepl } from '../composables/codeRepl.js'
|
||||
import IconClose from './IconClose.vue'
|
||||
import IconConsole from './IconConsole.vue'
|
||||
import IconRun from './IconRun.vue'
|
||||
import Loading from './Loading.vue'
|
||||
import IconClose from './icons/IconClose.vue'
|
||||
import IconConsole from './icons/IconConsole.vue'
|
||||
import IconRun from './icons/IconRun.vue'
|
||||
import Loading from './icons/Loading.vue'
|
||||
|
||||
defineProps<{
|
||||
editable?: boolean
|
||||
|
||||
241
plugins/plugin-md-power/src/client/components/CodeTabs.vue
Normal file
241
plugins/plugin-md-power/src/client/components/CodeTabs.vue
Normal file
@ -0,0 +1,241 @@
|
||||
<script setup lang="ts">
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { onMounted, ref, shallowRef, watch } from 'vue'
|
||||
|
||||
interface TabProps extends Record<string, unknown> {
|
||||
id: string
|
||||
}
|
||||
const props = withDefaults(defineProps<{
|
||||
id: string
|
||||
tabId?: string
|
||||
active?: number
|
||||
data: TabProps[]
|
||||
}>(), { active: 0, tabId: '' })
|
||||
|
||||
const CODE_TAB_STORE_NAME = 'VUEPRESS_CODE_TAB_STORE'
|
||||
const codeTabStore = useStorage<Record<string, string>>(CODE_TAB_STORE_NAME, {})
|
||||
|
||||
// Index of current active item
|
||||
const activeIndex = ref(props.active)
|
||||
|
||||
// Refs of the tab buttons
|
||||
const tabRefs = shallowRef<HTMLUListElement[]>([])
|
||||
|
||||
// Update store
|
||||
function updateStore(): void {
|
||||
if (props.tabId)
|
||||
codeTabStore.value[props.tabId] = props.data[activeIndex.value].id
|
||||
}
|
||||
|
||||
// Activate next tab
|
||||
function activateNext(index = activeIndex.value): void {
|
||||
activeIndex.value = index < tabRefs.value.length - 1 ? index + 1 : 0
|
||||
tabRefs.value[activeIndex.value].focus()
|
||||
}
|
||||
|
||||
// Activate previous tab
|
||||
function activatePrev(index = activeIndex.value): void {
|
||||
activeIndex.value = index > 0 ? index - 1 : tabRefs.value.length - 1
|
||||
tabRefs.value[activeIndex.value].focus()
|
||||
}
|
||||
|
||||
// Handle keyboard event
|
||||
function keyboardHandler(event: KeyboardEvent, index: number): void {
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
event.preventDefault()
|
||||
activeIndex.value = index
|
||||
}
|
||||
else if (event.key === 'ArrowRight') {
|
||||
event.preventDefault()
|
||||
activateNext()
|
||||
}
|
||||
else if (event.key === 'ArrowLeft') {
|
||||
event.preventDefault()
|
||||
activatePrev()
|
||||
}
|
||||
|
||||
if (props.tabId)
|
||||
codeTabStore.value[props.tabId] = props.data[activeIndex.value].id
|
||||
}
|
||||
|
||||
function getInitialIndex(): number {
|
||||
if (props.tabId) {
|
||||
const valueIndex = props.data.findIndex(
|
||||
({ id }) => codeTabStore.value[props.tabId] === id,
|
||||
)
|
||||
|
||||
if (valueIndex !== -1)
|
||||
return valueIndex
|
||||
}
|
||||
|
||||
return props.active
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
activeIndex.value = getInitialIndex()
|
||||
|
||||
watch(
|
||||
() => codeTabStore.value[props.tabId],
|
||||
(newValue, oldValue) => {
|
||||
if (props.tabId && newValue !== oldValue) {
|
||||
const index = props.data.findIndex(({ id }) => id === newValue)
|
||||
|
||||
if (index !== -1)
|
||||
activeIndex.value = index
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
function onTabNavClick(index: number): void {
|
||||
activeIndex.value = index
|
||||
updateStore()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="data.length" class="vp-code-tabs">
|
||||
<div class="vp-code-tabs-nav" role="tablist">
|
||||
<button
|
||||
v-for="(item, index) in data"
|
||||
:key="index"
|
||||
:ref="(el) => el && (tabRefs[index] = el as HTMLUListElement)"
|
||||
class="vp-code-tab-nav" :class="{ active: index === activeIndex }"
|
||||
type="button" role="tab"
|
||||
:aria-controls="`codetab-${id}-${index}`"
|
||||
:aria-selected="index === activeIndex"
|
||||
@click="() => onTabNavClick(index)"
|
||||
@keydown="(e) => keyboardHandler(e, index)"
|
||||
>
|
||||
<slot :name="`title${index}`" :value="item.id" :is-active="index === activeIndex" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in data"
|
||||
:id="`codetab-${id}-${index}`" :key="index"
|
||||
class="vp-code-tab" :class="{ active: index === activeIndex }"
|
||||
role="tabpanel" :aria-expanded="index === activeIndex"
|
||||
>
|
||||
<div class="vp-code-tab-title">
|
||||
<slot :name="`title${index}`" :value="item.id" :is-active="index === activeIndex" />
|
||||
</div>
|
||||
<slot :name="`tab${index}`" :value="item.id" :is-active="index === activeIndex" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.vp-code-tabs-nav {
|
||||
padding: 0 12px;
|
||||
margin: 16px 0 0;
|
||||
overflow: auto hidden;
|
||||
white-space: nowrap;
|
||||
list-style: none;
|
||||
background-color: var(--vp-code-tab-bg);
|
||||
border-radius: 6px 6px 0 0;
|
||||
box-shadow: inset 0 -1px var(--vp-code-tab-divider);
|
||||
transition: background-color var(--vp-t-color), box-shadow var(--vp-t-color);
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-code-tabs-nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.vp-code-tabs-nav {
|
||||
margin: 16px -24px 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.vp-doc li .vp-code-tabs-nav {
|
||||
border-top-left-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-code-tab-nav {
|
||||
position: relative;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 48px;
|
||||
color: var(--vp-code-tab-text-color);
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-code-tab-nav:hover {
|
||||
color: var(--vp-code-tab-hover-text-color);
|
||||
}
|
||||
|
||||
.vp-code-tab-nav::after {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: -1px;
|
||||
left: 8px;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 2px;
|
||||
content: "";
|
||||
background: transparent;
|
||||
border-radius: 2px;
|
||||
transition: background var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-code-tab-nav.active {
|
||||
color: var(--vp-code-tab-active-text-color);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.vp-code-tab-nav.active::after {
|
||||
background: var(--vp-code-tab-active-bar-color);
|
||||
}
|
||||
|
||||
.vp-code-tab-nav .vp-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.vp-code-tab-nav span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@media (max-width: 419px) {
|
||||
.hint-container .vp-code-tabs-nav {
|
||||
margin: 0.85rem -0.75rem 0 -1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-code-tab {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-code-tab {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-code-tab.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab div[class*="language-"] {
|
||||
margin-top: 0;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.vp-code-tab-title {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-code-tab-title {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { ReplitTokenMeta } from '../../shared/index.js'
|
||||
import { computed, getCurrentInstance, ref } from 'vue'
|
||||
import Loading from './Loading.vue'
|
||||
import Loading from './icons/Loading.vue'
|
||||
|
||||
const props = defineProps<ReplitTokenMeta>()
|
||||
|
||||
|
||||
277
plugins/plugin-md-power/src/client/components/Tabs.vue
Normal file
277
plugins/plugin-md-power/src/client/components/Tabs.vue
Normal file
@ -0,0 +1,277 @@
|
||||
<script setup lang="ts">
|
||||
import { useStorage } from '@vueuse/core'
|
||||
import { onMounted, ref, shallowRef, watch } from 'vue'
|
||||
|
||||
interface TabProps extends Record<string, unknown> {
|
||||
id: string
|
||||
}
|
||||
const props = withDefaults(defineProps<{
|
||||
id: string
|
||||
tabId?: string
|
||||
active?: number
|
||||
data: TabProps[]
|
||||
}>(), { active: 0, tabId: '' })
|
||||
|
||||
const TAB_STORE_NAME = 'VUEPRESS_TAB_STORE'
|
||||
|
||||
const tabStore = useStorage<Record<string, string>>(TAB_STORE_NAME, {})
|
||||
|
||||
// Index of current active item
|
||||
const activeIndex = ref(props.active)
|
||||
|
||||
// Refs of the tab buttons
|
||||
const tabRefs = shallowRef<HTMLUListElement[]>([])
|
||||
|
||||
// Update store
|
||||
function updateStore(): void {
|
||||
if (props.tabId)
|
||||
tabStore.value[props.tabId] = props.data[activeIndex.value].id
|
||||
}
|
||||
|
||||
// Activate next tab
|
||||
function activateNext(index = activeIndex.value): void {
|
||||
activeIndex.value = index < tabRefs.value.length - 1 ? index + 1 : 0
|
||||
tabRefs.value[activeIndex.value].focus()
|
||||
}
|
||||
|
||||
// Activate previous tab
|
||||
function activatePrev(index = activeIndex.value): void {
|
||||
activeIndex.value = index > 0 ? index - 1 : tabRefs.value.length - 1
|
||||
tabRefs.value[activeIndex.value].focus()
|
||||
}
|
||||
|
||||
// Handle keyboard event
|
||||
function keyboardHandler(event: KeyboardEvent, index: number): void {
|
||||
if (event.key === ' ' || event.key === 'Enter') {
|
||||
event.preventDefault()
|
||||
activeIndex.value = index
|
||||
}
|
||||
else if (event.key === 'ArrowRight') {
|
||||
event.preventDefault()
|
||||
activateNext()
|
||||
}
|
||||
else if (event.key === 'ArrowLeft') {
|
||||
event.preventDefault()
|
||||
activatePrev()
|
||||
}
|
||||
|
||||
updateStore()
|
||||
}
|
||||
|
||||
function getInitialIndex(): number {
|
||||
if (props.tabId) {
|
||||
const valueIndex = props.data.findIndex(
|
||||
({ id }) => tabStore.value[props.tabId] === id,
|
||||
)
|
||||
|
||||
if (valueIndex !== -1)
|
||||
return valueIndex
|
||||
}
|
||||
|
||||
return props.active
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
activeIndex.value = getInitialIndex()
|
||||
|
||||
watch(
|
||||
() => tabStore.value[props.tabId],
|
||||
(newValue, oldValue) => {
|
||||
if (props.tabId && newValue !== oldValue) {
|
||||
const index = props.data.findIndex(({ id }) => id === newValue)
|
||||
|
||||
if (index !== -1)
|
||||
activeIndex.value = index
|
||||
}
|
||||
},
|
||||
)
|
||||
})
|
||||
|
||||
function onTabNavClick(index: number): void {
|
||||
activeIndex.value = index
|
||||
updateStore()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="data.length" class="vp-tabs">
|
||||
<div class="vp-tabs-nav" role="tablist">
|
||||
<button
|
||||
v-for="(item, index) in data"
|
||||
:key="index"
|
||||
:ref="(el) => el && (tabRefs[index] = el as HTMLUListElement)"
|
||||
class="vp-tab-nav" :class="{ active: index === activeIndex }"
|
||||
type="button" role="tab"
|
||||
:aria-controls="`tab-${id}-${index}`"
|
||||
:aria-selected="index === activeIndex"
|
||||
@click="() => onTabNavClick(index)"
|
||||
@keydown="(e) => keyboardHandler(e, index)"
|
||||
>
|
||||
<slot :name="`title${index}`" :value="item.id" :is-active="index === activeIndex" />
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-for="(item, index) in data"
|
||||
:id="`tab-${id}-${index}`" :key="index"
|
||||
class="vp-tab" :class="{ active: index === activeIndex }"
|
||||
role="tabpanel" :aria-expanded="index === activeIndex"
|
||||
>
|
||||
<div class="vp-tab-title">
|
||||
<slot :name="`title${index}`" :value="item.id" :is-active="index === activeIndex" />
|
||||
</div>
|
||||
<slot :name="`tab${index}`" :value="item.id" :is-active="index === activeIndex" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.vp-tabs {
|
||||
margin: 16px 0;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
border-radius: 6px;
|
||||
transition: border var(--vp-t-color);
|
||||
}
|
||||
|
||||
@media (max-width: 419px) {
|
||||
.vp-tabs {
|
||||
margin: 16px -24px;
|
||||
border: none;
|
||||
border-bottom: 1px solid var(--vp-c-divider);
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .vp-tabs-nav {
|
||||
padding: 0 12px;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
background-color: var(--vp-code-tab-bg);
|
||||
box-shadow: inset 0 -1px var(--vp-code-tab-divider);
|
||||
transition: background-color var(--vp-t-color), box-shadow var(--vp-t-color);
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-doc .vp-tabs-nav {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav {
|
||||
position: relative;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 48px;
|
||||
color: var(--vp-code-tab-text-color);
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav:hover {
|
||||
color: var(--vp-code-tab-text-hover-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav::after {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: -1px;
|
||||
left: 8px;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 2px;
|
||||
content: "";
|
||||
background: transparent;
|
||||
border-radius: 2px;
|
||||
transition: background var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav.active {
|
||||
color: var(--vp-code-tab-active-text-color);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav.active::after {
|
||||
background: var(--vp-code-tab-active-bar-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab {
|
||||
display: none;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab :nth-child(2) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-title {
|
||||
display: none;
|
||||
padding: 4px;
|
||||
font-weight: 500;
|
||||
color: var(--vp-code-tab-text-color);
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab:nth-child(n+2) .vp-tab-title {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-doc .vp-tab-title {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-tabs {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
@media (max-width: 419px) {
|
||||
.vp-doc .hint-container .vp-tabs {
|
||||
margin: 8px -16px;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-tab-nav {
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-info-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-note-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-tip-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-warning-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.danger .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-danger-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-caution-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-custom-block-important-code-bg);
|
||||
}
|
||||
</style>
|
||||
21
plugins/plugin-md-power/src/node/container/align.ts
Normal file
21
plugins/plugin-md-power/src/node/container/align.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import type Token from 'markdown-it/lib/token.mjs'
|
||||
import type { Markdown } from 'vuepress/markdown'
|
||||
import container from 'markdown-it-container'
|
||||
|
||||
const alignList = ['left', 'center', 'right', 'justify']
|
||||
|
||||
export function alignPlugin(md: Markdown): void {
|
||||
for (const name of alignList) {
|
||||
md.use(container, name, {
|
||||
validate: (info: string) => info.trim() === name,
|
||||
render: (tokens: Token[], idx: number): string => {
|
||||
if (tokens[idx].nesting === 1) {
|
||||
return `<div style="text-align:${name}">`
|
||||
}
|
||||
else {
|
||||
return '</div>'
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
55
plugins/plugin-md-power/src/node/container/codeTabs.ts
Normal file
55
plugins/plugin-md-power/src/node/container/codeTabs.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import type { PluginSimple } from 'markdown-it'
|
||||
import { tab } from '@mdit/plugin-tab'
|
||||
import { getFileIconName } from '../fileIcons/index.js'
|
||||
import { stringifyProp } from '../utils/stringifyProp.js'
|
||||
|
||||
export const codeTabs: PluginSimple = (md) => {
|
||||
tab(md, {
|
||||
name: 'code-tabs',
|
||||
|
||||
tabsOpenRenderer: ({ active, data }, tokens, index) => {
|
||||
const { meta } = tokens[index]
|
||||
const titles = data.map(({ title }) => md.renderInline(title))
|
||||
const tabsData = data.map((item, dataIndex) => {
|
||||
const { id = titles[dataIndex] } = item
|
||||
|
||||
return { id }
|
||||
})
|
||||
|
||||
const titlesContent = titles.map((title, index) => {
|
||||
const icon = getFileIconName(title)
|
||||
return `<template #title${index}="{ value, isActive }">${icon ? `<VPIcon name="${icon}"/>` : ''}<span>${title}</span></template>`
|
||||
}).join('')
|
||||
|
||||
return `<CodeTabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? '' : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id as string}"` : ''}>${titlesContent}`
|
||||
},
|
||||
|
||||
tabsCloseRenderer: () => `</CodeTabs>`,
|
||||
|
||||
tabOpenRenderer: ({ index }, tokens, tokenIndex) => {
|
||||
let foundFence = false
|
||||
|
||||
// Hide all elements excerpt the first fence
|
||||
for (let i = tokenIndex; i < tokens.length; i++) {
|
||||
const { block, type } = tokens[i]
|
||||
|
||||
if (block) {
|
||||
if (type === 'code-tabs_tab_close')
|
||||
break
|
||||
|
||||
if ((type === 'fence' || type === 'import_code') && !foundFence) {
|
||||
foundFence = true
|
||||
continue
|
||||
}
|
||||
|
||||
tokens[i].type = 'code_tab_empty'
|
||||
tokens[i].hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
return `<template #tab${index}="{ value, isActive }">`
|
||||
},
|
||||
|
||||
tabCloseRenderer: () => `</template>`,
|
||||
})
|
||||
}
|
||||
@ -1,5 +1,8 @@
|
||||
import type { Markdown } from 'vuepress/markdown'
|
||||
import Token from 'markdown-it/lib/token.mjs'
|
||||
import container from 'markdown-it-container'
|
||||
import { removeEndingSlash, removeLeadingSlash } from 'vuepress/shared'
|
||||
import { getFileIcon } from '../fileIcons/index.js'
|
||||
|
||||
interface FileTreeNode {
|
||||
filename: string
|
||||
@ -9,6 +12,63 @@ interface FileTreeNode {
|
||||
empty: boolean
|
||||
}
|
||||
|
||||
const type = 'file-tree'
|
||||
const closeType = `container_${type}_close`
|
||||
const componentName = 'FileTreeItem'
|
||||
const itemOpen = 'file_tree_item_open'
|
||||
const itemClose = 'file_tree_item_close'
|
||||
|
||||
export function fileTreePlugin(md: Markdown) {
|
||||
const validate = (info: string): boolean => info.trim().startsWith(type)
|
||||
const render = (tokens: Token[], idx: number): string => {
|
||||
if (tokens[idx].nesting === 1) {
|
||||
const hasRes: number[] = [] // level stack
|
||||
for (
|
||||
let i = idx + 1;
|
||||
!(tokens[i].nesting === -1
|
||||
&& tokens[i].type === closeType);
|
||||
++i
|
||||
) {
|
||||
const token = tokens[i]
|
||||
if (token.type === 'list_item_open') {
|
||||
const result = resolveTreeNodeInfo(tokens, token, i)
|
||||
if (result) {
|
||||
hasRes.push(token.level)
|
||||
const [info, inline] = result
|
||||
const { filename, type, expanded, empty } = info
|
||||
const icon = getFileIcon(filename, type)
|
||||
|
||||
token.type = itemOpen
|
||||
token.tag = componentName
|
||||
token.attrSet('type', type)
|
||||
token.attrSet(':expanded', expanded ? 'true' : 'false')
|
||||
token.attrSet(':empty', empty ? 'true' : 'false')
|
||||
updateInlineToken(inline, info, icon)
|
||||
}
|
||||
else {
|
||||
hasRes.push(-1)
|
||||
}
|
||||
}
|
||||
else if (token.type === 'list_item_close') {
|
||||
if (token.level === hasRes.pop()) {
|
||||
token.type = itemClose
|
||||
token.tag = componentName
|
||||
}
|
||||
}
|
||||
}
|
||||
const info = tokens[idx].info.trim()
|
||||
|
||||
const title = info.slice(type.length).trim()
|
||||
return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ''}`
|
||||
}
|
||||
else {
|
||||
return '</div>'
|
||||
}
|
||||
}
|
||||
|
||||
md.use(container, type, { validate, render })
|
||||
}
|
||||
|
||||
export function resolveTreeNodeInfo(
|
||||
tokens: Token[],
|
||||
current: Token,
|
||||
@ -1,62 +0,0 @@
|
||||
import type Token from 'markdown-it/lib/token.mjs'
|
||||
import type { Markdown } from 'vuepress/markdown'
|
||||
import container from 'markdown-it-container'
|
||||
import { getFileIcon } from './findIcon.js'
|
||||
import { resolveTreeNodeInfo, updateInlineToken } from './resolveTreeNodeInfo.js'
|
||||
|
||||
const type = 'file-tree'
|
||||
const closeType = `container_${type}_close`
|
||||
const componentName = 'FileTreeItem'
|
||||
const itemOpen = 'file_tree_item_open'
|
||||
const itemClose = 'file_tree_item_close'
|
||||
|
||||
export function fileTreePlugin(md: Markdown) {
|
||||
const validate = (info: string): boolean => info.trim().startsWith(type)
|
||||
const render = (tokens: Token[], idx: number): string => {
|
||||
if (tokens[idx].nesting === 1) {
|
||||
const hasRes: number[] = [] // level stack
|
||||
for (
|
||||
let i = idx + 1;
|
||||
!(tokens[i].nesting === -1
|
||||
&& tokens[i].type === closeType);
|
||||
++i
|
||||
) {
|
||||
const token = tokens[i]
|
||||
if (token.type === 'list_item_open') {
|
||||
const result = resolveTreeNodeInfo(tokens, token, i)
|
||||
if (result) {
|
||||
hasRes.push(token.level)
|
||||
const [info, inline] = result
|
||||
const { filename, type, expanded, empty } = info
|
||||
const icon = getFileIcon(filename, type)
|
||||
|
||||
token.type = itemOpen
|
||||
token.tag = componentName
|
||||
token.attrSet('type', type)
|
||||
token.attrSet(':expanded', expanded ? 'true' : 'false')
|
||||
token.attrSet(':empty', empty ? 'true' : 'false')
|
||||
updateInlineToken(inline, info, icon)
|
||||
}
|
||||
else {
|
||||
hasRes.push(-1)
|
||||
}
|
||||
}
|
||||
else if (token.type === 'list_item_close') {
|
||||
if (token.level === hasRes.pop()) {
|
||||
token.type = itemClose
|
||||
token.tag = componentName
|
||||
}
|
||||
}
|
||||
}
|
||||
const info = tokens[idx].info.trim()
|
||||
|
||||
const title = info.slice(type.length).trim()
|
||||
return `<div class="vp-file-tree">${title ? `<p class="vp-file-tree-title">${title}</p>` : ''}`
|
||||
}
|
||||
else {
|
||||
return '</div>'
|
||||
}
|
||||
}
|
||||
|
||||
md.use(container, type, { validate, render })
|
||||
}
|
||||
@ -1,14 +1,24 @@
|
||||
import type { App } from 'vuepress'
|
||||
import type { Markdown } from 'vuepress/markdown'
|
||||
import type { MarkdownPowerPluginOptions } from '../../shared/index.js'
|
||||
import { fileTreePlugin } from './fileTree/index.js'
|
||||
import { alignPlugin } from './align.js'
|
||||
import { codeTabs } from './codeTabs.js'
|
||||
import { fileTreePlugin } from './fileTree.js'
|
||||
import { langReplPlugin } from './langRepl.js'
|
||||
import { tabs } from './tabs.js'
|
||||
|
||||
export async function containerPlugin(
|
||||
app: App,
|
||||
md: Markdown,
|
||||
options: MarkdownPowerPluginOptions,
|
||||
) {
|
||||
// ::: left / right / center / justify
|
||||
alignPlugin(md)
|
||||
// ::: tabs
|
||||
tabs(md)
|
||||
// ::: code-tabs
|
||||
codeTabs(md)
|
||||
|
||||
if (options.repl)
|
||||
await langReplPlugin(app, md, options.repl)
|
||||
|
||||
|
||||
31
plugins/plugin-md-power/src/node/container/tabs.ts
Normal file
31
plugins/plugin-md-power/src/node/container/tabs.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import type { PluginSimple } from 'markdown-it'
|
||||
import { tab } from '@mdit/plugin-tab'
|
||||
import { stringifyProp } from '../utils/stringifyProp.js'
|
||||
|
||||
export const tabs: PluginSimple = (md) => {
|
||||
tab(md, {
|
||||
name: 'tabs',
|
||||
|
||||
tabsOpenRenderer: ({ active, data }, tokens, index) => {
|
||||
const { meta } = tokens[index]
|
||||
const titles = data.map(({ title }) => md.renderInline(title))
|
||||
const tabsData = data.map((item, dataIndex) => {
|
||||
const { id = titles[dataIndex] } = item
|
||||
|
||||
return { id }
|
||||
})
|
||||
|
||||
return `<Tabs id="${index}" :data='${stringifyProp(tabsData)}'${active === -1 ? '' : ` :active="${active}"`}${meta.id ? ` tab-id="${meta.id as string}"` : ''}>
|
||||
${titles.map((title, titleIndex) =>
|
||||
`<template #title${titleIndex}="{ value, isActive }">${title}</template>`,
|
||||
).join('')}`
|
||||
},
|
||||
|
||||
tabsCloseRenderer: () => `</Tabs>`,
|
||||
|
||||
tabOpenRenderer: ({ index }) =>
|
||||
`<template #tab${index}="{ value, isActive }">`,
|
||||
|
||||
tabCloseRenderer: () => `</template>`,
|
||||
})
|
||||
}
|
||||
@ -12,111 +12,148 @@ export const defaultFile = 'vscode-icons:default-file'
|
||||
export const definitions: Definitions = {
|
||||
named: {
|
||||
// package manager
|
||||
pnpm: 'vscode-icons:file-type-light-pnpm',
|
||||
PNPM: 'vscode-icons:file-type-light-pnpm',
|
||||
npm: 'vscode-icons:file-type-npm',
|
||||
NPM: 'vscode-icons:file-type-npm',
|
||||
yarn: 'vscode-icons:file-type-yarn',
|
||||
Yarn: 'vscode-icons:file-type-yarn',
|
||||
bun: 'vscode-icons:file-type-bun',
|
||||
Bun: 'vscode-icons:file-type-bun',
|
||||
deno: 'vscode-icons:file-type-light-deno',
|
||||
Deno: 'vscode-icons:file-type-light-deno',
|
||||
'pnpm': 'vscode-icons:file-type-light-pnpm',
|
||||
'PNPM': 'vscode-icons:file-type-light-pnpm',
|
||||
'npm': 'logos:npm-icon',
|
||||
'NPM': 'logos:npm-icon',
|
||||
'yarn': 'vscode-icons:file-type-yarn',
|
||||
'Yarn': 'vscode-icons:file-type-yarn',
|
||||
'bun': 'vscode-icons:file-type-bun',
|
||||
'Bun': 'vscode-icons:file-type-bun',
|
||||
'deno': 'vscode-icons:file-type-light-deno',
|
||||
'Deno': 'vscode-icons:file-type-light-deno',
|
||||
// bundlers
|
||||
rollup: 'vscode-icons:file-type-rollup',
|
||||
Rollup: 'vscode-icons:file-type-rollup',
|
||||
webpack: 'vscode-icons:file-type-webpack',
|
||||
Webpack: 'vscode-icons:file-type-webpack',
|
||||
vite: 'vscode-icons:file-type-vite',
|
||||
Vite: 'vscode-icons:file-type-vite',
|
||||
esbuild: 'vscode-icons:file-type-esbuild',
|
||||
Esbuild: 'vscode-icons:file-type-esbuild',
|
||||
'rollup': 'vscode-icons:file-type-rollup',
|
||||
'Rollup': 'vscode-icons:file-type-rollup',
|
||||
'webpack': 'vscode-icons:file-type-webpack',
|
||||
'Webpack': 'vscode-icons:file-type-webpack',
|
||||
'vite': 'vscode-icons:file-type-vite',
|
||||
'Vite': 'vscode-icons:file-type-vite',
|
||||
'esbuild': 'vscode-icons:file-type-esbuild',
|
||||
'Esbuild': 'vscode-icons:file-type-esbuild',
|
||||
// frameworks
|
||||
vue: 'vscode-icons:file-type-vue',
|
||||
Vue: 'vscode-icons:file-type-vue',
|
||||
svelte: 'vscode-icons:file-type-svelte',
|
||||
sveltekit: 'vscode-icons:file-type-svelte',
|
||||
angular: 'vscode-icons:file-type-angular',
|
||||
Angular: 'vscode-icons:file-type-angular',
|
||||
react: 'vscode-icons:file-type-reactjs',
|
||||
React: 'vscode-icons:file-type-reactjs',
|
||||
next: 'vscode-icons:file-type-light-next',
|
||||
Next: 'vscode-icons:file-type-light-next',
|
||||
Nextjs: 'vscode-icons:file-type-light-next',
|
||||
NextJS: 'vscode-icons:file-type-light-next',
|
||||
nuxt: 'vscode-icons:file-type-nuxt',
|
||||
Nuxt: 'vscode-icons:file-type-nuxt',
|
||||
Nuxtjs: 'vscode-icons:file-type-nuxt',
|
||||
NuxtJS: 'vscode-icons:file-type-nuxt',
|
||||
solid: 'logos:solidjs-icon',
|
||||
Solid: 'logos:solidjs-icon',
|
||||
solidjs: 'logos:solidjs-icon',
|
||||
astro: 'vscode-icons:file-type-light-astro',
|
||||
Astro: 'vscode-icons:file-type-light-astro',
|
||||
'vue': 'vscode-icons:file-type-vue',
|
||||
'Vue': 'vscode-icons:file-type-vue',
|
||||
'svelte': 'vscode-icons:file-type-svelte',
|
||||
'Svelte': 'vscode-icons:file-type-svelte',
|
||||
'sveltekit': 'vscode-icons:file-type-svelte',
|
||||
'SvelteKit': 'vscode-icons:file-type-svelte',
|
||||
'angular': 'vscode-icons:file-type-angular',
|
||||
'Angular': 'vscode-icons:file-type-angular',
|
||||
'react': 'vscode-icons:file-type-reactjs',
|
||||
'React': 'vscode-icons:file-type-reactjs',
|
||||
'next': 'vscode-icons:file-type-light-next',
|
||||
'Next': 'vscode-icons:file-type-light-next',
|
||||
'Nextjs': 'vscode-icons:file-type-light-next',
|
||||
'NextJS': 'vscode-icons:file-type-light-next',
|
||||
'nuxt': 'vscode-icons:file-type-nuxt',
|
||||
'Nuxt': 'vscode-icons:file-type-nuxt',
|
||||
'Nuxtjs': 'vscode-icons:file-type-nuxt',
|
||||
'NuxtJS': 'vscode-icons:file-type-nuxt',
|
||||
'solid': 'logos:solidjs-icon',
|
||||
'Solid': 'logos:solidjs-icon',
|
||||
'solidjs': 'logos:solidjs-icon',
|
||||
'astro': 'vscode-icons:file-type-light-astro',
|
||||
'Astro': 'vscode-icons:file-type-light-astro',
|
||||
|
||||
vitest: 'vscode-icons:file-type-vitest',
|
||||
Vitest: 'vscode-icons:file-type-vitest',
|
||||
playwright: 'vscode-icons:file-type-playwright',
|
||||
Playwright: 'vscode-icons:file-type-playwright',
|
||||
jest: 'vscode-icons:file-type-jest',
|
||||
Jest: 'vscode-icons:file-type-jest',
|
||||
cypress: 'vscode-icons:file-type-cypress',
|
||||
Cypress: 'vscode-icons:file-type-cypress',
|
||||
'vitest': 'vscode-icons:file-type-vitest',
|
||||
'Vitest': 'vscode-icons:file-type-vitest',
|
||||
'playwright': 'vscode-icons:file-type-playwright',
|
||||
'Playwright': 'vscode-icons:file-type-playwright',
|
||||
'jest': 'vscode-icons:file-type-jest',
|
||||
'Jest': 'vscode-icons:file-type-jest',
|
||||
'cypress': 'vscode-icons:file-type-cypress',
|
||||
'Cypress': 'vscode-icons:file-type-cypress',
|
||||
|
||||
docker: 'vscode-icons:file-type-docker',
|
||||
Docker: 'vscode-icons:file-type-docker',
|
||||
'docker': 'vscode-icons:file-type-docker',
|
||||
'Docker': 'vscode-icons:file-type-docker',
|
||||
|
||||
// TODO: code group title icons
|
||||
// programming languages
|
||||
html: 'vscode-icons:file-type-html',
|
||||
Html: 'vscode-icons:file-type-html',
|
||||
HTML: 'vscode-icons:file-type-html',
|
||||
javascript: 'vscode-icons:file-type-js-official',
|
||||
Javascript: 'vscode-icons:file-type-js-official',
|
||||
JavaScript: 'vscode-icons:file-type-js-official',
|
||||
js: 'vscode-icons:file-type-js-official',
|
||||
JS: 'vscode-icons:file-type-js-official',
|
||||
typescript: 'vscode-icons:file-type-typescript-official',
|
||||
Typescript: 'vscode-icons:file-type-typescript-official',
|
||||
TypeScript: 'vscode-icons:file-type-typescript-official',
|
||||
ts: 'vscode-icons:file-type-typescript-official',
|
||||
TS: 'vscode-icons:file-type-typescript-official',
|
||||
css: 'vscode-icons:file-type-css',
|
||||
CSS: 'vscode-icons:file-type-css',
|
||||
less: 'vscode-icons:file-type-less',
|
||||
Less: 'vscode-icons:file-type-less',
|
||||
scss: 'vscode-icons:file-type-scss',
|
||||
Scss: 'vscode-icons:file-type-scss',
|
||||
SCSS: 'vscode-icons:file-type-scss',
|
||||
sass: 'vscode-icons:file-type-sass',
|
||||
Sass: 'vscode-icons:file-type-sass',
|
||||
SASS: 'vscode-icons:file-type-sass',
|
||||
stylus: 'vscode-icons:file-type-light-stylus',
|
||||
Stylus: 'vscode-icons:file-type-light-stylus',
|
||||
postcss: 'vscode-icons:file-type-postcss',
|
||||
Postcss: 'vscode-icons:file-type-postcss',
|
||||
PostCSS: 'vscode-icons:file-type-postcss',
|
||||
java: 'vscode-icons:file-type-java',
|
||||
Java: 'vscode-icons:file-type-java',
|
||||
JAVA: 'vscode-icons:file-type-java',
|
||||
php: 'vscode-icons:file-type-php3',
|
||||
PHP: 'vscode-icons:file-type-php3',
|
||||
c: 'vscode-icons:file-type-c',
|
||||
C: 'vscode-icons:file-type-c',
|
||||
python: 'vscode-icons:file-type-python',
|
||||
Python: 'vscode-icons:file-type-python',
|
||||
kotlin: 'vscode-icons:file-type-kotlin',
|
||||
Kotlin: 'vscode-icons:file-type-kotlin',
|
||||
go: 'vscode-icons:file-type-go-gopher',
|
||||
golang: 'vscode-icons:file-type-go-gopher',
|
||||
Go: 'vscode-icons:file-type-go-gopher',
|
||||
GoLang: 'vscode-icons:file-type-go-gopher',
|
||||
rust: 'vscode-icons:file-type-rust',
|
||||
Rust: 'vscode-icons:file-type-rust',
|
||||
zig: 'vscode-icons:file-type-zig',
|
||||
Zig: 'vscode-icons:file-type-zig',
|
||||
swift: 'vscode-icons:file-type-swift',
|
||||
Swift: 'vscode-icons:file-type-swift',
|
||||
'html': 'vscode-icons:file-type-html',
|
||||
'Html': 'vscode-icons:file-type-html',
|
||||
'HTML': 'vscode-icons:file-type-html',
|
||||
'javascript': 'vscode-icons:file-type-js-official',
|
||||
'Javascript': 'vscode-icons:file-type-js-official',
|
||||
'JavaScript': 'vscode-icons:file-type-js-official',
|
||||
'js': 'vscode-icons:file-type-js-official',
|
||||
'JS': 'vscode-icons:file-type-js-official',
|
||||
'typescript': 'vscode-icons:file-type-typescript-official',
|
||||
'Typescript': 'vscode-icons:file-type-typescript-official',
|
||||
'TypeScript': 'vscode-icons:file-type-typescript-official',
|
||||
'ts': 'vscode-icons:file-type-typescript-official',
|
||||
'TS': 'vscode-icons:file-type-typescript-official',
|
||||
'css': 'vscode-icons:file-type-css',
|
||||
'CSS': 'vscode-icons:file-type-css',
|
||||
'less': 'vscode-icons:file-type-less',
|
||||
'Less': 'vscode-icons:file-type-less',
|
||||
'scss': 'vscode-icons:file-type-scss',
|
||||
'Scss': 'vscode-icons:file-type-scss',
|
||||
'SCSS': 'vscode-icons:file-type-scss',
|
||||
'sass': 'vscode-icons:file-type-sass',
|
||||
'Sass': 'vscode-icons:file-type-sass',
|
||||
'SASS': 'vscode-icons:file-type-sass',
|
||||
'stylus': 'vscode-icons:file-type-light-stylus',
|
||||
'Stylus': 'vscode-icons:file-type-light-stylus',
|
||||
'postcss': 'vscode-icons:file-type-postcss',
|
||||
'Postcss': 'vscode-icons:file-type-postcss',
|
||||
'PostCSS': 'vscode-icons:file-type-postcss',
|
||||
'sh': 'vscode-icons:file-type-shell',
|
||||
'shell': 'vscode-icons:file-type-shell',
|
||||
'Shell': 'vscode-icons:file-type-shell',
|
||||
'bash': 'vscode-icons:file-type-shell',
|
||||
'Bash': 'vscode-icons:file-type-shell',
|
||||
'java': 'vscode-icons:file-type-java',
|
||||
'Java': 'vscode-icons:file-type-java',
|
||||
'JAVA': 'vscode-icons:file-type-java',
|
||||
'php': 'vscode-icons:file-type-php3',
|
||||
'PHP': 'vscode-icons:file-type-php3',
|
||||
'c': 'vscode-icons:file-type-c',
|
||||
'C': 'vscode-icons:file-type-c',
|
||||
'python': 'vscode-icons:file-type-python',
|
||||
'Python': 'vscode-icons:file-type-python',
|
||||
'kotlin': 'vscode-icons:file-type-kotlin',
|
||||
'Kotlin': 'vscode-icons:file-type-kotlin',
|
||||
'go': 'vscode-icons:file-type-go-gopher',
|
||||
'golang': 'vscode-icons:file-type-go-gopher',
|
||||
'Go': 'vscode-icons:file-type-go-gopher',
|
||||
'GoLang': 'vscode-icons:file-type-go-gopher',
|
||||
'rust': 'vscode-icons:file-type-rust',
|
||||
'Rust': 'vscode-icons:file-type-rust',
|
||||
'zig': 'vscode-icons:file-type-zig',
|
||||
'Zig': 'vscode-icons:file-type-zig',
|
||||
'swift': 'vscode-icons:file-type-swift',
|
||||
'Swift': 'vscode-icons:file-type-swift',
|
||||
'c#': 'vscode-icons:file-type-csharp',
|
||||
'CSharp': 'vscode-icons:file-type-csharp',
|
||||
'c++': 'vscode-icons:file-type-cpp',
|
||||
'C++': 'vscode-icons:file-type-cpp',
|
||||
'ruby': 'vscode-icons:file-type-ruby',
|
||||
'Ruby': 'vscode-icons:file-type-ruby',
|
||||
'makefile': 'vscode-icons:file-type-makefile',
|
||||
'Makefile': 'vscode-icons:file-type-makefile',
|
||||
'Object-C': 'vscode-icons:file-type-objectivec',
|
||||
'object-c': 'vscode-icons:file-type-objectivec',
|
||||
'SQL': 'vscode-icons:file-type-sql',
|
||||
'sql': 'vscode-icons:file-type-sql',
|
||||
'mysql': 'vscode-icons:file-type-mysql',
|
||||
'MySQL': 'vscode-icons:file-type-mysql',
|
||||
'MySql': 'vscode-icons:file-type-mysql',
|
||||
'pgsql': 'vscode-icons:file-type-pgsql',
|
||||
'PostgreSQL': 'vscode-icons:file-type-pgsql',
|
||||
'PGSQL': 'vscode-icons:file-type-pgsql',
|
||||
'xml': 'vscode-icons:file-type-xml',
|
||||
'XML': 'vscode-icons:file-type-xml',
|
||||
'wasm': 'vscode-icons:file-type-wasm',
|
||||
'webassembly': 'vscode-icons:file-type-wasm',
|
||||
'WebAssembly': 'vscode-icons:file-type-wasm',
|
||||
'WASM': 'vscode-icons:file-type-wasm',
|
||||
'toml': 'vscode-icons:file-type-light-toml',
|
||||
'Toml': 'vscode-icons:file-type-light-toml',
|
||||
'TOML': 'vscode-icons:file-type-light-toml',
|
||||
'yaml': 'vscode-icons:file-type-light-yaml',
|
||||
'Yaml': 'vscode-icons:file-type-light-yaml',
|
||||
'YAML': 'vscode-icons:file-type-light-yaml',
|
||||
},
|
||||
folders: {
|
||||
'default': 'vscode-icons:default-folder',
|
||||
@ -8,7 +8,7 @@ export function getFileIcon(fileName: string, type: 'file' | 'folder' = 'file'):
|
||||
return name
|
||||
}
|
||||
|
||||
function getFileIconName(fileName: string, type: 'file' | 'folder' = 'file'): string | undefined {
|
||||
export function getFileIconName(fileName: string, type: 'file' | 'folder' = 'file'): string | undefined {
|
||||
if (type === 'folder') {
|
||||
const icon = definitions.folders[fileName]
|
||||
if (icon)
|
||||
2
plugins/plugin-md-power/src/node/fileIcons/index.ts
Normal file
2
plugins/plugin-md-power/src/node/fileIcons/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './definitions.js'
|
||||
export * from './findIcon.js'
|
||||
@ -1,5 +1,11 @@
|
||||
import type { Markdown } from 'vuepress/markdown'
|
||||
import type { MarkdownPowerPluginOptions } from '../../shared/index.js'
|
||||
import { attrs } from '@mdit/plugin-attrs'
|
||||
import { footnote } from '@mdit/plugin-footnote'
|
||||
import { mark } from '@mdit/plugin-mark'
|
||||
import { sub } from '@mdit/plugin-sub'
|
||||
import { sup } from '@mdit/plugin-sup'
|
||||
import { tasklist } from '@mdit/plugin-tasklist'
|
||||
import { iconsPlugin } from './icons.js'
|
||||
import { plotPlugin } from './plot.js'
|
||||
|
||||
@ -7,6 +13,13 @@ export function inlineSyntaxPlugin(
|
||||
md: Markdown,
|
||||
options: MarkdownPowerPluginOptions,
|
||||
): void {
|
||||
md.use(attrs)
|
||||
md.use(mark)
|
||||
md.use(sub)
|
||||
md.use(sup)
|
||||
md.use(footnote)
|
||||
md.use(tasklist)
|
||||
|
||||
if (options.icons) {
|
||||
// :[collect:name]:
|
||||
md.use(iconsPlugin)
|
||||
|
||||
@ -14,6 +14,12 @@ export async function prepareConfigFile(app: App, options: MarkdownPowerPluginOp
|
||||
const imports = new Set<string>()
|
||||
const enhances = new Set<string>()
|
||||
|
||||
imports.add(`import Tabs from '${CLIENT_FOLDER}components/Tabs.vue'`)
|
||||
enhances.add(`app.component('Tabs', Tabs)`)
|
||||
|
||||
imports.add(`import CodeTabs from '${CLIENT_FOLDER}components/CodeTabs.vue'`)
|
||||
enhances.add(`app.component('CodeTabs', CodeTabs)`)
|
||||
|
||||
if (options.pdf) {
|
||||
imports.add(`import PDFViewer from '${CLIENT_FOLDER}components/PDFViewer.vue'`)
|
||||
enhances.add(`app.component('PDFViewer', PDFViewer)`)
|
||||
|
||||
4
plugins/plugin-md-power/src/node/utils/stringifyProp.ts
Normal file
4
plugins/plugin-md-power/src/node/utils/stringifyProp.ts
Normal file
@ -0,0 +1,4 @@
|
||||
// Single quote will break @vue/compiler-sfc
|
||||
export function stringifyProp(data: unknown): string {
|
||||
return JSON.stringify(data).replace(/'/g, ''')
|
||||
}
|
||||
@ -40,7 +40,7 @@
|
||||
"vuepress": "2.0.0-rc.15"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vuepress/helper": "2.0.0-rc.46",
|
||||
"@vuepress/helper": "2.0.0-rc.47",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"@vueuse/integrations": "^11.1.0",
|
||||
"chokidar": "3.6.0",
|
||||
@ -48,7 +48,7 @@
|
||||
"mark.js": "^8.11.1",
|
||||
"minisearch": "^7.1.0",
|
||||
"p-map": "^7.0.2",
|
||||
"vue": "^3.5.7"
|
||||
"vue": "^3.5.8"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
|
||||
@ -39,7 +39,7 @@
|
||||
"@shikijs/transformers": "^1.18.0",
|
||||
"@shikijs/twoslash": "^1.18.0",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@vuepress/helper": "2.0.0-rc.46",
|
||||
"@vuepress/helper": "2.0.0-rc.47",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"floating-vue": "^5.2.2",
|
||||
"mdast-util-from-markdown": "^2.0.1",
|
||||
|
||||
3866
pnpm-lock.yaml
generated
3866
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -63,6 +63,11 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@iconify/json": "^2",
|
||||
"katex": "^0.16.10",
|
||||
"mathjax-full": "^3.2.2",
|
||||
"sass": "^1.79.3",
|
||||
"sass-embedded": "^1.79.3",
|
||||
"sass-loader": "^16.0.2",
|
||||
"swiper": "^11.0.0",
|
||||
"vuepress": "2.0.0-rc.15"
|
||||
},
|
||||
@ -70,6 +75,21 @@
|
||||
"@iconify/json": {
|
||||
"optional": true
|
||||
},
|
||||
"katex": {
|
||||
"optional": true
|
||||
},
|
||||
"mathjax-full": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-loader": {
|
||||
"optional": true
|
||||
},
|
||||
"swiper": {
|
||||
"optional": true
|
||||
}
|
||||
@ -82,37 +102,40 @@
|
||||
"@vuepress-plume/plugin-fonts": "workspace:*",
|
||||
"@vuepress-plume/plugin-search": "workspace:*",
|
||||
"@vuepress-plume/plugin-shikiji": "workspace:*",
|
||||
"@vuepress/helper": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-active-header-links": "2.0.0-rc.46",
|
||||
"@vuepress/helper": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-active-header-links": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-cache": "2.0.0-rc.42",
|
||||
"@vuepress/plugin-comment": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-docsearch": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-comment": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-docsearch": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-git": "2.0.0-rc.44",
|
||||
"@vuepress/plugin-markdown-container": "2.0.0-rc.43",
|
||||
"@vuepress/plugin-nprogress": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-photo-swipe": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-reading-time": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-seo": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-sitemap": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-watermark": "2.0.0-rc.46",
|
||||
"@vuepress/plugin-markdown-hint": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-markdown-image": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-markdown-math": "2.0.0-rc.49",
|
||||
"@vuepress/plugin-nprogress": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-photo-swipe": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-reading-time": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-seo": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-sitemap": "2.0.0-rc.47",
|
||||
"@vuepress/plugin-watermark": "2.0.0-rc.47",
|
||||
"@vueuse/core": "^11.1.0",
|
||||
"bcrypt-ts": "^5.0.2",
|
||||
"chokidar": "3.6.0",
|
||||
"create-filter": "^1.1.0",
|
||||
"date-fns": "^4.1.0",
|
||||
"esbuild": "^0.23.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"esbuild": "^0.24.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"gray-matter": "^4.0.3",
|
||||
"json2yaml": "^1.1.0",
|
||||
"katex": "^0.16.11",
|
||||
"local-pkg": "^0.5.0",
|
||||
"nanoid": "^5.0.7",
|
||||
"vue": "^3.5.7",
|
||||
"vuepress-plugin-md-enhance": "2.0.0-rc.52",
|
||||
"vue": "^3.5.8",
|
||||
"vuepress-plugin-md-enhance": "2.0.0-rc.54",
|
||||
"vuepress-plugin-md-power": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/json": "^2.2.251",
|
||||
"@iconify/json": "^2.2.252",
|
||||
"swiper": "^11.1.14",
|
||||
"vue-router": "^4.4.5"
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ const showFooter = computed(() => {
|
||||
|
||||
<style scoped>
|
||||
.vp-doc-footer {
|
||||
margin-top: 96px;
|
||||
margin-top: 64px;
|
||||
}
|
||||
|
||||
@media (min-width: 640px) {
|
||||
|
||||
@ -184,7 +184,7 @@
|
||||
position: absolute;
|
||||
inset-inline-start: 14px;
|
||||
top: 34px;
|
||||
bottom: 6px;
|
||||
bottom: 5px;
|
||||
width: 1px;
|
||||
content: "";
|
||||
background-color: var(--vp-c-divider);
|
||||
@ -202,7 +202,11 @@
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.vp-doc .vp-steps > ol > li > :first-child:where(p) {
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.vp-doc .vp-steps > ol > li + li,
|
||||
.vp-doc .vp-steps > ul > li + li {
|
||||
margin-top: 0;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
310
theme/src/client/styles/hint-container.css
Normal file
310
theme/src/client/styles/hint-container.css
Normal file
@ -0,0 +1,310 @@
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
.vp-doc .hint-container {
|
||||
padding: 16px 16px 8px;
|
||||
margin: 16px auto;
|
||||
font-size: var(--vp-custom-block-font-size);
|
||||
line-height: var(--vp-custom-block-line-height);
|
||||
color: var(--vp-c-text-2);
|
||||
border: 1px solid transparent;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info {
|
||||
color: var(--vp-custom-block-info-text);
|
||||
background-color: var(--vp-custom-block-info-bg);
|
||||
border-color: var(--vp-custom-block-info-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info a,
|
||||
.vp-doc .hint-container.info code {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info a:hover,
|
||||
.vp-doc .hint-container.info a:hover > code {
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info code {
|
||||
background-color: var(--vp-custom-block-info-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note {
|
||||
color: var(--vp-custom-block-note-text);
|
||||
background-color: var(--vp-custom-block-note-bg);
|
||||
border-color: var(--vp-custom-block-note-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note a,
|
||||
.vp-doc .hint-container.note code {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note a:hover,
|
||||
.vp-doc .hint-container.note a:hover > code {
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note code {
|
||||
background-color: var(--vp-custom-block-note-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip {
|
||||
color: var(--vp-custom-block-tip-text);
|
||||
background-color: var(--vp-custom-block-tip-bg);
|
||||
border-color: var(--vp-custom-block-tip-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip a,
|
||||
.vp-doc .hint-container.tip code {
|
||||
color: var(--vp-c-tip-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip a:hover,
|
||||
.vp-doc .hint-container.tip a:hover > code {
|
||||
color: var(--vp-c-tip-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip code {
|
||||
background-color: var(--vp-custom-block-tip-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important {
|
||||
color: var(--vp-custom-block-important-text);
|
||||
background-color: var(--vp-custom-block-important-bg);
|
||||
border-color: var(--vp-custom-block-important-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important a,
|
||||
.vp-doc .hint-container.important code {
|
||||
color: var(--vp-c-important-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important a:hover,
|
||||
.vp-doc .hint-container.important a:hover > code {
|
||||
color: var(--vp-c-important-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important code {
|
||||
background-color: var(--vp-custom-block-important-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning {
|
||||
color: var(--vp-custom-block-warning-text);
|
||||
background-color: var(--vp-custom-block-warning-bg);
|
||||
border-color: var(--vp-custom-block-warning-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning a,
|
||||
.vp-doc .hint-container.warning code {
|
||||
color: var(--vp-c-warning-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning a:hover,
|
||||
.vp-doc .hint-container.warning a:hover > code {
|
||||
color: var(--vp-c-warning-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning code {
|
||||
background-color: var(--vp-custom-block-warning-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.danger {
|
||||
color: var(--vp-custom-block-danger-text);
|
||||
background-color: var(--vp-custom-block-danger-bg);
|
||||
border-color: var(--vp-custom-block-danger-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.danger a,
|
||||
.vp-doc .hint-container.danger code {
|
||||
color: var(--vp-c-danger-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.danger a:hover,
|
||||
.vp-doc .hint-container.danger a:hover > code {
|
||||
color: var(--vp-c-danger-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.danger code {
|
||||
background-color: var(--vp-custom-block-danger-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution {
|
||||
color: var(--vp-custom-block-caution-text);
|
||||
background-color: var(--vp-custom-block-caution-bg);
|
||||
border-color: var(--vp-custom-block-caution-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution a,
|
||||
.vp-doc .hint-container.caution code {
|
||||
color: var(--vp-c-caution-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution a:hover,
|
||||
.vp-doc .hint-container.caution a:hover > code {
|
||||
color: var(--vp-c-caution-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution code {
|
||||
background-color: var(--vp-custom-block-caution-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details {
|
||||
color: var(--vp-custom-block-details-text);
|
||||
background-color: var(--vp-custom-block-details-bg);
|
||||
border-color: var(--vp-custom-block-details-border);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details a {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details a:hover,
|
||||
.vp-doc .hint-container.details a:hover > code {
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details code {
|
||||
background-color: var(--vp-custom-block-details-code-bg);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container-title {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container p + p {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details summary {
|
||||
margin: 0 0 8px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details summary + p {
|
||||
margin: 16px 0 8px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container a:hover {
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container code {
|
||||
font-size: var(--vp-custom-block-code-font-size);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.vp-doc .hint-container th,
|
||||
.vp-doc .hint-container.vp-doc .hint-container blockquote > p {
|
||||
font-size: var(--vp-custom-block-font-size);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
/* ---------------------------------------- */
|
||||
|
||||
.vp-doc .hint-container p {
|
||||
line-height: var(--vp-custom-block-line-height);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container p + p {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container > :not(summary):first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container > :not(summary):last-child {
|
||||
margin-bottom: 8px !important;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container th,
|
||||
.vp-doc .hint-container blockquote > p {
|
||||
font-size: var(--vp-custom-block-font-size);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"] {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-code-tab div[class*="language-"] {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"] code {
|
||||
font-size: var(--vp-custom-block-code-font-size);
|
||||
font-weight: 400;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"].line-numbers-mode .line-numbers {
|
||||
font-size: var(--vp-custom-block-code-font-size);
|
||||
}
|
||||
|
||||
@media (max-width: 419px) {
|
||||
.vp-doc .hint-container {
|
||||
margin: 16px -16px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"] {
|
||||
margin: 0.75rem -0.75rem;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-code-tabs-nav {
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-code-tab div[class*="language-"] {
|
||||
margin: 0 -0.75rem;
|
||||
border-radius: 0 0 6px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container-title::before {
|
||||
display: inline-block;
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
margin-right: 4px;
|
||||
vertical-align: middle;
|
||||
content: "";
|
||||
background-image: var(--icon);
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100%;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
@media print {
|
||||
.vp-doc .hint-container-title::before {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note .hint-container-title::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath fill='%235da1a2' d='M9 22c-.6 0-1-.4-1-1v-3H4c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2h-6.1l-3.7 3.7c-.2.2-.4.3-.7.3zm1-6v3.1l3.1-3.1H20V4H4v12zm6.3-10l-1.4 3H17v4h-4V8.8L14.3 6zm-6 0L8.9 9H11v4H7V8.8L8.3 6z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info .hint-container-title::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 48 48'%3E%3Ccircle cx='24' cy='24' r='21' fill='%232196f3'/%3E%3Cpath fill='%23fff' d='M22 22h4v11h-4z'/%3E%3Ccircle cx='24' cy='16.5' r='2.5' fill='%23fff'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip .hint-container-title::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 512 512'%3E%3Cpath fill='%2330a46c' d='M208 464h96v32h-96zm-16-48h128v32H192zM369.42 62.69C339.35 32.58 299.07 16 256 16A159.62 159.62 0 0 0 96 176c0 46.62 17.87 90.23 49 119.64l4.36 4.09C167.37 316.57 192 339.64 192 360v40h48V269.11L195.72 244L214 217.72L256 240l41.29-22.39l19.1 25.68l-44.39 26V400h48v-40c0-19.88 24.36-42.93 42.15-59.77l4.91-4.66C399.08 265 416 223.61 416 176a159.16 159.16 0 0 0-46.58-113.31'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning .hint-container-title::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 16 16'%3E%3Cpath fill='%23da8b17' fill-rule='evenodd' d='M6.285 1.975C7.06.68 8.939.68 9.715 1.975l5.993 9.997c.799 1.333-.161 3.028-1.716 3.028H2.008C.453 15-.507 13.305.292 11.972zM8 5a.75.75 0 0 1 .75.75v3a.75.75 0 0 1-1.5 0v-3A.75.75 0 0 1 8 5m1 6.5a1 1 0 1 1-2 0a1 1 0 0 1 2 0' clip-rule='evenodd'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.danger .hint-container-title::before,
|
||||
.vp-doc .hint-container.caution .hint-container-title::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath fill='%23b62a3c' d='M8.27 3L3 8.27v7.46L8.27 21h7.46L21 15.73V8.27L15.73 3M8.41 7L12 10.59L15.59 7L17 8.41L13.41 12L17 15.59L15.59 17L12 13.41L8.41 17L7 15.59L10.59 12L7 8.41'/%3E%3C/svg%3E");
|
||||
|
||||
width: 1.4em;
|
||||
height: 1.4em;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important .hint-container-title::before {
|
||||
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1em' height='1em' viewBox='0 0 24 24'%3E%3Cpath fill='%238e5cd9' d='M5 19q-.425 0-.712-.288T4 18t.288-.712T5 17h1v-7q0-2.075 1.25-3.687T10.5 4.2v-.7q0-.625.438-1.062T12 2t1.063.438T13.5 3.5v.7q2 .5 3.25 2.113T18 10v7h1q.425 0 .713.288T20 18t-.288.713T19 19zm7 3q-.825 0-1.412-.587T10 20h4q0 .825-.587 1.413T12 22m0-9q.425 0 .713-.288T13 12V9q0-.425-.288-.712T12 8t-.712.288T11 9v3q0 .425.288.713T12 13m0 3q.425 0 .713-.288T13 15t-.288-.712T12 14t-.712.288T11 15t.288.713T12 16'/%3E%3C/svg%3E");
|
||||
}
|
||||
@ -9,7 +9,7 @@
|
||||
@import url("./content.css");
|
||||
@import url("./code.css");
|
||||
@import url("./custom-block.css");
|
||||
|
||||
@import url("./hint-container.css");
|
||||
@import url("./twoslash.css");
|
||||
@import url("./md-enhance.css");
|
||||
@import url("./search.css");
|
||||
|
||||
@ -1,228 +1,5 @@
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
|
||||
/* ------------------ Markdown Enhance: Hint Container ------------------ */
|
||||
.vp-doc .hint-container {
|
||||
padding: 16px;
|
||||
font-size: var(--vp-custom-block-font-size);
|
||||
line-height: 24px;
|
||||
color: var(--vp-c-text-2);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .hint-container-title {
|
||||
margin-top: 0;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container p + p {
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container > :not(summary):first-child {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container > :last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container th,
|
||||
.vp-doc .hint-container blockquote > p {
|
||||
font-size: var(--vp-custom-block-font-size);
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"] {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-code-tab div[class*="language-"] {
|
||||
margin: 0 0 8px;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"] code {
|
||||
font-size: var(--vp-custom-block-code-font-size);
|
||||
font-weight: 400;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container div[class*="language-"].line-numbers-mode .line-numbers {
|
||||
font-size: var(--vp-custom-block-code-font-size);
|
||||
}
|
||||
|
||||
@media (max-width: 419px) {
|
||||
.vp-doc .hint-container div[class*="language-"] {
|
||||
margin: 0.85rem -0.75rem;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-code-tabs-nav {
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-code-tab div[class*="language-"] {
|
||||
margin: 0 -0.75rem 0 -1rem;
|
||||
border-radius: 0 0 6px 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note {
|
||||
color: var(--vp-c-text-3);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.info {
|
||||
color: var(--vp-custom-block-info-text);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.tip {
|
||||
color: var(--vp-custom-block-tip-text);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning {
|
||||
color: var(--vp-custom-block-warning-text);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution {
|
||||
color: var(--vp-custom-block-danger-text);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details {
|
||||
color: var(--vp-custom-block-details-text);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.details summary {
|
||||
font-weight: 700;
|
||||
color: var(--vp-c-text-1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
.vp-doc .hint-container.details summary {
|
||||
margin: -16px;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note a,
|
||||
.vp-doc .hint-container.note code,
|
||||
.vp-doc .hint-container.info a,
|
||||
.vp-doc .hint-container.info code,
|
||||
.vp-doc .hint-container.tip a,
|
||||
.vp-doc .hint-container.tip code,
|
||||
.vp-doc .hint-container.details a,
|
||||
.vp-doc .hint-container.details code {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.note a:hover,
|
||||
.vp-doc .hint-container.info a:hover,
|
||||
.vp-doc .hint-container.tip a:hover,
|
||||
.vp-doc .hint-container.details a:hover {
|
||||
color: var(--vp-c-brand-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important a,
|
||||
.vp-doc .hint-container.important code {
|
||||
color: var(--vp-c-purple-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.important a:hover {
|
||||
color: var(--vp-c-purple-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning a,
|
||||
.vp-doc .hint-container.warning code {
|
||||
color: var(--vp-c-warning-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.warning a:hover {
|
||||
color: var(--vp-c-warning-2);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution a,
|
||||
.vp-doc .hint-container.caution code {
|
||||
color: var(--vp-c-danger-1);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container.caution a:hover {
|
||||
color: var(--vp-c-danger-2);
|
||||
}
|
||||
|
||||
/* ------------------ Markdown Enhance: Code Tabs ----------------------- */
|
||||
.vp-doc .code-tabs-nav {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tabs-nav {
|
||||
padding: 0 12px;
|
||||
margin: 16px 0 0;
|
||||
overflow-y: hidden;
|
||||
background-color: var(--vp-code-tab-bg);
|
||||
box-shadow: inset 0 -1px var(--vp-code-tab-divider);
|
||||
transition: background-color var(--vp-t-color), box-shadow var(--vp-t-color);
|
||||
}
|
||||
|
||||
@media (max-width: 639px) {
|
||||
.vp-doc .vp-code-tabs-nav {
|
||||
margin: 16px -24px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab-nav {
|
||||
position: relative;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 48px;
|
||||
color: var(--vp-code-tab-text-color);
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab-nav::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab-nav::after {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: -1px;
|
||||
left: 8px;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 2px;
|
||||
content: "";
|
||||
background: transparent;
|
||||
border-radius: 2px;
|
||||
transition: background var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab-nav.active {
|
||||
color: var(--vp-code-tab-active-text-color);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab-nav.active::after {
|
||||
background: var(--vp-code-tab-active-bar-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab-nav:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.vp-doc .vp-code-tab div[class*="language-"] {
|
||||
margin-top: 0;
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 419px) {
|
||||
.vp-doc .hint-container .vp-code-tabs-nav {
|
||||
margin: 0.85rem -0.75rem 0 -1rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------- Markdown Enhance: Code Demo -------------------- */
|
||||
.vp-doc .vp-code-demo {
|
||||
overflow: hidden;
|
||||
@ -374,6 +151,7 @@
|
||||
/* ---------------------- Markdown Enhance: Task List ---------------------- */
|
||||
.vp-doc .task-list-container {
|
||||
padding-left: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.vp-doc .task-list-container .task-list-item input {
|
||||
@ -387,142 +165,53 @@
|
||||
margin-left: 1.2em;
|
||||
}
|
||||
|
||||
.vp-doc .task-list-container .task-list-item input::before,
|
||||
.vp-doc .task-list-container .task-list-item input::after {
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: 0;
|
||||
.vp-doc .task-list-container .task-list-item input::before {
|
||||
display: inline-block;
|
||||
font-size: 1em;
|
||||
content: none;
|
||||
}
|
||||
|
||||
.vp-doc .task-list-container .task-list-item input::after {
|
||||
content: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="1em" height="1em" viewBox="0 0 32 32"%3E%3Cpath fill="%23c2c2c4" d="M26 27.5H6A1.5 1.5 0 0 1 4.5 26V6c0-.83.67-1.5 1.5-1.5h20c.828 0 1.5.67 1.5 1.5v20a1.5 1.5 0 0 1-1.5 1.5m-18.5-3h17v-17h-17z"%2F%3E%3C%2Fsvg%3E');
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.vp-doc .task-list-container .task-list-item input:checked[disabled]::after {
|
||||
content: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="1em" height="1em" viewBox="0 0 32 32"%3E%3Cpath fill="%23299764" d="M29.548 3.043a2.5 2.5 0 0 0-3.513.4L16 16.067l-3.508-4.414a2.5 2.5 0 0 0-3.915 3.112l5.465 6.875c.474.597 1.195.943 1.957.943s1.482-.35 1.957-.944L29.95 6.555c.86-1.08.68-2.654-.402-3.513zM24.5 24.5h-17v-17h12.756l2.385-3H6c-.83 0-1.5.67-1.5 1.5v20c0 .828.67 1.5 1.5 1.5h20a1.5 1.5 0 0 0 1.5-1.5V12.85l-3 3.774z"%2F%3E%3C%2Fsvg%3E');
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* ---------------------------- Markdown Enhance: Tabs ----------------------------- */
|
||||
.vp-doc .vp-tabs {
|
||||
margin: 1.5rem -0.75rem;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
transition: border var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tabs-nav {
|
||||
padding: 0 12px;
|
||||
background-color: var(--vp-code-tab-bg);
|
||||
box-shadow: inset 0 -1px var(--vp-code-tab-divider);
|
||||
transition: background-color var(--vp-t-color), box-shadow var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav {
|
||||
position: relative;
|
||||
padding: 0 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
line-height: 48px;
|
||||
color: var(--vp-code-tab-text-color);
|
||||
white-space: nowrap;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: color var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav::before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav::after {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
bottom: -1px;
|
||||
left: 8px;
|
||||
z-index: 1;
|
||||
display: block;
|
||||
width: auto;
|
||||
height: 2px;
|
||||
width: 1.25em;
|
||||
height: 1.25em;
|
||||
content: "";
|
||||
background: transparent;
|
||||
border-radius: 2px;
|
||||
transition: background var(--vp-t-color);
|
||||
background-image: var(--icon);
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: 100% 100%;
|
||||
transform: translateY(2px);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav.active {
|
||||
color: var(--vp-code-tab-active-text-color);
|
||||
background: transparent;
|
||||
|
||||
.vp-doc .task-list-container .task-list-item input::before {
|
||||
--icon: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="1em" height="1em" viewBox="0 0 32 32"%3E%3Cpath fill="%23c2c2c4" d="M26 27.5H6A1.5 1.5 0 0 1 4.5 26V6c0-.83.67-1.5 1.5-1.5h20c.828 0 1.5.67 1.5 1.5v20a1.5 1.5 0 0 1-1.5 1.5m-18.5-3h17v-17h-17z"%2F%3E%3C%2Fsvg%3E');
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav.active::after {
|
||||
background: var(--vp-code-tab-active-bar-color);
|
||||
}
|
||||
|
||||
.vp-doc .vp-tab-nav:hover {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
@media (min-width: 419px) {
|
||||
.vp-doc .vp-tabs {
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-tabs {
|
||||
margin: 1rem -0.45rem 1rem -0.75rem;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-tabs .vp-tabs-nav {
|
||||
background: var(--vp-c-default-soft);
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-tabs .vp-tab {
|
||||
padding: 0.45rem 0.75rem;
|
||||
font-size: 14px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.vp-doc .hint-container .vp-tabs .vp-tab p {
|
||||
margin: 8px 0;
|
||||
.vp-doc .task-list-container .task-list-item input:checked[disabled]::before {
|
||||
--icon: url('data:image/svg+xml,%3Csvg xmlns="http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg" width="1em" height="1em" viewBox="0 0 32 32"%3E%3Cpath fill="%23299764" d="M29.548 3.043a2.5 2.5 0 0 0-3.513.4L16 16.067l-3.508-4.414a2.5 2.5 0 0 0-3.915 3.112l5.465 6.875c.474.597 1.195.943 1.957.943s1.482-.35 1.957-.944L29.95 6.555c.86-1.08.68-2.654-.402-3.513zM24.5 24.5h-17v-17h12.756l2.385-3H6c-.83 0-1.5.67-1.5 1.5v20c0 .828.67 1.5 1.5 1.5h20a1.5 1.5 0 0 0 1.5-1.5V12.85l-3 3.774z"%2F%3E%3C%2Fsvg%3E');
|
||||
}
|
||||
|
||||
/* --------------------- Markdown Enhance: Footnote -------------------------------- */
|
||||
.vp-doc .footnotes-sep {
|
||||
margin-top: 48px;
|
||||
border-top: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vp-doc .footnotes {
|
||||
position: relative;
|
||||
padding: 48px 0 12px 16px;
|
||||
padding: 12px 0 12px 16px;
|
||||
margin-top: 32px;
|
||||
font-size: 14px;
|
||||
border: 1px solid var(--vp-c-divider);
|
||||
|
||||
background-color: var(--vp-c-bg-safe);
|
||||
border-radius: 6px;
|
||||
box-shadow: var(--vp-shadow-1);
|
||||
opacity: 0.75;
|
||||
transition: border var(--vp-t-color), box-shadow var(--vp-t-color);
|
||||
opacity: 0.85;
|
||||
transition: background var(--vp-t-color);
|
||||
}
|
||||
|
||||
.vp-doc .footnotes::before {
|
||||
position: absolute;
|
||||
top: 12px;
|
||||
left: 16px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
@media (max-width: 419px) {
|
||||
.vp-doc .footnotes {
|
||||
margin: 16px -24px;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
[lang="zh-CN"] .vp-doc .footnotes::before {
|
||||
content: "脚注:";
|
||||
}
|
||||
|
||||
[lang="en-US"] .vp-doc .footnotes::before {
|
||||
content: "Footnotes:";
|
||||
.vp-doc .footnotes p {
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.vp-doc .footnotes ol {
|
||||
|
||||
@ -224,6 +224,21 @@
|
||||
--vp-c-tip-3: var(--vp-c-brand-3);
|
||||
--vp-c-tip-soft: var(--vp-c-brand-soft);
|
||||
|
||||
--vp-c-note-1: var(--vp-c-brand-1);
|
||||
--vp-c-note-2: var(--vp-c-brand-2);
|
||||
--vp-c-note-3: var(--vp-c-brand-3);
|
||||
--vp-c-note-soft: var(--vp-c-brand-soft);
|
||||
|
||||
--vp-c-success-1: var(--vp-c-green-1);
|
||||
--vp-c-success-2: var(--vp-c-green-2);
|
||||
--vp-c-success-3: var(--vp-c-green-3);
|
||||
--vp-c-success-soft: var(--vp-c-green-soft);
|
||||
|
||||
--vp-c-important-1: var(--vp-c-purple-1);
|
||||
--vp-c-important-2: var(--vp-c-purple-2);
|
||||
--vp-c-important-3: var(--vp-c-purple-3);
|
||||
--vp-c-important-soft: var(--vp-c-purple-soft);
|
||||
|
||||
--vp-c-warning-1: var(--vp-c-yellow-1);
|
||||
--vp-c-warning-2: var(--vp-c-yellow-2);
|
||||
--vp-c-warning-3: var(--vp-c-yellow-3);
|
||||
@ -233,6 +248,11 @@
|
||||
--vp-c-danger-2: var(--vp-c-red-2);
|
||||
--vp-c-danger-3: var(--vp-c-red-3);
|
||||
--vp-c-danger-soft: var(--vp-c-red-soft);
|
||||
|
||||
--vp-c-caution-1: var(--vp-c-red-1);
|
||||
--vp-c-caution-2: var(--vp-c-red-2);
|
||||
--vp-c-caution-3: var(--vp-c-red-3);
|
||||
--vp-c-caution-soft: var(--vp-c-red-soft);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -418,6 +438,7 @@
|
||||
* -------------------------------------------------------------------------- */
|
||||
:root {
|
||||
--vp-custom-block-font-size: 14px;
|
||||
--vp-custom-block-line-height: 24px;
|
||||
--vp-custom-block-code-font-size: 13px;
|
||||
|
||||
--vp-custom-block-info-border: transparent;
|
||||
@ -425,10 +446,20 @@
|
||||
--vp-custom-block-info-bg: var(--vp-c-default-soft);
|
||||
--vp-custom-block-info-code-bg: var(--vp-c-default-soft);
|
||||
|
||||
--vp-custom-block-note-border: transparent;
|
||||
--vp-custom-block-note-text: var(--vp-c-text-1);
|
||||
--vp-custom-block-note-bg: var(--vp-c-default-soft);
|
||||
--vp-custom-block-note-code-bg: var(--vp-c-default-soft);
|
||||
|
||||
--vp-custom-block-tip-border: transparent;
|
||||
--vp-custom-block-tip-text: var(--vp-c-text-1);
|
||||
--vp-custom-block-tip-bg: var(--vp-c-brand-soft);
|
||||
--vp-custom-block-tip-code-bg: var(--vp-c-brand-soft);
|
||||
--vp-custom-block-tip-bg: var(--vp-c-tip-soft);
|
||||
--vp-custom-block-tip-code-bg: var(--vp-c-tip-soft);
|
||||
|
||||
--vp-custom-block-important-border: transparent;
|
||||
--vp-custom-block-important-text: var(--vp-c-text-1);
|
||||
--vp-custom-block-important-bg: var(--vp-c-important-soft);
|
||||
--vp-custom-block-important-code-bg: var(--vp-c-important-soft);
|
||||
|
||||
--vp-custom-block-warning-border: transparent;
|
||||
--vp-custom-block-warning-text: var(--vp-c-text-1);
|
||||
@ -440,6 +471,11 @@
|
||||
--vp-custom-block-danger-bg: var(--vp-c-danger-soft);
|
||||
--vp-custom-block-danger-code-bg: var(--vp-c-danger-soft);
|
||||
|
||||
--vp-custom-block-caution-border: transparent;
|
||||
--vp-custom-block-caution-text: var(--vp-c-text-1);
|
||||
--vp-custom-block-caution-bg: var(--vp-c-caution-soft);
|
||||
--vp-custom-block-caution-code-bg: var(--vp-c-caution-soft);
|
||||
|
||||
--vp-custom-block-details-border: var(--vp-custom-block-info-border);
|
||||
--vp-custom-block-details-text: var(--vp-custom-block-info-text);
|
||||
--vp-custom-block-details-bg: var(--vp-custom-block-info-bg);
|
||||
|
||||
@ -2,7 +2,7 @@ import type {
|
||||
AutoFrontmatter,
|
||||
AutoFrontmatterObject,
|
||||
} from '../../shared/index.js'
|
||||
import { format } from 'date-fns'
|
||||
import dayjs from 'dayjs'
|
||||
|
||||
export function createBaseFrontmatter(options: AutoFrontmatter): AutoFrontmatterObject {
|
||||
const res: AutoFrontmatterObject = {}
|
||||
@ -13,7 +13,7 @@ export function createBaseFrontmatter(options: AutoFrontmatter): AutoFrontmatter
|
||||
return formatTime
|
||||
if (data.friends || data.pageLayout === 'friends')
|
||||
return
|
||||
return format(new Date(createTime), 'yyyy/MM/dd HH:mm:ss')
|
||||
return dayjs(new Date(createTime)).format('YYYY/MM/DD HH:mm:ss')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,6 @@ export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
|
||||
.rule('scss')
|
||||
.use('sass-loader')
|
||||
.tap((options: any) => ({
|
||||
api: 'modern-compiler',
|
||||
...options,
|
||||
sassOptions: {
|
||||
silenceDeprecations: ['mixed-decls', 'legacy-js-api'],
|
||||
@ -48,26 +47,9 @@ export function extendsBundlerOptions(bundlerOptions: any, app: App): void {
|
||||
preprocessorOptions: {
|
||||
sass: {
|
||||
silenceDeprecations: ['mixed-decls', 'legacy-js-api'],
|
||||
logger: {
|
||||
warn: (message, { deprecation, deprecationType }) => {
|
||||
if (deprecation && deprecationType.id === 'mixed-decls')
|
||||
return
|
||||
|
||||
console.warn(message)
|
||||
},
|
||||
},
|
||||
},
|
||||
scss: {
|
||||
silenceDeprecations: ['mixed-decls', 'legacy-js-api'],
|
||||
logger: {
|
||||
warn: (message, { deprecation, deprecationType }) => {
|
||||
if (deprecation && deprecationType.id === 'mixed-decls')
|
||||
return
|
||||
if (!message.includes('repetitive deprecation warnings omitted')) {
|
||||
console.warn(message)
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@ -36,7 +36,7 @@ export const customContainerPlugins: Plugin[] = [
|
||||
<div class="demo-container" ${containerStyle ? `style="${containerStyle}"` : ''}>\n`
|
||||
},
|
||||
after() {
|
||||
return '</div></div>\n'
|
||||
return '</div></div>'
|
||||
},
|
||||
}),
|
||||
/**
|
||||
|
||||
@ -5,6 +5,9 @@ import { cachePlugin } from '@vuepress/plugin-cache'
|
||||
import { commentPlugin } from '@vuepress/plugin-comment'
|
||||
import { docsearchPlugin } from '@vuepress/plugin-docsearch'
|
||||
import { gitPlugin } from '@vuepress/plugin-git'
|
||||
import { markdownHintPlugin } from '@vuepress/plugin-markdown-hint'
|
||||
import { markdownImagePlugin } from '@vuepress/plugin-markdown-image'
|
||||
import { markdownMathPlugin } from '@vuepress/plugin-markdown-math'
|
||||
import { nprogressPlugin } from '@vuepress/plugin-nprogress'
|
||||
import { photoSwipePlugin } from '@vuepress/plugin-photo-swipe'
|
||||
import { readingTimePlugin } from '@vuepress/plugin-reading-time'
|
||||
@ -21,6 +24,7 @@ import {
|
||||
resolveDocsearchOptions,
|
||||
resolveSearchOptions,
|
||||
} from '../config/index.js'
|
||||
import { deleteAttrs } from '../utils/index.js'
|
||||
import { customContainerPlugins } from './containerPlugins.js'
|
||||
import { markdownTitlePlugin } from './markdown-title.js'
|
||||
|
||||
@ -49,6 +53,7 @@ export function getPlugins({
|
||||
delay: 200,
|
||||
offset: 5,
|
||||
}),
|
||||
markdownHintPlugin({ hint: true, alert: true, injectStyles: false }),
|
||||
|
||||
...customContainerPlugins,
|
||||
]
|
||||
@ -107,30 +112,14 @@ export function getPlugins({
|
||||
}
|
||||
|
||||
if (pluginOptions.markdownEnhance !== false) {
|
||||
plugins.push(mdEnhancePlugin(
|
||||
Object.assign(
|
||||
{
|
||||
hint: true, // info note tip warning danger details
|
||||
codetabs: true,
|
||||
tabs: true,
|
||||
align: true,
|
||||
mark: true,
|
||||
tasklist: true,
|
||||
attrs: true,
|
||||
sup: true,
|
||||
sub: true,
|
||||
alert: true,
|
||||
footnote: true,
|
||||
katex: true,
|
||||
} as MarkdownEnhancePluginOptions,
|
||||
pluginOptions.markdownEnhance || {},
|
||||
),
|
||||
))
|
||||
const options: MarkdownEnhancePluginOptions = {
|
||||
...pluginOptions.markdownEnhance,
|
||||
}
|
||||
plugins.push(mdEnhancePlugin(deleteAttrs(options, 'hint', 'alert', 'imgSize', 'imgLazyload', 'imgMark', 'figure', 'obsidianImgSize', 'katex', 'mathjax', 'tabs', 'codetabs', 'align', 'mark', 'sub', 'sup', 'attrs', 'tasklist', 'footnote')))
|
||||
}
|
||||
|
||||
if (pluginOptions.markdownPower !== false) {
|
||||
plugins.push(markdownPowerPlugin({
|
||||
caniuse: pluginOptions.caniuse,
|
||||
fileTree: true,
|
||||
plot: true,
|
||||
icons: true,
|
||||
@ -141,6 +130,14 @@ export function getPlugins({
|
||||
}))
|
||||
}
|
||||
|
||||
if (pluginOptions.markdownMath !== false) {
|
||||
plugins.push(markdownMathPlugin(pluginOptions.markdownMath ?? { type: 'katex' }))
|
||||
}
|
||||
|
||||
if (pluginOptions.markdownImage) {
|
||||
plugins.push(markdownImagePlugin(pluginOptions.markdownImage))
|
||||
}
|
||||
|
||||
if (pluginOptions.watermark) {
|
||||
plugins.push(watermarkPlugin({
|
||||
delay: 300,
|
||||
|
||||
12
theme/src/node/utils/deleteAttrs.ts
Normal file
12
theme/src/node/utils/deleteAttrs.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export function deleteAttrs<
|
||||
T extends Record<string, any> = Record<string, any>,
|
||||
>(obj: T, ...attrs: (keyof T)[]): Omit<T, keyof T> {
|
||||
const res = {} as T
|
||||
|
||||
for (const key in obj) {
|
||||
if (!attrs.includes(key)) {
|
||||
res[key] = obj[key]
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -4,6 +4,7 @@ export const THEME_NAME = 'vuepress-theme-plume'
|
||||
|
||||
export const logger = new Logger(THEME_NAME)
|
||||
|
||||
export * from './deleteAttrs.js'
|
||||
export * from './hash.js'
|
||||
export * from './interopDefault.js'
|
||||
export * from './package.js'
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
import type { CommentPluginOptions } from '@vuepress/plugin-comment'
|
||||
import type { DocSearchOptions } from '@vuepress/plugin-docsearch'
|
||||
import type { MarkdownImagePluginOptions } from '@vuepress/plugin-markdown-image'
|
||||
import type { MarkdownMathPluginOptions } from '@vuepress/plugin-markdown-math'
|
||||
import type { ReadingTimePluginOptions } from '@vuepress/plugin-reading-time'
|
||||
import type { WatermarkPluginOptions } from '@vuepress/plugin-watermark'
|
||||
import type { SearchPluginOptions } from '@vuepress-plume/plugin-search'
|
||||
@ -8,13 +10,6 @@ import type { MarkdownEnhancePluginOptions } from 'vuepress-plugin-md-enhance'
|
||||
import type { MarkdownPowerPluginOptions } from 'vuepress-plugin-md-power'
|
||||
|
||||
export interface PlumeThemePluginOptions {
|
||||
/**
|
||||
* @deprecated 迁移至 `plugin-md-power` 插件
|
||||
*
|
||||
* 是否启用 can-i-use 插件
|
||||
*/
|
||||
caniuse?: false
|
||||
|
||||
/**
|
||||
* plugin-search 配置
|
||||
*/
|
||||
@ -25,12 +20,6 @@ export interface PlumeThemePluginOptions {
|
||||
*/
|
||||
docsearch?: false | DocSearchOptions
|
||||
|
||||
/**
|
||||
* @deprecated move to `shiki`
|
||||
* 代码高亮 配置
|
||||
*/
|
||||
shikiji?: never
|
||||
|
||||
/**
|
||||
* 代码高亮 配置
|
||||
*/
|
||||
@ -45,22 +34,45 @@ export interface PlumeThemePluginOptions {
|
||||
|
||||
photoSwipe?: false
|
||||
|
||||
markdownEnhance?: false | MarkdownEnhancePluginOptions
|
||||
/**
|
||||
* 是否启用 `vuepress-plugin-md-enhance` 插件
|
||||
*
|
||||
* - `hint`, `alert` 已迁移至 `@vuepress/plugin-markdown-hint`, 且主题内置并默认启用。
|
||||
* - `imgSize`, `imgMark`, `imgLazyload`, `figure`, `obsidianImgSize` 已迁移至 `@vuepress/plugin-markdown-image`, 请使用 `plugins.markdownImage` 配置项代替。
|
||||
* - `katex`, `mathjax` 已迁移至 `@vuepress/plugin-markdown-math`, 请使用 `plugins.markdownMath` 配置项代替
|
||||
*/
|
||||
markdownEnhance?:
|
||||
| false
|
||||
| Omit<
|
||||
MarkdownEnhancePluginOptions,
|
||||
'hint' | 'alert' | 'imgSize' | 'imgMark' | 'imgLazyload' | 'figure' | 'obsidianImgSize'
|
||||
| 'katex' | 'mathjax'
|
||||
>
|
||||
|
||||
markdownPower?: false | MarkdownPowerPluginOptions
|
||||
|
||||
/**
|
||||
* 是否启用 `@vuepress/plugin-markdown-image` 插件
|
||||
*
|
||||
* @default false
|
||||
* @see https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-image.html
|
||||
*/
|
||||
markdownImage?: false | MarkdownImagePluginOptions
|
||||
|
||||
/**
|
||||
* 是否启用 `@vuepress/plugin-markdown-math` 插件
|
||||
*
|
||||
* @default { type: 'katex' }
|
||||
* @see https://ecosystem.vuejs.press/zh/plugins/markdown/markdown-math.html
|
||||
*/
|
||||
markdownMath?: false | MarkdownMathPluginOptions
|
||||
|
||||
comment?: false | CommentPluginOptions
|
||||
|
||||
sitemap?: false
|
||||
|
||||
seo?: false
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* 请使用 [@vuepress/plugin-baidu-analytics](https://ecosystem.vuejs.press/zh/plugins/analytics/baidu-analytics.html) 代替
|
||||
*/
|
||||
baiduTongji?: false | { key: string }
|
||||
|
||||
/**
|
||||
* 阅读时间、字数统计
|
||||
*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user