Extension:SourcesCatalogHighlighter

From MediaWiki.org

Jump to: navigation, search
Manual on MediaWiki Extensions
List of MediaWiki Extensions
SourcesCatalogHiglighter

Release status: beta

Implementation Extended syntax
Description This extension enables you to add on your pages clickable catalog of sources with highlight
Author(s) Nikolai Gishkevich (black zorro)
Version 1.1
MediaWiki Tested on 1.10.0
Download black-zorro.jino-net.ru
Hooks used

OutputPageBeforeHTML

Contents

[edit] What can this extension do?

This extension enables you to add on your pages clickable catalog of sources with highlight. Heart of extension is geshi ( http://qbnz.com/highlighter/ ). You can manage with rules of mapping file extension to file type (program language)

[edit] Usage

[edit] Installation

First copy files into extension directory. Next, modify extension config file in order to point to GeShi library location.

// path to geshi
define('PATH_TO_GESHI', '../geshi');

Next, modify config file in order to map file extensions to file formats:

$MAP_EXT_TO_SOURCE  = array (
'as' => 'actionscript',
'as2' => 'actionscript',
'as3' => 'actionscript',
 
'c' => 'c',
'cpp' => 'cpp',
 
'css' => 'css',
 
'html' => 'html4strict',
'htm' => 'html4strict',
'shtml' => 'html4strict',
 
'php' => 'php',
'php3' => 'php',
'php4' => 'php',
'php5' => 'php',
'phtml' => 'php',
);

[edit] Parameters

[edit] Changes to LocalSettings.php

require_once("$IP/extensions/sourcehighlighter/setup.php");

[edit] Code

@ {sourceshighlight css="shc_basic.css" base="wiki/extensions" }

  1. css = name of default css file
  2. base = catalog name to render

[edit] See also

Sources of 2 files:

main.php
<?php
// wiki plugin -- by black zorro -- black-zorro@tut.by
//---- usage  example : -----
//Hello It's My Page
//@{sourceshighlight css="shc_basic.css" base="adodb" }
// Hello, Plugin correct place 2 or more sourceslists in one page
//@{sourceshighlight css="shc_basic.css" base="wiki/extensions" }
// your must supply params to plugin:
// css - name of css file (must be in plugin dir)
// base - root catalog name  (not relative from wiki)
// optional: file or index - emulate first user action
// ---- installation ---
// add line into LocalSettings.php
// include_once ('extensions/sourcehighlighter/setup.php');   
// and of course copy this plugin into extension dir
 
 
 
// объявляются две константы управляющие параметрами работы подсветки исходников в каталоге
 
// путь к установленной гейше
define('PATH_TO_GESHI', dirname (__FILE__) . '/../SyntaxHighlight_GeSHi/geshi');
 
// префикс селекторов классов css
define('PRE_CSS_SELECTOR', 'css_whi_smp_');
 
// здесь выполняется регистрация расширений файлов на их название типа - по названию типа и выполняется раскраска кода
$MAP_EXT_TO_SOURCE  = array (
'as' => 'actionscript',
'as2' => 'actionscript',
'as3' => 'actionscript',
 
'c' => 'c',
'cpp' => 'cpp',
 
'css' => 'css',
 
'html' => 'html4strict',
'htm' => 'html4strict',
'shtml' => 'html4strict',
 
'php' => 'php',
'php3' => 'php',
'php4' => 'php',
'php5' => 'php',
'phtml' => 'php',
);
 
 
// функция генерящая сообщение об ошибке если что то не так
function THROW_ERROR ($msg){
        trigger_error($msg,  E_USER_ERROR);
}
 
 
// класс реализующий функциональность плагина
class SourceHighlightManager {
        var $base = '/';
        var $base_of_page_url = '';
        var $m = '';
 
        function SourceHighlightManager ($m, $base, $base_of_page_url){
                $this->m = $m;
                $this->base = $base;
                $this->base_of_page_url = $base_of_page_url;
 
                if (! file_exists($this->base))
                THROW_ERROR ('Ошибка инициализации, запрошенный путь корня подсветки не может быть обнаружен (c:001)');
        }
 
 
        function get_ext ($file){
                if (strpos($file , '.') === false)
                        return false;
                $rev = strrev($file);
                return  strrev( substr($rev , 0, strpos($rev , '.') ) );
        }
 
        function mapping_extensions ($file){
                $ext = $this->get_ext ($file);
                if (! $ext)
                        return 'text';
                global $MAP_EXT_TO_SOURCE;    
                return  isset($MAP_EXT_TO_SOURCE [$ext])?$MAP_EXT_TO_SOURCE [$ext]:'text';
 
        }
 
        function index_data ($folder){
                $arr_files = array ();
                $folder_s = $folder;
                if ($folder [strlen($folder) - 1] != '/'){
                        $folder_s .= '/';
                }
                $dir = realpath( $this->base . '/' . $folder) . '/';
                if (is_dir($dir)){
                        if ($h = opendir($dir)){
                                while ( ($file = readdir($h)) !== false ){
                                        if ($file == '..' || $file == '.') continue;
                                        $fullname = $dir . $file;
                                        $arr_files []= array (
                                        'name' => $file,
                                        'realname' => $fullname,
                                        'fullname' => $folder_s . $file,
                                        'size' => filesize($fullname),
                                        'kind' => (is_dir($fullname)?'d':'f'),
                                        'ext' => $this->get_ext ($file)
                                        );
                                }
                                closedir($h);
                        }
 
                }
                return $arr_files;
        }
 
        function index_render ($folder = ''){
                $data = $this->index_data ($folder);
 
                if (! $data)
                return '<div class="'.PRE_CSS_SELECTOR.'error_not_found">Ошибка, запрошенный вами путь визуализации не может быть найден"'.$folder.'" </div>';
 
                $html = '<div class="'.PRE_CSS_SELECTOR.'heading_index_sourcesh">Список файлов/подкаталогов в текущем каталоге "'.$folder.'" </div>'. "\n";
                if ($folder != ''){
                        $f = explode('/', $folder);
                        $html .= '<a href="'.$this->base_of_page_url.'?index='.(join("/", array_slice($f , 0, count($f) - 1))).'" >Подняться выше</a>'. "\n";
                }
                $html .= '<table cellpadding="0" cellspacing="0" border="1" class="'.PRE_CSS_SELECTOR.'table_scrlist_index">' . "\n";
                $html .= '<tr>' . "\n";
                $html .= '<th>Тип файла</th>' .  "\n";
                $html .= '<th>Имя файла</th>' .  "\n";
                $html .= '<th>Размер</th>' .  "\n";
                $html .= '</tr>' . "\n";
 
                for ($i = 0; $i < count($data); $i++){
                        $idata = $data [$i];
                        $url_special = '';
                        if ($idata ['kind'] == 'f')
                        $url_special = $this->base_of_page_url.'?file='.$idata ['fullname'] .'&m=' . $this->m;
                        else
                        $url_special = $this->base_of_page_url.'?index='.$idata ['fullname'] .'&m=' . $this->m;
 
 
                        $html .= '<tr>' . "\n";
 
                        $html .= '<td>' . ($idata ['kind']=='d'?'Каталог':'Файл') . '</td>' . "\n";
                        $html .= '<td><a href="'.$url_special.'">' . $idata ['name'] .'</a></td>' . "\n";
                        $html .= '<td>' . ($idata ['size']) . '</td>' . "\n";
 
                        $html .= '</tr>' . "\n";
                }
                $html .= '</table>' . "\n";
                return $html;
        }
 
 
 
        function file_data ($file){
                require_once(PATH_TO_GESHI .  '/geshi.php');
 
                $fullname = $this->base . $file;
                if (! file_exists($fullname))
                return false;
 
                $language = $this->mapping_extensions ($file);
 
                $source = join(file($fullname));
                $geshi = new GeSHi($source, $language);
                $geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS);
                return $geshi->parse_code();
        }
 
 
        function file_render ($file){
                $data = $this->file_data ($file);
                if (! $data)
                return '<div class="'.PRE_CSS_SELECTOR.'error_not_found">Ошибка, запрошенный вами путь визуализации не может быть найден"'.$file.'" </div>';
 
 
                $html = '<div class="'.PRE_CSS_SELECTOR.'heading_index_sourcesh">Содержимое файла "'.$file.'" </div>'. "\n";
                $f = explode('/', $folder);
                $html .= '<a href="'.$this->base_of_page_url.'?index='.(join("/",array_slice($f , 0, count($f) - 1))).'" >Подняться выше</a>'. "\n";
 
                $html .= '<div class="'.PRE_CSS_SELECTOR.'div_sourcebox">'.$data.'</div>';
                return $html;
        }
 
 
        function service (){
                if (isset($_REQUEST['m']) && $_REQUEST['m'] == $this->m){
                        if (isset($_REQUEST['index']))
                        return $this->index_render($_REQUEST['index']);
 
                        if (isset($_REQUEST['file']))
                        return $this->file_render($_REQUEST['file']);
                }
                else{
 
                        return $this->index_render();
                }
        }
 
 
}
next file: setup.php
<?php
/*
'OutputPageBeforeHTML': a page has been processed by the parser and
the resulting HTML is about to be displayed.
$parserOutput: the parserOutput (object) that corresponds to the page
$text: the text that will be displayed, in HTML (string)
*/
 
include_once ('main.php');
 
global $wgHooks;
 
$wgHooks['OutputPageBeforeHTML'][] = 'makeSourcesHighlightTag';
 
if (! function_exists('win2utf'))    {
        function win2utf($str)
        {
                $utf = "";
                for($i = 0; $i < strlen($str); $i++)
                {
                        $donotrecode = false;
                        $c = ord(substr($str, $i, 1));
                        if ($c == 0xA8) $res = 0xD081;
                        elseif ($c == 0xB8) $res = 0xD191;
                        elseif ($c < 0xC0) $donotrecode = true;
                        elseif ($c < 0xF0) $res = $c + 0xCFD0;
                        else $res = $c + 0xD090;
                        $utf .= ($donotrecode) ? chr($c) : (chr($res >> 8) . chr($res & 0xff));
                }
                return $utf;
        }
}
 
 
 
function cmpl_2321_reg_shhic ($arr_got){
        $params = $arr_got [1];
 
        $m = md5($params);
 
        $css = 'shc_basic.css';
        $arr_got = array ();
        if (preg_match('/css="([^"]+)"/iUs',$params, $arr_got))
        $css = $arr_got [1];
 
        $base = false;
        $arr_got = array ();
        if (preg_match('/base="([^"]+)"/iUs',$params, $arr_got))
        $base = $arr_got [1];
 
        $index = false;
        $arr_got = array ();
        if (preg_match('/index="([^"]+)"/iUs',$params, $arr_got))
        $index = $arr_got [1];
 
        $file = false;
        $arr_got = array ();
        if (preg_match('/file="([^"]+)"/iUs',$params, $arr_got))
        $file = $arr_got [1];
 
        $base2 = realpath( dirname(__FILE__) . '/../../../' . $base) . '/';
 
        if ($file){
                $_REQUEST ['file'] = $file;
                $_REQUEST ['m'] = $m;
        }
 
        if ($index){
                $_REQUEST ['index'] = $file;
                $_REQUEST ['m'] = $m;
        }
 
        $sc = new SourceHighlightManager (
                $m,
                $base2, 
                ''
        );
        return win2utf($sc->service($m));
 
}
 
function makeSourcesHighlightTag (& $paout, & $text){
        //@{sourceshighlight css="shc_basic.css" base="adodb" }
        $text = preg_replace_callback('/@{sourceshighlight([^}]+)}/iUs', 'cmpl_2321_reg_shhic', $text);
        return true;
}


Examples of images:

 Image:sourceshighligter_1.png
 Image:sourceshighligter_2.png
 Image:sourceshighligter_3.png
 Image:sourceshighligter_4.png
Personal tools