import { getAsciiArt } from "../util/asciiArt.ts"; import { toCase } from "util/caseManagement.ts"; import { ArgParser } from "./argParser.ts"; import { colorize } from "./style.ts"; import { selectMenuInteractive } from "./selectMenu.ts"; import { TerminalBlock, TerminalLayout } from "./TerminalLayout.ts"; import { cliAlert, cliLog } from "./prompts.ts"; export class PdfToolsCli { private tools: Map = new Map(); private terminalLayout = new TerminalLayout(); private args = ArgParser.parse(Deno.args); async importTools(tools?: string) { tools = tools?.replace(/\/$/, "").replace(/^\.?\//, "") || "tools"; for (const toolfile of Deno.readDirSync(tools)) { if (toolfile.isFile) { const tool = await import( Deno.cwd() + "/" + tools + "/" + toolfile.name ); if (tool.default) { this.tools.set( toCase(toolfile.name.replace(".ts", ""), "title"), tool.default, ); } } } } private async banana() { const asciiArt = await getAsciiArt("banana"); const body = this.terminalLayout.getBlock("body"); body.clearAll(); cliLog(colorize(asciiArt, "yellow"), body); } private async help() { this.terminalLayout.clear(); this.ensmallenHeader("Help"); const bodyBlock = this.terminalLayout.getBlock("body"); bodyBlock.clearAll(); await cliAlert("BearMetal PDF CLI\n", bodyBlock); await this.embiggenHeader(); } public async run() { try { const titleBlock = new TerminalBlock(); this.terminalLayout.register("title", titleBlock); const bodyBlock = new TerminalBlock(); this.terminalLayout.register("body", bodyBlock); this.embiggenHeader(); if (Deno.args.length === 0) { // console.log( // colorize("No tool specified. Importing all tools...", "gray"), // ); await this.importTools(); } await this.toolMenu(); } finally { this.terminalLayout.clearAll(); Deno.stdin.setRaw(false); } } private async toolMenu() { const tools = this.tools.keys().toArray(); const bodyBlock = this.terminalLayout.getBlock("body"); bodyBlock.clearAll(); bodyBlock.setPreserveHistory(false); const selected = await selectMenuInteractive( "Choose a tool", tools.concat(["Help", "Exit"]), { terminalBlock: bodyBlock, }, ); if (!selected) return; if (selected === "Exit") { return; } await this.runTool(selected); await this.toolMenu(); } private async runTool(toolName: string) { if (toolName === "Help") { return await this.help(); } const tool = this.tools.get(toolName); if (tool) { this.ensmallenHeader(tool.name + " - " + tool.description); const bodyBlock = this.terminalLayout.getBlock("body"); bodyBlock.clearAll(); tool.setBlock?.(bodyBlock); await tool.run(); await tool.done?.(); this.embiggenHeader(); } } private ensmallenHeader(subtitle: string) { this.terminalLayout.clear(); const titleBlock = this.terminalLayout.getBlock("title"); titleBlock.clear(); titleBlock.setFixedHeight(3); titleBlock.setLines([ colorize("BearMetal PDF Tools", "porple"), colorize(subtitle, "gray"), "-=".repeat(Deno.consoleSize().columns / 2), ]); } private async embiggenHeader() { const titleBlock = this.terminalLayout.getBlock("title"); titleBlock.clear(); const lines: string[] = []; for (const t of ["bearmetal:porple", "pdftools:cyan"]) { const [name, color] = t.split(":"); const asciiArt = await getAsciiArt(name); lines.push(...colorize(asciiArt, color).split("\n")); } titleBlock.setFixedHeight(lines.length); titleBlock.setLines(lines); } }