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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import * as fs from "fs";
import { promisify } from "util";
const readFileAsync = promisify(fs.readFile);
let path = require("path");
import * as _ from "lodash";
import { IAsyncArgdownPlugin, IAsyncRequestHandler } from "../IAsyncArgdownPlugin";
import { IArgdownRequest, IRequestHandler, ArgdownPluginError } from "@argdown/core";
import { IFileRequest } from "../IFileRequest";
export interface IIncludeSettings {
regEx?: RegExp;
}
export interface IIncludeRequest {
include?: IIncludeSettings;
}
export class IncludePlugin implements IAsyncArgdownPlugin {
name = "IncludePlugin";
defaults: IIncludeSettings;
constructor(config?: IIncludeSettings) {
this.defaults = _.defaultsDeep({}, config, {
regEx: /@include\(([^\)]+)\)/g
});
}
getSettings = (request: IArgdownRequest): IIncludeSettings => {
const r = <IIncludeRequest>request;
r.include = r.include || {};
return r.include;
};
prepare: IRequestHandler = request => {
_.defaultsDeep(this.getSettings(request), this.defaults);
};
runAsync: IAsyncRequestHandler = async request => {
if (!request.input) {
throw new ArgdownPluginError(this.name, "Missing input.");
}
if (!(<IFileRequest>request).inputPath) {
throw new ArgdownPluginError(this.name, "Missing input path.");
}
const fileRequest = <IFileRequest>request;
const settings = this.getSettings(request);
settings.regEx!.lastIndex = 0;
request.input = await this.replaceIncludesAsync(fileRequest.inputPath!, request.input!, settings.regEx!, []);
};
async replaceIncludesAsync(currentFilePath: string, str: string, regEx: RegExp, filesAlreadyIncluded: string[]) {
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);
strToInclude = await readFileAsync(absoluteFilePath, "utf8");
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;
}
}
|