diff --git a/package-lock.json b/package-lock.json index 4c2eb3e..227c5e1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "axios": "^1.4.0", "js-yaml": "^4.1.0", "leaflet": "^1.9.4", + "markdown-it-anchor": "^8.6.7", "pinia": "^2.1.6", "unhead": "^1.2.2", "vue": "^3.3.4", @@ -898,14 +899,12 @@ "node_modules/@types/linkify-it": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", - "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", - "dev": true + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==" }, "node_modules/@types/markdown-it": { "version": "12.2.3", "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", - "dev": true, "dependencies": { "@types/linkify-it": "*", "@types/mdurl": "*" @@ -914,8 +913,7 @@ "node_modules/@types/mdurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", - "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", - "dev": true + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==" }, "node_modules/@types/ms": { "version": "0.7.31", @@ -2006,7 +2004,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -3368,7 +3365,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", - "dev": true, "dependencies": { "uc.micro": "^1.0.1" } @@ -3459,7 +3455,6 @@ "version": "13.0.1", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", - "dev": true, "dependencies": { "argparse": "^2.0.1", "entities": "~3.0.1", @@ -3471,11 +3466,19 @@ "markdown-it": "bin/markdown-it.js" } }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, "node_modules/mdurl": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" }, "node_modules/media-typer": { "version": "0.3.0", @@ -4945,8 +4948,7 @@ "node_modules/uc.micro": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" }, "node_modules/unhead": { "version": "1.2.2", diff --git a/package.json b/package.json index 501d8d6..5bfd4b7 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "axios": "^1.4.0", "js-yaml": "^4.1.0", "leaflet": "^1.9.4", + "markdown-it-anchor": "^8.6.7", "pinia": "^2.1.6", "unhead": "^1.2.2", "vue": "^3.3.4", diff --git a/src/plugins/markdown/relativeToRouter.js b/src/plugins/markdown/relativeToRouter.js new file mode 100644 index 0000000..203676f --- /dev/null +++ b/src/plugins/markdown/relativeToRouter.js @@ -0,0 +1,29 @@ +export default (md) => { + const scan = (state) => { + state.tokens.forEach((tokens) => { + if (tokens.type !== 'inline') { + return + } + const inlineTokens = tokens.children + let isRT = false + for (let i = 0; i < inlineTokens.length; i++) { + if (isRT && inlineTokens[i].type === 'link_close') { + inlineTokens[i].tag = 'router-link' + isRT = false + } else if (inlineTokens[i].type === 'link_open') { + const attrs = inlineTokens[i].attrs + const href = attrs?.find((v) => v[0] === 'href') + if (href && !href[1].startsWith('http')) { + inlineTokens[i].tag = 'router-link' + inlineTokens[i].attrs = [['to', href[1]]] + isRT = true + } else { + inlineTokens[i].attrs.push(['rel', 'noopener noreferrer']) + inlineTokens[i].attrs.push(['target', '_blank']) + } + } + } + }) + } + md.core.ruler.push('router-link', scan) +} diff --git a/src/router/index.js b/src/router/index.js index a3b8e71..9b7dd05 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -38,6 +38,11 @@ function getHistory() { export function createRouter() { return _createRouter({ history: getHistory(), - routes + routes, + scrollBehavior(to, from, savedPosition) { + if (to.hash) { + return { el: to.hash } + } + } }) } diff --git a/vite.config.js b/vite.config.js index a525b3c..2040750 100644 --- a/vite.config.js +++ b/vite.config.js @@ -3,6 +3,8 @@ import { loadConfiguration } from './src/utils/loadConfiguration.js' import path from 'path' import Vue from '@vitejs/plugin-vue' import Markdown from 'vite-plugin-md' +import markdownAnchor from 'markdown-it-anchor' +import markdownRelativeToRouter from './src/plugins/markdown/relativeToRouter.js' import Pages from 'vite-plugin-pages' import './src/utils/globalVars' @@ -26,7 +28,11 @@ export default () => { }), Markdown({ wrapperClasses: - '!container mx-auto p-4 sm:pl-0 sm:pr-0 prose dark:prose-invert box-border' + '!container mx-auto p-4 sm:pl-0 sm:pr-0 prose dark:prose-invert box-border', + markdownItSetup(md) { + md.use(markdownAnchor) + }, + markdownItUses: [markdownRelativeToRouter] }), Pages({ dirs: 'pages',