diff options
Diffstat (limited to 'release/build/js/ParseMaster.js')
-rw-r--r-- | release/build/js/ParseMaster.js | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/release/build/js/ParseMaster.js b/release/build/js/ParseMaster.js new file mode 100644 index 000000000..915a8b5db --- /dev/null +++ b/release/build/js/ParseMaster.js @@ -0,0 +1,106 @@ +/* + ParseMaster, version 1.0.2 (2005-08-19) + Copyright 2005, Dean Edwards + License: http://creativecommons.org/licenses/LGPL/2.1/ +*/ + +/* a multi-pattern parser */ + +// KNOWN BUG: erroneous behavior when using escapeChar with a replacement value that is a function + +function ParseMaster() { + // constants + var $EXPRESSION = 0, $REPLACEMENT = 1, $LENGTH = 2; + // used to determine nesting levels + var $GROUPS = /\(/g, $SUB_REPLACE = /\$\d/, $INDEXED = /^\$\d+$/, + $TRIM = /(['"])\1\+(.*)\+\1\1$/, $$ESCAPE = /\\./g, $QUOTE = /'/, + $$DELETED = /\x01[^\x01]*\x01/g; + var self = this; + // public + this.add = function($expression, $replacement) { + if (!$replacement) $replacement = ""; + // count the number of sub-expressions + // - add one because each pattern is itself a sub-expression + var $length = (_internalEscape(String($expression)).match($GROUPS) || "").length + 1; + // does the pattern deal with sub-expressions? + if ($SUB_REPLACE.test($replacement)) { + // a simple lookup? (e.g. "$2") + if ($INDEXED.test($replacement)) { + // store the index (used for fast retrieval of matched strings) + $replacement = parseInt($replacement.slice(1)) - 1; + } else { // a complicated lookup (e.g. "Hello $2 $1") + // build a function to do the lookup + var i = $length; + var $quote = $QUOTE.test(_internalEscape($replacement)) ? '"' : "'"; + while (i) $replacement = $replacement.split("$" + i--).join($quote + "+a[o+" + i + "]+" + $quote); + $replacement = new Function("a,o", "return" + $quote + $replacement.replace($TRIM, "$1") + $quote); + } + } + // pass the modified arguments + _add($expression || "/^$/", $replacement, $length); + }; + // execute the global replacement + this.exec = function($string) { + _escaped.length = 0; + return _unescape(_escape($string, this.escapeChar).replace( + new RegExp(_patterns, this.ignoreCase ? "gi" : "g"), _replacement), this.escapeChar).replace($$DELETED, ""); + }; + // clear the patterns collection so that this object may be re-used + this.reset = function() { + _patterns.length = 0; + }; + + // private + var _escaped = []; // escaped characters + var _patterns = []; // patterns stored by index + var _toString = function(){return "(" + String(this[$EXPRESSION]).slice(1, -1) + ")"}; + _patterns.toString = function(){return this.join("|")}; + // create and add a new pattern to the patterns collection + function _add() { + arguments.toString = _toString; + // store the pattern - as an arguments object (i think this is quicker..?) + _patterns[_patterns.length] = arguments; + } + // this is the global replace function (it's quite complicated) + function _replacement() { + if (!arguments[0]) return ""; + var i = 1, j = 0, $pattern; + // loop through the patterns + while ($pattern = _patterns[j++]) { + // do we have a result? + if (arguments[i]) { + var $replacement = $pattern[$REPLACEMENT]; + switch (typeof $replacement) { + case "function": return $replacement(arguments, i); + case "number": return arguments[$replacement + i]; + } + var $delete = (arguments[i].indexOf(self.escapeChar) == -1) ? "" : + "\x01" + arguments[i] + "\x01"; + return $delete + $replacement; + // skip over references to sub-expressions + } else i += $pattern[$LENGTH]; + } + }; + // encode escaped characters + function _escape($string, $escapeChar) { + return $escapeChar ? $string.replace(new RegExp("\\" + $escapeChar + "(.)", "g"), function($match, $char) { + _escaped[_escaped.length] = $char; + return $escapeChar; + }) : $string; + }; + // decode escaped characters + function _unescape($string, $escapeChar) { + var i = 0; + return $escapeChar ? $string.replace(new RegExp("\\" + $escapeChar, "g"), function() { + return $escapeChar + (_escaped[i++] || ""); + }) : $string; + }; + function _internalEscape($string) { + return $string.replace($$ESCAPE, ""); + }; +}; +ParseMaster.prototype = { + constructor: ParseMaster, + ignoreCase: false, + escapeChar: "" +}; |