Location: PHPKode > scripts > Wiki-Parser > wikiparser.php
<?php
/**
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Kai Dorschner <the-hide@address.com>
 * @copyright Copyright 2010, Kai Dorschner
 * @license http://www.gnu.org/licenses/lgpl.html LGPLv3
 */

/**
 * Static wiki parser class.
 *
 * Parses a text for wiki elements selected via regex patterns set in the
 * {@see WikiElement::$pattern} subclasses of the WikiElement class.
 */
class WikiParser
{
	/**
	 * List of parsed elements.
	 *
	 * @access protected
	 * @var Array
	 */
	protected $elements = array
	(
		'HeadlineWikiElement',
		'UnderlineWikiElement',
		'StrongWikiElement',
		'StrikeWikiElement',
		'AnchorWikiElement',
		'ParagraphWikiElement',
		'BreakWikiElement'
	);

	public function __construct(Array $forbiddenElements = array())
	{
		foreach($forbiddenElements as $element)
		{
			if($k = array_search($element, $this->elements))
			{
				unset($this->elements[$k]);
			}
		}
	}

	public function parse($text, $wrapIn = null)
	{
		foreach($this->elements as $element)
		{
			if(class_exists($element))
			{
				$object = new $element();
				$text = preg_replace_callback($object->pattern, array(&$object, 'program'), $text);
			}
		}
		if($wrapIn)
		{
			if(preg_match('/[A-z]\w*/', $wrapIn))
			{
				$text = '<'.$wrapIn.'>'.$text.'</'.$wrapIn.'>';
			}
			else
			{
				throw new Exception('The wrapping element "'.$wrapIn.'" is invalid. It must neither be empty nor start with a digit nor contain special chars. Please verify your second argument in '.__METHOD__);
			}
		}
		return $text;
	}

	public function parseAsDomDocument($text, $wrapIn = 'wiki')
	{
		$x = new DomDocument();
		$x->loadXML($this->parse($text, $wrapIn));
		return $x;
	}
}

/**
 * General structure of a WikiElement.
 */
abstract class WikiElement
{
	/**
	 * Pattern for a wiki element.
	 *
	 * @access public
	 * @var String
	 */
	public $pattern = '/^.*$/';
	/**
	 * XML node name.
	 *
	 * @access protected
	 * @var String
	 */
	protected $name;

	/**
	 * This method can be inherited and extended for own purposes.
	 *
	 * @access public
	 * @return void
	 * @param Array $v Array of matches.
	 */
	public function program(Array $v)
	{
		return '<'.$this->getName().'>'.$v[1].'</'.$this->getName().'>';
	}

	/**
	 * Getter of {@see $name}
	 *
	 * @access protected
	 * @return String XML node name.
	 */
	protected function getName()
	{
		return $this->name;
	}
}

class UnderlineWikiElement extends WikiElement
{
	public $pattern = '/_{2}\s*([^_{2}]+)\s*_{2}/';
	protected $name = 'text';

	public function program(Array $v)
	{
		return '<'.$this->getName().' format="underline">'.$v[1].'</'.$this->getName().'>';
	}
}


class AnchorWikiElement extends WikiElement
{
	public $pattern = '/\[\[([^\]\]]+)\]\]/';
	protected $name = 'anchor';

	public function program(Array $v)
	{
		$external = false;
		$value = (count($array = explode('|', $v[1])) > 1 ? $array[1] : $array[0]);
		if(preg_match('/http:\/\/(.+)/', $array[0]))
		{
			$href = $array[0];
			$external = true;
		}
		else
		{
			if($GLOBALS['filesystem']->isFile($array[0]))
			{
				$href = sprintf($GLOBALS['pathformat'], $GLOBALS['linkprefix'], $array[0], $GLOBALS['media']);
			}
			else
			{
				return '';
			}
		}
		return '<'.$this->getName().' href="'.$href.'" '.($external ? ' location="external"':'').'>'.$value.'</'.$this->getName().'>';
	}
}

class StrikeWikiElement extends WikiElement
{
	public $pattern = '/-{2}\s*([^-{2}]+)\s*-{2}/';
	protected $name = 'text';

	public function program(Array $v)
	{
		return '<'.$this->getName().' format="strike">'.$v[1].'</'.$this->getName().'>';
	}
}

class StrongWikiElement extends WikiElement
{
	public $pattern = '/\'{3}\s*([^\'{3}]+)\s*\'{3}/';
	protected $name = 'text';

	public function program(Array $v)
	{
		return '<'.$this->getName().' format="strong">'.$v[1].'</'.$this->getName().'>';
	}
}

class BreakWikiElement extends WikiElement
{
	public $pattern = '/(.+)\n/';
	protected $name = 'linebreak';

	public function program(Array $v)
	{
		return $v[1].'<'.$this->getName().'/>';
	}

}

class ParagraphWikiElement extends WikiElement
{
	public $pattern = '/(?:(?:[\r\n]{1,}){2,})?\s*(.+)/';
	protected $name = 'paragraph';
}
Return current item: Wiki-Parser