UNPKG

jscc

Version:

Tiny and powerful preprocessor for conditional comments and replacement of compile-time variables in text files

118 lines 3.96 kB
"use strict"; const remapVars = require("./remap-vars"); /** * Matches line-ending of win, mac, and unix type */ const EOLS = /[^\r\n]+/g; /** * Helper class for the `parseChunks` function. */ class ParseHelper { /** * @param source Original source * @param props jscc properties */ constructor(source, props) { this.source = source; this.props = props; this.lastPos = 0; // keep the next offset to flush this.output = true; // output state, starts "active" } /** * Final flush. The final output is always in "active" state. */ flush() { return this.commit(this.lastPos, this.source.length); } /** * Write pending changes. * * _IMPORTANT:_ `Parser.parse` can change the current jscc values, * so this function _MUST BE_ called before the parsing to make any * replacements with the current values. * * @param offset Starting position of the matched line */ flushPrev(offset) { if (this.output) { this.commit(this.lastPos, offset); } } /** * A line was processed, flush buffers as necessary. * * @param start Starting position of the chunk into the original buffer * @param end Position of the character following the chunk * @param output The updated output state * @returns The updated position where to continue the search. */ flushLine(start, end, output) { // Find the start of the next line in the buffer. if (end < this.source.length) { end += this.source.substr(end, 2) === '\r\n' ? 2 : 1; } if (output !== this.output) { this.output = output; this.flushit(start, end); } else if (output) { // flushPrev was already called, so no need to commit this.remove(start, end); } return end; } /** * If the parsed `chunk` seems to contain varnames to replace, call the * remapVars function which will make the replacement and store the chunk * into the MagicString intance. Otherwise, do nothing. * * _NOTE:_ This function updates `this.lastPos` * * @param start Starting position of the chunk into the original buffer * @param end Position of the character following the chunk * @returns `true` if the chunk was changed */ commit(start, end) { if (start >= end) { return false; } this.lastPos = end; // Get the fragment of source where to search varnames to replace const chunk = this.source.slice(start, end); // Call remapVars only if a memvar prefix exists in the chunk return chunk.indexOf('$_') > -1 && remapVars(this.props, chunk, start); } /** * Removes the block from the `start` to the `end` position, inclusive. * * _NOTE:_ This function updates `this.lastPos` * * @param start Starting position of the chunk into the original buffer * @param end Position of the character following the chunk * @returns Position of the character following the removed block. */ remove(start, end) { this.lastPos = end; const block = this.props.keepLines ? this.source.slice(start, end).replace(EOLS, '') : ''; this.props.magicStr.overwrite(start, end, block); } /** * The output state changed, flush the buffer. * * @param start Start of current line * @param end End of current line */ flushit(start, end) { if (this.output) { // Output begins, remove previous hidden block. this.remove(this.lastPos, end); } else { // Output ends, flush the already processed block. this.commit(this.lastPos, start); } } } module.exports = ParseHelper; //# sourceMappingURL=parse-helper.js.map