@cocalc/project
Version:
CoCalc: project daemon
69 lines (64 loc) • 1.99 kB
text/typescript
/*
* This file is part of CoCalc: Copyright © 2020 Sagemath, Inc.
* License: AGPLv3 s.t. "Commons Clause" – see LICENSE.md for details
*/
import { writeFile, unlink } from "fs";
import { file } from "tmp";
import { callback } from "awaiting";
import { spawn } from "child_process";
import { replace_all } from "@cocalc/util/misc";
interface ParserOptions {
parser: string;
tabWidth?: number;
useTabs?: boolean;
}
function close(proc, cb): void {
proc.on("close", (code) => cb(undefined, code));
}
export async function latex_format(
input: string,
options: ParserOptions
): Promise<string> {
// create input temp file
const input_path: string = await callback(file, { postfix: ".tex" });
try {
await callback(writeFile, input_path, input);
// spawn the latexindent script.
const latexindent = spawn("latexindent", [input_path]);
let output: string = "";
// read data as it is produced.
latexindent.stdout.on("data", (data) => (output += data.toString()));
// wait for subprocess to close.
const code = await callback(close, latexindent);
if (code) {
throw Error(`latexindent exited with code ${code}`);
}
// now process the result according to the options.
if (!options.useTabs) {
// replace tabs by spaces
let tab_width = 2;
if (options.tabWidth !== undefined) {
tab_width = options.tabWidth;
}
let SPACES = "";
for (let i = 0; i < tab_width; i++) {
SPACES += " ";
}
output = replace_all(output, "\t", SPACES);
}
// latexindent also annoyingly introduces a lot of whitespace lines.
const lines: string[] = output.split("\n"),
lines2: string[] = [];
for (let i = 0; i < lines.length; i++) {
if (/\S/.test(lines[i])) {
lines2.push(lines[i]);
} else {
lines2.push("");
}
output = lines2.join("\n");
}
return output;
} finally {
unlink(input_path, () => {});
}
}