diff options
Diffstat (limited to 'paste/include/geshi/classes/class.geshistringcontext.php')
-rw-r--r-- | paste/include/geshi/classes/class.geshistringcontext.php | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/paste/include/geshi/classes/class.geshistringcontext.php b/paste/include/geshi/classes/class.geshistringcontext.php new file mode 100644 index 0000000..1d712e5 --- /dev/null +++ b/paste/include/geshi/classes/class.geshistringcontext.php @@ -0,0 +1,190 @@ +<?php +/** + * GeSHi - Generic Syntax Highlighter + * + * For information on how to use GeSHi, please consult the documentation + * found in the docs/ directory, or online at http://geshi.org/docs/ + * + * This file is part of GeSHi. + * + * GeSHi is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GeSHi is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GeSHi; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * You can view a copy of the GNU GPL in the COPYING file that comes + * with GeSHi, in the docs/ directory. + * + * @package core + * @author Nigel McNie <nigel@geshi.org> + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL + * @copyright (C) 2005 Nigel McNie + * @version 1.1.0 + * + */ + +/** + * The GeSHiStringContext class. This class extends GeSHiContext to handle + * the concept of escape characters that strings often use. + * + * @package core + * @author Nigel McNie <nigel@geshi.org> + * @since 1.1.0 + * @version 1.1.0 + * @see GeSHiContext + */ +class GeSHiStringContext extends GeSHiContext +{ + /**#@- + * @access private + */ + var $_escapeCharacters; + + // Characters that should be escaped + var $_charsToEscape; + + /** + * This is used by the 'DELIM' "character" in the _charsToEscape array. We + * abuse the fact that _addParseData will be called right after _getContextEndData + * if the context is to be passed + */ + var $_lastOpener; + + /**#@-*/ + + /** + * GetContextEndData + */ + function _getContextEndData ($code, $context_open_key, $context_opener) + { + geshi_dbg('GeSHiStringContext::_getContextEndData(' . $this->_contextName . ', ' . $context_open_key . ', ' . $context_opener . ')', GESHI_DBG_API | GESHI_DBG_PARSE); + $this->_lastOpener = $context_opener; + + foreach ($this->_contextDelimiters[$context_open_key][1] as $ender) { + geshi_dbg(' Checking ender: ' . $ender, GESHI_DBG_PARSE); + + // Prepare ender regexes if needed + $ender = $this->_substitutePlaceholders($ender); + geshi_dbg(' ender after substitution: ' . $ender, GESHI_DBG_PARSE); + + $pos = 0; + while (true) { + $pos = geshi_get_position($code, $ender, $pos); + if (false === $pos) { + break; + } + $len = $pos['len']; + $pos = $pos['pos']; + + $possible_string = substr($code, 0, $pos); + geshi_dbg(' String might be: ' . $possible_string, GESHI_DBG_PARSE); + + foreach ($this->_escapeCharacters as $escape_char) { + // remove escaped escape characters + $possible_string = str_replace($escape_char . $escape_char, '', $possible_string); + } + + geshi_dbg(' String with double escapes removed: ' . $possible_string, GESHI_DBG_PARSE); + + //@todo [blocking 1.1.1] possible bug: only last escape character checked here + if (substr($possible_string, -1) != $escape_char) { + // We may have found the correct ender. If we haven't, then this string + // never ends and we will set the end position to the length of the code + // substr($code, $pos, 1) == $ender + $endpos = geshi_get_position($code, $ender, $pos); + geshi_dbg(' position of ender: ' . $endpos['pos'], GESHI_DBG_PARSE); + $pos = ($pos && $endpos['pos'] === $pos) ? $pos : strlen($code); + return array('pos' => $pos, 'len' => $len, 'dlm' => $ender); + } + // else, start further up + ++$pos; + } + } + return false; + } + + /** + * Overrides addParseData to add escape characters also + */ + function _addParseData ($code, $first_char_of_next_context = '') + { + geshi_dbg('GeSHiStringContext::_addParseData(' . substr($code, 0, 15) . '...)', GESHI_DBG_PARSE); + + $length = strlen($code); + $string = ''; + for ($i = 0; $i < $length; $i++) { + $char = substr($code, $i, 1); + geshi_dbg('Char: ' . $char, GESHI_DBG_PARSE); + $skip = false; + + foreach ($this->_escapeCharacters as $escape_char) { + $len = 1; + if ($char == $escape_char && (false !== ($len = $this->_shouldBeEscaped(substr($code, $i + 1))))) { + geshi_dbg('Match: len = ' . $len, GESHI_DBG_PARSE); + if ($string) { + $this->_styler->addParseData($string, $this->_contextName); + $string = ''; + } + // Needs a better name than /esc + $this->_styler->addParseData($escape_char . substr($code, $i + 1, $len), $this->_contextName . '/esc'); + // FastForward + $i += $len; + $skip = true; + break; + } + } + + if (!$skip) { + $string .= $char; + } + } + if ($string) { + $this->_styler->addParseData($string, $this->_contextName); + } + } + + /** + * Checks whether the character(s) at the start of the parameter string are + * characters that should be escaped. + * + * @param string The string to check the beginning of for escape characters + * @return int|false The length of the escape character sequence, else false + */ + function _shouldBeEscaped ($code) + { + // Feature: If 'DELIM' is one of the "characters" in the _charsToEscape array, then it is + // replaced by the context opener + $chars_to_escape = str_replace('DELIM', $this->_lastOpener, $this->_charsToEscape); + + geshi_dbg('Checking: ' . substr($code, 0, 15), GESHI_DBG_PARSE); + foreach ($chars_to_escape as $match) { + if ('REGEX' != substr($match, 0, 5)) { + geshi_dbg('Test: ' . $match, GESHI_DBG_PARSE); + if (substr($code, 0, 1) == $match) { + return 1; + } + } else { + geshi_dbg(' Testing via regex: ' . $match . '... ', GESHI_DBG_PARSE, false); + $data = geshi_get_position($code, $match, 0); + if (0 === $data['pos']) { + geshi_dbg('match, data = ' . print_r($data, true), GESHI_DBG_PARSE); + return $data['len']; + } + geshi_dbg('no match', GESHI_DBG_PARSE); + } + } + // No matches... + return false; + } +} + +?> |