@mgks/docmd 0.2.0 → 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.
- package/assets/css/welcome.css +6 -66
- package/config.js +10 -5
- package/docs/configuration.md +11 -5
- package/docs/content/custom-containers.md +24 -0
- package/docs/content/no-style-example.md +2 -0
- package/docs/content/no-style-pages.md +52 -28
- package/docs/index.md +49 -18
- package/docs/plugins/seo.md +80 -33
- package/package.json +13 -7
- package/src/assets/css/docmd-main.css +5 -1167
- package/src/assets/css/docmd-theme-retro.css +3 -806
- package/src/assets/css/docmd-theme-ruby.css +7 -617
- package/src/assets/css/docmd-theme-sky.css +7 -650
- package/src/assets/js/docmd-image-lightbox.js +5 -1
- package/src/assets/js/docmd-main.js +89 -29
- package/src/commands/build.js +62 -120
- package/src/commands/dev.js +2 -1
- package/src/commands/init.js +4 -0
- package/src/core/config-loader.js +2 -0
- package/src/core/file-processor.js +130 -97
- package/src/core/html-generator.js +31 -12
- package/src/core/icon-renderer.js +3 -2
- package/src/plugins/analytics.js +5 -1
- package/src/plugins/seo.js +114 -66
- package/src/plugins/sitemap.js +6 -0
- package/src/templates/layout.ejs +8 -2
- package/src/templates/no-style.ejs +23 -6
- package/src/templates/partials/theme-init.js +26 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Source file from the docmd project — https://github.com/mgks/docmd
|
|
2
|
+
|
|
2
3
|
const fs = require('fs-extra');
|
|
3
4
|
const MarkdownIt = require('markdown-it');
|
|
4
5
|
const matter = require('gray-matter');
|
|
5
6
|
const hljs = require('highlight.js');
|
|
6
|
-
const container = require('markdown-it-container');
|
|
7
7
|
const attrs = require('markdown-it-attrs');
|
|
8
8
|
const path = require('path');
|
|
9
9
|
const markdown_it_footnote = require('markdown-it-footnote');
|
|
@@ -23,59 +23,79 @@ function formatPathForDisplay(absolutePath) {
|
|
|
23
23
|
return relativePath;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
26
|
+
function createMarkdownItInstance(config) {
|
|
27
|
+
const mdOptions = {
|
|
28
|
+
html: true,
|
|
29
|
+
linkify: true,
|
|
30
|
+
typographer: true,
|
|
31
|
+
breaks: true,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Conditionally enable highlighting
|
|
35
|
+
if (config.theme?.codeHighlight !== false) {
|
|
36
|
+
mdOptions.highlight = function (str, lang) {
|
|
37
|
+
if (lang && hljs.getLanguage(lang)) {
|
|
38
|
+
try {
|
|
39
|
+
return `<pre class="hljs"><code>${hljs.highlight(str, { language: lang, ignoreIllegals: true }).value}</code></pre>`;
|
|
40
|
+
} catch (e) { console.error(`Highlighting error for lang ${lang}:`, e); }
|
|
41
|
+
}
|
|
42
|
+
return `<pre class="hljs"><code>${new MarkdownIt().utils.escapeHtml(str)}</code></pre>`;
|
|
43
|
+
};
|
|
42
44
|
}
|
|
43
|
-
});
|
|
44
45
|
|
|
46
|
+
const md = new MarkdownIt(mdOptions);
|
|
45
47
|
|
|
48
|
+
// --- Attach all plugins and rules to this instance ---
|
|
49
|
+
md.use(attrs, { leftDelimiter: '{', rightDelimiter: '}' });
|
|
50
|
+
md.use(markdown_it_footnote);
|
|
51
|
+
md.use(markdown_it_task_lists);
|
|
52
|
+
md.use(markdown_it_abbr);
|
|
53
|
+
md.use(markdown_it_deflist);
|
|
46
54
|
|
|
47
|
-
//
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
md.
|
|
51
|
-
md.
|
|
52
|
-
|
|
55
|
+
// Register renderers for all containers
|
|
56
|
+
Object.keys(containers).forEach(containerName => {
|
|
57
|
+
const container = containers[containerName];
|
|
58
|
+
md.renderer.rules[`container_${containerName}_open`] = container.render;
|
|
59
|
+
md.renderer.rules[`container_${containerName}_close`] = container.render;
|
|
60
|
+
});
|
|
53
61
|
|
|
54
|
-
//
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
.replace(/"/g, '"')
|
|
65
|
-
.replace(/'/g, ''');
|
|
66
|
-
|
|
67
|
-
// If no language is specified, preserve the original content without processing
|
|
68
|
-
if (!token.info || token.info.trim() === '') {
|
|
69
|
-
return '<pre class="hljs"><code>' + escapedContent + '</code></pre>';
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// For all language blocks, preserve the original content to avoid processing HTML or other content
|
|
73
|
-
// This ensures code blocks are treated as literal text only
|
|
74
|
-
const language = token.info.trim();
|
|
75
|
-
return '<pre class="hljs"><code class="language-' + language + '">' + escapedContent + '</code></pre>';
|
|
76
|
-
};
|
|
62
|
+
// Register the enhanced rules
|
|
63
|
+
md.block.ruler.before('fence', 'steps_container', stepsContainerRule, {
|
|
64
|
+
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
65
|
+
});
|
|
66
|
+
md.block.ruler.before('fence', 'enhanced_tabs', enhancedTabsRule, {
|
|
67
|
+
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
68
|
+
});
|
|
69
|
+
md.block.ruler.before('paragraph', 'advanced_container', advancedContainerRule, {
|
|
70
|
+
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
71
|
+
});
|
|
77
72
|
|
|
73
|
+
// Register all custom renderers
|
|
74
|
+
md.renderer.rules.ordered_list_open = customOrderedListOpenRenderer;
|
|
75
|
+
md.renderer.rules.list_item_open = customListItemOpenRenderer;
|
|
76
|
+
md.renderer.rules.image = customImageRenderer;
|
|
77
|
+
|
|
78
|
+
// Register tabs renderers
|
|
79
|
+
md.renderer.rules.tabs_open = tabsOpenRenderer;
|
|
80
|
+
md.renderer.rules.tabs_nav_open = tabsNavOpenRenderer;
|
|
81
|
+
md.renderer.rules.tabs_nav_close = tabsNavCloseRenderer;
|
|
82
|
+
md.renderer.rules.tabs_nav_item = tabsNavItemRenderer;
|
|
83
|
+
md.renderer.rules.tabs_content_open = tabsContentOpenRenderer;
|
|
84
|
+
md.renderer.rules.tabs_content_close = tabsContentCloseRenderer;
|
|
85
|
+
md.renderer.rules.tab_pane_open = tabPaneOpenRenderer;
|
|
86
|
+
md.renderer.rules.tab_pane_close = tabPaneCloseRenderer;
|
|
87
|
+
md.renderer.rules.tabs_close = tabsCloseRenderer;
|
|
88
|
+
|
|
89
|
+
// Register heading ID plugin
|
|
90
|
+
md.use(headingIdPlugin);
|
|
91
|
+
|
|
92
|
+
// Register standalone closing rule
|
|
93
|
+
md.block.ruler.before('paragraph', 'standalone_closing', standaloneClosingRule, {
|
|
94
|
+
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
95
|
+
});
|
|
78
96
|
|
|
97
|
+
return md;
|
|
98
|
+
}
|
|
79
99
|
|
|
80
100
|
// ===================================================================
|
|
81
101
|
// --- ADVANCED NESTED CONTAINER SYSTEM ---
|
|
@@ -452,7 +472,7 @@ function enhancedTabsRule(state, startLine, endLine, silent) {
|
|
|
452
472
|
'</code></pre>';
|
|
453
473
|
} catch (e) { console.error(`Error highlighting language ${lang}:`, e); }
|
|
454
474
|
}
|
|
455
|
-
return '<pre class="hljs"><code>' + str + '</code></pre>';
|
|
475
|
+
return '<pre class="hljs"><code>' + MarkdownIt.utils.escapeHtml(str) + '</code></pre>';
|
|
456
476
|
}
|
|
457
477
|
});
|
|
458
478
|
|
|
@@ -481,6 +501,30 @@ function enhancedTabsRule(state, startLine, endLine, silent) {
|
|
|
481
501
|
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
482
502
|
});
|
|
483
503
|
|
|
504
|
+
// Register custom renderers for the tab markdown instance
|
|
505
|
+
tabMd.renderer.rules.ordered_list_open = customOrderedListOpenRenderer;
|
|
506
|
+
tabMd.renderer.rules.list_item_open = customListItemOpenRenderer;
|
|
507
|
+
tabMd.renderer.rules.image = customImageRenderer;
|
|
508
|
+
|
|
509
|
+
// Register tabs renderers for the tab markdown instance
|
|
510
|
+
tabMd.renderer.rules.tabs_open = tabsOpenRenderer;
|
|
511
|
+
tabMd.renderer.rules.tabs_nav_open = tabsNavOpenRenderer;
|
|
512
|
+
tabMd.renderer.rules.tabs_nav_close = tabsNavCloseRenderer;
|
|
513
|
+
tabMd.renderer.rules.tabs_nav_item = tabsNavItemRenderer;
|
|
514
|
+
tabMd.renderer.rules.tabs_content_open = tabsContentOpenRenderer;
|
|
515
|
+
tabMd.renderer.rules.tabs_content_close = tabsContentCloseRenderer;
|
|
516
|
+
tabMd.renderer.rules.tab_pane_open = tabPaneOpenRenderer;
|
|
517
|
+
tabMd.renderer.rules.tab_pane_close = tabPaneCloseRenderer;
|
|
518
|
+
tabMd.renderer.rules.tabs_close = tabsCloseRenderer;
|
|
519
|
+
|
|
520
|
+
// Register heading ID plugin for the tab markdown instance
|
|
521
|
+
tabMd.use(headingIdPlugin);
|
|
522
|
+
|
|
523
|
+
// Register standalone closing rule for the tab markdown instance
|
|
524
|
+
tabMd.block.ruler.before('paragraph', 'standalone_closing', standaloneClosingRule, {
|
|
525
|
+
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
526
|
+
});
|
|
527
|
+
|
|
484
528
|
// Render the tab content
|
|
485
529
|
const renderedContent = tabMd.render(tabContent);
|
|
486
530
|
const htmlToken = state.push('html_block', '', 0);
|
|
@@ -495,19 +539,8 @@ function enhancedTabsRule(state, startLine, endLine, silent) {
|
|
|
495
539
|
return true;
|
|
496
540
|
}
|
|
497
541
|
|
|
498
|
-
// Register the enhanced rules
|
|
499
|
-
md.block.ruler.before('fence', 'steps_container', stepsContainerRule, {
|
|
500
|
-
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
501
|
-
});
|
|
502
|
-
md.block.ruler.before('fence', 'enhanced_tabs', enhancedTabsRule, {
|
|
503
|
-
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
504
|
-
});
|
|
505
|
-
md.block.ruler.before('paragraph', 'advanced_container', advancedContainerRule, {
|
|
506
|
-
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
507
|
-
});
|
|
508
|
-
|
|
509
542
|
// Add a rule to handle standalone closing tags
|
|
510
|
-
|
|
543
|
+
const standaloneClosingRule = (state, startLine, endLine, silent) => {
|
|
511
544
|
const start = state.bMarks[startLine] + state.tShift[startLine];
|
|
512
545
|
const max = state.eMarks[startLine];
|
|
513
546
|
const lineContent = state.src.slice(start, max).trim();
|
|
@@ -520,19 +553,10 @@ md.block.ruler.before('paragraph', 'standalone_closing', (state, startLine, endL
|
|
|
520
553
|
}
|
|
521
554
|
|
|
522
555
|
return false;
|
|
523
|
-
}
|
|
524
|
-
alt: ['paragraph', 'reference', 'blockquote', 'list']
|
|
525
|
-
});
|
|
526
|
-
|
|
527
|
-
// Register renderers for all containers
|
|
528
|
-
Object.keys(containers).forEach(containerName => {
|
|
529
|
-
const container = containers[containerName];
|
|
530
|
-
md.renderer.rules[`container_${containerName}_open`] = container.render;
|
|
531
|
-
md.renderer.rules[`container_${containerName}_close`] = container.render;
|
|
532
|
-
});
|
|
556
|
+
};
|
|
533
557
|
|
|
534
558
|
// Custom renderer for ordered lists in steps containers
|
|
535
|
-
|
|
559
|
+
const customOrderedListOpenRenderer = function(tokens, idx, options, env, self) {
|
|
536
560
|
const token = tokens[idx];
|
|
537
561
|
// Check if we're inside a steps container by looking at the context
|
|
538
562
|
let isInSteps = false;
|
|
@@ -561,7 +585,7 @@ md.renderer.rules.ordered_list_open = function(tokens, idx, options, env, self)
|
|
|
561
585
|
};
|
|
562
586
|
|
|
563
587
|
// Custom renderer for list items in steps containers
|
|
564
|
-
|
|
588
|
+
const customListItemOpenRenderer = function(tokens, idx, options, env, self) {
|
|
565
589
|
const token = tokens[idx];
|
|
566
590
|
// Check if we're inside a steps container and this is a direct child
|
|
567
591
|
let isInStepsList = false;
|
|
@@ -596,34 +620,34 @@ md.renderer.rules.list_item_open = function(tokens, idx, options, env, self) {
|
|
|
596
620
|
};
|
|
597
621
|
|
|
598
622
|
// Enhanced tabs renderers
|
|
599
|
-
|
|
623
|
+
const tabsOpenRenderer = (tokens, idx) => {
|
|
600
624
|
const token = tokens[idx];
|
|
601
625
|
return `<div class="${token.attrs.map(attr => attr[1]).join(' ')}">`;
|
|
602
626
|
};
|
|
603
627
|
|
|
604
|
-
|
|
605
|
-
|
|
628
|
+
const tabsNavOpenRenderer = () => '<div class="docmd-tabs-nav">';
|
|
629
|
+
const tabsNavCloseRenderer = () => '</div>';
|
|
606
630
|
|
|
607
|
-
|
|
631
|
+
const tabsNavItemRenderer = (tokens, idx) => {
|
|
608
632
|
const token = tokens[idx];
|
|
609
633
|
return `<div class="${token.attrs[0][1]}">${token.content}</div>`;
|
|
610
634
|
};
|
|
611
635
|
|
|
612
|
-
|
|
613
|
-
|
|
636
|
+
const tabsContentOpenRenderer = () => '<div class="docmd-tabs-content">';
|
|
637
|
+
const tabsContentCloseRenderer = () => '</div>';
|
|
614
638
|
|
|
615
|
-
|
|
639
|
+
const tabPaneOpenRenderer = (tokens, idx) => {
|
|
616
640
|
const token = tokens[idx];
|
|
617
641
|
return `<div class="${token.attrs[0][1]}">`;
|
|
618
642
|
};
|
|
619
643
|
|
|
620
|
-
|
|
644
|
+
const tabPaneCloseRenderer = () => '</div>';
|
|
621
645
|
|
|
622
|
-
|
|
646
|
+
const tabsCloseRenderer = () => '</div>';
|
|
623
647
|
|
|
624
648
|
// Override the default image renderer to properly handle attributes like {.class}.
|
|
625
|
-
const
|
|
626
|
-
|
|
649
|
+
const customImageRenderer = function(tokens, idx, options, env, self) {
|
|
650
|
+
const defaultImageRenderer = function(tokens, idx, options, env, self) { return self.renderToken(tokens, idx, options); };
|
|
627
651
|
const renderedImage = defaultImageRenderer(tokens, idx, options, env, self);
|
|
628
652
|
const nextToken = tokens[idx + 1];
|
|
629
653
|
if (nextToken && nextToken.type === 'attrs_block') {
|
|
@@ -635,11 +659,11 @@ md.renderer.rules.image = function(tokens, idx, options, env, self) {
|
|
|
635
659
|
};
|
|
636
660
|
|
|
637
661
|
// Add IDs to headings for anchor links, used by the Table of Contents.
|
|
638
|
-
|
|
639
|
-
const defaultRender =
|
|
662
|
+
const headingIdPlugin = (md) => {
|
|
663
|
+
const defaultRender = function(tokens, idx, options, env, self) {
|
|
640
664
|
return self.renderToken(tokens, idx, options);
|
|
641
665
|
};
|
|
642
|
-
|
|
666
|
+
const headingOpenRenderer = function(tokens, idx, options, env, self) {
|
|
643
667
|
const token = tokens[idx];
|
|
644
668
|
const contentToken = tokens[idx + 1];
|
|
645
669
|
if (contentToken && contentToken.type === 'inline') {
|
|
@@ -648,8 +672,8 @@ md.use((md) => {
|
|
|
648
672
|
if (id) { token.attrSet('id', id); }
|
|
649
673
|
}
|
|
650
674
|
return defaultRender(tokens, idx, options, env, self);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
653
677
|
|
|
654
678
|
|
|
655
679
|
// ===================================================================
|
|
@@ -685,13 +709,21 @@ function extractHeadingsFromHtml(htmlContent) {
|
|
|
685
709
|
return headings;
|
|
686
710
|
}
|
|
687
711
|
|
|
688
|
-
async function processMarkdownFile(filePath,
|
|
712
|
+
async function processMarkdownFile(filePath, md, config) {
|
|
689
713
|
const rawContent = await fs.readFile(filePath, 'utf8');
|
|
690
|
-
let
|
|
714
|
+
let frontmatter, markdownContent;
|
|
715
|
+
|
|
716
|
+
try {
|
|
717
|
+
({ data: frontmatter, content: markdownContent } = matter(rawContent));
|
|
718
|
+
} catch (e) {
|
|
719
|
+
console.error(`❌ Error parsing frontmatter in ${formatPathForDisplay(filePath)}:`);
|
|
720
|
+
console.error(` ${e.message}`);
|
|
721
|
+
console.error(' This page will be skipped. Please fix the YAML syntax.');
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
691
724
|
|
|
692
|
-
// Handle autoTitleFromH1
|
|
693
725
|
if (!frontmatter.title) {
|
|
694
|
-
if (config.autoTitleFromH1 !== false) {
|
|
726
|
+
if (config.autoTitleFromH1 !== false) {
|
|
695
727
|
const h1Match = markdownContent.match(/^#\s+(.*)/m);
|
|
696
728
|
if (h1Match && h1Match[1]) {
|
|
697
729
|
frontmatter.title = h1Match[1].trim();
|
|
@@ -702,11 +734,12 @@ async function processMarkdownFile(filePath, options = { isDev: false }, config)
|
|
|
702
734
|
}
|
|
703
735
|
}
|
|
704
736
|
|
|
705
|
-
// For no-style pages, skip markdown processing and treat content as raw HTML
|
|
706
737
|
let htmlContent, headings;
|
|
707
738
|
if (frontmatter.noStyle === true) {
|
|
708
|
-
|
|
709
|
-
|
|
739
|
+
// For noStyle pages, NO markdown processing at all
|
|
740
|
+
// Pass the raw content directly as-is
|
|
741
|
+
htmlContent = markdownContent;
|
|
742
|
+
headings = [];
|
|
710
743
|
} else {
|
|
711
744
|
htmlContent = md.render(markdownContent);
|
|
712
745
|
headings = extractHeadingsFromHtml(htmlContent);
|
|
@@ -735,7 +768,7 @@ async function findMarkdownFiles(dir) {
|
|
|
735
768
|
|
|
736
769
|
module.exports = {
|
|
737
770
|
processMarkdownFile,
|
|
738
|
-
|
|
771
|
+
createMarkdownItInstance,
|
|
739
772
|
extractHeadingsFromHtml,
|
|
740
773
|
findMarkdownFiles
|
|
741
774
|
};
|
|
@@ -1,38 +1,51 @@
|
|
|
1
|
-
//
|
|
1
|
+
//
|
|
2
|
+
|
|
2
3
|
const ejs = require('ejs');
|
|
3
4
|
const path = require('path');
|
|
4
5
|
const fs = require('fs-extra');
|
|
5
|
-
const {
|
|
6
|
+
const { createMarkdownItInstance } = require('./file-processor');
|
|
6
7
|
const { generateSeoMetaTags } = require('../plugins/seo');
|
|
7
8
|
const { generateAnalyticsScripts } = require('../plugins/analytics');
|
|
8
|
-
const { renderIcon } = require('./icon-renderer');
|
|
9
|
+
const { renderIcon } = require('./icon-renderer');
|
|
10
|
+
|
|
11
|
+
// Create a markdown instance for inline rendering
|
|
12
|
+
let mdInstance = null;
|
|
13
|
+
|
|
14
|
+
let themeInitScript = '';
|
|
15
|
+
(async () => {
|
|
16
|
+
const themeInitPath = path.join(__dirname, '..', 'templates', 'partials', 'theme-init.js');
|
|
17
|
+
if (await fs.pathExists(themeInitPath)) {
|
|
18
|
+
const scriptContent = await fs.readFile(themeInitPath, 'utf8');
|
|
19
|
+
themeInitScript = `<script>${scriptContent}</script>`;
|
|
20
|
+
}
|
|
21
|
+
})();
|
|
9
22
|
|
|
10
23
|
async function processPluginHooks(config, pageData, relativePathToRoot) {
|
|
11
24
|
let metaTagsHtml = '';
|
|
12
25
|
let faviconLinkHtml = '';
|
|
13
|
-
let themeCssLinkHtml = '';
|
|
14
|
-
let pluginStylesHtml = '';
|
|
26
|
+
let themeCssLinkHtml = '';
|
|
27
|
+
let pluginStylesHtml = '';
|
|
15
28
|
let pluginHeadScriptsHtml = '';
|
|
16
29
|
let pluginBodyScriptsHtml = '';
|
|
17
30
|
|
|
18
|
-
//
|
|
31
|
+
// Favicon (built-in handling)
|
|
19
32
|
if (config.favicon) {
|
|
20
33
|
const faviconPath = config.favicon.startsWith('/') ? config.favicon.substring(1) : config.favicon;
|
|
21
34
|
faviconLinkHtml = `<link rel="shortcut icon" href="${relativePathToRoot}${faviconPath}" type="image/x-icon">\n`;
|
|
22
35
|
}
|
|
23
36
|
|
|
24
|
-
//
|
|
37
|
+
// Theme CSS (built-in handling for theme.name)
|
|
25
38
|
if (config.theme && config.theme.name && config.theme.name !== 'default') {
|
|
26
39
|
const themeCssPath = `assets/css/docmd-theme-${config.theme.name}.css`;
|
|
27
40
|
themeCssLinkHtml = ` <link rel="stylesheet" href="${relativePathToRoot}${themeCssPath}">\n`;
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
//
|
|
43
|
+
// SEO Plugin (if configured)
|
|
31
44
|
if (config.plugins?.seo) {
|
|
32
45
|
metaTagsHtml += generateSeoMetaTags(config, pageData, relativePathToRoot);
|
|
33
46
|
}
|
|
34
47
|
|
|
35
|
-
//
|
|
48
|
+
// Analytics Plugin (if configured)
|
|
36
49
|
if (config.plugins?.analytics) {
|
|
37
50
|
const analyticsScripts = generateAnalyticsScripts(config, pageData);
|
|
38
51
|
pluginHeadScriptsHtml += analyticsScripts.headScriptsHtml;
|
|
@@ -56,17 +69,21 @@ async function generateHtmlPage(templateData) {
|
|
|
56
69
|
prevPage, nextPage, currentPagePath, headings
|
|
57
70
|
} = templateData;
|
|
58
71
|
|
|
59
|
-
const pageTitle = frontmatter.title;
|
|
72
|
+
const pageTitle = frontmatter.title;
|
|
60
73
|
|
|
61
74
|
// Process plugins to get their HTML contributions
|
|
62
75
|
const pluginOutputs = await processPluginHooks(
|
|
63
76
|
config,
|
|
64
|
-
{ frontmatter, outputPath },
|
|
77
|
+
{ frontmatter, outputPath },
|
|
65
78
|
relativePathToRoot
|
|
66
79
|
);
|
|
67
80
|
|
|
68
81
|
let footerHtml = '';
|
|
69
82
|
if (config.footer) {
|
|
83
|
+
// Initialize mdInstance if not already done
|
|
84
|
+
if (!mdInstance) {
|
|
85
|
+
mdInstance = createMarkdownItInstance(config);
|
|
86
|
+
}
|
|
70
87
|
footerHtml = mdInstance.renderInline(config.footer);
|
|
71
88
|
}
|
|
72
89
|
|
|
@@ -85,7 +102,8 @@ async function generateHtmlPage(templateData) {
|
|
|
85
102
|
|
|
86
103
|
const ejsData = {
|
|
87
104
|
content,
|
|
88
|
-
pageTitle,
|
|
105
|
+
pageTitle,
|
|
106
|
+
themeInitScript,
|
|
89
107
|
description: frontmatter.description,
|
|
90
108
|
siteTitle,
|
|
91
109
|
navigationHtml,
|
|
@@ -109,6 +127,7 @@ async function generateHtmlPage(templateData) {
|
|
|
109
127
|
headings: headings || [],
|
|
110
128
|
isActivePage,
|
|
111
129
|
frontmatter,
|
|
130
|
+
config: config,
|
|
112
131
|
...pluginOutputs,
|
|
113
132
|
};
|
|
114
133
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
|
|
1
|
+
// Source file from the docmd project — https://github.com/mgks/docmd
|
|
2
|
+
|
|
3
|
+
const lucideStatic = require('lucide-static');
|
|
3
4
|
|
|
4
5
|
// On first load, log debug information about a specific icon to understand its structure
|
|
5
6
|
let debugRun = false;
|
package/src/plugins/analytics.js
CHANGED