UNPKG

@argdown/node

Version:

Async Argdown application for node.js

73 lines 3.1 kB
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