@leadertechie/md2html 0.1.0-alpha.2 → 0.1.0-alpha.3
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/README.md +28 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -6
- package/dist/pipeline.d.ts +2 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +11 -3
- package/dist/renderer.d.ts +8 -1
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +57 -9
- package/dist/types.d.ts +6 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,10 +55,35 @@ const pipeline = new MarkdownPipeline({
|
|
|
55
55
|
gfm: true,
|
|
56
56
|
breaks: false,
|
|
57
57
|
pedantic: false
|
|
58
|
+
},
|
|
59
|
+
styleOptions: {
|
|
60
|
+
classPrefix: 'md-',
|
|
61
|
+
customCSS: 'body { font-family: system-ui; }',
|
|
62
|
+
addHeadingIds: true
|
|
58
63
|
}
|
|
59
64
|
});
|
|
60
65
|
```
|
|
61
66
|
|
|
67
|
+
### Style Configuration Options
|
|
68
|
+
|
|
69
|
+
| Option | Type | Default | Description |
|
|
70
|
+
|--------|------|---------|-------------|
|
|
71
|
+
| `classPrefix` | string | `''` | Prefix for CSS classes on elements (e.g., `'md-'` produces `md-heading`, `md-paragraph`) |
|
|
72
|
+
| `customCSS` | string | `''` | Custom CSS string to inject (use `pipeline.getCustomCSS()` to retrieve) |
|
|
73
|
+
| `addHeadingIds` | boolean | `false` | Add ID attributes to headings based on their content for anchor links |
|
|
74
|
+
|
|
75
|
+
When `classPrefix` or `addHeadingIds` is set, CSS classes will be added to elements:
|
|
76
|
+
- `heading`, `paragraph`, `list`, `list-item`, `image`, `code`, `container`, `blockquote`
|
|
77
|
+
|
|
78
|
+
Example output with `classPrefix: 'md-'` and `addHeadingIds: true`:
|
|
79
|
+
```html
|
|
80
|
+
<h1 id="hello-world" class="md-heading">Hello World</h1>
|
|
81
|
+
<p class="md-paragraph">This is a paragraph.</p>
|
|
82
|
+
<ul class="md-list">
|
|
83
|
+
<li class="md-list-item">Item 1</li>
|
|
84
|
+
</ul>
|
|
85
|
+
```
|
|
86
|
+
|
|
62
87
|
### API
|
|
63
88
|
|
|
64
89
|
| Method | Description |
|
|
@@ -66,7 +91,9 @@ const pipeline = new MarkdownPipeline({
|
|
|
66
91
|
| `parse(markdown)` | Parse markdown string to AST |
|
|
67
92
|
| `render(nodes)` | Render AST to HTML string |
|
|
68
93
|
| `renderMarkdown(markdown)` | Parse and render in one call |
|
|
69
|
-
| `renderPage(title, nodes)` | Render AST to full HTML page |
|
|
94
|
+
| `renderPage(title, nodes, options?)` | Render AST to full HTML page |
|
|
95
|
+
| `getCustomCSS()` | Get custom CSS string from style config |
|
|
96
|
+
| `getConfig()` | Get current pipeline configuration |
|
|
70
97
|
|
|
71
98
|
## License
|
|
72
99
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export * from './parser';
|
|
3
|
-
export * from './renderer';
|
|
4
|
-
export * from './lit-renderer';
|
|
5
|
-
export * from './pipeline';
|
|
6
|
-
export { LitRenderer as HTMLRenderer } from './lit-renderer';
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './parser.js';
|
|
3
|
+
export * from './renderer.js';
|
|
4
|
+
export * from './lit-renderer.js';
|
|
5
|
+
export * from './pipeline.js';
|
|
6
|
+
export { LitRenderer as HTMLRenderer } from './lit-renderer.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAE9B,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export * from './parser';
|
|
3
|
-
export * from './renderer';
|
|
4
|
-
export * from './lit-renderer';
|
|
5
|
-
export * from './pipeline';
|
|
6
|
-
export { LitRenderer as HTMLRenderer } from './lit-renderer';
|
|
1
|
+
export * from './types.js';
|
|
2
|
+
export * from './parser.js';
|
|
3
|
+
export * from './renderer.js';
|
|
4
|
+
export * from './lit-renderer.js';
|
|
5
|
+
export * from './pipeline.js';
|
|
6
|
+
export { LitRenderer as HTMLRenderer } from './lit-renderer.js';
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContentNode, MarkdownContent, PipelineConfig } from './types';
|
|
1
|
+
import { ContentNode, MarkdownContent, PipelineConfig } from './types.js';
|
|
2
2
|
export declare class MarkdownPipeline {
|
|
3
3
|
private parser;
|
|
4
4
|
private renderer;
|
|
@@ -13,5 +13,6 @@ export declare class MarkdownPipeline {
|
|
|
13
13
|
charset?: string;
|
|
14
14
|
}): string;
|
|
15
15
|
getConfig(): Readonly<Required<PipelineConfig>>;
|
|
16
|
+
getCustomCSS(): string;
|
|
16
17
|
}
|
|
17
18
|
//# sourceMappingURL=pipeline.d.ts.map
|
package/dist/pipeline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAe,MAAM,YAAY,CAAC;AAEvF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,MAAM,CAA2B;gBAE7B,MAAM,GAAE,cAAmB;IAuBvC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE;IAItC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe;IAIpD,MAAM,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM;IAIpC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKxC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE;QACxD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,MAAM;IAeV,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IAI/C,YAAY,IAAI,MAAM;CAGvB"}
|
package/dist/pipeline.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { MarkdownParser } from './parser';
|
|
2
|
-
import { HTMLRenderer } from './renderer';
|
|
1
|
+
import { MarkdownParser } from './parser.js';
|
|
2
|
+
import { HTMLRenderer } from './renderer.js';
|
|
3
3
|
export class MarkdownPipeline {
|
|
4
4
|
constructor(config = {}) {
|
|
5
5
|
this.config = {
|
|
@@ -9,13 +9,18 @@ export class MarkdownPipeline {
|
|
|
9
9
|
gfm: config.parseOptions?.gfm ?? true,
|
|
10
10
|
breaks: config.parseOptions?.breaks ?? false,
|
|
11
11
|
pedantic: config.parseOptions?.pedantic ?? false
|
|
12
|
+
},
|
|
13
|
+
styleOptions: {
|
|
14
|
+
classPrefix: config.styleOptions?.classPrefix || '',
|
|
15
|
+
customCSS: config.styleOptions?.customCSS || '',
|
|
16
|
+
addHeadingIds: config.styleOptions?.addHeadingIds ?? false
|
|
12
17
|
}
|
|
13
18
|
};
|
|
14
19
|
this.parser = new MarkdownParser({
|
|
15
20
|
imagePathPrefix: this.config.imagePathPrefix,
|
|
16
21
|
imageBaseUrl: this.config.imageBaseUrl
|
|
17
22
|
});
|
|
18
|
-
this.renderer = new HTMLRenderer();
|
|
23
|
+
this.renderer = new HTMLRenderer(this.config.styleOptions);
|
|
19
24
|
}
|
|
20
25
|
parse(markdown) {
|
|
21
26
|
return this.parser.parseToNodes(markdown, this.config.parseOptions);
|
|
@@ -47,4 +52,7 @@ export class MarkdownPipeline {
|
|
|
47
52
|
getConfig() {
|
|
48
53
|
return { ...this.config };
|
|
49
54
|
}
|
|
55
|
+
getCustomCSS() {
|
|
56
|
+
return this.renderer.getCustomCSS();
|
|
57
|
+
}
|
|
50
58
|
}
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import { ContentNode } from './types';
|
|
1
|
+
import { ContentNode, StyleConfig } from './types.js';
|
|
2
2
|
export declare class HTMLRenderer {
|
|
3
|
+
private config;
|
|
4
|
+
constructor(config?: StyleConfig);
|
|
5
|
+
private hasClassConfig;
|
|
6
|
+
private getClass;
|
|
7
|
+
private generateHeadingId;
|
|
8
|
+
private renderWithClass;
|
|
3
9
|
renderNode(node: ContentNode): string;
|
|
4
10
|
renderNodes(nodes: ContentNode[]): string;
|
|
5
11
|
renderToHTMLString(nodes: ContentNode[]): string;
|
|
6
12
|
render(markdown: string): string;
|
|
13
|
+
getCustomCSS(): string;
|
|
7
14
|
}
|
|
8
15
|
//# sourceMappingURL=renderer.d.ts.map
|
package/dist/renderer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAwB;gBAE1B,MAAM,GAAE,WAAgB;IAQpC,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,eAAe;IAOvB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM;IA4DrC,WAAW,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM;IAOzC,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,MAAM;IAIhD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIhC,YAAY,IAAI,MAAM;CAGvB"}
|
package/dist/renderer.js
CHANGED
|
@@ -1,35 +1,80 @@
|
|
|
1
1
|
export class HTMLRenderer {
|
|
2
|
+
constructor(config = {}) {
|
|
3
|
+
this.config = {
|
|
4
|
+
classPrefix: config.classPrefix || '',
|
|
5
|
+
customCSS: config.customCSS || '',
|
|
6
|
+
addHeadingIds: config.addHeadingIds ?? false
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
hasClassConfig() {
|
|
10
|
+
return this.config.classPrefix !== '' || this.config.addHeadingIds;
|
|
11
|
+
}
|
|
12
|
+
getClass(baseClass, nodeClass) {
|
|
13
|
+
if (!this.hasClassConfig()) {
|
|
14
|
+
return nodeClass || '';
|
|
15
|
+
}
|
|
16
|
+
const prefix = this.config.classPrefix;
|
|
17
|
+
const classes = [prefix ? `${prefix}${baseClass}` : baseClass];
|
|
18
|
+
if (nodeClass)
|
|
19
|
+
classes.push(nodeClass);
|
|
20
|
+
return classes.join(' ');
|
|
21
|
+
}
|
|
22
|
+
generateHeadingId(content) {
|
|
23
|
+
if (!content)
|
|
24
|
+
return '';
|
|
25
|
+
return content
|
|
26
|
+
.toLowerCase()
|
|
27
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
28
|
+
.replace(/(^-|-$)/g, '');
|
|
29
|
+
}
|
|
30
|
+
renderWithClass(tag, content, baseClass, nodeClass, extraAttrs) {
|
|
31
|
+
const classAttr = this.hasClassConfig() && baseClass
|
|
32
|
+
? ` class="${this.getClass(baseClass, nodeClass)}"`
|
|
33
|
+
: '';
|
|
34
|
+
return `<${tag}${classAttr}${extraAttrs || ''}>${content}</${tag}>`;
|
|
35
|
+
}
|
|
2
36
|
renderNode(node) {
|
|
3
37
|
switch (node.type) {
|
|
4
38
|
case 'heading':
|
|
5
39
|
const level = node.attributes?.level || '2';
|
|
6
|
-
|
|
40
|
+
const headingId = this.config.addHeadingIds
|
|
41
|
+
? ` id="${this.generateHeadingId(node.content)}"`
|
|
42
|
+
: '';
|
|
43
|
+
if (!this.hasClassConfig()) {
|
|
44
|
+
return `<h${level}${headingId}>${node.content || ''}</h${level}>`;
|
|
45
|
+
}
|
|
46
|
+
return `<h${level}${headingId} class="${this.getClass('heading')}">${node.content || ''}</h${level}>`;
|
|
7
47
|
case 'paragraph':
|
|
8
48
|
if (node.children) {
|
|
9
|
-
|
|
49
|
+
const childrenHtml = node.children.map(child => this.renderNode(child)).join('');
|
|
50
|
+
return this.renderWithClass('p', childrenHtml, 'paragraph');
|
|
10
51
|
}
|
|
11
|
-
return
|
|
52
|
+
return this.renderWithClass('p', node.content || '', 'paragraph');
|
|
12
53
|
case 'list':
|
|
13
54
|
const tag = node.ordered ? 'ol' : 'ul';
|
|
14
55
|
const items = node.children?.map(child => this.renderNode(child)).join('') || '';
|
|
15
|
-
return
|
|
56
|
+
return this.renderWithClass(tag, items, 'list');
|
|
16
57
|
case 'list-item':
|
|
17
|
-
return
|
|
58
|
+
return this.renderWithClass('li', node.content || '', 'list-item');
|
|
18
59
|
case 'image':
|
|
19
60
|
const src = node.src || node.attributes?.src || '';
|
|
20
61
|
const alt = node.alt || node.attributes?.alt || '';
|
|
21
|
-
|
|
62
|
+
const classStr = this.getClass('image', node.className || undefined);
|
|
63
|
+
return `<img src="${src}" alt="${alt}"${classStr ? ` class="${classStr}"` : ''}>`;
|
|
22
64
|
case 'code':
|
|
23
|
-
|
|
65
|
+
const codeClass = this.hasClassConfig()
|
|
66
|
+
? ` class="${this.getClass('code')} language-${node.attributes?.lang || ''}"`
|
|
67
|
+
: ` class="language-${node.attributes?.lang || ''}"`;
|
|
68
|
+
return `<pre><code${codeClass}>${node.content || ''}</code></pre>`;
|
|
24
69
|
case 'container':
|
|
25
70
|
if (node.attributes?.tag === 'hr')
|
|
26
71
|
return '<hr>';
|
|
27
72
|
if (node.attributes?.tag === 'blockquote') {
|
|
28
73
|
const children = node.children?.map(child => this.renderNode(child)).join('') || '';
|
|
29
|
-
return
|
|
74
|
+
return this.renderWithClass('blockquote', children, 'blockquote');
|
|
30
75
|
}
|
|
31
76
|
const containerChildren = node.children?.map(child => this.renderNode(child)).join('') || '';
|
|
32
|
-
return
|
|
77
|
+
return this.renderWithClass('div', containerChildren, 'container', node.className || undefined);
|
|
33
78
|
case 'strong':
|
|
34
79
|
return `<strong>${node.content || ''}</strong>`;
|
|
35
80
|
case 'emphasis':
|
|
@@ -51,4 +96,7 @@ export class HTMLRenderer {
|
|
|
51
96
|
render(markdown) {
|
|
52
97
|
return markdown;
|
|
53
98
|
}
|
|
99
|
+
getCustomCSS() {
|
|
100
|
+
return this.config.customCSS;
|
|
101
|
+
}
|
|
54
102
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -19,9 +19,15 @@ export interface ParseOptions {
|
|
|
19
19
|
breaks?: boolean;
|
|
20
20
|
pedantic?: boolean;
|
|
21
21
|
}
|
|
22
|
+
export interface StyleConfig {
|
|
23
|
+
classPrefix?: string;
|
|
24
|
+
customCSS?: string;
|
|
25
|
+
addHeadingIds?: boolean;
|
|
26
|
+
}
|
|
22
27
|
export interface PipelineConfig {
|
|
23
28
|
imagePathPrefix?: string;
|
|
24
29
|
imageBaseUrl?: string;
|
|
25
30
|
parseOptions?: ParseOptions;
|
|
31
|
+
styleOptions?: StyleConfig;
|
|
26
32
|
}
|
|
27
33
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,SAAS,GACT,WAAW,GACX,MAAM,GACN,WAAW,GACX,OAAO,GACP,MAAM,GACN,WAAW,GACX,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,MAAM,GACN,SAAS,GACT,WAAW,GACX,MAAM,GACN,WAAW,GACX,OAAO,GACP,MAAM,GACN,WAAW,GACX,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B"}
|
package/package.json
CHANGED