A note-taking app inspired by nb
1import { existsSync } from "@std/fs";
2
3export function print(s: string = "", nl = true) {
4 const out = nl ? s + "\n" : s;
5 Deno.stdout.writeSync(new TextEncoder().encode(out));
6}
7
8export function moveFile(
9 origin: string,
10 destination: string,
11 clobber: boolean = false,
12) {
13 if (existsSync(destination)) {
14 if (clobber) {
15 Deno.removeSync(destination, { recursive: true });
16 } else {
17 throw new Error(`file ${destination} already exists`);
18 }
19 }
20 Deno.renameSync(origin, destination);
21}
22
23let terminalMarked: import("marked").Marked | null = null;
24let htmlMarked: import("marked").Marked | null = null;
25let wrapWidth: number | null = null;
26
27async function getTerminalMarked() {
28 if (terminalMarked == null) {
29 const { Marked } = await import("marked");
30 const { markedTerminal } = await import("marked-terminal");
31 terminalMarked = new Marked();
32 terminalMarked.use(markedTerminal());
33 }
34 return terminalMarked;
35}
36
37async function getHtmlMarked() {
38 if (htmlMarked == null) {
39 const { Marked } = await import("marked");
40 htmlMarked = new Marked();
41 htmlMarked.use({ gfm: false });
42 }
43 return htmlMarked;
44}
45
46function getWrapWidth() {
47 if (wrapWidth == null) {
48 wrapWidth = Math.min(Deno.consoleSize().columns, 80);
49 }
50 return wrapWidth;
51}
52
53export async function renderMarkdown(
54 s: string,
55 format: "terminal" | "html",
56): Promise<string> {
57 switch (format) {
58 case "terminal": {
59 const marked = await getTerminalMarked();
60 const wrapAnsi = (await import("wrap-ansi")).default;
61 return wrapAnsi(marked.parse(s) as string, getWrapWidth());
62 }
63 case "html": {
64 const marked = await getHtmlMarked();
65 return marked.parse(s) as string;
66 }
67 }
68}
69
70export function truncateString(
71 s: string,
72 length: number,
73 placeholder: string = "...",
74): string {
75 if (s.length < length) return s;
76 const idx = s.slice(0, length - placeholder.length - 1).trimEnd().lastIndexOf(
77 " ",
78 );
79 if (idx > 0) {
80 return s.slice(0, idx) + placeholder;
81 } else {
82 return s.slice(0, length - placeholder.length) + placeholder;
83 }
84}
85
86export function ensureSuffix(s: string, suffix: string): string {
87 return s.endsWith(suffix) ? s : s + suffix;
88}