diff --git a/deploy/nginx/nginx.conf b/deploy/nginx/nginx.conf index 2a599a07eb406d1fc0585da43e628bb52526476c..d71e7e69e43d8910d846fce50eefe391c0ae5d45 100644 --- a/deploy/nginx/nginx.conf +++ b/deploy/nginx/nginx.conf @@ -159,7 +159,7 @@ http { proxy_pass https://dsapi.test.osinfra.cn/; } - + location /25.03/ { proxy_set_header X-Forwarded-For $http_x_real_ip; proxy_http_version 1.1; @@ -167,7 +167,7 @@ http { proxy_ssl_protocols TLSv1.2; proxy_ssl_verify off; - proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080/; + proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080; } location /zh/25.03/ { @@ -177,7 +177,7 @@ http { proxy_ssl_protocols TLSv1.2; proxy_ssl_verify off; - proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080/zh/; + proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080; } location /en/25.03/ { @@ -187,7 +187,7 @@ http { proxy_ssl_protocols TLSv1.2; proxy_ssl_verify off; - proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080/en/; + proxy_pass https://openeuler-docs-website-25-03.openeuler-website-docs:8080; } location ^~ /docs/24.03_LTS_SP1/ { diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 67ac107052aa9fb8e849cb5020c7cc94a1085bed..9130d0f76d560056be6833ca50b06eaf1e7f373e 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -1,4 +1,5 @@ import hljs from 'highlight.js'; +import type Markdown from 'markdown-it'; export default { base: '/', @@ -65,7 +66,7 @@ export default { return `
${code}
`; } }, - config: (md) => { + config: (md: Markdown) => { md.renderer.rules.code_inline = (tokens, idx) => { const content = tokens[idx].content; // 转义 @@ -83,6 +84,22 @@ export default { } return escapedContent; }; + + // 标题处理 + md.renderer.rules.heading_open = function (tokens, idx, options, _, self) { + const aIndex = tokens[idx].attrIndex('id'); + const id = tokens[idx].attrs?.[aIndex]?.[1]; + const tag = tokens[idx].tag; + const render = self.renderToken(tokens, idx, options); + + // 自定义标题的 HTML 结构 + return `${render}${tag === 'h1' || tag === 'h2' ? `` : ''}`; + }; + + md.renderer.rules.heading_close = function (tokens, idx, options, _, self) { + const tag = tokens[idx].tag; + return `${tag === 'h1' || tag === 'h2' ? '' : ''}${self.renderToken(tokens, idx, options)}`; + }; }, }, }; diff --git a/docs/.vitepress/src/assets/svg-icons/icon-link.svg b/docs/.vitepress/src/assets/svg-icons/icon-link.svg new file mode 100644 index 0000000000000000000000000000000000000000..4c9e24db6cd352b1f8c6720a6cbb06817129450c --- /dev/null +++ b/docs/.vitepress/src/assets/svg-icons/icon-link.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/.vitepress/src/assets/svg-icons/icon-pin.svg b/docs/.vitepress/src/assets/svg-icons/icon-pin.svg new file mode 100644 index 0000000000000000000000000000000000000000..0f940828ec55359a3811db85f15bcfea07284e35 --- /dev/null +++ b/docs/.vitepress/src/assets/svg-icons/icon-pin.svg @@ -0,0 +1,4 @@ + + + + diff --git a/docs/.vitepress/src/components/markdown/MarkdownTitle.vue b/docs/.vitepress/src/components/markdown/MarkdownTitle.vue new file mode 100644 index 0000000000000000000000000000000000000000..3f2408dd14530da56ebe193d0e68f3b1bb7a7606 --- /dev/null +++ b/docs/.vitepress/src/components/markdown/MarkdownTitle.vue @@ -0,0 +1,156 @@ + + + + + diff --git a/docs/.vitepress/src/composables/useClipboard.ts b/docs/.vitepress/src/composables/useClipboard.ts new file mode 100644 index 0000000000000000000000000000000000000000..8d05472ebde3a0d1cfa34bd90fd22f9d535ce68b --- /dev/null +++ b/docs/.vitepress/src/composables/useClipboard.ts @@ -0,0 +1,19 @@ +import Clipboard from 'clipboard'; +interface ClipboardJSExtended extends ClipboardJS { + onClick: (event: MouseEvent) => void; +} + +export const useClipboard = (options: { text: string; target: MouseEvent; success?: Function; error?: Function }) => { + const clipboard = new Clipboard(options.target.currentTarget as Element, { + text: () => options.text, + }) as ClipboardJSExtended; + clipboard.on('success', (e) => { + options?.success && options?.success(e); + clipboard.destroy(); + }); + clipboard.on('error', (e) => { + options?.error && options?.error(e); + clipboard.destroy(); + }); + clipboard.onClick(options.target); +}; diff --git a/docs/.vitepress/src/layouts/LayoutDoc.vue b/docs/.vitepress/src/layouts/LayoutDoc.vue index 69c4f32d2f34561df7d29319d02af27eb4c1af78..407c7838315f4aafabb026153730deaece21b40f 100644 --- a/docs/.vitepress/src/layouts/LayoutDoc.vue +++ b/docs/.vitepress/src/layouts/LayoutDoc.vue @@ -186,7 +186,7 @@ const onScrollAnchor = () => { const top = getOffsetTop(target, scrollContainer.value); - if (top < 100) { + if (top < 110) { distances.push({ item, top, @@ -219,7 +219,7 @@ const onScrollNodeAnchor = useDebounceFn(() => { for (let i = 0; i < idArr.length; i++) { const top = getOffsetTop(idArr[i], nodeScrollContainer.value); - if (top < 130) { + if (top < 120) { distances.push({ index: i, top, diff --git a/docs/.vitepress/src/utils/scroll-to.ts b/docs/.vitepress/src/utils/scroll-to.ts index da33dc6971f11f5476be48188104df082da2928b..02b93afb49f7b485c168d4909fc25ed636ce51f3 100644 --- a/docs/.vitepress/src/utils/scroll-to.ts +++ b/docs/.vitepress/src/utils/scroll-to.ts @@ -101,7 +101,7 @@ export function scrollTo(y: number, opts: ScrollTopOptions) { } -export async function scrollIntoView(target: HTMLElement, scrollContainer: HTMLElement, targetOffset = 120) { +export async function scrollIntoView(target: HTMLElement, scrollContainer: HTMLElement, targetOffset = 100) { const { scrollTop } = getScroll(scrollContainer); const offsetTop = getOffsetTop(target, scrollContainer); const y = scrollTop + offsetTop - targetOffset; diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts index 10dfc89a8d1fc04f7e658bc01d6c95697deb1553..a89af7a20159407c49153b181d8fb016bdfaf2ed 100644 --- a/docs/.vitepress/theme/index.ts +++ b/docs/.vitepress/theme/index.ts @@ -16,6 +16,7 @@ import '@/assets/style/global.scss'; import '@/assets/style/element-plus/index.scss'; import VueDOMPurifyHTML from 'vue-dompurify-html'; +import MarkdownTitle from '@/components/markdown/MarkdownTitle.vue'; export default { Layout, @@ -31,5 +32,7 @@ export default { Object.keys(directives).forEach((directive) => { app.directive(directive, directives[directive]); }); + // 注册组件 + app.component('MarkdownTitle', MarkdownTitle); }, }; diff --git a/package.json b/package.json index 545efb457b6ce0e99cd0cd07ed59ceb07ad81c12..ebbaedac8c253f10b6526a2103598b1f50a5ee56 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@opensig/opendesign": "0.0.68", "@vueuse/core": "9.12.0", "axios": "1.7.4", + "clipboard": "2.0.11", "element-plus": "2.3.12", "gray-matter": "4.0.3", "highlight.js": "11.9.0", @@ -39,6 +40,7 @@ "@types/highlight.js": "^10.1.0", "@types/js-cookie": "^3.0.6", "@types/lodash-es": "^4.17.12", + "@types/markdown-it": "^14.1.2", "@types/node": "^18.18.10", "@vitejs/plugin-basic-ssl": "^1.1.0", "@vitejs/plugin-vue": "^4.4.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 402aa24eaa25cb7cf0ccbeef119b9b76d578b79e..15e88ac4a5a55786045b2fcc39788ad06d2ee725 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -24,11 +24,14 @@ importers: axios: specifier: 1.6.7 version: 1.6.7 + clipboard: + specifier: 2.0.11 + version: 2.0.11 element-plus: specifier: 2.3.12 version: 2.3.12(vue@3.3.4) gray-matter: - specifier: ^4.0.3 + specifier: 4.0.3 version: 4.0.3 highlight.js: specifier: 11.9.0 @@ -37,7 +40,7 @@ importers: specifier: 3.0.5 version: 3.0.5 lodash-es: - specifier: ^4.17.21 + specifier: 4.17.21 version: 4.17.21 pinia: specifier: 2.1.6 @@ -70,6 +73,9 @@ importers: '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 + '@types/markdown-it': + specifier: ^14.1.2 + version: 14.1.2 '@types/node': specifier: ^18.18.10 version: 18.19.70 @@ -1205,6 +1211,9 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + clipboard@2.0.11: + resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1288,6 +1297,9 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} + delegate@3.2.0: + resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -1546,6 +1558,9 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + good-listener@1.2.2: + resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2055,6 +2070,9 @@ packages: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} + select@1.1.2: + resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2150,6 +2168,9 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + tiny-emitter@2.1.0: + resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -3615,6 +3636,12 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + clipboard@2.0.11: + dependencies: + good-listener: 1.2.2 + select: 1.1.2 + tiny-emitter: 2.1.0 + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -3679,6 +3706,8 @@ snapshots: delayed-stream@1.0.0: {} + delegate@3.2.0: {} + dequal@2.0.3: {} devlop@1.1.0: @@ -4001,6 +4030,10 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + good-listener@1.2.2: + dependencies: + delegate: 3.2.0 + graceful-fs@4.2.11: {} graphemer@1.4.0: {} @@ -4495,6 +4528,8 @@ snapshots: extend-shallow: 2.0.1 kind-of: 6.0.3 + select@1.1.2: {} + semver@6.3.1: {} semver@7.6.3: {} @@ -4580,6 +4615,8 @@ snapshots: text-table@0.2.0: {} + tiny-emitter@2.1.0: {} + tinyexec@0.3.2: {} to-regex-range@5.0.1: