// sanitizeInput.js
(function () {
/*global adventurejs A*/
var p = adventurejs.Parser.prototype;
/**
* <ul>
* <li>toLowerCase(), excluding quoted text</li>
* <li>strip trailing "."</li>
* <li>replace tabs with spaces</li>
* <li>trim()</li>
* <li>reduce multiple spaces to single</li>
* <li>replace " and then " with " then "</li>
* <li>split by periods</li>
* <li>split by "then"</li>
* <li>check for "again"</li>
* </ul>
* @memberOf adventurejs.Parser
* @method adventurejs.Parser#sanitizeInput
* @param {String} parsed_input
* @param {String} unparsed_input
* @returns {Array} [string, string]
*/
p.sanitizeInput = function Parser_sanitizeInput(
parsed_input,
unparsed_input
) {
//this.game.log( "log", "high", "sanitizeInput.js > receive: " + parsed_input , 'Parser' );
// we're going to convert to lower case, but exempt quoted substrings
// ie 'Yell "WILHELM!"'
let quoted = false;
let cased_input = "";
for (let i = 0; i < parsed_input.length; i++) {
const char = parsed_input[i];
if (char === '"') {
quoted = !quoted; // Toggle the flag when encountering quotes
}
if (quoted) {
cased_input += char; // Keep the characters inside quotes unchanged
} else {
cased_input += char.toLowerCase(); // Convert characters outside quotes to lowercase
}
}
parsed_input = cased_input;
if (parsed_input[parsed_input.length - 1] === ".") {
// strip trailing period
parsed_input = parsed_input.slice(0, -1);
}
// convert tabs to spaces
parsed_input = parsed_input.replace(/\t/g, " ");
parsed_input = parsed_input.trim();
// replace multiple spaces with single
parsed_input = parsed_input.replace(/\s+/g, " ");
// replace " and then " with " then "
parsed_input = parsed_input.replace(/ and then /g, " then ");
var periodArray = this.splitByPeriods(parsed_input);
var thenArray = this.splitByThens(parsed_input);
var pushArray = [];
/**
* We're assuming that phrases
* ending in periods might include 'then',
* but that phrases joined by 'then'
* don't have internal periods.
*
* Ex:
* Go north then take thing then drop thing.
* vs:
* Go North. Take thing then drop thing.
*
* splitByPeriods recursively tries splitByThens,
* but splitByThens doesn't try splitByPeriods.
*/
if (periodArray.length > 1) {
pushArray = periodArray;
} else if (thenArray.length > 1) {
pushArray = thenArray;
}
if (0 === pushArray.length) {
// single clause found, use input as is
// did player enter "again" ?
// if so, copy last turn into this turn
if (this.game.dictionary.testVerbSynonyms(parsed_input, "again")) {
// var msg = "$(We) haven't done anything that bears repeating. ";
// if(msg) this.game.print( msg, "" );
// return null;
parsed_input = unparsed_input = this.game.parser.input_history[0].input;
}
} else if (pushArray.length > 0) {
// player entered multiple clauses
// is first item in queue "again"?
// replace with last turn
if (this.game.dictionary.testVerbSynonyms(pushArray[0], "again")) {
pushArray[0] = this.game.parser.input_history[0].input;
}
// is any other item in queue "again"?
// replace with the turn preceding it in the queue
for (var i = 1; i < pushArray.length; i++) {
if (this.game.dictionary.testVerbSynonyms(pushArray[i], "again")) {
pushArray[i] = pushArray[i - 1];
}
}
// use the first one now
parsed_input = unparsed_input = pushArray.shift();
// queue up the rest for subsequent turns
for (var i = 0; i < pushArray.length; i++) {
this.input_queue.push({
input: pushArray[i],
printInput: true,
});
}
}
this.game.log(
"L1092",
"log",
"high",
`sanitizeInput.js > return parsed: ${parsed_input}, unparsed: ${unparsed_input}`,
"Parser"
);
return [parsed_input, unparsed_input];
};
})();