Merge branch 'main' into translate_vitepress

pull/3934/head
Camilo Parra 1 year ago committed by GitHub
commit f5ea57409b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,3 +1,35 @@
## [1.2.2](https://github.com/vuejs/vitepress/compare/v1.2.1...v1.2.2) (2024-05-21)
### Bug Fixes
- dont escape ampersand twice in title ([7ea3572](https://github.com/vuejs/vitepress/commit/7ea357256c855ae0a9a142c14bbd5e7d344ef865))
## [1.2.1](https://github.com/vuejs/vitepress/compare/v1.2.0...v1.2.1) (2024-05-21)
### Bug Fixes
- **a11y:** make code blocks accessible with keyboard ([#3902](https://github.com/vuejs/vitepress/issues/3902)) ([cb308b9](https://github.com/vuejs/vitepress/commit/cb308b9295e1e661c2c72fa4229b5c7d83278d49))
- escape title properly in build ([49b1233](https://github.com/vuejs/vitepress/commit/49b1233378436054c07a6ef646d0029096124021))
- **theme:** remove unnecessary navigation role on nav element ([af4717d](https://github.com/vuejs/vitepress/commit/af4717d6820233a011200d44abba53d0f66bfad3))
# [1.2.0](https://github.com/vuejs/vitepress/compare/v1.1.4...v1.2.0) (2024-05-18)
### Bug Fixes
- **build:** show file info on error ([f0debd2](https://github.com/vuejs/vitepress/commit/f0debd20f48ab7eb58cfd142147531509d6c0209))
- **dev:** match dev and prod routing behavior ([#3837](https://github.com/vuejs/vitepress/issues/3837)) ([b360ac8](https://github.com/vuejs/vitepress/commit/b360ac88df3bfd60e3498cc19066c0c90261ee4f))
- **markdown:** entities and escapes not working properly ([#3882](https://github.com/vuejs/vitepress/issues/3882)) ([d5dbd70](https://github.com/vuejs/vitepress/commit/d5dbd704ceb215ebf3ce9b23deec6e6c90634f0a))
- render 404 page completely on client to infer locale from browser path ([#3858](https://github.com/vuejs/vitepress/issues/3858)) ([728cb15](https://github.com/vuejs/vitepress/commit/728cb15677f4f84b33bed6bb2f70f47600ea1057))
- **style:** prefer YaHei over DengXian ([f0a37b4](https://github.com/vuejs/vitepress/commit/f0a37b4b8445ec914700df054c0897721382e5b1))
- **theme/regression:** custom font not applying in Chinese docs because of specificity ([fa2f38a](https://github.com/vuejs/vitepress/commit/fa2f38a0c3bd121dcb7e07420566087c19b10f96)), closes [#3864](https://github.com/vuejs/vitepress/issues/3864)
- **theme:** external link icon not visible for target \_blank links ([d08eeed](https://github.com/vuejs/vitepress/commit/d08eeed89726572f7ea341df59864cc72716751c)), closes [#3327](https://github.com/vuejs/vitepress/issues/3327)
- **theme:** fix invalid vp-offset in ssr ([9794877](https://github.com/vuejs/vitepress/commit/9794877347140c7b4955d735cd8867c260a5089d))
### Features
- **build/i18n:** support customizing copy code button's tooltip text ([#3854](https://github.com/vuejs/vitepress/issues/3854)) ([ed6ada7](https://github.com/vuejs/vitepress/commit/ed6ada7a688c466920f3e0ef33b7176b8eb01eee))
- **build:** add localeIndex to md.env ([#3862](https://github.com/vuejs/vitepress/issues/3862)) ([0cbb469](https://github.com/vuejs/vitepress/commit/0cbb469842d74381ad56d44b7975f34c405b78f8))
## [1.1.4](https://github.com/vuejs/vitepress/compare/v1.1.3...v1.1.4) (2024-04-27) ## [1.1.4](https://github.com/vuejs/vitepress/compare/v1.1.3...v1.1.4) (2024-04-27)
### Bug Fixes ### Bug Fixes

@ -29,6 +29,10 @@ $ pnpm add -D vitepress
$ yarn add -D vitepress $ yarn add -D vitepress
``` ```
```sh [yarn (pnp)]
$ yarn add -D vitepress vue
```
```sh [bun] ```sh [bun]
$ bun add -D vitepress $ bun add -D vitepress
``` ```

@ -3,13 +3,11 @@
VitePress comes with out-of-the-box support for generating a `sitemap.xml` file for your site. To enable it, add the following to your `.vitepress/config.js`: VitePress comes with out-of-the-box support for generating a `sitemap.xml` file for your site. To enable it, add the following to your `.vitepress/config.js`:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com' hostname: 'https://example.com'
} }
}) }
``` ```
To have `<lastmod>` tags in your `sitemap.xml`, you can enable the [`lastUpdated`](../reference/default-theme-last-updated) option. To have `<lastmod>` tags in your `sitemap.xml`, you can enable the [`lastUpdated`](../reference/default-theme-last-updated) option.
@ -19,14 +17,23 @@ To have `<lastmod>` tags in your `sitemap.xml`, you can enable the [`lastUpdated
Sitemap support is powered by the [`sitemap`](https://www.npmjs.com/package/sitemap) module. You can pass any options supported by it to the `sitemap` option in your config file. These will be passed directly to the `SitemapStream` constructor. Refer to the [`sitemap` documentation](https://www.npmjs.com/package/sitemap#options-you-can-pass) for more details. Example: Sitemap support is powered by the [`sitemap`](https://www.npmjs.com/package/sitemap) module. You can pass any options supported by it to the `sitemap` option in your config file. These will be passed directly to the `SitemapStream` constructor. Refer to the [`sitemap` documentation](https://www.npmjs.com/package/sitemap#options-you-can-pass) for more details. Example:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com', hostname: 'https://example.com',
lastmodDateOnly: false lastmodDateOnly: false
} }
}) }
```
If you're using `base` in your config, you should append it to the `hostname` option:
```ts
export default {
base: '/my-site/',
sitemap: {
hostname: 'https://example.com/my-site/'
}
}
``` ```
## `transformItems` Hook ## `transformItems` Hook
@ -34,9 +41,7 @@ export default defineConfig({
You can use the `sitemap.transformItems` hook to modify the sitemap items before they are written to the `sitemap.xml` file. This hook is called with an array of sitemap items and expects an array of sitemap items to be returned. Example: You can use the `sitemap.transformItems` hook to modify the sitemap items before they are written to the `sitemap.xml` file. This hook is called with an array of sitemap items and expects an array of sitemap items to be returned. Example:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com', hostname: 'https://example.com',
transformItems: (items) => { transformItems: (items) => {
@ -49,5 +54,5 @@ export default defineConfig({
return items return items
} }
} }
}) }
``` ```

@ -10,7 +10,7 @@
"preview": "vitepress preview" "preview": "vitepress preview"
}, },
"devDependencies": { "devDependencies": {
"@lunariajs/core": "^0.0.32", "@lunariajs/core": "^0.1.0",
"markdown-it-mathjax3": "^4.3.2", "markdown-it-mathjax3": "^4.3.2",
"open-cli": "^8.0.0", "open-cli": "^8.0.0",
"vitepress": "workspace:*" "vitepress": "workspace:*"

@ -29,6 +29,10 @@ $ pnpm add -D vitepress
$ yarn add -D vitepress $ yarn add -D vitepress
``` ```
```sh [yarn (pnp)]
$ yarn add -D vitepress vue
```
```sh [bun] ```sh [bun]
$ bun add -D vitepress $ bun add -D vitepress
``` ```

@ -29,6 +29,10 @@ $ pnpm add -D vitepress
$ yarn add -D vitepress $ yarn add -D vitepress
``` ```
```sh [yarn (pnp)]
$ yarn add -D vitepress vue
```
```sh [bun] ```sh [bun]
$ bun add -D vitepress $ bun add -D vitepress
``` ```

@ -3,13 +3,11 @@
VitePress поставляется с готовой поддержкой генерации файла `sitemap.xml` для вашего сайта. Чтобы включить её, добавьте следующее в файл `.vitepress/config.js`: VitePress поставляется с готовой поддержкой генерации файла `sitemap.xml` для вашего сайта. Чтобы включить её, добавьте следующее в файл `.vitepress/config.js`:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com' hostname: 'https://example.com'
} }
}) }
``` ```
Чтобы теги `<lastmod>` присутствовали в вашем файле `sitemap.xml`, вы можете включить опцию [`lastUpdated`](../reference/default-theme-last-updated). Чтобы теги `<lastmod>` присутствовали в вашем файле `sitemap.xml`, вы можете включить опцию [`lastUpdated`](../reference/default-theme-last-updated).
@ -19,14 +17,23 @@ export default defineConfig({
Поддержка карты сайта осуществляется с помощью модуля [`sitemap`](https://www.npmjs.com/package/sitemap). Вы можете передать любые поддерживаемые им параметры в опцию `sitemap` в вашем конфигурационном файле. Они будут переданы непосредственно в конструктор `SitemapStream`. Более подробную информацию см. в документации [`sitemap`](https://www.npmjs.com/package/sitemap#options-you-can-pass). Пример: Поддержка карты сайта осуществляется с помощью модуля [`sitemap`](https://www.npmjs.com/package/sitemap). Вы можете передать любые поддерживаемые им параметры в опцию `sitemap` в вашем конфигурационном файле. Они будут переданы непосредственно в конструктор `SitemapStream`. Более подробную информацию см. в документации [`sitemap`](https://www.npmjs.com/package/sitemap#options-you-can-pass). Пример:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com', hostname: 'https://example.com',
lastmodDateOnly: false lastmodDateOnly: false
} }
}) }
```
При использовании параметра `base` в своей конфигурации обязательно добавьте его в адрес `hostname`:
```ts
export default {
base: '/my-site/',
sitemap: {
hostname: 'https://example.com/my-site/'
}
}
``` ```
## Хук `transformItems` {#transformitems-hook} ## Хук `transformItems` {#transformitems-hook}
@ -34,9 +41,7 @@ export default defineConfig({
Вы можете использовать хук `sitemap.transformItems` для изменения элементов карты сайта перед их записью в файл `sitemap.xml`. Этот хук вызывается с массивом элементов sitemap и ожидает возвращения массива элементов sitemap. Пример: Вы можете использовать хук `sitemap.transformItems` для изменения элементов карты сайта перед их записью в файл `sitemap.xml`. Этот хук вызывается с массивом элементов sitemap и ожидает возвращения массива элементов sitemap. Пример:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com', hostname: 'https://example.com',
transformItems: (items) => { transformItems: (items) => {
@ -49,5 +54,5 @@ export default defineConfig({
return items return items
} }
} }
}) }
``` ```

@ -28,7 +28,7 @@ export default defineConfig({
### i18n {#local-search-i18n} ### i18n {#local-search-i18n}
Вы можете использовать подобную конфигурацию для использования многоязычного поиска: Пример конфигурации для использования многоязычного поиска:
```ts ```ts
import { defineConfig } from 'vitepress' import { defineConfig } from 'vitepress'
@ -199,7 +199,7 @@ export default defineConfig({
### i18n {#algolia-search-i18n} ### i18n {#algolia-search-i18n}
Вы можете использовать подобную конфигурацию для использования многоязычного поиска: Пример конфигурации для использования многоязычного поиска:
```ts ```ts
import { defineConfig } from 'vitepress' import { defineConfig } from 'vitepress'

@ -287,3 +287,51 @@ Cache-Control: max-age=31536000,immutable
### Kinsta 静态站点托管 {#kinsta-static-site-hosting} ### Kinsta 静态站点托管 {#kinsta-static-site-hosting}
你可以按照这些[说明](https://kinsta.com/docs/vitepress-static-site-example/) 在 [Kinsta](https://kinsta.com/static-site-hosting/) 上部署 Vitepress 站点。 你可以按照这些[说明](https://kinsta.com/docs/vitepress-static-site-example/) 在 [Kinsta](https://kinsta.com/static-site-hosting/) 上部署 Vitepress 站点。
### Stormkit
你可以按照这些[说明](https://stormkit.io/blog/how-to-deploy-vitepress)将你的 VitePress 项目部署到 [Stormkit](https://www.stormkit.io)。
### Nginx
下面是一个 Nginx 服务器块配置示例。此配置包括对基于文本的常见资源的 gzip 压缩、使用适当缓存头为 VitePress 站点静态文件提供服务的规则以及处理 `cleanUrls: true` 的方法。
```nginx
server {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
listen 80;
server_name _;
index index.html;
location / {
# content location
root /app;
# exact matches -> reverse clean urls -> folders -> not found
try_files $uri $uri.html $uri/ =404;
# non existent pages
error_page 404 /404.html;
# a folder without index.html raises 403 in this setup
error_page 403 /404.html;
# adjust caching headers
# files in the assets folder have hashes filenames
location ~* ^/assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}
```
本配置默认已构建的 VitePress 站点位于服务器上的 `/app` 目录中。如果站点文件位于其他位置,请相应调整 `root` 指令。
::: warning 不要默认为 index.html
try_files 解析不能像其他 Vue 应用那样默认为 index.html。这会导致页面状态处于无效。
:::
更多信息请参见 [nginx 官方文档](https://nginx.org/en/docs/)、这些 GitHub Issue [#2837](https://github.com/vuejs/vitepress/discussions/2837)、[#3235](https://github.com/vuejs/vitepress/issues/3235)以及 Mehdi Merah 发表的[博客](https://blog.mehdi.cc/articles/vitepress-cleanurls-on-nginx-environment#readings)。

@ -29,6 +29,10 @@ $ pnpm add -D vitepress
$ yarn add -D vitepress $ yarn add -D vitepress
``` ```
```sh [yarn (pnp)]
$ yarn add -D vitepress vue
```
```sh [bun] ```sh [bun]
$ bun add -D vitepress $ bun add -D vitepress
``` ```
@ -86,7 +90,7 @@ $ bun vitepress init
<<< @/snippets/init.ansi <<< @/snippets/init.ansi
:::tip Vue 作为 peer dependency :::tip Vue 作为 peer dependency
如果打算使用 Vue 组件或 API 进行自定义,还应该明确地将 `vue` 安装为 peer dependency。 如果打算使用 Vue 组件或 API 进行自定义,还应该明确地将 `vue` 安装为 dependency。
::: :::
## 文件结构 {#file-structure} ## 文件结构 {#file-structure}

@ -3,13 +3,11 @@
VitePress 提供开箱即用的配置,为站点生成 `sitemap.xml` 文件。要启用它,请将以下内容添加到 `.vitepress/config.js` 中: VitePress 提供开箱即用的配置,为站点生成 `sitemap.xml` 文件。要启用它,请将以下内容添加到 `.vitepress/config.js` 中:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com' hostname: 'https://example.com'
} }
}) }
``` ```
要在 `sitemap.xml` 中包含 `<lastmod>` 标签,可以启用 [`lastUpdated`](../reference/default-theme-last-updated) 选项。 要在 `sitemap.xml` 中包含 `<lastmod>` 标签,可以启用 [`lastUpdated`](../reference/default-theme-last-updated) 选项。
@ -19,14 +17,23 @@ export default defineConfig({
VitePress 的 sitemap 由 [`sitemap`](https://www.npmjs.com/package/sitemap) 模块提供支持。可以将该模块支持的选项传递给配置文件中的 `sitemap` 选项。这些选项将直接传递给 `SitemapStream` 构造函数。有关更多详细信息,请参阅 [`sitemap` 文档](https://www.npmjs.com/package/sitemap#options-you-can-pass)。例如: VitePress 的 sitemap 由 [`sitemap`](https://www.npmjs.com/package/sitemap) 模块提供支持。可以将该模块支持的选项传递给配置文件中的 `sitemap` 选项。这些选项将直接传递给 `SitemapStream` 构造函数。有关更多详细信息,请参阅 [`sitemap` 文档](https://www.npmjs.com/package/sitemap#options-you-can-pass)。例如:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com', hostname: 'https://example.com',
lastmodDateOnly: false lastmodDateOnly: false
} }
}) }
```
如果在配置中使用 `base`,则应将其追加到 `hostname` 选项中:
```ts
export default {
base: '/my-site/',
sitemap: {
hostname: 'https://example.com/my-site/'
}
}
``` ```
## `transformItems` Hook ## `transformItems` Hook
@ -34,13 +41,11 @@ export default defineConfig({
在将 sitemap 写入 `sitemap.xml` 文件之前,可以使用 `sitemap.transformItems` 钩子来修改 sitemap。使用 sitemap 调用该钩子,应返回 sitemap 数组。例如: 在将 sitemap 写入 `sitemap.xml` 文件之前,可以使用 `sitemap.transformItems` 钩子来修改 sitemap。使用 sitemap 调用该钩子,应返回 sitemap 数组。例如:
```ts ```ts
import { defineConfig } from 'vitepress' export default {
export default defineConfig({
sitemap: { sitemap: {
hostname: 'https://example.com', hostname: 'https://example.com',
transformItems: (items) => { transformItems: (items) => {
// 添加新选项或修改/过滤现有选项 // 添加新项目或修改/筛选现有选项
items.push({ items.push({
url: '/extra-page', url: '/extra-page',
changefreq: 'monthly', changefreq: 'monthly',
@ -49,5 +54,5 @@ export default defineConfig({
return items return items
} }
} }
}) }
``` ```

@ -1,20 +1,17 @@
{ {
"name": "vitepress", "name": "vitepress",
"version": "1.1.4", "version": "1.2.2",
"description": "Vite & Vue powered static site generator", "description": "Vite & Vue powered static site generator",
"keywords": [ "keywords": [
"vite", "vite",
"vue", "vue",
"vitepress" "vitepress"
], ],
"homepage": "https://github.com/vuejs/vitepress/tree/main/#readme", "homepage": "https://vitepress.dev/",
"bugs": { "bugs": {
"url": "https://github.com/vuejs/vitepress/issues" "url": "https://github.com/vuejs/vitepress/issues"
}, },
"repository": { "repository": "github:vuejs/vitepress",
"type": "git",
"url": "git+https://github.com/vuejs/vitepress.git"
},
"license": "MIT", "license": "MIT",
"author": "Evan You", "author": "Evan You",
"type": "module", "type": "module",
@ -104,39 +101,38 @@
"dependencies": { "dependencies": {
"@docsearch/css": "^3.6.0", "@docsearch/css": "^3.6.0",
"@docsearch/js": "^3.6.0", "@docsearch/js": "^3.6.0",
"@shikijs/core": "^1.4.0", "@shikijs/core": "^1.6.1",
"@shikijs/transformers": "^1.4.0", "@shikijs/transformers": "^1.6.1",
"@types/markdown-it": "^14.1.1", "@types/markdown-it": "^14.1.1",
"@vitejs/plugin-vue": "^5.0.4", "@vitejs/plugin-vue": "^5.0.5",
"@vue/devtools-api": "^7.0.27", "@vue/devtools-api": "^7.2.0",
"@vue/shared": "^3.4.26", "@vue/shared": "^3.4.27",
"@vueuse/core": "^10.9.0", "@vueuse/core": "^10.10.0",
"@vueuse/integrations": "^10.9.0", "@vueuse/integrations": "^10.10.0",
"focus-trap": "^7.5.4", "focus-trap": "^7.5.4",
"mark.js": "8.11.1", "mark.js": "8.11.1",
"minisearch": "^6.3.0", "minisearch": "^6.3.0",
"shiki": "^1.4.0", "shiki": "^1.6.1",
"vite": "^5.2.11", "vite": "^5.2.12",
"vue": "^3.4.26" "vue": "^3.4.27"
}, },
"devDependencies": { "devDependencies": {
"@clack/prompts": "^0.7.0", "@clack/prompts": "^0.7.0",
"@mdit-vue/plugin-component": "^2.1.2", "@mdit-vue/plugin-component": "^2.1.3",
"@mdit-vue/plugin-frontmatter": "^2.1.2", "@mdit-vue/plugin-frontmatter": "^2.1.3",
"@mdit-vue/plugin-headers": "^2.1.2", "@mdit-vue/plugin-headers": "^2.1.3",
"@mdit-vue/plugin-sfc": "^2.1.2", "@mdit-vue/plugin-sfc": "^2.1.3",
"@mdit-vue/plugin-title": "^2.1.2", "@mdit-vue/plugin-title": "^2.1.3",
"@mdit-vue/plugin-toc": "^2.1.2", "@mdit-vue/plugin-toc": "^2.1.3",
"@mdit-vue/shared": "^2.1.2", "@mdit-vue/shared": "^2.1.3",
"@polka/compression": "1.0.0-next.25", "@polka/compression": "1.0.0-next.25",
"@rollup/plugin-alias": "^5.1.0", "@rollup/plugin-alias": "^5.1.0",
"@rollup/plugin-commonjs": "^25.0.7", "@rollup/plugin-commonjs": "^25.0.8",
"@rollup/plugin-json": "^6.1.0", "@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "^5.0.5", "@rollup/plugin-replace": "^5.0.5",
"@types/cross-spawn": "^6.0.6", "@types/cross-spawn": "^6.0.6",
"@types/debug": "^4.1.12", "@types/debug": "^4.1.12",
"@types/escape-html": "^1.0.4",
"@types/fs-extra": "^11.0.4", "@types/fs-extra": "^11.0.4",
"@types/lodash.template": "^4.5.3", "@types/lodash.template": "^4.5.3",
"@types/mark.js": "^8.11.12", "@types/mark.js": "^8.11.12",
@ -145,57 +141,56 @@
"@types/markdown-it-emoji": "^3.0.1", "@types/markdown-it-emoji": "^3.0.1",
"@types/micromatch": "^4.0.7", "@types/micromatch": "^4.0.7",
"@types/minimist": "^1.2.5", "@types/minimist": "^1.2.5",
"@types/node": "^20.12.8", "@types/node": "^20.12.13",
"@types/postcss-prefix-selector": "^1.16.3", "@types/postcss-prefix-selector": "^1.16.3",
"@types/prompts": "^2.4.9", "@types/prompts": "^2.4.9",
"chokidar": "^3.6.0", "chokidar": "^3.6.0",
"conventional-changelog-cli": "^4.1.0", "conventional-changelog-cli": "^5.0.0",
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.3",
"debug": "^4.3.4", "debug": "^4.3.5",
"esbuild": "^0.20.2", "esbuild": "^0.21.4",
"escape-html": "^1.0.3", "execa": "^9.1.0",
"execa": "^8.0.1",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"get-port": "^7.1.0", "get-port": "^7.1.0",
"gray-matter": "^4.0.3", "gray-matter": "^4.0.3",
"lint-staged": "^15.2.2", "lint-staged": "^15.2.5",
"lodash.template": "^4.5.0", "lodash.template": "^4.5.0",
"lru-cache": "^10.2.2", "lru-cache": "^10.2.2",
"markdown-it": "^14.1.0", "markdown-it": "^14.1.0",
"markdown-it-anchor": "^8.6.7", "markdown-it-anchor": "^9.0.1",
"markdown-it-attrs": "^4.1.6", "markdown-it-attrs": "^4.1.6",
"markdown-it-container": "^4.0.0", "markdown-it-container": "^4.0.0",
"markdown-it-emoji": "^3.0.0", "markdown-it-emoji": "^3.0.0",
"markdown-it-mathjax3": "^4.3.2", "markdown-it-mathjax3": "^4.3.2",
"micromatch": "^4.0.5", "micromatch": "^4.0.7",
"minimist": "^1.2.8", "minimist": "^1.2.8",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"ora": "^8.0.1", "ora": "^8.0.1",
"p-map": "^7.0.2", "p-map": "^7.0.2",
"path-to-regexp": "^6.2.2", "path-to-regexp": "^6.2.2",
"picocolors": "^1.0.0", "picocolors": "^1.0.1",
"pkg-dir": "^8.0.0", "pkg-dir": "^8.0.0",
"playwright-chromium": "^1.43.1", "playwright-chromium": "^1.44.1",
"polka": "1.0.0-next.25", "polka": "1.0.0-next.25",
"postcss-prefix-selector": "^1.16.1", "postcss-prefix-selector": "^1.16.1",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"prompts": "^2.4.2", "prompts": "^2.4.2",
"punycode": "^2.3.1", "punycode": "^2.3.1",
"rimraf": "^5.0.5", "rimraf": "^5.0.7",
"rollup": "^4.17.2", "rollup": "^4.18.0",
"rollup-plugin-dts": "^6.1.0", "rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "^6.1.1", "rollup-plugin-esbuild": "^6.1.1",
"semver": "^7.6.0", "semver": "^7.6.2",
"simple-git-hooks": "^2.11.1", "simple-git-hooks": "^2.11.1",
"sirv": "^2.0.4", "sirv": "^2.0.4",
"sitemap": "^7.1.1", "sitemap": "^8.0.0",
"sort-package-json": "^2.10.0", "sort-package-json": "^2.10.0",
"supports-color": "^9.4.0", "supports-color": "^9.4.0",
"typescript": "^5.4.5", "typescript": "^5.4.5",
"vitest": "^1.5.3", "vitest": "^1.6.0",
"vue-tsc": "2.0.14", "vue-tsc": "^2.0.19",
"wait-on": "^7.2.0" "wait-on": "^7.2.0"
}, },
"peerDependencies": { "peerDependencies": {
@ -210,7 +205,7 @@
"optional": true "optional": true
} }
}, },
"packageManager": "pnpm@9.0.6", "packageManager": "pnpm@9.1.4",
"pnpm": { "pnpm": {
"peerDependencyRules": { "peerDependencyRules": {
"ignoreMissing": [ "ignoreMissing": [
@ -221,10 +216,6 @@
}, },
"overrides": { "overrides": {
"ora>string-width": "^5" "ora>string-width": "^5"
},
"patchedDependencies": {
"markdown-it-anchor@8.6.7": "patches/markdown-it-anchor@8.6.7.patch",
"rollup-plugin-dts@6.1.0": "patches/rollup-plugin-dts@6.1.0.patch"
} }
} }
} }

@ -1,29 +0,0 @@
diff --git a/types/index.d.ts b/types/index.d.ts
index 7c94aae194faa66ca006ace98cdb0dee82a3e471..0377cace7c4a9653d4ecf963babffd4bd68494b0 100644
--- a/types/index.d.ts
+++ b/types/index.d.ts
@@ -1,10 +1,10 @@
-import MarkdownIt = require('markdown-it');
-import Token = require('markdown-it/lib/token');
-import State = require('markdown-it/lib/rules_core/state_core');
+import MarkdownIt from 'markdown-it';
+import Token from 'markdown-it/lib/token.mjs';
+import StateCore from 'markdown-it/lib/rules_core/state_core.mjs';
declare namespace anchor {
- export type RenderHref = (slug: string, state: State) => string;
- export type RenderAttrs = (slug: string, state: State) => Record<string, string | number>;
+ export type RenderHref = (slug: string, state: StateCore) => string;
+ export type RenderAttrs = (slug: string, state: StateCore) => Record<string, string | number>;
export interface PermalinkOptions {
class?: string,
@@ -37,7 +37,7 @@ declare namespace anchor {
placement?: 'before' | 'after'
}
- export type PermalinkGenerator = (slug: string, opts: PermalinkOptions, state: State, index: number) => void;
+ export type PermalinkGenerator = (slug: string, opts: PermalinkOptions, state: StateCore, index: number) => void;
export interface AnchorInfo {
slug: string;

@ -1,13 +0,0 @@
diff --git a/dist/rollup-plugin-dts.mjs b/dist/rollup-plugin-dts.mjs
index 4a9412285c48c37d03340a086c771f8e61fd82ac..c73cba3bf47550f69011366e37d2ae974f0c9fc0 100644
--- a/dist/rollup-plugin-dts.mjs
+++ b/dist/rollup-plugin-dts.mjs
@@ -675,6 +675,8 @@ function preProcess({ sourceFile }) {
const nextToken = children[idx + 1];
const isPunctuation = nextToken.kind >= ts.SyntaxKind.FirstPunctuation && nextToken.kind <= ts.SyntaxKind.LastPunctuation;
if (isPunctuation) {
+ const addSpace = code.slice(token.getEnd(), nextToken.getStart()) != " ";
+ code.appendLeft(nextToken.getStart(), `${addSpace ? " " : ""}${defaultExport}`);
code.appendLeft(nextToken.getStart(), defaultExport);
}
else {

File diff suppressed because it is too large Load Diff

@ -13,7 +13,7 @@ import {
type AsyncComponentLoader type AsyncComponentLoader
} from 'vue' } from 'vue'
export { inBrowser } from '../shared' export { inBrowser, escapeHtml as _escapeHtml } from '../shared'
/** /**
* Join two paths by resolving the slash collision. * Join two paths by resolving the slash collision.

@ -21,7 +21,8 @@ export {
onContentUpdated, onContentUpdated,
defineClientComponent, defineClientComponent,
withBase, withBase,
getScrollOffset getScrollOffset,
_escapeHtml
} from './app/utils' } from './app/utils'
// components // components

@ -30,7 +30,6 @@ useActiveAnchor(container, marker)
class="VPDocAsideOutline" class="VPDocAsideOutline"
:class="{ 'has-outline': headers.length > 0 }" :class="{ 'has-outline': headers.length > 0 }"
ref="container" ref="container"
role="navigation"
> >
<div class="content"> <div class="content">
<div class="outline-marker" ref="marker" /> <div class="outline-marker" ref="marker" />

@ -242,8 +242,7 @@ vite-error-overlay {
} }
mjx-container { mjx-container {
display: inline-block; overflow-x: auto;
margin: auto 2px -2px;
} }
mjx-container > svg { mjx-container > svg {

@ -268,11 +268,11 @@
font-optical-sizing: auto; font-optical-sizing: auto;
} }
:root:lang(zh) { :root:where(:lang(zh)) {
--vp-font-family-base: 'Punctuation SC', 'Inter', ui-sans-serif, system-ui, --vp-font-family-base: 'Punctuation SC', 'Inter', ui-sans-serif, system-ui,
'PingFang SC', 'Noto Sans CJK SC', 'Noto Sans SC', 'Heiti SC', 'DengXian', 'PingFang SC', 'Noto Sans CJK SC', 'Noto Sans SC', 'Heiti SC',
'Microsoft YaHei', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Microsoft YaHei', 'DengXian', sans-serif, 'Apple Color Emoji',
'Segoe UI Symbol', 'Noto Color Emoji'; 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
} }
/** /**

@ -1,13 +1,14 @@
import { isBooleanAttr } from '@vue/shared' import { isBooleanAttr } from '@vue/shared'
import escape from 'escape-html'
import fs from 'fs-extra' import fs from 'fs-extra'
import path from 'path' import path from 'path'
import { pathToFileURL } from 'url' import { pathToFileURL } from 'url'
import { normalizePath, transformWithEsbuild, type Rollup } from 'vite' import { normalizePath, transformWithEsbuild, type Rollup } from 'vite'
import { version } from '../../../package.json'
import type { SiteConfig } from '../config' import type { SiteConfig } from '../config'
import { import {
EXTERNAL_URL_RE, EXTERNAL_URL_RE,
createTitle, createTitle,
escapeHtml,
mergeHead, mergeHead,
notFoundPageData, notFoundPageData,
resolveSiteDataByRoute, resolveSiteDataByRoute,
@ -17,7 +18,6 @@ import {
type PageData, type PageData,
type SSGContext type SSGContext
} from '../shared' } from '../shared'
import { version } from '../../../package.json'
export async function renderPage( export async function renderPage(
render: (path: string) => Promise<SSGContext>, render: (path: string) => Promise<SSGContext>,
@ -163,7 +163,7 @@ export async function renderPage(
? '' ? ''
: '<meta name="viewport" content="width=device-width,initial-scale=1">' : '<meta name="viewport" content="width=device-width,initial-scale=1">'
} }
<title>${title}</title> <title>${escapeHtml(title)}</title>
${ ${
isDescriptionOverridden(head) isDescriptionOverridden(head)
? '' ? ''
@ -260,7 +260,7 @@ function renderAttrs(attrs: Record<string, string>): string {
return Object.keys(attrs) return Object.keys(attrs)
.map((key) => { .map((key) => {
if (isBooleanAttr(key)) return ` ${key}` if (isBooleanAttr(key)) return ` ${key}`
return ` ${key}="${escape(attrs[key] as string)}"` return ` ${key}="${escapeHtml(attrs[key] as string)}"`
}) })
.join('') .join('')
} }

@ -231,6 +231,10 @@ export const createMarkdownRenderer = async (
) )
.use(lineNumberPlugin, options.lineNumbers) .use(lineNumberPlugin, options.lineNumbers)
md.renderer.rules.table_open = function (tokens, idx, options, env, self) {
return '<table tabindex="0">\n'
}
if (options.gfmAlerts !== false) { if (options.gfmAlerts !== false) {
md.use(gitHubAlertsPlugin) md.use(gitHubAlertsPlugin)
} }
@ -287,6 +291,13 @@ export const createMarkdownRenderer = async (
md.use(mathPlugin.default ?? mathPlugin, { md.use(mathPlugin.default ?? mathPlugin, {
...(typeof options.math === 'boolean' ? {} : options.math) ...(typeof options.math === 'boolean' ? {} : options.math)
}) })
const orig = md.renderer.rules.math_block!
md.renderer.rules.math_block = (tokens, idx, options, env, self) => {
return orig(tokens, idx, options, env, self).replace(
/^<mjx-container /,
'<mjx-container tabindex="0" '
)
}
} catch (error) { } catch (error) {
throw new Error( throw new Error(
'You need to install `markdown-it-mathjax3` to use math support.' 'You need to install `markdown-it-mathjax3` to use math support.'

@ -1,8 +1,10 @@
import type MarkdownIt from 'markdown-it' import type MarkdownIt from 'markdown-it'
import container from 'markdown-it-container'
import type { RenderRule } from 'markdown-it/lib/renderer.mjs' import type { RenderRule } from 'markdown-it/lib/renderer.mjs'
import type Token from 'markdown-it/lib/token.mjs' import type Token from 'markdown-it/lib/token.mjs'
import container from 'markdown-it-container'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import type { MarkdownEnv } from '../../shared'
import { import {
extractTitle, extractTitle,
getAdaptiveThemeMarker, getAdaptiveThemeMarker,
@ -60,7 +62,7 @@ function createContainer(
container, container,
klass, klass,
{ {
render(tokens, idx, _options, env) { render(tokens, idx, _options, env: MarkdownEnv & { references?: any }) {
const token = tokens[idx] const token = tokens[idx]
const info = token.info.trim().slice(klass.length).trim() const info = token.info.trim().slice(klass.length).trim()
const attrs = md.renderer.renderAttrs(token) const attrs = md.renderer.renderAttrs(token)

@ -85,7 +85,6 @@ export async function highlight(
{ {
name: 'vitepress:clean-up', name: 'vitepress:clean-up',
pre(node) { pre(node) {
delete node.properties.tabindex
delete node.properties.style delete node.properties.style
} }
} }

@ -1,11 +1,50 @@
import type MarkdownIt from 'markdown-it' import type MarkdownIt from 'markdown-it'
import type StateCore from 'markdown-it/lib/rules_core/state_core.mjs'
import type Token from 'markdown-it/lib/token.mjs'
import { escapeHtml } from '../../shared'
export function restoreEntities(md: MarkdownIt): void { export function restoreEntities(md: MarkdownIt): void {
md.core.ruler.disable('text_join') md.core.ruler.at('text_join', text_join)
md.renderer.rules.text_special = (tokens, idx) => { md.renderer.rules.text = (tokens, idx) => escapeHtml(tokens[idx].content)
if (tokens[idx].info === 'entity') {
return tokens[idx].markup // leave as is so Vue can handle it
} }
return md.utils.escapeHtml(tokens[idx].content)
function text_join(state: StateCore): void {
let curr, last
const blockTokens = state.tokens
const l = blockTokens.length
for (let j = 0; j < l; ++j) {
if (blockTokens[j].type !== 'inline') continue
const tokens = blockTokens[j].children || []
const max = tokens.length
for (curr = 0; curr < max; ++curr)
if (tokens[curr].type === 'text_special') tokens[curr].type = 'text'
for (curr = last = 0; curr < max; ++curr)
if (
tokens[curr].type === 'text' &&
curr + 1 < max &&
tokens[curr + 1].type === 'text'
) {
tokens[curr + 1].content =
getContent(tokens[curr]) + getContent(tokens[curr + 1])
tokens[curr + 1].info = ''
tokens[curr + 1].markup = ''
} else {
if (curr !== last) tokens[last] = tokens[curr]
++last
} }
if (curr !== last) tokens.length = last
}
}
function getContent(token: Token): string {
return token.info === 'entity'
? token.markup
: token.info === 'escape' && token.content === '&'
? '&amp;'
: token.content
} }

@ -11,11 +11,12 @@ import {
} from './markdown/markdown' } from './markdown/markdown'
import { import {
EXTERNAL_URL_RE, EXTERNAL_URL_RE,
getLocaleForPath,
slash, slash,
treatAsHtml,
type HeadConfig, type HeadConfig,
type MarkdownEnv, type MarkdownEnv,
type PageData, type PageData
treatAsHtml
} from './shared' } from './shared'
import { getGitTimestamp } from './utils/getGitTimestamp' import { getGitTimestamp } from './utils/getGitTimestamp'
import { processIncludes } from './utils/processIncludes' import { processIncludes } from './utils/processIncludes'
@ -95,13 +96,16 @@ export async function createMarkdownToVueRenderFn(
let includes: string[] = [] let includes: string[] = []
src = processIncludes(srcDir, src, fileOrig, includes) src = processIncludes(srcDir, src, fileOrig, includes)
const localeIndex = getLocaleForPath(siteConfig?.site, relativePath)
// reset env before render // reset env before render
const env: MarkdownEnv = { const env: MarkdownEnv = {
path: file, path: file,
relativePath, relativePath,
cleanUrls, cleanUrls,
includes, includes,
realPath: fileOrig realPath: fileOrig,
localeIndex
} }
const html = md.render(src, env) const html = md.render(src, env)
const { const {

@ -87,7 +87,7 @@ export async function createVitePressPlugin(
if (markdown?.math) { if (markdown?.math) {
isCustomElement = (tag) => { isCustomElement = (tag) => {
if (['mjx-container', 'mjx-assistive-mml'].includes(tag)) { if (tag.startsWith('mjx-')) {
return true return true
} }
return userCustomElementChecker?.(tag) ?? false return userCustomElementChecker?.(tag) ?? false

@ -7,7 +7,7 @@ import type { Plugin, ViteDevServer } from 'vite'
import type { SiteConfig } from '../config' import type { SiteConfig } from '../config'
import { createMarkdownRenderer } from '../markdown/markdown' import { createMarkdownRenderer } from '../markdown/markdown'
import { import {
resolveSiteDataByRoute, getLocaleForPath,
slash, slash,
type DefaultTheme, type DefaultTheme,
type MarkdownEnv type MarkdownEnv
@ -83,12 +83,6 @@ export async function localSearchPlugin(
return index return index
} }
function getLocaleForPath(file: string) {
const relativePath = slash(path.relative(siteConfig.srcDir, file))
const siteData = resolveSiteDataByRoute(siteConfig.site, relativePath)
return siteData?.localeIndex ?? 'root'
}
let server: ViteDevServer | undefined let server: ViteDevServer | undefined
function onIndexUpdated() { function onIndexUpdated() {
@ -126,7 +120,7 @@ export async function localSearchPlugin(
const file = path.join(siteConfig.srcDir, page) const file = path.join(siteConfig.srcDir, page)
// get file metadata // get file metadata
const fileId = getDocId(file) const fileId = getDocId(file)
const locale = getLocaleForPath(file) const locale = getLocaleForPath(siteConfig.site, page)
const index = getIndexByLocale(locale) const index = getIndexByLocale(locale)
// retrieve file and split into "sections" // retrieve file and split into "sections"
const html = await render(file) const html = await render(file)

@ -72,6 +72,20 @@ export function isExternal(path: string): boolean {
return EXTERNAL_URL_RE.test(path) return EXTERNAL_URL_RE.test(path)
} }
export function getLocaleForPath(
siteData: SiteData | undefined,
relativePath: string
): string {
return (
Object.keys(siteData?.locales || {}).find(
(key) =>
key !== 'root' &&
!isExternal(key) &&
isActive(relativePath, `/${key}/`, true)
) || 'root'
)
}
/** /**
* this merges the locales data to the main data by the route * this merges the locales data to the main data by the route
*/ */
@ -79,13 +93,7 @@ export function resolveSiteDataByRoute(
siteData: SiteData, siteData: SiteData,
relativePath: string relativePath: string
): SiteData { ): SiteData {
const localeIndex = const localeIndex = getLocaleForPath(siteData, relativePath)
Object.keys(siteData.locales).find(
(key) =>
key !== 'root' &&
!isExternal(key) &&
isActive(relativePath, `/${key}/`, true)
) || 'root'
return Object.assign({}, siteData, { return Object.assign({}, siteData, {
localeIndex, localeIndex,
@ -211,3 +219,14 @@ export function treatAsHtml(filename: string): boolean {
export function escapeRegExp(str: string) { export function escapeRegExp(str: string) {
return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d') return str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&').replace(/-/g, '\\x2d')
} }
/**
* @internal
*/
export function escapeHtml(str: string): string {
return str
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/&(?![\w#]+;)/g, '&amp;')
}

1
types/shared.d.ts vendored

@ -200,4 +200,5 @@ export interface MarkdownEnv {
links?: string[] links?: string[]
includes?: string[] includes?: string[]
realPath?: string realPath?: string
localeIndex?: string
} }

Loading…
Cancel
Save