Support overflowing tables in default styles
This commit is contained in:
parent
51b3633077
commit
5dfb004a59
6 changed files with 90 additions and 29 deletions
86
src/index.ts
86
src/index.ts
|
@ -1,7 +1,7 @@
|
|||
import Path from "node:path";
|
||||
import { parseArgs } from "node:util";
|
||||
import EMDY from "@endeavorance/emdy";
|
||||
import type { BunFile } from "bun";
|
||||
import { Glob, type BunFile } from "bun";
|
||||
import DEFAULT_STYLESHEET from "./defaults/default-style.css" with {
|
||||
type: "text",
|
||||
};
|
||||
|
@ -10,10 +10,17 @@ import DEFAULT_TEMPLATE from "./defaults/default-template.html" with {
|
|||
};
|
||||
import { CLIError } from "./error";
|
||||
import { parseMarkdown } from "./markdown";
|
||||
import { watch } from "node:fs/promises";
|
||||
|
||||
const DEFAULT_TEMPLATE_FILE = "_template.html";
|
||||
const DEFAULT_STYLESHEET_FILE = "_style.css";
|
||||
|
||||
async function isDirectory(path: string): Promise<boolean> {
|
||||
const file = Bun.file(path);
|
||||
const stat = await file.stat();
|
||||
return stat.isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a file path, attempt to read the text of the file
|
||||
* @param filePath - The path to the file to read
|
||||
|
@ -66,6 +73,9 @@ interface CLIOptions {
|
|||
/** The path to the stylesheet file */
|
||||
stylesheetFilePath: string | null;
|
||||
|
||||
/** If the default stylesheet should be included regardless of the provided stylesheet */
|
||||
includeDefaultStylesheet: boolean;
|
||||
|
||||
/** If true, show help message */
|
||||
help: boolean;
|
||||
|
||||
|
@ -107,6 +117,10 @@ function parseCLIArgs(): { options: CLIOptions; args: string[] } {
|
|||
type: "string",
|
||||
short: "s",
|
||||
},
|
||||
"include-default-stylesheet": {
|
||||
type: "boolean",
|
||||
short: "S",
|
||||
},
|
||||
cwd: {
|
||||
type: "string",
|
||||
default: process.cwd(),
|
||||
|
@ -119,12 +133,14 @@ function parseCLIArgs(): { options: CLIOptions; args: string[] } {
|
|||
allowPositionals: true,
|
||||
});
|
||||
|
||||
// Validation
|
||||
// == Argument Validation ==
|
||||
|
||||
if (positionals.length > 1 && flags.outfile) {
|
||||
// Outfile requires only one argument
|
||||
if (flags.outfile && positionals.length > 1) {
|
||||
throw new CLIError("--outfile cannot be used with multiple inputs.");
|
||||
}
|
||||
|
||||
// Outfile and Outdir cannot be used together
|
||||
if (flags.outdir && flags.outfile) {
|
||||
throw new CLIError("--outdir and --outfile cannot be used together.");
|
||||
}
|
||||
|
@ -137,6 +153,7 @@ function parseCLIArgs(): { options: CLIOptions; args: string[] } {
|
|||
stdout: flags.stdout ?? false,
|
||||
templateFilePath: flags.template ?? null,
|
||||
stylesheetFilePath: flags.stylesheet ?? null,
|
||||
includeDefaultStylesheet: flags["include-default-stylesheet"] ?? false,
|
||||
help: flags.help ?? false,
|
||||
title: flags.title ?? null,
|
||||
},
|
||||
|
@ -171,8 +188,11 @@ async function loadTemplate(options: CLIOptions): Promise<string> {
|
|||
* @returns The stylesheet string
|
||||
*/
|
||||
async function loadStylesheet(options: CLIOptions): Promise<string> {
|
||||
const preamble = options.includeDefaultStylesheet ? DEFAULT_STYLESHEET : "";
|
||||
|
||||
if (options.stylesheetFilePath) {
|
||||
return readFile(options.stylesheetFilePath);
|
||||
const loadedSheet = await readFile(options.stylesheetFilePath);
|
||||
return [preamble, loadedSheet].join("\n");
|
||||
}
|
||||
|
||||
const checkStylesheetFile = Bun.file(
|
||||
|
@ -180,7 +200,8 @@ async function loadStylesheet(options: CLIOptions): Promise<string> {
|
|||
);
|
||||
|
||||
if (await checkStylesheetFile.exists()) {
|
||||
return checkStylesheetFile.text();
|
||||
const loadedSheet = await checkStylesheetFile.text();
|
||||
return [preamble, loadedSheet].join("\n");
|
||||
}
|
||||
|
||||
return DEFAULT_STYLESHEET;
|
||||
|
@ -263,6 +284,27 @@ async function getOutputFile(
|
|||
return Bun.file(outputPath);
|
||||
}
|
||||
|
||||
function processStdin(options: CLIOptions): Promise<void> {
|
||||
const outfile = options.outfile ? Bun.file(options.outfile) : Bun.stdout;
|
||||
return buildFile(Bun.stdin, outfile, options);
|
||||
}
|
||||
|
||||
async function processFile(
|
||||
options: CLIOptions,
|
||||
filePath: string,
|
||||
): Promise<void> {
|
||||
console.log(`Building ${filePath}...`);
|
||||
const file = Bun.file(filePath);
|
||||
|
||||
// Ensure input files exist
|
||||
if (!(await file.exists())) {
|
||||
throw new CLIError(`File ${filePath} does not exist.`);
|
||||
}
|
||||
|
||||
const outfile = await getOutputFile(filePath, options);
|
||||
await buildFile(file, outfile, options);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { options, args } = parseCLIArgs();
|
||||
|
||||
|
@ -277,13 +319,14 @@ Usage:
|
|||
echo "some markdown" | buildmd
|
||||
|
||||
Options:
|
||||
--outfile, -o <file> Output path
|
||||
--outdir, -d <dir> Output directory
|
||||
--stdout Force output to stdout
|
||||
--template, -t <file> Template path (default: _template.html)
|
||||
--stylesheet, -s <file> Stylesheet path (default: _style.css)
|
||||
--title, -T <string> Document title override
|
||||
--help, -h Show this help message
|
||||
--outfile, -o <file> Output path
|
||||
--outdir, -d <dir> Output directory
|
||||
--stdout Force output to stdout
|
||||
--template, -t <file> Template path (default: _template.html)
|
||||
--stylesheet, -s <file> Stylesheet path (default: _style.css)
|
||||
--include-default-stylesheet, -S Extend default CSS instead of overwriting
|
||||
--title, -T <string> Document title override
|
||||
--help, -h Show this help message
|
||||
`.trim(),
|
||||
);
|
||||
process.exit(0);
|
||||
|
@ -291,22 +334,21 @@ Options:
|
|||
|
||||
// stdin mode
|
||||
if (args.length === 0) {
|
||||
const outfile = options.outfile ? Bun.file(options.outfile) : Bun.stdout;
|
||||
await buildFile(Bun.stdin, outfile, options);
|
||||
process.exit(0);
|
||||
return processStdin(options);
|
||||
}
|
||||
|
||||
// file mode
|
||||
for (const arg of args) {
|
||||
const file = Bun.file(arg);
|
||||
const isDir = await isDirectory(arg);
|
||||
|
||||
// Ensure input files exist
|
||||
if (!(await file.exists())) {
|
||||
throw new CLIError(`File ${arg} does not exist.`);
|
||||
if (isDir) {
|
||||
const dirGlob = new Glob(`${arg}/**/*.md`);
|
||||
for await (const file of dirGlob.scan()) {
|
||||
await processFile(options, file);
|
||||
}
|
||||
} else {
|
||||
await processFile(options, arg);
|
||||
}
|
||||
|
||||
const outfile = await getOutputFile(arg, options);
|
||||
await buildFile(file, outfile, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue