@leadertechie/md2html 0.1.0-alpha.17 → 0.1.0-alpha.19
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 +152 -2
- package/dist/index.d.ts +283 -29
- package/dist/index.js +484 -436
- package/dist/index.js.map +1 -1
- package/dist/index2.js +4 -325
- package/dist/index2.js.map +1 -1
- package/dist/lit-renderer-Bp1Q6wYL.js +790 -0
- package/dist/lit-renderer-Bp1Q6wYL.js.map +1 -0
- package/dist/lit-renderer.d.ts +46 -2
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -189,9 +189,94 @@ Additional safety with `maxRecursionDepth` (default: 100) to prevent stack overf
|
|
|
189
189
|
|
|
190
190
|
## Architecture (v2)
|
|
191
191
|
|
|
192
|
-
|
|
192
|
+
The pipeline is built from modular stages, each with a clear design pattern and single responsibility:
|
|
193
193
|
|
|
194
|
-
|
|
194
|
+
```
|
|
195
|
+
Markdown String
|
|
196
|
+
│
|
|
197
|
+
▼
|
|
198
|
+
┌──────────────────────────┐
|
|
199
|
+
│ 1. Preprocessor Chain │ Chain of Responsibility
|
|
200
|
+
│ (preprocessor.ts) │ Transforms raw markdown before lexing
|
|
201
|
+
│ • ContainerBlock │ (e.g., ::: containers → HTML comments)
|
|
202
|
+
└──────────┬───────────────┘
|
|
203
|
+
│
|
|
204
|
+
▼
|
|
205
|
+
┌──────────────────────────┐
|
|
206
|
+
│ 2. marked.lexer() │ Third-party lexer
|
|
207
|
+
└──────────┬───────────────┘
|
|
208
|
+
│
|
|
209
|
+
▼
|
|
210
|
+
┌──────────────────────────┐
|
|
211
|
+
│ 3. Token Postprocessor │ Chain of Responsibility
|
|
212
|
+
│ (token-postprocessor │ Restructures flat tokens → nested tree
|
|
213
|
+
│ .ts) │ (e.g., comments → containerBlock)
|
|
214
|
+
│ • ContainerBlock │
|
|
215
|
+
└──────────┬───────────────┘
|
|
216
|
+
│
|
|
217
|
+
▼
|
|
218
|
+
┌──────────────────────────┐
|
|
219
|
+
│ 4. Token Handlers │ Strategy Pattern
|
|
220
|
+
│ (handlers/) │ Each marked token type has a dedicated
|
|
221
|
+
│ • TokenHandlerRegistry│ handler, registered by type name.
|
|
222
|
+
│ • CatchAllHandler │ Extensible at runtime via registry.
|
|
223
|
+
└──────────┬───────────────┘
|
|
224
|
+
│
|
|
225
|
+
▼
|
|
226
|
+
ContentNode[]
|
|
227
|
+
(AST)
|
|
228
|
+
│
|
|
229
|
+
▼
|
|
230
|
+
┌──────────────────────────┐
|
|
231
|
+
│ 5. Renderer │ Strategy Pattern
|
|
232
|
+
│ (renderer-strategies │ Each ContentNode type has its own
|
|
233
|
+
│ .ts / lit-strategies │ render strategy — choose between:
|
|
234
|
+
│ .ts) │ • HTMLRenderer (plain HTML strings)
|
|
235
|
+
│ • NodeRendererStrategy│ • LitRenderer (Lit TemplateResult)
|
|
236
|
+
│ • LitNodeRendererStrat│
|
|
237
|
+
└──────────────────────────┘
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### 1. Preprocessing (`preprocessor.ts`)
|
|
241
|
+
|
|
242
|
+
The `CompositePreprocessor` chains `Preprocessor` transforms that run on raw markdown **before** lexing. Built-in:
|
|
243
|
+
|
|
244
|
+
- **`ContainerBlockPreprocessor`** — converts `:::tag#id.class` fences to `<!-- md-container:... -->` HTML comment markers, so `marked` preserves them without affecting inner markdown parsing
|
|
245
|
+
|
|
246
|
+
The chain is extensible:
|
|
247
|
+
|
|
248
|
+
```typescript
|
|
249
|
+
import { MarkdownParser, Preprocessor } from '@leadertechie/md2html';
|
|
250
|
+
|
|
251
|
+
class EmojiPreprocessor implements Preprocessor {
|
|
252
|
+
readonly name = 'emoji';
|
|
253
|
+
process(markdown: string): string {
|
|
254
|
+
return markdown.replace(':smile:', '😊');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
const parser = new MarkdownParser();
|
|
259
|
+
parser.preprocessors.add(new EmojiPreprocessor());
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### 2. Token Postprocessing (`token-postprocessor.ts`)
|
|
263
|
+
|
|
264
|
+
The `CompositeTokenPostprocessor` chains `TokenPostprocessor` transforms that run on the flat token array **after** lexing. Built-in:
|
|
265
|
+
|
|
266
|
+
- **`ContainerBlockPostprocessor`** — collapses `<!-- md-container:... -->` / `<!-- /md-container -->` markers into nested `containerBlock` tokens with proper parent-child structure (handles arbitrary nesting depth)
|
|
267
|
+
|
|
268
|
+
Custom postprocessors:
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
parser.postprocessors.add({
|
|
272
|
+
name: 'filter-unwanted',
|
|
273
|
+
process: (tokens) => tokens.filter(t => (t as any).type !== 'html')
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 3. Token Handling — Strategy Pattern (`handlers/`)
|
|
278
|
+
|
|
279
|
+
Each marked token type has its own `TokenHandler` class, registered in the `TokenHandlerRegistry`:
|
|
195
280
|
|
|
196
281
|
```
|
|
197
282
|
src/handlers/
|
|
@@ -205,6 +290,10 @@ src/handlers/
|
|
|
205
290
|
├── hr-handler.ts # <hr>
|
|
206
291
|
├── blockquote-handler.ts # <blockquote>
|
|
207
292
|
├── html-handler.ts # raw HTML passthrough
|
|
293
|
+
├── link-handler.ts # <a>
|
|
294
|
+
├── frontmatter-handler.ts# YAML frontmatter metadata
|
|
295
|
+
├── container-block- # ::: container blocks
|
|
296
|
+
│ handler.ts
|
|
208
297
|
└── catchall-handler.ts # fallback for unregistered types
|
|
209
298
|
```
|
|
210
299
|
|
|
@@ -253,6 +342,67 @@ const parser = new MarkdownParser({
|
|
|
253
342
|
});
|
|
254
343
|
```
|
|
255
344
|
|
|
345
|
+
### 4. Rendering — Strategy Pattern (`renderer-strategies.ts`, `lit-strategies.ts`)
|
|
346
|
+
|
|
347
|
+
The AST renderers use the same Strategy + Registry pattern as the token handlers:
|
|
348
|
+
|
|
349
|
+
- **`HTMLRenderer`** — produces plain HTML strings. Uses `NodeRendererStrategy` / `RendererStrategyRegistry` for each node type. Supports `classPrefix`, `addHeadingIds`, and `emitScopeAnchors` styling.
|
|
350
|
+
- **`LitRenderer`** — produces Lit `TemplateResult` objects. Uses `LitNodeRendererStrategy` / `LitStrategyRegistry`. Perfect for Lit web components.
|
|
351
|
+
|
|
352
|
+
Both registries are publicly accessible for customization:
|
|
353
|
+
|
|
354
|
+
```typescript
|
|
355
|
+
import { HTMLRenderer, NodeRendererStrategy } from '@leadertechie/md2html';
|
|
356
|
+
|
|
357
|
+
const renderer = new HTMLRenderer({ classPrefix: 'my-' });
|
|
358
|
+
|
|
359
|
+
// Register a custom strategy
|
|
360
|
+
renderer.strategies.register({
|
|
361
|
+
type: 'custom',
|
|
362
|
+
render: (node, renderChild, ctx) => `<my-el>${node.content}</my-el>`
|
|
363
|
+
});
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
The `LitRenderer.renderToHTMLString()` delegates to `HTMLRenderer` to avoid duplicating string rendering logic.
|
|
367
|
+
|
|
368
|
+
### 5. Context Factory (`context-factory.ts`)
|
|
369
|
+
|
|
370
|
+
The `createParseContext()` pure function separates context construction from the parser class. It bridges parser services (image processing, slot resolution, HTML sanitization) to token handlers via the `ParserServices` interface. This makes the context testable in isolation and decouples handler logic from parser internals.
|
|
371
|
+
|
|
372
|
+
### Source Map
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
src/
|
|
376
|
+
├── parser.ts # Orchestrator: coordinates pre/post-processing + token handling
|
|
377
|
+
├── preprocessor.ts # Chain of Responsibility: markdown transforms before lexing
|
|
378
|
+
├── token-postprocessor.ts # Chain of Responsibility: token transforms after lexing
|
|
379
|
+
├── context-factory.ts # Factory: creates ParseContext for token handlers
|
|
380
|
+
├── handlers/ # Strategy: per-token-type ContentNode producers
|
|
381
|
+
│ ├── types.ts
|
|
382
|
+
│ ├── registry.ts
|
|
383
|
+
│ ├── heading-handler.ts
|
|
384
|
+
│ ├── paragraph-handler.ts
|
|
385
|
+
│ ├── list-handler.ts
|
|
386
|
+
│ ├── image-handler.ts
|
|
387
|
+
│ ├── code-handler.ts
|
|
388
|
+
│ ├── hr-handler.ts
|
|
389
|
+
│ ├── blockquote-handler.ts
|
|
390
|
+
│ ├── html-handler.ts
|
|
391
|
+
│ ├── link-handler.ts
|
|
392
|
+
│ ├── frontmatter-handler.ts
|
|
393
|
+
│ ├── container-block-handler.ts
|
|
394
|
+
│ └── catchall-handler.ts
|
|
395
|
+
├── renderer.ts # HTMLRenderer: transforms ContentNodes to plain HTML
|
|
396
|
+
├── renderer-strategies.ts # Strategy: per-node-type HTML string renderers
|
|
397
|
+
├── lit-renderer.ts # LitRenderer: transforms ContentNodes to Lit TemplateResult
|
|
398
|
+
├── lit-strategies.ts # Strategy: per-node-type Lit TemplateResult renderers
|
|
399
|
+
├── visitor.ts # Visitor: tree traversal utilities
|
|
400
|
+
├── factory.ts # NodeFactory: ContentNode builder API
|
|
401
|
+
├── pipeline.ts # Facade: high-level MarkdownPipeline API
|
|
402
|
+
├── types.ts # Core types: ContentNode, MarkdownContent, configs
|
|
403
|
+
└── telemetry-init.ts # Shared logger initialization
|
|
404
|
+
```
|
|
405
|
+
|
|
256
406
|
## License
|
|
257
407
|
|
|
258
408
|
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { LoggerInterface } from '@leadertechie/telemetry';
|
|
2
|
+
import { TemplateResult } from 'lit';
|
|
3
|
+
|
|
1
4
|
/**
|
|
2
5
|
* Handles 'blockquote' tokens.
|
|
3
6
|
*/
|
|
@@ -71,6 +74,42 @@ export declare function collectImages(root: ContentNode): Array<{
|
|
|
71
74
|
alt: string;
|
|
72
75
|
}>;
|
|
73
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Sequentially applies multiple preprocessors to the markdown.
|
|
79
|
+
* Each preprocessor's output becomes the next one's input.
|
|
80
|
+
*
|
|
81
|
+
* This follows the Chain of Responsibility pattern — you can add
|
|
82
|
+
* new preprocessors without modifying existing code.
|
|
83
|
+
*/
|
|
84
|
+
export declare class CompositePreprocessor implements Preprocessor {
|
|
85
|
+
readonly name = "composite";
|
|
86
|
+
private processors;
|
|
87
|
+
constructor(processors?: Preprocessor[]);
|
|
88
|
+
/** Add a preprocessor to the chain. Returns `this` for fluent API. */
|
|
89
|
+
add(processor: Preprocessor): this;
|
|
90
|
+
/** Remove a preprocessor by name. */
|
|
91
|
+
remove(name: string): void;
|
|
92
|
+
/** Get the list of registered preprocessors. */
|
|
93
|
+
getProcessors(): ReadonlyArray<Preprocessor>;
|
|
94
|
+
process(markdown: string): string;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Sequentially applies multiple postprocessors to the token array.
|
|
99
|
+
*/
|
|
100
|
+
export declare class CompositeTokenPostprocessor implements TokenPostprocessor {
|
|
101
|
+
readonly name = "composite";
|
|
102
|
+
private processors;
|
|
103
|
+
constructor(processors?: TokenPostprocessor[]);
|
|
104
|
+
/** Add a postprocessor to the chain. Returns `this` for fluent API. */
|
|
105
|
+
add(processor: TokenPostprocessor): this;
|
|
106
|
+
/** Remove a postprocessor by name. */
|
|
107
|
+
remove(name: string): void;
|
|
108
|
+
/** Get the list of registered postprocessors. */
|
|
109
|
+
getProcessors(): ReadonlyArray<TokenPostprocessor>;
|
|
110
|
+
process(tokens: unknown[]): unknown[];
|
|
111
|
+
}
|
|
112
|
+
|
|
74
113
|
/**
|
|
75
114
|
* ContainerBlockHandler — handles custom :::tag#id.class container blocks.
|
|
76
115
|
*
|
|
@@ -88,6 +127,39 @@ export declare class ContainerBlockHandler implements TokenHandler {
|
|
|
88
127
|
handle(token: Record<string, unknown>, ctx: ParseContext): ContentNode | null;
|
|
89
128
|
}
|
|
90
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Collapses `<!-- md-container:... -->` and `<!-- /md-container -->` comment
|
|
132
|
+
* markers into nested `containerBlock` tokens with proper parent-child structure.
|
|
133
|
+
*
|
|
134
|
+
* Handles nesting depth up to any reasonable limit (depends on stack memory).
|
|
135
|
+
*/
|
|
136
|
+
export declare class ContainerBlockPostprocessor implements TokenPostprocessor {
|
|
137
|
+
readonly name = "container-blocks";
|
|
138
|
+
process(tokens: unknown[]): unknown[];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Converts `:::tag#id.class` container syntax into HTML comment markers
|
|
143
|
+
* that marked will preserve as HTML tokens, without affecting markdown parsing
|
|
144
|
+
* of the inner content.
|
|
145
|
+
*
|
|
146
|
+
* Example:
|
|
147
|
+
* :::section#header
|
|
148
|
+
* # Heading inside container
|
|
149
|
+
* Some text
|
|
150
|
+
* :::
|
|
151
|
+
*
|
|
152
|
+
* Becomes:
|
|
153
|
+
* <!-- md-container:section#header -->
|
|
154
|
+
* # Heading inside container
|
|
155
|
+
* Some text
|
|
156
|
+
* <!-- /md-container -->
|
|
157
|
+
*/
|
|
158
|
+
export declare class ContainerBlockPreprocessor implements Preprocessor {
|
|
159
|
+
readonly name = "container-blocks";
|
|
160
|
+
process(markdown: string): string;
|
|
161
|
+
}
|
|
162
|
+
|
|
91
163
|
export declare interface ContentNode {
|
|
92
164
|
type: ContentNodeType;
|
|
93
165
|
content?: string;
|
|
@@ -105,6 +177,23 @@ export declare interface ContentNode {
|
|
|
105
177
|
|
|
106
178
|
export declare type ContentNodeType = 'text' | 'heading' | 'paragraph' | 'list' | 'list-item' | 'image' | 'code' | 'container' | 'strong' | 'emphasis' | 'link';
|
|
107
179
|
|
|
180
|
+
/** Default postprocessor chain with the built-in container block support. */
|
|
181
|
+
export declare function createDefaultPostprocessor(): CompositeTokenPostprocessor;
|
|
182
|
+
|
|
183
|
+
/** Default preprocessor chain with the built-in container block support. */
|
|
184
|
+
export declare function createDefaultPreprocessor(): CompositePreprocessor;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Create a ParseContext from parser services.
|
|
188
|
+
*
|
|
189
|
+
* Each call creates a fresh context with its own metadata store,
|
|
190
|
+
* allowing for clean separation between recursive parse calls.
|
|
191
|
+
*
|
|
192
|
+
* The getters use closures to lazily access the parser's current state,
|
|
193
|
+
* so the context always reflects the latest configuration.
|
|
194
|
+
*/
|
|
195
|
+
export declare function createParseContext(services: ParserServices): ParseContext;
|
|
196
|
+
|
|
108
197
|
/** Default allowed HTML tags for preserveRawHTML mode */
|
|
109
198
|
export declare const defaultAllowedHTMLTags: string[];
|
|
110
199
|
|
|
@@ -208,6 +297,22 @@ export declare class ImageHandler implements TokenHandler {
|
|
|
208
297
|
};
|
|
209
298
|
}
|
|
210
299
|
|
|
300
|
+
/**
|
|
301
|
+
* Handles standalone 'link' tokens (e.g., reference-style links, or links
|
|
302
|
+
* that appear outside paragraphs in certain edge cases).
|
|
303
|
+
*/
|
|
304
|
+
export declare class LinkHandler implements TokenHandler {
|
|
305
|
+
readonly type = "link";
|
|
306
|
+
handle(token: Record<string, unknown>, ctx: ParseContext): {
|
|
307
|
+
type: "link";
|
|
308
|
+
content: string;
|
|
309
|
+
attributes: {
|
|
310
|
+
title?: string | undefined;
|
|
311
|
+
href: string;
|
|
312
|
+
};
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
|
|
211
316
|
/**
|
|
212
317
|
* Handles 'list' tokens (ordered and unordered).
|
|
213
318
|
*/
|
|
@@ -223,6 +328,118 @@ export declare class ListHandler implements TokenHandler {
|
|
|
223
328
|
};
|
|
224
329
|
}
|
|
225
330
|
|
|
331
|
+
export declare class LitCodeStrategy implements LitNodeRendererStrategy {
|
|
332
|
+
readonly type = "code";
|
|
333
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export declare class LitContainerStrategy implements LitNodeRendererStrategy {
|
|
337
|
+
readonly type = "container";
|
|
338
|
+
render(node: ContentNode, renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export declare class LitEmphasisStrategy implements LitNodeRendererStrategy {
|
|
342
|
+
readonly type = "emphasis";
|
|
343
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
export declare class LitFallbackStrategy implements LitNodeRendererStrategy {
|
|
347
|
+
readonly type = "*";
|
|
348
|
+
render(_node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export declare class LitHeadingStrategy implements LitNodeRendererStrategy {
|
|
352
|
+
readonly type = "heading";
|
|
353
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export declare class LitImageStrategy implements LitNodeRendererStrategy {
|
|
357
|
+
readonly type = "image";
|
|
358
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
export declare class LitLinkStrategy implements LitNodeRendererStrategy {
|
|
362
|
+
readonly type = "link";
|
|
363
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export declare class LitListItemStrategy implements LitNodeRendererStrategy {
|
|
367
|
+
readonly type = "list-item";
|
|
368
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export declare class LitListStrategy implements LitNodeRendererStrategy {
|
|
372
|
+
readonly type = "list";
|
|
373
|
+
render(node: ContentNode, renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export declare interface LitNodeRendererStrategy {
|
|
377
|
+
/** The ContentNode type this strategy handles */
|
|
378
|
+
readonly type: string;
|
|
379
|
+
/** Render a node to a Lit TemplateResult */
|
|
380
|
+
render(node: ContentNode, renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export declare class LitParagraphStrategy implements LitNodeRendererStrategy {
|
|
384
|
+
readonly type = "paragraph";
|
|
385
|
+
render(node: ContentNode, renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export declare class LitRenderer {
|
|
389
|
+
private strategyRegistry;
|
|
390
|
+
/** Lazily created HTMLRenderer for string output, sharing the same config */
|
|
391
|
+
private htmlRenderer?;
|
|
392
|
+
constructor();
|
|
393
|
+
/** Access the strategy registry for customization. */
|
|
394
|
+
get strategies(): LitStrategyRegistry;
|
|
395
|
+
/**
|
|
396
|
+
* Render a single node to a Lit TemplateResult.
|
|
397
|
+
*/
|
|
398
|
+
renderNode(node: ContentNode): TemplateResult;
|
|
399
|
+
/**
|
|
400
|
+
* Render an array of nodes to a single Lit TemplateResult.
|
|
401
|
+
*/
|
|
402
|
+
renderNodes(nodes: ContentNode[]): TemplateResult;
|
|
403
|
+
/**
|
|
404
|
+
* Render nodes to a plain HTML string.
|
|
405
|
+
* Delegates to HTMLRenderer to avoid duplicating string rendering logic.
|
|
406
|
+
*
|
|
407
|
+
* Note: Uses default HTMLRenderer config (no classPrefix, scope anchors,
|
|
408
|
+
* or heading IDs). For full HTML rendering with those features,
|
|
409
|
+
* use HTMLRenderer directly.
|
|
410
|
+
*/
|
|
411
|
+
renderToHTMLString(nodes: ContentNode[]): string;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Registry of Lit renderer strategies.
|
|
416
|
+
*
|
|
417
|
+
* Two-tier lookup:
|
|
418
|
+
* 1. Dedicated strategy by node type
|
|
419
|
+
* 2. Fallback to a catch-all strategy (default: renders empty)
|
|
420
|
+
*/
|
|
421
|
+
export declare class LitStrategyRegistry {
|
|
422
|
+
private strategies;
|
|
423
|
+
private fallback;
|
|
424
|
+
constructor();
|
|
425
|
+
register(strategy: LitNodeRendererStrategy): void;
|
|
426
|
+
unregister(type: string): void;
|
|
427
|
+
get(type: string): LitNodeRendererStrategy;
|
|
428
|
+
has(type: string): boolean;
|
|
429
|
+
get types(): string[];
|
|
430
|
+
setFallback(strategy: LitNodeRendererStrategy): void;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
export declare class LitStrongStrategy implements LitNodeRendererStrategy {
|
|
434
|
+
readonly type = "strong";
|
|
435
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
export declare class LitTextStrategy implements LitNodeRendererStrategy {
|
|
439
|
+
readonly type = "text";
|
|
440
|
+
render(node: ContentNode, _renderChild: (child: ContentNode) => TemplateResult): TemplateResult;
|
|
441
|
+
}
|
|
442
|
+
|
|
226
443
|
export declare interface MarkdownContent {
|
|
227
444
|
title: string;
|
|
228
445
|
metadata?: Record<string, unknown>;
|
|
@@ -241,9 +458,16 @@ export declare class MarkdownParser {
|
|
|
241
458
|
private allowedAttributes;
|
|
242
459
|
private handlerRegistry;
|
|
243
460
|
private onUnhandledToken?;
|
|
461
|
+
private log;
|
|
462
|
+
private preprocessor;
|
|
463
|
+
private postprocessor;
|
|
244
464
|
constructor(options?: ParserOptions);
|
|
245
465
|
/** Access the handler registry for customization. */
|
|
246
466
|
get handlers(): TokenHandlerRegistry;
|
|
467
|
+
/** Access the preprocessor chain for customization. */
|
|
468
|
+
get preprocessors(): CompositePreprocessor;
|
|
469
|
+
/** Access the token postprocessor chain for customization. */
|
|
470
|
+
get postprocessors(): CompositeTokenPostprocessor;
|
|
247
471
|
private processImagePath;
|
|
248
472
|
private processInlineFormatting;
|
|
249
473
|
private processSlots;
|
|
@@ -263,41 +487,16 @@ export declare class MarkdownParser {
|
|
|
263
487
|
private filterTagAttributes;
|
|
264
488
|
private processRawHTML;
|
|
265
489
|
/**
|
|
266
|
-
* Build
|
|
267
|
-
*
|
|
490
|
+
* Build a ParserServices object that bridges the parser's private methods
|
|
491
|
+
* to the ParseContext factory. This keeps context creation decoupled.
|
|
268
492
|
*/
|
|
269
|
-
private
|
|
493
|
+
private buildServices;
|
|
270
494
|
/**
|
|
271
495
|
* Process an array of marked tokens into ContentNodes.
|
|
272
496
|
* When depth === 0 (root), creates a shared context that accumulates metadata.
|
|
273
497
|
* For recursive calls (depth > 0), creates a fresh context for each level.
|
|
274
498
|
*/
|
|
275
499
|
private parseTokens;
|
|
276
|
-
/**
|
|
277
|
-
* Pre-process markdown: convert `:::tag#id.class` container syntax
|
|
278
|
-
* into HTML comment markers that marked will preserve as html tokens,
|
|
279
|
-
* but won't affect markdown parsing of the inner content.
|
|
280
|
-
*
|
|
281
|
-
* Example:
|
|
282
|
-
* :::section#header
|
|
283
|
-
* # Heading inside container
|
|
284
|
-
* Some text
|
|
285
|
-
* :::
|
|
286
|
-
*
|
|
287
|
-
* Becomes:
|
|
288
|
-
* <!-- md-container:section#header -->
|
|
289
|
-
* # Heading inside container
|
|
290
|
-
* Some text
|
|
291
|
-
* <!-- /md-container -->
|
|
292
|
-
*/
|
|
293
|
-
private preprocessContainerBlocks;
|
|
294
|
-
/**
|
|
295
|
-
* Post-process marked tokens to collapse container block markers
|
|
296
|
-
* into structured containerBlock tokens with proper nesting.
|
|
297
|
-
*
|
|
298
|
-
* This handles nesting depth up to maxRecursionDepth.
|
|
299
|
-
*/
|
|
300
|
-
private postprocessTokens;
|
|
301
500
|
parse(markdown: string, options?: ParseOptions): MarkdownContent;
|
|
302
501
|
parseToNodes(markdown: string, options?: ParseOptions): ContentNode[];
|
|
303
502
|
}
|
|
@@ -306,6 +505,7 @@ export declare class MarkdownPipeline {
|
|
|
306
505
|
private parser;
|
|
307
506
|
private renderer;
|
|
308
507
|
private config;
|
|
508
|
+
private log;
|
|
309
509
|
constructor(config?: PipelineConfigV2);
|
|
310
510
|
parse(markdown: string): ContentNode[];
|
|
311
511
|
parseWithMetadata(markdown: string): MarkdownContent;
|
|
@@ -389,7 +589,7 @@ export declare interface NodeVisitor {
|
|
|
389
589
|
}
|
|
390
590
|
|
|
391
591
|
/**
|
|
392
|
-
* Handles 'paragraph' tokens, including inline images and raw HTML.
|
|
592
|
+
* Handles 'paragraph' tokens, including inline images, links, and raw HTML.
|
|
393
593
|
*/
|
|
394
594
|
export declare class ParagraphHandler implements TokenHandler {
|
|
395
595
|
readonly type = "paragraph";
|
|
@@ -432,6 +632,8 @@ export declare interface ParseOptions {
|
|
|
432
632
|
}
|
|
433
633
|
|
|
434
634
|
export declare interface ParserOptions {
|
|
635
|
+
/** Optional telemetry logger */
|
|
636
|
+
logger?: LoggerInterface;
|
|
435
637
|
imagePathPrefix?: string;
|
|
436
638
|
imageBaseUrl?: string;
|
|
437
639
|
preserveRawHTML?: boolean;
|
|
@@ -458,6 +660,22 @@ export declare interface ParserOptions {
|
|
|
458
660
|
onUnhandledToken?: (type: string, token: Record<string, unknown>) => void;
|
|
459
661
|
}
|
|
460
662
|
|
|
663
|
+
/**
|
|
664
|
+
* Services needed by the ParseContext factory.
|
|
665
|
+
* This is the interface the parser exposes to context creation.
|
|
666
|
+
*/
|
|
667
|
+
export declare interface ParserServices {
|
|
668
|
+
preserveRawHTML: boolean;
|
|
669
|
+
errorRecovery: 'throw' | 'warn' | 'silent';
|
|
670
|
+
maxRecursionDepth: number;
|
|
671
|
+
processImagePath(src: string): string;
|
|
672
|
+
processInlineFormatting(text: string): string;
|
|
673
|
+
processSlots(text: string): string;
|
|
674
|
+
processRawHTML(html: string): string;
|
|
675
|
+
parseTokens(tokens: unknown[], depth: number): ContentNode[];
|
|
676
|
+
onUnhandledToken?: (type: string, token: Record<string, unknown>) => void;
|
|
677
|
+
}
|
|
678
|
+
|
|
461
679
|
export declare interface PipelineConfig {
|
|
462
680
|
imagePathPrefix?: string;
|
|
463
681
|
imageBaseUrl?: string;
|
|
@@ -469,6 +687,8 @@ export declare interface PipelineConfig {
|
|
|
469
687
|
* v2: Extended PipelineConfig with raw HTML passthrough, slot hooks, and error recovery.
|
|
470
688
|
*/
|
|
471
689
|
export declare interface PipelineConfigV2 extends PipelineConfig {
|
|
690
|
+
/** Optional telemetry logger for observability. Pass your own or a default console logger is used. */
|
|
691
|
+
logger?: LoggerInterface;
|
|
472
692
|
styleOptions?: StyleConfigV2;
|
|
473
693
|
/** Preserve raw HTML tags in markdown (img, style, div, span, etc.) (default: false) */
|
|
474
694
|
preserveRawHTML?: boolean;
|
|
@@ -491,6 +711,24 @@ export declare interface PipelineConfigV2 extends PipelineConfig {
|
|
|
491
711
|
allowedAttributes?: Record<string, string[]>;
|
|
492
712
|
}
|
|
493
713
|
|
|
714
|
+
/**
|
|
715
|
+
* Markdown Preprocessor
|
|
716
|
+
*
|
|
717
|
+
* Single responsibility: Transform markdown text before it reaches the lexer.
|
|
718
|
+
* Currently handles `:::` container block syntax conversion to HTML comments.
|
|
719
|
+
*
|
|
720
|
+
* This is the first stage in the parsing pipeline.
|
|
721
|
+
*
|
|
722
|
+
* Extensibility: Additional preprocessors can be composed via the
|
|
723
|
+
* CompositePipeline pattern (see composite-pipeline.ts).
|
|
724
|
+
*/
|
|
725
|
+
export declare interface Preprocessor {
|
|
726
|
+
/** Name identifier for logging/debugging */
|
|
727
|
+
readonly name: string;
|
|
728
|
+
/** Transform the markdown before lexing */
|
|
729
|
+
process(markdown: string): string;
|
|
730
|
+
}
|
|
731
|
+
|
|
494
732
|
/**
|
|
495
733
|
* Context passed to every render strategy, providing access to
|
|
496
734
|
* shared rendering services and configuration.
|
|
@@ -596,6 +834,22 @@ export declare class TokenHandlerRegistry {
|
|
|
596
834
|
getCatchAll(): TokenHandler;
|
|
597
835
|
}
|
|
598
836
|
|
|
837
|
+
/**
|
|
838
|
+
* Token Postprocessor
|
|
839
|
+
*
|
|
840
|
+
* Single responsibility: Transform the flat array of marked tokens into
|
|
841
|
+
* a structured tree. Currently handles collapsing HTML comment markers
|
|
842
|
+
* (from container block preprocessing) into structured `containerBlock` tokens.
|
|
843
|
+
*
|
|
844
|
+
* This is the third stage in the parsing pipeline (after lexing).
|
|
845
|
+
*/
|
|
846
|
+
export declare interface TokenPostprocessor {
|
|
847
|
+
/** Name identifier for logging/debugging */
|
|
848
|
+
readonly name: string;
|
|
849
|
+
/** Transform an array of tokens into an array of (possibly restructured) tokens */
|
|
850
|
+
process(tokens: unknown[]): unknown[];
|
|
851
|
+
}
|
|
852
|
+
|
|
599
853
|
/**
|
|
600
854
|
* Walk a ContentNode tree, applying a visitor at each node.
|
|
601
855
|
* Returns a new tree (immutable) — does not mutate the original.
|