@argdown/node
Version:
Async Argdown application for node.js
73 lines • 3.1 kB
JavaScript
import * as fs from "fs";
import { promisify } from "util";
const readFileAsync = promisify(fs.readFile);
let path = require("path");
import defaultsDeep from "lodash.defaultsdeep";
import includes from "lodash.includes";
import { ArgdownPluginError } from "@argdown/core";
export class IncludePlugin {
constructor(config) {
this.name = "IncludePlugin";
this.getSettings = (request) => {
request.include = request.include || {};
return request.include;
};
this.prepare = request => {
defaultsDeep(this.getSettings(request), this.defaults);
};
this.runAsync = async (request) => {
if (!request.input) {
throw new ArgdownPluginError(this.name, "missing-input-request-field", "Missing input.");
}
if (!request.inputPath) {
throw new ArgdownPluginError(this.name, "missing-inputPath-request-field", "Missing input path.");
}
const settings = this.getSettings(request);
settings.regEx.lastIndex = 0;
request.input = await this.replaceIncludesAsync(request.inputPath, request.input, settings.regEx, []);
};
this.defaults = defaultsDeep({}, config, {
regEx: /@include\(([^\)]+)\)/g
});
}
async replaceIncludesAsync(currentFilePath, str, regEx, filesAlreadyIncluded) {
let match = null;
const directoryPath = path.dirname(currentFilePath);
regEx.lastIndex = 0;
while ((match = regEx.exec(str))) {
const absoluteFilePath = path.resolve(directoryPath, match[1]);
let strToInclude = "";
if (includes(filesAlreadyIncluded, absoluteFilePath)) {
strToInclude =
"<!-- Include failed: File '" +
absoluteFilePath +
"' already included. To avoid infinite loops, each file can only be included once. -->";
}
else {
filesAlreadyIncluded.push(absoluteFilePath);
try {
strToInclude = await readFileAsync(absoluteFilePath, "utf8");
}
catch (e) {
throw new ArgdownPluginError(this.name, "file-not-found", `'${absoluteFilePath}' not found.`);
}
if (strToInclude == null) {
strToInclude =
"<!-- Include failed: File '" +
absoluteFilePath +
"' not found. -->\n";
}
else {
strToInclude = await this.replaceIncludesAsync(absoluteFilePath, strToInclude, regEx, filesAlreadyIncluded);
}
}
str =
str.substr(0, match.index) +
strToInclude +
str.substr(match.index + match[0].length);
regEx.lastIndex = match.index + strToInclude.length;
}
return str;
}
}
//# sourceMappingURL=IncludePlugin.js.map