Pre-release
AdventureJS Docs Downloads
Score: 0 Moves: 0
// dehydrateStrings.js

(function () {
  /* global AdventureJS A */

  var p = AdventureJS.Parser.prototype;

  /**
   * Dehydration is a temporary step where we convert
   * quoted substrings to simple symbols. Example:
   * 'type "foo" on keyboard' => `type $0 on keyboard`
   * We do this to preserve the contents of the substring
   * exactly as entered rather than subjecting them to
   * interpretation, even across queued turns.
   * @memberOf AdventureJS.Parser
   * @method AdventureJS.Parser#dehydrateStrings
   * @param {String} input
   * @returns {String|Boolean}
   * @TODO escape $ in input
   */
  p.dehydrateStrings = function Parser_dehydrateStrings(input) {
    this.game.log(
      "L1603",
      "log",
      "high",
      `[dehydrateStrings.js] dehydrateStrings() receive: ${input}`,
      "Parser"
    );

    const this_turn = this.input_history[0];

    const replaceRange = function (str, start, end, replacement) {
      this_turn.quote_tokens[replacement] = input.slice(start, end);
      return str.slice(0, start) + replacement + str.slice(end);
    };

    let quoted_ranges = [];
    let quote = null;
    let start = null;

    for (let i = 0; i < input.length; i++) {
      const char = input[i];

      if (!quote) {
        // opening quote
        if (
          (char === '"' || char === "'") &&
          (i === 0 || /\s/.test(input[i - 1]))
        ) {
          quote = char;
          start = i;
        }
      } else {
        // match closing quote only
        if (
          char === quote &&
          (i === input.length - 1 || /\s/.test(input[i + 1]))
        ) {
          quoted_ranges.push([start, i]);
          quote = null;
          start = null;
        }
      }
    } // if !quote

    // check for unbalanced quotes
    for (let block in quoted_ranges) {
      let pair = quoted_ranges[block];
      if (pair.length !== 2) {
        let msg = `There appears to be an unclosed double quote in that input. Please try again. `;
        this.game.log(
          "L1595",
          "warn",
          "high",
          `[dehydrateStrings.js] found uneven quotes in ${input}`,
          "Parser"
        );
        this.game.display.printInput(input);
        this.game.debug(
          `D1632`,
          `dehydrateStrings.js `,
          `found uneven quotes in ${input}`
        );
        this.game.print(msg);
        return false;
      }
    }

    for (let i = quoted_ranges.length - 1; i > -1; i--) {
      input = replaceRange(
        input,
        quoted_ranges[i][0],
        quoted_ranges[i][1] + 1,
        `$${i}`
      );
    }

    this.game.log(
      "L1604",
      "log",
      "high",
      `[dehydrateStrings.js] dehydrateStrings() return: ${input}`,
      "Parser"
    );
    return input;
  };
})();