#!/usr/bin/env node import { readFileSync } from "fs"; import path from "path"; import fs from "vinyl-fs"; import yargs from "yargs"; import * as CSS from "./css.js"; import { streamHTML, toHTML } from "./html.js"; const internal = (file) => path.resolve(path.dirname(new URL(import.meta.url).pathname), file); const pkg = JSON.parse(readFileSync(internal("package.json"), "utf-8")); const cli = yargs(process.argv.slice(2)) .config("config", function (path) { return JSON.parse(readFileSync(path), "utf-8"); }) .scriptName("gmi-web") .command("$0 [files..]", pkg.description, (yargs) => yargs .example("$0 --body < doc.gmi") .example("$0 --html en $(find ~/my-capsule -name '*.gmi')") .example("$0 --foreground '#9EEBCF' --html en < doc.gmi") .example("$0 --image jpg --audio mp3 --image png --body < doc.gmi") .epilog("See the gmi-web(1) man page for more information.") ) .options({ body: { type: "boolean", group: "Core:", }, html: { type: "string", requiresArg: true, group: "Core:", }, css: { requiresArg: true, group: "Core:", }, dir: { type: "string", hidden: true, choices: ["rtl", "ltr"], default: "ltr", requiresArg: true, group: "HTML:", }, author: { type: "string", requiresArg: true, group: "HTML:", }, description: { coerce: (arg) => (typeof arg === "number" ? arg : arg ? Infinity : 0), group: "HTML:", }, charset: { type: "string", hidden: true, default: "utf-8", requiresArg: true, group: "HTML:", }, image: { type: "array", requiresArg: true, group: "Media:", }, audio: { type: "array", requiresArg: true, group: "Media:", }, video: { type: "array", requiresArg: true, group: "Media:", }, inline: { type: "boolean", hidden: true, group: "CSS:", }, }); const css = yargs(process.argv.slice(2)) .version(false) .help(false) .exitProcess(false) .parse().css || "gmi-web.css"; const CSS_VARS = CSS.rootVariables(CSS.load({ css })); Object.keys(CSS_VARS).forEach((key) => { cli.option(key, { default: CSS_VARS[key] }); cli.conflicts(key, "core"); cli.conflicts(key, "none"); }); cli.group(Object.keys(CSS_VARS), `${css}:`); const argv = cli .conflicts("author", "body") .conflicts("html", "body") .alias("html", "language") .alias("html", "lang") .showHelpOnFail(true) .version(pkg.version) .help().argv; if (!argv.html && !argv.body) { cli.showHelp(); console.error(`\nMissing required argument: --html or --body`); cli.exit(1); } if (!argv.files) { let gemtext; try { gemtext = readFileSync(process.stdin.fd, "utf-8"); } catch (e) { cli.showHelp(); console.error("\nMissing files: pipe from stdin or provide [files..]"); cli.exit(1); } console.log(toHTML(gemtext, argv)); } else { fs.src(argv.files) .pipe(streamHTML(argv)) .pipe(fs.dest((file) => path.dirname(file.path))); }