+58
-46
lib/utils.ts
+58
-46
lib/utils.ts
···
4
4
import katex from "katex";
5
5
import sanitizeHTML from "sanitize-html";
6
6
import {
7
+
PubLeafletBlocksBlockquote,
7
8
PubLeafletBlocksCode,
8
9
PubLeafletBlocksHeader,
9
10
PubLeafletBlocksHorizontalRule,
···
182
183
"hr",
183
184
"div",
184
185
"span",
186
+
"blockquote",
185
187
],
186
188
selfClosing: ["img"],
187
189
});
···
242
244
};
243
245
}
244
246
}
247
+
}
248
+
249
+
function parseTextBlock(block: PubLeafletBlocksText.Main) {
250
+
let html = "";
251
+
const rt = new RichText({
252
+
text: block.plaintext,
253
+
facets: block.facets || [],
254
+
});
255
+
const children = [];
256
+
for (const segment of rt.segments()) {
257
+
const link = segment.facet?.find(
258
+
(segment) => segment.$type === "pub.leaflet.richtext.facet#link",
259
+
);
260
+
const isBold = segment.facet?.find(
261
+
(segment) => segment.$type === "pub.leaflet.richtext.facet#bold",
262
+
);
263
+
const isCode = segment.facet?.find(
264
+
(segment) => segment.$type === "pub.leaflet.richtext.facet#code",
265
+
);
266
+
const isStrikethrough = segment.facet?.find(
267
+
(segment) => segment.$type === "pub.leaflet.richtext.facet#strikethrough",
268
+
);
269
+
const isUnderline = segment.facet?.find(
270
+
(segment) => segment.$type === "pub.leaflet.richtext.facet#underline",
271
+
);
272
+
const isItalic = segment.facet?.find(
273
+
(segment) => segment.$type === "pub.leaflet.richtext.facet#italic",
274
+
);
275
+
if (isCode) {
276
+
children.push(`<pre><code>${segment.text}</code></pre>`);
277
+
} else if (link) {
278
+
children.push(
279
+
`<a href="${link.uri}" target="_blank" rel="noopener noreferrer">${segment.text}</a>`,
280
+
);
281
+
} else if (isBold) {
282
+
children.push(`<b>${segment.text}</b>`);
283
+
} else if (isStrikethrough) {
284
+
children.push(`<s>${segment.text}</s>`);
285
+
} else if (isUnderline) {
286
+
children.push(
287
+
`<span style="text-decoration:underline;">${segment.text}</span>`,
288
+
);
289
+
} else if (isItalic) {
290
+
children.push(`<i>${segment.text}</i>`);
291
+
} else {
292
+
children.push(`${segment.text}`);
293
+
}
294
+
}
295
+
html += `<p>${children.join("")}</p>`;
296
+
297
+
return html.trim();
245
298
}
246
299
247
300
function parseBlocks({
···
254
307
let html = "";
255
308
256
309
if (is(PubLeafletBlocksText.mainSchema, block.block)) {
257
-
const rt = new RichText({
258
-
text: block.block.plaintext,
259
-
facets: block.block.facets || [],
260
-
});
261
-
const children = [];
262
-
for (const segment of rt.segments()) {
263
-
const link = segment.facet?.find(
264
-
(segment) => segment.$type === "pub.leaflet.richtext.facet#link",
265
-
);
266
-
const isBold = segment.facet?.find(
267
-
(segment) => segment.$type === "pub.leaflet.richtext.facet#bold",
268
-
);
269
-
const isCode = segment.facet?.find(
270
-
(segment) => segment.$type === "pub.leaflet.richtext.facet#code",
271
-
);
272
-
const isStrikethrough = segment.facet?.find(
273
-
(segment) =>
274
-
segment.$type === "pub.leaflet.richtext.facet#strikethrough",
275
-
);
276
-
const isUnderline = segment.facet?.find(
277
-
(segment) => segment.$type === "pub.leaflet.richtext.facet#underline",
278
-
);
279
-
const isItalic = segment.facet?.find(
280
-
(segment) => segment.$type === "pub.leaflet.richtext.facet#italic",
281
-
);
282
-
if (isCode) {
283
-
children.push(`<pre><code>${segment.text}</code></pre>`);
284
-
} else if (link) {
285
-
children.push(
286
-
`<a href="${link.uri}" target="_blank" rel="noopener noreferrer">${segment.text}</a>`,
287
-
);
288
-
} else if (isBold) {
289
-
children.push(`<b>${segment.text}</b>`);
290
-
} else if (isStrikethrough) {
291
-
children.push(`<s>${segment.text}</s>`);
292
-
} else if (isUnderline) {
293
-
children.push(
294
-
`<span style="text-decoration:underline;">${segment.text}</span>`,
295
-
);
296
-
} else if (isItalic) {
297
-
children.push(`<i>${segment.text}</i>`);
298
-
} else {
299
-
children.push(`${segment.text}`);
300
-
}
301
-
}
302
-
html += `<p>${children.join("")}</p>`;
310
+
html += parseTextBlock(block.block);
303
311
}
304
312
305
313
if (is(PubLeafletBlocksHeader.mainSchema, block.block)) {
···
341
349
if (is(PubLeafletBlocksImage.mainSchema, block.block)) {
342
350
// @ts-ignore
343
351
html += `<div><img src="https://cdn.bsky.app/img/feed_fullsize/plain/${did}/${block.block.image.ref.$link}@jpeg" height="${block.block.aspectRatio.height}" width="${block.block.aspectRatio.width}" alt="${block.block.alt}" /></div>`;
352
+
}
353
+
354
+
if (is(PubLeafletBlocksBlockquote.mainSchema, block.block)) {
355
+
html += `<blockquote>${parseTextBlock(block.block)}</blockquote>`;
344
356
}
345
357
346
358
return html.trim();