An error occurred while loading the file. Please try again.
-
Guillaume Perréal authoreda8cfed21
import exec from "../util/exec";
import fs from "fs";
import { merge } from "merge-anything";
import { mkTempFile } from "../util/tempdir";
import parallel from "../util/parallel";
import path from "path";
import PluginError from "plugin-error";
import { promisify } from "util";
const writeFile = promisify(fs.writeFile);
const exists = promisify(fs.exists);
const PLUGIN_NAME = "pandoc";
const DEFAULTS = {
slideLevel: 2,
tocDepth: 2,
revealJSURL: "reveal.js",
template: path.normalize(__dirname + "/../../templates/revealjs.html"),
variables: {
width: 960,
height: 700,
navigationMode: "linear",
theme: "inrae",
slideNumber: true,
history: true,
fragmentInURL: true,
},
};
/**
* @param {string} url
* @return {function}
*/
export function getRevealJSResolver(url) {
if (url.match(/^(https?:)?\/\//i)) {
return () => url;
}
return (output) => path.relative(path.dirname(output.relative), url);
}
/**
* @param {import("vinyl")} input
* @param {string} path
* @return {Promise<void>|never}
* @throws PluginError
*/
async function writeToDisk(input, path) {
if (input.isStream()) {
const write = fs.createWriteStream(path);
const done = new Promise((resolve, reject) => {
write.on("close", () => resolve());
input.on("error", reject);
write.on("error", reject);
});
input.contents.pipe(write);
return done;
}
if (input.isBuffer()) {
return writeFile(path, input.contents, {});
}
throw new PluginError(PLUGIN_NAME, `cannot handle input ${input.inspect()}`);
}
/**
* @param {import("vinyl")} input
* @return {import("vinyl")}
* @throws PluginError
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
*/
async function onDisk(input) {
if (await exists(input.path)) {
return input;
}
const tmpFile = await mkTempFile(input);
await writeToDisk(input, tmpFile.path);
return tmpFile;
}
export default function pandoc(options = {}) {
const { slideLevel, tocDepth, revealJSURL, template, variables } = merge(
{},
DEFAULTS,
options
);
const revealJSURLResolver = getRevealJSResolver(revealJSURL);
return parallel(
/**
* @param {import("vinyl")} input
*/
async function (input) {
const output = input.clone({ contents: false });
output.extname = ".html";
output.contents = null;
const src = await onDisk(input);
const args = [
"--from=markdown+backtick_code_blocks+pandoc_title_block+yaml_metadata_block",
"--to=revealjs",
"--standalone",
`--template=${template}`,
`--slide-level=${slideLevel}`,
"--toc",
`--toc-depth=${tocDepth}`,
`--variable=revealjs-url:${revealJSURLResolver(output)}`,
...Object.getOwnPropertyNames(variables).map(
(name) => `--variable=${name}:${variables[name]}`
),
src.path,
];
const { stdout } = await exec(PLUGIN_NAME, "pandoc", args, {
encoding: "buffer",
cwd: input.cwd,
});
output.contents = stdout;
this.push(output);
}
);
}