root/plugins/highlighter/trunk/highlighter.plugin.php

Revision 1790, 2.8 kB (checked in by sean, 2 months ago)

fix ' somehow accidentally introduced (by me) in r1773

  • Property svn:eol-style set to native
Line 
1<?php
2/**
3 * Highlighter Plugin
4 *
5 * Using this plugin is simple. To highlight inline source using GeSHi,
6 * just surround your code in <div class="highlight php"> ... </div>
7 *
8 * Where "php" could be any language supported by GeSHi.
9 *
10 * I also recommend you use CDATA blocks (which the plugin will automatically
11 * strip), just in case the plugin is ever disabled:
12 *
13 * <div class="highlight php">
14 * <![CDATA[
15 *   <?php
16 *   $foo = 'bar';
17 *   ?>
18 * ]]>
19 * </div>
20 *
21 * Note, you'll also need to grab GeSHi from http://qbnz.com/highlighter/ and
22 * unpack the archive to: [habari directory]/3rdparty/geshi
23 *
24 * THIS PLUGIN REQUIRES HABARI 0.7-dev! IT WILL NOT WORK ON 0.6 (needs at least r3475)
25 */
26
27class HighlightPlugin extends Plugin {
28
29    public function info() {
30        return array (
31            'name' => 'Highlighter',
32            'url' => 'http://seancoates.com/habari',
33            'author' => 'Sean Coates',
34            'authorurl' => 'http://seancoates.com/',
35            'version' => '0.1.1',
36            'description' => 'Highlighter',
37            'license' => 'Apache License 2.0',
38        );
39    }
40
41    public function action_init() {
42        spl_autoload_register( array( __CLASS__, '_autoload') );
43        Format::apply( 'do_highlight', 'post_content_out' );
44        Format::apply( 'do_highlight', 'comment_content_out' );
45    }
46
47    public static function _autoload( $class_name ) {
48        if ( strtolower( $class_name ) == 'geshi' ) {
49            require HABARI_PATH . "/3rdparty/geshi/geshi.php";
50        }
51    }
52}
53
54class GeshiHighlighterFormatPlugin extends Format
55{
56
57    public static function do_highlight( $in )
58    {
59        // Look, ma! No Regex!
60       
61        $tokenizer = new HTMLTokenizer( $in, false );
62        $tokens = $tokenizer->parse();
63        $slices = $tokens->slice( array('div','pre','code') , array( 'class' => 'highlight' ) );
64        foreach ($slices as $slice) {
65            $classes = array_filter( explode( ' ', trim( str_replace( 'highlight', '', $slice[0]['attrs']['class'] ) ) ) ); // ugly, refactor
66            $slice->trim_container(); // trims off the div
67            $sliceValue = trim( (string)$slice );
68           
69            $sliceCacheName = 'plugin.highlight.' . md5($sliceValue);
70           
71            if ( Cache::has( $sliceCacheName ) ) {
72                $geshiOutput = Cache::get( $sliceCacheName );
73            } else {
74                // capture the first class (not "highlight")
75                if ( substr( $sliceValue, 0, 9 ) == '<![CDATA[' && substr( $sliceValue, -3 ) == ']]>' ) {
76                    // trim off CDATA wrapper:
77                    $sliceValue = substr( $sliceValue, 9, -3 );
78                }
79                $geshi = new Geshi( trim( $sliceValue ), isset( $classes[0] ) ? $classes[0] : 'php' );
80                $geshi->set_header_type( GESHI_HEADER_PRE );
81                $geshi->set_overall_class( 'geshicode' );
82                $geshiOutput = @$geshi->parse_code(); // @ is slow, but geshi is full of E_NOTICE
83                Cache::set( $sliceCacheName, $geshiOutput );
84            }
85            $slice->tokenize_replace( $geshiOutput );
86            $tokens->replace_slice( $slice );
87        }
88        return (string) $tokens;
89    }
90}
91
92?>
Note: See TracBrowser for help on using the browser.