@knowcode/doc-builder 1.10.5 → 1.10.7
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/assets/css/notion-style.css +18 -16
- package/assets/js/main.js +31 -0
- package/lib/core-builder.js +45 -17
- package/package.json +1 -1
|
@@ -605,19 +605,19 @@ pre code {
|
|
|
605
605
|
}
|
|
606
606
|
|
|
607
607
|
.nav-section[data-level="1"] {
|
|
608
|
-
margin-left: var(--space-
|
|
608
|
+
margin-left: var(--space-2);
|
|
609
609
|
margin-bottom: var(--space-0-5);
|
|
610
610
|
}
|
|
611
611
|
|
|
612
612
|
.nav-section[data-level="2"] {
|
|
613
|
-
margin-left: var(--space-
|
|
613
|
+
margin-left: var(--space-4);
|
|
614
614
|
margin-bottom: var(--space-0-5);
|
|
615
615
|
}
|
|
616
616
|
|
|
617
617
|
.nav-title {
|
|
618
618
|
display: flex;
|
|
619
619
|
align-items: center;
|
|
620
|
-
padding: var(--space-
|
|
620
|
+
padding: var(--space-0-5) var(--space-3);
|
|
621
621
|
font-size: var(--text-sm);
|
|
622
622
|
font-weight: var(--font-medium);
|
|
623
623
|
color: var(--color-text-secondary);
|
|
@@ -629,11 +629,11 @@ pre code {
|
|
|
629
629
|
|
|
630
630
|
/* Indent nav titles based on their level */
|
|
631
631
|
.nav-section[data-level="1"] .nav-title {
|
|
632
|
-
padding-left: calc(var(--space-3) + var(--space-
|
|
632
|
+
padding-left: calc(var(--space-3) + var(--space-2));
|
|
633
633
|
}
|
|
634
634
|
|
|
635
635
|
.nav-section[data-level="2"] .nav-title {
|
|
636
|
-
padding-left: calc(var(--space-3) + var(--space-
|
|
636
|
+
padding-left: calc(var(--space-3) + var(--space-4));
|
|
637
637
|
}
|
|
638
638
|
|
|
639
639
|
.nav-title:hover {
|
|
@@ -668,27 +668,27 @@ pre code {
|
|
|
668
668
|
.nav-item {
|
|
669
669
|
display: flex;
|
|
670
670
|
align-items: center;
|
|
671
|
-
padding: var(--space-
|
|
671
|
+
padding: var(--space-0-5) var(--space-3);
|
|
672
672
|
font-size: var(--text-sm);
|
|
673
673
|
color: var(--color-text-primary);
|
|
674
674
|
text-decoration: none;
|
|
675
675
|
border-radius: var(--radius-md);
|
|
676
676
|
transition: all var(--duration-fast) var(--easing-out);
|
|
677
677
|
margin-bottom: 0;
|
|
678
|
-
gap: var(--space-
|
|
678
|
+
gap: var(--space-1);
|
|
679
679
|
}
|
|
680
680
|
|
|
681
681
|
/* Indent nav items based on their parent section level */
|
|
682
682
|
.nav-section[data-level="0"] .nav-item {
|
|
683
|
-
padding-left: calc(var(--space-3) + var(--space-
|
|
683
|
+
padding-left: calc(var(--space-3) + var(--space-3));
|
|
684
684
|
}
|
|
685
685
|
|
|
686
686
|
.nav-section[data-level="1"] .nav-item {
|
|
687
|
-
padding-left: calc(var(--space-3) + var(--space-
|
|
687
|
+
padding-left: calc(var(--space-3) + var(--space-5));
|
|
688
688
|
}
|
|
689
689
|
|
|
690
690
|
.nav-section[data-level="2"] .nav-item {
|
|
691
|
-
padding-left: calc(var(--space-3) + var(--space-
|
|
691
|
+
padding-left: calc(var(--space-3) + var(--space-6));
|
|
692
692
|
}
|
|
693
693
|
|
|
694
694
|
.nav-item:hover {
|
|
@@ -1031,7 +1031,8 @@ tr:hover {
|
|
|
1031
1031
|
white-space: nowrap;
|
|
1032
1032
|
}
|
|
1033
1033
|
|
|
1034
|
-
/* PDF
|
|
1034
|
+
/* MD and PDF buttons in breadcrumbs */
|
|
1035
|
+
.breadcrumb-md-btn,
|
|
1035
1036
|
.breadcrumb-pdf-btn {
|
|
1036
1037
|
background: none;
|
|
1037
1038
|
border: none;
|
|
@@ -1043,6 +1044,7 @@ tr:hover {
|
|
|
1043
1044
|
font-size: 1rem;
|
|
1044
1045
|
}
|
|
1045
1046
|
|
|
1047
|
+
.breadcrumb-md-btn:hover,
|
|
1046
1048
|
.breadcrumb-pdf-btn:hover {
|
|
1047
1049
|
background: var(--color-bg-tertiary);
|
|
1048
1050
|
color: var(--color-text-primary);
|
|
@@ -1979,8 +1981,8 @@ tr:hover {
|
|
|
1979
1981
|
.nav-title {
|
|
1980
1982
|
display: flex;
|
|
1981
1983
|
align-items: center;
|
|
1982
|
-
gap: var(--space-
|
|
1983
|
-
padding: var(--space-
|
|
1984
|
+
gap: var(--space-1);
|
|
1985
|
+
padding: var(--space-1);
|
|
1984
1986
|
color: var(--color-text-primary);
|
|
1985
1987
|
text-decoration: none;
|
|
1986
1988
|
font-size: var(--text-sm);
|
|
@@ -2029,14 +2031,14 @@ tr:hover {
|
|
|
2029
2031
|
.nav-item {
|
|
2030
2032
|
display: flex;
|
|
2031
2033
|
align-items: center;
|
|
2032
|
-
gap: var(--space-
|
|
2033
|
-
padding: var(--space-
|
|
2034
|
+
gap: var(--space-1);
|
|
2035
|
+
padding: var(--space-0-5) var(--space-2);
|
|
2034
2036
|
color: var(--color-text-secondary);
|
|
2035
2037
|
text-decoration: none;
|
|
2036
2038
|
font-size: var(--text-sm);
|
|
2037
2039
|
border-radius: var(--radius-md);
|
|
2038
2040
|
transition: all var(--duration-fast);
|
|
2039
|
-
margin-bottom:
|
|
2041
|
+
margin-bottom: 0;
|
|
2040
2042
|
}
|
|
2041
2043
|
|
|
2042
2044
|
.nav-item:hover {
|
package/assets/js/main.js
CHANGED
|
@@ -1296,6 +1296,31 @@ function initNavigationFilter() {
|
|
|
1296
1296
|
});
|
|
1297
1297
|
}
|
|
1298
1298
|
|
|
1299
|
+
// Markdown Download functionality
|
|
1300
|
+
function downloadMarkdown() {
|
|
1301
|
+
// Get current page path and convert to .md
|
|
1302
|
+
let currentPath = window.location.pathname;
|
|
1303
|
+
|
|
1304
|
+
// Handle different path formats
|
|
1305
|
+
if (currentPath.endsWith('/')) {
|
|
1306
|
+
currentPath += 'index.html';
|
|
1307
|
+
}
|
|
1308
|
+
if (!currentPath.endsWith('.html')) {
|
|
1309
|
+
currentPath += '.html';
|
|
1310
|
+
}
|
|
1311
|
+
|
|
1312
|
+
// Replace .html with .md
|
|
1313
|
+
const mdPath = currentPath.replace(/\.html$/, '.md');
|
|
1314
|
+
|
|
1315
|
+
// Create a link and trigger download
|
|
1316
|
+
const link = document.createElement('a');
|
|
1317
|
+
link.href = mdPath;
|
|
1318
|
+
link.download = mdPath.split('/').pop(); // Get filename
|
|
1319
|
+
document.body.appendChild(link);
|
|
1320
|
+
link.click();
|
|
1321
|
+
document.body.removeChild(link);
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1299
1324
|
// PDF Export functionality
|
|
1300
1325
|
function exportToPDF() {
|
|
1301
1326
|
// Hide UI elements for printing
|
|
@@ -1588,6 +1613,9 @@ function generateBreadcrumbs() {
|
|
|
1588
1613
|
<div class="breadcrumbs-content breadcrumbs-homepage">
|
|
1589
1614
|
<div class="breadcrumbs-right">
|
|
1590
1615
|
<span class="breadcrumb-date" title="Built with doc-builder v${docBuilderVersion || ''}">Last updated: ${displayDate}</span>
|
|
1616
|
+
<button class="breadcrumb-md-btn" onclick="downloadMarkdown()" title="Download Markdown" aria-label="Download Markdown">
|
|
1617
|
+
<i class="fas fa-file-code"></i>
|
|
1618
|
+
</button>
|
|
1591
1619
|
<button class="breadcrumb-pdf-btn" onclick="exportToPDF()" title="Export to PDF" aria-label="Export to PDF">
|
|
1592
1620
|
<i class="fas fa-file-pdf"></i>
|
|
1593
1621
|
</button>
|
|
@@ -1605,6 +1633,9 @@ function generateBreadcrumbs() {
|
|
|
1605
1633
|
</div>
|
|
1606
1634
|
<div class="breadcrumbs-right">
|
|
1607
1635
|
<span class="breadcrumb-date" title="Built with doc-builder v${docBuilderVersion || ''}">Last updated: ${displayDate}</span>
|
|
1636
|
+
<button class="breadcrumb-md-btn" onclick="downloadMarkdown()" title="Download Markdown" aria-label="Download Markdown">
|
|
1637
|
+
<i class="fas fa-file-code"></i>
|
|
1638
|
+
</button>
|
|
1608
1639
|
<button class="breadcrumb-pdf-btn" onclick="exportToPDF()" title="Export to PDF" aria-label="Export to PDF">
|
|
1609
1640
|
<i class="fas fa-file-pdf"></i>
|
|
1610
1641
|
</button>
|
package/lib/core-builder.js
CHANGED
|
@@ -349,21 +349,16 @@ function processMarkdownContent(content, config = {}) {
|
|
|
349
349
|
|
|
350
350
|
// Parse the markdown
|
|
351
351
|
let html = marked.parse(processedContent);
|
|
352
|
-
|
|
352
|
+
|
|
353
353
|
// Replace placeholders with actual mermaid blocks
|
|
354
354
|
mermaidBlocks.forEach((block, index) => {
|
|
355
355
|
html = html.replace(`<p>MERMAID_BLOCK_${index}</p>`, block);
|
|
356
356
|
html = html.replace(`MERMAID_BLOCK_${index}`, block);
|
|
357
357
|
});
|
|
358
|
-
|
|
359
|
-
// Convert internal .md links to .html links
|
|
360
|
-
// Matches href="...md" or href='...md' and converts to .html
|
|
361
|
-
// Handles: file.md, path/file.md, file.md#anchor, file.md?query
|
|
362
|
-
html = html.replace(/href=(["'])([^"']*?)\.md((?:#[^"']*)?(?:\?[^"']*)?)\1/gi, 'href=$1$2.html$3$1');
|
|
363
|
-
|
|
358
|
+
|
|
364
359
|
// Replace emojis with Phosphor icons if enabled
|
|
365
360
|
html = replaceEmojisWithIcons(html, config);
|
|
366
|
-
|
|
361
|
+
|
|
367
362
|
return html;
|
|
368
363
|
}
|
|
369
364
|
|
|
@@ -418,7 +413,12 @@ function generateHTML(title, content, navigation, currentPath = '', config = {},
|
|
|
418
413
|
// Get doc-builder version from package.json
|
|
419
414
|
const packageJson = require('../package.json');
|
|
420
415
|
const docBuilderVersion = packageJson.version;
|
|
421
|
-
|
|
416
|
+
|
|
417
|
+
// Extract source metadata if available
|
|
418
|
+
const sourceMetadata = config._sourceMetadata || {};
|
|
419
|
+
const sourcePath = sourceMetadata.sourcePath || '';
|
|
420
|
+
const generatedAt = sourceMetadata.generatedAt || new Date().toISOString();
|
|
421
|
+
|
|
422
422
|
// SEO preparation
|
|
423
423
|
let seoTags = '';
|
|
424
424
|
let jsonLd = '';
|
|
@@ -503,7 +503,11 @@ function generateHTML(title, content, navigation, currentPath = '', config = {},
|
|
|
503
503
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
504
504
|
<meta name="description" content="${escapeHtml(pageDescription || generateDescription(originalContent || content) || siteDescription)}">
|
|
505
505
|
<title>${escapeHtml(finalSeoTitle || `${title} - ${siteName}`)}</title>
|
|
506
|
-
|
|
506
|
+
|
|
507
|
+
<!-- Source metadata -->
|
|
508
|
+
${sourcePath ? `<meta name="md-source" content="${escapeHtml(sourcePath)}">` : ''}
|
|
509
|
+
<meta name="doc-generated" content="${escapeHtml(generatedAt)}">
|
|
510
|
+
|
|
507
511
|
${seoTags}
|
|
508
512
|
|
|
509
513
|
<!-- Fonts -->
|
|
@@ -796,6 +800,9 @@ ${seoTags}
|
|
|
796
800
|
minute: '2-digit',
|
|
797
801
|
timeZone: 'UTC'
|
|
798
802
|
})} UTC</span>
|
|
803
|
+
<button class="breadcrumb-md-btn" onclick="downloadMarkdown()" title="Download Markdown" aria-label="Download Markdown">
|
|
804
|
+
<i class="fas fa-file-code"></i>
|
|
805
|
+
</button>
|
|
799
806
|
<button class="breadcrumb-pdf-btn" onclick="if(typeof exportToPDF !== 'undefined') exportToPDF(); else window.print();" title="Export to PDF" aria-label="Export to PDF">
|
|
800
807
|
<i class="fas fa-file-pdf"></i>
|
|
801
808
|
</button>
|
|
@@ -838,6 +845,13 @@ ${seoTags}
|
|
|
838
845
|
mermaidEnhanced: ${config.features?.mermaidEnhanced !== false}
|
|
839
846
|
}
|
|
840
847
|
};
|
|
848
|
+
|
|
849
|
+
// Source metadata for JS consumers
|
|
850
|
+
window.__DOC_SOURCE__ = {
|
|
851
|
+
mdSource: ${sourcePath ? `"${escapeHtml(sourcePath)}"` : 'null'},
|
|
852
|
+
generatedAt: "${escapeHtml(generatedAt)}",
|
|
853
|
+
docBuilderVersion: "${docBuilderVersion}"
|
|
854
|
+
};
|
|
841
855
|
</script>
|
|
842
856
|
<script src="${resourcePath}js/main.js"></script>
|
|
843
857
|
${(config.features?.authentication === 'supabase' || config.features?.privateDirectoryAuth === true) ? `<script src="https://unpkg.com/@supabase/supabase-js@2"></script>
|
|
@@ -1145,21 +1159,35 @@ async function processMarkdownFile(filePath, outputPath, allFiles, config, useSt
|
|
|
1145
1159
|
|
|
1146
1160
|
// Process content
|
|
1147
1161
|
const htmlContent = processMarkdownContent(content, config);
|
|
1148
|
-
|
|
1162
|
+
|
|
1163
|
+
// Create config with source metadata for HTML generation
|
|
1164
|
+
const generationTimestamp = new Date().toISOString();
|
|
1165
|
+
const htmlConfig = {
|
|
1166
|
+
...config,
|
|
1167
|
+
_sourceMetadata: {
|
|
1168
|
+
sourcePath: relativePath, // e.g., "docs/technical/local-dev-troubleshooting.md"
|
|
1169
|
+
generatedAt: generationTimestamp
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
|
|
1149
1173
|
// Build navigation - pass config to handle private file filtering
|
|
1150
1174
|
// For static HTML, we need to build navigation with relative paths
|
|
1151
|
-
const navConfig = useStaticHTML ? { ...
|
|
1175
|
+
const navConfig = useStaticHTML ? { ...htmlConfig, isStaticOutput: true } : htmlConfig;
|
|
1152
1176
|
const navigation = buildNavigationStructure(allFiles, urlPath, navConfig);
|
|
1153
|
-
|
|
1177
|
+
|
|
1154
1178
|
// Generate full HTML (pass original content and front matter for SEO)
|
|
1155
|
-
const html = useStaticHTML
|
|
1156
|
-
? generateStaticHTML(title, htmlContent, navigation, urlPath,
|
|
1157
|
-
: generateHTML(title, htmlContent, navigation, urlPath,
|
|
1179
|
+
const html = useStaticHTML
|
|
1180
|
+
? generateStaticHTML(title, htmlContent, navigation, urlPath, htmlConfig, content, frontMatter)
|
|
1181
|
+
: generateHTML(title, htmlContent, navigation, urlPath, htmlConfig, content, frontMatter);
|
|
1158
1182
|
|
|
1159
1183
|
// Write file
|
|
1160
1184
|
await fs.ensureDir(path.dirname(outputPath));
|
|
1161
1185
|
await fs.writeFile(outputPath, html);
|
|
1162
|
-
|
|
1186
|
+
|
|
1187
|
+
// Copy source .md file alongside HTML for download
|
|
1188
|
+
const mdOutputPath = outputPath.replace(/\.html$/, '.md');
|
|
1189
|
+
await fs.copyFile(filePath, mdOutputPath);
|
|
1190
|
+
|
|
1163
1191
|
return { title, urlPath, summary, frontMatter };
|
|
1164
1192
|
}
|
|
1165
1193
|
|