📄 geshi.php
字号:
if ($this->enable_important_blocks) { $this->language_data['COMMENT_MULTI'][GESHI_START_IMPORTANT] = GESHI_END_IMPORTANT; } if ($this->strict_mode) { // Break the source into bits. Each bit will be a portion of the code // within script delimiters - for example, HTML between < and > $parts = array(0 => array(0 => '')); $k = 0; for ($i = 0; $i < $length; $i++) { $char = substr($code, $i, 1); if (!$HIGHLIGHTING_ON) { foreach ($this->language_data['SCRIPT_DELIMITERS'] as $key => $delimiters) { foreach ($delimiters as $open => $close) { // Get the next little bit for this opening string $check = substr($code, $i, strlen($open)); // If it matches... if ($check == $open) { // We start a new block with the highlightable // code in it $HIGHLIGHTING_ON = $open; $i += strlen($open) - 1; $char = $open; $parts[++$k][0] = $char; // No point going around again... break(2); } } } } else { foreach ($this->language_data['SCRIPT_DELIMITERS'] as $key => $delimiters) { foreach ($delimiters as $open => $close) { if ($open == $HIGHLIGHTING_ON) { // Found the closing tag break(2); } } } // We check code from our current position BACKWARDS. This is so // the ending string for highlighting can be included in the block $check = substr($code, $i - strlen($close) + 1, strlen($close)); if ($check == $close) { $HIGHLIGHTING_ON = ''; // Add the string to the rest of the string for this part $parts[$k][1] = ( isset($parts[$k][1]) ) ? $parts[$k][1] . $char : $char; $parts[++$k][0] = ''; $char = ''; } } $parts[$k][1] = ( isset($parts[$k][1]) ) ? $parts[$k][1] . $char : $char; } $HIGHLIGHTING_ON = ''; } else { // Not strict mode - simply dump the source into // the array at index 1 (the first highlightable block) $parts = array( 1 => array( 0 => '', 1 => $code ) ); } // Now we go through each part. We know that even-indexed parts are // code that shouldn't be highlighted, and odd-indexed parts should // be highlighted foreach ($parts as $key => $data) { $part = $data[1]; // If this block should be highlighted... if ($key % 2) { if ($this->strict_mode) { // Find the class key for this block of code foreach ($this->language_data['SCRIPT_DELIMITERS'] as $script_key => $script_data) { foreach ($script_data as $open => $close) { if ($data[0] == $open) { break(2); } } } if ($this->language_data['STYLES']['SCRIPT'][$script_key] != '' && $this->lexic_permissions['SCRIPT']) { // Add a span element around the source to // highlight the overall source block if (!$this->use_classes && $this->language_data['STYLES']['SCRIPT'][$script_key] != '') { $attributes = ' style="' . $this->language_data['STYLES']['SCRIPT'][$script_key] . '"'; } else { $attributes = ' class="sc' . $script_key . '"'; } $result .= "<span$attributes>"; $STRICTATTRS = $attributes; } } if (!$this->strict_mode || $this->language_data['HIGHLIGHT_STRICT_BLOCK'][$script_key]) { // Now, highlight the code in this block. This code // is really the engine of GeSHi (along with the method // parse_non_string_part). $length = strlen($part); for ($i = 0; $i < $length; $i++) { // Get the next char $char = substr($part, $i, 1); $hq = isset($this->language_data['HARDQUOTE']) ? $this->language_data['HARDQUOTE'][0] : false; // Is this char the newline and line numbers being used? if (($this->line_numbers != GESHI_NO_LINE_NUMBERS || count($this->highlight_extra_lines) > 0) && $char == "\n") { // If so, is there a string open? If there is, we should end it before // the newline and begin it again (so when <li>s are put in the source // remains XHTML compliant) // note to self: This opens up possibility of config files specifying // that languages can/cannot have multiline strings??? if ($STRING_OPEN) { if (!$this->use_classes) { $attributes = ' style="' . $this->language_data['STYLES']['STRINGS'][0] . '"'; } else { $attributes = ' class="st0"'; } $char = '</span>' . $char . "<span$attributes>"; } } else if ($char == $STRING_OPEN) { // A match of a string delimiter if (($this->lexic_permissions['ESCAPE_CHAR'] && $ESCAPE_CHAR_OPEN) || ($this->lexic_permissions['STRINGS'] && !$ESCAPE_CHAR_OPEN)) { $char = GeSHi::hsc($char) . '</span>'; } $escape_me = false; if ($HARDQUOTE_OPEN) { if ($ESCAPE_CHAR_OPEN) { $escape_me = true; } else { foreach ($this->language_data['HARDESCAPE'] as $hardesc) { if (substr($part, $i, strlen($hardesc)) == $hardesc) { $escape_me = true; break; } } } } if (!$ESCAPE_CHAR_OPEN) { $STRING_OPEN = ''; $CLOSE_STRING = true; } if (!$escape_me) { $HARDQUOTE_OPEN = false; } $ESCAPE_CHAR_OPEN = false; } else if (in_array($char, $this->language_data['QUOTEMARKS']) && ($STRING_OPEN == '') && $this->lexic_permissions['STRINGS']) { // The start of a new string $STRING_OPEN = $char; if (!$this->use_classes) { $attributes = ' style="' . $this->language_data['STYLES']['STRINGS'][0] . '"'; } else { $attributes = ' class="st0"'; } $char = "<span$attributes>" . GeSHi::hsc($char); $result .= $this->parse_non_string_part( $stuff_to_parse ); $stuff_to_parse = ''; } else if ($hq && substr($part, $i, strlen($hq)) == $hq && ($STRING_OPEN == '') && $this->lexic_permissions['STRINGS']) { // The start of a hard quoted string $STRING_OPEN = $this->language_data['HARDQUOTE'][1]; if (!$this->use_classes) { $attributes = ' style="' . $this->language_data['STYLES']['STRINGS'][0] . '"'; } else { $attributes = ' class="st0"'; } $char = "<span$attributes>" . $hq; $i += strlen($hq) - 1; $HARDQUOTE_OPEN = true; $result .= $this->parse_non_string_part($stuff_to_parse); $stuff_to_parse = ''; } else if ($char == $this->language_data['ESCAPE_CHAR'] && $STRING_OPEN != '') { // An escape character if (!$ESCAPE_CHAR_OPEN) { $ESCAPE_CHAR_OPEN = !$HARDQUOTE_OPEN; // true unless $HARDQUOTE_OPEN if ($HARDQUOTE_OPEN) { foreach ($this->language_data['HARDESCAPE'] as $hard) { if (substr($part, $i, strlen($hard)) == $hard) { $ESCAPE_CHAR_OPEN = true; break; } } } if ($ESCAPE_CHAR_OPEN && $this->lexic_permissions['ESCAPE_CHAR']) { if (!$this->use_classes) { $attributes = ' style="' . $this->language_data['STYLES']['ESCAPE_CHAR'][0] . '"'; } else { $attributes = ' class="es0"'; } $char = "<span$attributes>" . $char; if (substr($code, $i + 1, 1) == "\n") { // escaping a newline, what's the point in putting the span around // the newline? It only causes hassles when inserting line numbers $char .= '</span>'; $ESCAPE_CHAR_OPEN = false; } } } else { $ESCAPE_CHAR_OPEN = false; if ($this->lexic_permissions['ESCAPE_CHAR']) { $char .= '</span>'; } } } else if ($ESCAPE_CHAR_OPEN) { if ($this->lexic_permissions['ESCAPE_CHAR']) { $char .= '</span>'; } $ESCAPE_CHAR_OPEN = false; $test_str = $char; } else if ($STRING_OPEN == '') { // Is this a multiline comment? foreach ($this->language_data['COMMENT_MULTI'] as $open => $close) { $com_len = strlen($open); $test_str = substr( $part, $i, $com_len ); $test_str_match = $test_str; if ($open == $test_str) { $COMMENT_MATCHED = true; //@todo If remove important do remove here if ($this->lexic_permissions['COMMENTS']['MULTI'] || $test_str == GESHI_START_IMPORTANT) { if ($test_str != GESHI_START_IMPORTANT) { if (!$this->use_classes) { $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS']['MULTI'] . '"'; } else { $attributes = ' class="coMULTI"'; } $test_str = "<span$attributes>" . GeSHi::hsc($test_str); } else { if (!$this->use_classes) { $attributes = ' style="' . $this->important_styles . '"'; } else { $attributes = ' class="imp"'; } // We don't include the start of the comment if it's an // "important" part $test_str = "<span$attributes>"; } } else { $test_str = GeSHi::hsc($test_str); } $close_pos = strpos( $part, $close, $i + strlen($close) ); $oops = false; if ($close_pos === false) { $close_pos = strlen($part); $oops = true; } else { $close_pos -= ($com_len - strlen($close)); } // Short-cut through all the multiline code $rest_of_comment = GeSHi::hsc(substr($part, $i + $com_len, $close_pos - $i)); if (($this->lexic_permissions['COMMENTS']['MULTI'] || $test_str_match == GESHI_START_IMPORTANT) && ($this->line_numbers != GESHI_NO_LINE_NUMBERS || count($this->highlight_extra_lines) > 0)) { // strreplace to put close span and open span around multiline newlines $test_str .= str_replace("\n", "</span>\n<span$attributes>", $rest_of_comment); } else { $test_str .= $rest_of_comment; } if ($this->lexic_permissions['COMMENTS']['MULTI'] || $test_str_match == GESHI_START_IMPORTANT) { $test_str .= '</span>'; if ($oops) { $test_str .= "\n"; } } $i = $close_pos + $com_len - 1; // parse the rest $result .= $this->parse_non_string_part($stuff_to_parse); $stuff_to_parse = ''; break; } } // If we haven't matched a multiline comment, try single-line comments if (!$COMMENT_MATCHED) { foreach ($this->language_data['COMMENT_SINGLE'] as $comment_key => $comment_mark) { $com_len = strlen($comment_mark); $test_str = substr($part, $i, $com_len); if ($this->language_data['CASE_SENSITIVE'][GESHI_COMMENTS]) { $match = ($comment_mark == $test_str); } else { $match = (strtolower($comment_mark) == strtolower($test_str)); } if ($match) { $COMMENT_MATCHED = true; if ($this->lexic_permissions['COMMENTS'][$comment_key]) { if (!$this->use_classes) { $attributes = ' style="' . $this->language_data['STYLES']['COMMENTS'][$comment_key] . '"'; } else { $attributes = ' class="co' . $comment_key . '"'; } $test_str = "<span$attributes>" . GeSHi::hsc($this->change_case($test_str)); } else { $test_str = GeSHi::hsc($test_str); } $close_pos = strpos($part, "\n", $i); $oops = false; if ($close_pos === false) { $close_pos = strlen($part); $oops = true; } $test_str .= GeSHi::hsc(substr($part, $i + $com_len, $close_pos - $i - $com_len)); if ($this->lexic_permissions['COMMENTS'][$comment_key]) { $test_str .= "</span>"; } // Take into account that the comment might be the last in the source if (!$oops) { $test_str .= "\n"; } $i = $close_pos; // parse the rest $result .= $this->parse_non_string_part($stuff_to_parse); $stuff_to_parse = ''; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -