1// text-content extraction processors. `text-contents` fills
2// `media_files.contents` for plain text files; `highlight-code` fills it
3// with pre-rendered syntax highlighting html for source code.
4const procLoadTextContents: Processor = {
5 name: "text-contents",
6 version: 2,
7 title: "load text content",
8 include: rules.extsReadContents,
9 cores: 1,
10 async run({ path, mediaFile, stat }) {
11 if (stat.size > 1_000_000) return;
12 const text = await path.read("utf-8");
13 mediaFile.setContents(text);
14 },
15};
16
17const procHighlightCode: Processor = {
18 name: "highlight-code",
19 version: 2,
20 title: "highlight source code",
21 include: new Set(rules.extsCode.keys()),
22 cores: 1,
23 async run({ path, mediaFile, stat }) {
24 const language = UNWRAP(
25 rules.extsCode.get(path.ext.toLowerCase()),
26 );
27 // An issue is that .ts is an overloaded extension, shared between
28 // 'transport stream' and 'typescript'.
29 //
30 // Filter used here is:
31 // - more than 1mb
32 // - invalid UTF-8
33 if (stat.size > 1_000_000) return;
34 let code;
35 const buf = await path.read();
36 try {
37 code = new TextDecoder("utf-8", { fatal: true }).decode(buf);
38 } catch (error) {
39 mediaFile.setContents("");
40 return;
41 }
42 const content = await highlight.highlightCode(code, language);
43 mediaFile.setContents(content);
44 },
45};
46
47export const processors: Processor[] = [
48 procLoadTextContents,
49 procHighlightCode,
50];
51
52import { UNWRAP } from "@clo/lib/assert";
53
54import * as highlight from "#src/file-viewer/highlight.ts";
55import * as rules from "#src/file-viewer/rules.ts";
56import type { Processor } from "../registry.ts";