+19
-2
lib/utils.ts
+19
-2
lib/utils.ts
···
1
1
import { is } from "@atcute/lexicons";
2
2
import { AtUri, UnicodeString } from "@atproto/api";
3
3
import sanitizeHTML from "sanitize-html";
4
+
import katex from "katex";
4
5
import {
6
+
PubLeafletBlocksCode,
5
7
PubLeafletBlocksHeader,
6
8
PubLeafletBlocksHorizontalRule,
9
+
PubLeafletBlocksMath,
7
10
PubLeafletBlocksText,
8
11
PubLeafletBlocksUnorderedList,
9
12
PubLeafletPagesLinearDocument,
···
136
139
html += parseBlocks(block);
137
140
}
138
141
139
-
return sanitizeHTML(html);
142
+
return sanitizeHTML(html, {
143
+
// this is specifically for the math block, though someone could overwrite this if they wanted to
144
+
// can leave this as the default
145
+
allowedAttributes: {
146
+
"*": ["class", "style"],
147
+
},
148
+
});
140
149
}
141
150
142
151
export class RichText {
···
226
235
(segment) => segment.$type === "pub.leaflet.richtext.facet#italic",
227
236
);
228
237
if (isCode) {
229
-
children.push(`<code>${segment.text}</code>`);
238
+
children.push(`<pre><code>${segment.text}</code></pre>`);
230
239
} else if (link) {
231
240
children.push(
232
241
`<a href="${link.uri}" target="_blank" rel="noopener noreferrer">${segment.text}</a>`,
···
274
283
}
275
284
if (is(PubLeafletBlocksUnorderedList.mainSchema, block.block)) {
276
285
html += `<ul>${block.block.children.map((child) => renderListItem(child)).join("")}</ul>`;
286
+
}
287
+
288
+
if (is(PubLeafletBlocksMath.mainSchema, block.block)) {
289
+
html += `<div>${katex.renderToString(block.block.tex, { displayMode: true, output: "html", throwOnError: false })}</div>`;
290
+
}
291
+
292
+
if (is(PubLeafletBlocksCode.mainSchema, block.block)) {
293
+
html += `<pre><code data-language=${block.block.language}>${block.block.plaintext}</code></pre>`;
277
294
}
278
295
279
296
return html.trim();
+1
package.json
+1
package.json
+17
pnpm-lock.yaml
+17
pnpm-lock.yaml
···
17
17
'@atproto/did':
18
18
specifier: ^0.1.5
19
19
version: 0.1.5
20
+
katex:
21
+
specifier: ^0.16.22
22
+
version: 0.16.22
20
23
sanitize-html:
21
24
specifier: ^2.17.0
22
25
version: 2.17.0
···
931
934
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
932
935
engines: {node: '>= 6'}
933
936
937
+
commander@8.3.0:
938
+
resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==}
939
+
engines: {node: '>= 12'}
940
+
934
941
common-ancestor-path@1.0.1:
935
942
resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==}
936
943
···
1336
1343
1337
1344
jsonfile@4.0.0:
1338
1345
resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==}
1346
+
1347
+
katex@0.16.22:
1348
+
resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
1349
+
hasBin: true
1339
1350
1340
1351
kleur@3.0.3:
1341
1352
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
···
3335
3346
3336
3347
commander@4.1.1: {}
3337
3348
3349
+
commander@8.3.0: {}
3350
+
3338
3351
common-ancestor-path@1.0.1: {}
3339
3352
3340
3353
confbox@0.1.8: {}
···
3792
3805
jsonfile@4.0.0:
3793
3806
optionalDependencies:
3794
3807
graceful-fs: 4.2.11
3808
+
3809
+
katex@0.16.22:
3810
+
dependencies:
3811
+
commander: 8.3.0
3795
3812
3796
3813
kleur@3.0.3: {}
3797
3814