Extension:Sort2

This page describes the usage of the mediawiki extension Sort2.

The source code of Extension:Sort authored by Rob Church was taken from the Subversion repository and modified to fit my needs and expectations.--Kaeptn00

Please use the discussion page for any bug reports and suggestions. I would also like to know where this extension is installed, so please add an entry to the appropriate section on the discussion page. Thanks.

Purpose
The purpose of this extension is to sort lists.

Features

 * Sorts ul,ol,dl and br (linebreaked) lists
 * Sorts case sensitive or case insensitive
 * A title can be added to precede the list (V1.1)
 * Unordered, ordered and definition lists can have a style sheet (V1.1)
 * Ordered lists can have a starting number (V1.1)
 * Has 5 different output modes
 * Wiki syntax inside the list remains untouched
 * Can convert list types to each other
 * Even though of a rather small importance, it can also sort whole paragraphs based on their first character

General usage
You just need to surround the list you want to sort or convert by the tags  . That's all there is and your list get sorted as ul, ascending, case insensitive.

Rob's original version did not strip the wiki syntax list tokens *,#, and :</tt> so you could not sort already existing lists without removing the tokens. I found this too awful. Sorry Rob ;).

As a side effect you can now convert lists from one type to another or easily convert some paragraphs to a list of your choice.

Syntax
The syntax of this extension is pretty easy and intuitive as it resembles the usage you know from HTML already.

<sort2 [type=""] [order=""] [casesense=""] [separator=""] [style=""] [start=""] [title=""]>

... any text ...

Options
All options are optional, default values are rendered bold below. Bold and teletype is hard to read - at least on my system - so defaults are also always the first in the list.


 * type=""</tt>
 * The option type</tt> takes a string as argument. It can be one of:
 * ul</tt>, list is generated as unordered list
 * ol</tt>, list is generated as ordered list
 * dl</tt>, list is generated as definition list
 * br</tt>, list is generated as separate lines
 * inline</tt>, list is generated as one item after the other separated by separator</tt> (see below)
 * Note: This option was named class</tt> in the original version but I found this too confusing because class</tt> normaly is used for a style sheet class.


 * order=""</tt>
 * The option order</tt> takes a string as argument. It can be one of:
 * asc</tt>, sorting direction is ascending
 * desc</tt>, sorting direction is descending
 * none</tt>, no sorting of the list. This one is useful for converting list types. For instance some paragraphs to an unordered list without changing order.


 * <tt>casesense=""</tt>
 * The option <tt>casesense</tt> takes a string as argument. It can be one of:
 * <tt>false</tt>, sorting is case insensitive. Uses php <tt>natcasesort</tt>
 * <tt>true</tt>, sorting is case sensitive. Uses php <tt>natsort</tt>


 * <tt>separator=""</tt>
 * The option <tt>separator</tt> takes a string as argument. It is only evaluated when <tt>type</tt> is set to <tt>inline</tt>. The list items are separated by the char(s) you give as argument to this option. Since the parser eats spaces using php <tt>trim</tt>, I had to introduce a pseudo-entity to be able to render separators like "<tt>, </tt>" or "<tt> | </tt>". If you want a space at the end or beginning of the separator, you have to use <tt>&sp;</tt>.
 * Examples:
 * <tt>separator=",&sp;"</tt>
 * <tt>separator="&sp;|&sp;"</tt>
 * Note: You can not pass HTML or wikisyntax as an argument. Just in case you wonder why there is this extra <tt>type="br"</tt> option.


 * <tt>style=""</tt>
 * The option <tt>style</tt> takes a string as argument. It is only evaluated when <tt>type</tt> is set to <tt>ul</tt>, <tt>ol</tt>, or <tt>dl</tt>. Its main purpose is to be able to control what kind of numbered list you are generating and having control over the margins. If you want to change the <tt>list-style-type</tt> and do this by setting <tt>list-style</tt> to <tt>none</tt>, also set <tt>list-style-image</tt> to <tt>none</tt>, since there's a default image set - at least with the Monobook skin. If you don't set this explicitly, Firefox will happily omit the list bullet but IE will still display the image.
 * Since this can have a large impact on layout, administrators can switch off that behaviour by setting <tt>$wgSort2AllowStyles = false</tt> in <tt>LocalSettings.php</tt>. More about this on the discussion page.


 * <tt>start=""</tt>
 * The option <tt>start</tt> takes an integer as argument. It is only evaluated when <tt>type</tt> is set to <tt>ol</tt> and controls the starting number of the ordered list.


 * <tt>title=""</tt>
 * The option <tt>title</tt> takes a string as argument. It is prepended to all list types and can hold wikisyntax. A space at the beginning or end must be entered as the pseudo-entity <tt>&sp;</tt>.

Examples
I am sure you get the idea.

Restrictions

 * The extension does not sense the original type of the list. So <tt>ol</tt> gets converted to a <tt>ul</tt> if you don't set the type accordingly
 * The extension eliminates identical items
 * The extension does not work with lists which have sub levels. Something like the following does not work correctly.
 * Item 1
 * Subitem
 * Item 2
 * Subitem

This would mess up the order because of the two stars and also eliminate one of the subitems.

Installation
Create a file named <tt>Sort2.php</tt> in the extensions directory and copy the source code to that file. Insert the following line at the end of your <tt>LocalSettings.php</tt> file: include_once("$IP/extensions/Sort2.php");

Version history

 * V1.1, 24.08.2006
 * Added <tt>style</tt> option for <tt>ul</tt>,<tt>ol</tt> and <tt>dl</tt>
 * Added <tt>start</tt> option for <tt>ol</tt>
 * Added <tt>title</tt> option
 * Changed rendering method from wikisyntax (<tt>*</tt>,<tt>#</tt>, and <tt>;,:</tt>) to HTML syntax (<tt>ul</tt>, <tt>ol</tt>, and <tt>dl,dd</tt>) to be able to add more features


 * V1.0, 16.08.2006
 * Initial release
 * Minor bug corrected on 20.08.2006

Source Code
<?php

/** * Parser hook extension adds a tag to wiki markup * * * @package MediaWiki * @subpackage Extensions * @author kaeptn00 <kaeptn00@yahoo.de> * @copyright © 2006 kaeptn00 * @license GNU General Public Licence 2.0 * @version 1.1 06/08/24 * */ if( defined( 'MEDIAWIKI' ) ) {

$wgExtensionFunctions[] = 'Sort2'; $wgExtensionCredits['parserhook'][] = array( 'name' => 'Sort2', 'author' => 'kaeptn00', 'url' => 'http://www.mediawiki.org/wiki/Extension:Sort2' );

$wgSort2AllowStyles = true; // Set global config variable to true function Sort2 { global $wgParser; $wgParser->setHook( 'sort2', 'RenderSort2' ); }	function RenderSort2( $input, $args, &$parser ) { $sorter2 = new Sorter2( $parser ); $sorter2->loadSettings( $args ); return $sorter2->sortToHtml( $input ); }	class Sorter2 { var $parser; var $order; var $type; var $separator; var $casesense; var $style; var $start; var $title; var $allowStyles; function Sorter2( &$parser ) { $this->parser = &$parser; $this->order = 'asc'; $this->type = 'ul'; $this->separator = "\n"; $this->casesense = "false"; $this->style = ""; $this->start = ""; $this->title = ""; $this->allowStyles = $GLOBALS['wgSort2AllowStyles']; }		function loadSettings( $settings ) { if( isset( $settings['order'] ) ){ $o = strtolower( $settings['order'] ); if( $o == 'asc' || $o == 'desc' || $o == 'none') $this->order = $o; }			if( isset( $settings['type'] ) ) { $c = strtolower( $settings['type'] ); if( $c == 'ol' || $c == 'ul' || $c == 'dl' || $c == 'inline' || $c == "br") $this->type = $c; }			if( isset($settings['separator']) AND $this->type == "inline" ){ $this->separator = str_ireplace("&sp;"," ",$settings['separator']); }			if( isset($settings['casesense']) AND strtolower($settings['casesense'] == "true") ) $this->casesense = "true"; if( isset($settings['style']) AND $this->allowStyles == true) $this->style = 'style="'.$settings['style'].'"'; if( isset($settings['start'])) $this->start = 'start="'.$settings['start'].'"'; if( isset($settings['title'])) $this->title = str_ireplace("&sp;"," ",$settings['title']); }		function sortToHtml( $text ) { wfProfileIn( 'Sorter2::sortToHtml' ); $lines = $this->internalSort( $text ); $list = $this->makeList( $lines ); $html = $this->parse( $list ); wfProfileOut( 'Sorter2::sortToHtml' ); return $html; }		function internalSort( $text ) { wfProfileIn( 'Sorter2::internalSort' ); $lines = explode( "\n", $text ); $inter = array; foreach( $lines as $line ) $inter[ $line ] = $this->stripWikiTokens( $line ); if ($this->order != "none"){ if ($this->casesense == "true"){ natsort( $inter ); } else { natcasesort( $inter ); }			}			if( $this->order == 'desc' ) $inter = array_reverse( $inter, true ); wfProfileOut( 'Sorter2::internalSort' ); return array_keys( $inter ); }		function stripWikiTokens( $text ) { $find = array( '[', '{', '\'', '}', ']'); return trim(str_replace( $find, '', $text )); }		function stripWikiListTokens( $text ) { $find = array( '*', '#',':'); return trim(str_replace( $find, '', $text )); }		function makeList( $lines ) { wfProfileIn( 'Sorter2::makeList' ); $list = array; $listtoken = "<li>"; $endlisttoken = "</li>";

switch ($this->type){ case ("ul"): $starttoken = "<ul $this->style>"; $endtoken = "</ul>"; break; case ("ol"): $starttoken = "<ol {$this->style} {$this->start}>"; $endtoken = "</ol>"; break; case ("dl"): $starttoken = "<dl $this->style>"; $endtoken = "</dl>"; $listtoken = "<dd>"; $endlisttoken = ""; break; case ("br"): $starttoken = ""; $endtoken = ""; $listtoken = ""; $endlisttoken = ""; $this->separator = " "; break; case ("inline"): $starttoken = ""; $endtoken = ""; $listtoken = ""; $endlisttoken = ""; break; default: $starttoken = "<ul $this->style>"; $endtoken = "</ul>"; break; }			foreach( $lines as $line ) if( strlen( $line ) > 0 ) $list[] = "$listtoken". $this->stripWikiListTokens($line). "$endlisttoken"; wfProfileOut( 'Sorter2::makeList' ); if ($this->type =="ul" OR $this->type=="ol" OR $this->type=="dl"){ array_unshift($list,$starttoken); array_push($list,$endtoken); }			/*array_unshift($list,$this->title);*/ return $this->title.implode($this->separator, $list ); }		function parse( $text ) { wfProfileIn( 'Sorter2::parse' ); $title =& $this->parser->mTitle; $options =& $this->parser->mOptions; $output = $this->parser->parse( $text, $title, $options, true, false ); wfProfileOut( 'Sorter2::parse' ); return $output->getText; }	}

} else { echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); die( -1 ); }

?>