zengen 0.1.35 → 0.1.36
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 +57 -0
- package/.zen/translations.json +51 -0
- package/dist/ai-client.d.ts +34 -0
- package/dist/ai-client.d.ts.map +1 -0
- package/dist/ai-client.js +180 -0
- package/dist/ai-client.js.map +1 -0
- package/dist/ai-processor.d.ts +51 -0
- package/dist/ai-processor.d.ts.map +1 -0
- package/dist/ai-processor.js +215 -0
- package/dist/ai-processor.js.map +1 -0
- package/dist/ai-service.d.ts +79 -0
- package/dist/ai-service.d.ts.map +1 -0
- package/dist/ai-service.js +257 -0
- package/dist/ai-service.js.map +1 -0
- package/dist/builder.d.ts +26 -2
- package/dist/builder.d.ts.map +1 -1
- package/dist/builder.js +420 -9
- package/dist/builder.js.map +1 -1
- package/dist/cli.js +45 -3
- package/dist/cli.js.map +1 -1
- package/dist/gitignore.d.ts +2 -1
- package/dist/gitignore.d.ts.map +1 -1
- package/dist/gitignore.js +21 -3
- package/dist/gitignore.js.map +1 -1
- package/dist/gitignore.test.js +82 -17
- package/dist/gitignore.test.js.map +1 -1
- package/dist/markdown.d.ts +6 -1
- package/dist/markdown.d.ts.map +1 -1
- package/dist/markdown.js +31 -9
- package/dist/markdown.js.map +1 -1
- package/dist/navigation.js +5 -5
- package/dist/navigation.js.map +1 -1
- package/dist/scanner.d.ts +26 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +190 -0
- package/dist/scanner.js.map +1 -0
- package/dist/template.d.ts +6 -2
- package/dist/template.d.ts.map +1 -1
- package/dist/template.js +57 -8
- package/dist/template.js.map +1 -1
- package/dist/translation-service.d.ts +72 -0
- package/dist/translation-service.d.ts.map +1 -0
- package/dist/translation-service.js +291 -0
- package/dist/translation-service.js.map +1 -0
- package/dist/types.d.ts +35 -4
- package/dist/types.d.ts.map +1 -1
- package/docs/advanced-usage.md +39 -0
- package/docs/getting-started.md +26 -0
- package/docs/guides/best-practices.md +0 -113
- package/docs/guides/config.md +0 -233
- package/package.json +2 -1
- package/src/ai-client.ts +227 -0
- package/src/ai-processor.ts +243 -0
- package/src/ai-service.ts +281 -0
- package/src/builder.ts +543 -10
- package/src/cli.ts +49 -3
- package/src/gitignore.test.ts +82 -17
- package/src/gitignore.ts +23 -3
- package/src/markdown.ts +39 -11
- package/src/navigation.ts +5 -5
- package/src/scanner.ts +180 -0
- package/src/template.ts +68 -8
- package/src/translation-service.ts +350 -0
- package/src/types.ts +39 -3
- package/test-multilang.js +44 -0
- package/docs/ci/github-ci-cd.md +0 -127
- package/docs/guides/api.md +0 -277
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.TranslationService = void 0;
|
|
37
|
+
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const ai_service_1 = require("./ai-service");
|
|
40
|
+
/**
|
|
41
|
+
* 翻译服务类
|
|
42
|
+
*/
|
|
43
|
+
class TranslationService {
|
|
44
|
+
constructor(config = {}) {
|
|
45
|
+
// 从环境变量读取配置
|
|
46
|
+
const apiKey = process.env.OPENAI_API_KEY || '';
|
|
47
|
+
const baseUrl = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
|
|
48
|
+
// 配置优先级:构造函数参数 > 环境变量 > 默认值
|
|
49
|
+
const model = config.model || process.env.OPENAI_MODEL || 'gpt-3.5-turbo';
|
|
50
|
+
this.config = {
|
|
51
|
+
enabled: config.enabled ?? apiKey !== '',
|
|
52
|
+
apiKey,
|
|
53
|
+
baseUrl,
|
|
54
|
+
model,
|
|
55
|
+
temperature: 0, // 总是设置为 0,翻译不需要随机性
|
|
56
|
+
maxTokens: config.maxTokens || 2000,
|
|
57
|
+
};
|
|
58
|
+
this.aiService = new ai_service_1.AIService();
|
|
59
|
+
this.translationCachePath = path.join(process.cwd(), '.zen', 'translations.json');
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* 检查是否启用翻译功能
|
|
63
|
+
*/
|
|
64
|
+
isEnabled() {
|
|
65
|
+
const enabled = this.config.enabled && this.config.apiKey !== '';
|
|
66
|
+
if (!enabled && this.config.enabled) {
|
|
67
|
+
console.warn('⚠️ Translation is enabled but API key is missing. Please set OPENAI_API_KEY environment variable.');
|
|
68
|
+
}
|
|
69
|
+
return enabled;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 加载翻译缓存
|
|
73
|
+
*/
|
|
74
|
+
async loadTranslationCache() {
|
|
75
|
+
try {
|
|
76
|
+
await fs.access(this.translationCachePath);
|
|
77
|
+
const content = await fs.readFile(this.translationCachePath, 'utf-8');
|
|
78
|
+
return JSON.parse(content);
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
// 如果文件不存在,返回空数组
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 保存翻译缓存
|
|
87
|
+
*/
|
|
88
|
+
async saveTranslationCache(cache) {
|
|
89
|
+
// 确保 .zen 目录存在
|
|
90
|
+
const zenDir = path.dirname(this.translationCachePath);
|
|
91
|
+
await fs.mkdir(zenDir, { recursive: true });
|
|
92
|
+
// 保存文件
|
|
93
|
+
await fs.writeFile(this.translationCachePath, JSON.stringify(cache, null, 2), 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 获取缓存的翻译
|
|
97
|
+
*/
|
|
98
|
+
async getCachedTranslation(sourceHash, sourceLang, targetLang) {
|
|
99
|
+
if (!this.isEnabled()) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const cache = await this.loadTranslationCache();
|
|
104
|
+
const cachedTranslation = cache.find(item => item.sourceHash === sourceHash &&
|
|
105
|
+
item.sourceLang === sourceLang &&
|
|
106
|
+
item.targetLang === targetLang);
|
|
107
|
+
if (cachedTranslation) {
|
|
108
|
+
console.log(`📚 Using cached translation for ${sourceHash} (${sourceLang} → ${targetLang})`);
|
|
109
|
+
return cachedTranslation.translatedContent;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.warn(`⚠️ Failed to load translation cache:`, error);
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* 缓存翻译结果
|
|
119
|
+
*/
|
|
120
|
+
async cacheTranslation(sourceHash, sourceLang, targetLang, translatedContent) {
|
|
121
|
+
if (!this.isEnabled()) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
const cache = await this.loadTranslationCache();
|
|
126
|
+
// 查找是否已存在相同翻译
|
|
127
|
+
const existingIndex = cache.findIndex(item => item.sourceHash === sourceHash &&
|
|
128
|
+
item.sourceLang === sourceLang &&
|
|
129
|
+
item.targetLang === targetLang);
|
|
130
|
+
if (existingIndex >= 0) {
|
|
131
|
+
// 更新现有缓存
|
|
132
|
+
cache[existingIndex] = {
|
|
133
|
+
sourceHash,
|
|
134
|
+
sourceLang,
|
|
135
|
+
targetLang,
|
|
136
|
+
translatedContent,
|
|
137
|
+
lastUpdated: new Date().toISOString(),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// 添加新缓存
|
|
142
|
+
cache.push({
|
|
143
|
+
sourceHash,
|
|
144
|
+
sourceLang,
|
|
145
|
+
targetLang,
|
|
146
|
+
translatedContent,
|
|
147
|
+
lastUpdated: new Date().toISOString(),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
await this.saveTranslationCache(cache);
|
|
151
|
+
console.log(`💾 Cached translation for ${sourceHash} (${sourceLang} → ${targetLang})`);
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
console.warn(`⚠️ Failed to cache translation:`, error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* 使用AI翻译内容
|
|
159
|
+
*/
|
|
160
|
+
async translateWithAI(content, sourceLang, targetLang) {
|
|
161
|
+
if (!this.isEnabled()) {
|
|
162
|
+
throw new Error('Translation service is not enabled');
|
|
163
|
+
}
|
|
164
|
+
const prompt = `请将以下${sourceLang}文本翻译成${targetLang}。保持Markdown格式不变,只翻译文本内容:
|
|
165
|
+
|
|
166
|
+
${content}
|
|
167
|
+
|
|
168
|
+
翻译结果(保持原格式):`;
|
|
169
|
+
try {
|
|
170
|
+
const response = await fetch(`${this.config.baseUrl}/chat/completions`, {
|
|
171
|
+
method: 'POST',
|
|
172
|
+
headers: {
|
|
173
|
+
'Content-Type': 'application/json',
|
|
174
|
+
'Authorization': `Bearer ${this.config.apiKey}`,
|
|
175
|
+
},
|
|
176
|
+
body: JSON.stringify({
|
|
177
|
+
model: this.config.model,
|
|
178
|
+
messages: [
|
|
179
|
+
{
|
|
180
|
+
role: 'system',
|
|
181
|
+
content: '你是一个专业的翻译助手,擅长将文档翻译成不同语言,同时保持原有的格式和结构。'
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
role: 'user',
|
|
185
|
+
content: prompt
|
|
186
|
+
}
|
|
187
|
+
],
|
|
188
|
+
temperature: this.config.temperature,
|
|
189
|
+
max_tokens: this.config.maxTokens,
|
|
190
|
+
}),
|
|
191
|
+
});
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
const errorText = await response.text();
|
|
194
|
+
throw new Error(`Translation API error: ${response.status} ${errorText}`);
|
|
195
|
+
}
|
|
196
|
+
const data = await response.json();
|
|
197
|
+
const translatedContent = data.choices[0]?.message?.content?.trim() || '';
|
|
198
|
+
if (!translatedContent) {
|
|
199
|
+
throw new Error('Empty translation response');
|
|
200
|
+
}
|
|
201
|
+
return translatedContent;
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
console.error(`❌ Translation failed:`, error);
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 翻译文件
|
|
210
|
+
*/
|
|
211
|
+
async translateFile(fileInfo, sourceLang, targetLang) {
|
|
212
|
+
const sourceHash = fileInfo.hash || this.aiService.calculateFileHash(fileInfo.content);
|
|
213
|
+
// 检查缓存
|
|
214
|
+
const cachedTranslation = await this.getCachedTranslation(sourceHash, sourceLang, targetLang);
|
|
215
|
+
if (cachedTranslation) {
|
|
216
|
+
return cachedTranslation;
|
|
217
|
+
}
|
|
218
|
+
// 如果目标语言与源语言相同,直接返回原内容
|
|
219
|
+
if (sourceLang === targetLang) {
|
|
220
|
+
console.log(`📝 Skipping translation (same language): ${sourceLang} → ${targetLang}`);
|
|
221
|
+
await this.cacheTranslation(sourceHash, sourceLang, targetLang, fileInfo.content);
|
|
222
|
+
return fileInfo.content;
|
|
223
|
+
}
|
|
224
|
+
// 使用AI翻译
|
|
225
|
+
console.log(`🌐 Translating from ${sourceLang} to ${targetLang}...`);
|
|
226
|
+
const translatedContent = await this.translateWithAI(fileInfo.content, sourceLang, targetLang);
|
|
227
|
+
// 缓存结果
|
|
228
|
+
await this.cacheTranslation(sourceHash, sourceLang, targetLang, translatedContent);
|
|
229
|
+
return translatedContent;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* 生成翻译后的文件路径
|
|
233
|
+
*/
|
|
234
|
+
getTranslatedFilePath(originalPath, targetLang, nativeHash) {
|
|
235
|
+
const zenSrcDir = path.join(process.cwd(), '.zen', 'src');
|
|
236
|
+
const langDir = path.join(zenSrcDir, targetLang);
|
|
237
|
+
const fileName = `${nativeHash}.md`;
|
|
238
|
+
return path.join(langDir, fileName);
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* 确保翻译文件存在
|
|
242
|
+
*/
|
|
243
|
+
async ensureTranslatedFile(fileInfo, sourceLang, targetLang, nativeHash) {
|
|
244
|
+
const translatedFilePath = this.getTranslatedFilePath(fileInfo.path, targetLang, nativeHash);
|
|
245
|
+
try {
|
|
246
|
+
// 检查文件是否已存在
|
|
247
|
+
await fs.access(translatedFilePath);
|
|
248
|
+
console.log(`📄 Translation file already exists: ${translatedFilePath}`);
|
|
249
|
+
// 读取现有内容
|
|
250
|
+
const existingContent = await fs.readFile(translatedFilePath, 'utf-8');
|
|
251
|
+
return existingContent;
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
// 文件不存在,需要翻译
|
|
255
|
+
console.log(`🔄 Creating translation file: ${translatedFilePath}`);
|
|
256
|
+
// 翻译内容
|
|
257
|
+
const translatedContent = await this.translateFile(fileInfo, sourceLang, targetLang);
|
|
258
|
+
// 确保目录存在
|
|
259
|
+
const dirPath = path.dirname(translatedFilePath);
|
|
260
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
261
|
+
// 保存翻译文件
|
|
262
|
+
await fs.writeFile(translatedFilePath, translatedContent, 'utf-8');
|
|
263
|
+
return translatedContent;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* 清理过期的翻译缓存
|
|
268
|
+
*/
|
|
269
|
+
async cleanupCache(maxAgeDays = 30) {
|
|
270
|
+
try {
|
|
271
|
+
const cache = await this.loadTranslationCache();
|
|
272
|
+
const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
|
|
273
|
+
const originalCount = cache.length;
|
|
274
|
+
// 过滤掉过期的缓存
|
|
275
|
+
const filteredCache = cache.filter(item => {
|
|
276
|
+
const itemTime = new Date(item.lastUpdated).getTime();
|
|
277
|
+
return itemTime >= cutoffTime;
|
|
278
|
+
});
|
|
279
|
+
const cleanedCount = originalCount - filteredCache.length;
|
|
280
|
+
if (cleanedCount > 0) {
|
|
281
|
+
await this.saveTranslationCache(filteredCache);
|
|
282
|
+
console.log(`🧹 Cleaned ${cleanedCount} expired translation cache entries`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
console.warn(`⚠️ Failed to cleanup translation cache:`, error);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
exports.TranslationService = TranslationService;
|
|
291
|
+
//# sourceMappingURL=translation-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translation-service.js","sourceRoot":"","sources":["../src/translation-service.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,10 +8,16 @@ export interface BuildOptions {
|
|
|
8
8
|
port?: number;
|
|
9
9
|
host?: string;
|
|
10
10
|
baseUrl?: string;
|
|
11
|
+
langs?: string[];
|
|
12
|
+
}
|
|
13
|
+
export interface ScannedFile {
|
|
14
|
+
path: string;
|
|
15
|
+
name: string;
|
|
16
|
+
ext: string;
|
|
17
|
+
hash?: string;
|
|
11
18
|
}
|
|
12
19
|
export interface FileInfo {
|
|
13
20
|
path: string;
|
|
14
|
-
relativePath: string;
|
|
15
21
|
name: string;
|
|
16
22
|
ext: string;
|
|
17
23
|
content: string;
|
|
@@ -19,6 +25,20 @@ export interface FileInfo {
|
|
|
19
25
|
metadata?: {
|
|
20
26
|
title: string;
|
|
21
27
|
};
|
|
28
|
+
hash?: string;
|
|
29
|
+
aiMetadata?: AIMetadata;
|
|
30
|
+
}
|
|
31
|
+
export interface AIMetadata {
|
|
32
|
+
title: string;
|
|
33
|
+
summary: string;
|
|
34
|
+
tags: string[];
|
|
35
|
+
inferred_date?: string;
|
|
36
|
+
inferred_lang: string;
|
|
37
|
+
tokens_used?: {
|
|
38
|
+
prompt: number;
|
|
39
|
+
completion: number;
|
|
40
|
+
total: number;
|
|
41
|
+
};
|
|
22
42
|
}
|
|
23
43
|
export interface NavigationItem {
|
|
24
44
|
title: string;
|
|
@@ -29,10 +49,10 @@ export interface TemplateData {
|
|
|
29
49
|
title: string;
|
|
30
50
|
content: string;
|
|
31
51
|
navigation: NavigationItem[];
|
|
32
|
-
metadata?:
|
|
33
|
-
title: string;
|
|
34
|
-
};
|
|
52
|
+
metadata?: AIMetadata;
|
|
35
53
|
currentPath?: string;
|
|
54
|
+
lang?: string;
|
|
55
|
+
availableLangs?: string[];
|
|
36
56
|
}
|
|
37
57
|
export interface MarkdownProcessor {
|
|
38
58
|
beforeParse?(content: string, fileInfo: FileInfo): string | Promise<string>;
|
|
@@ -48,8 +68,19 @@ export interface ZenConfig {
|
|
|
48
68
|
targetLangs: string[];
|
|
49
69
|
apiKey?: string;
|
|
50
70
|
};
|
|
71
|
+
ai?: {
|
|
72
|
+
enabled?: boolean;
|
|
73
|
+
model?: string;
|
|
74
|
+
temperature?: number;
|
|
75
|
+
maxTokens?: number;
|
|
76
|
+
};
|
|
51
77
|
processors?: MarkdownProcessor[];
|
|
52
78
|
includePattern?: string;
|
|
53
79
|
excludePattern?: string;
|
|
54
80
|
}
|
|
81
|
+
export interface MultiLangBuildOptions extends BuildOptions {
|
|
82
|
+
langs: string[];
|
|
83
|
+
useMetaData?: boolean;
|
|
84
|
+
filterOrphans?: boolean;
|
|
85
|
+
}
|
|
55
86
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# 高级用法
|
|
2
|
+
|
|
3
|
+
深入介绍 ZEN 的高级功能和配置选项。
|
|
4
|
+
|
|
5
|
+
## 自定义模板
|
|
6
|
+
|
|
7
|
+
ZEN 支持自定义 HTML 模板:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
zengen build --src ./docs --out ./dist --template ./custom-template.html
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## 配置选项
|
|
14
|
+
|
|
15
|
+
可以在 `.zenrc` 文件中配置:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"srcDir": "./docs",
|
|
20
|
+
"outDir": "./dist",
|
|
21
|
+
"template": "./template.html",
|
|
22
|
+
"baseUrl": "https://example.com",
|
|
23
|
+
"i18n": {
|
|
24
|
+
"sourceLang": "zh-Hans",
|
|
25
|
+
"targetLangs": ["en-US", "ja-JP"]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 插件系统
|
|
31
|
+
|
|
32
|
+
ZEN 支持插件扩展功能:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
interface MarkdownProcessor {
|
|
36
|
+
beforeParse?(content: string, fileInfo: FileInfo): string | Promise<string>;
|
|
37
|
+
afterParse?(html: string, fileInfo: FileInfo): string | Promise<string>;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# 快速开始指南
|
|
2
|
+
|
|
3
|
+
本文档介绍如何快速开始使用 ZEN 文档生成器。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g zengen
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 基本用法
|
|
12
|
+
|
|
13
|
+
1. 创建文档目录
|
|
14
|
+
2. 编写 Markdown 文件
|
|
15
|
+
3. 运行构建命令
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
zengen build --src ./docs --out ./dist
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 特性
|
|
22
|
+
|
|
23
|
+
- 极简配置
|
|
24
|
+
- 内置响应式模板
|
|
25
|
+
- AI 辅助元数据提取
|
|
26
|
+
- 多语言支持
|
|
@@ -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
|
### 构建优化
|