UNPKG

gulp-emu

Version:
279 lines 12.9 kB
"use strict"; /*! * Copyright 2021 Ron Buckton (rbuckton@chronicles.org) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; const async_countdown_1 = require("@esfx/async-countdown"); const async_queue_1 = require("@esfx/async-queue"); const fs = require("fs"); const path = require("path"); const stream_1 = require("stream"); const ecmarkupModule_1 = require("./ecmarkupModule"); const PluginError = require("plugin-error"); const Vinyl = require("vinyl"); function ecmarkup(opts) { return new ecmarkup.EcmarkupTransform(opts); } (function (ecmarkup) { class EcmarkupTransform extends stream_1.Transform { constructor(opts = {}) { var _a, _b, _c, _d, _e; super({ objectMode: true }); this._queue = new async_queue_1.AsyncQueue(); this._countdown = new async_countdown_1.AsyncCountdownEvent(1); this._cache = new Map(); this._ecmarkup = ecmarkupModule_1.getEcmarkupModule(); this._opts = { js: (_b = (_a = pluck(opts, "js")) !== null && _a !== void 0 ? _a : pluck(opts, "jsOut")) !== null && _b !== void 0 ? _b : false, css: (_d = (_c = pluck(opts, "css")) !== null && _c !== void 0 ? _c : pluck(opts, "cssOut")) !== null && _d !== void 0 ? _d : false, biblio: (_e = pluck(opts, "biblio")) !== null && _e !== void 0 ? _e : false, assetsDir: pluck(opts, "assetsDir"), }; this._emuOpts = Object.assign({}, opts); delete this._emuOpts.outfile; delete this._emuOpts.cssOut; delete this._emuOpts.jsOut; delete this._emuOpts.assetsDir; if (this._emuOpts.multipage) { if (this._opts.js) { throw new Error("Cannot use 'multipage' with 'js'"); } if (this._opts.css) { throw new Error("Cannot use 'multipage' with 'css'"); } } switch (this._ecmarkup.mode) { case "v18": // ecmarkup v18 removes `jsOut` & `cssOut` in favor of `assetsDir` if (this._opts.js) { throw new Error(`Cannot use 'js' or 'jsOut' option with ecmarkup@v18 or later. Specify 'assets: "external"' and use 'assetsDir' instead.`); } if (this._opts.css) { throw new Error(`Cannot use 'css' or 'cssOut' option with ecmarkup@v18 or later. Specify 'assets: "external"' and use 'assetsDir' instead.`); } if (this._emuOpts.multipage) { this._emuOpts.outfile = ""; } break; case "v7": // ecmarkup v7 adds js and css outputs to `generatedFiles` if (this._emuOpts.multipage) { this._emuOpts.outfile = ""; } if (typeof this._opts.js === "string") { this._emuOpts.jsOut = this._opts.js; } else if (this._opts.js) { this._emuOpts.jsOut = "ecmarkup.js"; } else if (this._opts.assetsDir) { this._emuOpts.jsOut = path.join(this._opts.assetsDir, "ecmarkup.js"); } if (typeof this._opts.css === "string") { this._emuOpts.cssOut = this._opts.css; } else if (this._opts.css) { this._emuOpts.cssOut = "ecmarkup.css"; } else if (this._opts.assetsDir) { this._emuOpts.cssOut = path.join(this._opts.assetsDir, "ecmarkup.css"); } break; case "v3": if (this._emuOpts.multipage) { throw new Error("'multipage' requires ecmarkup >= v7.0.0"); } break; } this._waitForWrite(); } get ecmarkupVersion() { return this._ecmarkup.version; } _write(file, enc, cb) { if (file.isNull()) { return cb(); } if (file.isStream()) { throw new PluginError("gulp-emu", "Stream not supported."); } // cache the file contents this._cache.set(file.path, file.contents.toString("utf8")); // put an entry into the queue for the transformation this._enqueue(this._buildAsync(file)); cb(); } _flush(cb) { switch (this._ecmarkup.mode) { case "v3": { const files = []; // add extra files const css = this._opts.css; if (css) { const dest = typeof css === "string" ? css : "elements.css"; files.push({ src: [path.join(this._ecmarkup.path, "css/elements.css")], dest }); } const js = this._opts.js; if (js) { if (typeof js === "string") { files.push({ src: [ path.join(this._ecmarkup.path, "js/menu.js"), path.join(this._ecmarkup.path, "js/findLocalReferences.js") ], dest: js }); } else { files.push({ src: [path.join(this._ecmarkup.path, "js/menu.js")], dest: "menu.js" }); files.push({ src: [path.join(this._ecmarkup.path, "js/findLocalReferences.js")], dest: "findLocalReferences.js" }); } } if (files.length) { this._enqueue(this._readFilesAsync(files)); } } } this._countdown.signal(); this._countdown.wait() .then(() => cb()) .catch(e => this.emit("error", e)); } _enqueue(promise) { this._countdown.add(); this._queue.put(promise); } _finishWrite(files) { for (const file of files) { this.push(file); } this._countdown.signal(); this._waitForWrite(); } _waitForWrite() { this._queue.get().then(file => this._finishWrite(file), e => this.emit("error", e)); } _buildAsync(file) { var _a, _b; return __awaiter(this, void 0, void 0, function* () { const files = []; const opts = Object.assign({}, this._emuOpts); (_a = opts.log) !== null && _a !== void 0 ? _a : (opts.log = msg => { console.log("ecmarkup:", msg); }); (_b = opts.warn) !== null && _b !== void 0 ? _b : (opts.warn = err => { console.warn(err.message); }); const spec = yield this._ecmarkup.module.build(file.path, path => this._readFileAsync(path), this._emuOpts); if (spec) { if (this._opts.biblio) { const dirname = path.dirname(file.path); const extname = path.extname(file.path); const basename = path.basename(file.path, extname); const biblio = new Vinyl({ path: path.join(dirname, basename + ".biblio.json"), base: file.base, contents: Buffer.from(JSON.stringify(spec.exportBiblio(), undefined, " "), "utf8") }); files.push(biblio); } switch (this._ecmarkup.mode) { case "v18": case "v7": if (!isMultiPageSpec(spec)) throw new TypeError("Cannot read spec output."); const dirname = path.dirname(file.path); for (const [filename, contents] of spec.generatedFiles) { if (filename === null) { file.contents = Buffer.from(contents, "utf8"); files.push(file); } else { const output = new Vinyl({ path: path.join(dirname, filename), base: file.base, contents: Buffer.from(contents, "utf8") }); files.push(output); } } break; case "v3": if (!isSinglePageSpec(spec)) throw new TypeError("Cannot read spec output."); file.contents = Buffer.from(spec.toHTML(), "utf8"); files.push(file); break; } } return files; }); } _readFilesAsync(files) { return __awaiter(this, void 0, void 0, function* () { return yield Promise.all(files.map(file => this._mergeFilesAsync(file))); }); } _mergeFilesAsync(file) { return __awaiter(this, void 0, void 0, function* () { const srcContents = yield Promise.all(file.src.map(src => this._readFileAsync(src))); const contents = srcContents.join(""); const base = path.dirname(file.src[0]); return new Vinyl({ path: path.join(base, file.dest), base, contents: Buffer.from(contents, "utf8") }); }); } _readFileAsync(path) { return __awaiter(this, void 0, void 0, function* () { let contents = this._cache.get(path); if (!contents) { contents = yield readFile(path, "utf8"); this._cache.set(path, contents); } return contents; }); } } ecmarkup.EcmarkupTransform = EcmarkupTransform; })(ecmarkup || (ecmarkup = {})); function readFile(file, encoding) { return new Promise((resolve, reject) => { fs.readFile(file, encoding, (err, data) => err ? reject(err) : resolve(data)); }); } function pluck(obj, key) { const value = obj[key]; delete obj[key]; return value; } function isSinglePageSpec(spec) { return typeof spec.toHTML === "function"; } function isMultiPageSpec(spec) { return typeof spec.generatedFiles === "object"; } module.exports = ecmarkup; //# sourceMappingURL=index.js.map