Extension:Sort2

From MediaWiki.org
Jump to: navigation, search

Script error

MediaWiki extensions manual
Crystal Clear action run.png
Sort2

Release status: stable

Implementation Tag
Description Generates sorted lists based on existing token lists or separate lines/paragraphs
Author(s) Kaeptn00
Latest version 1.1 (2006-08-24)
MediaWiki 1.7.1
Database changes No
License No license specified
Download Download
Changelog

Translate the Sort2 extension if it is available at translatewiki.net

Check usage and version matrix; code metrics

The Sort2 generates sorted lists based on existing token lists or separate lines/paragraphs. The source code of Extension:Sort authored by Rob Church was taken from the Subversion repository and modified to fit my needs and expectations.

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[edit | edit source]

The purpose of this extension is to sort lists.

Features[edit | edit source]

  • 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[edit | edit source]

You just need to surround the list you want to sort or convert by the tags <sort2></sort2>. 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 : 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[edit | edit source]

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 ...

</sort2>

Options[edit | edit source]

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=""
The option type takes a string as argument. It can be one of:
  • ul, list is generated as unordered list
  • ol, list is generated as ordered list
  • dl, list is generated as definition list
  • br, list is generated as separate lines
  • inline, list is generated as one item after the other separated by separator (see below)
Note: This option was named class in the original version but I found this too confusing because class normaly is used for a style sheet class.
order=""
The option order takes a string as argument. It can be one of:
  • asc, sorting direction is ascending
  • desc, sorting direction is descending
  • none, no sorting of the list. This one is useful for converting list types. For instance some paragraphs to an unordered list without changing order.
casesense=""
The option casesense takes a string as argument. It can be one of:
  • false, sorting is case insensitive. Uses php natcasesort()
  • true, sorting is case sensitive. Uses php natsort()
separator=""
The option separator takes a string as argument. It is only evaluated when type is set to inline. The list items are separated by the char(s) you give as argument to this option. Since the parser eats spaces using php trim(), I had to introduce a pseudo-entity to be able to render separators like ", " or " | ". If you want a space at the end or beginning of the separator, you have to use &sp;.
Examples:
separator=",&sp;"
separator="&sp;|&sp;"
Note: You can not pass HTML or wikisyntax as an argument. Just in case you wonder why there is this extra type="br" option.
style=""
The option style takes a string as argument. It is only evaluated when type is set to ul, ol, or dl. 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 list-style-type and do this by setting list-style to none , also set list-style-image to none, 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 $wgSort2AllowStyles = false in LocalSettings.php. More about this on the discussion page.
start=""
The option start takes an integer as argument. It is only evaluated when type is set to ol and controls the starting number of the ordered list.
title=""
The option title 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 &sp;.

Examples[edit | edit source]

The code Results in
<sort2>
*2
*1
*ball
*AMD
*BMW
*argument
</sort2>
  • 1
  • 2
  • AMD
  • argument
  • ball
  • BMW
<sort2 casesense="true">
#2
#1
#ball
#AMD
#BMW
#argument
</sort2>
  • 1
  • 2
  • AMD
  • BMW
  • argument
  • ball
<sort2 type="inline" separator="&sp;|&sp;" title="A list:&sp;">
2
1
ball
AMD
BMW
argument
</sort2>

A list: 1 | 2 | AMD | argument | ball | BMW

<sort2 type="ol">
This is sample paragraph

And this is another one

Yet another one.
</sort2>
  1. And this is another one
  2. This is sample paragraph
  3. Yet another one.

I am sure you get the idea.

Restrictions[edit | edit source]

  • The extension does not sense the original type of the list. So ol gets converted to a ul 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.
<sort>
* Item 1
** Subitem
* Item 2
** Subitem
</sort>

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

Installation[edit | edit source]

Create a file named Sort2.php in the extensions directory and copy the source code to that file. Insert the following line at the end of your LocalSettings.php file:

require_once("$IP/extensions/Sort2.php");

Version history[edit | edit source]

V1.1, 24.08.2006
Added style option for ul,ol and dl
Added start option for ol
Added title option
Changed rendering method from wikisyntax (*,#, and ;,:) to HTML syntax (ul, ol, and dl,dd) to be able to add more features
V1.0, 16.08.2006
Initial release
Minor bug corrected on 20.08.2006

Source Code[edit | edit source]

<?php
 
/**
 * Parser hook extension adds a <sort2> 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',
        'description' => 'Adds a <tt>&lt;sort2&gt;</tt> tag for sorting lists',
        '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 = "<br />";
					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 );
}

See also[edit | edit source]