0a6bf1372f0ce2e62f6545996f66f625af6ed530.svn-base 1.75 KB
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;

var _stringLength = _interopRequireDefault(require("string-length"));

var _sliceAnsi = _interopRequireDefault(require("slice-ansi"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

/**
 * "Virtual" output class
 *
 * Handles the positioning and saving of the output of each node in the tree.
 * Also responsible for applying transformations to each character of the output.
 *
 * Used to generate the final output of all nodes before writing it to actual output stream (e.g. stdout)
 */
class Output {
  constructor({
    width,
    height
  }) {
    // Initialize output array with a specific set of rows, so that margin/padding at the bottom is preserved
    const output = [];

    for (let y = 0; y < height; y++) {
      output.push(' '.repeat(width));
    }

    this.output = output;
  }

  write(x, y, text, {
    transformers
  }) {
    if (!text) {
      return;
    }

    const lines = text.split('\n');
    let offsetY = 0;

    for (let line of lines) {
      const length = (0, _stringLength.default)(line);
      const currentLine = this.output[y + offsetY]; // Line can be missing if `text` is taller than height of pre-initialized `this.output`

      if (!currentLine) {
        continue;
      }

      for (const transformer of transformers) {
        line = transformer(line);
      }

      this.output[y + offsetY] = (0, _sliceAnsi.default)(currentLine, 0, x) + line + (0, _sliceAnsi.default)(currentLine, x + length);
      offsetY++;
    }
  }

  get() {
    return this.output.map(line => line.trimRight()).join('\n');
  }

  getHeight() {
    return this.output.length;
  }

}

exports.default = Output;