|
1 <?php |
|
2 /* |
|
3 Plugin Name: GeSHi syntax highlighting |
|
4 Plugin URI: http://enanocms.org/GeSHi_support |
|
5 Description: Adds syntax highlighting support using the GeSHi engine. |
|
6 Author: Dan Fuhry |
|
7 Version: 0.1 |
|
8 Author URI: http://enanocms.org/ |
|
9 */ |
|
10 |
|
11 /* |
|
12 * GeSHi highlighting plugin for Enano |
|
13 * Version 0.1 |
|
14 * Copyright (C) 2007 Dan Fuhry |
|
15 * |
|
16 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License |
|
17 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. |
|
18 * |
|
19 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied |
|
20 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details. |
|
21 */ |
|
22 |
|
23 global $db, $session, $paths, $template, $plugins; // Common objects |
|
24 $GLOBALS['geshi_supported_formats'] = array( |
|
25 'abap', 'blitzbasic', 'cpp-qt', 'd', 'idl', 'lua', 'ocaml', 'python', 'smalltalk', 'vhdl', 'actionscript', 'bnf', 'csharp', |
|
26 'eiffel', 'ini', 'm68k', 'oobas', 'qbasic', 'smarty', 'visualfoxpro', 'ada', 'caddcl', 'fortran', 'inno', 'matlab', |
|
27 'oracle8', 'rails', 'sql', 'winbatch', 'apache', 'cadlisp', 'css', 'freebasic', 'io', 'mirc', 'pascal', 'reg', 'tcl', 'xml', |
|
28 'applescript', 'cfdg', 'delphi', 'genero', 'java5', 'mpasm', 'perl', 'robots', 'text', 'xpp', 'asm', 'cfm', 'diff', 'gml', 'java', |
|
29 'mysql', 'per', 'ruby', 'thinbasic', 'z80', 'asp', 'c_mac', 'div', 'groovy', 'javascript', 'nsis', 'php-brief', 'sas', 'tsql', |
|
30 'autoit', 'c', 'dos', 'haskell', 'latex', 'objc', 'php', 'scheme', 'vbnet', 'bash', 'cpp', 'dot', 'html', 'lisp', |
|
31 'ocaml-brief', 'plsql', 'sdlbasic', 'vb' |
|
32 ); |
|
33 |
|
34 // Knock out the existing <code> tag support |
|
35 $plugins->attachHook('text_wiki_construct', 'geshi_disable_tw_code($this);'); |
|
36 |
|
37 function geshi_disable_tw_code($tw) |
|
38 { |
|
39 $tw->disable[] = 'Code'; |
|
40 foreach ( $tw->rules as $i => $rule ) |
|
41 { |
|
42 if ( $rule == 'Code' ) |
|
43 { |
|
44 unset($tw->rules[$i]); |
|
45 return true; |
|
46 } |
|
47 } |
|
48 } |
|
49 |
|
50 // Prevent <code> tags from being stripped or sanitized (the plugin will handle all sanitation) |
|
51 $plugins->attachHook('render_sanitize_pre', 'geshi_strip_code($text, $geshi_code_blocks, $random_id);'); |
|
52 $plugins->attachHook('render_sanitize_post', 'geshi_restore_code($text, $geshi_code_blocks, $random_id);'); |
|
53 |
|
54 function geshi_strip_code(&$text, &$codeblocks, $random_id) |
|
55 { |
|
56 global $geshi_supported_formats; |
|
57 $codeblocks = array(); |
|
58 $sf = '(' . implode('|', $geshi_supported_formats) . ')'; |
|
59 preg_match_all('/<code type="?' . $sf . '"?>([\w\W]*?)<\/code>/ms', $text, $matches); |
|
60 |
|
61 // for debug |
|
62 /* |
|
63 if ( strstr($text, '<code type') ) |
|
64 die('processing codes: <pre>' . htmlspecialchars(print_r($matches, true)) . '</pre><pre>' . htmlspecialchars($text) . '</pre>' . htmlspecialchars('/<code type="?' . $sf . '"?>([\w\W]*?)<\/code>/')); |
|
65 */ |
|
66 |
|
67 foreach ( $matches[0] as $i => $match ) |
|
68 { |
|
69 $codeblocks[$i] = array( |
|
70 'match' => $match, |
|
71 'lang' => $matches[1][$i], |
|
72 'code' => $matches[2][$i] |
|
73 ); |
|
74 $text = str_replace_once($match, "{GESHI_BLOCK:$i:$random_id}", $text); |
|
75 } |
|
76 } |
|
77 |
|
78 function geshi_restore_code(&$text, &$codeblocks, $random_id) |
|
79 { |
|
80 foreach ( $codeblocks as $i => $match ) |
|
81 { |
|
82 $text = str_replace_once("{GESHI_BLOCK:$i:$random_id}", $match['match'], $text); |
|
83 } |
|
84 } |
|
85 |
|
86 // Formatter hook - where the actual highlighting is performed |
|
87 $plugins->attachHook('render_wikiformat_veryearly', 'geshi_strip_code($text, $codeblocks, $random_id);'); |
|
88 $plugins->attachHook('render_wikiformat_post', 'geshi_perform_highlight($result, $codeblocks, $random_id);'); |
|
89 |
|
90 function geshi_perform_highlight(&$text, &$codeblocks, $random_id) |
|
91 { |
|
92 static $did_header_tweak = false; |
|
93 if ( !$did_header_tweak ) |
|
94 { |
|
95 $did_header_tweak = true; |
|
96 global $template; |
|
97 $template->add_header('<style type="text/css"> |
|
98 pre.geshi_highlighted { |
|
99 max-height: 1000000px !important; |
|
100 } |
|
101 pre.geshi_highlighted a { |
|
102 background-image: none !important; |
|
103 padding-right: 0 !important; |
|
104 } |
|
105 </style> |
|
106 '); |
|
107 } |
|
108 if ( !defined('GESHI_ROOT') ) |
|
109 define('GESHI_ROOT', ENANO_ROOT . '/plugins/geshi/'); |
|
110 |
|
111 require_once ( GESHI_ROOT . '/base.php' ); |
|
112 |
|
113 foreach ( $codeblocks as $i => $match ) |
|
114 { |
|
115 $lang =& $match['lang']; |
|
116 $code =& $match['code']; |
|
117 |
|
118 $geshi = new GeSHi($code, $lang, null); |
|
119 $geshi->set_header_type(GESHI_HEADER_PRE); |
|
120 // $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS); |
|
121 $geshi->set_overall_class('geshi_highlighted'); |
|
122 $parsed = $geshi->parse_code(); |
|
123 |
|
124 $text = str_replace_once("{GESHI_BLOCK:$i:$random_id}", $parsed, $text); |
|
125 } |
|
126 } |