add toc
This commit is contained in:
parent
0e84fd0760
commit
13ef2e3b36
@ -23,7 +23,9 @@
|
|||||||
"@pinia/nuxt": "^0.7.0",
|
"@pinia/nuxt": "^0.7.0",
|
||||||
"github-markdown-css": "^5.8.1",
|
"github-markdown-css": "^5.8.1",
|
||||||
"markdown-it": "^14.1.0",
|
"markdown-it": "^14.1.0",
|
||||||
|
"markdown-it-anchor": "^9.2.0",
|
||||||
"markdown-it-mathjax3": "^4.3.2",
|
"markdown-it-mathjax3": "^4.3.2",
|
||||||
|
"markdown-it-toc-done-right": "^4.2.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"nuxt": "^3.14.159",
|
"nuxt": "^3.14.159",
|
||||||
"vue": "latest",
|
"vue": "latest",
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
const route = useRoute(),
|
const route = useRoute(),
|
||||||
cid = route.params.cid as string,
|
cid = route.params.cid as string,
|
||||||
content = ref<IBlogResponse<IPostFull>>(),
|
content = ref<IBlogResponse<IPostFull>>(),
|
||||||
|
toc = ref<HTMLDivElement | null>(null),
|
||||||
|
|
||||||
getPost = get<IBlogResponse<IPostFull>, unknown>('/blog/index.php/api/post', {
|
getPost = get<IBlogResponse<IPostFull>, unknown>('/blog/index.php/api/post', {
|
||||||
params: {
|
params: {
|
||||||
@ -11,19 +12,47 @@ const route = useRoute(),
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
title = computed(() => content.value?.data.title || 'Can not see me... can not see me...'),
|
title = computed(() => content.value?.data.title || 'Can not see me... can not see me...'),
|
||||||
text = computed(() => content.value?.data.text || '## Ops!'),
|
text = computed(() => content.value ? content.value.data.text + '[[toc]]' : '## Ops!'),
|
||||||
date = computed(() => new Date((content.value?.data.date.timeStamp || 0) * 1000)
|
date = computed(() => new Date((content.value?.data.date.timeStamp || 0) * 1000)
|
||||||
.toISOString()
|
.toISOString()
|
||||||
.split('T')[0],
|
.split('T')[0],
|
||||||
),
|
),
|
||||||
category = computed(() => content.value?.data.category || 'default'),
|
category = computed(() => content.value?.data.category || 'default'),
|
||||||
url = computed(() => content.value?.data.url || '/error/404')
|
url = computed(() => content.value?.data.url || '/error/404'),
|
||||||
|
bindAnchorClickEvent = () => {
|
||||||
|
const autoGenTOC = document.querySelector('#toc')
|
||||||
|
if (!autoGenTOC || !toc.value) return
|
||||||
|
|
||||||
|
toc.value.innerHTML = autoGenTOC.innerHTML
|
||||||
|
autoGenTOC.remove()
|
||||||
|
|
||||||
|
toc.value.querySelectorAll('a').forEach((elem: HTMLElement) => {
|
||||||
|
elem.onclick = (event: MouseEvent) => {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
let id = elem.getAttribute('href') || ''
|
||||||
|
if (id.startsWith('#'))
|
||||||
|
id = id.replace('#', '')
|
||||||
|
|
||||||
|
const element = document.getElementById(id)
|
||||||
|
if (element) {
|
||||||
|
const offsetTop = element.offsetTop - 70
|
||||||
|
window.scrollTo({ top: offsetTop, behavior: 'smooth' })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
content.value = await getPost()
|
content.value = await getPost()
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
bindAnchorClickEvent()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section class="container m-4 mx-auto rounded-xl bg-white p-8 shadow-md lg:max-w-screen-lg">
|
<div class="flex container m-4 mx-auto xl:max-w-screen-xl gap-4">
|
||||||
|
<section class="container mx-auto rounded-xl bg-white p-8 shadow-md flex-shrink-0 lg:max-w-screen-lg">
|
||||||
<div class="mb-4 border-b-2 border-dashed border-gray-200 pb-4">
|
<div class="mb-4 border-b-2 border-dashed border-gray-200 pb-4">
|
||||||
<h1 class="text-center text-3xl font-bold">
|
<h1 class="text-center text-3xl font-bold">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
@ -47,8 +76,17 @@ content.value = await getPost()
|
|||||||
</div>
|
</div>
|
||||||
<markdown-section :content="text" />
|
<markdown-section :content="text" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<aside class="flex-1 overflow-hidden">
|
||||||
|
<div class="rounded-xl p-8 bg-white shadow-md">
|
||||||
|
<div ref="toc" />
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="scss">
|
||||||
|
.toc-style {
|
||||||
|
@apply truncate
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
definePageMeta({
|
definePageMeta({
|
||||||
maintenance: true,
|
maintenance: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const s = '# markdown-it rulezz!\n\n[[toc]]\n## with markdown-it-toc-done-right rulezz even more!'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NuxtWelcome />
|
<markdown-section :content="s" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import md, { type Options } from 'markdown-it'
|
import md, { type Options } from 'markdown-it'
|
||||||
import mm from 'markdown-it-mathjax3'
|
import mm from 'markdown-it-mathjax3'
|
||||||
|
import anchor from 'markdown-it-anchor'
|
||||||
|
import toc from 'markdown-it-toc-done-right'
|
||||||
|
|
||||||
const options: Options = {
|
const options: Options = {
|
||||||
breaks: true,
|
breaks: true,
|
||||||
@ -15,6 +17,13 @@ export default defineNuxtPlugin(() => {
|
|||||||
const render = md(options)
|
const render = md(options)
|
||||||
.use(mm, {
|
.use(mm, {
|
||||||
})
|
})
|
||||||
|
.use(anchor, {
|
||||||
|
})
|
||||||
|
.use(toc, {
|
||||||
|
containerId: 'toc',
|
||||||
|
itemClass: 'truncate',
|
||||||
|
// format: (x: string, fn: (s: string) => string) => `<!--<span class="truncate">${fn(x)}</span>-->`,
|
||||||
|
})
|
||||||
return {
|
return {
|
||||||
provide: {
|
provide: {
|
||||||
mdRender: render,
|
mdRender: render,
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -4385,6 +4385,11 @@ magicast@^0.3.5:
|
|||||||
"@babel/types" "^7.25.4"
|
"@babel/types" "^7.25.4"
|
||||||
source-map-js "^1.2.0"
|
source-map-js "^1.2.0"
|
||||||
|
|
||||||
|
markdown-it-anchor@^9.2.0:
|
||||||
|
version "9.2.0"
|
||||||
|
resolved "https://registry.npmmirror.com/markdown-it-anchor/-/markdown-it-anchor-9.2.0.tgz#89375d9a2a79336403ab7c4fd36b1965cc45e5c8"
|
||||||
|
integrity sha512-sa2ErMQ6kKOA4l31gLGYliFQrMKkqSO0ZJgGhDHKijPf0pNFM9vghjAh3gn26pS4JDRs7Iwa9S36gxm3vgZTzg==
|
||||||
|
|
||||||
markdown-it-mathjax3@^4.3.2:
|
markdown-it-mathjax3@^4.3.2:
|
||||||
version "4.3.2"
|
version "4.3.2"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz#1e34aa86f8560b283fd283008334adc2d6b05a37"
|
resolved "https://registry.npmmirror.com/markdown-it-mathjax3/-/markdown-it-mathjax3-4.3.2.tgz#1e34aa86f8560b283fd283008334adc2d6b05a37"
|
||||||
@ -4393,6 +4398,11 @@ markdown-it-mathjax3@^4.3.2:
|
|||||||
juice "^8.0.0"
|
juice "^8.0.0"
|
||||||
mathjax-full "^3.2.0"
|
mathjax-full "^3.2.0"
|
||||||
|
|
||||||
|
markdown-it-toc-done-right@^4.2.0:
|
||||||
|
version "4.2.0"
|
||||||
|
resolved "https://registry.npmmirror.com/markdown-it-toc-done-right/-/markdown-it-toc-done-right-4.2.0.tgz#3ccdce22d5022ffae7b991d07261b1b1de5459d0"
|
||||||
|
integrity sha512-UB/IbzjWazwTlNAX0pvWNlJS8NKsOQ4syrXZQ/C72j+jirrsjVRT627lCaylrKJFBQWfRsPmIVQie8x38DEhAQ==
|
||||||
|
|
||||||
markdown-it@^14.1.0:
|
markdown-it@^14.1.0:
|
||||||
version "14.1.0"
|
version "14.1.0"
|
||||||
resolved "https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
|
resolved "https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user