markopress 0.0.2 → 0.0.4
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/dist/build/index.d.ts +0 -1
- package/dist/build/index.js +1 -1627
- package/dist/build/types.d.ts +0 -1
- package/dist/build/types.js +1 -5
- package/dist/build/vite-markdown-plugin.d.ts +0 -1
- package/dist/build/vite-markdown-plugin.js +1 -147
- package/dist/cli/index.d.ts +0 -1
- package/dist/cli/index.js +1 -74
- package/dist/config/app-root.d.ts +0 -1
- package/dist/config/app-root.js +1 -24
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +1 -6
- package/dist/config/loader.d.ts +0 -1
- package/dist/config/loader.js +1 -188
- package/dist/config/types.d.ts +0 -1
- package/dist/config/types.js +1 -5
- package/dist/config/validation.d.ts +0 -1
- package/dist/config/validation.js +1 -139
- package/dist/content/index.d.ts +0 -1
- package/dist/content/index.js +1 -6
- package/dist/content/registry.d.ts +0 -1
- package/dist/content/registry.js +1 -45
- package/dist/content/types.d.ts +0 -1
- package/dist/content/types.js +1 -5
- package/dist/dev/index.d.ts +0 -1
- package/dist/dev/index.js +1 -93
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -17
- package/dist/markdown/base-path-plugin.d.ts +16 -0
- package/dist/markdown/base-path-plugin.js +1 -0
- package/dist/markdown/code.d.ts +0 -1
- package/dist/markdown/code.js +1 -305
- package/dist/markdown/containers.d.ts +0 -1
- package/dist/markdown/containers.js +1 -143
- package/dist/markdown/includes.d.ts +0 -1
- package/dist/markdown/includes.js +1 -9
- package/dist/markdown/index.d.ts +0 -1
- package/dist/markdown/index.js +1 -8
- package/dist/markdown/loader.d.ts +0 -1
- package/dist/markdown/loader.js +1 -325
- package/dist/markdown/md-link-plugin.d.ts +14 -0
- package/dist/markdown/md-link-plugin.js +1 -0
- package/dist/markdown/preserve-tags.d.ts +0 -1
- package/dist/markdown/preserve-tags.js +1 -233
- package/dist/markdown/renderer.d.ts +0 -1
- package/dist/markdown/renderer.js +1 -146
- package/dist/markdown/tag-validator.d.ts +0 -1
- package/dist/markdown/tag-validator.js +1 -118
- package/dist/markdown/types.d.ts +2 -1
- package/dist/markdown/types.js +1 -5
- package/dist/plugin/compat.d.ts +0 -1
- package/dist/plugin/compat.js +1 -78
- package/dist/plugin/context.d.ts +0 -1
- package/dist/plugin/context.js +1 -103
- package/dist/plugin/index.d.ts +0 -1
- package/dist/plugin/index.js +1 -6
- package/dist/plugin/manager.d.ts +0 -1
- package/dist/plugin/manager.js +1 -385
- package/dist/plugin/types.d.ts +1 -1
- package/dist/plugin/types.js +1 -5
- package/dist/plugins/blog-index/index.d.ts +0 -1
- package/dist/plugins/blog-index/index.js +1 -158
- package/dist/plugins/sidenav/index.d.ts +0 -1
- package/dist/plugins/sidenav/index.js +1 -86
- package/dist/plugins/toc/index.d.ts +0 -1
- package/dist/plugins/toc/index.js +1 -79
- package/dist/preview/index.d.ts +0 -1
- package/dist/preview/index.js +1 -25
- package/dist/theme/default/design-systems/default.d.ts +0 -1
- package/dist/theme/default/design-systems/default.js +1 -289
- package/dist/theme/default/design-systems/docusaurus.d.ts +0 -1
- package/dist/theme/default/design-systems/docusaurus.js +1 -299
- package/dist/theme/default/design-systems/index.d.ts +0 -1
- package/dist/theme/default/design-systems/index.js +1 -54
- package/dist/theme/default/design-systems/rspress.d.ts +0 -1
- package/dist/theme/default/design-systems/rspress.js +1 -299
- package/dist/theme/default/design-systems/types.d.ts +0 -1
- package/dist/theme/default/design-systems/types.js +1 -6
- package/dist/theme/default/design-systems/vitepress.d.ts +0 -1
- package/dist/theme/default/design-systems/vitepress.js +1 -299
- package/dist/theme/default/index.d.ts +0 -1
- package/dist/theme/default/index.js +1 -44
- package/dist/theme/default/theme.d.ts +0 -1
- package/dist/theme/default/theme.js +1 -58
- package/dist/theme/index.d.ts +0 -1
- package/dist/theme/index.js +1 -6
- package/dist/theme/loader.d.ts +0 -1
- package/dist/theme/loader.js +1 -125
- package/dist/theme/types.d.ts +1 -1
- package/dist/theme/types.js +1 -5
- package/dist/vite/index.d.ts +0 -1
- package/dist/vite/index.js +1 -6
- package/dist/vite/markdownPlugin.d.ts +0 -1
- package/dist/vite/markdownPlugin.js +1 -111
- package/dist/vite/plugin.d.ts +0 -1
- package/dist/vite/plugin.js +1 -94
- package/package.json +3 -2
- package/src/theme/default/layouts/blog.marko +1 -1
- package/src/theme/default/layouts/default.marko +5 -5
- package/src/theme/default/layouts/docs.marko +6 -6
- package/src/theme/default/layouts/page.marko +1 -1
- package/templates/catch-all-handler.js.template +2 -17
- package/dist/build/index.d.ts.map +0 -1
- package/dist/build/index.js.map +0 -1
- package/dist/build/manifest-generator.d.ts +0 -34
- package/dist/build/manifest-generator.d.ts.map +0 -1
- package/dist/build/manifest-generator.js +0 -86
- package/dist/build/manifest-generator.js.map +0 -1
- package/dist/build/security.test.d.ts +0 -6
- package/dist/build/security.test.d.ts.map +0 -1
- package/dist/build/security.test.js +0 -88
- package/dist/build/security.test.js.map +0 -1
- package/dist/build/types.d.ts.map +0 -1
- package/dist/build/types.js.map +0 -1
- package/dist/build/vite-config.test.d.ts +0 -2
- package/dist/build/vite-config.test.d.ts.map +0 -1
- package/dist/build/vite-config.test.js +0 -53
- package/dist/build/vite-config.test.js.map +0 -1
- package/dist/build/vite-markdown-plugin.d.ts.map +0 -1
- package/dist/build/vite-markdown-plugin.js.map +0 -1
- package/dist/build/vite-markdown-plugin.test.d.ts +0 -2
- package/dist/build/vite-markdown-plugin.test.d.ts.map +0 -1
- package/dist/build/vite-markdown-plugin.test.js +0 -41
- package/dist/build/vite-markdown-plugin.test.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/index.js.map +0 -1
- package/dist/config/app-root.d.ts.map +0 -1
- package/dist/config/app-root.js.map +0 -1
- package/dist/config/app-root.test.d.ts +0 -2
- package/dist/config/app-root.test.d.ts.map +0 -1
- package/dist/config/app-root.test.js +0 -71
- package/dist/config/app-root.test.js.map +0 -1
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/index.js.map +0 -1
- package/dist/config/loader.d.ts.map +0 -1
- package/dist/config/loader.js.map +0 -1
- package/dist/config/loader.test.d.ts +0 -2
- package/dist/config/loader.test.d.ts.map +0 -1
- package/dist/config/loader.test.js +0 -24
- package/dist/config/loader.test.js.map +0 -1
- package/dist/config/types.d.ts.map +0 -1
- package/dist/config/types.js.map +0 -1
- package/dist/config/validation.d.ts.map +0 -1
- package/dist/config/validation.js.map +0 -1
- package/dist/content/index.d.ts.map +0 -1
- package/dist/content/index.js.map +0 -1
- package/dist/content/registry.d.ts.map +0 -1
- package/dist/content/registry.js.map +0 -1
- package/dist/content/scanner.d.ts +0 -9
- package/dist/content/scanner.d.ts.map +0 -1
- package/dist/content/scanner.js +0 -115
- package/dist/content/scanner.js.map +0 -1
- package/dist/content/types.d.ts.map +0 -1
- package/dist/content/types.js.map +0 -1
- package/dist/dev/index.d.ts.map +0 -1
- package/dist/dev/index.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/markdown/code.d.ts.map +0 -1
- package/dist/markdown/code.js.map +0 -1
- package/dist/markdown/containers.d.ts.map +0 -1
- package/dist/markdown/containers.js.map +0 -1
- package/dist/markdown/includes.d.ts.map +0 -1
- package/dist/markdown/includes.js.map +0 -1
- package/dist/markdown/index.d.ts.map +0 -1
- package/dist/markdown/index.js.map +0 -1
- package/dist/markdown/loader.d.ts.map +0 -1
- package/dist/markdown/loader.js.map +0 -1
- package/dist/markdown/preserve-tags.d.ts.map +0 -1
- package/dist/markdown/preserve-tags.js.map +0 -1
- package/dist/markdown/renderer.d.ts.map +0 -1
- package/dist/markdown/renderer.js.map +0 -1
- package/dist/markdown/tag-validator.d.ts.map +0 -1
- package/dist/markdown/tag-validator.js.map +0 -1
- package/dist/markdown/types.d.ts.map +0 -1
- package/dist/markdown/types.js.map +0 -1
- package/dist/plugin/compat.d.ts.map +0 -1
- package/dist/plugin/compat.js.map +0 -1
- package/dist/plugin/context.d.ts.map +0 -1
- package/dist/plugin/context.js.map +0 -1
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js.map +0 -1
- package/dist/plugin/manager.d.ts.map +0 -1
- package/dist/plugin/manager.js.map +0 -1
- package/dist/plugin/types.d.ts.map +0 -1
- package/dist/plugin/types.js.map +0 -1
- package/dist/plugins/blog-index/index.d.ts.map +0 -1
- package/dist/plugins/blog-index/index.js.map +0 -1
- package/dist/plugins/sidenav/index.d.ts.map +0 -1
- package/dist/plugins/sidenav/index.js.map +0 -1
- package/dist/plugins/toc/index.d.ts.map +0 -1
- package/dist/plugins/toc/index.js.map +0 -1
- package/dist/preview/index.d.ts.map +0 -1
- package/dist/preview/index.js.map +0 -1
- package/dist/theme/default/build/generate-all.d.ts +0 -9
- package/dist/theme/default/build/generate-all.d.ts.map +0 -1
- package/dist/theme/default/build/generate-all.js +0 -85
- package/dist/theme/default/build/generate-all.js.map +0 -1
- package/dist/theme/default/build/generate-css.d.ts +0 -19
- package/dist/theme/default/build/generate-css.d.ts.map +0 -1
- package/dist/theme/default/build/generate-css.js +0 -199
- package/dist/theme/default/build/generate-css.js.map +0 -1
- package/dist/theme/default/build/index.d.ts +0 -5
- package/dist/theme/default/build/index.d.ts.map +0 -1
- package/dist/theme/default/build/index.js +0 -5
- package/dist/theme/default/build/index.js.map +0 -1
- package/dist/theme/default/design-systems/default.d.ts.map +0 -1
- package/dist/theme/default/design-systems/default.js.map +0 -1
- package/dist/theme/default/design-systems/docusaurus.d.ts.map +0 -1
- package/dist/theme/default/design-systems/docusaurus.js.map +0 -1
- package/dist/theme/default/design-systems/index.d.ts.map +0 -1
- package/dist/theme/default/design-systems/index.js.map +0 -1
- package/dist/theme/default/design-systems/rspress.d.ts.map +0 -1
- package/dist/theme/default/design-systems/rspress.js.map +0 -1
- package/dist/theme/default/design-systems/types.d.ts.map +0 -1
- package/dist/theme/default/design-systems/types.js.map +0 -1
- package/dist/theme/default/design-systems/vitepress.d.ts.map +0 -1
- package/dist/theme/default/design-systems/vitepress.js.map +0 -1
- package/dist/theme/default/index.d.ts.map +0 -1
- package/dist/theme/default/index.js.map +0 -1
- package/dist/theme/default/theme.d.ts.map +0 -1
- package/dist/theme/default/theme.js.map +0 -1
- package/dist/theme/index.d.ts.map +0 -1
- package/dist/theme/index.js.map +0 -1
- package/dist/theme/loader.d.ts.map +0 -1
- package/dist/theme/loader.js.map +0 -1
- package/dist/theme/types.d.ts.map +0 -1
- package/dist/theme/types.js.map +0 -1
- package/dist/vite/index.d.ts.map +0 -1
- package/dist/vite/index.js.map +0 -1
- package/dist/vite/markdownPlugin.d.ts.map +0 -1
- package/dist/vite/markdownPlugin.js.map +0 -1
- package/dist/vite/plugin.d.ts.map +0 -1
- package/dist/vite/plugin.js.map +0 -1
- package/src/theme/default/build/generate-all.ts +0 -99
- package/src/theme/default/build/generate-css.ts +0 -234
- package/src/theme/default/build/index.ts +0 -5
- package/src/theme/default/components/doc-footer.marko +0 -180
- package/src/theme/default/components/footer.marko +0 -32
- package/src/theme/default/components/header.marko +0 -49
- package/src/theme/default/components/nav-bar.marko +0 -191
- package/src/theme/default/components/page-header.marko +0 -20
- package/src/theme/default/components/reading-progress.marko +0 -36
- package/src/theme/default/components/search.marko +0 -239
- package/src/theme/default/components/sidebar.marko +0 -211
- package/src/theme/default/components/site-footer.marko +0 -211
- package/src/theme/default/components/skip-link.marko +0 -49
- package/src/theme/default/components/theme/theme-aside-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-aside-top.marko +0 -1
- package/src/theme/default/components/theme/theme-body-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-body-top.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-footer-after.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-footer-before.marko +0 -1
- package/src/theme/default/components/theme/theme-doc-top.marko +0 -1
- package/src/theme/default/components/theme/theme-head-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-head-top.marko +0 -1
- package/src/theme/default/components/theme/theme-home-features-after.marko +0 -1
- package/src/theme/default/components/theme/theme-home-hero-after.marko +0 -1
- package/src/theme/default/components/theme/theme-home-hero-before.marko +0 -1
- package/src/theme/default/components/theme/theme-navbar-center.marko +0 -5
- package/src/theme/default/components/theme/theme-navbar-end.marko +0 -30
- package/src/theme/default/components/theme/theme-navbar-start.marko +0 -1
- package/src/theme/default/components/theme/theme-page-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-page-top.marko +0 -1
- package/src/theme/default/components/theme/theme-sidebar-bottom.marko +0 -1
- package/src/theme/default/components/theme/theme-sidebar-top.marko +0 -1
- package/src/theme/default/components/theme/theme-toc-item.marko +0 -1
- package/src/theme/default/components/theme-toggle.marko +0 -122
- package/src/theme/default/components/toc.marko +0 -140
- package/src/theme/default/design-systems/default.ts +0 -331
- package/src/theme/default/design-systems/docusaurus.ts +0 -341
- package/src/theme/default/design-systems/index.ts +0 -67
- package/src/theme/default/design-systems/rspress.ts +0 -341
- package/src/theme/default/design-systems/types.ts +0 -296
- package/src/theme/default/design-systems/vitepress.ts +0 -341
- package/src/theme/default/index.ts +0 -107
- package/src/theme/default/theme.ts +0 -83
- package/templates/example-tags/README.md +0 -212
- package/templates/example-tags/alert-box.marko +0 -98
- package/templates/example-tags/button-primary.marko +0 -28
- package/templates/example-tags/button-secondary.marko +0 -28
- package/templates/example-tags/button.marko +0 -6
- package/templates/example-tags/card-body.marko +0 -8
- package/templates/example-tags/card-footer.marko +0 -7
- package/templates/example-tags/card-header.marko +0 -7
- package/templates/example-tags/card.marko +0 -20
- package/templates/example-tags/icon.marko +0 -149
|
@@ -1,143 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Custom container plugin for markdown-it
|
|
3
|
-
* Implements VitePress-style and Docusaurus-style containers
|
|
4
|
-
*/
|
|
5
|
-
import container from 'markdown-it-container';
|
|
6
|
-
const DEFAULT_TYPES = ['tip', 'info', 'note', 'warning', 'danger', 'details'];
|
|
7
|
-
/**
|
|
8
|
-
* Setup custom containers for markdown-it
|
|
9
|
-
*/
|
|
10
|
-
export function setupContainers(md, options = {}) {
|
|
11
|
-
const types = options.types || DEFAULT_TYPES;
|
|
12
|
-
// Register each container type
|
|
13
|
-
for (const type of types) {
|
|
14
|
-
md.use(container, type, {
|
|
15
|
-
validate: (params) => {
|
|
16
|
-
return params.trim().match(new RegExp(`^${type}\\s*(.*)$`));
|
|
17
|
-
},
|
|
18
|
-
render: (tokens, idx) => {
|
|
19
|
-
const token = tokens[idx];
|
|
20
|
-
if (token.nesting === 1) {
|
|
21
|
-
// Opening tag
|
|
22
|
-
const info = token.info.trim().slice(type.length).trim();
|
|
23
|
-
const title = md.utils.escapeHtml(info || getDefaultTitle(type));
|
|
24
|
-
return `<div class="custom-container ${type}">
|
|
25
|
-
<p class="custom-container-title">${title}</p>
|
|
26
|
-
`;
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
// Closing tag
|
|
30
|
-
return '</div>\n';
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
// GitHub-style alerts (NOTE, TIP, IMPORTANT, WARNING, CAUTION)
|
|
36
|
-
setupGitHubAlerts(md);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Setup GitHub-style alerts
|
|
40
|
-
* Syntax: [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION]
|
|
41
|
-
*/
|
|
42
|
-
function setupGitHubAlerts(md) {
|
|
43
|
-
const alertTypes = {
|
|
44
|
-
NOTE: 'note',
|
|
45
|
-
TIP: 'tip',
|
|
46
|
-
IMPORTANT: 'important',
|
|
47
|
-
WARNING: 'warning',
|
|
48
|
-
CAUTION: 'danger',
|
|
49
|
-
};
|
|
50
|
-
// Add a rule to detect GitHub-style alerts in blockquotes
|
|
51
|
-
md.core.ruler.after('block', 'github-alerts', (state) => {
|
|
52
|
-
const tokens = state.tokens;
|
|
53
|
-
for (let i = 0; i < tokens.length; i++) {
|
|
54
|
-
if (tokens[i].type !== 'blockquote_open') {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
// Check if the next token is a paragraph containing an alert marker
|
|
58
|
-
const nextToken = tokens[i + 1];
|
|
59
|
-
if (!nextToken || nextToken.type !== 'paragraph_open') {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
const inlineToken = tokens[i + 2];
|
|
63
|
-
if (!inlineToken || inlineToken.type !== 'inline') {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
const content = inlineToken.content;
|
|
67
|
-
const match = content.match(/^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(.*)$/);
|
|
68
|
-
if (match) {
|
|
69
|
-
const [, alertType, restContent] = match;
|
|
70
|
-
const containerType = alertTypes[alertType];
|
|
71
|
-
// Convert blockquote to custom container
|
|
72
|
-
tokens[i].type = 'container_note_open';
|
|
73
|
-
tokens[i].tag = 'div';
|
|
74
|
-
tokens[i].attrSet('class', `custom-container ${containerType}`);
|
|
75
|
-
// Add title
|
|
76
|
-
const titleToken = new state.Token('html_block', '', 0);
|
|
77
|
-
titleToken.content = `<p class="custom-container-title">${alertType}</p>\n`;
|
|
78
|
-
tokens.splice(i + 1, 0, titleToken);
|
|
79
|
-
// Update content
|
|
80
|
-
if (restContent.trim()) {
|
|
81
|
-
inlineToken.content = restContent.trim();
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
// Remove empty paragraph
|
|
85
|
-
tokens.splice(i + 1, 3);
|
|
86
|
-
i += 1;
|
|
87
|
-
continue;
|
|
88
|
-
}
|
|
89
|
-
// Find the closing blockquote tag and change it
|
|
90
|
-
for (let j = i + 1; j < tokens.length; j++) {
|
|
91
|
-
if (tokens[j].type === 'blockquote_close') {
|
|
92
|
-
tokens[j].type = 'container_note_close';
|
|
93
|
-
tokens[j].tag = 'div';
|
|
94
|
-
break;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
i += 3; // Skip the processed tokens
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Get default title for container type
|
|
104
|
-
*/
|
|
105
|
-
function getDefaultTitle(type) {
|
|
106
|
-
const titles = {
|
|
107
|
-
tip: 'TIP',
|
|
108
|
-
info: 'INFO',
|
|
109
|
-
note: 'NOTE',
|
|
110
|
-
warning: 'WARNING',
|
|
111
|
-
danger: 'DANGER',
|
|
112
|
-
details: 'Details',
|
|
113
|
-
important: 'IMPORTANT',
|
|
114
|
-
caution: 'CAUTION',
|
|
115
|
-
};
|
|
116
|
-
return titles[type] || type.toUpperCase();
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Setup collapsible details container
|
|
120
|
-
*/
|
|
121
|
-
export function setupDetails(md) {
|
|
122
|
-
md.use(container, 'details', {
|
|
123
|
-
validate: (params) => {
|
|
124
|
-
return params.trim().match(/^details\s*(.*)$/);
|
|
125
|
-
},
|
|
126
|
-
render: (tokens, idx) => {
|
|
127
|
-
const token = tokens[idx];
|
|
128
|
-
if (token.nesting === 1) {
|
|
129
|
-
// Opening tag
|
|
130
|
-
const info = token.info.trim().slice('details'.length).trim();
|
|
131
|
-
const summary = md.utils.escapeHtml(info || 'Details');
|
|
132
|
-
return `<details class="custom-container details">
|
|
133
|
-
<summary>${summary}</summary>
|
|
134
|
-
`;
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
// Closing tag
|
|
138
|
-
return '</details>\n';
|
|
139
|
-
}
|
|
140
|
-
},
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=containers.js.map
|
|
1
|
+
import t from"markdown-it-container";const n=["tip","info","note","warning","danger","details"];export function setupContainers(i,o={}){const s=o.types||n;for(const n of s)i.use(t,n,{validate:t=>t.trim().match(RegExp(`^${n}\\s*(.*)$`)),render:(t,o)=>{const s=t[o];if(1===s.nesting){const t=s.info.trim().slice(n.length).trim(),o=i.utils.escapeHtml(t||e(n));return`<div class="custom-container ${n}">\n <p class="custom-container-title">${o}</p>\n`}return"</div>\n"}});!function(t){const n={NOTE:"note",TIP:"tip",IMPORTANT:"important",WARNING:"warning",CAUTION:"danger"};t.core.ruler.after("block","github-alerts",t=>{const e=t.tokens;for(let i=0;i<e.length;i++){if("blockquote_open"!==e[i].type)continue;const o=e[i+1];if(!o||"paragraph_open"!==o.type)continue;const s=e[i+2];if(!s||"inline"!==s.type)continue;const c=s.content.match(/^\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION)\]\s*(.*)$/);if(c){const[,o,r]=c,a=n[o];e[i].type="container_note_open",e[i].tag="div",e[i].attrSet("class","custom-container "+a);const l=new t.Token("html_block","",0);if(l.content=`<p class="custom-container-title">${o}</p>\n`,e.splice(i+1,0,l),!r.trim()){e.splice(i+1,3),i+=1;continue}s.content=r.trim();for(let t=i+1;t<e.length;t++)if("blockquote_close"===e[t].type){e[t].type="container_note_close",e[t].tag="div";break}i+=3}}})}(i)}function e(t){return{tip:"TIP",info:"INFO",note:"NOTE",warning:"WARNING",danger:"DANGER",details:"Details",important:"IMPORTANT",caution:"CAUTION"}[t]||t.toUpperCase()}export function setupDetails(n){n.use(t,"details",{validate:t=>t.trim().match(/^details\s*(.*)$/),render:(t,e)=>{const i=t[e];if(1===i.nesting){const t=i.info.trim().slice(7).trim();return`<details class="custom-container details">\n <summary>${n.utils.escapeHtml(t||"Details")}</summary>\n`}return"</details>\n"}})}
|
|
@@ -1,9 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* File includes preprocessing for markdown
|
|
3
|
-
*/
|
|
4
|
-
export function preprocessIncludesWithRegions(content, context) {
|
|
5
|
-
// For now, just return content as-is
|
|
6
|
-
// TODO: Implement actual file inclusion logic
|
|
7
|
-
return content;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=includes.js.map
|
|
1
|
+
export function preprocessIncludesWithRegions(e,n){return e}
|
package/dist/markdown/index.d.ts
CHANGED
package/dist/markdown/index.js
CHANGED
|
@@ -1,8 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Markdown module exports
|
|
3
|
-
*/
|
|
4
|
-
export * from './loader.js';
|
|
5
|
-
export * from './types.js';
|
|
6
|
-
export * from './renderer.js';
|
|
7
|
-
export { globalTagValidator, formatValidationError } from './tag-validator.js';
|
|
8
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export*from"./loader.js";export*from"./types.js";export*from"./renderer.js";export{globalTagValidator,formatValidationError}from"./tag-validator.js";
|
package/dist/markdown/loader.js
CHANGED
|
@@ -1,325 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Markdown loader with frontmatter parsing
|
|
3
|
-
*/
|
|
4
|
-
import matter from 'gray-matter';
|
|
5
|
-
import MarkdownIt from 'markdown-it';
|
|
6
|
-
import mdAnchor from 'markdown-it-anchor';
|
|
7
|
-
import mdAttrs from 'markdown-it-attrs';
|
|
8
|
-
import * as mdEmoji from 'markdown-it-emoji';
|
|
9
|
-
import { createHighlighter } from 'shiki';
|
|
10
|
-
import { setupContainers, setupDetails } from './containers.js';
|
|
11
|
-
import { createEnhancedHighlighter } from './code.js';
|
|
12
|
-
import { preprocessIncludesWithRegions } from './includes.js';
|
|
13
|
-
import { preserveTagsPlugin } from './preserve-tags.js';
|
|
14
|
-
import { globalTagValidator } from './tag-validator.js';
|
|
15
|
-
// Cache highlighter instance
|
|
16
|
-
let highlighterInstance = null;
|
|
17
|
-
// Track languages that have been loaded for lazy loading
|
|
18
|
-
const loadedLanguages = new Set();
|
|
19
|
-
let loadLanguagePromise = null;
|
|
20
|
-
/**
|
|
21
|
-
* Essential languages to load immediately (covers ~80% of use cases)
|
|
22
|
-
* Everything else loads on-demand to speed up initial build
|
|
23
|
-
*/
|
|
24
|
-
const ESSENTIAL_LANGUAGES = [
|
|
25
|
-
'javascript',
|
|
26
|
-
'typescript',
|
|
27
|
-
'js',
|
|
28
|
-
'ts',
|
|
29
|
-
'bash',
|
|
30
|
-
'markdown',
|
|
31
|
-
'md',
|
|
32
|
-
];
|
|
33
|
-
/**
|
|
34
|
-
* Language alias map (shorthand -> full name)
|
|
35
|
-
*/
|
|
36
|
-
const LANGUAGE_ALIASES = {
|
|
37
|
-
'js': 'javascript',
|
|
38
|
-
'ts': 'typescript',
|
|
39
|
-
'py': 'python',
|
|
40
|
-
'rs': 'rust',
|
|
41
|
-
'sh': 'bash',
|
|
42
|
-
'shell': 'bash',
|
|
43
|
-
'yml': 'yaml',
|
|
44
|
-
'cs': 'csharp',
|
|
45
|
-
'cpp': 'c++',
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* Resolve language alias to canonical name
|
|
49
|
-
*/
|
|
50
|
-
function resolveLanguageAlias(lang) {
|
|
51
|
-
return LANGUAGE_ALIASES[lang] || lang;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Get or create Shiki highlighter with lazy loading support
|
|
55
|
-
*
|
|
56
|
-
* Lazy loading strategy:
|
|
57
|
-
* 1. Start with only essential languages (js, ts, bash, md)
|
|
58
|
-
* 2. Load additional languages via preloadLanguages() as needed
|
|
59
|
-
* 3. Cache loaded languages to avoid re-loading
|
|
60
|
-
*/
|
|
61
|
-
async function getHighlighterInstance() {
|
|
62
|
-
if (!highlighterInstance) {
|
|
63
|
-
// Start with essential languages (covers ~80% of use cases)
|
|
64
|
-
// Additional languages are loaded via preloadLanguages() after scanning content
|
|
65
|
-
highlighterInstance = await createHighlighter({
|
|
66
|
-
themes: ['github-light', 'github-dark'],
|
|
67
|
-
langs: Array.from(ESSENTIAL_LANGUAGES),
|
|
68
|
-
});
|
|
69
|
-
// Initialize loaded languages tracking
|
|
70
|
-
ESSENTIAL_LANGUAGES.forEach(lang => loadedLanguages.add(resolveLanguageAlias(lang)));
|
|
71
|
-
}
|
|
72
|
-
return highlighterInstance;
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Pre-load a list of languages in parallel
|
|
76
|
-
* Called after scanning all files to load only the languages actually used
|
|
77
|
-
*/
|
|
78
|
-
export async function preloadLanguages(languages) {
|
|
79
|
-
if (!highlighterInstance) {
|
|
80
|
-
// Create base highlighter with essential languages first
|
|
81
|
-
await getHighlighterInstance();
|
|
82
|
-
}
|
|
83
|
-
// Load all needed languages in parallel
|
|
84
|
-
const loadPromises = [];
|
|
85
|
-
for (const lang of languages) {
|
|
86
|
-
const resolved = resolveLanguageAlias(lang);
|
|
87
|
-
if (!loadedLanguages.has(resolved)) {
|
|
88
|
-
loadPromises.push((async () => {
|
|
89
|
-
try {
|
|
90
|
-
const { bundledLanguages } = await import('shiki/langs');
|
|
91
|
-
if (resolved in bundledLanguages) {
|
|
92
|
-
await highlighterInstance.loadLanguage(bundledLanguages[resolved]);
|
|
93
|
-
loadedLanguages.add(resolved);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
catch {
|
|
97
|
-
// Language not available, ignore
|
|
98
|
-
}
|
|
99
|
-
})());
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
await Promise.all(loadPromises);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Get or create a shared MarkdownIt instance
|
|
106
|
-
* This allows reusing the same instance across multiple parseMarkdown calls
|
|
107
|
-
*
|
|
108
|
-
* @param options - Markdown parsing options
|
|
109
|
-
* @param env - Markdown environment context
|
|
110
|
-
* @returns Configured MarkdownIt instance
|
|
111
|
-
*/
|
|
112
|
-
export async function getMarkdownIt(options = {}, env = {}) {
|
|
113
|
-
const highlighter = await getHighlighterInstance();
|
|
114
|
-
// Create enhanced highlighter with line features
|
|
115
|
-
const enhancedHighlight = createEnhancedHighlighter(highlighter, {
|
|
116
|
-
lineNumbers: options.lineNumbers ?? true,
|
|
117
|
-
});
|
|
118
|
-
const md = new MarkdownIt({
|
|
119
|
-
html: true, // Allow HTML in markdown (authors are trusted in SSG context)
|
|
120
|
-
linkify: true,
|
|
121
|
-
typographer: true,
|
|
122
|
-
highlight: (code, lang, attrs) => {
|
|
123
|
-
if (!lang) {
|
|
124
|
-
return ''; // Use default escaping
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
// attrs contains a meta string (e.g., "{4}" or "title='file.js'")
|
|
128
|
-
return enhancedHighlight(code, lang, attrs);
|
|
129
|
-
}
|
|
130
|
-
catch (e) {
|
|
131
|
-
// Fallback for unsupported languages
|
|
132
|
-
return '';
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
});
|
|
136
|
-
// Add plugins
|
|
137
|
-
md.use(mdAnchor, {
|
|
138
|
-
slugify: slugify,
|
|
139
|
-
permalink: mdAnchor.permalink.linkInsideHeader({
|
|
140
|
-
symbol: '#',
|
|
141
|
-
placement: 'before',
|
|
142
|
-
}),
|
|
143
|
-
});
|
|
144
|
-
md.use(mdAttrs);
|
|
145
|
-
md.use(mdEmoji.full || mdEmoji.bare);
|
|
146
|
-
// Add custom containers (tip, warning, danger, info, note)
|
|
147
|
-
setupContainers(md);
|
|
148
|
-
// Add collapsible details container
|
|
149
|
-
setupDetails(md);
|
|
150
|
-
// Add preserve Marko tags plugin if enabled
|
|
151
|
-
if (options.markoTags?.enabled) {
|
|
152
|
-
md.use(preserveTagsPlugin, {
|
|
153
|
-
tagsDir: options.markoTags?.tagsDir || 'tags/',
|
|
154
|
-
onTagDetected: (tagName, lineNumber) => {
|
|
155
|
-
// Track tag for validation at end of build
|
|
156
|
-
globalTagValidator.addDetectedTag(tagName, env.filePath || 'unknown', lineNumber);
|
|
157
|
-
},
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
return md;
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Parse markdown with frontmatter
|
|
164
|
-
*/
|
|
165
|
-
export async function parseMarkdown(src, options = {}, env = {}, existingMd) {
|
|
166
|
-
// Parse frontmatter
|
|
167
|
-
const { data: frontmatter, content: rawContent, excerpt } = matter(src, {
|
|
168
|
-
excerpt: true,
|
|
169
|
-
excerpt_separator: '<!-- more -->',
|
|
170
|
-
});
|
|
171
|
-
// Preprocess file includes
|
|
172
|
-
const content = await preprocessIncludesWithRegions(rawContent, {
|
|
173
|
-
root: env.rootDir ?? process.cwd(),
|
|
174
|
-
currentFile: env.filePath ?? '',
|
|
175
|
-
});
|
|
176
|
-
// Use provided MarkdownIt or create new one
|
|
177
|
-
const md = existingMd || await setupMarkdownIt(options, env);
|
|
178
|
-
// Render to HTML
|
|
179
|
-
const html = md.render(content, env);
|
|
180
|
-
// Extract headers only if TOC is enabled for this module
|
|
181
|
-
const headers = env.extractToc ? extractHeaders(content) : [];
|
|
182
|
-
return {
|
|
183
|
-
frontmatter,
|
|
184
|
-
content,
|
|
185
|
-
html,
|
|
186
|
-
excerpt,
|
|
187
|
-
headers: buildHeaderTree(headers),
|
|
188
|
-
};
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Setup markdown-it with plugins and Shiki highlighting
|
|
192
|
-
* @deprecated Use getMarkdownIt() directly for better reusability
|
|
193
|
-
*/
|
|
194
|
-
async function setupMarkdownIt(options, env) {
|
|
195
|
-
return getMarkdownIt(options, env);
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Strip markdown formatting from text for cleaner TOC entries
|
|
199
|
-
* Removes bold, italic, code, links, and other inline markdown
|
|
200
|
-
*/
|
|
201
|
-
function stripMarkdownFormatting(text) {
|
|
202
|
-
return text
|
|
203
|
-
// Remove inline code: `code`
|
|
204
|
-
.replace(/`([^`]+)`/g, '$1')
|
|
205
|
-
// Remove bold/italic: **text**, __text__, *text*, _text_
|
|
206
|
-
.replace(/\*\*\*\+([^*]+)\*\*\+/g, '$1')
|
|
207
|
-
.replace(/___+([^_]+)___+/g, '$1')
|
|
208
|
-
.replace(/\*\*([^*]+)\*\*/g, '$1')
|
|
209
|
-
.replace(/__([^_]+)__/g, '$1')
|
|
210
|
-
.replace(/\*([^*]+)\*/g, '$1')
|
|
211
|
-
.replace(/_([^_]+)_/g, '$1')
|
|
212
|
-
// Remove links: [text](url) or [text](url "title")
|
|
213
|
-
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
|
|
214
|
-
.replace(/\[([^\]]+)\]\[[^\]]+\]/g, '$1')
|
|
215
|
-
.trim();
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Extract headers from markdown content
|
|
219
|
-
* Skips code blocks (fenced and indented) to avoid extracting comments from code examples
|
|
220
|
-
*/
|
|
221
|
-
function extractHeaders(content) {
|
|
222
|
-
const headers = [];
|
|
223
|
-
// Remove code blocks before processing headers
|
|
224
|
-
// This prevents extracting # comments from bash/code examples
|
|
225
|
-
const withoutCodeBlocks = content
|
|
226
|
-
.replace(/```[\s\S]*?```/g, '') // Fenced code blocks
|
|
227
|
-
.replace(/~~~[\s\S]*?~~~/g, '') // Tilde-fenced code blocks
|
|
228
|
-
.replace(/^(\t| {4}).+$/gm, ''); // Indented code blocks
|
|
229
|
-
const headerRegex = /^(#{1,6})\s+(.+)$/gm;
|
|
230
|
-
let match;
|
|
231
|
-
while ((match = headerRegex.exec(withoutCodeBlocks)) !== null) {
|
|
232
|
-
const level = match[1].length;
|
|
233
|
-
const rawTitle = match[2].trim();
|
|
234
|
-
const title = stripMarkdownFormatting(rawTitle);
|
|
235
|
-
const slug = slugify(rawTitle); // Use raw title for slug to preserve numbering
|
|
236
|
-
headers.push({ level, title, slug });
|
|
237
|
-
}
|
|
238
|
-
return headers;
|
|
239
|
-
}
|
|
240
|
-
/**
|
|
241
|
-
* Build header tree from flat list
|
|
242
|
-
*/
|
|
243
|
-
function buildHeaderTree(headers) {
|
|
244
|
-
const result = [];
|
|
245
|
-
const stack = [];
|
|
246
|
-
for (const header of headers) {
|
|
247
|
-
const node = {
|
|
248
|
-
level: header.level,
|
|
249
|
-
title: header.title,
|
|
250
|
-
slug: header.slug,
|
|
251
|
-
children: [],
|
|
252
|
-
};
|
|
253
|
-
// Pop from stack until we find parent level
|
|
254
|
-
while (stack.length > 0 && stack[stack.length - 1].level >= header.level) {
|
|
255
|
-
stack.pop();
|
|
256
|
-
}
|
|
257
|
-
if (stack.length === 0) {
|
|
258
|
-
result.push(node);
|
|
259
|
-
}
|
|
260
|
-
else {
|
|
261
|
-
stack[stack.length - 1].children.push(node);
|
|
262
|
-
}
|
|
263
|
-
stack.push(node);
|
|
264
|
-
}
|
|
265
|
-
return result;
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Slugify text for URL-safe IDs
|
|
269
|
-
* Preserves emojis (URL-safe) and text, removes special chars
|
|
270
|
-
* Handles camelCase by inserting hyphens at word boundaries
|
|
271
|
-
*/
|
|
272
|
-
function slugify(text) {
|
|
273
|
-
return text
|
|
274
|
-
.trim()
|
|
275
|
-
// Insert hyphens between lowercase-to-uppercase transitions (camelCase)
|
|
276
|
-
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
277
|
-
// Insert hyphens between digit-to-letter transitions
|
|
278
|
-
.replace(/([0-9])([a-zA-Z])/g, '$1-$2')
|
|
279
|
-
// Insert hyphens between letter-to-digit transitions
|
|
280
|
-
.replace(/([a-zA-Z])([0-9])/g, '$1-$2')
|
|
281
|
-
.toLowerCase()
|
|
282
|
-
// Replace spaces with hyphens
|
|
283
|
-
.replace(/\s+/g, '-')
|
|
284
|
-
// Remove special chars but keep letters, numbers, hyphens, and emojis
|
|
285
|
-
// Emojis are in Unicode ranges outside \w (word chars)
|
|
286
|
-
.replace(/[^\w\u00A0-\uFFFF\-]+/g, '')
|
|
287
|
-
// Remove leading/trailing hyphens
|
|
288
|
-
.replace(/^-+|-+$/g, '')
|
|
289
|
-
// Replace multiple hyphens with single
|
|
290
|
-
.replace(/-+/g, '-');
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Validate frontmatter against VitePress/Docusaurus schema
|
|
294
|
-
*/
|
|
295
|
-
export function validateFrontmatter(frontmatter) {
|
|
296
|
-
const errors = [];
|
|
297
|
-
// Common fields
|
|
298
|
-
if (frontmatter.title !== undefined && typeof frontmatter.title !== 'string') {
|
|
299
|
-
errors.push('title must be a string');
|
|
300
|
-
}
|
|
301
|
-
if (frontmatter.description !== undefined && typeof frontmatter.description !== 'string') {
|
|
302
|
-
errors.push('description must be a string');
|
|
303
|
-
}
|
|
304
|
-
if (frontmatter.draft !== undefined && typeof frontmatter.draft !== 'boolean') {
|
|
305
|
-
errors.push('draft must be a boolean');
|
|
306
|
-
}
|
|
307
|
-
// Date fields
|
|
308
|
-
if (frontmatter.date !== undefined) {
|
|
309
|
-
if (!(typeof frontmatter.date === 'string' || frontmatter.date instanceof Date)) {
|
|
310
|
-
errors.push('date must be a string or Date');
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
// Tags/categories
|
|
314
|
-
if (frontmatter.tags !== undefined && !Array.isArray(frontmatter.tags)) {
|
|
315
|
-
errors.push('tags must be an array');
|
|
316
|
-
}
|
|
317
|
-
if (frontmatter.categories !== undefined && !Array.isArray(frontmatter.categories)) {
|
|
318
|
-
errors.push('categories must be an array');
|
|
319
|
-
}
|
|
320
|
-
return {
|
|
321
|
-
valid: errors.length === 0,
|
|
322
|
-
errors,
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
//# sourceMappingURL=loader.js.map
|
|
1
|
+
import e from"gray-matter";import t from"markdown-it";import r from"markdown-it-anchor";import a from"markdown-it-attrs";import*as s from"markdown-it-emoji";import{createHighlighter as n}from"shiki";import{setupContainers as o,setupDetails as i}from"./containers.js";import{createEnhancedHighlighter as c}from"./code.js";import{preprocessIncludesWithRegions as l}from"./includes.js";import{preserveTagsPlugin as p}from"./preserve-tags.js";import{globalTagValidator as g}from"./tag-validator.js";import{basePathPlugin as u}from"./base-path-plugin.js";import{mdLinkPlugin as m}from"./md-link-plugin.js";let d=null;const f=new Set,h=["javascript","typescript","js","ts","bash","markdown","md"],y={js:"javascript",ts:"typescript",py:"python",rs:"rust",sh:"bash",shell:"bash",yml:"yaml",cs:"csharp",cpp:"c++"};function b(e){return y[e]||e}async function w(){return d||(d=await n({themes:["github-light","github-dark"],langs:Array.from(h)}),h.forEach(e=>f.add(b(e)))),d}export async function preloadLanguages(e){d||await w();const t=[];for(const r of e){const e=b(r);f.has(e)||t.push((async()=>{try{const{bundledLanguages:t}=await import("shiki/langs");e in t&&(await d.loadLanguage(t[e]),f.add(e))}catch{}})())}await Promise.all(t)}export async function getMarkdownIt(e={},n={}){const l=await w(),d=c(l,{lineNumbers:e.lineNumbers??!0}),f=new t({html:!0,linkify:!0,typographer:!0,highlight:(e,t,r)=>{if(!t)return"";try{return d(e,t,r)}catch(e){return""}}});return f.use(r,{slugify:v,permalink:r.permalink.linkInsideHeader({symbol:"#",placement:"before"})}),f.use(a),f.use(s.full||s.bare),o(f),i(f),e.markoTags?.enabled&&f.use(p,{tagsDir:e.markoTags?.tagsDir||"tags/",onTagDetected:(e,t)=>{g.addDetectedTag(e,n.filePath||"unknown",t)}}),f.use(m),e.base&&f.use(u,e.base),f}export async function parseMarkdown(t,r={},a={},s){const{data:n,content:o,excerpt:i}=e(t,{excerpt:!0,excerpt_separator:"\x3c!-- more --\x3e"}),c=await l(o,{root:a.rootDir??process.cwd(),currentFile:a.filePath??""}),p=s||await async function(e,t){return getMarkdownIt(e,t)}(r,a),g=p.render(c,a),u=a.extractToc?function(e){const t=[],r=e.replace(/```[\s\S]*?```/g,"").replace(/~~~[\s\S]*?~~~/g,"").replace(/^(\t| {4}).+$/gm,""),a=/^(#{1,6})\s+(.+)$/gm;let s;for(;null!==(s=a.exec(r));){const e=s[1].length,r=s[2].trim(),a=k(r),n=v(r);t.push({level:e,title:a,slug:n})}return t}(c):[];return{frontmatter:n,content:c,html:g,excerpt:i,headers:$(u)}}function k(e){return e.replace(/`([^`]+)`/g,"$1").replace(/\*\*\*\+([^*]+)\*\*\+/g,"$1").replace(/___+([^_]+)___+/g,"$1").replace(/\*\*([^*]+)\*\*/g,"$1").replace(/__([^_]+)__/g,"$1").replace(/\*([^*]+)\*/g,"$1").replace(/_([^_]+)_/g,"$1").replace(/\[([^\]]+)\]\([^)]+\)/g,"$1").replace(/\[([^\]]+)\]\[[^\]]+\]/g,"$1").trim()}function $(e){const t=[],r=[];for(const a of e){const e={level:a.level,title:a.title,slug:a.slug,children:[]};for(;r.length>0&&r[r.length-1].level>=a.level;)r.pop();0===r.length?t.push(e):r[r.length-1].children.push(e),r.push(e)}return t}function v(e){return e.trim().replace(/([a-z])([A-Z])/g,"$1-$2").replace(/([0-9])([a-zA-Z])/g,"$1-$2").replace(/([a-zA-Z])([0-9])/g,"$1-$2").toLowerCase().replace(/\s+/g,"-").replace(/[^\w\u00A0-\uFFFF\-]+/g,"").replace(/^-+|-+$/g,"").replace(/-+/g,"-")}export function validateFrontmatter(e){const t=[];return void 0!==e.title&&"string"!=typeof e.title&&t.push("title must be a string"),void 0!==e.description&&"string"!=typeof e.description&&t.push("description must be a string"),void 0!==e.draft&&"boolean"!=typeof e.draft&&t.push("draft must be a boolean"),void 0!==e.date&&("string"==typeof e.date||e.date instanceof Date||t.push("date must be a string or Date")),void 0===e.tags||Array.isArray(e.tags)||t.push("tags must be an array"),void 0===e.categories||Array.isArray(e.categories)||t.push("categories must be an array"),{valid:0===t.length,errors:t}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type MarkdownIt from 'markdown-it';
|
|
2
|
+
/**
|
|
3
|
+
* markdown-it plugin that strips .md extensions from link hrefs.
|
|
4
|
+
*
|
|
5
|
+
* Rewrites:
|
|
6
|
+
* ./theming.md → ./theming
|
|
7
|
+
* ../guides/api.md → ../guides/api
|
|
8
|
+
* /guides/plugins.md → /guides/plugins
|
|
9
|
+
*
|
|
10
|
+
* Does NOT rewrite:
|
|
11
|
+
* https://example.com/file.md (external)
|
|
12
|
+
* #section (anchor)
|
|
13
|
+
*/
|
|
14
|
+
export declare function mdLinkPlugin(md: MarkdownIt): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export function mdLinkPlugin(n){const r=n.renderer.rules.link_open||((t,e,n,r,s)=>s.renderToken(t,e,n));n.renderer.rules.link_open=(e,n,s,i,o)=>{const l=e[n].attrIndex("href");if(l>=0){const r=e[n].attrs[l][1];e[n].attrs[l][1]=t(r)}return r(e,n,s,i,o)};const s=n.renderer.rules.html_block||((t,e)=>t[e].content);n.renderer.rules.html_block=(t,n,r,i,o)=>(t[n].content=e(t[n].content),s(t,n,r,i,o));const i=n.renderer.rules.html_inline||((t,e)=>t[e].content);n.renderer.rules.html_inline=(t,n,r,s,o)=>(t[n].content=e(t[n].content),i(t,n,r,s,o))}function t(t){return t.startsWith("http://")||t.startsWith("https://")||t.startsWith("//")||t.startsWith("#")||t.startsWith("mailto:")?t:t.endsWith(".md")?t.slice(0,-3):t}function e(e){return e.replace(/(href\s*=\s*)(["'])([^"']*\.md)\2/gi,(e,n,r,s)=>n+r+t(s)+r)}
|