nandi/oripublic Fork 0
db7446cc6b52b6bd9196294c1e66e5eb56754d5e
Commits
Clone
git clone https://git.rickub.com/nandi/ori.git
git clone ssh://git@rickub.com/nandi/ori.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

forked from bots-garden/ori

AsciiDocView.tsx · 58 lines · 1.6 KBTypeScript Blame HistoryRaw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * AsciiDocView renders an AsciiDoc document to HTML with Asciidoctor,
 * lazy-loading the (heavy) converter on first use.
 *
 * The converted HTML comes from files in the user's own workspace, rendered
 * for the user who owns them — the same trust model as opening the file in
 * any editor's preview.
 *
 * @example
 * <AsciiDocView content="= Title" />
 */

import { useEffect, useState } from "react";

export function AsciiDocView({ content }: { content: string }) {
	const [html, setHtml] = useState<string | null>(null);
	const [error, setError] = useState<string | null>(null);

	useEffect(() => {
		let cancelled = false;
		// @asciidoctor/core v4 exposes an async convert() as a named export
		// (the v3 synchronous asciidoctor() factory is gone).
		import("@asciidoctor/core")
			.then(({ convert }) =>
				convert(content, {
					safe: "safe",
					attributes: { showtitle: true, icons: "font" },
				}),
			)
			.then((converted) => {
				if (!cancelled) {
					setHtml(String(converted));
				}
			})
			.catch((cause: Error) => {
				if (!cancelled) {
					setError(`AsciiDoc rendering failed: ${cause.message}`);
				}
			});
		return () => {
			cancelled = true;
		};
	}, [content]);

	if (error) {
		return <p className="pane-error">{error}</p>;
	}
	if (html === null) {
		return <p className="pane-empty">rendering</p>;
	}
	return (
		<div
			className="markdown asciidoc"
			// biome-ignore lint/security/noDangerouslySetInnerHtml: Asciidoctor's output over the user's own workspace files, converted in safe mode — the accepted pattern for a local document preview.
			dangerouslySetInnerHTML={{ __html: html }}
		/>
	);
}