zengen 0.1.36 → 0.2.1

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.
Files changed (150) hide show
  1. package/.github/workflows/pages.yml +1 -1
  2. package/.zen/meta.json +112 -32
  3. package/.zen/src/en-US/01d04f7c17b4a541ead9d759d877b30b403e15b849182a49eb1f62bd29ecd18c.md +120 -0
  4. package/.zen/src/en-US/1b798c44a4f353e47296ca83d5905e37e6aba3e90bbd9bc3b3d34fc12059a2ca.md +75 -0
  5. package/.zen/src/en-US/1e96be58d76c60056b708eb5bd8b8b81d7b5845d9cfe0b879d85068a5f11df3a.md +189 -0
  6. package/.zen/src/en-US/5ec990146b35e00de2630559126ee07f7cdcddeb23b0e8cab3d85b4181353e26.md +53 -0
  7. package/.zen/src/en-US/6124ea88edec5bde737b26b21f71ecfeffe4e73151784856edf813ee231a4baa.md +11 -0
  8. package/.zen/src/en-US/80ae9bed74fc6348a7c1fe9f33e86b65f5d919169721f77bcf0e1bc29fbdb4f9.md +61 -0
  9. package/.zen/src/en-US/f0c2799126931ccd113a0c45b1e623870b0d4f4f400becf6dd877da8f1011517.md +40 -0
  10. package/.zen/src/en-US/fdfca9b960d0eaa8b2b96fe988ead7481d2c0b16f66ebc94fb477139b4178cdc.md +65 -0
  11. package/.zen/src/zh-Hans/01d04f7c17b4a541ead9d759d877b30b403e15b849182a49eb1f62bd29ecd18c.md +120 -0
  12. package/.zen/src/zh-Hans/1b798c44a4f353e47296ca83d5905e37e6aba3e90bbd9bc3b3d34fc12059a2ca.md +77 -0
  13. package/.zen/src/zh-Hans/1e96be58d76c60056b708eb5bd8b8b81d7b5845d9cfe0b879d85068a5f11df3a.md +189 -0
  14. package/.zen/src/zh-Hans/5ec990146b35e00de2630559126ee07f7cdcddeb23b0e8cab3d85b4181353e26.md +55 -0
  15. package/.zen/src/zh-Hans/6124ea88edec5bde737b26b21f71ecfeffe4e73151784856edf813ee231a4baa.md +11 -0
  16. package/.zen/src/zh-Hans/80ae9bed74fc6348a7c1fe9f33e86b65f5d919169721f77bcf0e1bc29fbdb4f9.md +63 -0
  17. package/.zen/src/zh-Hans/f0c2799126931ccd113a0c45b1e623870b0d4f4f400becf6dd877da8f1011517.md +40 -0
  18. package/.zen/src/zh-Hans/fdfca9b960d0eaa8b2b96fe988ead7481d2c0b16f66ebc94fb477139b4178cdc.md +65 -0
  19. package/assets/templates/default/layout.html +274 -0
  20. package/dist/ai/extractMetadataFromMarkdown.d.ts +8 -0
  21. package/dist/ai/extractMetadataFromMarkdown.d.ts.map +1 -0
  22. package/dist/ai/extractMetadataFromMarkdown.js +88 -0
  23. package/dist/ai/extractMetadataFromMarkdown.js.map +1 -0
  24. package/dist/ai/translateMarkdown.d.ts +8 -0
  25. package/dist/ai/translateMarkdown.d.ts.map +1 -0
  26. package/dist/ai/translateMarkdown.js +29 -0
  27. package/dist/ai/translateMarkdown.js.map +1 -0
  28. package/dist/build/pipeline.d.ts +6 -0
  29. package/dist/build/pipeline.d.ts.map +1 -0
  30. package/dist/build/pipeline.js +219 -0
  31. package/dist/build/pipeline.js.map +1 -0
  32. package/dist/cli.js +10 -118
  33. package/dist/cli.js.map +1 -1
  34. package/dist/findEntries.d.ts +10 -0
  35. package/dist/findEntries.d.ts.map +1 -0
  36. package/dist/findEntries.js +38 -0
  37. package/dist/findEntries.js.map +1 -0
  38. package/dist/index.d.ts +1 -32
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +1 -35
  41. package/dist/index.js.map +1 -1
  42. package/dist/metadata.d.ts +14 -0
  43. package/dist/metadata.d.ts.map +1 -0
  44. package/dist/metadata.js +78 -0
  45. package/dist/metadata.js.map +1 -0
  46. package/dist/paths.d.ts +6 -0
  47. package/dist/paths.d.ts.map +1 -0
  48. package/dist/paths.js +10 -0
  49. package/dist/paths.js.map +1 -0
  50. package/dist/process/extractMetadataByAI.d.ts +5 -0
  51. package/dist/process/extractMetadataByAI.d.ts.map +1 -0
  52. package/dist/process/extractMetadataByAI.js +31 -0
  53. package/dist/process/extractMetadataByAI.js.map +1 -0
  54. package/dist/process/template.d.ts +5 -0
  55. package/dist/process/template.d.ts.map +1 -0
  56. package/dist/process/template.js +188 -0
  57. package/dist/process/template.js.map +1 -0
  58. package/dist/scan/files.d.ts +7 -0
  59. package/dist/scan/files.d.ts.map +1 -0
  60. package/dist/scan/files.js +54 -0
  61. package/dist/scan/files.js.map +1 -0
  62. package/dist/services/openai.d.ts +41 -0
  63. package/dist/services/openai.d.ts.map +1 -0
  64. package/dist/services/openai.js +54 -0
  65. package/dist/services/openai.js.map +1 -0
  66. package/dist/types.d.ts +16 -67
  67. package/dist/types.d.ts.map +1 -1
  68. package/dist/utils/convertMarkdownToHtml.d.ts +7 -0
  69. package/dist/utils/convertMarkdownToHtml.d.ts.map +1 -0
  70. package/dist/utils/convertMarkdownToHtml.js +39 -0
  71. package/dist/utils/convertMarkdownToHtml.js.map +1 -0
  72. package/dist/utils/frontmatter.d.ts +6 -0
  73. package/dist/utils/frontmatter.d.ts.map +1 -0
  74. package/dist/utils/frontmatter.js +22 -0
  75. package/dist/utils/frontmatter.js.map +1 -0
  76. package/docs/deployment/github-pages.md +1 -2
  77. package/docs/guides/best-practices.md +4 -4
  78. package/docs/guides/config.md +0 -5
  79. package/package.json +4 -2
  80. package/src/ai/extractMetadataFromMarkdown.ts +95 -0
  81. package/src/ai/translateMarkdown.ts +29 -0
  82. package/src/build/pipeline.ts +217 -0
  83. package/src/cli.ts +10 -132
  84. package/src/findEntries.ts +37 -0
  85. package/src/index.ts +1 -40
  86. package/src/metadata.ts +44 -0
  87. package/src/paths.ts +7 -0
  88. package/src/process/extractMetadataByAI.ts +31 -0
  89. package/src/process/template.ts +201 -0
  90. package/src/scan/files.ts +17 -0
  91. package/src/services/openai.ts +92 -0
  92. package/src/types.ts +18 -72
  93. package/src/utils/convertMarkdownToHtml.ts +32 -0
  94. package/src/utils/frontmatter.ts +18 -0
  95. package/.zen/translations.json +0 -51
  96. package/dist/ai-client.d.ts +0 -34
  97. package/dist/ai-client.d.ts.map +0 -1
  98. package/dist/ai-client.js +0 -180
  99. package/dist/ai-client.js.map +0 -1
  100. package/dist/ai-processor.d.ts +0 -51
  101. package/dist/ai-processor.d.ts.map +0 -1
  102. package/dist/ai-processor.js +0 -215
  103. package/dist/ai-processor.js.map +0 -1
  104. package/dist/ai-service.d.ts +0 -79
  105. package/dist/ai-service.d.ts.map +0 -1
  106. package/dist/ai-service.js +0 -257
  107. package/dist/ai-service.js.map +0 -1
  108. package/dist/builder.d.ts +0 -70
  109. package/dist/builder.d.ts.map +0 -1
  110. package/dist/builder.js +0 -854
  111. package/dist/builder.js.map +0 -1
  112. package/dist/gitignore.d.ts +0 -41
  113. package/dist/gitignore.d.ts.map +0 -1
  114. package/dist/gitignore.js +0 -202
  115. package/dist/gitignore.js.map +0 -1
  116. package/dist/gitignore.test.d.ts +0 -2
  117. package/dist/gitignore.test.d.ts.map +0 -1
  118. package/dist/gitignore.test.js +0 -309
  119. package/dist/gitignore.test.js.map +0 -1
  120. package/dist/markdown.d.ts +0 -35
  121. package/dist/markdown.d.ts.map +0 -1
  122. package/dist/markdown.js +0 -221
  123. package/dist/markdown.js.map +0 -1
  124. package/dist/navigation.d.ts +0 -46
  125. package/dist/navigation.d.ts.map +0 -1
  126. package/dist/navigation.js +0 -196
  127. package/dist/navigation.js.map +0 -1
  128. package/dist/scanner.d.ts +0 -26
  129. package/dist/scanner.d.ts.map +0 -1
  130. package/dist/scanner.js +0 -190
  131. package/dist/scanner.js.map +0 -1
  132. package/dist/template.d.ts +0 -33
  133. package/dist/template.d.ts.map +0 -1
  134. package/dist/template.js +0 -434
  135. package/dist/template.js.map +0 -1
  136. package/dist/translation-service.d.ts +0 -72
  137. package/dist/translation-service.d.ts.map +0 -1
  138. package/dist/translation-service.js +0 -291
  139. package/dist/translation-service.js.map +0 -1
  140. package/src/ai-client.ts +0 -227
  141. package/src/ai-processor.ts +0 -243
  142. package/src/ai-service.ts +0 -281
  143. package/src/builder.ts +0 -991
  144. package/src/gitignore.test.ts +0 -318
  145. package/src/gitignore.ts +0 -193
  146. package/src/markdown.ts +0 -212
  147. package/src/navigation.ts +0 -237
  148. package/src/scanner.ts +0 -180
  149. package/src/template.ts +0 -425
  150. package/src/translation-service.ts +0 -350
package/src/template.ts DELETED
@@ -1,425 +0,0 @@
1
- import { TemplateData, NavigationItem, FileInfo } from './types';
2
- import * as fs from 'fs/promises';
3
- import * as path from 'path';
4
-
5
- export class TemplateEngine {
6
- private defaultTemplate = `<!DOCTYPE html>
7
- <html lang="zh-CN">
8
- <head>
9
- <meta charset="UTF-8">
10
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
- <title>{{title}}</title>
12
- <style>
13
- * {
14
- margin: 0;
15
- padding: 0;
16
- box-sizing: border-box;
17
- }
18
-
19
- body {
20
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
21
- line-height: 1.6;
22
- color: #333;
23
- background: #f8f9fa;
24
- display: flex;
25
- min-height: 100vh;
26
- }
27
-
28
- .sidebar {
29
- width: 280px;
30
- background: #fff;
31
- border-right: 1px solid #e9ecef;
32
- padding: 2rem 1rem;
33
- overflow-y: auto;
34
- position: fixed;
35
- height: 100vh;
36
- left: 0;
37
- top: 0;
38
- }
39
-
40
- .sidebar-header {
41
- margin-bottom: 2rem;
42
- padding-bottom: 1rem;
43
- border-bottom: 1px solid #e9ecef;
44
- }
45
-
46
- .sidebar-header h1 {
47
- font-size: 1.5rem;
48
- font-weight: 600;
49
- color: #212529;
50
- }
51
-
52
- .sidebar-header p {
53
- color: #6c757d;
54
- font-size: 0.875rem;
55
- margin-top: 0.5rem;
56
- }
57
-
58
- .nav-list {
59
- list-style: none;
60
- }
61
-
62
- .nav-item {
63
- margin-bottom: 0.5rem;
64
- }
65
-
66
- .nav-link {
67
- display: block;
68
- padding: 0.5rem 1rem;
69
- color: #495057;
70
- text-decoration: none;
71
- border-radius: 4px;
72
- transition: all 0.2s;
73
- }
74
-
75
- .nav-link:hover {
76
- background: #e9ecef;
77
- color: #212529;
78
- }
79
-
80
- .nav-link.active {
81
- background: #007bff;
82
- color: white;
83
- }
84
-
85
- .nav-submenu {
86
- list-style: none;
87
- margin-left: 1rem;
88
- margin-top: 0.25rem;
89
- }
90
-
91
- .content {
92
- flex: 1;
93
- margin-left: 280px;
94
- padding: 3rem 4rem;
95
- max-width: 900px;
96
- }
97
-
98
- .content-header {
99
- margin-bottom: 2rem;
100
- padding-bottom: 1rem;
101
- border-bottom: 1px solid #e9ecef;
102
- }
103
-
104
- .content-header h1 {
105
- font-size: 2.5rem;
106
- font-weight: 700;
107
- color: #212529;
108
- margin-bottom: 0.5rem;
109
- }
110
-
111
- .content-header .meta {
112
- color: #6c757d;
113
- font-size: 0.875rem;
114
- }
115
-
116
- .content-body {
117
- font-size: 1.125rem;
118
- line-height: 1.8;
119
- }
120
-
121
- .content-body h1 {
122
- font-size: 2rem;
123
- margin: 2rem 0 1rem;
124
- color: #212529;
125
- }
126
-
127
- .content-body h2 {
128
- font-size: 1.75rem;
129
- margin: 1.75rem 0 0.875rem;
130
- color: #343a40;
131
- }
132
-
133
- .content-body h3 {
134
- font-size: 1.5rem;
135
- margin: 1.5rem 0 0.75rem;
136
- color: #495057;
137
- }
138
-
139
- .content-body p {
140
- margin: 1rem 0;
141
- }
142
-
143
- .content-body ul, .content-body ol {
144
- margin: 1rem 0 1rem 2rem;
145
- }
146
-
147
- .content-body li {
148
- margin: 0.5rem 0;
149
- }
150
-
151
- .content-body blockquote {
152
- border-left: 4px solid #007bff;
153
- padding: 0.5rem 1rem;
154
- margin: 1rem 0;
155
- background: #f8f9fa;
156
- color: #495057;
157
- }
158
-
159
- .content-body code {
160
- background: #f8f9fa;
161
- padding: 0.2rem 0.4rem;
162
- border-radius: 3px;
163
- font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace;
164
- font-size: 0.875em;
165
- }
166
-
167
- .content-body pre {
168
- background: #f8f9fa;
169
- padding: 1rem;
170
- border-radius: 6px;
171
- overflow-x: auto;
172
- margin: 1rem 0;
173
- }
174
-
175
- .content-body pre code {
176
- background: none;
177
- padding: 0;
178
- }
179
-
180
- .content-body table {
181
- width: 100%;
182
- border-collapse: collapse;
183
- margin: 1rem 0;
184
- }
185
-
186
- .content-body th, .content-body td {
187
- border: 1px solid #dee2e6;
188
- padding: 0.75rem;
189
- text-align: left;
190
- }
191
-
192
- .content-body th {
193
- background: #f8f9fa;
194
- font-weight: 600;
195
- }
196
-
197
- .content-body img {
198
- max-width: 100%;
199
- height: auto;
200
- border-radius: 6px;
201
- margin: 1rem 0;
202
- }
203
-
204
- .content-body a {
205
- color: #007bff;
206
- text-decoration: none;
207
- }
208
-
209
- .content-body a:hover {
210
- text-decoration: underline;
211
- }
212
-
213
- .footer {
214
- margin-top: 3rem;
215
- padding-top: 2rem;
216
- border-top: 1px solid #e9ecef;
217
- color: #6c757d;
218
- font-size: 0.875rem;
219
- text-align: center;
220
- }
221
-
222
- @media (max-width: 768px) {
223
- body {
224
- flex-direction: column;
225
- }
226
-
227
- .sidebar {
228
- width: 100%;
229
- height: auto;
230
- position: static;
231
- border-right: none;
232
- border-bottom: 1px solid #e9ecef;
233
- }
234
-
235
- .content {
236
- margin-left: 0;
237
- padding: 2rem;
238
- }
239
- }
240
- </style>
241
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/styles/github.min.css">
242
- </head>
243
- <body>
244
- <nav class="sidebar">
245
- <div class="sidebar-header">
246
- <h1>ZEN Documentation</h1>
247
- <p>A minimalist Markdown documentation site builder</p>
248
- </div>
249
- {{navigation}}
250
- </nav>
251
-
252
- <main class="content">
253
- <header class="content-header">
254
- <h1>{{title}}</h1>
255
- </header>
256
-
257
- <article class="content-body">
258
- {{{content}}}
259
- </article>
260
-
261
- <footer class="footer">
262
- <p>Generated by <strong>ZEN</strong> • <a href="https://github.com/zccz14/ZEN" target="_blank">View on GitHub</a></p>
263
- </footer>
264
- </main>
265
-
266
- <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
267
- <script>hljs.highlightAll();</script>
268
- </body>
269
- </html>`;
270
-
271
- /**
272
- * 生成语言切换器 HTML
273
- */
274
- private generateLanguageSwitcher(currentLang: string, availableLangs: string[]): string {
275
- const langNames: Record<string, string> = {
276
- 'zh-Hans': '简体中文',
277
- 'en-US': 'English',
278
- 'ja-JP': '日本語',
279
- 'ko-KR': '한국어',
280
- };
281
-
282
- const items = availableLangs
283
- .map(lang => {
284
- const langName = langNames[lang] || lang;
285
- const isCurrent = lang === currentLang;
286
- const activeClass = isCurrent ? 'active' : '';
287
-
288
- return `<li class="lang-item ${activeClass}">
289
- <a href="?lang=${lang}" class="lang-link">${langName}</a>
290
- </li>`;
291
- })
292
- .join('');
293
-
294
- return `<div class="language-switcher">
295
- <span class="lang-label">Language:</span>
296
- <ul class="lang-list">${items}</ul>
297
- </div>`;
298
- }
299
-
300
- /**
301
- * 生成导航 HTML
302
- */
303
- private generateNavigationHtml(navigation: NavigationItem[], currentPath?: string): string {
304
- const renderItem = (item: NavigationItem): string => {
305
- const isActive = currentPath === item.path;
306
- const activeClass = isActive ? 'active' : '';
307
-
308
- let html = `<li class="nav-item">`;
309
- html += `<a href="${item.path}" class="nav-link ${activeClass}">${item.title}</a>`;
310
-
311
- if (item.children && item.children.length > 0) {
312
- html += `<ul class="nav-submenu">`;
313
- html += item.children.map(child => renderItem(child)).join('');
314
- html += `</ul>`;
315
- }
316
-
317
- html += `</li>`;
318
- return html;
319
- };
320
-
321
- return `<ul class="nav-list">${navigation.map(item => renderItem(item)).join('')}</ul>`;
322
- }
323
-
324
- /**
325
- * 简单的模板变量替换
326
- */
327
- private renderTemplate(template: string, data: TemplateData): string {
328
- let result = template;
329
-
330
- // 替换导航
331
- const navigationHtml = this.generateNavigationHtml(data.navigation, data.currentPath);
332
- result = result.replace('{{navigation}}', navigationHtml);
333
-
334
- // 替换其他变量 - 使用全局替换
335
- result = result.replace(/{{title}}/g, data.title || 'Untitled');
336
- result = result.replace(/{{{content}}}/g, data.content || '');
337
-
338
- // 替换元数据变量
339
- if (data.metadata) {
340
- result = result.replace(/{{summary}}/g, data.metadata.summary || '');
341
- result = result.replace(/{{tags}}/g, data.metadata.tags?.join(', ') || '');
342
- result = result.replace(/{{inferred_date}}/g, data.metadata.inferred_date || '');
343
- result = result.replace(/{{inferred_lang}}/g, data.metadata.inferred_lang || '');
344
- }
345
-
346
- // 替换语言相关变量
347
- result = result.replace(/{{lang}}/g, data.lang || '');
348
- if (data.availableLangs && data.availableLangs.length > 0 && data.lang) {
349
- const langSwitcher = this.generateLanguageSwitcher(data.lang, data.availableLangs);
350
- result = result.replace('{{language_switcher}}', langSwitcher);
351
- }
352
-
353
- return result;
354
- }
355
-
356
- /**
357
- * 渲染模板
358
- */
359
- async render(data: TemplateData, templatePath?: string): Promise<string> {
360
- let template = this.defaultTemplate;
361
-
362
- if (templatePath) {
363
- try {
364
- template = await fs.readFile(templatePath, 'utf-8');
365
- } catch (error) {
366
- console.warn(
367
- `Failed to load custom template from ${templatePath}, using default template:`,
368
- error
369
- );
370
- }
371
- }
372
-
373
- return this.renderTemplate(template, data);
374
- }
375
-
376
- /**
377
- * 从文件信息生成模板数据
378
- */
379
- generateTemplateData(
380
- fileInfo: FileInfo,
381
- navigation: NavigationItem[],
382
- lang?: string,
383
- availableLangs?: string[]
384
- ): TemplateData {
385
- // 优先使用 AI 元数据中的标题,其次使用文件元数据,最后使用文件名
386
- const title = fileInfo.aiMetadata?.title || fileInfo.metadata?.title || fileInfo.name;
387
-
388
- return {
389
- title,
390
- content: fileInfo.html || '',
391
- navigation,
392
- metadata: fileInfo.aiMetadata, // 使用完整的 AI 元数据
393
- currentPath: `/${fileInfo.path.replace(/\.md$/, '.html')}`,
394
- lang,
395
- availableLangs,
396
- };
397
- }
398
-
399
- /**
400
- * 生成输出文件路径
401
- */
402
- getOutputPath(fileInfo: FileInfo, outDir: string, lang?: string, hash?: string): string {
403
- if (lang && hash) {
404
- // 多语言模式:.zen/dist/{lang}/{hash}.html
405
- return path.join(outDir, lang, `${hash}.html`);
406
- } else {
407
- // 传统模式:保持目录结构
408
- const htmlFileName = `${fileInfo.name}.html`;
409
- const relativeDir = path.dirname(fileInfo.path);
410
- return path.join(outDir, relativeDir, htmlFileName);
411
- }
412
- }
413
-
414
- /**
415
- * 保存渲染结果到文件
416
- */
417
- async saveToFile(html: string, outputPath: string): Promise<void> {
418
- // 确保目录存在
419
- const dir = path.dirname(outputPath);
420
- await fs.mkdir(dir, { recursive: true });
421
-
422
- // 写入文件
423
- await fs.writeFile(outputPath, html, 'utf-8');
424
- }
425
- }