Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | // We have to use a local file and let babel ignore it, until pdfkit is ported to ES6
var PDFDocument = require("../pdfkit.js");
var fs = require("fs");
let path = require("path");
let mkdirp = require("mkdirp");
import * as SVGtoPDF from "svg-to-pdfkit";
import * as _ from "lodash";
import { IAsyncArgdownPlugin, IAsyncRequestHandler } from "../IAsyncArgdownPlugin";
import { IArgdownRequest, IRequestHandler, ArgdownPluginError } from "@argdown/core";
import { ISvgResponse } from "./DotToSvgExportPlugin";
import { IFileRequest } from "../IFileRequest";
import { IFileNameProvider } from "./SaveAsFilePlugin";
export interface IPdfSettings {
outputDir?: string;
}
export interface IPdfRequest {
pdf?: IPdfSettings;
}
export interface ISvgToPdfSettings {
outputDir?: string;
format?: string;
fileName?: string | IFileNameProvider;
}
export interface ISvgToPdfRequest extends IArgdownRequest {
svgToPdf?: ISvgToPdfSettings;
}
export class SvgToPdfExportPlugin implements IAsyncArgdownPlugin {
name = "SvgToPdfExportPlugin";
defaults: ISvgToPdfSettings;
constructor(config?: ISvgToPdfSettings) {
this.defaults = _.defaultsDeep({}, config, {
outputDir: "./pdf",
format: "svg"
});
}
getSettings(request: IArgdownRequest): ISvgToPdfSettings {
const r = <ISvgToPdfRequest>request;
r.svgToPdf = r.svgToPdf || {};
return r.svgToPdf;
}
prepare: IRequestHandler = (request, response) => {
if (!(<ISvgResponse>response).svg) {
throw new ArgdownPluginError(this.name, "Missing svg field in response.");
}
_.defaults(this.getSettings(request), this.defaults);
};
runAsync: IAsyncRequestHandler = async (request, response) => {
const settings = this.getSettings(request);
let fileName = "default";
let outputDir = settings.outputDir;
const fileRequest = <IFileRequest>request;
const pdfRequest = <IPdfRequest>request;
if (fileRequest.outputDir) {
fileName = this.getFileName(fileRequest.outputDir);
outputDir = path.dirname(fileRequest.outputDir);
} else if (pdfRequest.pdf && pdfRequest.pdf.outputDir) {
fileName = this.getFileName(pdfRequest.pdf.outputDir);
outputDir = path.dirname(pdfRequest.pdf.outputDir);
} else if (_.isFunction(settings.fileName)) {
fileName = settings.fileName.call(this, request, response);
} else if (_.isString(settings.fileName)) {
fileName = settings.fileName;
} else if (fileRequest.inputPath) {
fileName = this.getFileName(fileRequest.inputPath);
}
const absoluteOutputDir = path.resolve(process.cwd(), outputDir);
const filePath = absoluteOutputDir + "/" + fileName + ".pdf";
await new Promise((resolve, reject) => {
mkdirp(absoluteOutputDir, function(err: Error) {
if (err) {
reject(err);
}
resolve();
});
});
const svgResponse = <ISvgResponse>response;
const doc = new PDFDocument(settings);
SVGtoPDF(doc, svgResponse.svg, 0, 0, settings);
await this.savePdfToFile(doc, filePath);
};
// https://github.com/devongovett/pdfkit/issues/265
async savePdfToFile(pdf: any, fileName: string) {
return new Promise(resolve => {
// To determine when the PDF has finished being written successfully
// we need to confirm the following 2 conditions:
//
// 1. The write stream has been closed
// 2. PDFDocument.end() was called syncronously without an error being thrown
let pendingStepCount = 2;
const stepFinished = () => {
if (--pendingStepCount == 0) {
resolve();
}
};
const writeStream = fs.createWriteStream(fileName);
writeStream.on("close", stepFinished);
pdf.pipe(writeStream);
pdf.end();
stepFinished();
});
}
getFileName(file: string): string {
let extension = path.extname(file);
return path.basename(file, extension);
}
}
|