@leadertechie/md2html 0.1.0-alpha.18 → 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.
@@ -0,0 +1,790 @@
1
+ import { html } from "lit";
2
+ const defaultAllowedHTMLTags = [
3
+ "img",
4
+ "style",
5
+ "div",
6
+ "span",
7
+ "section",
8
+ "article",
9
+ "aside",
10
+ "header",
11
+ "footer",
12
+ "nav",
13
+ "main",
14
+ "figure",
15
+ "figcaption",
16
+ "details",
17
+ "summary",
18
+ "mark",
19
+ "time",
20
+ "video",
21
+ "audio",
22
+ "source",
23
+ "iframe",
24
+ "embed"
25
+ ];
26
+ const nodeTypeToScope = {
27
+ "text": "root",
28
+ "heading": "heading",
29
+ "paragraph": "paragraph",
30
+ "list": "list",
31
+ "list-item": "list-item",
32
+ "image": "image",
33
+ "code": "code",
34
+ "container": "container",
35
+ "strong": "strong",
36
+ "emphasis": "emphasis",
37
+ "link": "link"
38
+ };
39
+ class HeadingRendererStrategy {
40
+ constructor() {
41
+ this.type = "heading";
42
+ }
43
+ render(node, _renderChild, ctx) {
44
+ const level = node.attributes?.level || "2";
45
+ const headingId = ctx.addHeadingIds ? ` id="${ctx.generateHeadingId(node.content)}"` : "";
46
+ const scopeAttr = ctx.getScopeAttr(node);
47
+ if (!ctx.hasClassConfig()) {
48
+ return `<h${level}${headingId}${scopeAttr}>${node.content || ""}</h${level}>`;
49
+ }
50
+ const prefix = ctx.classPrefix;
51
+ const levelClass = level === "1" ? "h1" : level === "2" ? "h2" : level === "3" ? "h3" : level === "4" ? "h4" : level === "5" ? "h5" : "h6";
52
+ const headingClass = prefix ? `${prefix}${levelClass}` : levelClass;
53
+ return `<h${level}${headingId}${scopeAttr} class="${headingClass}">${node.content || ""}</h${level}>`;
54
+ }
55
+ }
56
+ class ParagraphRendererStrategy {
57
+ constructor() {
58
+ this.type = "paragraph";
59
+ }
60
+ render(node, renderChild, ctx) {
61
+ const scopeAttr = ctx.getScopeAttr(node);
62
+ if (node.children) {
63
+ const childrenHtml = node.children.map(renderChild).join("");
64
+ return ctx.hasClassConfig() && ctx.classPrefix ? `<p class="${ctx.classPrefix}paragraph"${scopeAttr}>${childrenHtml}</p>` : `<p${scopeAttr}>${childrenHtml}</p>`;
65
+ }
66
+ return ctx.hasClassConfig() && ctx.classPrefix ? `<p class="${ctx.classPrefix}paragraph"${scopeAttr}>${node.content || ""}</p>` : `<p${scopeAttr}>${node.content || ""}</p>`;
67
+ }
68
+ }
69
+ class ListRendererStrategy {
70
+ constructor() {
71
+ this.type = "list";
72
+ }
73
+ render(node, renderChild, ctx) {
74
+ const tag = node.ordered ? "ol" : "ul";
75
+ const items = node.children?.map(renderChild).join("") || "";
76
+ const scopeAttr = ctx.getScopeAttr(node);
77
+ return ctx.hasClassConfig() && ctx.classPrefix ? `<${tag} class="${ctx.classPrefix}list"${scopeAttr}>${items}</${tag}>` : `<${tag}${scopeAttr}>${items}</${tag}>`;
78
+ }
79
+ }
80
+ class ListItemRendererStrategy {
81
+ constructor() {
82
+ this.type = "list-item";
83
+ }
84
+ render(node, _renderChild, ctx) {
85
+ const scopeAttr = ctx.getScopeAttr(node);
86
+ return ctx.hasClassConfig() && ctx.classPrefix ? `<li class="${ctx.classPrefix}list-item"${scopeAttr}>${node.content || ""}</li>` : `<li${scopeAttr}>${node.content || ""}</li>`;
87
+ }
88
+ }
89
+ class ImageRendererStrategy {
90
+ constructor() {
91
+ this.type = "image";
92
+ }
93
+ render(node, _renderChild, ctx) {
94
+ const src = node.src || node.attributes?.src || "";
95
+ const alt = node.alt || node.attributes?.alt || "";
96
+ const scopeAttr = ctx.getScopeAttr(node);
97
+ let classStr = "";
98
+ if (ctx.hasClassConfig()) {
99
+ const prefix = ctx.classPrefix;
100
+ classStr = prefix ? `${prefix}image` : "image";
101
+ if (node.className) classStr += ` ${node.className}`;
102
+ return `<img src="${src}" alt="${alt}" class="${classStr}"${scopeAttr}>`;
103
+ }
104
+ if (node.className) {
105
+ return `<img src="${src}" alt="${alt}" class="${node.className}"${scopeAttr}>`;
106
+ }
107
+ return `<img src="${src}" alt="${alt}"${scopeAttr}>`;
108
+ }
109
+ }
110
+ class CodeRendererStrategy {
111
+ constructor() {
112
+ this.type = "code";
113
+ }
114
+ render(node, _renderChild, ctx) {
115
+ const scopeAttr = ctx.getScopeAttr(node);
116
+ const lang = node.attributes?.lang || "";
117
+ if (ctx.hasClassConfig()) {
118
+ const prefix = ctx.classPrefix;
119
+ const codeClass = prefix ? `${prefix}code` : "code";
120
+ return `<pre${scopeAttr}><code class="${codeClass} language-${lang}">${node.content || ""}</code></pre>`;
121
+ }
122
+ return `<pre${scopeAttr}><code class="language-${lang}">${node.content || ""}</code></pre>`;
123
+ }
124
+ }
125
+ class ContainerRendererStrategy {
126
+ constructor() {
127
+ this.type = "container";
128
+ }
129
+ render(node, renderChild, ctx) {
130
+ if (node.rawHTML) {
131
+ return node.rawHTML;
132
+ }
133
+ const tag = node.attributes?.tag || "div";
134
+ const children = node.children?.map(renderChild).join("") || "";
135
+ const id = node.attributes?.id;
136
+ const idAttr = id ? ` id="${id}"` : "";
137
+ const scopeAttr = ctx.getScopeAttr(node);
138
+ if (tag === "hr") return "<hr>";
139
+ if (ctx.hasClassConfig()) {
140
+ const containerClass = ctx.getContainerClass(tag);
141
+ const prefix = ctx.classPrefix;
142
+ if (prefix) {
143
+ const classes2 = [prefix + (containerClass || "container")];
144
+ if (node.className) classes2.push(node.className);
145
+ return `<${tag} class="${classes2.join(" ")}"${idAttr}${scopeAttr}>${children}</${tag}>`;
146
+ }
147
+ const classes = [containerClass || "container"];
148
+ if (node.className) classes.push(node.className);
149
+ return `<${tag} class="${classes.join(" ")}"${idAttr}${scopeAttr}>${children}</${tag}>`;
150
+ }
151
+ if (node.className) {
152
+ return `<${tag} class="${node.className}"${idAttr}${scopeAttr}>${children}</${tag}>`;
153
+ }
154
+ return `<${tag}${idAttr}${scopeAttr}>${children}</${tag}>`;
155
+ }
156
+ }
157
+ class StrongRendererStrategy {
158
+ constructor() {
159
+ this.type = "strong";
160
+ }
161
+ render(node, _renderChild, ctx) {
162
+ return `<strong${ctx.getScopeAttr(node)}>${node.content || ""}</strong>`;
163
+ }
164
+ }
165
+ class EmphasisRendererStrategy {
166
+ constructor() {
167
+ this.type = "emphasis";
168
+ }
169
+ render(node, _renderChild, ctx) {
170
+ return `<em${ctx.getScopeAttr(node)}>${node.content || ""}</em>`;
171
+ }
172
+ }
173
+ class LinkRendererStrategy {
174
+ constructor() {
175
+ this.type = "link";
176
+ }
177
+ render(node, _renderChild, ctx) {
178
+ const href = node.attributes?.href || "";
179
+ return `<a href="${href}"${ctx.getScopeAttr(node)}>${node.content || ""}</a>`;
180
+ }
181
+ }
182
+ class TextRendererStrategy {
183
+ constructor() {
184
+ this.type = "text";
185
+ }
186
+ render(node, _renderChild, _ctx) {
187
+ return node.content || "";
188
+ }
189
+ }
190
+ class RendererStrategyRegistry {
191
+ constructor() {
192
+ this.strategies = /* @__PURE__ */ new Map();
193
+ this.register(new HeadingRendererStrategy());
194
+ this.register(new ParagraphRendererStrategy());
195
+ this.register(new ListRendererStrategy());
196
+ this.register(new ListItemRendererStrategy());
197
+ this.register(new ImageRendererStrategy());
198
+ this.register(new CodeRendererStrategy());
199
+ this.register(new ContainerRendererStrategy());
200
+ this.register(new StrongRendererStrategy());
201
+ this.register(new EmphasisRendererStrategy());
202
+ this.register(new LinkRendererStrategy());
203
+ this.register(new TextRendererStrategy());
204
+ this.fallback = new TextRendererStrategy();
205
+ }
206
+ /** Register a strategy for a node type. Overrides any existing strategy. */
207
+ register(strategy) {
208
+ this.strategies.set(strategy.type, strategy);
209
+ }
210
+ /** Unregister a strategy by node type. */
211
+ unregister(type) {
212
+ this.strategies.delete(type);
213
+ }
214
+ /** Get a strategy for the given node type, falling back to catch-all. */
215
+ get(type) {
216
+ return this.strategies.get(type) ?? this.fallback;
217
+ }
218
+ /** Check if a dedicated strategy exists for the given node type. */
219
+ has(type) {
220
+ return this.strategies.has(type);
221
+ }
222
+ /** Get all registered dedicated strategy types. */
223
+ get types() {
224
+ return Array.from(this.strategies.keys());
225
+ }
226
+ /** Replace the fallback strategy. */
227
+ setFallback(strategy) {
228
+ this.fallback = strategy;
229
+ }
230
+ }
231
+ class HTMLRenderer {
232
+ constructor(config = {}) {
233
+ this.config = {
234
+ classPrefix: config.classPrefix || "",
235
+ customCSS: config.customCSS || "",
236
+ addHeadingIds: config.addHeadingIds ?? false,
237
+ emitScopeAnchors: config.emitScopeAnchors ?? false
238
+ };
239
+ this.strategyRegistry = new RendererStrategyRegistry();
240
+ }
241
+ /** Access the strategy registry for customization. */
242
+ get strategies() {
243
+ return this.strategyRegistry;
244
+ }
245
+ hasClassConfig() {
246
+ return this.config.classPrefix !== "" || this.config.addHeadingIds;
247
+ }
248
+ getClass(baseClass, nodeClass) {
249
+ if (!this.hasClassConfig()) {
250
+ return nodeClass || "";
251
+ }
252
+ const prefix = this.config.classPrefix;
253
+ const classes = [prefix ? `${prefix}${baseClass}` : baseClass];
254
+ if (nodeClass) classes.push(nodeClass);
255
+ return classes.join(" ");
256
+ }
257
+ generateHeadingId(content) {
258
+ if (!content) return "";
259
+ return content.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
260
+ }
261
+ /**
262
+ * Get the scope attribute string for a node type.
263
+ * Returns empty string if emitScopeAnchors is disabled.
264
+ */
265
+ getScopeAttr(node) {
266
+ if (!this.config.emitScopeAnchors) return "";
267
+ const scopeValue = node.scope || nodeTypeToScope[node.type] || "container";
268
+ return ` data-md-scope="${scopeValue}"`;
269
+ }
270
+ /**
271
+ * Get the CSS class for a container's tag-based rendering.
272
+ * Returns just the tag name since renderWithClass applies the prefix.
273
+ */
274
+ getContainerClass(tag) {
275
+ if (!this.hasClassConfig()) return "";
276
+ return tag;
277
+ }
278
+ buildRenderContext() {
279
+ const self = this;
280
+ return {
281
+ get classPrefix() {
282
+ return self.config.classPrefix;
283
+ },
284
+ get addHeadingIds() {
285
+ return self.config.addHeadingIds;
286
+ },
287
+ get emitScopeAnchors() {
288
+ return self.config.emitScopeAnchors;
289
+ },
290
+ get customCSS() {
291
+ return self.config.customCSS;
292
+ },
293
+ hasClassConfig: () => self.hasClassConfig(),
294
+ getClass: (baseClass, nodeClass) => self.getClass(baseClass, nodeClass),
295
+ getScopeAttr: (node) => self.getScopeAttr(node),
296
+ generateHeadingId: (content) => self.generateHeadingId(content),
297
+ getContainerClass: (tag) => self.getContainerClass(tag)
298
+ };
299
+ }
300
+ renderNode(node) {
301
+ const ctx = this.buildRenderContext();
302
+ const strategy = this.strategyRegistry.get(node.type);
303
+ return strategy.render(node, (child) => this.renderNode(child), ctx);
304
+ }
305
+ renderNodes(nodes) {
306
+ if (!nodes || nodes.length === 0) {
307
+ return "";
308
+ }
309
+ if (this.config.emitScopeAnchors) {
310
+ const inner = nodes.map((node) => this.renderNode(node)).join("\n");
311
+ return `<div data-md-scope="root">
312
+ ${inner}
313
+ </div>`;
314
+ }
315
+ return nodes.map((node) => this.renderNode(node)).join("\n");
316
+ }
317
+ renderToHTMLString(nodes) {
318
+ return this.renderNodes(nodes);
319
+ }
320
+ render(markdown) {
321
+ return markdown;
322
+ }
323
+ getCustomCSS() {
324
+ return this.config.customCSS;
325
+ }
326
+ }
327
+ const t$1 = globalThis, i$1 = (t2) => t2, s = t$1.trustedTypes, e$2 = s ? s.createPolicy("lit-html", { createHTML: (t2) => t2 }) : void 0, h = "$lit$", o$1 = `lit$${Math.random().toFixed(9).slice(2)}$`, n = "?" + o$1, r = `<${n}>`, l = document, c = () => l.createComment(""), a = (t2) => null === t2 || "object" != typeof t2 && "function" != typeof t2, u = Array.isArray, d = (t2) => u(t2) || "function" == typeof t2?.[Symbol.iterator], f = "[ \n\f\r]", v = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, _ = /-->/g, m = />/g, p = RegExp(`>|${f}(?:([^\\s"'>=/]+)(${f}*=${f}*(?:[^
328
+ \f\r"'\`<>=]|("|')|))|$)`, "g"), g = /'/g, $ = /"/g, y = /^(?:script|style|textarea|title)$/i, E = /* @__PURE__ */ Symbol.for("lit-noChange"), A = /* @__PURE__ */ Symbol.for("lit-nothing"), C = /* @__PURE__ */ new WeakMap(), P = l.createTreeWalker(l, 129);
329
+ function V(t2, i2) {
330
+ if (!u(t2) || !t2.hasOwnProperty("raw")) throw Error("invalid template strings array");
331
+ return void 0 !== e$2 ? e$2.createHTML(i2) : i2;
332
+ }
333
+ const N = (t2, i2) => {
334
+ const s2 = t2.length - 1, e2 = [];
335
+ let n2, l2 = 2 === i2 ? "<svg>" : 3 === i2 ? "<math>" : "", c2 = v;
336
+ for (let i3 = 0; i3 < s2; i3++) {
337
+ const s3 = t2[i3];
338
+ let a2, u2, d2 = -1, f2 = 0;
339
+ for (; f2 < s3.length && (c2.lastIndex = f2, u2 = c2.exec(s3), null !== u2); ) f2 = c2.lastIndex, c2 === v ? "!--" === u2[1] ? c2 = _ : void 0 !== u2[1] ? c2 = m : void 0 !== u2[2] ? (y.test(u2[2]) && (n2 = RegExp("</" + u2[2], "g")), c2 = p) : void 0 !== u2[3] && (c2 = p) : c2 === p ? ">" === u2[0] ? (c2 = n2 ?? v, d2 = -1) : void 0 === u2[1] ? d2 = -2 : (d2 = c2.lastIndex - u2[2].length, a2 = u2[1], c2 = void 0 === u2[3] ? p : '"' === u2[3] ? $ : g) : c2 === $ || c2 === g ? c2 = p : c2 === _ || c2 === m ? c2 = v : (c2 = p, n2 = void 0);
340
+ const x = c2 === p && t2[i3 + 1].startsWith("/>") ? " " : "";
341
+ l2 += c2 === v ? s3 + r : d2 >= 0 ? (e2.push(a2), s3.slice(0, d2) + h + s3.slice(d2) + o$1 + x) : s3 + o$1 + (-2 === d2 ? i3 : x);
342
+ }
343
+ return [V(t2, l2 + (t2[s2] || "<?>") + (2 === i2 ? "</svg>" : 3 === i2 ? "</math>" : "")), e2];
344
+ };
345
+ class S {
346
+ constructor({ strings: t2, _$litType$: i2 }, e2) {
347
+ let r2;
348
+ this.parts = [];
349
+ let l2 = 0, a2 = 0;
350
+ const u2 = t2.length - 1, d2 = this.parts, [f2, v2] = N(t2, i2);
351
+ if (this.el = S.createElement(f2, e2), P.currentNode = this.el.content, 2 === i2 || 3 === i2) {
352
+ const t3 = this.el.content.firstChild;
353
+ t3.replaceWith(...t3.childNodes);
354
+ }
355
+ for (; null !== (r2 = P.nextNode()) && d2.length < u2; ) {
356
+ if (1 === r2.nodeType) {
357
+ if (r2.hasAttributes()) for (const t3 of r2.getAttributeNames()) if (t3.endsWith(h)) {
358
+ const i3 = v2[a2++], s2 = r2.getAttribute(t3).split(o$1), e3 = /([.?@])?(.*)/.exec(i3);
359
+ d2.push({ type: 1, index: l2, name: e3[2], strings: s2, ctor: "." === e3[1] ? I : "?" === e3[1] ? L : "@" === e3[1] ? z : H }), r2.removeAttribute(t3);
360
+ } else t3.startsWith(o$1) && (d2.push({ type: 6, index: l2 }), r2.removeAttribute(t3));
361
+ if (y.test(r2.tagName)) {
362
+ const t3 = r2.textContent.split(o$1), i3 = t3.length - 1;
363
+ if (i3 > 0) {
364
+ r2.textContent = s ? s.emptyScript : "";
365
+ for (let s2 = 0; s2 < i3; s2++) r2.append(t3[s2], c()), P.nextNode(), d2.push({ type: 2, index: ++l2 });
366
+ r2.append(t3[i3], c());
367
+ }
368
+ }
369
+ } else if (8 === r2.nodeType) if (r2.data === n) d2.push({ type: 2, index: l2 });
370
+ else {
371
+ let t3 = -1;
372
+ for (; -1 !== (t3 = r2.data.indexOf(o$1, t3 + 1)); ) d2.push({ type: 7, index: l2 }), t3 += o$1.length - 1;
373
+ }
374
+ l2++;
375
+ }
376
+ }
377
+ static createElement(t2, i2) {
378
+ const s2 = l.createElement("template");
379
+ return s2.innerHTML = t2, s2;
380
+ }
381
+ }
382
+ function M(t2, i2, s2 = t2, e2) {
383
+ if (i2 === E) return i2;
384
+ let h2 = void 0 !== e2 ? s2._$Co?.[e2] : s2._$Cl;
385
+ const o2 = a(i2) ? void 0 : i2._$litDirective$;
386
+ return h2?.constructor !== o2 && (h2?._$AO?.(false), void 0 === o2 ? h2 = void 0 : (h2 = new o2(t2), h2._$AT(t2, s2, e2)), void 0 !== e2 ? (s2._$Co ??= [])[e2] = h2 : s2._$Cl = h2), void 0 !== h2 && (i2 = M(t2, h2._$AS(t2, i2.values), h2, e2)), i2;
387
+ }
388
+ class R {
389
+ constructor(t2, i2) {
390
+ this._$AV = [], this._$AN = void 0, this._$AD = t2, this._$AM = i2;
391
+ }
392
+ get parentNode() {
393
+ return this._$AM.parentNode;
394
+ }
395
+ get _$AU() {
396
+ return this._$AM._$AU;
397
+ }
398
+ u(t2) {
399
+ const { el: { content: i2 }, parts: s2 } = this._$AD, e2 = (t2?.creationScope ?? l).importNode(i2, true);
400
+ P.currentNode = e2;
401
+ let h2 = P.nextNode(), o2 = 0, n2 = 0, r2 = s2[0];
402
+ for (; void 0 !== r2; ) {
403
+ if (o2 === r2.index) {
404
+ let i3;
405
+ 2 === r2.type ? i3 = new k(h2, h2.nextSibling, this, t2) : 1 === r2.type ? i3 = new r2.ctor(h2, r2.name, r2.strings, this, t2) : 6 === r2.type && (i3 = new Z(h2, this, t2)), this._$AV.push(i3), r2 = s2[++n2];
406
+ }
407
+ o2 !== r2?.index && (h2 = P.nextNode(), o2++);
408
+ }
409
+ return P.currentNode = l, e2;
410
+ }
411
+ p(t2) {
412
+ let i2 = 0;
413
+ for (const s2 of this._$AV) void 0 !== s2 && (void 0 !== s2.strings ? (s2._$AI(t2, s2, i2), i2 += s2.strings.length - 2) : s2._$AI(t2[i2])), i2++;
414
+ }
415
+ }
416
+ class k {
417
+ get _$AU() {
418
+ return this._$AM?._$AU ?? this._$Cv;
419
+ }
420
+ constructor(t2, i2, s2, e2) {
421
+ this.type = 2, this._$AH = A, this._$AN = void 0, this._$AA = t2, this._$AB = i2, this._$AM = s2, this.options = e2, this._$Cv = e2?.isConnected ?? true;
422
+ }
423
+ get parentNode() {
424
+ let t2 = this._$AA.parentNode;
425
+ const i2 = this._$AM;
426
+ return void 0 !== i2 && 11 === t2?.nodeType && (t2 = i2.parentNode), t2;
427
+ }
428
+ get startNode() {
429
+ return this._$AA;
430
+ }
431
+ get endNode() {
432
+ return this._$AB;
433
+ }
434
+ _$AI(t2, i2 = this) {
435
+ t2 = M(this, t2, i2), a(t2) ? t2 === A || null == t2 || "" === t2 ? (this._$AH !== A && this._$AR(), this._$AH = A) : t2 !== this._$AH && t2 !== E && this._(t2) : void 0 !== t2._$litType$ ? this.$(t2) : void 0 !== t2.nodeType ? this.T(t2) : d(t2) ? this.k(t2) : this._(t2);
436
+ }
437
+ O(t2) {
438
+ return this._$AA.parentNode.insertBefore(t2, this._$AB);
439
+ }
440
+ T(t2) {
441
+ this._$AH !== t2 && (this._$AR(), this._$AH = this.O(t2));
442
+ }
443
+ _(t2) {
444
+ this._$AH !== A && a(this._$AH) ? this._$AA.nextSibling.data = t2 : this.T(l.createTextNode(t2)), this._$AH = t2;
445
+ }
446
+ $(t2) {
447
+ const { values: i2, _$litType$: s2 } = t2, e2 = "number" == typeof s2 ? this._$AC(t2) : (void 0 === s2.el && (s2.el = S.createElement(V(s2.h, s2.h[0]), this.options)), s2);
448
+ if (this._$AH?._$AD === e2) this._$AH.p(i2);
449
+ else {
450
+ const t3 = new R(e2, this), s3 = t3.u(this.options);
451
+ t3.p(i2), this.T(s3), this._$AH = t3;
452
+ }
453
+ }
454
+ _$AC(t2) {
455
+ let i2 = C.get(t2.strings);
456
+ return void 0 === i2 && C.set(t2.strings, i2 = new S(t2)), i2;
457
+ }
458
+ k(t2) {
459
+ u(this._$AH) || (this._$AH = [], this._$AR());
460
+ const i2 = this._$AH;
461
+ let s2, e2 = 0;
462
+ for (const h2 of t2) e2 === i2.length ? i2.push(s2 = new k(this.O(c()), this.O(c()), this, this.options)) : s2 = i2[e2], s2._$AI(h2), e2++;
463
+ e2 < i2.length && (this._$AR(s2 && s2._$AB.nextSibling, e2), i2.length = e2);
464
+ }
465
+ _$AR(t2 = this._$AA.nextSibling, s2) {
466
+ for (this._$AP?.(false, true, s2); t2 !== this._$AB; ) {
467
+ const s3 = i$1(t2).nextSibling;
468
+ i$1(t2).remove(), t2 = s3;
469
+ }
470
+ }
471
+ setConnected(t2) {
472
+ void 0 === this._$AM && (this._$Cv = t2, this._$AP?.(t2));
473
+ }
474
+ }
475
+ class H {
476
+ get tagName() {
477
+ return this.element.tagName;
478
+ }
479
+ get _$AU() {
480
+ return this._$AM._$AU;
481
+ }
482
+ constructor(t2, i2, s2, e2, h2) {
483
+ this.type = 1, this._$AH = A, this._$AN = void 0, this.element = t2, this.name = i2, this._$AM = e2, this.options = h2, s2.length > 2 || "" !== s2[0] || "" !== s2[1] ? (this._$AH = Array(s2.length - 1).fill(new String()), this.strings = s2) : this._$AH = A;
484
+ }
485
+ _$AI(t2, i2 = this, s2, e2) {
486
+ const h2 = this.strings;
487
+ let o2 = false;
488
+ if (void 0 === h2) t2 = M(this, t2, i2, 0), o2 = !a(t2) || t2 !== this._$AH && t2 !== E, o2 && (this._$AH = t2);
489
+ else {
490
+ const e3 = t2;
491
+ let n2, r2;
492
+ for (t2 = h2[0], n2 = 0; n2 < h2.length - 1; n2++) r2 = M(this, e3[s2 + n2], i2, n2), r2 === E && (r2 = this._$AH[n2]), o2 ||= !a(r2) || r2 !== this._$AH[n2], r2 === A ? t2 = A : t2 !== A && (t2 += (r2 ?? "") + h2[n2 + 1]), this._$AH[n2] = r2;
493
+ }
494
+ o2 && !e2 && this.j(t2);
495
+ }
496
+ j(t2) {
497
+ t2 === A ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t2 ?? "");
498
+ }
499
+ }
500
+ class I extends H {
501
+ constructor() {
502
+ super(...arguments), this.type = 3;
503
+ }
504
+ j(t2) {
505
+ this.element[this.name] = t2 === A ? void 0 : t2;
506
+ }
507
+ }
508
+ class L extends H {
509
+ constructor() {
510
+ super(...arguments), this.type = 4;
511
+ }
512
+ j(t2) {
513
+ this.element.toggleAttribute(this.name, !!t2 && t2 !== A);
514
+ }
515
+ }
516
+ class z extends H {
517
+ constructor(t2, i2, s2, e2, h2) {
518
+ super(t2, i2, s2, e2, h2), this.type = 5;
519
+ }
520
+ _$AI(t2, i2 = this) {
521
+ if ((t2 = M(this, t2, i2, 0) ?? A) === E) return;
522
+ const s2 = this._$AH, e2 = t2 === A && s2 !== A || t2.capture !== s2.capture || t2.once !== s2.once || t2.passive !== s2.passive, h2 = t2 !== A && (s2 === A || e2);
523
+ e2 && this.element.removeEventListener(this.name, this, s2), h2 && this.element.addEventListener(this.name, this, t2), this._$AH = t2;
524
+ }
525
+ handleEvent(t2) {
526
+ "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t2) : this._$AH.handleEvent(t2);
527
+ }
528
+ }
529
+ class Z {
530
+ constructor(t2, i2, s2) {
531
+ this.element = t2, this.type = 6, this._$AN = void 0, this._$AM = i2, this.options = s2;
532
+ }
533
+ get _$AU() {
534
+ return this._$AM._$AU;
535
+ }
536
+ _$AI(t2) {
537
+ M(this, t2);
538
+ }
539
+ }
540
+ const B = t$1.litHtmlPolyfillSupport;
541
+ B?.(S, k), (t$1.litHtmlVersions ??= []).push("3.3.2");
542
+ const t = { CHILD: 2 }, e$1 = (t2) => (...e2) => ({ _$litDirective$: t2, values: e2 });
543
+ class i {
544
+ constructor(t2) {
545
+ }
546
+ get _$AU() {
547
+ return this._$AM._$AU;
548
+ }
549
+ _$AT(t2, e2, i2) {
550
+ this._$Ct = t2, this._$AM = e2, this._$Ci = i2;
551
+ }
552
+ _$AS(t2, e2) {
553
+ return this.update(t2, e2);
554
+ }
555
+ update(t2, e2) {
556
+ return this.render(...e2);
557
+ }
558
+ }
559
+ class e extends i {
560
+ constructor(i2) {
561
+ if (super(i2), this.it = A, i2.type !== t.CHILD) throw Error(this.constructor.directiveName + "() can only be used in child bindings");
562
+ }
563
+ render(r2) {
564
+ if (r2 === A || null == r2) return this._t = void 0, this.it = r2;
565
+ if (r2 === E) return r2;
566
+ if ("string" != typeof r2) throw Error(this.constructor.directiveName + "() called with a non-string value");
567
+ if (r2 === this.it) return this._t;
568
+ this.it = r2;
569
+ const s2 = [r2];
570
+ return s2.raw = s2, this._t = { _$litType$: this.constructor.resultType, strings: s2, values: [] };
571
+ }
572
+ }
573
+ e.directiveName = "unsafeHTML", e.resultType = 1;
574
+ const o = e$1(e);
575
+ class LitStrategyRegistry {
576
+ constructor() {
577
+ this.strategies = /* @__PURE__ */ new Map();
578
+ this.register(new LitHeadingStrategy());
579
+ this.register(new LitParagraphStrategy());
580
+ this.register(new LitListStrategy());
581
+ this.register(new LitListItemStrategy());
582
+ this.register(new LitImageStrategy());
583
+ this.register(new LitCodeStrategy());
584
+ this.register(new LitContainerStrategy());
585
+ this.register(new LitStrongStrategy());
586
+ this.register(new LitEmphasisStrategy());
587
+ this.register(new LitLinkStrategy());
588
+ this.register(new LitTextStrategy());
589
+ this.fallback = new LitFallbackStrategy();
590
+ }
591
+ register(strategy) {
592
+ this.strategies.set(strategy.type, strategy);
593
+ }
594
+ unregister(type) {
595
+ this.strategies.delete(type);
596
+ }
597
+ get(type) {
598
+ return this.strategies.get(type) ?? this.fallback;
599
+ }
600
+ has(type) {
601
+ return this.strategies.has(type);
602
+ }
603
+ get types() {
604
+ return Array.from(this.strategies.keys());
605
+ }
606
+ setFallback(strategy) {
607
+ this.fallback = strategy;
608
+ }
609
+ }
610
+ class LitHeadingStrategy {
611
+ constructor() {
612
+ this.type = "heading";
613
+ }
614
+ render(node, _renderChild) {
615
+ const level = node.attributes?.level || "2";
616
+ switch (level) {
617
+ case "1":
618
+ return html`<h1>${o(node.content || "")}</h1>`;
619
+ case "2":
620
+ return html`<h2>${o(node.content || "")}</h2>`;
621
+ case "3":
622
+ return html`<h3>${o(node.content || "")}</h3>`;
623
+ default:
624
+ return html`<h2>${o(node.content || "")}</h2>`;
625
+ }
626
+ }
627
+ }
628
+ class LitParagraphStrategy {
629
+ constructor() {
630
+ this.type = "paragraph";
631
+ }
632
+ render(node, renderChild) {
633
+ if (node.children) {
634
+ return html`<p>${node.children.map((child) => renderChild(child))}</p>`;
635
+ }
636
+ return html`<p>${o(node.content || "")}</p>`;
637
+ }
638
+ }
639
+ class LitListStrategy {
640
+ constructor() {
641
+ this.type = "list";
642
+ }
643
+ render(node, renderChild) {
644
+ return html`<ul>${node.children?.map((child) => renderChild(child))}</ul>`;
645
+ }
646
+ }
647
+ class LitListItemStrategy {
648
+ constructor() {
649
+ this.type = "list-item";
650
+ }
651
+ render(node, _renderChild) {
652
+ return html`<li>${o(node.content || "")}</li>`;
653
+ }
654
+ }
655
+ class LitImageStrategy {
656
+ constructor() {
657
+ this.type = "image";
658
+ }
659
+ render(node, _renderChild) {
660
+ const src = node.src || node.attributes?.src || "";
661
+ const alt = node.alt || node.attributes?.alt || "";
662
+ const className = node.className || "inline-image";
663
+ return html`<img src="${src}" alt="${alt}" class="${className}" style="max-width:100%;height:auto;">`;
664
+ }
665
+ }
666
+ class LitCodeStrategy {
667
+ constructor() {
668
+ this.type = "code";
669
+ }
670
+ render(node, _renderChild) {
671
+ const lang = node.attributes?.lang || "";
672
+ return html`<pre><code class="language-${lang}">${node.content || ""}</code></pre>`;
673
+ }
674
+ }
675
+ class LitContainerStrategy {
676
+ constructor() {
677
+ this.type = "container";
678
+ }
679
+ render(node, renderChild) {
680
+ const className = node.className || "";
681
+ const style = node.attributes?.style || "";
682
+ return html`<div class="${className}" style="${style}">
683
+ ${node.children?.map((child) => renderChild(child))}
684
+ </div>`;
685
+ }
686
+ }
687
+ class LitStrongStrategy {
688
+ constructor() {
689
+ this.type = "strong";
690
+ }
691
+ render(node, _renderChild) {
692
+ return html`<strong>${o(node.content || "")}</strong>`;
693
+ }
694
+ }
695
+ class LitEmphasisStrategy {
696
+ constructor() {
697
+ this.type = "emphasis";
698
+ }
699
+ render(node, _renderChild) {
700
+ return html`<em>${o(node.content || "")}</em>`;
701
+ }
702
+ }
703
+ class LitLinkStrategy {
704
+ constructor() {
705
+ this.type = "link";
706
+ }
707
+ render(node, _renderChild) {
708
+ const href = node.attributes?.href || "";
709
+ return html`<a href="${href}">${o(node.content || "")}</a>`;
710
+ }
711
+ }
712
+ class LitTextStrategy {
713
+ constructor() {
714
+ this.type = "text";
715
+ }
716
+ render(node, _renderChild) {
717
+ return html`${node.content || ""}`;
718
+ }
719
+ }
720
+ class LitFallbackStrategy {
721
+ constructor() {
722
+ this.type = "*";
723
+ }
724
+ render(_node, _renderChild) {
725
+ return html``;
726
+ }
727
+ }
728
+ class LitRenderer {
729
+ constructor() {
730
+ this.strategyRegistry = new LitStrategyRegistry();
731
+ }
732
+ /** Access the strategy registry for customization. */
733
+ get strategies() {
734
+ return this.strategyRegistry;
735
+ }
736
+ /**
737
+ * Render a single node to a Lit TemplateResult.
738
+ */
739
+ renderNode(node) {
740
+ const strategy = this.strategyRegistry.get(node.type);
741
+ return strategy.render(node, (child) => this.renderNode(child));
742
+ }
743
+ /**
744
+ * Render an array of nodes to a single Lit TemplateResult.
745
+ */
746
+ renderNodes(nodes) {
747
+ if (!nodes || nodes.length === 0) {
748
+ return html``;
749
+ }
750
+ return html`${nodes.map((node) => this.renderNode(node))}`;
751
+ }
752
+ /**
753
+ * Render nodes to a plain HTML string.
754
+ * Delegates to HTMLRenderer to avoid duplicating string rendering logic.
755
+ *
756
+ * Note: Uses default HTMLRenderer config (no classPrefix, scope anchors,
757
+ * or heading IDs). For full HTML rendering with those features,
758
+ * use HTMLRenderer directly.
759
+ */
760
+ renderToHTMLString(nodes) {
761
+ if (!nodes || nodes.length === 0) {
762
+ return "";
763
+ }
764
+ if (!this.htmlRenderer) {
765
+ this.htmlRenderer = new HTMLRenderer();
766
+ }
767
+ return this.htmlRenderer.renderNodes(nodes);
768
+ }
769
+ }
770
+ export {
771
+ HTMLRenderer as H,
772
+ LitCodeStrategy as L,
773
+ RendererStrategyRegistry as R,
774
+ LitContainerStrategy as a,
775
+ LitEmphasisStrategy as b,
776
+ LitFallbackStrategy as c,
777
+ defaultAllowedHTMLTags as d,
778
+ LitHeadingStrategy as e,
779
+ LitImageStrategy as f,
780
+ LitLinkStrategy as g,
781
+ LitListItemStrategy as h,
782
+ LitListStrategy as i,
783
+ LitParagraphStrategy as j,
784
+ LitRenderer as k,
785
+ LitStrategyRegistry as l,
786
+ LitStrongStrategy as m,
787
+ LitTextStrategy as n,
788
+ nodeTypeToScope as o
789
+ };
790
+ //# sourceMappingURL=lit-renderer-Bp1Q6wYL.js.map