/** * Runs the script and outputs highlighted code. * * @return void */ public function run() { $parser = $this->createParser(); try { $result = $parser->parse(); $file = $result->args['infile']; $format = $result->options['format']; $renderer = $result->options['renderer']; if ($format == '') { $format = $this->detectFormat($file); } $geshi = new GeSHi(file_get_contents($file), $format); if ($renderer) { $rendclass = self::$arRenderers[$renderer]; require_once GESHI_CLASSES_ROOT . 'class.geshirenderer.php'; require_once GESHI_CLASSES_ROOT . 'renderers/class.' . strtolower($rendclass) . '.php'; $geshi->setRenderer(new $rendclass()); } echo $geshi->parseCode() . "\n"; } catch (Exception $e) { $parser->displayError($e->getMessage()); exit(1); } }
<?php require_once dirname(__FILE__) . '/../class.geshi.php'; $geshi = new GeSHi(file_get_contents(__FILE__), 'php'); require_once GESHI_CLASSES_ROOT . 'class.geshirenderer.php'; require_once GESHI_CLASSES_ROOT . 'renderers/class.geshirenderertroff.php'; $geshi->setRenderer(new GeSHiRendererTroff()); $highlighted = $geshi->parseCode(); $manpage = <<<MAN .TH DemoManPage .SH EXAMPLE {$highlighted} MAN; file_put_contents('test-manpage', $manpage); echo "run 'man ./test-manpage' now!\n";
/** * Function called by the pre_typography extension hook before the text will be parsed by EE * @param string $str text that will be parsed * @param object $typo Typography object * @param array $prefs Preferences sent to $TYPE->parse_type * @return string text where the code has been stripped and code positions marked with an MD5-ID * @access public * @global $EXT Extension-Object to support multiple calls to the same extension hook * @global $OUT could be used to display errors - it isn't at the moment * @todo Display error using $OUT */ function pre_typography($str, $typo, $prefs) { // we don't need the DB, nor IN, nor DSP // should probably use OUT to display user_error messages global $EXT, $OUT; // here we're doing the actual work if ($EXT->last_call !== FALSE) { // A different extension has run before us $str = $EXT->last_call; } $cache_dir = dirname(__FILE__) . '/' . $this->settings['cache_dir']; $rllen = strlen($this->rlimit); $pos = array(); preg_match_all($this->llimit, $str, $matches, PREG_OFFSET_CAPTURE); foreach ($matches[0] as $key => $match) { $pos[$match[1]] = array(); $pos[$match[1]]['match'] = $match[0]; // lang (called type internally for historical reasons) if (!empty($matches[1][$key][0])) { // strip slashes for filesystem security and quotes because the value might be quoted $pos[$match[1]]['type'] = str_replace(array('/', '"', "'"), '', substr($matches[1][$key][0], 5)); } else { $pos[$match[1]]['type'] = NULL; } // strict if (!empty($matches[2][$key][0])) { switch (str_replace(array('"', "'"), '', strtolower(substr($matches[2][$key][0], 7)))) { case 'true': case '1': $pos[$match[1]]['strict'] = TRUE; break; case 'false': case '0': $pos[$match[1]]['strict'] = FALSE; break; default: $pos[$match[1]]['strict'] = NULL; break; } } else { $pos[$match[1]]['strict'] = NULL; } // line $pos[$match[1]]['line'] = !empty($matches[3][$key][0]) ? str_replace(array('"', "'"), '', substr($matches[3][$key][0], 5)) : NULL; // start $pos[$match[1]]['start'] = !empty($matches[4][$key][0]) ? str_replace(array('"', "'"), '', substr($matches[4][$key][0], 6)) : NULL; // keyword_links if (!empty($matches[5][$key][0])) { switch (str_replace(array("'", '"'), '', strtolower(substr($matches[5][$key][0], 14)))) { case 'true': case '1': $pos[$match[1]]['keyword_links'] = TRUE; break; case 'false': case '0': $pos[$match[1]]['keyword_links'] = FALSE; break; default: $pos[$match[1]]['keyword_links'] = NULL; break; } } else { $pos[$match[1]]['keyword_links'] = NULL; } // overall_class $pos[$match[1]]['overall_class'] = !empty($matches[6][$key][0]) ? str_replace(array("'", '"'), '', substr($matches[6][$key][0], 14)) : NULL; // overall_id $pos[$match[1]]['overall_id'] = !empty($matches[7][$key][0]) ? str_replace(array("'", '"'), '', substr($matches[7][$key][0], 11)) : NULL; } // clean variables used in the loop unset($matches, $key, $match); // krsort the array so we can use substr stuff and won't mess future replacements krsort($pos); // Check for the cache dir if (file_exists($cache_dir) && is_dir($cache_dir)) { $cache_dir = realpath($cache_dir) . '/'; if (!is_writable($cache_dir)) { // try to chmod it @chmod($cache_dir, 0777); if (!is_writable($cache_dir)) { // still not writable? display a warning print '<b>Warning</b>: Your <i>' . $this->name . '</i> cache directory <b>' . $cache_dir . '</b> is not writable! This will cause severe performance problems, so I suggest you chmod that dir.'; } } } else { if (!mkdir($cache_dir, 0777)) { print '<b>Warning</b>: Your <i>' . $this->name . '</i> cache directory <b>' . $cache_dir . '</b> could not be created! This will cause severe performance problems, so I suggest you create and chmod that dir.'; } else { // create an index.html so the contents will not be listed. @touch($cache_dir . 'index.html'); } } if (mt_rand(0, 10) == 10) { // on every 10th visit do the garbage collection $cur = time(); $d = dir($cache_dir); while (($f = $d->read()) !== FALSE) { if ($f != 'index.html' && $f[0] != '.') { if ($cur - filemtime($cache_dir . $f) > $this->settings['cache_cutoff']) { // File is older than cutoff, delete it. @unlink($cache_dir . $f); } } } } // loop through the code snippets $i = 0; foreach ($pos as $code_pos => $match) { $error = FALSE; if (($code_end_pos = strpos($str, $this->rlimit, (int) $code_pos + strlen($match['match']))) !== FALSE) { // we have a matching end tag. // make sure cache is regenerated when changing options, too! $md5 = md5(($not_geshified = substr($str, $code_pos + strlen($match['match']), $code_end_pos - $code_pos - strlen($match['match']))) . print_r($match, TRUE) . print_r($this->settings, TRUE)); // check whether we already have this in a cache file if (is_file($cache_dir . $md5) && is_readable($cache_dir . $md5)) { if (is_callable('file_get_contents')) { $geshified = file_get_contents($cache_dir . $md5); // this is for the garbage collection touch($cache_dir . $md5); } else { // screw PHP4! $f = fopen($cache_dir . $md5, 'r'); $geshified = fread($f, filesize($cache_dir . $md5)); fclose($f); touch($cache_dir . $md5); } } else { // no cache so do the GeSHi thing if ($this->settings['geshi_version'] == '1.1') { // use GeSHi 1.1 include_once dirname(__FILE__) . '/geshi-1.1/class.geshi.php'; // highlight code according to type setting, default to setting $geshi = new GeSHi($not_geshified, $match['type'] !== NULL ? $match['type'] : $this->settings['default_type']); $str_error = $geshi->error(); if (empty($str_error)) { // neither line numbers, nor strict mode is supported in GeSHi 1.1 yet. // in fact it does pretty much nothing // there used to be a rather large block of code here, testing wether methods were callable and call them if // that's the case. // parse the code $geshified = $geshi->parseCode(); } else { $error = TRUE; } } else { // use GeSHi 1.0 include_once dirname(__FILE__) . '/geshi-1.0/geshi.php'; // highlight code according to type setting, default to php $geshi = new GeSHi($not_geshified, $match['type'] !== NULL ? $match['type'] : $this->settings['default_type']); $str_error = $geshi->error(); if (empty($str_error)) { // enable line numbers $number_style = !empty($match['line']) ? $match['line'] : $this->settings['default_line']; switch (strtolower(preg_replace('/\\d+/', '', $number_style))) { case 'normal': $geshi->enable_line_numbers(GESHI_NORMAL_LINE_NUMBERS); break; case 'fancy': $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS, (int) preg_replace('/[^\\d]*/', '', $number_style)); break; case 'none': $geshi->enable_line_numbers(GESHI_NO_LINE_NUMBERS); break; } // set first line number if ($match['start']) { $geshi->start_line_numbers_at($match['start']); } // set strict mode if ($match['strict']) { $geshi->enable_strict_mode(TRUE); } // enable or disable keyword links $geshi->enable_keyword_links((bool) ($match['keyword_links'] !== NULL) ? $match['keyword_links'] : $this->settings['keyword_links']); // set overall class name if ($match['overall_class'] != NULL) { $geshi->set_overall_class($match['overall_class']); } // set overall id if ($match['overall_id'] != NULL) { $geshi->set_overall_id($match['overall_id']); } // set header type switch ($this->settings['geshi_header_type']) { case 'div': $geshi->set_header_type(GESHI_HEADER_DIV); break; case 'pre': $geshi->set_header_type(GESHI_HEADER_PRE); break; case 'pre-valid': $geshi->set_header_type(GESHI_HEADER_PRE_VALID); break; case 'pre-table': $geshi->set_header_type(GESHI_HEADER_PRE_TABLE); break; case 'none': $geshi->set_header_type(GESHI_HEADER_NONE); break; } // set encoding (for legacy reasons afaik) $geshi->set_encoding($this->settings['geshi_encoding']); // parse the source code $geshified = $geshi->parse_code(); } else { $error = TRUE; } } if (!file_exists($cache_dir . $md5) && is_writable($cache_dir) || file_exists($cache_dir . $md5) && is_writable($cache_dir . $md5)) { if (!$error) { // we can write to the cache file if (is_callable('file_put_contents')) { file_put_contents($cache_dir . $md5, $geshified); @chmod($cache_dir . $md5, 0777); } else { // when will you guys finally drop PHP4 support? $f = fopen($cache_dir . $md5, 'w'); fwrite($f, $geshified); fclose($f); @chmod($cache_dir . $md5, 0777); } } } else { // We could ignore that, but for performance reasons better warn the user. print '<b>Warning</b>: Your <i>' . $this->name . '</i> cache directory <b>' . $cache_dir . '</b> is not writable! This will cause severe performance problems, so I suggest you chmod that dir.'; } } // save replacement to cache and mark location with an identifier for later replacement if (!isset($_SESSION['cache']['ext.geshify'])) { $_SESSION['cache']['ext.geshify'] = array(); } if (!$error) { $_SESSION['cache']['ext.geshify'][$md5] = $geshified; $str = substr($str, 0, $code_pos) . $md5 . substr($str, $code_end_pos + $rllen); } } // unset used variables, so we don't get messed up unset($code_pos, $code_end_pos, $md5, $geshified, $not_geshified, $geshi, $match, $ident, $error); } return $str; }
// </ol></pre> //$geshi->set_line_style('color: #003030;', 'font-weight: bold; color: #006060;', true); //$geshi->set_code_style('color: #000020;', true); // Styles for hyperlinks in the code. GESHI_LINK for default styles, GESHI_HOVER for hover style etc... // note that classes must be enabled for this to work. //$geshi->set_link_styles(GESHI_LINK, 'color: #000060;'); //$geshi->set_link_styles(GESHI_HOVER, 'background-color: #f0f000;'); // Use the header/footer functionality. This puts a div with content within the PRE element, so it is // affected by the styles set by set_overall_style. So if the PRE has a border then the header/footer will // appear inside it. //$geshi->set_header_content('<SPEED> <TIME> GeSHi © 2004-2007, Nigel McNie, 2007-2008 Benny Baumann. View source of example.php for example of using GeSHi'); //$geshi->set_header_content_style('font-family: sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-bottom: 1px solid #d0d0d0; padding: 2px;'); // You can use <TIME> and <VERSION> as placeholders //$geshi->set_footer_content('Parsed in <TIME> seconds at <SPEED>, using GeSHi <VERSION>'); //$geshi->set_footer_content_style('font-family: sans-serif; color: #808080; font-size: 70%; font-weight: bold; background-color: #f0f0ff; border-top: 1px solid #d0d0d0; padding: 2px;'); $parsed_code = $geshi->parseCode(); } else { // make sure we don't preselect any language $_POST['language'] = null; } $debug_output = ob_get_contents(); ob_end_clean(); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>GeSHi examples</title> <style type="text/css"> <!-- <?php