Commit fb50d48d authored by Guillaume Perréal's avatar Guillaume Perréal
Browse files

Ajoute la génération du PDF.

parent 3c4b59e9
......@@ -4,6 +4,7 @@ import drawio from "./lib/drawio";
import index from "./lib/index";
import pandoc from "./lib/pandoc";
import server from "gulp-server-livereload";
import wkhtmltopdf from "./lib/wkhtmltopdf";
const SRC_DIR = process.env.SRC || "src";
const DEST_DIR = process.env.OUTPUT || "public";
......@@ -14,6 +15,7 @@ const ASSET_GLOB = [
];
const PREZ_GLOB = `${SRC_DIR}/**/index.md`;
const GRAPH_GLOB = `${SRC_DIR}/**/*.drawio`;
const PDF_GLOB = `${DEST_DIR}/**/index.html`;
export const clean = () => del(`${DEST_DIR}/**`);
......@@ -21,8 +23,9 @@ export const assets = () => src(ASSET_GLOB).pipe(dest(DEST_DIR));
export const graphs = () => src(GRAPH_GLOB).pipe(drawio()).pipe(dest(DEST_DIR));
export const prez = () =>
src(PREZ_GLOB).pipe(index()).pipe(pandoc()).pipe(dest(DEST_DIR));
export const pdf = () => src(PDF_GLOB).pipe(wkhtmltopdf()).pipe(dest(DEST_DIR));
export const build = series(clean, parallel(assets, prez, graphs));
export const build = series(clean, parallel(assets, prez, graphs), pdf);
const serve = () => {
src(DEST_DIR).pipe(
......@@ -34,13 +37,14 @@ const serve = () => {
);
};
const watch_prez = () => watch(PREZ_GLOB, { ignoreInitial: false }, prez);
const watch_assets = () => watch(ASSET_GLOB, { ignoreInitial: false }, assets);
const watch_graphs = () => watch(GRAPH_GLOB, { ignoreInitial: false }, graphs);
const watch_prez = () => watch(PREZ_GLOB, prez);
const watch_assets = () => watch(ASSET_GLOB, assets);
const watch_graphs = () => watch(GRAPH_GLOB, graphs);
const watch_pdf = () => watch(`${DEST_DIR}/**/*.{html,svg,jpg,gif,png}`, pdf);
export const dev = series(
clean,
parallel(serve, watch_prez, watch_assets, watch_graphs)
build,
parallel(serve, watch_prez, watch_assets, watch_graphs, watch_pdf)
);
export default build;
import { callbackify, promisify } from "util";
import child_process from "child_process";
import File from "vinyl";
import fs from "fs";
import logger from "gulplog";
import { mkTempFile } from "./tempdir";
import { obj } from "through2";
import os from "os";
import PluginError from "plugin-error";
const PLUGIN_NAME = "drawio";
const execFile = promisify(child_process.execFile);
const mkdir = promisify(fs.mkdir);
const DRAWIO_BINARY = process.env.DRAWIO_BINARY || "drawio";
export default function (options = {}) {
const verbose = options.verbose || false;
const tmpDir = fs.mkdtempSync(`${os.tmpdir()}/drawio-`) + "/";
const execFile = promisify(child_process.execFile);
export default function drawio() {
return obj(
callbackify(async function (input) {
try {
const output = new File({
path: tmpDir + input.relative,
base: tmpDir,
history: input.history,
contents: null,
});
const output = await mkTempFile(input);
output.extname = ".svg";
const args = [
......@@ -39,13 +30,13 @@ export default function (options = {}) {
input.path,
];
await mkdir(output.dirname, { recursive: true, mode: 0o700 });
logger.debug(PLUGIN_NAME, input.path, "=>", output.path);
const { stdout, stderr } = await execFile("drawio", args);
if (verbose) {
options.log("Done:", input.path);
const { stdout, stderr } = await execFile(DRAWIO_BINARY, args);
logger.info("%s: generated %s", PLUGIN_NAME, output.relative);
if (stdout.length > 0) {
logger.debug(PLUGIN_NAME, "stdout:", stdout);
logger.debug(PLUGIN_NAME, "stderr:", stderr);
}
if (stderr.length > 0) {
logger.info(PLUGIN_NAME, "stderr:", stderr);
}
output.contents = fs.createReadStream(output.path, {
......
......@@ -65,6 +65,28 @@ function parseYamlTitleBlock(text) {
);
}
/**
* @param {File} input
* @return {string}
*/
function getPrezFilename(input) {
const prez = input.clone({ deep: false, contents: false });
prez.extname = ".html";
return prez.relative;
}
/**
* @param {File} input
* @return {string}
*/
function getPdfFilename(input) {
const parent = new File({ path: input.dirname });
const pdf = input.clone({ deep: false, contents: false });
pdf.stem = parent.stem;
pdf.extname = ".pdf";
return pdf.relative;
}
function renderIndex(inputs) {
return `% Présentations
% Dev@Science
......@@ -85,13 +107,8 @@ function renderIndex(inputs) {
${inputs
.map(
(input) =>
`- [${input.titleBlock.title}](${input.relative.replace(
".md",
".html"
)})` +
`[<img class="plain icon" src="file_pdf.png"/>](${
input.dirname.substr(input.base.length + 1) + ".pdf"
})`
`- [${input.titleBlock.title}](${getPrezFilename(input)})` +
`[<img class="plain icon" src="file_pdf.png"/>](${getPdfFilename(input)})`
)
.join("\n")}`;
}
......@@ -122,6 +139,7 @@ export default function index() {
contents: Buffer.from(contents),
})
);
logger.info("%s: generated index.md", PLUGIN_NAME);
})
);
}
import del from "del";
import File from "vinyl";
import fs from "fs";
import logger from "gulplog";
import os from "os";
import { promisify } from "util";
const mkdtemp = promisify(fs.mkdtemp);
const mkdir = promisify(fs.mkdir);
let tmpDir = null;
const TMPDIR = process.env.TMPDIR || os.tmpdir();
/**
* @return {Promise<string>}
*/
export default function getTempDir() {
if (tmpDir === null) {
tmpDir = mkdtemp(TMPDIR + "/prezbuilder-").then((path) => {
path += "/";
logger.debug("Created temporary directory `%s`", path);
process.once("beforeExit", () => {
logger.debug("Removing temporary directory `%s`", path);
return del(path, { recursive: true, force: true });
});
return path;
});
}
return tmpDir;
}
/**
* @param {File} file
* @return {Promise<File>}
*/
export async function mkTempFile(file) {
const tmpDir = await getTempDir();
const tmpFile = new File({
history: file.history,
base: tmpDir,
path: tmpDir + file.relative,
});
await mkdir(tmpFile.dirname, { recursive: true, mode: 0o700 });
return tmpFile;
}
import { callbackify, promisify } from "util";
import child_process from "child_process";
import { createReadStream } from "fs";
import File from "vinyl";
import logger from "gulplog";
import { mkTempFile } from "./tempdir";
import { obj } from "through2";
import PluginError from "plugin-error";
const execFile = promisify(child_process.execFile);
const PLUGIN_NAME = "wkhtmltopdf";
const DEFAULT_OPTIONS = {
args: [
"--quiet",
"--orientation",
"Landscape",
"--page-size",
"A4",
"--background",
"--print-media-type",
"--enable-local-file-access",
"--margin-bottom",
"0",
"--margin-left",
"0",
"--margin-right",
"0",
"--margin-top",
"0",
],
};
const WKHTMLTOPDF_BINARY = process.env.WKHTMLTOPDF_BINARY || "wkhtmltopdf";
export default function wkhtmltopdf(options = {}) {
const { args } = Object.assign({}, DEFAULT_OPTIONS, options);
return obj(
callbackify(async function (input) {
try {
const output = await mkTempFile(input);
const parent = new File({ path: input.dirname });
output.stem = parent.stem;
output.extname = ".pdf";
const execArgs = [
...args,
`file://${input.path}?print-pdf`,
output.path,
];
const { stdout, stderr } = await execFile(WKHTMLTOPDF_BINARY, execArgs);
logger.info("%s: generated %s", PLUGIN_NAME, output.relative);
if (stdout.length > 0) {
logger.debug(PLUGIN_NAME, "stdout:", stdout);
}
if (stderr.length > 0) {
logger.debug(PLUGIN_NAME, "stderr:", stderr);
}
output.contents = createReadStream(output.path);
this.push(output);
} catch (err) {
throw new PluginError(PLUGIN_NAME, err, { filename: input.path });
}
})
);
}
......@@ -45,6 +45,7 @@
"es2017": true
},
"rules": {
"prettier/prettier": "warn",
"no-console": "warn",
"no-unused-vars": [
"error",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment