zengen 0.1.35 → 0.2.0
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/bump-version.yml +112 -0
- package/.github/workflows/ci.yml +2 -2
- package/.github/workflows/pages.yml +1 -7
- package/.zen/meta.json +155 -0
- package/.zen/src/en-US/01d04f7c17b4a541ead9d759d877b30b403e15b849182a49eb1f62bd29ecd18c.md +120 -0
- package/.zen/src/en-US/1b798c44a4f353e47296ca83d5905e37e6aba3e90bbd9bc3b3d34fc12059a2ca.md +75 -0
- package/.zen/src/en-US/1e96be58d76c60056b708eb5bd8b8b81d7b5845d9cfe0b879d85068a5f11df3a.md +189 -0
- package/.zen/src/en-US/5ec990146b35e00de2630559126ee07f7cdcddeb23b0e8cab3d85b4181353e26.md +53 -0
- package/.zen/src/en-US/6124ea88edec5bde737b26b21f71ecfeffe4e73151784856edf813ee231a4baa.md +11 -0
- package/.zen/src/en-US/80ae9bed74fc6348a7c1fe9f33e86b65f5d919169721f77bcf0e1bc29fbdb4f9.md +61 -0
- package/.zen/src/en-US/f0c2799126931ccd113a0c45b1e623870b0d4f4f400becf6dd877da8f1011517.md +41 -0
- package/.zen/src/en-US/fdfca9b960d0eaa8b2b96fe988ead7481d2c0b16f66ebc94fb477139b4178cdc.md +65 -0
- package/.zen/src/zh-Hans/01d04f7c17b4a541ead9d759d877b30b403e15b849182a49eb1f62bd29ecd18c.md +120 -0
- package/.zen/src/zh-Hans/1b798c44a4f353e47296ca83d5905e37e6aba3e90bbd9bc3b3d34fc12059a2ca.md +77 -0
- package/.zen/src/zh-Hans/1e96be58d76c60056b708eb5bd8b8b81d7b5845d9cfe0b879d85068a5f11df3a.md +189 -0
- package/.zen/src/zh-Hans/5ec990146b35e00de2630559126ee07f7cdcddeb23b0e8cab3d85b4181353e26.md +55 -0
- package/.zen/src/zh-Hans/6124ea88edec5bde737b26b21f71ecfeffe4e73151784856edf813ee231a4baa.md +1 -0
- package/.zen/src/zh-Hans/6ad8db715a1b60613fe934fefb29fa981ecad9b63145593accff144d73b44bde.md +175 -0
- package/.zen/src/zh-Hans/80ae9bed74fc6348a7c1fe9f33e86b65f5d919169721f77bcf0e1bc29fbdb4f9.md +63 -0
- package/.zen/src/zh-Hans/a1580f71c6c6c1ff4a314be72d410a8507af2f087d56360c7f5048d349c21953.md +48 -0
- package/.zen/src/zh-Hans/d49012f98c4367b34034063400e2f7826bf0615952210c82396920172d468e2c.md +107 -0
- package/.zen/src/zh-Hans/f0c2799126931ccd113a0c45b1e623870b0d4f4f400becf6dd877da8f1011517.md +41 -0
- package/.zen/src/zh-Hans/fdfca9b960d0eaa8b2b96fe988ead7481d2c0b16f66ebc94fb477139b4178cdc.md +65 -0
- package/assets/templates/default/layout.html +274 -0
- package/dist/ai/extractMetadataFromMarkdown.d.ts +8 -0
- package/dist/ai/extractMetadataFromMarkdown.d.ts.map +1 -0
- package/dist/ai/extractMetadataFromMarkdown.js +88 -0
- package/dist/ai/extractMetadataFromMarkdown.js.map +1 -0
- package/dist/ai/translateMarkdown.d.ts +8 -0
- package/dist/ai/translateMarkdown.d.ts.map +1 -0
- package/dist/ai/translateMarkdown.js +29 -0
- package/dist/ai/translateMarkdown.js.map +1 -0
- package/dist/build/pipeline.d.ts +6 -0
- package/dist/build/pipeline.d.ts.map +1 -0
- package/dist/build/pipeline.js +218 -0
- package/dist/build/pipeline.js.map +1 -0
- package/dist/cli.js +17 -83
- package/dist/cli.js.map +1 -1
- package/dist/findEntries.d.ts +10 -0
- package/dist/findEntries.d.ts.map +1 -0
- package/dist/findEntries.js +38 -0
- package/dist/findEntries.js.map +1 -0
- package/dist/index.d.ts +1 -32
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -35
- package/dist/index.js.map +1 -1
- package/dist/metadata.d.ts +14 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +78 -0
- package/dist/metadata.js.map +1 -0
- package/dist/paths.d.ts +6 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +10 -0
- package/dist/paths.js.map +1 -0
- package/dist/process/extractMetadataByAI.d.ts +5 -0
- package/dist/process/extractMetadataByAI.d.ts.map +1 -0
- package/dist/process/extractMetadataByAI.js +31 -0
- package/dist/process/extractMetadataByAI.js.map +1 -0
- package/dist/process/template.d.ts +5 -0
- package/dist/process/template.d.ts.map +1 -0
- package/dist/process/template.js +188 -0
- package/dist/process/template.js.map +1 -0
- package/dist/scan/files.d.ts +7 -0
- package/dist/scan/files.d.ts.map +1 -0
- package/dist/scan/files.js +54 -0
- package/dist/scan/files.js.map +1 -0
- package/dist/services/openai.d.ts +41 -0
- package/dist/services/openai.d.ts.map +1 -0
- package/dist/services/openai.js +54 -0
- package/dist/services/openai.js.map +1 -0
- package/dist/types.d.ts +26 -46
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/convertMarkdownToHtml.d.ts +7 -0
- package/dist/utils/convertMarkdownToHtml.d.ts.map +1 -0
- package/dist/utils/convertMarkdownToHtml.js +39 -0
- package/dist/utils/convertMarkdownToHtml.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +6 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +22 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/docs/advanced-usage.md +39 -0
- package/docs/deployment/github-pages.md +1 -2
- package/docs/getting-started.md +26 -0
- package/docs/guides/best-practices.md +4 -117
- package/docs/guides/config.md +0 -238
- package/package.json +5 -2
- package/src/ai/extractMetadataFromMarkdown.ts +95 -0
- package/src/ai/translateMarkdown.ts +29 -0
- package/src/build/pipeline.ts +211 -0
- package/src/cli.ts +18 -94
- package/src/findEntries.ts +37 -0
- package/src/index.ts +1 -40
- package/src/metadata.ts +44 -0
- package/src/paths.ts +7 -0
- package/src/process/extractMetadataByAI.ts +29 -0
- package/src/process/template.ts +201 -0
- package/src/scan/files.ts +17 -0
- package/src/services/openai.ts +92 -0
- package/src/types.ts +29 -47
- package/src/utils/convertMarkdownToHtml.ts +32 -0
- package/src/utils/frontmatter.ts +18 -0
- package/test-multilang.js +44 -0
- package/dist/builder.d.ts +0 -46
- package/dist/builder.d.ts.map +0 -1
- package/dist/builder.js +0 -443
- package/dist/builder.js.map +0 -1
- package/dist/gitignore.d.ts +0 -40
- package/dist/gitignore.d.ts.map +0 -1
- package/dist/gitignore.js +0 -184
- package/dist/gitignore.js.map +0 -1
- package/dist/gitignore.test.d.ts +0 -2
- package/dist/gitignore.test.d.ts.map +0 -1
- package/dist/gitignore.test.js +0 -244
- package/dist/gitignore.test.js.map +0 -1
- package/dist/markdown.d.ts +0 -30
- package/dist/markdown.d.ts.map +0 -1
- package/dist/markdown.js +0 -199
- package/dist/markdown.js.map +0 -1
- package/dist/navigation.d.ts +0 -46
- package/dist/navigation.d.ts.map +0 -1
- package/dist/navigation.js +0 -196
- package/dist/navigation.js.map +0 -1
- package/dist/template.d.ts +0 -29
- package/dist/template.d.ts.map +0 -1
- package/dist/template.js +0 -385
- package/dist/template.js.map +0 -1
- package/docs/ci/github-ci-cd.md +0 -127
- package/docs/guides/api.md +0 -277
- package/src/builder.ts +0 -458
- package/src/gitignore.test.ts +0 -253
- package/src/gitignore.ts +0 -173
- package/src/markdown.ts +0 -184
- package/src/navigation.ts +0 -237
- package/src/template.ts +0 -365
|
@@ -2,95 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
本文档介绍使用 ZEN 构建文档站点的最佳实践。
|
|
4
4
|
|
|
5
|
-
## 文件组织
|
|
6
|
-
|
|
7
|
-
### 推荐的文件结构
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
project/
|
|
11
|
-
├── docs/ # 文档源文件
|
|
12
|
-
│ ├── index.md # 首页
|
|
13
|
-
│ ├── getting-started.md # 入门指南
|
|
14
|
-
│ ├── api/ # API 文档目录
|
|
15
|
-
│ │ ├── overview.md
|
|
16
|
-
│ │ ├── core-api.md
|
|
17
|
-
│ │ └── plugins.md
|
|
18
|
-
│ ├── guides/ # 指南目录
|
|
19
|
-
│ │ ├── installation.md
|
|
20
|
-
│ │ └── configuration.md
|
|
21
|
-
│ └── resources/ # 资源文件
|
|
22
|
-
│ └── images/
|
|
23
|
-
└── package.json
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**注意**: ZEN 强制使用当前目录作为源目录,所以应该切换到 `docs/` 目录下运行构建命令:
|
|
27
|
-
|
|
28
|
-
```bash
|
|
29
|
-
cd docs
|
|
30
|
-
npx zengen build
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### 命名约定
|
|
34
|
-
|
|
35
|
-
- 使用小写字母和连字符:`getting-started.md`
|
|
36
|
-
- 避免特殊字符和空格
|
|
37
|
-
- 主要页面使用简短名称:`index.md`, `api.md`
|
|
38
|
-
- 分类页面使用目录组织
|
|
39
|
-
|
|
40
|
-
## 写作规范
|
|
41
|
-
|
|
42
|
-
### Markdown 语法
|
|
43
|
-
|
|
44
|
-
**推荐:**
|
|
45
|
-
|
|
46
|
-
````markdown
|
|
47
|
-
# 一级标题
|
|
48
|
-
|
|
49
|
-
## 二级标题
|
|
50
|
-
|
|
51
|
-
### 三级标题
|
|
52
|
-
|
|
53
|
-
使用 **粗体** 和 _斜体_ 强调重要内容。
|
|
54
|
-
|
|
55
|
-
- 列表项 1
|
|
56
|
-
- 列表项 2
|
|
57
|
-
- 子列表项
|
|
58
|
-
|
|
59
|
-
1. 有序列表项 1
|
|
60
|
-
2. 有序列表项 2
|
|
61
|
-
|
|
62
|
-
> 引用重要的说明或提示。
|
|
63
|
-
|
|
64
|
-
`行内代码` 用于技术术语。
|
|
65
|
-
|
|
66
|
-
```javascript
|
|
67
|
-
// 代码块示例
|
|
68
|
-
console.log('Hello ZEN!');
|
|
69
|
-
```
|
|
70
|
-
````
|
|
71
|
-
|
|
72
|
-
````
|
|
73
|
-
|
|
74
|
-
**避免:**
|
|
75
|
-
- 过多的标题层级(超过 4 级)
|
|
76
|
-
- 复杂的表格(考虑使用简单列表替代)
|
|
77
|
-
- 过长的行(建议 80-100 字符换行)
|
|
78
|
-
|
|
79
|
-
### 元数据使用
|
|
80
|
-
|
|
81
|
-
在每个 Markdown 文件顶部添加 frontmatter:
|
|
82
|
-
|
|
83
|
-
```yaml
|
|
84
|
-
---
|
|
85
|
-
title: 页面标题
|
|
86
|
-
description: 简洁的页面描述
|
|
87
|
-
keywords: [关键词1, 关键词2]
|
|
88
|
-
author: 作者名
|
|
89
|
-
date: 2024-01-01
|
|
90
|
-
last_modified: 2024-01-15
|
|
91
|
-
---
|
|
92
|
-
````
|
|
93
|
-
|
|
94
5
|
## 多语言管理
|
|
95
6
|
|
|
96
7
|
### 翻译策略
|
|
@@ -100,30 +11,6 @@ last_modified: 2024-01-15
|
|
|
100
11
|
3. **术语一致**: 建立术语表保持翻译一致性
|
|
101
12
|
4. **人工校对**: AI 翻译后建议人工校对
|
|
102
13
|
|
|
103
|
-
### 翻译文件管理
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
docs/
|
|
107
|
-
├── index.zh-CN.md # 中文源文件
|
|
108
|
-
├── index.en-US.md # 英文翻译
|
|
109
|
-
├── api/
|
|
110
|
-
│ ├── overview.zh-CN.md
|
|
111
|
-
│ └── overview.en-US.md
|
|
112
|
-
└── glossary.json # 术语表
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### 配置示例
|
|
116
|
-
|
|
117
|
-
```json
|
|
118
|
-
{
|
|
119
|
-
"i18n": {
|
|
120
|
-
"sourceLang": "zh-CN",
|
|
121
|
-
"targetLangs": ["en-US", "ja-JP"],
|
|
122
|
-
"apiKey": "your-openai-api-key"
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
```
|
|
126
|
-
|
|
127
14
|
## 性能优化
|
|
128
15
|
|
|
129
16
|
### 构建优化
|
|
@@ -143,7 +30,7 @@ npx zengen build --watch
|
|
|
143
30
|
npx zengen build --watch --serve
|
|
144
31
|
|
|
145
32
|
# 生产构建
|
|
146
|
-
npx zengen build
|
|
33
|
+
npx zengen build
|
|
147
34
|
```
|
|
148
35
|
|
|
149
36
|
## 部署策略
|
|
@@ -176,7 +63,7 @@ jobs:
|
|
|
176
63
|
- name: Build documentation
|
|
177
64
|
run: |
|
|
178
65
|
cd docs
|
|
179
|
-
npx zengen build --
|
|
66
|
+
npx zengen build --base-url /my-docs
|
|
180
67
|
|
|
181
68
|
- name: Deploy to GitHub Pages
|
|
182
69
|
uses: peaceiris/actions-gh-pages@v3
|
|
@@ -194,8 +81,8 @@ jobs:
|
|
|
194
81
|
# 切换到文档目录
|
|
195
82
|
cd docs
|
|
196
83
|
|
|
197
|
-
#
|
|
198
|
-
npx zengen build
|
|
84
|
+
# 构建文档
|
|
85
|
+
npx zengen build
|
|
199
86
|
|
|
200
87
|
# 同步到服务器
|
|
201
88
|
rsync -avz .zen/dist/ user@server:/var/www/docs/
|
package/docs/guides/config.md
CHANGED
|
@@ -19,12 +19,6 @@ npx zengen build --watch --serve
|
|
|
19
19
|
# 自定义端口
|
|
20
20
|
npx zengen build --watch --serve --port 8080
|
|
21
21
|
|
|
22
|
-
# 使用配置文件
|
|
23
|
-
npx zengen build --config zen.config.json
|
|
24
|
-
|
|
25
|
-
# 清理输出目录
|
|
26
|
-
npx zengen build --clean
|
|
27
|
-
|
|
28
22
|
# 显示详细日志
|
|
29
23
|
npx zengen build --verbose
|
|
30
24
|
|
|
@@ -49,238 +43,6 @@ npx zengen
|
|
|
49
43
|
| `--serve` | `-s` | 启动开发服务器(需要 `--watch`) | `false` |
|
|
50
44
|
| `--port` | `-p` | 开发服务器端口 | `3000` |
|
|
51
45
|
| `--host` | | 开发服务器主机 | `localhost` |
|
|
52
|
-
| `--template` | `-t` | 自定义模板文件路径 | 内置模板 |
|
|
53
|
-
| `--config` | `-c` | 配置文件路径 | 无 |
|
|
54
46
|
| `--verbose` | `-v` | 显示详细日志 | `false` |
|
|
55
|
-
| `--clean` | | 清理输出目录 | `false` |
|
|
56
47
|
| `--base-url` | | 站点基础 URL | 无 |
|
|
57
48
|
| `--help` | `-h` | 显示帮助信息 | 无 |
|
|
58
|
-
|
|
59
|
-
## 配置文件
|
|
60
|
-
|
|
61
|
-
### 配置文件格式
|
|
62
|
-
|
|
63
|
-
在项目根目录创建 `zen.config.json` 文件:
|
|
64
|
-
|
|
65
|
-
```json
|
|
66
|
-
{
|
|
67
|
-
"template": "./custom-template.html",
|
|
68
|
-
"baseUrl": "/my-docs",
|
|
69
|
-
"i18n": {
|
|
70
|
-
"sourceLang": "zh-CN",
|
|
71
|
-
"targetLangs": ["en-US", "ja-JP"],
|
|
72
|
-
"apiKey": "your-openai-api-key"
|
|
73
|
-
},
|
|
74
|
-
"includePattern": "**/*.md",
|
|
75
|
-
"excludePattern": "**/_*.md"
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
### 配置项说明
|
|
80
|
-
|
|
81
|
-
#### `template`
|
|
82
|
-
|
|
83
|
-
- **类型**: `string`
|
|
84
|
-
- **描述**: 自定义模板文件路径
|
|
85
|
-
- **示例**: `"./templates/custom.html"`
|
|
86
|
-
|
|
87
|
-
#### `baseUrl`
|
|
88
|
-
|
|
89
|
-
- **类型**: `string`
|
|
90
|
-
- **描述**: 站点基础 URL,用于生成绝对路径
|
|
91
|
-
- **示例**: `"/docs"`, `"/my-project"`
|
|
92
|
-
|
|
93
|
-
#### `i18n`
|
|
94
|
-
|
|
95
|
-
- **类型**: `object`
|
|
96
|
-
- **描述**: 多语言翻译配置
|
|
97
|
-
- **字段**:
|
|
98
|
-
- `sourceLang`: 源语言代码(如 `"zh-CN"`)
|
|
99
|
-
- `targetLangs`: 目标语言代码数组(如 `["en-US", "ja-JP"]`)
|
|
100
|
-
- `apiKey`: OpenAI API 密钥(可选,从环境变量读取)
|
|
101
|
-
|
|
102
|
-
#### `includePattern`
|
|
103
|
-
|
|
104
|
-
- **类型**: `string`
|
|
105
|
-
- **描述**: 包含的文件模式(glob 语法)
|
|
106
|
-
- **默认**: `"**/*.md"`
|
|
107
|
-
- **示例**: `"**/*.{md,markdown}"`
|
|
108
|
-
|
|
109
|
-
#### `excludePattern`
|
|
110
|
-
|
|
111
|
-
- **类型**: `string`
|
|
112
|
-
- **描述**: 排除的文件模式(glob 语法)
|
|
113
|
-
- **默认**: 无
|
|
114
|
-
- **示例**: `"**/_*.md"`, `"**/node_modules/**"`
|
|
115
|
-
|
|
116
|
-
## 模板配置
|
|
117
|
-
|
|
118
|
-
### 默认模板
|
|
119
|
-
|
|
120
|
-
ZEN 使用内置的极简模板,包含:
|
|
121
|
-
|
|
122
|
-
- 响应式布局
|
|
123
|
-
- 代码高亮(使用 highlight.js)
|
|
124
|
-
- 导航菜单
|
|
125
|
-
- 深色/浅色主题切换
|
|
126
|
-
|
|
127
|
-
### 自定义模板
|
|
128
|
-
|
|
129
|
-
创建自定义模板文件 `custom-template.html`:
|
|
130
|
-
|
|
131
|
-
```html
|
|
132
|
-
<!DOCTYPE html>
|
|
133
|
-
<html lang="zh-CN">
|
|
134
|
-
<head>
|
|
135
|
-
<meta charset="UTF-8" />
|
|
136
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
137
|
-
<title>{{title}}</title>
|
|
138
|
-
<link rel="stylesheet" href="/styles.css" />
|
|
139
|
-
</head>
|
|
140
|
-
<body>
|
|
141
|
-
<nav class="sidebar">{{navigation}}</nav>
|
|
142
|
-
<main class="content">{{content}}</main>
|
|
143
|
-
<footer>
|
|
144
|
-
<p>由 ZEN 生成</p>
|
|
145
|
-
</footer>
|
|
146
|
-
</body>
|
|
147
|
-
</html>
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**可用模板变量:**
|
|
151
|
-
|
|
152
|
-
| 变量 | 描述 |
|
|
153
|
-
| ----------------- | ------------------------- |
|
|
154
|
-
| `{{title}}` | 页面标题 |
|
|
155
|
-
| `{{content}}` | 转换后的 HTML 内容 |
|
|
156
|
-
| `{{navigation}}` | 导航菜单 HTML |
|
|
157
|
-
| `{{metadata}}` | 页面元数据(JSON 字符串) |
|
|
158
|
-
| `{{currentPath}}` | 当前页面路径 |
|
|
159
|
-
|
|
160
|
-
### 模板位置
|
|
161
|
-
|
|
162
|
-
1. **命令行指定**: `--template ./my-template.html`
|
|
163
|
-
2. **配置文件指定**: `"template": "./my-template.html"`
|
|
164
|
-
3. **默认模板**: 内置模板
|
|
165
|
-
|
|
166
|
-
## 多语言配置
|
|
167
|
-
|
|
168
|
-
### 基本配置
|
|
169
|
-
|
|
170
|
-
```json
|
|
171
|
-
{
|
|
172
|
-
"i18n": {
|
|
173
|
-
"sourceLang": "zh-CN",
|
|
174
|
-
"targetLangs": ["en-US", "ja-JP"],
|
|
175
|
-
"apiKey": "sk-..."
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### 环境变量
|
|
181
|
-
|
|
182
|
-
也可以使用环境变量配置 API 密钥:
|
|
183
|
-
|
|
184
|
-
```bash
|
|
185
|
-
export OPENAI_API_KEY="sk-..."
|
|
186
|
-
npx zengen build
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### 翻译文件结构
|
|
190
|
-
|
|
191
|
-
```
|
|
192
|
-
docs/
|
|
193
|
-
├── index.md # 源文件(中文)
|
|
194
|
-
├── index.en-US.md # 英文翻译(自动生成)
|
|
195
|
-
└── index.ja-JP.md # 日文翻译(自动生成)
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### 翻译流程
|
|
199
|
-
|
|
200
|
-
1. **首次构建**: 翻译所有内容
|
|
201
|
-
2. **增量更新**: 只翻译新增或修改的内容
|
|
202
|
-
3. **手动更新**: 可以直接编辑翻译文件
|
|
203
|
-
|
|
204
|
-
## 文件处理配置
|
|
205
|
-
|
|
206
|
-
### 文件过滤
|
|
207
|
-
|
|
208
|
-
```json
|
|
209
|
-
{
|
|
210
|
-
"includePattern": "**/*.{md,markdown}",
|
|
211
|
-
"excludePattern": "**/{_*,node_modules}/**"
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### 元数据提取
|
|
216
|
-
|
|
217
|
-
在 Markdown 文件顶部添加 YAML frontmatter:
|
|
218
|
-
|
|
219
|
-
```yaml
|
|
220
|
-
---
|
|
221
|
-
title: 页面标题
|
|
222
|
-
description: 页面描述
|
|
223
|
-
author: 作者名
|
|
224
|
-
date: 2024-01-01
|
|
225
|
-
tags: [文档, 教程]
|
|
226
|
-
---
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### 自定义处理器
|
|
230
|
-
|
|
231
|
-
通过 API 使用自定义处理器,配置文件不支持直接配置处理器。
|
|
232
|
-
|
|
233
|
-
## 开发服务器配置
|
|
234
|
-
|
|
235
|
-
### 基本配置
|
|
236
|
-
|
|
237
|
-
```bash
|
|
238
|
-
# 启动开发服务器
|
|
239
|
-
npx zengen build --watch --serve
|
|
240
|
-
|
|
241
|
-
# 自定义端口和主机
|
|
242
|
-
npx zengen build --watch --serve --port 8080 --host 0.0.0.0
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### 服务器特性
|
|
246
|
-
|
|
247
|
-
- 自动重载:文件变化时自动刷新浏览器
|
|
248
|
-
- 静态文件服务:提供构建的文档站点
|
|
249
|
-
- 实时预览:即时查看修改效果
|
|
250
|
-
|
|
251
|
-
## 环境配置
|
|
252
|
-
|
|
253
|
-
### Node.js 版本
|
|
254
|
-
|
|
255
|
-
- **最低版本**: Node.js 16.x
|
|
256
|
-
- **推荐版本**: Node.js 18.x 或更高
|
|
257
|
-
|
|
258
|
-
### 内存要求
|
|
259
|
-
|
|
260
|
-
- 小型项目:~100MB
|
|
261
|
-
- 大型项目:~500MB(包含翻译)
|
|
262
|
-
|
|
263
|
-
### 网络要求
|
|
264
|
-
|
|
265
|
-
- 使用 AI 翻译时需要网络连接
|
|
266
|
-
- 纯本地构建无需网络
|
|
267
|
-
|
|
268
|
-
## 最佳实践
|
|
269
|
-
|
|
270
|
-
### 配置文件管理
|
|
271
|
-
|
|
272
|
-
1. **版本控制**: 将 `zen.config.json` 加入版本控制
|
|
273
|
-
2. **环境变量**: 敏感信息(如 API 密钥)使用环境变量
|
|
274
|
-
3. **模板分离**: 自定义模板单独存放
|
|
275
|
-
|
|
276
|
-
### 性能优化
|
|
277
|
-
|
|
278
|
-
1. **增量构建**: 使用 `--watch` 模式开发
|
|
279
|
-
2. **文件组织**: 合理组织文档结构
|
|
280
|
-
3. **缓存利用**: ZEN 会自动缓存处理结果
|
|
281
|
-
|
|
282
|
-
### 错误处理
|
|
283
|
-
|
|
284
|
-
1. **详细日志**: 使用 `--verbose` 查看详细错误信息
|
|
285
|
-
2. **配置验证**: ZEN 会自动验证配置
|
|
286
|
-
3. **错误恢复**: 构建失败时会保留上次成功的结果
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zengen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "ZEN - A minimalist Markdown documentation site builder",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -10,6 +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
14
|
"test": "npm run build && node --test dist/**/*.test.js",
|
|
14
15
|
"test:types": "tsc --noEmit",
|
|
15
16
|
"test:build": "npm run build && test -f dist/index.js && test -f dist/cli.js",
|
|
@@ -54,9 +55,11 @@
|
|
|
54
55
|
"dependencies": {
|
|
55
56
|
"chokidar": "^5.0.0",
|
|
56
57
|
"clipanion": "^4.0.0-rc.4",
|
|
58
|
+
"dotenv": "^16.4.7",
|
|
57
59
|
"express": "^4.21.2",
|
|
58
60
|
"highlight.js": "^11.11.1",
|
|
59
61
|
"marked": "^17.0.1",
|
|
60
|
-
"minimatch": "^10.1.1"
|
|
62
|
+
"minimatch": "^10.1.1",
|
|
63
|
+
"yaml": "^2.8.2"
|
|
61
64
|
}
|
|
62
65
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { completeMessages, OpenAIMessage } from '../services/openai';
|
|
2
|
+
import { AIMetadata } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 从 markdown 内容中提取 metadata
|
|
6
|
+
* @param content Markdown 内容
|
|
7
|
+
* @returns Promise<AIMetadata> 提取的元数据,失败时抛出错误
|
|
8
|
+
*/
|
|
9
|
+
export async function extractMetadataFromMarkdown(content: string): Promise<AIMetadata> {
|
|
10
|
+
const prompt = buildMetadataPrompt(content);
|
|
11
|
+
const messages: OpenAIMessage[] = [
|
|
12
|
+
{
|
|
13
|
+
role: 'system',
|
|
14
|
+
content:
|
|
15
|
+
'你是一个专业的文档分析助手,擅长从文档中提取结构化信息。请严格按照要求的 JSON 格式返回结果。',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
role: 'user',
|
|
19
|
+
content: prompt,
|
|
20
|
+
},
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
const response = await completeMessages(messages, {
|
|
24
|
+
response_format: { type: 'json_object' },
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const metadata = parseMetadataResponse(response.choices[0].message.content);
|
|
28
|
+
|
|
29
|
+
// 添加 tokens 使用情况
|
|
30
|
+
metadata.tokens_used = {
|
|
31
|
+
prompt: response.usage.prompt_tokens,
|
|
32
|
+
completion: response.usage.completion_tokens,
|
|
33
|
+
total: response.usage.total_tokens,
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
return metadata;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* 构建提取 metadata 的 prompt
|
|
41
|
+
*/
|
|
42
|
+
function buildMetadataPrompt(content: string): string {
|
|
43
|
+
// 限制内容长度以避免 token 超限
|
|
44
|
+
const maxContentLength = 8000;
|
|
45
|
+
const truncatedContent =
|
|
46
|
+
content.length > maxContentLength
|
|
47
|
+
? content.substring(0, maxContentLength) + '... [内容已截断]'
|
|
48
|
+
: content;
|
|
49
|
+
|
|
50
|
+
return `请分析以下文档内容,提取以下信息并返回 JSON 格式:
|
|
51
|
+
|
|
52
|
+
文档内容:
|
|
53
|
+
"""
|
|
54
|
+
${truncatedContent}
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
请提取:
|
|
58
|
+
1. title: 文档的标题(简洁明了,不超过 20 个字)
|
|
59
|
+
2. summary: 文档摘要(控制在 100 字以内,概括主要内容)
|
|
60
|
+
3. tags: 关键词列表(3-8 个关键词,使用中文或英文)
|
|
61
|
+
4. inferred_date: 文档中隐含的创建日期(如果有的话,格式:YYYY-MM-DD,没有就留空字符串)
|
|
62
|
+
5. inferred_lang: 文档使用的语言代码(例如:zh-Hans 表示简体中文,en-US 表示美式英语)
|
|
63
|
+
|
|
64
|
+
请严格按照以下 JSON 格式返回,不要包含任何其他文本:
|
|
65
|
+
{
|
|
66
|
+
"title": "文档标题",
|
|
67
|
+
"summary": "文档摘要...",
|
|
68
|
+
"tags": ["关键词1", "关键词2", "关键词3"],
|
|
69
|
+
"inferred_date": "2023-01-01",
|
|
70
|
+
"inferred_lang": "zh-Hans"
|
|
71
|
+
}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* 解析 AI 返回的 metadata
|
|
76
|
+
*/
|
|
77
|
+
function parseMetadataResponse(responseContent: string): AIMetadata {
|
|
78
|
+
try {
|
|
79
|
+
const metadata = JSON.parse(responseContent);
|
|
80
|
+
|
|
81
|
+
// 验证和清理数据
|
|
82
|
+
return {
|
|
83
|
+
title: metadata.title?.trim() || '未命名文档',
|
|
84
|
+
summary: metadata.summary?.trim() || '',
|
|
85
|
+
tags: Array.isArray(metadata.tags)
|
|
86
|
+
? metadata.tags.map((tag: string) => tag.trim()).filter(Boolean)
|
|
87
|
+
: [],
|
|
88
|
+
inferred_date: metadata.inferred_date?.trim() || undefined,
|
|
89
|
+
inferred_lang: metadata.inferred_lang?.trim() || 'zh-Hans',
|
|
90
|
+
};
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error('❌ Failed to parse AI response:', error, 'Response:', responseContent);
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { completeMessages, OpenAIMessage } from '../services/openai';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 将 markdown 翻译为指定的语言
|
|
5
|
+
* @param content Markdown 内容
|
|
6
|
+
* @param targetLang 目标语言代码(例如:zh-Hans, en-US)
|
|
7
|
+
* @returns Promise<string> 翻译后的 Markdown 内容
|
|
8
|
+
*/
|
|
9
|
+
export async function translateMarkdown(content: string, targetLang: string): Promise<string> {
|
|
10
|
+
const messages: OpenAIMessage[] = [
|
|
11
|
+
{
|
|
12
|
+
role: 'system',
|
|
13
|
+
content: `你是一个专业的翻译助手,擅长将文档翻译成不同语言,同时保持原有的格式和结构。请将用户输入翻译成 ${targetLang},注意保持 Markdown 格式不变,链接不变,不要翻译代码,但是可以翻译代码中的注释。`,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
role: 'user',
|
|
17
|
+
content: content,
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const response = await completeMessages(messages);
|
|
22
|
+
const translatedContent = response.choices[0]?.message?.content?.trim() || '';
|
|
23
|
+
|
|
24
|
+
if (!translatedContent) {
|
|
25
|
+
throw new Error('Empty translation response');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return translatedContent;
|
|
29
|
+
}
|