This commit is contained in:
Emmaline Autumn 2025-04-24 21:40:59 -06:00
parent 7d42920dcb
commit 2634f40f2b
7 changed files with 68 additions and 23 deletions

View File

@ -27,6 +27,10 @@ export class TerminalLayout {
}
}
getBlock(name: string) {
return this.blocks[name];
}
requestRender() {
if (this.debounceTimer !== null) {
clearTimeout(this.debounceTimer);

View File

@ -3,9 +3,13 @@ import { toCase } from "util/caseManagement.ts";
import { ArgParser } from "./argParser.ts";
import { colorize } from "./colorize.ts";
import { selectMenuInteractive } from "./selectMenu.ts";
import { TerminalBlock, TerminalLayout } from "./TerminalLayout.ts";
export class PdfToolsCli {
private tools: Map<string, ITool> = new Map();
private terminalLayout = new TerminalLayout();
private args = ArgParser.parse(Deno.args);
async importTools(tools?: string) {
tools = tools?.replace(/\/$/, "").replace(/^\.?\//, "") || "tools";
@ -34,31 +38,48 @@ export class PdfToolsCli {
}
public async run() {
console.clear();
let lineCount = 0;
for (const t of ["bearmetal:porple", "pdftools:cyan"]) {
const [name, color] = t.split(":");
const asciiArt = await getAsciiArt(name);
console.log(colorize(asciiArt, color));
lineCount += asciiArt.split("\n").length;
try {
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"));
}
const titleBlock = new TerminalBlock();
this.terminalLayout.register("title", titleBlock);
const bodyBlock = new TerminalBlock();
this.terminalLayout.register("body", bodyBlock);
titleBlock.setFixedHeight(lines.length);
titleBlock.setLines(lines);
if (Deno.args.length === 0) {
// console.log(
// colorize("No tool specified. Importing all tools...", "gray"),
// );
await this.importTools();
}
this.toolMenu();
} finally {
this.terminalLayout.clearAll();
}
if (Deno.args.length === 0) {
console.log(
colorize("No tool specified. Importing all tools...", "gray"),
);
await this.importTools();
}
const args = ArgParser.parse(Deno.args);
this.toolMenu(Deno.consoleSize().rows - lineCount);
}
private async toolMenu(space?: number) {
private async toolMenu() {
const tools = this.tools.keys().toArray();
const selected = await selectMenuInteractive("Choose a tool", tools);
const bodyBlock = this.terminalLayout.getBlock("body");
const selected = await selectMenuInteractive("Choose a tool", tools, {
terminalBlock: bodyBlock,
});
bodyBlock.clear();
if (!selected) return;
const tool = this.tools.get(toCase(selected, "camel"));
await this.runTool(selected);
this.toolMenu();
}
private async runTool(toolName: string) {
const tool = this.tools.get(toolName);
if (tool) {
await tool.run();
await tool.done?.();
}
}
}

View File

@ -1,9 +1,10 @@
{
"name": "@bearmetal/pdf-tools",
"tasks": {
"dev": "deno run -A --watch main.ts",
"dev": "deno run -A --env-file=.env --watch main.ts",
"compile": "deno compile -o compare-form-fields.exe --target x86_64-pc-windows-msvc -R ./main.ts",
"install": "deno install -fgq --import-map ./deno.json -n checkfields -R ./main.ts"
"install": "deno install -fgq --import-map ./deno.json -n checkfields -R ./main.ts",
"debug": "deno run -A --env-file=.env --inspect-wait --watch main.ts"
},
"imports": {
"@std/assert": "jsr:@std/assert@1",

View File

@ -80,6 +80,22 @@ async function renameFields(
}
}
class RenameFields implements ITool {
name = "renamefields";
description = "Renames fields in a PDF form";
help() {
console.log("Usage: renamefields <pdfPath> <pattern> <change>");
}
async run(pdfPath: string = "", pattern: string = "", change: string = "") {
await callWithArgPrompt(renameFields, [
["Please provide path to PDF:", (p) => !!p && p.endsWith(".pdf")],
"Please provide search string:",
"Please provide requested change:",
], [pdfPath, pattern, change]);
}
}
export default new RenameFields();
if (import.meta.main) {
// await call(renameFields)
// while (!path || !path.endsWith('.pdf')) path = prompt("Please provide path to PDF:") || '';

View File

@ -5,5 +5,6 @@ declare global {
description: string;
run: ToolFunc<any[]>;
help?: () => Promise<void> | void;
done?: () => Promise<void> | void;
}
}

View File

@ -15,7 +15,11 @@ export async function call<T extends unknown[]>(
Object.assign(config, conf);
}
const args = config.args || Deno.args;
let args = config.args || Deno.args;
if (!args.length && transforms.length) {
config.multiTransform ? args = transforms.map(() => "") : args = [""];
}
const shouldPair = transforms.length === args.length;
const multiTransform = config.multiTransform ||
!shouldPair && transforms.length > 1;

View File

@ -99,10 +99,8 @@ function coerceCaseToLower(str: string, caseType: CaseType) {
export function toCase(str: string, toCase: CaseType) {
const caseType = parseCase(str) || "";
console.log(caseType);
if (caseType === toCase) return str;
const lowerStr = coerceCaseToLower(str, caseType);
console.log(lowerStr);
switch (toCase) {
case "pascal":
return lowerToPascalCase(lowerStr);