md-tech-pdf 0.1.0
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/LICENSE +176 -0
- package/README.ja.md +330 -0
- package/README.md +315 -0
- package/dist/cli/index.d.ts +10 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +96 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config/config-resolver.d.ts +19 -0
- package/dist/config/config-resolver.d.ts.map +1 -0
- package/dist/config/config-resolver.js +41 -0
- package/dist/config/config-resolver.js.map +1 -0
- package/dist/config/document-options.d.ts +52 -0
- package/dist/config/document-options.d.ts.map +1 -0
- package/dist/config/document-options.js +8 -0
- package/dist/config/document-options.js.map +1 -0
- package/dist/config/error.d.ts +12 -0
- package/dist/config/error.d.ts.map +1 -0
- package/dist/config/error.js +12 -0
- package/dist/config/error.js.map +1 -0
- package/dist/config/frontmatter-parser.d.ts +16 -0
- package/dist/config/frontmatter-parser.d.ts.map +1 -0
- package/dist/config/frontmatter-parser.js +271 -0
- package/dist/config/frontmatter-parser.js.map +1 -0
- package/dist/core/converter.d.ts +34 -0
- package/dist/core/converter.d.ts.map +1 -0
- package/dist/core/converter.js +109 -0
- package/dist/core/converter.js.map +1 -0
- package/dist/html/default-style.d.ts +6 -0
- package/dist/html/default-style.d.ts.map +1 -0
- package/dist/html/default-style.js +237 -0
- package/dist/html/default-style.js.map +1 -0
- package/dist/html/google-fonts.d.ts +20 -0
- package/dist/html/google-fonts.d.ts.map +1 -0
- package/dist/html/google-fonts.js +50 -0
- package/dist/html/google-fonts.js.map +1 -0
- package/dist/html/html-builder.d.ts +20 -0
- package/dist/html/html-builder.d.ts.map +1 -0
- package/dist/html/html-builder.js +88 -0
- package/dist/html/html-builder.js.map +1 -0
- package/dist/html/html-renderer.d.ts +25 -0
- package/dist/html/html-renderer.d.ts.map +1 -0
- package/dist/html/html-renderer.js +148 -0
- package/dist/html/html-renderer.js.map +1 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/attributes-parser.d.ts +13 -0
- package/dist/parser/attributes-parser.d.ts.map +1 -0
- package/dist/parser/attributes-parser.js +110 -0
- package/dist/parser/attributes-parser.js.map +1 -0
- package/dist/parser/error.d.ts +15 -0
- package/dist/parser/error.d.ts.map +1 -0
- package/dist/parser/error.js +15 -0
- package/dist/parser/error.js.map +1 -0
- package/dist/parser/markdown-parser.d.ts +17 -0
- package/dist/parser/markdown-parser.d.ts.map +1 -0
- package/dist/parser/markdown-parser.js +86 -0
- package/dist/parser/markdown-parser.js.map +1 -0
- package/dist/pdf/default-options.d.ts +6 -0
- package/dist/pdf/default-options.d.ts.map +1 -0
- package/dist/pdf/default-options.js +12 -0
- package/dist/pdf/default-options.js.map +1 -0
- package/dist/pdf/error.d.ts +9 -0
- package/dist/pdf/error.d.ts.map +1 -0
- package/dist/pdf/error.js +10 -0
- package/dist/pdf/error.js.map +1 -0
- package/dist/pdf/pdf-generator.d.ts +16 -0
- package/dist/pdf/pdf-generator.d.ts.map +1 -0
- package/dist/pdf/pdf-generator.js +95 -0
- package/dist/pdf/pdf-generator.js.map +1 -0
- package/dist/pdf/types.d.ts +16 -0
- package/dist/pdf/types.d.ts.map +1 -0
- package/dist/pdf/types.js +2 -0
- package/dist/pdf/types.js.map +1 -0
- package/dist/renderer/diagram-renderer.d.ts +11 -0
- package/dist/renderer/diagram-renderer.d.ts.map +1 -0
- package/dist/renderer/diagram-renderer.js +2 -0
- package/dist/renderer/diagram-renderer.js.map +1 -0
- package/dist/renderer/error.d.ts +10 -0
- package/dist/renderer/error.d.ts.map +1 -0
- package/dist/renderer/error.js +10 -0
- package/dist/renderer/error.js.map +1 -0
- package/dist/renderer/mermaid-executor.d.ts +16 -0
- package/dist/renderer/mermaid-executor.d.ts.map +1 -0
- package/dist/renderer/mermaid-executor.js +99 -0
- package/dist/renderer/mermaid-executor.js.map +1 -0
- package/dist/renderer/mermaid-renderer.d.ts +25 -0
- package/dist/renderer/mermaid-renderer.d.ts.map +1 -0
- package/dist/renderer/mermaid-renderer.js +35 -0
- package/dist/renderer/mermaid-renderer.js.map +1 -0
- package/dist/renderer/plantuml-executor.d.ts +11 -0
- package/dist/renderer/plantuml-executor.d.ts.map +1 -0
- package/dist/renderer/plantuml-executor.js +100 -0
- package/dist/renderer/plantuml-executor.js.map +1 -0
- package/dist/renderer/plantuml-renderer.d.ts +26 -0
- package/dist/renderer/plantuml-renderer.d.ts.map +1 -0
- package/dist/renderer/plantuml-renderer.js +95 -0
- package/dist/renderer/plantuml-renderer.js.map +1 -0
- package/dist/types/diagram.d.ts +34 -0
- package/dist/types/diagram.d.ts.map +1 -0
- package/dist/types/diagram.js +2 -0
- package/dist/types/diagram.js.map +1 -0
- package/package.json +70 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default CSS stylesheet for md-tech-pdf HTML output.
|
|
3
|
+
* Designed for clean technical documentation readability and print/PDF layout.
|
|
4
|
+
*/
|
|
5
|
+
export const DEFAULT_DOCUMENT_STYLE = `
|
|
6
|
+
:root {
|
|
7
|
+
--color-bg: #ffffff;
|
|
8
|
+
--color-text: #24292f;
|
|
9
|
+
--color-text-muted: #57606a;
|
|
10
|
+
--color-border: #d0d7de;
|
|
11
|
+
--color-code-bg: #f6f8fa;
|
|
12
|
+
--color-blockquote-border: #d0d7de;
|
|
13
|
+
--font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, "Noto Sans JP", sans-serif;
|
|
14
|
+
--font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
*, *::before, *::after {
|
|
18
|
+
box-sizing: border-box;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
html {
|
|
22
|
+
font-size: 16px;
|
|
23
|
+
line-height: 1.6;
|
|
24
|
+
-webkit-text-size-adjust: 100%;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
body {
|
|
28
|
+
margin: 0;
|
|
29
|
+
padding: 0;
|
|
30
|
+
background-color: var(--color-bg);
|
|
31
|
+
color: var(--color-text);
|
|
32
|
+
font-family: var(--font-sans);
|
|
33
|
+
font-size: 1rem;
|
|
34
|
+
word-wrap: break-word;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/* Headings */
|
|
38
|
+
h1, h2, h3, h4, h5, h6 {
|
|
39
|
+
margin-top: 1.8rem;
|
|
40
|
+
margin-bottom: 0.8rem;
|
|
41
|
+
font-weight: 600;
|
|
42
|
+
line-height: 1.3;
|
|
43
|
+
color: var(--color-text);
|
|
44
|
+
page-break-after: avoid;
|
|
45
|
+
break-after: avoid;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Prevent heading orphans by keeping them with the subsequent content element */
|
|
49
|
+
h1 + *, h2 + *, h3 + *, h4 + *, h5 + *, h6 + * {
|
|
50
|
+
page-break-before: avoid;
|
|
51
|
+
break-before: avoid;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
h1 {
|
|
55
|
+
font-size: 2rem;
|
|
56
|
+
padding-bottom: 0.4rem;
|
|
57
|
+
border-bottom: 1px solid var(--color-border);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
h2 {
|
|
61
|
+
font-size: 1.5rem;
|
|
62
|
+
padding-bottom: 0.3rem;
|
|
63
|
+
border-bottom: 1px solid var(--color-border);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
h3 { font-size: 1.25rem; }
|
|
67
|
+
h4 { font-size: 1.1rem; }
|
|
68
|
+
h5 { font-size: 1rem; }
|
|
69
|
+
h6 { font-size: 0.9rem; color: var(--color-text-muted); }
|
|
70
|
+
|
|
71
|
+
/* Paragraph & Lists */
|
|
72
|
+
p {
|
|
73
|
+
margin-top: 0;
|
|
74
|
+
margin-bottom: 1rem;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
ul, ol {
|
|
78
|
+
margin-top: 0;
|
|
79
|
+
margin-bottom: 1rem;
|
|
80
|
+
padding-left: 2rem;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
li {
|
|
84
|
+
margin-bottom: 0.3rem;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
li > p {
|
|
88
|
+
margin-bottom: 0.5rem;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* Blockquote */
|
|
92
|
+
blockquote {
|
|
93
|
+
margin: 1rem 0;
|
|
94
|
+
padding: 0.5rem 1rem;
|
|
95
|
+
color: var(--color-text-muted);
|
|
96
|
+
border-left: 0.25rem solid var(--color-blockquote-border);
|
|
97
|
+
background-color: var(--color-code-bg);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
blockquote > :first-child { margin-top: 0; }
|
|
101
|
+
blockquote > :last-child { margin-bottom: 0; }
|
|
102
|
+
|
|
103
|
+
/* Tables */
|
|
104
|
+
table {
|
|
105
|
+
border-collapse: collapse;
|
|
106
|
+
width: 100%;
|
|
107
|
+
margin-top: 1rem;
|
|
108
|
+
margin-bottom: 1.5rem;
|
|
109
|
+
display: table;
|
|
110
|
+
table-layout: auto;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
table th, table td {
|
|
114
|
+
padding: 0.5rem 0.6rem;
|
|
115
|
+
border: 1px solid var(--color-border);
|
|
116
|
+
text-align: left;
|
|
117
|
+
overflow-wrap: anywhere;
|
|
118
|
+
word-break: normal;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
table th {
|
|
122
|
+
background-color: var(--color-code-bg);
|
|
123
|
+
font-weight: 600;
|
|
124
|
+
word-break: keep-all;
|
|
125
|
+
overflow-wrap: normal;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
table tr:nth-child(2n) {
|
|
129
|
+
background-color: #fafbfc;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Code and Preformatted text */
|
|
133
|
+
code {
|
|
134
|
+
font-family: var(--font-mono);
|
|
135
|
+
font-size: 85%;
|
|
136
|
+
padding: 0.2em 0.4em;
|
|
137
|
+
margin: 0;
|
|
138
|
+
background-color: var(--color-code-bg);
|
|
139
|
+
border-radius: 4px;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
pre {
|
|
143
|
+
margin-top: 1rem;
|
|
144
|
+
margin-bottom: 1.5rem;
|
|
145
|
+
padding: 1rem;
|
|
146
|
+
font-family: var(--font-mono);
|
|
147
|
+
font-size: 85%;
|
|
148
|
+
line-height: 1.45;
|
|
149
|
+
background-color: var(--color-code-bg);
|
|
150
|
+
border: 1px solid var(--color-border);
|
|
151
|
+
border-radius: 6px;
|
|
152
|
+
page-break-inside: avoid;
|
|
153
|
+
break-inside: avoid;
|
|
154
|
+
white-space: pre-wrap;
|
|
155
|
+
overflow-wrap: anywhere;
|
|
156
|
+
word-break: normal;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
pre code {
|
|
160
|
+
padding: 0;
|
|
161
|
+
background-color: transparent;
|
|
162
|
+
border-radius: 0;
|
|
163
|
+
font-size: 100%;
|
|
164
|
+
white-space: inherit;
|
|
165
|
+
overflow-wrap: inherit;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/* Links */
|
|
169
|
+
a {
|
|
170
|
+
color: #0969da;
|
|
171
|
+
text-decoration: none;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
a:hover {
|
|
175
|
+
text-decoration: underline;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
hr {
|
|
179
|
+
height: 0.25em;
|
|
180
|
+
padding: 0;
|
|
181
|
+
margin: 2rem 0;
|
|
182
|
+
background-color: var(--color-border);
|
|
183
|
+
border: 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* Diagram Container & Alignment */
|
|
187
|
+
.md-tech-diagram {
|
|
188
|
+
margin-top: 1.5rem;
|
|
189
|
+
margin-bottom: 1.5rem;
|
|
190
|
+
display: block;
|
|
191
|
+
page-break-inside: avoid;
|
|
192
|
+
break-inside: avoid;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
.md-tech-diagram-align-center {
|
|
196
|
+
margin-left: auto;
|
|
197
|
+
margin-right: auto;
|
|
198
|
+
text-align: center;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
.md-tech-diagram-align-left {
|
|
202
|
+
margin-left: 0;
|
|
203
|
+
margin-right: auto;
|
|
204
|
+
text-align: left;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
.md-tech-diagram-align-right {
|
|
208
|
+
margin-left: auto;
|
|
209
|
+
margin-right: 0;
|
|
210
|
+
text-align: right;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.md-tech-diagram-content {
|
|
214
|
+
display: inline-flex;
|
|
215
|
+
justify-content: center;
|
|
216
|
+
align-items: center;
|
|
217
|
+
width: 100%;
|
|
218
|
+
height: 100%;
|
|
219
|
+
overflow: hidden;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* Diagram Fit modes */
|
|
223
|
+
.md-tech-diagram-fit-contain .md-tech-diagram-content svg {
|
|
224
|
+
width: 100%;
|
|
225
|
+
height: 100%;
|
|
226
|
+
max-width: 100%;
|
|
227
|
+
max-height: 100%;
|
|
228
|
+
object-fit: contain;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.md-tech-diagram-fit-fill .md-tech-diagram-content svg {
|
|
232
|
+
width: 100%;
|
|
233
|
+
height: 100%;
|
|
234
|
+
object-fit: fill;
|
|
235
|
+
}
|
|
236
|
+
`;
|
|
237
|
+
//# sourceMappingURL=default-style.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-style.js","sourceRoot":"","sources":["../../src/html/default-style.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuOrC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { GoogleFontsOptions } from '../config/document-options.js';
|
|
2
|
+
export declare const ALLOWED_GOOGLE_FONT_WEIGHTS: readonly [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
3
|
+
/**
|
|
4
|
+
* Builds Google Fonts CSS2 API URL from GoogleFontsOptions.
|
|
5
|
+
* Returns null if no families are specified.
|
|
6
|
+
*
|
|
7
|
+
* Example output:
|
|
8
|
+
* https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&family=Roboto+Mono:wght@400;700&display=swap
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildGoogleFontsUrl(options?: GoogleFontsOptions): string | null;
|
|
11
|
+
/**
|
|
12
|
+
* Sanitizes a font family name and formats it safely for CSS font-family declarations.
|
|
13
|
+
* Prevents CSS injection by removing control characters, quotes, and structural CSS delimiters.
|
|
14
|
+
*
|
|
15
|
+
* Example:
|
|
16
|
+
* buildFontFamilyCss("Noto Sans JP", "sans-serif")
|
|
17
|
+
* -> '"Noto Sans JP", sans-serif'
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildFontFamilyCss(family: string, fallback: 'sans-serif' | 'monospace'): string;
|
|
20
|
+
//# sourceMappingURL=google-fonts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-fonts.d.ts","sourceRoot":"","sources":["../../src/html/google-fonts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE,eAAO,MAAM,2BAA2B,wDAAyD,CAAC;AAElG;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,MAAM,GAAG,IAAI,CAgC/E;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,WAAW,GAAG,MAAM,CAK/F"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const ALLOWED_GOOGLE_FONT_WEIGHTS = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
|
2
|
+
/**
|
|
3
|
+
* Builds Google Fonts CSS2 API URL from GoogleFontsOptions.
|
|
4
|
+
* Returns null if no families are specified.
|
|
5
|
+
*
|
|
6
|
+
* Example output:
|
|
7
|
+
* https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@400;500;700&family=Roboto+Mono:wght@400;700&display=swap
|
|
8
|
+
*/
|
|
9
|
+
export function buildGoogleFontsUrl(options) {
|
|
10
|
+
if (!options || !Array.isArray(options.families) || options.families.length === 0) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const familyParams = [];
|
|
14
|
+
for (const item of options.families) {
|
|
15
|
+
const trimmedName = item.name?.trim();
|
|
16
|
+
if (!trimmedName) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
// Google Fonts format replaces spaces with '+'
|
|
20
|
+
// Encode special URI characters while representing spaces as '+'
|
|
21
|
+
const encodedName = encodeURIComponent(trimmedName).replace(/%20/g, '+');
|
|
22
|
+
if (item.weights && item.weights.length > 0) {
|
|
23
|
+
// Deduplicate and sort weights ascending
|
|
24
|
+
const uniqueWeights = Array.from(new Set(item.weights)).sort((a, b) => a - b);
|
|
25
|
+
const weightsStr = uniqueWeights.join(';');
|
|
26
|
+
familyParams.push(`family=${encodedName}:wght@${weightsStr}`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
familyParams.push(`family=${encodedName}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (familyParams.length === 0) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
return `https://fonts.googleapis.com/css2?${familyParams.join('&')}&display=swap`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Sanitizes a font family name and formats it safely for CSS font-family declarations.
|
|
39
|
+
* Prevents CSS injection by removing control characters, quotes, and structural CSS delimiters.
|
|
40
|
+
*
|
|
41
|
+
* Example:
|
|
42
|
+
* buildFontFamilyCss("Noto Sans JP", "sans-serif")
|
|
43
|
+
* -> '"Noto Sans JP", sans-serif'
|
|
44
|
+
*/
|
|
45
|
+
export function buildFontFamilyCss(family, fallback) {
|
|
46
|
+
// Disallow or sanitize characters that could break CSS syntax: ", ', ;, {, }, \, \r, \n
|
|
47
|
+
const sanitized = family.replace(/["';{}\\\r\n]/g, '').trim();
|
|
48
|
+
return `"${sanitized}", ${fallback}`;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=google-fonts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"google-fonts.js","sourceRoot":"","sources":["../../src/html/google-fonts.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAElG;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA4B;IAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,YAAY,GAAa,EAAE,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QACtC,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,SAAS;QACX,CAAC;QAED,+CAA+C;QAC/C,iEAAiE;QACjE,MAAM,WAAW,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAEzE,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,yCAAyC;YACzC,MAAM,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC9E,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3C,YAAY,CAAC,IAAI,CAAC,UAAU,WAAW,SAAS,UAAU,EAAE,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,qCAAqC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC;AACpF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,QAAoC;IACrF,wFAAwF;IACxF,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAE9D,OAAO,IAAI,SAAS,MAAM,QAAQ,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FontOptions } from '../config/document-options.js';
|
|
2
|
+
import type { DiagramFit, DiagramOptions } from '../types/diagram.js';
|
|
3
|
+
export interface DocumentBuildOptions {
|
|
4
|
+
title?: string;
|
|
5
|
+
customCss?: string;
|
|
6
|
+
fontOptions?: FontOptions;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Adjusts the SVG attributes according to the diagram fit mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare function adaptSvgForFit(svg: string, fit: DiagramFit): string;
|
|
12
|
+
/**
|
|
13
|
+
* Builds HTML container structure for a rendered diagram with applied DiagramOptions.
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildDiagramContainer(svg: string, options: DiagramOptions): string;
|
|
16
|
+
/**
|
|
17
|
+
* Wraps rendered HTML body into a complete HTML5 document.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildCompleteHtml(bodyContent: string, options?: DocumentBuildOptions): string;
|
|
20
|
+
//# sourceMappingURL=html-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-builder.d.ts","sourceRoot":"","sources":["../../src/html/html-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAItE,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAWD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,GAAG,MAAM,CASnE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,MAAM,CAwBlF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAiD7F"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { DEFAULT_DOCUMENT_STYLE } from './default-style.js';
|
|
2
|
+
import { buildFontFamilyCss, buildGoogleFontsUrl } from './google-fonts.js';
|
|
3
|
+
function escapeHtml(text) {
|
|
4
|
+
return text
|
|
5
|
+
.replace(/&/g, '&')
|
|
6
|
+
.replace(/</g, '<')
|
|
7
|
+
.replace(/>/g, '>')
|
|
8
|
+
.replace(/"/g, '"')
|
|
9
|
+
.replace(/'/g, ''');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Adjusts the SVG attributes according to the diagram fit mode.
|
|
13
|
+
*/
|
|
14
|
+
export function adaptSvgForFit(svg, fit) {
|
|
15
|
+
const targetAspect = fit === 'fill' ? 'preserveAspectRatio="none"' : 'preserveAspectRatio="xMidYMid meet"';
|
|
16
|
+
if (/preserveAspectRatio="[^"]*"/.test(svg)) {
|
|
17
|
+
return svg.replace(/preserveAspectRatio="[^"]*"/, targetAspect);
|
|
18
|
+
}
|
|
19
|
+
return svg.replace(/<svg\b([^>]*)>/, `<svg$1 ${targetAspect}>`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Builds HTML container structure for a rendered diagram with applied DiagramOptions.
|
|
23
|
+
*/
|
|
24
|
+
export function buildDiagramContainer(svg, options) {
|
|
25
|
+
const styles = [];
|
|
26
|
+
if (options.width) {
|
|
27
|
+
styles.push(`width: ${options.width};`);
|
|
28
|
+
}
|
|
29
|
+
if (options.height) {
|
|
30
|
+
styles.push(`height: ${options.height};`);
|
|
31
|
+
}
|
|
32
|
+
const inlineStyle = styles.length > 0 ? ` style="${styles.join(' ')}"` : '';
|
|
33
|
+
const alignClass = `md-tech-diagram-align-${options.align}`;
|
|
34
|
+
const fitClass = `md-tech-diagram-fit-${options.fit}`;
|
|
35
|
+
const adjustedSvg = adaptSvgForFit(svg, options.fit);
|
|
36
|
+
return [
|
|
37
|
+
`<div class="md-tech-diagram ${alignClass} ${fitClass}"${inlineStyle}>`,
|
|
38
|
+
' <div class="md-tech-diagram-content">',
|
|
39
|
+
` ${adjustedSvg}`,
|
|
40
|
+
' </div>',
|
|
41
|
+
'</div>',
|
|
42
|
+
].join('\n');
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Wraps rendered HTML body into a complete HTML5 document.
|
|
46
|
+
*/
|
|
47
|
+
export function buildCompleteHtml(bodyContent, options) {
|
|
48
|
+
const title = options?.title ?? 'md-tech-pdf';
|
|
49
|
+
const customCss = options?.customCss ?? '';
|
|
50
|
+
const fontOptions = options?.fontOptions;
|
|
51
|
+
const googleFontsUrl = fontOptions?.google ? buildGoogleFontsUrl(fontOptions.google) : null;
|
|
52
|
+
const headLinks = [];
|
|
53
|
+
if (googleFontsUrl) {
|
|
54
|
+
headLinks.push(` <link rel="stylesheet" href="${escapeHtml(googleFontsUrl)}">`);
|
|
55
|
+
}
|
|
56
|
+
const fontStyleRules = [];
|
|
57
|
+
if (fontOptions?.family) {
|
|
58
|
+
fontStyleRules.push(`body { font-family: ${buildFontFamilyCss(fontOptions.family, 'sans-serif')}; }`);
|
|
59
|
+
}
|
|
60
|
+
if (fontOptions?.codeFamily) {
|
|
61
|
+
fontStyleRules.push(`code, pre { font-family: ${buildFontFamilyCss(fontOptions.codeFamily, 'monospace')}; }`);
|
|
62
|
+
}
|
|
63
|
+
const fontCss = fontStyleRules.length > 0 ? fontStyleRules.join('\n') : '';
|
|
64
|
+
const headContent = [
|
|
65
|
+
' <meta charset="UTF-8">',
|
|
66
|
+
' <meta name="viewport" content="width=device-width, initial-scale=1.0">',
|
|
67
|
+
` <title>${escapeHtml(title)}</title>`,
|
|
68
|
+
...headLinks,
|
|
69
|
+
' <style>',
|
|
70
|
+
DEFAULT_DOCUMENT_STYLE,
|
|
71
|
+
fontCss,
|
|
72
|
+
customCss,
|
|
73
|
+
' </style>',
|
|
74
|
+
].join('\n');
|
|
75
|
+
return [
|
|
76
|
+
'<!DOCTYPE html>',
|
|
77
|
+
'<html lang="ja">',
|
|
78
|
+
'<head>',
|
|
79
|
+
headContent,
|
|
80
|
+
'</head>',
|
|
81
|
+
'<body>',
|
|
82
|
+
bodyContent,
|
|
83
|
+
'</body>',
|
|
84
|
+
'</html>',
|
|
85
|
+
'',
|
|
86
|
+
].join('\n');
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=html-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-builder.js","sourceRoot":"","sources":["../../src/html/html-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DocumentOptions } from '../config/document-options.js';
|
|
2
|
+
import type { DiagramRenderer } from '../renderer/diagram-renderer.js';
|
|
3
|
+
export interface HtmlRenderOptions {
|
|
4
|
+
title?: string;
|
|
5
|
+
customCss?: string;
|
|
6
|
+
documentOptions?: DocumentOptions;
|
|
7
|
+
}
|
|
8
|
+
export interface HtmlRendererConfig {
|
|
9
|
+
mermaidRenderer?: DiagramRenderer;
|
|
10
|
+
plantumlRenderer?: DiagramRenderer;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Converts Markdown technical documents into complete HTML documents,
|
|
14
|
+
* extracting Front Matter and rendering Mermaid and PlantUML diagram blocks into styled SVG containers.
|
|
15
|
+
*/
|
|
16
|
+
export declare class HtmlRenderer {
|
|
17
|
+
private readonly renderers;
|
|
18
|
+
private readonly md;
|
|
19
|
+
constructor(mermaidRendererOrConfig?: DiagramRenderer | HtmlRendererConfig, plantumlRenderer?: DiagramRenderer);
|
|
20
|
+
/**
|
|
21
|
+
* Renders Markdown source into a complete HTML5 document.
|
|
22
|
+
*/
|
|
23
|
+
render(markdown: string, options?: HtmlRenderOptions): Promise<string>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=html-renderer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../src/html/html-renderer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAGrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAMvE,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,gBAAgB,CAAC,EAAE,eAAe,CAAC;CACpC;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAkC;gBAGnD,uBAAuB,CAAC,EAAE,eAAe,GAAG,kBAAkB,EAC9D,gBAAgB,CAAC,EAAE,eAAe;IA4BpC;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;CAuI7E"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import MarkdownIt from 'markdown-it';
|
|
2
|
+
import { resolveDiagramOptions } from '../config/config-resolver.js';
|
|
3
|
+
import { parseFrontMatter } from '../config/frontmatter-parser.js';
|
|
4
|
+
import { parseRawAttributes } from '../parser/attributes-parser.js';
|
|
5
|
+
import { MermaidRenderer } from '../renderer/mermaid-renderer.js';
|
|
6
|
+
import { PlantUmlRenderer } from '../renderer/plantuml-renderer.js';
|
|
7
|
+
import { buildCompleteHtml, buildDiagramContainer } from './html-builder.js';
|
|
8
|
+
/**
|
|
9
|
+
* Converts Markdown technical documents into complete HTML documents,
|
|
10
|
+
* extracting Front Matter and rendering Mermaid and PlantUML diagram blocks into styled SVG containers.
|
|
11
|
+
*/
|
|
12
|
+
export class HtmlRenderer {
|
|
13
|
+
renderers;
|
|
14
|
+
md;
|
|
15
|
+
constructor(mermaidRendererOrConfig, plantumlRenderer) {
|
|
16
|
+
this.renderers = new Map();
|
|
17
|
+
if (mermaidRendererOrConfig && 'render' in mermaidRendererOrConfig) {
|
|
18
|
+
this.renderers.set('mermaid', mermaidRendererOrConfig);
|
|
19
|
+
this.renderers.set('plantuml', plantumlRenderer ?? new PlantUmlRenderer());
|
|
20
|
+
}
|
|
21
|
+
else if (mermaidRendererOrConfig && typeof mermaidRendererOrConfig === 'object') {
|
|
22
|
+
this.renderers.set('mermaid', mermaidRendererOrConfig.mermaidRenderer ?? new MermaidRenderer());
|
|
23
|
+
this.renderers.set('plantuml', mermaidRendererOrConfig.plantumlRenderer ?? new PlantUmlRenderer());
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this.renderers.set('mermaid', new MermaidRenderer());
|
|
27
|
+
this.renderers.set('plantuml', plantumlRenderer ?? new PlantUmlRenderer());
|
|
28
|
+
}
|
|
29
|
+
this.md = new MarkdownIt({
|
|
30
|
+
html: true,
|
|
31
|
+
linkify: true,
|
|
32
|
+
typographer: false,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Renders Markdown source into a complete HTML5 document.
|
|
37
|
+
*/
|
|
38
|
+
async render(markdown, options) {
|
|
39
|
+
// 1. Extract Front Matter and separate body content
|
|
40
|
+
const { content: markdownBody, options: parsedDocOptions } = parseFrontMatter(markdown);
|
|
41
|
+
// Merge document options (argument options override parsed frontmatter)
|
|
42
|
+
const docOptions = {
|
|
43
|
+
...parsedDocOptions,
|
|
44
|
+
...options?.documentOptions,
|
|
45
|
+
diagram: {
|
|
46
|
+
...parsedDocOptions.diagram,
|
|
47
|
+
...options?.documentOptions?.diagram,
|
|
48
|
+
},
|
|
49
|
+
pdf: {
|
|
50
|
+
...parsedDocOptions.pdf,
|
|
51
|
+
...options?.documentOptions?.pdf,
|
|
52
|
+
},
|
|
53
|
+
mermaid: {
|
|
54
|
+
...parsedDocOptions.mermaid,
|
|
55
|
+
...options?.documentOptions?.mermaid,
|
|
56
|
+
},
|
|
57
|
+
plantuml: {
|
|
58
|
+
...parsedDocOptions.plantuml,
|
|
59
|
+
...options?.documentOptions?.plantuml,
|
|
60
|
+
},
|
|
61
|
+
style: {
|
|
62
|
+
...parsedDocOptions.style,
|
|
63
|
+
...options?.documentOptions?.style,
|
|
64
|
+
font: {
|
|
65
|
+
...parsedDocOptions.style?.font,
|
|
66
|
+
...options?.documentOptions?.style?.font,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
// If PlantUML options are configured in Front Matter, create an ad-hoc renderer if default was used
|
|
71
|
+
let plantumlRenderer = this.renderers.get('plantuml');
|
|
72
|
+
if (docOptions.plantuml &&
|
|
73
|
+
(!plantumlRenderer || plantumlRenderer instanceof PlantUmlRenderer)) {
|
|
74
|
+
plantumlRenderer = new PlantUmlRenderer({
|
|
75
|
+
javaPath: docOptions.plantuml.javaPath,
|
|
76
|
+
jarPath: docOptions.plantuml.jarPath,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
const tokens = this.md.parse(markdownBody, {});
|
|
80
|
+
// Collect all diagram fence tokens (mermaid, plantuml) to render asynchronously
|
|
81
|
+
const pendingRenders = [];
|
|
82
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
83
|
+
const token = tokens[i];
|
|
84
|
+
if (token.type !== 'fence') {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
const info = token.info.trim();
|
|
88
|
+
if (!info) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const match = info.match(/^([a-zA-Z0-9_-]+)(.*)$/);
|
|
92
|
+
if (!match) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
const lang = match[1].toLowerCase();
|
|
96
|
+
if (lang !== 'mermaid' && lang !== 'plantuml') {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const line = token.map ? token.map[0] + 1 : undefined;
|
|
100
|
+
const rawRest = match[2].trim();
|
|
101
|
+
let attributesString;
|
|
102
|
+
if (rawRest !== '') {
|
|
103
|
+
if (rawRest.startsWith('{') && rawRest.endsWith('}')) {
|
|
104
|
+
attributesString = rawRest.slice(1, -1).trim();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const rawOptions = parseRawAttributes(attributesString);
|
|
108
|
+
const diagramOptions = resolveDiagramOptions(rawOptions, docOptions.diagram);
|
|
109
|
+
const cleanSource = token.content.replace(/\r?\n$/, '');
|
|
110
|
+
pendingRenders.push({
|
|
111
|
+
index: i,
|
|
112
|
+
block: {
|
|
113
|
+
type: lang,
|
|
114
|
+
source: cleanSource,
|
|
115
|
+
options: diagramOptions,
|
|
116
|
+
rawOptions,
|
|
117
|
+
line,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
// Render all diagrams asynchronously
|
|
122
|
+
for (const item of pendingRenders) {
|
|
123
|
+
const renderer = item.block.type === 'plantuml' && plantumlRenderer
|
|
124
|
+
? plantumlRenderer
|
|
125
|
+
: this.renderers.get(item.block.type);
|
|
126
|
+
if (!renderer) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const renderOptions = item.block.type === 'mermaid' && docOptions.mermaid?.theme
|
|
130
|
+
? { theme: docOptions.mermaid.theme }
|
|
131
|
+
: undefined;
|
|
132
|
+
const svg = await renderer.render(item.block.source, renderOptions);
|
|
133
|
+
const containerHtml = buildDiagramContainer(svg, item.block.options);
|
|
134
|
+
const targetToken = tokens[item.index];
|
|
135
|
+
targetToken.type = 'html_block';
|
|
136
|
+
targetToken.content = containerHtml;
|
|
137
|
+
targetToken.children = null;
|
|
138
|
+
}
|
|
139
|
+
// Render Markdown AST with transformed diagram tokens to HTML body
|
|
140
|
+
const bodyHtml = this.md.renderer.render(tokens, this.md.options, {});
|
|
141
|
+
// Wrap in full HTML document
|
|
142
|
+
return buildCompleteHtml(bodyHtml, {
|
|
143
|
+
...options,
|
|
144
|
+
fontOptions: docOptions.style?.font,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=html-renderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-renderer.js","sourceRoot":"","sources":["../../src/html/html-renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* md-tech-pdf Core Library
|
|
3
|
+
* Core PDF generation engine decoupled from CLI and editor extensions.
|
|
4
|
+
*/
|
|
5
|
+
export * from './types/diagram.js';
|
|
6
|
+
export * from './parser/error.js';
|
|
7
|
+
export * from './parser/attributes-parser.js';
|
|
8
|
+
export * from './parser/markdown-parser.js';
|
|
9
|
+
export * from './renderer/diagram-renderer.js';
|
|
10
|
+
export * from './renderer/mermaid-renderer.js';
|
|
11
|
+
export * from './renderer/mermaid-executor.js';
|
|
12
|
+
export * from './renderer/plantuml-renderer.js';
|
|
13
|
+
export * from './renderer/plantuml-executor.js';
|
|
14
|
+
export * from './renderer/error.js';
|
|
15
|
+
export * from './html/default-style.js';
|
|
16
|
+
export * from './html/google-fonts.js';
|
|
17
|
+
export * from './html/html-builder.js';
|
|
18
|
+
export * from './html/html-renderer.js';
|
|
19
|
+
export * from './pdf/types.js';
|
|
20
|
+
export * from './pdf/default-options.js';
|
|
21
|
+
export * from './pdf/error.js';
|
|
22
|
+
export * from './pdf/pdf-generator.js';
|
|
23
|
+
export * from './config/document-options.js';
|
|
24
|
+
export * from './config/error.js';
|
|
25
|
+
export * from './config/frontmatter-parser.js';
|
|
26
|
+
export * from './config/config-resolver.js';
|
|
27
|
+
export * from './core/converter.js';
|
|
28
|
+
export interface GeneratorOptions {
|
|
29
|
+
inputPath?: string;
|
|
30
|
+
outputPath?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface GeneratorResult {
|
|
33
|
+
success: boolean;
|
|
34
|
+
message: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Entry point for document generation in Core.
|
|
38
|
+
* PDF generation logic and diagram processing will be implemented here.
|
|
39
|
+
*/
|
|
40
|
+
export declare function generatePdf(_options?: GeneratorOptions): Promise<GeneratorResult>;
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|