Extension:SourcesCatalogHighlighter

From MediaWiki.org
Jump to navigation Jump to search
MediaWiki extensions manual
OOjs UI icon advanced.svg
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)
Latest version 1.1
MediaWiki Tested on 1.10.0
License No license specified
Download black-zorro.jino-net.ru
Translate the SourcesCatalogHighlighter extension if it is available at translatewiki.net
Check usage and version matrix.

What can this extension do?[edit]

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)

Usage[edit]

Installation[edit]

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',
);

Parameters[edit]

Changes to LocalSettings.php[edit]

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

Code[edit]

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

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

See also[edit]

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, -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, -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:

 Sourceshighligter 1.png
 Sourceshighligter 2.png
 Sourceshighligter 3.png
 Sourceshighligter 4.png