zengen 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/pages.yml +7 -4
- package/.zen/meta.json +40 -118
- package/.zen/src/ar-SA/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/da-DK/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/de-DE/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/de-DE/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/de-DE/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/en-US/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/en-US/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/en-US/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/en-US/afbf4998656c97181d0edc711e388ad11e0f08f5c6f329861327202462a3a34a.md +63 -0
- package/.zen/src/es-ES/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/es-ES/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/es-ES/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/es-MX/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/fi-FI/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/fr-FR/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/fr-FR/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/fr-FR/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/hi-IN/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/id-ID/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/it-IT/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/ja-JP/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +71 -0
- package/.zen/src/ja-JP/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/ja-JP/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/ko-KR/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/ko-KR/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/nl-NL/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/no-NO/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/pl-PL/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/pt-BR/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/pt-PT/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/pt-PT/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/pt-PT/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/ru-RU/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/ru-RU/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/ru-RU/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/sv-SE/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/th-TH/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/tr-TR/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/uk-UA/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/vi-VN/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/zh-Hans/04319611d7cde718d0e82da8e034e04b15fb3bb37c3784d8f7313577c5178b06.md +73 -0
- package/.zen/src/zh-Hans/084ef1f6a0167df8621c673c79211309d4af6c588e7bbe3e043f7c244edd0ac6.md +80 -0
- package/.zen/src/zh-Hans/48eb2ad3e174cd06ed16c959fa58e0381dbc4a4147fa3456b21eea2b3d67c329.md +81 -0
- package/.zen/src/zh-Hans/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/.zen/src/zh-Hans/afbf4998656c97181d0edc711e388ad11e0f08f5c6f329861327202462a3a34a.md +63 -0
- package/.zen/src/zh-Hant/74541be9d53c64107a548e09847244d52bff803960942cd2bfbd2a8600afb805.md +71 -0
- package/README.md +30 -34
- package/assets/templates/default/layout.html +58 -3
- package/dist/ai/translateMarkdown.d.ts +1 -1
- package/dist/ai/translateMarkdown.d.ts.map +1 -1
- package/dist/ai/translateMarkdown.js +33 -2
- package/dist/ai/translateMarkdown.js.map +1 -1
- package/dist/languages.d.ts +2 -0
- package/dist/languages.d.ts.map +1 -0
- package/dist/languages.js +37 -0
- package/dist/languages.js.map +1 -0
- package/dist/process/template.js +11 -12
- package/dist/process/template.js.map +1 -1
- package/package.json +2 -2
- package/src/ai/translateMarkdown.ts +33 -2
- package/src/languages.ts +37 -0
- package/src/process/template.ts +12 -12
- package/docs/advanced-usage.md +0 -39
- package/docs/deployment/github-pages.md +0 -107
- package/docs/getting-started.md +0 -26
- package/docs/guides/best-practices.md +0 -175
- package/docs/guides/config.md +0 -48
- package/docs/guides/index.md +0 -51
- package/docs/testing/test-document.md +0 -1
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: ZEN - 極簡主義 Markdown + AI 靜態網站建構器
|
|
3
|
+
summary: ZEN 是一個結合 AI 的靜態網站生成器,支援智慧分類導航和自動增量翻譯,讓使用者專注於用母語寫作,簡化配置和建構過程。
|
|
4
|
+
tags:
|
|
5
|
+
- 靜態網站生成器
|
|
6
|
+
- Markdown
|
|
7
|
+
- AI
|
|
8
|
+
- 多語言翻譯
|
|
9
|
+
- 極簡主義
|
|
10
|
+
- 文件工具
|
|
11
|
+
- Node.js
|
|
12
|
+
inferred_lang: zh-Hant
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
# ZEN - 極簡主義 Markdown + AI 靜態網站建構器
|
|
16
|
+
|
|
17
|
+
[> 網站示範](https://zccz14.github.io/ZEN/)
|
|
18
|
+
|
|
19
|
+
## 基本功能
|
|
20
|
+
|
|
21
|
+
1. 📃 **靜態網站生成**:將任意一個包含 Markdown 的 git 資料夾建構成一個靜態 HTML 網站。
|
|
22
|
+
2. 🧭 **智慧分類導航**:使用 AI 進行內容分析,生成網站地圖和導航,原始檔案的位置不敏感。
|
|
23
|
+
3. 🌍 **自動增量翻譯**:使用 AI 進行增量翻譯,讓使用者使用母語編寫 Markdown,但是使用者可以是多語言的。
|
|
24
|
+
|
|
25
|
+
為什麼又搞了個 Markdown 靜態網站生成器?我重新思考了 AI 時代下,文件工具可以如何更好地服務於寫作者:
|
|
26
|
+
|
|
27
|
+
- 回歸內容:最小化打擾,專注寫作
|
|
28
|
+
|
|
29
|
+
讓文件回歸本質,讓寫作回歸寧靜。
|
|
30
|
+
|
|
31
|
+
其一,我不想做圖書管理員。我有時想寫下一些內容,但我可能還沒有想好它的標題,還沒有形成特別的組織。我希望 LLM 會自動幫我生成標題、做摘要、分類、導航等整理工作。
|
|
32
|
+
|
|
33
|
+
其二,我的書房必須打掃乾淨。我不想要配置複雜的建構工具,折騰複雜的文件配置,不喜歡複雜的結構。每次我看到 Docusaurus、VuePress、Astro 這些工具的配置檔案和專案結構,我就頭疼。現在,ZEN 選擇將所有的配置都隱藏到 .zen 目錄下,掃到角落裡,使用者只需要專注於寫作內容,其他的交給 ZEN 來處理。其他的目錄都是您的寫作空間,您可以隨意組織您的 Markdown 檔案。
|
|
34
|
+
|
|
35
|
+
- 回歸母語:用母語寫作,絲滑建構多語言版本
|
|
36
|
+
|
|
37
|
+
人生苦短,我懶得翻譯。人在使用母語時,才是最能發揮自身思考深度的。但同時與世界保持連接又是必要的,我不想放棄多語言的交流。於是我希望有一個工具,能讓我用母語寫作,同時又能讓更多人看到我的內容。現在的 i18n 需要自己翻譯不說,還得自己維護內容更新,太麻煩了。我選擇使用 LLM 來幫我做翻譯,省下了我很多時間,並且可以一鍵完成多國語言翻譯。
|
|
38
|
+
|
|
39
|
+
## 快速開始
|
|
40
|
+
|
|
41
|
+
前提:
|
|
42
|
+
|
|
43
|
+
- 已安裝 [Node.js](https://nodejs.org/)(建議版本 18 及以上,需要有 npx 命令)
|
|
44
|
+
- 已取得 [OpenAI API Key](https://platform.openai.com/account/api-keys),或者 OPENAI 相容的 API Key
|
|
45
|
+
- 已安裝 Git(用於從 Git 列出 Markdown 檔案,忽略 .gitignore 規則過濾的檔案)
|
|
46
|
+
|
|
47
|
+
首先,工作在一個已經被 git 管理的資料夾中:
|
|
48
|
+
|
|
49
|
+
配置環境變數
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
export OPENAI_API_KEY="sk-xxxxxx" # 必須:請替換為您的 OpenAI API Key
|
|
53
|
+
export OPENAI_BASE_URL="https://api.openai.com/v1" # 可選,預設使用 OpenAI 官方 API
|
|
54
|
+
export OPENAI_MODEL="gpt-3.5-turbo" # 可選,預設使用 gpt-3.5-turbo 模型
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
建構網站,支援多語言翻譯。使用當前目錄作為來源目錄,輸出到 `.zen/dist` 目錄。
|
|
58
|
+
|
|
59
|
+
- 可以透過多次使用 `--lang` 參數指定需要生成的語言版本(例如 `--lang zh-Hans --lang en-US`)。
|
|
60
|
+
- 可以透過 `--base-url` 參數指定網站的基礎 URL 前綴(例如 GitHub Pages 上的倉庫名)。
|
|
61
|
+
- 不需要配置來源語言,ZEN 會自動偵測。
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx zengen@latest build --lang zh-Hans --lang en-US
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**檢視更多參數或幫助**:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx zengen@latest
|
|
71
|
+
```
|
package/README.md
CHANGED
|
@@ -1,61 +1,57 @@
|
|
|
1
|
-
# ZEN -
|
|
1
|
+
# ZEN - 极简主义 Markdown + AI 静态站点构建器
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
[> Website Demo](https://zccz14.github.io/ZEN/)
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 基本功能
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
1. 📃 **静态站点生成**:将任意一个包含 Markdown 的 git 文件夹构建成一个静态 HTML 站点。
|
|
8
|
+
2. 🧭 **智能分类导航**:使用 AI 进行内容分析,生成站点地图和导航,源文件的位置不敏感。
|
|
9
|
+
3. 🌍 **自动增量翻译**:使用 AI 进行增量翻译,让用户使用母语编写 Markdown,但是用户可以是多语言的。
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
为什么又搞了个 Markdown 静态站点生成器?我重新思考了 AI 时代下,文档工具可以如何更好地服务于写作者:
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
- 回归内容:最小化打扰,专注写作
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
让文档回归本质,让写作回归宁静。
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
其一,我不想做图书管理员。我有时想写下一些内容,但我可能还没有想好它的标题,还没有形成特别的组织。我希望 LLM 会自动帮我生成标题、做摘要、分类、导航等整理工作。
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
- 将任意一个包含 Markdown 的文件夹构建成一个静态 HTML 站点
|
|
19
|
+
其二,我的书房必须打扫干净。我不想要配置复杂的构建工具,折腾复杂的文档配置,不喜欢复杂的结构。每次我看到 Docusaurus、VuePress、Astro 这些工具的配置文件和项目结构,我就头疼。现在,ZEN 选择将所有的配置都隐藏到 .zen 目录下,扫到角落里,用户只需要专注于写作内容,其他的交给 ZEN 来处理。其他的目录都是您的写作空间,您可以随意组织您的 Markdown 文件。
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
- 生成站点地图和导航,不需要保持原始的 Markdown 源文件的目录结构
|
|
21
|
+
- 回归母语:用母语写作,丝滑构建多语言版本
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- 使用 LLM 进行增量 i18n 翻译,让用户使用母语编写 Markdown,但是用户可以是多语言的
|
|
23
|
+
人生苦短,我懒得翻译。人在使用母语时,才是最能发挥自身思考深度的。但同时与世界保持连接又是必要的,我不想放弃多语言的交流。于是我希望有一个工具,能让我用母语写作,同时又能让更多人看到我的内容。现在的 i18n 需要自己翻译不说,还得自己维护内容更新,太麻烦了。我选择使用 LLM 来帮我做翻译,省下了我很多时间,并且可以一键完成多国语言翻译。
|
|
25
24
|
|
|
26
|
-
##
|
|
25
|
+
## 快速开始
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
- **内容优先**: 专注于写作,而不是工具配置
|
|
30
|
-
- **AI 赋能**: 利用 AI 处理翻译和内容组织
|
|
31
|
-
- **跨语言**: 支持多语言内容创作和展示
|
|
27
|
+
前提:
|
|
32
28
|
|
|
33
|
-
|
|
29
|
+
- 已安装 [Node.js](https://nodejs.org/)(建议版本 18 及以上,需要有 npx 命令)
|
|
30
|
+
- 已获取 [OpenAI API Key](https://platform.openai.com/account/api-keys),或者 OPENAI 兼容的 API Key
|
|
31
|
+
- 已安装 Git(用于从 Git 列出 Markdown 文件,忽略 .gitignore 规则过滤的文件)
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
首先,工作在一个已经被 git 管理的文件夹中:
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
配置环境变量
|
|
38
36
|
|
|
39
37
|
```bash
|
|
40
|
-
|
|
38
|
+
export OPENAI_API_KEY="sk-xxxxxx" # 必须:请替换为您的 OpenAI API Key
|
|
39
|
+
export OPENAI_BASE_URL="https://api.openai.com/v1" # 可选,默认使用 OpenAI 官方 API
|
|
40
|
+
export OPENAI_MODEL="gpt-3.5-turbo" # 可选,默认使用 gpt-3.5-turbo 模型
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
构建站点,支持多语言翻译。使用当前目录作为源目录,输出到 `.zen/dist` 目录。
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
- 可以通过多次使用 `--lang` 参数指定需要生成的语言版本(例如 `--lang zh-Hans --lang en-US`)。
|
|
46
|
+
- 可以通过 `--base-url` 参数指定站点的基础 URL 前缀(例如 GitHub Pages 上的仓库名)。
|
|
47
|
+
- 不需要配置源语言,ZEN 会自动检测。
|
|
46
48
|
|
|
47
49
|
```bash
|
|
48
|
-
npx zengen build --
|
|
50
|
+
npx zengen@latest build --lang zh-Hans --lang en-US
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
**查看更多参数或帮助**:
|
|
52
54
|
|
|
53
55
|
```bash
|
|
54
|
-
npx zengen
|
|
56
|
+
npx zengen@latest
|
|
55
57
|
```
|
|
56
|
-
|
|
57
|
-
**注意**:ZEN 强制使用当前目录作为源目录,输出到 `.zen/dist` 目录。不再支持指定源目录和输出目录参数。
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
**ZEN** - 让文档回归本质,让写作回归宁静。
|
|
@@ -84,6 +84,14 @@
|
|
|
84
84
|
margin-top: 0.25rem;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
blockquote {
|
|
88
|
+
border-left: 4px solid #007bff;
|
|
89
|
+
padding: 0.5rem 1rem;
|
|
90
|
+
margin: 1rem 0;
|
|
91
|
+
background: #f8f9fa;
|
|
92
|
+
color: #495057;
|
|
93
|
+
}
|
|
94
|
+
|
|
87
95
|
.content {
|
|
88
96
|
flex: 1;
|
|
89
97
|
margin-left: 280px;
|
|
@@ -217,6 +225,47 @@
|
|
|
217
225
|
text-align: center;
|
|
218
226
|
}
|
|
219
227
|
|
|
228
|
+
.language-switcher {
|
|
229
|
+
margin-top: 2rem;
|
|
230
|
+
text-align: center;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.lang-list {
|
|
234
|
+
list-style: none;
|
|
235
|
+
padding: 0;
|
|
236
|
+
/* display: flex; */
|
|
237
|
+
/* justify-content: center; */
|
|
238
|
+
/* flex-wrap: wrap; */
|
|
239
|
+
gap: 1rem;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.lang-item a {
|
|
243
|
+
color: #495057;
|
|
244
|
+
text-decoration: none;
|
|
245
|
+
font-weight: 500;
|
|
246
|
+
}
|
|
247
|
+
.lang-item.active a {
|
|
248
|
+
font-weight: 700;
|
|
249
|
+
color: #007bff;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.tags-list {
|
|
253
|
+
list-style: none;
|
|
254
|
+
padding: 0;
|
|
255
|
+
display: flex;
|
|
256
|
+
gap: 0.5rem;
|
|
257
|
+
margin-top: 0.5rem;
|
|
258
|
+
flex-wrap: wrap;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.tag-item {
|
|
262
|
+
background: #e9ecef;
|
|
263
|
+
color: #495057;
|
|
264
|
+
padding: 0.25rem 0.5rem;
|
|
265
|
+
border-radius: 4px;
|
|
266
|
+
font-size: 0.875rem;
|
|
267
|
+
}
|
|
268
|
+
|
|
220
269
|
@media (max-width: 768px) {
|
|
221
270
|
body {
|
|
222
271
|
flex-direction: column;
|
|
@@ -243,19 +292,25 @@
|
|
|
243
292
|
</head>
|
|
244
293
|
<body>
|
|
245
294
|
<nav class="sidebar">
|
|
246
|
-
<div class="sidebar-header">
|
|
295
|
+
<!-- <div class="sidebar-header">
|
|
247
296
|
<h1>ZEN Documentation</h1>
|
|
248
297
|
<p>A minimalist Markdown documentation site builder</p>
|
|
249
|
-
</div>
|
|
298
|
+
</div> -->
|
|
250
299
|
{{navigation}}
|
|
300
|
+
<hr />
|
|
251
301
|
<div>{{language_switcher}}</div>
|
|
252
302
|
</nav>
|
|
253
303
|
|
|
254
304
|
<main class="content">
|
|
255
305
|
<header class="content-header">
|
|
256
|
-
<
|
|
306
|
+
<h2>{{title}}</h2>
|
|
307
|
+
<blockquote>{{summary}}</blockquote>
|
|
308
|
+
<div>📅 {{inferred_date}}</div>
|
|
309
|
+
<div class="tags">{{tags}}</div>
|
|
257
310
|
</header>
|
|
258
311
|
|
|
312
|
+
<hr />
|
|
313
|
+
|
|
259
314
|
<article class="content-body">{{content}}</article>
|
|
260
315
|
|
|
261
316
|
<footer class="footer">
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translateMarkdown.d.ts","sourceRoot":"","sources":["../../src/ai/translateMarkdown.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"translateMarkdown.d.ts","sourceRoot":"","sources":["../../src/ai/translateMarkdown.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkD5F"}
|
|
@@ -1,18 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.translateMarkdown = translateMarkdown;
|
|
4
|
+
const languages_1 = require("../languages");
|
|
4
5
|
const openai_1 = require("../services/openai");
|
|
5
6
|
/**
|
|
6
|
-
|
|
7
|
+
|
|
7
8
|
* @param content Markdown 内容
|
|
8
9
|
* @param targetLang 目标语言代码(例如:zh-Hans, en-US)
|
|
9
10
|
* @returns Promise<string> 翻译后的 Markdown 内容
|
|
10
11
|
*/
|
|
11
12
|
async function translateMarkdown(content, targetLang) {
|
|
13
|
+
const langName = languages_1.LANGUAGE_NAMES[targetLang];
|
|
14
|
+
const lang = `${langName} (${targetLang})`;
|
|
12
15
|
const messages = [
|
|
13
16
|
{
|
|
14
17
|
role: 'system',
|
|
15
|
-
content:
|
|
18
|
+
content: [
|
|
19
|
+
`You are a professional document translator.`,
|
|
20
|
+
`Translate the following markdown content into ${lang}`,
|
|
21
|
+
targetLang === 'ja-JP'
|
|
22
|
+
? [
|
|
23
|
+
//
|
|
24
|
+
'使用日语母语者自然的表达方式。',
|
|
25
|
+
'采用适合技术/专业文档的礼貌、正式语体(丁寧体/です・ます体)',
|
|
26
|
+
'确保语法和字符集完全符合日语规范。',
|
|
27
|
+
'绝对禁止使用繁体中文汉字。',
|
|
28
|
+
'所有日语汉字必须使用标准的 **日本常用汉字(Jōyō kanji)** 字形。',
|
|
29
|
+
'特别检查以下字形示例,确保使用日文标准字形:',
|
|
30
|
+
'1. “国” - 使用“国”而非“國”',
|
|
31
|
+
'2. “学” - 使用“学”而非“學”',
|
|
32
|
+
'3. “広” - 使用“広”而非“廣”',
|
|
33
|
+
'4. “円” - 使用“円”而非“圓”',
|
|
34
|
+
'5. “医” - 使用“医”而非“醫”',
|
|
35
|
+
'6. “図” - 使用“図”而非“圖”',
|
|
36
|
+
'7. “対” - 使用“対”而非“對”',
|
|
37
|
+
'8. “声” - 使用“声”而非“聲”',
|
|
38
|
+
'9. “芸” - 使用“芸”而非“藝”',
|
|
39
|
+
'10. “験” - 使用“験”而非“驗”',
|
|
40
|
+
].join('\n')
|
|
41
|
+
: ``,
|
|
42
|
+
`Preserve the original markdown formatting, including headings, lists, code blocks, links, and images.`,
|
|
43
|
+
`Do not change any non-text elements or their formatting.`,
|
|
44
|
+
`Ensure that technical terms and code snippets remain unchanged.`,
|
|
45
|
+
`Provide a natural and fluent translation suitable for readers familiar with the subject matter.`,
|
|
46
|
+
].join('\n'),
|
|
16
47
|
},
|
|
17
48
|
{
|
|
18
49
|
role: 'user',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translateMarkdown.js","sourceRoot":"","sources":["../../src/ai/translateMarkdown.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"translateMarkdown.js","sourceRoot":"","sources":["../../src/ai/translateMarkdown.ts"],"names":[],"mappings":";;AASA,8CAkDC;AA3DD,4CAA8C;AAC9C,+CAAqE;AAErE;;;;;GAKG;AACI,KAAK,UAAU,iBAAiB,CAAC,OAAe,EAAE,UAAkB;IACzE,MAAM,QAAQ,GAAG,0BAAc,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,GAAG,QAAQ,KAAK,UAAU,GAAG,CAAC;IAC3C,MAAM,QAAQ,GAAoB;QAChC;YACE,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE;gBACP,6CAA6C;gBAC7C,iDAAiD,IAAI,EAAE;gBACvD,UAAU,KAAK,OAAO;oBACpB,CAAC,CAAC;wBACE,EAAE;wBACF,iBAAiB;wBACjB,iCAAiC;wBACjC,mBAAmB;wBACnB,eAAe;wBACf,0CAA0C;wBAC1C,wBAAwB;wBACxB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,qBAAqB;wBACrB,sBAAsB;qBACvB,CAAC,IAAI,CAAC,IAAI,CAAC;oBACd,CAAC,CAAC,EAAE;gBACN,uGAAuG;gBACvG,0DAA0D;gBAC1D,iEAAiE;gBACjE,iGAAiG;aAClG,CAAC,IAAI,CAAC,IAAI,CAAC;SACb;QACD;YACE,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,OAAO;SACjB;KACF,CAAC;IAEF,MAAM,QAAQ,GAAG,MAAM,IAAA,yBAAgB,EAAC,QAAQ,CAAC,CAAC;IAClD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAE9E,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,iBAAiB,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languages.d.ts","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAoCjD,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LANGUAGE_NAMES = void 0;
|
|
4
|
+
exports.LANGUAGE_NAMES = {
|
|
5
|
+
// 现有语言
|
|
6
|
+
'zh-Hans': '简体中文',
|
|
7
|
+
'en-US': 'English',
|
|
8
|
+
'ja-JP': '日本語',
|
|
9
|
+
'ko-KR': '한국어',
|
|
10
|
+
'es-ES': 'Español',
|
|
11
|
+
'fr-FR': 'Français',
|
|
12
|
+
'de-DE': 'Deutsch',
|
|
13
|
+
'ru-RU': 'Русский',
|
|
14
|
+
// 补充缺失的项目支持语言
|
|
15
|
+
'pt-PT': 'Português',
|
|
16
|
+
// 欧洲主要语言
|
|
17
|
+
'it-IT': 'Italiano',
|
|
18
|
+
'nl-NL': 'Nederlands',
|
|
19
|
+
'pl-PL': 'Polski',
|
|
20
|
+
'sv-SE': 'Svenska',
|
|
21
|
+
'fi-FI': 'Suomi',
|
|
22
|
+
'da-DK': 'Dansk',
|
|
23
|
+
'no-NO': 'Norsk',
|
|
24
|
+
// 亚洲主要语言
|
|
25
|
+
'zh-Hant': '繁體中文',
|
|
26
|
+
'hi-IN': 'हिन्दी',
|
|
27
|
+
'ar-SA': 'العربية',
|
|
28
|
+
'th-TH': 'ไทย',
|
|
29
|
+
'vi-VN': 'Tiếng Việt',
|
|
30
|
+
'id-ID': 'Bahasa Indonesia',
|
|
31
|
+
// 其他重要语言
|
|
32
|
+
'pt-BR': 'Português (Brasil)',
|
|
33
|
+
'es-MX': 'Español (México)',
|
|
34
|
+
'tr-TR': 'Türkçe',
|
|
35
|
+
'uk-UA': 'Українська',
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=languages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"languages.js","sourceRoot":"","sources":["../src/languages.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAA2B;IACpD,OAAO;IACP,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,UAAU;IACnB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAElB,cAAc;IACd,OAAO,EAAE,WAAW;IAEpB,SAAS;IACT,OAAO,EAAE,UAAU;IACnB,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,OAAO;IAChB,OAAO,EAAE,OAAO;IAEhB,SAAS;IACT,SAAS,EAAE,MAAM;IACjB,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,YAAY;IACrB,OAAO,EAAE,kBAAkB;IAE3B,SAAS;IACT,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,QAAQ;IACjB,OAAO,EAAE,YAAY;CACtB,CAAC"}
|
package/dist/process/template.js
CHANGED
|
@@ -36,16 +36,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.renderTemplates = renderTemplates;
|
|
37
37
|
const fs = __importStar(require("fs/promises"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
|
+
const languages_1 = require("../languages");
|
|
39
40
|
const metadata_1 = require("../metadata");
|
|
40
41
|
const paths_1 = require("../paths");
|
|
41
42
|
const convertMarkdownToHtml_1 = require("../utils/convertMarkdownToHtml");
|
|
42
43
|
const frontmatter_1 = require("../utils/frontmatter");
|
|
43
|
-
const langNames = {
|
|
44
|
-
'zh-Hans': '简体中文',
|
|
45
|
-
'en-US': 'English',
|
|
46
|
-
'ja-JP': '日本語',
|
|
47
|
-
'ko-KR': '한국어',
|
|
48
|
-
};
|
|
49
44
|
/**
|
|
50
45
|
* 生成语言切换器 HTML
|
|
51
46
|
* @param currentLang 当前语言
|
|
@@ -56,7 +51,7 @@ function generateLanguageSwitcher(templateData) {
|
|
|
56
51
|
const { options: { langs = [], baseUrl = '/' }, } = metadata_1.MetaData;
|
|
57
52
|
const items = langs
|
|
58
53
|
.map(lang => {
|
|
59
|
-
const langName =
|
|
54
|
+
const langName = languages_1.LANGUAGE_NAMES[lang] || lang;
|
|
60
55
|
const isCurrent = lang === templateData.lang;
|
|
61
56
|
const activeClass = isCurrent ? 'active' : '';
|
|
62
57
|
return `<li class="lang-item ${activeClass}">
|
|
@@ -65,10 +60,14 @@ function generateLanguageSwitcher(templateData) {
|
|
|
65
60
|
})
|
|
66
61
|
.join('');
|
|
67
62
|
return `<div class="language-switcher">
|
|
68
|
-
<span class="lang-label">Language:</span>
|
|
69
63
|
<ul class="lang-list">${items}</ul>
|
|
70
64
|
</div>`;
|
|
71
65
|
}
|
|
66
|
+
const generateTagsHtml = (tags) => {
|
|
67
|
+
return `<ul class="tags-list">${tags
|
|
68
|
+
.map(tag => `<li class="tag-item">${tag}</li>`)
|
|
69
|
+
.join('')}</ul>`;
|
|
70
|
+
};
|
|
72
71
|
/**
|
|
73
72
|
* 生成导航 HTML
|
|
74
73
|
* @param navigation 导航树
|
|
@@ -119,15 +118,15 @@ async function renderTemplate(template, data) {
|
|
|
119
118
|
// 替换元数据变量
|
|
120
119
|
if (frontmatter) {
|
|
121
120
|
result = result.replace(/{{summary}}/g, frontmatter.summary || '');
|
|
122
|
-
result = result.replace(/{{tags}}/g, frontmatter.tags
|
|
123
|
-
result = result.replace(/{{inferred_date}}/g, frontmatter.inferred_date || '');
|
|
124
|
-
result = result.replace(/{{inferred_lang}}/g, frontmatter.inferred_lang || '');
|
|
121
|
+
result = result.replace(/{{tags}}/g, generateTagsHtml(frontmatter.tags || []));
|
|
122
|
+
result = result.replace(/{{inferred_date}}/g, frontmatter.inferred_date || '--');
|
|
123
|
+
result = result.replace(/{{inferred_lang}}/g, frontmatter.inferred_lang || '--');
|
|
125
124
|
}
|
|
126
125
|
// 替换语言相关变量
|
|
127
126
|
result = result.replace(/{{lang}}/g, data.lang || '');
|
|
128
127
|
if (langs && langs.length > 1 && data.lang) {
|
|
129
128
|
const langSwitcher = generateLanguageSwitcher(data);
|
|
130
|
-
result = result.replace(
|
|
129
|
+
result = result.replace(/{{language_switcher}}/g, langSwitcher);
|
|
131
130
|
}
|
|
132
131
|
return result;
|
|
133
132
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/process/template.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiKA,0CAuCC;AAxMD,gDAAkC;AAClC,2CAA6B;AAC7B,0CAAuC;AACvC,oCAAqD;AAErD,0EAAuE;AACvE,sDAAwD;AAExD
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/process/template.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zengen",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "ZEN - A minimalist Markdown documentation site builder",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "npx rimraf dist && tsc",
|
|
12
12
|
"dev": "ts-node src/cli.ts",
|
|
13
|
-
"build:doc": "npm run build && node dist/cli.js build --lang zh-Hans --lang en-US --verbose",
|
|
13
|
+
"build:doc": "npm run build && node dist/cli.js build --base-url /ZEN --lang zh-Hans --lang en-US --lang ja-JP --lang ko-KR --lang es-ES --lang fr-FR --lang de-DE --lang ru-RU --lang pt-PT --lang it-IT --lang nl-NL --lang pl-PL --lang sv-SE --lang fi-FI --lang da-DK --lang no-NO --lang zh-Hant --lang hi-IN --lang ar-SA --lang th-TH --lang vi-VN --lang id-ID --lang pt-BR --lang es-MX --lang tr-TR --lang uk-UA --verbose",
|
|
14
14
|
"test": "npm run build && node --test dist/**/*.test.js",
|
|
15
15
|
"test:types": "tsc --noEmit",
|
|
16
16
|
"test:build": "npm run build && test -f dist/index.js && test -f dist/cli.js",
|
|
@@ -1,16 +1,47 @@
|
|
|
1
|
+
import { LANGUAGE_NAMES } from '../languages';
|
|
1
2
|
import { completeMessages, OpenAIMessage } from '../services/openai';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
|
-
|
|
5
|
+
|
|
5
6
|
* @param content Markdown 内容
|
|
6
7
|
* @param targetLang 目标语言代码(例如:zh-Hans, en-US)
|
|
7
8
|
* @returns Promise<string> 翻译后的 Markdown 内容
|
|
8
9
|
*/
|
|
9
10
|
export async function translateMarkdown(content: string, targetLang: string): Promise<string> {
|
|
11
|
+
const langName = LANGUAGE_NAMES[targetLang];
|
|
12
|
+
const lang = `${langName} (${targetLang})`;
|
|
10
13
|
const messages: OpenAIMessage[] = [
|
|
11
14
|
{
|
|
12
15
|
role: 'system',
|
|
13
|
-
content:
|
|
16
|
+
content: [
|
|
17
|
+
`You are a professional document translator.`,
|
|
18
|
+
`Translate the following markdown content into ${lang}`,
|
|
19
|
+
targetLang === 'ja-JP'
|
|
20
|
+
? [
|
|
21
|
+
//
|
|
22
|
+
'使用日语母语者自然的表达方式。',
|
|
23
|
+
'采用适合技术/专业文档的礼貌、正式语体(丁寧体/です・ます体)',
|
|
24
|
+
'确保语法和字符集完全符合日语规范。',
|
|
25
|
+
'绝对禁止使用繁体中文汉字。',
|
|
26
|
+
'所有日语汉字必须使用标准的 **日本常用汉字(Jōyō kanji)** 字形。',
|
|
27
|
+
'特别检查以下字形示例,确保使用日文标准字形:',
|
|
28
|
+
'1. “国” - 使用“国”而非“國”',
|
|
29
|
+
'2. “学” - 使用“学”而非“學”',
|
|
30
|
+
'3. “広” - 使用“広”而非“廣”',
|
|
31
|
+
'4. “円” - 使用“円”而非“圓”',
|
|
32
|
+
'5. “医” - 使用“医”而非“醫”',
|
|
33
|
+
'6. “図” - 使用“図”而非“圖”',
|
|
34
|
+
'7. “対” - 使用“対”而非“對”',
|
|
35
|
+
'8. “声” - 使用“声”而非“聲”',
|
|
36
|
+
'9. “芸” - 使用“芸”而非“藝”',
|
|
37
|
+
'10. “験” - 使用“験”而非“驗”',
|
|
38
|
+
].join('\n')
|
|
39
|
+
: ``,
|
|
40
|
+
`Preserve the original markdown formatting, including headings, lists, code blocks, links, and images.`,
|
|
41
|
+
`Do not change any non-text elements or their formatting.`,
|
|
42
|
+
`Ensure that technical terms and code snippets remain unchanged.`,
|
|
43
|
+
`Provide a natural and fluent translation suitable for readers familiar with the subject matter.`,
|
|
44
|
+
].join('\n'),
|
|
14
45
|
},
|
|
15
46
|
{
|
|
16
47
|
role: 'user',
|
package/src/languages.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const LANGUAGE_NAMES: Record<string, string> = {
|
|
2
|
+
// 现有语言
|
|
3
|
+
'zh-Hans': '简体中文',
|
|
4
|
+
'en-US': 'English',
|
|
5
|
+
'ja-JP': '日本語',
|
|
6
|
+
'ko-KR': '한국어',
|
|
7
|
+
'es-ES': 'Español',
|
|
8
|
+
'fr-FR': 'Français',
|
|
9
|
+
'de-DE': 'Deutsch',
|
|
10
|
+
'ru-RU': 'Русский',
|
|
11
|
+
|
|
12
|
+
// 补充缺失的项目支持语言
|
|
13
|
+
'pt-PT': 'Português',
|
|
14
|
+
|
|
15
|
+
// 欧洲主要语言
|
|
16
|
+
'it-IT': 'Italiano',
|
|
17
|
+
'nl-NL': 'Nederlands',
|
|
18
|
+
'pl-PL': 'Polski',
|
|
19
|
+
'sv-SE': 'Svenska',
|
|
20
|
+
'fi-FI': 'Suomi',
|
|
21
|
+
'da-DK': 'Dansk',
|
|
22
|
+
'no-NO': 'Norsk',
|
|
23
|
+
|
|
24
|
+
// 亚洲主要语言
|
|
25
|
+
'zh-Hant': '繁體中文',
|
|
26
|
+
'hi-IN': 'हिन्दी',
|
|
27
|
+
'ar-SA': 'العربية',
|
|
28
|
+
'th-TH': 'ไทย',
|
|
29
|
+
'vi-VN': 'Tiếng Việt',
|
|
30
|
+
'id-ID': 'Bahasa Indonesia',
|
|
31
|
+
|
|
32
|
+
// 其他重要语言
|
|
33
|
+
'pt-BR': 'Português (Brasil)',
|
|
34
|
+
'es-MX': 'Español (México)',
|
|
35
|
+
'tr-TR': 'Türkçe',
|
|
36
|
+
'uk-UA': 'Українська',
|
|
37
|
+
};
|
package/src/process/template.ts
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import * as fs from 'fs/promises';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { LANGUAGE_NAMES } from '../languages';
|
|
3
4
|
import { MetaData } from '../metadata';
|
|
4
5
|
import { ZEN_DIST_DIR, ZEN_SRC_DIR } from '../paths';
|
|
5
6
|
import { MetaDataStore } from '../types';
|
|
6
7
|
import { convertMarkdownToHtml } from '../utils/convertMarkdownToHtml';
|
|
7
8
|
import { parseFrontmatter } from '../utils/frontmatter';
|
|
8
9
|
|
|
9
|
-
const langNames: Record<string, string> = {
|
|
10
|
-
'zh-Hans': '简体中文',
|
|
11
|
-
'en-US': 'English',
|
|
12
|
-
'ja-JP': '日本語',
|
|
13
|
-
'ko-KR': '한국어',
|
|
14
|
-
};
|
|
15
10
|
/**
|
|
16
11
|
* 生成语言切换器 HTML
|
|
17
12
|
* @param currentLang 当前语言
|
|
@@ -25,7 +20,7 @@ function generateLanguageSwitcher(templateData: TemplateData): string {
|
|
|
25
20
|
|
|
26
21
|
const items = langs
|
|
27
22
|
.map(lang => {
|
|
28
|
-
const langName =
|
|
23
|
+
const langName = LANGUAGE_NAMES[lang] || lang;
|
|
29
24
|
const isCurrent = lang === templateData.lang;
|
|
30
25
|
const activeClass = isCurrent ? 'active' : '';
|
|
31
26
|
|
|
@@ -36,11 +31,16 @@ function generateLanguageSwitcher(templateData: TemplateData): string {
|
|
|
36
31
|
.join('');
|
|
37
32
|
|
|
38
33
|
return `<div class="language-switcher">
|
|
39
|
-
<span class="lang-label">Language:</span>
|
|
40
34
|
<ul class="lang-list">${items}</ul>
|
|
41
35
|
</div>`;
|
|
42
36
|
}
|
|
43
37
|
|
|
38
|
+
const generateTagsHtml = (tags: string[]): string => {
|
|
39
|
+
return `<ul class="tags-list">${tags
|
|
40
|
+
.map(tag => `<li class="tag-item">${tag}</li>`)
|
|
41
|
+
.join('')}</ul>`;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
44
|
/**
|
|
45
45
|
* 生成导航 HTML
|
|
46
46
|
* @param navigation 导航树
|
|
@@ -118,16 +118,16 @@ async function renderTemplate(template: string, data: TemplateData): Promise<str
|
|
|
118
118
|
// 替换元数据变量
|
|
119
119
|
if (frontmatter) {
|
|
120
120
|
result = result.replace(/{{summary}}/g, frontmatter.summary || '');
|
|
121
|
-
result = result.replace(/{{tags}}/g, frontmatter.tags
|
|
122
|
-
result = result.replace(/{{inferred_date}}/g, frontmatter.inferred_date || '');
|
|
123
|
-
result = result.replace(/{{inferred_lang}}/g, frontmatter.inferred_lang || '');
|
|
121
|
+
result = result.replace(/{{tags}}/g, generateTagsHtml(frontmatter.tags || []));
|
|
122
|
+
result = result.replace(/{{inferred_date}}/g, frontmatter.inferred_date || '--');
|
|
123
|
+
result = result.replace(/{{inferred_lang}}/g, frontmatter.inferred_lang || '--');
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
// 替换语言相关变量
|
|
127
127
|
result = result.replace(/{{lang}}/g, data.lang || '');
|
|
128
128
|
if (langs && langs.length > 1 && data.lang) {
|
|
129
129
|
const langSwitcher = generateLanguageSwitcher(data);
|
|
130
|
-
result = result.replace(
|
|
130
|
+
result = result.replace(/{{language_switcher}}/g, langSwitcher);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
return result;
|