diff --git a/docs/.vitepress/plugins/markdownTransform.ts b/docs/.vitepress/plugins/markdownTransform.ts
new file mode 100644
index 00000000..c1c145f7
--- /dev/null
+++ b/docs/.vitepress/plugins/markdownTransform.ts
@@ -0,0 +1,55 @@
+import type { Plugin } from 'vite'
+import { replacer } from '../../../scripts/markdownTransform'
+import { getReadingTime } from './../theme/utils'
+
+export function MarkdownTransform(): Plugin {
+ return {
+ name: 'toshiki-notebook-md-transform',
+ enforce: 'pre',
+ async transform(code, id) {
+ if (!id.match(/\.md\b/)) return null
+ // convert links to relative
+ code = code.replace(/https?:\/\/toshiki-notebook\.dev\//g, '/')
+ const [_name, i] = id.split('/').slice(-2)
+
+ // convert img by applying regex
+ const imgRegex = /!\[(.+?)\]\((.+?)\)/g
+ let imgMatches = imgRegex.exec(code)
+ while (imgMatches) {
+ const [text, link] = imgMatches.slice(1)
+ code = code.replace(imgMatches[0], `
`)
+ imgMatches = imgRegex.exec(code)
+ }
+
+ // convert links to components
+ const linkRegex = /\[(.+?)\]\((.+?)\)/g
+ let matches = linkRegex.exec(code)
+ while (matches) {
+ const [text, link] = matches.slice(1)
+ code = code.replace(matches[0], ``)
+ matches = linkRegex.exec(code)
+ }
+
+ // cut index.md
+ if (_name === 'docs' && i === 'index.md') return code
+
+ const { footer } = await getDocsMarkdown()
+ code = replacer(code, footer, 'FOOTER', 'tail')
+ const { readTime, words } = getReadingTime(code)
+ code = code.replace(/(#\s.+?\n)/, `$1\n\n\n`)
+
+ return code
+ },
+ }
+}
+
+export async function getDocsMarkdown() {
+ const CopyRightSection = `
+ `
+
+ const footer = `${CopyRightSection}\n`
+
+ return {
+ footer,
+ }
+}