@knowcode/doc-builder 1.5.4 → 1.5.6
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/CHANGELOG.md +39 -0
- package/CLAUDE.md +3 -0
- package/README.md +41 -0
- package/cli.js +173 -0
- package/html/README.html +12 -11
- package/html/documentation-index.html +12 -11
- package/html/guides/authentication-guide.html +12 -11
- package/html/guides/claude-workflow-guide.html +12 -11
- package/html/guides/documentation-standards.html +12 -11
- package/html/guides/google-site-verification-guide.html +12 -11
- package/html/guides/seo-guide.html +12 -11
- package/html/guides/seo-optimization-guide.html +493 -0
- package/html/guides/troubleshooting-guide.html +12 -11
- package/html/index.html +12 -11
- package/html/sitemap.xml +20 -14
- package/html/vercel-cli-setup-guide.html +12 -11
- package/html/vercel-first-time-setup-guide.html +12 -11
- package/lib/config.js +4 -0
- package/lib/core-builder.js +40 -19
- package/lib/seo.js +44 -7
- package/package.json +2 -1
package/html/sitemap.xml
CHANGED
|
@@ -2,85 +2,91 @@
|
|
|
2
2
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
3
3
|
<url>
|
|
4
4
|
<loc>https://doc-builder-delta.vercel.app/404.html</loc>
|
|
5
|
-
<lastmod>2025-07-
|
|
5
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
6
6
|
<changefreq>monthly</changefreq>
|
|
7
7
|
<priority>0.6</priority>
|
|
8
8
|
</url>
|
|
9
9
|
<url>
|
|
10
10
|
<loc>https://doc-builder-delta.vercel.app/README.html</loc>
|
|
11
|
-
<lastmod>2025-07-
|
|
11
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
12
12
|
<changefreq>monthly</changefreq>
|
|
13
13
|
<priority>0.6</priority>
|
|
14
14
|
</url>
|
|
15
15
|
<url>
|
|
16
16
|
<loc>https://doc-builder-delta.vercel.app/claude-workflow-guide.html</loc>
|
|
17
|
-
<lastmod>2025-07-
|
|
17
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
18
18
|
<changefreq>monthly</changefreq>
|
|
19
19
|
<priority>0.8</priority>
|
|
20
20
|
</url>
|
|
21
21
|
<url>
|
|
22
22
|
<loc>https://doc-builder-delta.vercel.app/documentation-index.html</loc>
|
|
23
|
-
<lastmod>2025-07-
|
|
23
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
24
24
|
<changefreq>monthly</changefreq>
|
|
25
25
|
<priority>0.6</priority>
|
|
26
26
|
</url>
|
|
27
27
|
<url>
|
|
28
28
|
<loc>https://doc-builder-delta.vercel.app/guides/authentication-guide.html</loc>
|
|
29
|
-
<lastmod>2025-07-
|
|
29
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
30
30
|
<changefreq>monthly</changefreq>
|
|
31
31
|
<priority>0.8</priority>
|
|
32
32
|
</url>
|
|
33
33
|
<url>
|
|
34
34
|
<loc>https://doc-builder-delta.vercel.app/guides/claude-workflow-guide.html</loc>
|
|
35
|
-
<lastmod>2025-07-
|
|
35
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
36
36
|
<changefreq>monthly</changefreq>
|
|
37
37
|
<priority>0.8</priority>
|
|
38
38
|
</url>
|
|
39
39
|
<url>
|
|
40
40
|
<loc>https://doc-builder-delta.vercel.app/guides/document-standards.html</loc>
|
|
41
|
-
<lastmod>2025-07-
|
|
41
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
42
42
|
<changefreq>monthly</changefreq>
|
|
43
43
|
<priority>0.8</priority>
|
|
44
44
|
</url>
|
|
45
45
|
<url>
|
|
46
46
|
<loc>https://doc-builder-delta.vercel.app/guides/documentation-standards.html</loc>
|
|
47
|
-
<lastmod>2025-07-
|
|
47
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
48
48
|
<changefreq>monthly</changefreq>
|
|
49
49
|
<priority>0.8</priority>
|
|
50
50
|
</url>
|
|
51
51
|
<url>
|
|
52
52
|
<loc>https://doc-builder-delta.vercel.app/guides/google-site-verification-guide.html</loc>
|
|
53
|
-
<lastmod>2025-07-
|
|
53
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
54
54
|
<changefreq>monthly</changefreq>
|
|
55
55
|
<priority>0.8</priority>
|
|
56
56
|
</url>
|
|
57
57
|
<url>
|
|
58
58
|
<loc>https://doc-builder-delta.vercel.app/guides/seo-guide.html</loc>
|
|
59
|
-
<lastmod>2025-07-
|
|
59
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
60
|
+
<changefreq>monthly</changefreq>
|
|
61
|
+
<priority>0.8</priority>
|
|
62
|
+
</url>
|
|
63
|
+
<url>
|
|
64
|
+
<loc>https://doc-builder-delta.vercel.app/guides/seo-optimization-guide.html</loc>
|
|
65
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
60
66
|
<changefreq>monthly</changefreq>
|
|
61
67
|
<priority>0.8</priority>
|
|
62
68
|
</url>
|
|
63
69
|
<url>
|
|
64
70
|
<loc>https://doc-builder-delta.vercel.app/guides/troubleshooting-guide.html</loc>
|
|
65
|
-
<lastmod>2025-07-
|
|
71
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
66
72
|
<changefreq>monthly</changefreq>
|
|
67
73
|
<priority>0.8</priority>
|
|
68
74
|
</url>
|
|
69
75
|
<url>
|
|
70
76
|
<loc>https://doc-builder-delta.vercel.app/index.html</loc>
|
|
71
|
-
<lastmod>2025-07-
|
|
77
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
72
78
|
<changefreq>weekly</changefreq>
|
|
73
79
|
<priority>1.0</priority>
|
|
74
80
|
</url>
|
|
75
81
|
<url>
|
|
76
82
|
<loc>https://doc-builder-delta.vercel.app/vercel-cli-setup-guide.html</loc>
|
|
77
|
-
<lastmod>2025-07-
|
|
83
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
78
84
|
<changefreq>monthly</changefreq>
|
|
79
85
|
<priority>0.8</priority>
|
|
80
86
|
</url>
|
|
81
87
|
<url>
|
|
82
88
|
<loc>https://doc-builder-delta.vercel.app/vercel-first-time-setup-guide.html</loc>
|
|
83
|
-
<lastmod>2025-07-
|
|
89
|
+
<lastmod>2025-07-22T08:09:57.928Z</lastmod>
|
|
84
90
|
<changefreq>monthly</changefreq>
|
|
85
91
|
<priority>0.8</priority>
|
|
86
92
|
</url>
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<meta name="description" content="
|
|
7
|
-
<title>Vercel CLI Setup Guide
|
|
6
|
+
<meta name="description" content="Generated: 2025-07-21 20:30 UTC">
|
|
7
|
+
<title>Vercel CLI Setup Guide | Doc Builder</title>
|
|
8
8
|
|
|
9
9
|
<meta name="author" content="Lindsay Smith">
|
|
10
|
-
<meta name="keywords" content="documentation, markdown, static site generator, vercel, notion-style, https, com
|
|
10
|
+
<meta name="keywords" content="documentation, markdown, static site generator, vercel, notion-style, https, com">
|
|
11
11
|
<meta name="robots" content="index, follow">
|
|
12
12
|
<link rel="canonical" href="https://doc-builder-delta.vercel.app/vercel-cli-setup-guide.html">
|
|
13
13
|
|
|
14
14
|
<!-- Open Graph / Facebook -->
|
|
15
15
|
<meta property="og:type" content="article">
|
|
16
16
|
<meta property="og:url" content="https://doc-builder-delta.vercel.app/vercel-cli-setup-guide.html">
|
|
17
|
-
<meta property="og:title" content="Vercel CLI Setup Guide
|
|
18
|
-
<meta property="og:description" content="
|
|
17
|
+
<meta property="og:title" content="Vercel CLI Setup Guide | Doc Builder">
|
|
18
|
+
<meta property="og:description" content="Generated: 2025-07-21 20:30 UTC">
|
|
19
19
|
<meta property="og:image" content="https://doc-builder-delta.vercel.app/og-default.png">
|
|
20
20
|
<meta property="og:site_name" content="Doc Builder">
|
|
21
21
|
<meta property="og:locale" content="en_US">
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
<meta name="twitter:card" content="summary_large_image">
|
|
25
25
|
<meta name="twitter:site" content="@planbbackups">
|
|
26
26
|
<meta name="twitter:creator" content="@planbbackups">
|
|
27
|
-
<meta name="twitter:title" content="Vercel CLI Setup Guide
|
|
28
|
-
<meta name="twitter:description" content="
|
|
27
|
+
<meta name="twitter:title" content="Vercel CLI Setup Guide | Doc Builder">
|
|
28
|
+
<meta name="twitter:description" content="Generated: 2025-07-21 20:30 UTC">
|
|
29
29
|
<meta name="twitter:image" content="https://doc-builder-delta.vercel.app/og-default.png">
|
|
30
30
|
|
|
31
31
|
<!-- Custom Meta Tags -->
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@context": "https://schema.org",
|
|
52
52
|
"@type": "TechArticle",
|
|
53
53
|
"headline": "Vercel CLI Setup Guide",
|
|
54
|
-
"description": "
|
|
54
|
+
"description": "Generated: 2025-07-21 20:30 UTC",
|
|
55
55
|
"author": {
|
|
56
56
|
"@type": "Person",
|
|
57
57
|
"name": "Lindsay Smith"
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"name": "Knowcode Ltd",
|
|
62
62
|
"url": "https://knowcode.tech"
|
|
63
63
|
},
|
|
64
|
-
"datePublished": "2025-07-
|
|
65
|
-
"dateModified": "2025-07-
|
|
64
|
+
"datePublished": "2025-07-22T08:09:57.912Z",
|
|
65
|
+
"dateModified": "2025-07-22T08:09:57.912Z",
|
|
66
66
|
"mainEntityOfPage": {
|
|
67
67
|
"@type": "WebPage",
|
|
68
68
|
"@id": "https://doc-builder-delta.vercel.app/vercel-cli-setup-guide.html"
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
|
|
96
96
|
<div class="header-actions">
|
|
97
97
|
<div class="deployment-info">
|
|
98
|
-
<span class="deployment-date" title="Built with doc-builder v1.5.
|
|
98
|
+
<span class="deployment-date" title="Built with doc-builder v1.5.5">Last updated: Jul 22, 2025, 08:09 AM UTC</span>
|
|
99
99
|
</div>
|
|
100
100
|
|
|
101
101
|
|
|
@@ -158,6 +158,7 @@
|
|
|
158
158
|
<a href="/guides/documentation-standards.html" class="nav-item" data-tooltip="This document defines the documentation standards and conventions for the @knowcode/doc-builder project."><i class="fas fa-file-alt"></i> Documentation Standards</a>
|
|
159
159
|
<a href="/guides/google-site-verification-guide.html" class="nav-item" data-tooltip="Google Search Console verification allows you to: Monitor your site's performance in Google Search Submit sitemaps for better indexing View search..."><i class="fas fa-file-alt"></i> Google Site Verification Guide</a>
|
|
160
160
|
<a href="/guides/seo-guide.html" class="nav-item" data-tooltip="@knowcode/doc-builder includes comprehensive SEO (Search Engine Optimization) features to help your documentation rank better in search results and..."><i class="fas fa-file-alt"></i> Seo Guide</a>
|
|
161
|
+
<a href="/guides/seo-optimization-guide.html" class="nav-item" data-tooltip="Good SEO helps your documentation: Rank higher in search results Get more organic traffic Improve click-through rates Reach the right audience Build..."><i class="fas fa-file-alt"></i> Seo Optimization Guide</a>
|
|
161
162
|
<a href="/guides/troubleshooting-guide.html" class="nav-item" data-tooltip="This guide helps you resolve common issues when using @knowcode/doc-builder."><i class="fas fa-file-alt"></i> Troubleshooting Guide</a></div></div>
|
|
162
163
|
</nav>
|
|
163
164
|
<div class="resize-handle"></div>
|
|
@@ -3,19 +3,19 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<meta name="description" content="
|
|
7
|
-
<title>Vercel First-Time Setup Guide - Complete Prompt-by
|
|
6
|
+
<meta name="description" content="Generated: 2025-07-21 20:45 UTC">
|
|
7
|
+
<title>Vercel First-Time Setup Guide - Complete Prompt-by...</title>
|
|
8
8
|
|
|
9
9
|
<meta name="author" content="Lindsay Smith">
|
|
10
|
-
<meta name="keywords" content="documentation, markdown, static site generator, vercel, notion-style, project, your
|
|
10
|
+
<meta name="keywords" content="documentation, markdown, static site generator, vercel, notion-style, project, your">
|
|
11
11
|
<meta name="robots" content="index, follow">
|
|
12
12
|
<link rel="canonical" href="https://doc-builder-delta.vercel.app/vercel-first-time-setup-guide.html">
|
|
13
13
|
|
|
14
14
|
<!-- Open Graph / Facebook -->
|
|
15
15
|
<meta property="og:type" content="article">
|
|
16
16
|
<meta property="og:url" content="https://doc-builder-delta.vercel.app/vercel-first-time-setup-guide.html">
|
|
17
|
-
<meta property="og:title" content="Vercel First-Time Setup Guide - Complete Prompt-by
|
|
18
|
-
<meta property="og:description" content="
|
|
17
|
+
<meta property="og:title" content="Vercel First-Time Setup Guide - Complete Prompt-by...">
|
|
18
|
+
<meta property="og:description" content="Generated: 2025-07-21 20:45 UTC">
|
|
19
19
|
<meta property="og:image" content="https://doc-builder-delta.vercel.app/og-default.png">
|
|
20
20
|
<meta property="og:site_name" content="Doc Builder">
|
|
21
21
|
<meta property="og:locale" content="en_US">
|
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
<meta name="twitter:card" content="summary_large_image">
|
|
25
25
|
<meta name="twitter:site" content="@planbbackups">
|
|
26
26
|
<meta name="twitter:creator" content="@planbbackups">
|
|
27
|
-
<meta name="twitter:title" content="Vercel First-Time Setup Guide - Complete Prompt-by
|
|
28
|
-
<meta name="twitter:description" content="
|
|
27
|
+
<meta name="twitter:title" content="Vercel First-Time Setup Guide - Complete Prompt-by...">
|
|
28
|
+
<meta name="twitter:description" content="Generated: 2025-07-21 20:45 UTC">
|
|
29
29
|
<meta name="twitter:image" content="https://doc-builder-delta.vercel.app/og-default.png">
|
|
30
30
|
|
|
31
31
|
<!-- Custom Meta Tags -->
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"@context": "https://schema.org",
|
|
52
52
|
"@type": "TechArticle",
|
|
53
53
|
"headline": "Vercel First-Time Setup Guide - Complete Prompt-by-Prompt Walkthrough",
|
|
54
|
-
"description": "
|
|
54
|
+
"description": "Generated: 2025-07-21 20:45 UTC",
|
|
55
55
|
"author": {
|
|
56
56
|
"@type": "Person",
|
|
57
57
|
"name": "Lindsay Smith"
|
|
@@ -61,8 +61,8 @@
|
|
|
61
61
|
"name": "Knowcode Ltd",
|
|
62
62
|
"url": "https://knowcode.tech"
|
|
63
63
|
},
|
|
64
|
-
"datePublished": "2025-07-
|
|
65
|
-
"dateModified": "2025-07-
|
|
64
|
+
"datePublished": "2025-07-22T08:09:57.916Z",
|
|
65
|
+
"dateModified": "2025-07-22T08:09:57.916Z",
|
|
66
66
|
"mainEntityOfPage": {
|
|
67
67
|
"@type": "WebPage",
|
|
68
68
|
"@id": "https://doc-builder-delta.vercel.app/vercel-first-time-setup-guide.html"
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
|
|
96
96
|
<div class="header-actions">
|
|
97
97
|
<div class="deployment-info">
|
|
98
|
-
<span class="deployment-date" title="Built with doc-builder v1.5.
|
|
98
|
+
<span class="deployment-date" title="Built with doc-builder v1.5.5">Last updated: Jul 22, 2025, 08:09 AM UTC</span>
|
|
99
99
|
</div>
|
|
100
100
|
|
|
101
101
|
|
|
@@ -158,6 +158,7 @@
|
|
|
158
158
|
<a href="/guides/documentation-standards.html" class="nav-item" data-tooltip="This document defines the documentation standards and conventions for the @knowcode/doc-builder project."><i class="fas fa-file-alt"></i> Documentation Standards</a>
|
|
159
159
|
<a href="/guides/google-site-verification-guide.html" class="nav-item" data-tooltip="Google Search Console verification allows you to: Monitor your site's performance in Google Search Submit sitemaps for better indexing View search..."><i class="fas fa-file-alt"></i> Google Site Verification Guide</a>
|
|
160
160
|
<a href="/guides/seo-guide.html" class="nav-item" data-tooltip="@knowcode/doc-builder includes comprehensive SEO (Search Engine Optimization) features to help your documentation rank better in search results and..."><i class="fas fa-file-alt"></i> Seo Guide</a>
|
|
161
|
+
<a href="/guides/seo-optimization-guide.html" class="nav-item" data-tooltip="Good SEO helps your documentation: Rank higher in search results Get more organic traffic Improve click-through rates Reach the right audience Build..."><i class="fas fa-file-alt"></i> Seo Optimization Guide</a>
|
|
161
162
|
<a href="/guides/troubleshooting-guide.html" class="nav-item" data-tooltip="This guide helps you resolve common issues when using @knowcode/doc-builder."><i class="fas fa-file-alt"></i> Troubleshooting Guide</a></div></div>
|
|
162
163
|
</nav>
|
|
163
164
|
<div class="resize-handle"></div>
|
package/lib/config.js
CHANGED
|
@@ -55,6 +55,10 @@ const defaultConfig = {
|
|
|
55
55
|
twitterHandle: '',
|
|
56
56
|
language: 'en-US',
|
|
57
57
|
keywords: [],
|
|
58
|
+
titleTemplate: '{pageTitle} | {siteName}', // Customizable title format
|
|
59
|
+
autoKeywords: true, // Extract keywords from content
|
|
60
|
+
keywordLimit: 7, // Max keywords per page
|
|
61
|
+
descriptionFallback: 'smart', // 'smart' or 'first-paragraph'
|
|
58
62
|
organization: {
|
|
59
63
|
name: '',
|
|
60
64
|
url: '',
|
package/lib/core-builder.js
CHANGED
|
@@ -2,6 +2,7 @@ const fs = require('fs-extra');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const marked = require('marked');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
|
+
const matter = require('gray-matter');
|
|
5
6
|
const {
|
|
6
7
|
generateMetaTags,
|
|
7
8
|
generateJSONLD,
|
|
@@ -189,7 +190,7 @@ function processMarkdownContent(content) {
|
|
|
189
190
|
}
|
|
190
191
|
|
|
191
192
|
// Generate HTML from template
|
|
192
|
-
function generateHTML(title, content, navigation, currentPath = '', config = {}, originalContent = '') {
|
|
193
|
+
function generateHTML(title, content, navigation, currentPath = '', config = {}, originalContent = '', frontMatter = {}) {
|
|
193
194
|
const depth = currentPath.split('/').filter(p => p).length;
|
|
194
195
|
const relativePath = depth > 0 ? '../'.repeat(depth) : '';
|
|
195
196
|
|
|
@@ -203,24 +204,40 @@ function generateHTML(title, content, navigation, currentPath = '', config = {},
|
|
|
203
204
|
// SEO preparation
|
|
204
205
|
let seoTags = '';
|
|
205
206
|
let jsonLd = '';
|
|
207
|
+
let finalSeoTitle = `${title} - ${siteName}`;
|
|
208
|
+
let pageDescription = frontMatter.description ||
|
|
209
|
+
generateDescription(originalContent || content, config.seo?.descriptionFallback) ||
|
|
210
|
+
siteDescription;
|
|
206
211
|
|
|
207
212
|
if (config.seo?.enabled && config.seo?.siteUrl) {
|
|
208
213
|
// Generate page URL
|
|
209
214
|
const pageUrl = `${config.seo.siteUrl}/${currentPath}`;
|
|
210
215
|
|
|
211
|
-
// Extract
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
const
|
|
216
|
-
const keywords = [...new Set([...(config.seo.keywords || []), ...contentKeywords])]
|
|
216
|
+
// Extract keywords - priority: front matter > content extraction + global
|
|
217
|
+
const contentKeywords = config.seo?.autoKeywords !== false ?
|
|
218
|
+
extractKeywords(originalContent || content, config.seo?.keywordLimit || 7) :
|
|
219
|
+
[];
|
|
220
|
+
const pageKeywords = frontMatter.keywords || [];
|
|
221
|
+
const keywords = [...new Set([...(config.seo.keywords || []), ...pageKeywords, ...contentKeywords])]
|
|
222
|
+
.slice(0, config.seo?.keywordLimit || 7);
|
|
217
223
|
|
|
218
224
|
// Generate breadcrumbs
|
|
219
225
|
const breadcrumbs = generateBreadcrumbs(currentPath, config.seo.siteUrl, siteName);
|
|
220
226
|
|
|
227
|
+
// Generate SEO-optimized title
|
|
228
|
+
const titleTemplate = config.seo?.titleTemplate || '{pageTitle} | {siteName}';
|
|
229
|
+
const seoTitle = titleTemplate
|
|
230
|
+
.replace('{pageTitle}', title)
|
|
231
|
+
.replace('{siteName}', siteName);
|
|
232
|
+
|
|
233
|
+
// Ensure title is within 50-60 characters
|
|
234
|
+
finalSeoTitle = seoTitle.length > 60 ?
|
|
235
|
+
title.length > 50 ? title.substring(0, 50) + '...' : title
|
|
236
|
+
: seoTitle;
|
|
237
|
+
|
|
221
238
|
// Generate meta tags
|
|
222
239
|
seoTags = generateMetaTags({
|
|
223
|
-
title:
|
|
240
|
+
title: finalSeoTitle,
|
|
224
241
|
description: pageDescription,
|
|
225
242
|
url: pageUrl,
|
|
226
243
|
author: config.seo.author,
|
|
@@ -254,8 +271,8 @@ function generateHTML(title, content, navigation, currentPath = '', config = {},
|
|
|
254
271
|
<head>
|
|
255
272
|
<meta charset="UTF-8">
|
|
256
273
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
257
|
-
<meta name="description" content="${escapeHtml(generateDescription(originalContent || content) || siteDescription)}">
|
|
258
|
-
<title>${escapeHtml(title
|
|
274
|
+
<meta name="description" content="${escapeHtml(pageDescription || generateDescription(originalContent || content) || siteDescription)}">
|
|
275
|
+
<title>${escapeHtml(finalSeoTitle || `${title} - ${siteName}`)}</title>
|
|
259
276
|
|
|
260
277
|
${seoTags}
|
|
261
278
|
|
|
@@ -578,17 +595,21 @@ function buildNavigationStructure(files, currentFile) {
|
|
|
578
595
|
|
|
579
596
|
// Process single markdown file
|
|
580
597
|
async function processMarkdownFile(filePath, outputPath, allFiles, config) {
|
|
581
|
-
const
|
|
598
|
+
const rawContent = await fs.readFile(filePath, 'utf-8');
|
|
582
599
|
const fileName = path.basename(filePath, '.md');
|
|
583
600
|
const relativePath = path.relative(config.docsDir, filePath);
|
|
584
601
|
const urlPath = relativePath.replace(/\.md$/, '.html').replace(/\\/g, '/');
|
|
585
602
|
|
|
586
|
-
//
|
|
587
|
-
const
|
|
588
|
-
|
|
603
|
+
// Parse front matter
|
|
604
|
+
const { data: frontMatter, content } = matter(rawContent);
|
|
605
|
+
|
|
606
|
+
// Extract title - priority: front matter > H1 > filename
|
|
607
|
+
const h1Match = content.match(/^#\s+(.+)$/m);
|
|
608
|
+
const h1Title = h1Match ? h1Match[1] : null;
|
|
609
|
+
const title = frontMatter.title || h1Title || fileName;
|
|
589
610
|
|
|
590
|
-
// Extract summary for tooltip
|
|
591
|
-
const summary = extractSummary(content);
|
|
611
|
+
// Extract summary for tooltip - priority: front matter > auto-extract
|
|
612
|
+
const summary = frontMatter.description || extractSummary(content);
|
|
592
613
|
|
|
593
614
|
// Process content
|
|
594
615
|
const htmlContent = processMarkdownContent(content);
|
|
@@ -596,14 +617,14 @@ async function processMarkdownFile(filePath, outputPath, allFiles, config) {
|
|
|
596
617
|
// Build navigation
|
|
597
618
|
const navigation = buildNavigationStructure(allFiles, urlPath);
|
|
598
619
|
|
|
599
|
-
// Generate full HTML (pass original content for SEO)
|
|
600
|
-
const html = generateHTML(title, htmlContent, navigation, urlPath, config, content);
|
|
620
|
+
// Generate full HTML (pass original content and front matter for SEO)
|
|
621
|
+
const html = generateHTML(title, htmlContent, navigation, urlPath, config, content, frontMatter);
|
|
601
622
|
|
|
602
623
|
// Write file
|
|
603
624
|
await fs.ensureDir(path.dirname(outputPath));
|
|
604
625
|
await fs.writeFile(outputPath, html);
|
|
605
626
|
|
|
606
|
-
return { title, urlPath, summary };
|
|
627
|
+
return { title, urlPath, summary, frontMatter };
|
|
607
628
|
}
|
|
608
629
|
|
|
609
630
|
// Get all markdown files
|
package/lib/seo.js
CHANGED
|
@@ -48,23 +48,60 @@ function extractKeywords(content, maxKeywords = 10) {
|
|
|
48
48
|
/**
|
|
49
49
|
* Generate meta description from content
|
|
50
50
|
*/
|
|
51
|
-
function generateDescription(content, maxLength = 160) {
|
|
52
|
-
// Remove markdown syntax
|
|
51
|
+
function generateDescription(content, mode = 'smart', maxLength = 160) {
|
|
52
|
+
// Remove markdown syntax
|
|
53
53
|
const plainText = content
|
|
54
54
|
.replace(/```[\s\S]*?```/g, '') // Remove code blocks
|
|
55
|
+
.replace(/^---[\s\S]*?---/m, '') // Remove front matter
|
|
55
56
|
.replace(/#+\s(.+)/g, '$1. ') // Convert headers to sentences
|
|
56
57
|
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Extract link text
|
|
57
58
|
.replace(/[*_~]/g, '') // Remove emphasis
|
|
58
59
|
.replace(/\n+/g, ' ') // Replace newlines with spaces
|
|
59
60
|
.trim();
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
let description = '';
|
|
63
|
+
|
|
64
|
+
if (mode === 'smart') {
|
|
65
|
+
// Try to find intro paragraph after first header
|
|
66
|
+
const lines = content.split('\n');
|
|
67
|
+
let foundH1 = false;
|
|
68
|
+
let introText = '';
|
|
69
|
+
|
|
70
|
+
for (const line of lines) {
|
|
71
|
+
if (line.match(/^#\s+/)) {
|
|
72
|
+
foundH1 = true;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (foundH1 && line.trim() && !line.match(/^#/)) {
|
|
76
|
+
introText = line.trim();
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (introText) {
|
|
82
|
+
// Clean markdown from intro text
|
|
83
|
+
description = introText
|
|
84
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
85
|
+
.replace(/[*_~]/g, '');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Fallback to first paragraph
|
|
90
|
+
if (!description) {
|
|
91
|
+
const firstSentence = plainText.match(/^[^.!?]+[.!?]/);
|
|
92
|
+
description = firstSentence ? firstSentence[0] : plainText;
|
|
93
|
+
}
|
|
64
94
|
|
|
65
|
-
//
|
|
95
|
+
// Ensure optimal length (140-160 chars)
|
|
66
96
|
if (description.length > maxLength) {
|
|
67
|
-
|
|
97
|
+
// Try to cut at word boundary
|
|
98
|
+
const cutPoint = description.lastIndexOf(' ', maxLength - 3);
|
|
99
|
+
description = description.substring(0, cutPoint > 100 ? cutPoint : maxLength - 3) + '...';
|
|
100
|
+
} else if (description.length < 140 && description.length > 100) {
|
|
101
|
+
// Maybe add a call to action if too short
|
|
102
|
+
if (!description.match(/[.!?]$/)) {
|
|
103
|
+
description += '.';
|
|
104
|
+
}
|
|
68
105
|
}
|
|
69
106
|
|
|
70
107
|
return description;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knowcode/doc-builder",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.6",
|
|
4
4
|
"description": "Reusable documentation builder for markdown-based sites with Vercel deployment support",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
"chalk": "^4.1.2",
|
|
28
28
|
"commander": "^11.0.0",
|
|
29
29
|
"fs-extra": "^11.2.0",
|
|
30
|
+
"gray-matter": "^4.0.3",
|
|
30
31
|
"marked": "^15.0.12",
|
|
31
32
|
"ora": "5.4.1",
|
|
32
33
|
"prompts": "^2.4.2"
|