Commit dafdc6fe authored by Jiwon Kwon's avatar Jiwon Kwon
Browse files

refactor: replace btoa to encoding, use Deno tempFile

parent a7d6819d
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -128,11 +128,11 @@ the versioning.
    isn't a TTY (for example, when redirecting to a file) or when the `NO_COLOR`
    environment variable is set.  [[#257], [#341] by Cho Hasang]
    
 -  The 'fedify lookup' command now displays images depending on user's 
 -  The `fedify lookup` command now displays images depending on user's 
    terminal emulator. [[#169], [#348] by Jiwon Kwon]

     - Supported terminal emulators are `Kitty`, `WezTerm`, `Konsole`, `Warp`,
      `Wayst`, `st`, and `iterms`.
     - Supported terminal emulators are Kitty, WezTerm, Konsole, Warp,
      Wayst, st, and iTerm.



+1 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
    "@logtape/logtape": "jsr:@logtape/logtape@^1.0.0",
    "@std/assert": "jsr:@std/assert@^1.0.13",
    "@std/async": "jsr:@std/async@^1.0.13",
    "@std/encoding": "jsr:@std/encoding@^1.0.10",
    "@std/fs": "jsr:@std/fs@^1.0.3",
    "@std/path": "jsr:@std/path@^1.0.6",
    "@std/yaml": "jsr:@std/yaml@^1.0.8",
+0 −3
Original line number Diff line number Diff line
@@ -3,8 +3,5 @@
    "patchedDependencies": {
      "vitepress@1.6.3": "patches/vitepress@1.6.3.patch"
    }
  },
  "dependencies": {
    "sharp": "^0.34.3"
  }
}
+13 −18
Original line number Diff line number Diff line
import { encodeBase64 } from "@std/encoding/base64";
import sharp from "sharp";

export type TerminalType = "kitty" | "iterm2" | "none";
@@ -16,15 +17,9 @@ type KittyCommand = Record<string, string | number>;
export function detectTerminalCapabilities(): TerminalType {
  const termProgram = (Deno.env.get("TERM_PROGRAM") || "").toLowerCase();

  for (const id of KITTY_IDENTIFIERS) {
    if (termProgram === id) {
      return "kitty";
    }
  }
  if (KITTY_IDENTIFIERS.includes(termProgram)) return "kitty";

  if (termProgram === "iterm.app") {
    return "iterm2";
  }
  if (termProgram === "iterm.app") return "iterm2";

  return "none";
}
@@ -66,8 +61,8 @@ export async function renderImageKitty(
  imagePath: string,
  cmd: KittyCommand,
): Promise<void> {
  const data = await Deno.readFile(imagePath);
  const base64Data = btoa(String.fromCharCode(...data));
  const imageData = await Deno.readFile(imagePath);
  const base64Data = encodeBase64(imageData);
  let remaining = base64Data;
  let isFirst = true;

@@ -77,9 +72,9 @@ export async function renderImageKitty(

    const chunkCmd = {
      ...(isFirst ? cmd : {}),
      m: remaining.length > 0 ? 1 : 0, // The required 'm' property
      m: remaining.length > 0 ? 1 : 0,
    };
    chunkCmd.m = remaining.length > 0 ? 1 : 0;

    const command = serializeGrCommand(chunkCmd, chunk);

    Deno.stdout.writeSync(command);
@@ -92,7 +87,7 @@ export async function renderImageITerm2(
  imagePath: string,
): Promise<void> {
  const imageData = await Deno.readFile(imagePath);
  const base64Data = btoa(String.fromCharCode(...imageData));
  const base64Data = encodeBase64(imageData);

  const encoder = new TextEncoder();
  const command = encoder.encode(
@@ -105,10 +100,8 @@ export async function downloadImage(url: string): Promise<string | null> {
  try {
    const response = await fetch(url);
    const imageData = new Uint8Array(await response.arrayBuffer());
    const tempDir = Deno.env.get("TMPDIR") || Deno.env.get("TMP") || "/tmp";
    const filename = `terminal_image_${Date.now()}_${crypto.randomUUID()}`;
    const extension = new URL(url).pathname.split(".").pop() || "jpg";
    const tempPath = `${tempDir}/${filename}.${extension}`;
    const tempPath = await Deno.makeTempFile({ suffix: `.${extension}` });

    await Deno.writeFile(tempPath, imageData);

@@ -118,7 +111,7 @@ export async function downloadImage(url: string): Promise<string | null> {
  }
}

export async function renderImage(
export async function renderImages(
  imageUrls: URL[],
): Promise<void> {
  const graphicsProtocol = await detectTerminalCapabilities();
@@ -134,6 +127,8 @@ export async function renderImage(
      .resize(300)
      .toFile(resizedPath);

    console.log(""); // clear the line before rendering image

    if (graphicsProtocol === "kitty") {
      await renderImageKitty(resizedPath, {
        a: "T",
@@ -142,8 +137,8 @@ export async function renderImage(
    } else if (graphicsProtocol === "iterm2") {
      await renderImageITerm2(resizedPath);
    } else {
      // Skip rendering for unsupported terminals
      continue;
    }
    console.log(""); // clear the line after rendering image
  }
}
+2 −2
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ import * as colors from "@std/fmt/colors";
import { dirname, isAbsolute, resolve } from "@std/path";
import ora from "ora";
import { getContextLoader, getDocumentLoader } from "./docloader.ts";
import { renderImage } from "./imagerenderer.ts";
import { renderImages } from "./imagerenderer.ts";
import { spawnTemporaryServer, type TemporaryServer } from "./tempserver.ts";
import { colorEnabled, formatCliObjectOutputWithColor } from "./utils.ts";

@@ -137,7 +137,7 @@ export async function writeObjectToStream(
      imageUrls = await findAllImages(object);
    }
    if (!options.output && imageUrls.length > 0) {
      await renderImage(imageUrls);
      await renderImages(imageUrls);
    }
  } finally {
    writer.releaseLock();