@mgks/docmd 0.2.7 → 0.2.9
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/CONTRIBUTING.md +129 -0
- package/.github/workflows/publish.yml +3 -1
- package/README.md +119 -82
- package/config.js +13 -1
- package/docs/configuration.md +29 -1
- package/docs/content/containers/changelogs.md +128 -0
- package/docs/content/containers/collapsible.md +89 -0
- package/docs/content/markdown-syntax.md +32 -0
- package/docs/contributing.md +8 -0
- package/package.json +3 -2
- package/src/assets/css/docmd-main.css +507 -299
- package/src/assets/css/docmd-theme-retro.css +860 -1
- package/src/assets/css/docmd-theme-ruby.css +621 -1
- package/src/assets/css/docmd-theme-sky.css +606 -1
- package/src/assets/js/docmd-image-lightbox.js +13 -13
- package/src/assets/js/docmd-main.js +23 -23
- package/src/assets/js/docmd-mermaid.js +28 -29
- package/src/commands/build.js +79 -40
- package/src/commands/init.js +10 -0
- package/src/core/file-processor.js +49 -777
- package/src/core/html-generator.js +23 -0
- package/src/core/markdown/containers.js +94 -0
- package/src/core/markdown/renderers.js +90 -0
- package/src/core/markdown/rules.js +355 -0
- package/src/core/markdown/setup.js +124 -0
- package/src/templates/layout.ejs +15 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Source file from the docmd project — https://github.com/mgks/docmd
|
|
2
|
+
|
|
3
|
+
const MarkdownIt = require('markdown-it');
|
|
4
|
+
const hljs = require('highlight.js');
|
|
5
|
+
const attrs = require('markdown-it-attrs');
|
|
6
|
+
const markdown_it_footnote = require('markdown-it-footnote');
|
|
7
|
+
const markdown_it_task_lists = require('markdown-it-task-lists');
|
|
8
|
+
const markdown_it_abbr = require('markdown-it-abbr');
|
|
9
|
+
const markdown_it_deflist = require('markdown-it-deflist');
|
|
10
|
+
|
|
11
|
+
const { containers } = require('./containers');
|
|
12
|
+
const rules = require('./rules');
|
|
13
|
+
const renderers = require('./renderers');
|
|
14
|
+
|
|
15
|
+
// Custom plugin for Heading IDs
|
|
16
|
+
const headingIdPlugin = (md) => {
|
|
17
|
+
const originalHeadingOpen = md.renderer.rules.heading_open || function(tokens, idx, options, env, self) {
|
|
18
|
+
return self.renderToken(tokens, idx, options);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
md.renderer.rules.heading_open = function(tokens, idx, options, env, self) {
|
|
22
|
+
const token = tokens[idx];
|
|
23
|
+
|
|
24
|
+
// Check if an ID was already set by markdown-it-attrs (e.g. {#my-id})
|
|
25
|
+
const existingId = token.attrGet('id');
|
|
26
|
+
|
|
27
|
+
// If NO ID exists, generate one automatically from the text content
|
|
28
|
+
if (!existingId) {
|
|
29
|
+
const contentToken = tokens[idx + 1];
|
|
30
|
+
if (contentToken && contentToken.type === 'inline' && contentToken.content) {
|
|
31
|
+
const headingText = contentToken.content;
|
|
32
|
+
|
|
33
|
+
// Note: markdown-it-attrs strips the curly braces content from .content
|
|
34
|
+
// BEFORE this rule runs, so headingText should be clean.
|
|
35
|
+
|
|
36
|
+
const id = headingText
|
|
37
|
+
.toLowerCase()
|
|
38
|
+
.replace(/\s+/g, '-') // Replace spaces with -
|
|
39
|
+
.replace(/[^\w\u4e00-\u9fa5-]+/g, '') // Remove all non-word chars (keeping hyphens). Added unicode support implies keeping more chars if needed.
|
|
40
|
+
.replace(/--+/g, '-') // Replace multiple - with single -
|
|
41
|
+
.replace(/^-+/, '') // Trim - from start of text
|
|
42
|
+
.replace(/-+$/, ''); // Trim - from end of text
|
|
43
|
+
|
|
44
|
+
if (id) {
|
|
45
|
+
token.attrSet('id', id);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return originalHeadingOpen(tokens, idx, options, env, self);
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
function createMarkdownItInstance(config) {
|
|
55
|
+
const mdOptions = {
|
|
56
|
+
html: true,
|
|
57
|
+
linkify: true,
|
|
58
|
+
typographer: true,
|
|
59
|
+
breaks: true,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const highlightFn = (str, lang) => {
|
|
63
|
+
if (lang === 'mermaid') {
|
|
64
|
+
return `<pre class="mermaid">${new MarkdownIt().utils.escapeHtml(str)}</pre>`;
|
|
65
|
+
}
|
|
66
|
+
if (lang && hljs.getLanguage(lang)) {
|
|
67
|
+
try {
|
|
68
|
+
return `<pre class="hljs"><code>${hljs.highlight(str, { language: lang, ignoreIllegals: true }).value}</code></pre>`;
|
|
69
|
+
} catch (e) { console.error(e); }
|
|
70
|
+
}
|
|
71
|
+
return `<pre class="hljs"><code>${new MarkdownIt().utils.escapeHtml(str)}</code></pre>`;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
mdOptions.highlight = config.theme?.codeHighlight !== false ? highlightFn : (str, lang) => {
|
|
75
|
+
if (lang === 'mermaid') return `<pre class="mermaid">${new MarkdownIt().utils.escapeHtml(str)}</pre>`;
|
|
76
|
+
return `<pre><code>${new MarkdownIt().utils.escapeHtml(str)}</code></pre>`;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const md = new MarkdownIt(mdOptions);
|
|
80
|
+
|
|
81
|
+
// Plugins
|
|
82
|
+
md.use(attrs, { leftDelimiter: '{', rightDelimiter: '}' });
|
|
83
|
+
md.use(markdown_it_footnote);
|
|
84
|
+
md.use(markdown_it_task_lists);
|
|
85
|
+
md.use(markdown_it_abbr);
|
|
86
|
+
md.use(markdown_it_deflist);
|
|
87
|
+
md.use(headingIdPlugin);
|
|
88
|
+
|
|
89
|
+
// Register Containers
|
|
90
|
+
Object.keys(containers).forEach(containerName => {
|
|
91
|
+
const container = containers[containerName];
|
|
92
|
+
md.renderer.rules[`container_${containerName}_open`] = container.render;
|
|
93
|
+
md.renderer.rules[`container_${containerName}_close`] = container.render;
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Register Rules (Order Matters)
|
|
97
|
+
md.block.ruler.before('fence', 'steps_container', rules.stepsContainerRule, { alt: ['paragraph', 'reference', 'blockquote', 'list'] });
|
|
98
|
+
md.block.ruler.before('fence', 'enhanced_tabs', rules.enhancedTabsRule, { alt: ['paragraph', 'reference', 'blockquote', 'list'] });
|
|
99
|
+
md.block.ruler.before('fence', 'changelog_timeline', rules.changelogTimelineRule, { alt: ['paragraph', 'reference', 'blockquote', 'list'] });
|
|
100
|
+
md.block.ruler.before('paragraph', 'advanced_container', rules.advancedContainerRule, { alt: ['paragraph', 'reference', 'blockquote', 'list'] });
|
|
101
|
+
md.block.ruler.before('paragraph', 'standalone_closing', rules.standaloneClosingRule, { alt: ['paragraph', 'reference', 'blockquote', 'list'] });
|
|
102
|
+
|
|
103
|
+
// Register Renderers
|
|
104
|
+
md.renderer.rules.ordered_list_open = renderers.customOrderedListOpenRenderer;
|
|
105
|
+
md.renderer.rules.list_item_open = renderers.customListItemOpenRenderer;
|
|
106
|
+
md.renderer.rules.image = renderers.customImageRenderer;
|
|
107
|
+
md.renderer.rules.table_open = renderers.tableOpenRenderer;
|
|
108
|
+
md.renderer.rules.table_close = renderers.tableCloseRenderer;
|
|
109
|
+
|
|
110
|
+
// Tabs Renderers
|
|
111
|
+
md.renderer.rules.tabs_open = renderers.tabsOpenRenderer;
|
|
112
|
+
md.renderer.rules.tabs_nav_open = renderers.tabsNavOpenRenderer;
|
|
113
|
+
md.renderer.rules.tabs_nav_close = renderers.tabsNavCloseRenderer;
|
|
114
|
+
md.renderer.rules.tabs_nav_item = renderers.tabsNavItemRenderer;
|
|
115
|
+
md.renderer.rules.tabs_content_open = renderers.tabsContentOpenRenderer;
|
|
116
|
+
md.renderer.rules.tabs_content_close = renderers.tabsContentCloseRenderer;
|
|
117
|
+
md.renderer.rules.tab_pane_open = renderers.tabPaneOpenRenderer;
|
|
118
|
+
md.renderer.rules.tab_pane_close = renderers.tabPaneCloseRenderer;
|
|
119
|
+
md.renderer.rules.tabs_close = renderers.tabsCloseRenderer;
|
|
120
|
+
|
|
121
|
+
return md;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
module.exports = { createMarkdownItInstance };
|
package/src/templates/layout.ejs
CHANGED
|
@@ -115,7 +115,22 @@
|
|
|
115
115
|
<%- include('toc', { content, headings, navigationHtml, isActivePage }) %>
|
|
116
116
|
</div>
|
|
117
117
|
</div>
|
|
118
|
+
|
|
119
|
+
<!-- Page footer actions -->
|
|
120
|
+
<div class="page-footer-actions">
|
|
121
|
+
<% if (locals.editUrl) { %>
|
|
122
|
+
<a href="<%= editUrl %>" target="_blank" rel="noopener noreferrer" class="edit-link">
|
|
123
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-pencil"><path d="M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z"/><path d="m15 5 4 4"/></svg>
|
|
124
|
+
<%= editLinkText %>
|
|
125
|
+
</a>
|
|
126
|
+
<% } %>
|
|
127
|
+
|
|
128
|
+
<% if (locals.lastUpdated) { %>
|
|
129
|
+
<!-- Placeholder for future Last Updated feature -->
|
|
130
|
+
<% } %>
|
|
131
|
+
</div>
|
|
118
132
|
</main>
|
|
133
|
+
|
|
119
134
|
<footer class="page-footer">
|
|
120
135
|
<div class="footer-content">
|
|
121
136
|
<div class="user-footer">
|