126 lines
2.9 KiB
JavaScript
Executable file
126 lines
2.9 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
import { readFileSync, existsSync } 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 cli = yargs(process.argv.slice(2))
|
|
.config("config", function (path) {
|
|
return JSON.parse(readFileSync(path), "utf-8");
|
|
})
|
|
.scriptName("gmi-web")
|
|
.command("$0 [files..]", "Convert text/gemini to text/html.", (yargs) =>
|
|
yargs
|
|
.example("$0 --body < ~/my-capsule/index.gmi")
|
|
.example("$0 --html en $(find ~/my-capsule -name '*.gmi')")
|
|
.example(
|
|
"$0 --foreground '#000000' --background '#EEEEEE' --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)).exitProcess(false).argv.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)
|
|
.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)));
|
|
}
|