Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Continued refactor

  • Loading branch information...
commit edeb95578c5a44ed130ee5b05043f763842d7201 1 parent f5b355c
Niko Pahajoki authored
View
206 Sources/Wiki/Parser/Bracket.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ *
+ */
+
+/**
+ *
+ */
+class Wiki_Parser_Bracket extends Wiki_Parser_SubParser
+{
+ /**
+ *
+ */
+ const WIKILINK = 1;
+
+ /**
+ *
+ */
+ const TEMPLATE = 2;
+
+ /**
+ *
+ */
+ const TEMPLATE_PARAM = 3;
+
+ /**
+ *
+ */
+ const HASHTAG = 4;
+
+ /**
+ *
+ */
+ const FUNC = 5;
+
+ /**
+ *
+ */
+ const VARIABLE = 6;
+
+ /**
+ *
+ */
+ const P_SEP = 1;
+
+ /**
+ *
+ */
+ const N_SEP = 2;
+
+ /**
+ *
+ */
+ const F_SEP = 3;
+
+ /**
+ *
+ */
+ static public $rules = array(
+ '[' => array(
+ 'close' => ']',
+ 'min' => 2,
+ 'max' => 2,
+ 'names' => array(
+ 2 => self::WIKILINK,
+ ),
+ ),
+ '{' => array(
+ 'close' => '}',
+ 'min' => 2,
+ 'max' => 3,
+ 'names' => array(
+ 2 => self::TEMPLATE,
+ 3 => self::TEMPLATE_PARAM,
+ ),
+ ),
+ );
+
+ /**
+ *
+ */
+ static public function getStartChars()
+ {
+ return array_keys(self::$rules);
+ }
+
+ /**
+ *
+ */
+ static public function parseStart($parser, $curChar, &$text, &$i)
+ {
+ $rule = self::$rules[$curChar];
+
+ $len = strspn($text, $curChar, $i);
+
+ if ($len >= $rule['min'])
+ {
+ $i += $len;
+ return new self($parser, $curChar, $len);
+ }
+ else
+ return false;
+ }
+
+ protected $char;
+ protected $len;
+ protected $rule;
+ protected $type;
+
+ /**
+ *
+ */
+ public function __construct(Wiki_Parser $parser, $char, $len)
+ {
+ $this->parser = $parser;
+
+ $this->rule = self::$rules[$char];
+ $this->char = $char;
+ $this->len = $len;
+ $this->is_complete = false;
+ }
+
+ /**
+ *
+ */
+ public function getCloseChar()
+ {
+ return $this->rule['close'];
+ }
+
+ /**
+ *
+ */
+ public function getWantedChars()
+ {
+ if ($this->char == '{')
+ return array('|' => self::P_SEP, '=' => self::N_SEP, ':' => self::F_SEP);
+ else
+ return array('|' => self::P_SEP, '=' => self::N_SEP);
+ }
+
+ /**
+ *
+ */
+ public function checkEnd($parser, &$stack, $curChar, &$text, &$i)
+ {
+ $maxLen = $this->len;
+ $len = strspn($text, $curChar, $i, $maxLen);
+
+ if ($len > $this->rule['max'])
+ $matchLen = $this->rule['max'];
+ else
+ {
+ $matchLen = $len;
+
+ while ($matchLen > 0 && !isset($this->rule['names'][$matchLen]))
+ $matchLen--;
+ }
+
+ if ($matchLen <= 0)
+ {
+ $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($curChar, $len));
+ $i += $len;
+
+ return false;
+ }
+
+ // There's still opening tags left to search end for
+ if ($matchLen < $this->len)
+ {
+ $open = $this->len - $matchLen;
+ $element->modifyLen($matchLen);
+
+ // Nested tag?
+ if ($open >= $this->rule['min'])
+ $target = new self($this->parser, $curChar, $open);
+ // or just unnecassary character?
+ else
+ {
+ $target = array_pop($stack);
+ $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($element->char, $open));
+ }
+ }
+ else
+ $target = array_pop($stack);
+
+ if (!$this->createElement())
+ {
+ $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($this->char, $this->len));
+ $this->fail($target);
+ $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($curChar, $matchLen));
+ }
+
+ $i += $matchLen;
+
+ return $target;
+ }
+
+ /**
+ *
+ */
+ function createElement()
+ {
+ return false;
+ }
+}
View
4 Sources/Wiki/Parser/Core.php
@@ -29,12 +29,12 @@ class Wiki_Parser_Core
// Rules for WikiElement (such as Wikilinks etc.)
const ELEMENT = 40;
- const ELEMENT_OPEN = 41;
+ /*const ELEMENT_OPEN = 41;
const ELEMENT_NAME = 42;
const ELEMENT_PARAM_NAME = 43;
const ELEMENT_NEW_PARAM = 44;
const ELEMENT_SEMI_COLON = 45;
- const ELEMENT_CLOSE = 49;
+ const ELEMENT_CLOSE = 49;*/
// Behaviour Switch
const BEHAVIOUR_SWITCH = 50;
View
158 Sources/Wiki/Parser/Parser.php
@@ -9,6 +9,13 @@
class Wiki_Parser
{
/**
+ *
+ */
+ public static $subParsers = array(
+ 'Wiki_Parser_Bracket',
+ );
+
+ /**
* Page variable containing WikiPage class.
*/
public $page;
@@ -27,12 +34,7 @@ class Wiki_Parser
*
*/
public $pageOptions = array();
-
- /**
- *
- */
- public $tableOfContents;
-
+
/**
* Contains used html ids to prevent duplicates
*/
@@ -210,7 +212,19 @@ private function __parse(Wiki_Parser_SectionContainer $target, $text, $is_templa
$text = str_replace(array("\r\n", "\r", '<br />', '<br>', '<br/>'), "\n", $text);
- $searchBase = "<[{#\n_";
+ //$searchBase = "<[{#\n_";
+ $searchBase = "\n";
+
+ $subParserMap = array();
+
+ foreach (self::$subParsers as $subparser)
+ {
+ foreach (call_user_func(array($subparser, 'getStartChars')) as $chr)
+ {
+ $searchBase .= $chr;
+ $subParserMap[$chr][] = $subparser;
+ }
+ }
$textLen = strlen($text);
@@ -220,12 +234,11 @@ private function __parse(Wiki_Parser_SectionContainer $target, $text, $is_templa
while ($i <= $textLen)
{
$search = $searchBase;
- $closeTag = '';
- if ($target instanceof WikiElement_Parser)
+ if ($target instanceof Wiki_Parser_SubParser)
{
- $search .= $target->rule['close'] . (empty($target->rule['no_param']) ? '|=' : '') . ($target->rule['close'] == '}' ? ':' : '');
- $closeTag = $target->rule['close'];
+ $closeChar = $target->getCloseChar();
+ $search .= $closeChar . implode('', array_keys($target->getWantedChars()));
}
else
{
@@ -427,120 +440,37 @@ private function __parse(Wiki_Parser_SectionContainer $target, $text, $is_templa
$target->throwContent(Wiki_Parser_Core::NEW_LINE, '<br />', "\n");
}
- if (false)
+ // Subparsers?
+ if (!empty($subParserMap[$curChar]))
{
-
+ foreach ($subParserMap[$curChar] as $subparser)
+ {
+ $parse_start = call_user_func_array(array($subparser, 'parseStart'), array($this, $curChar, &$text, &$i));
+
+ if ($parse_start)
+ {
+ $stack[] = $target;
+ $target = $parse_start;
+ continue 2;
+ }
+ unset($parse_start);
+ }
}
- /*
+
// Close char?
- if ($curChar == $closeTag)
+ if ($target instanceof Wiki_Parser_SubParser && $curChar == $closeChar)
{
- $maxLen = $target->len;
- $len = strspn($text, $curChar, $i, $maxLen);
-
- $rule = $target->rule;
-
- if ($len > $rule['max'])
- $matchLen = $rule['max'];
- else
+ if ($res = $target->checkEnd($this, $stack, $curChar, $text, $i))
{
- $matchLen = $len;
-
- while ($matchLen > 0 && !isset($target->rule['names'][$matchLen]))
- $matchLen--;
- }
-
- if ($matchLen <= 0)
- {
- $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($curChar, $len));
- $i += $len;
+ unset($target);
+ $target = $res;
continue;
}
-
- // Tell element that it was closed
- $target->throwContent(Wiki_Parser_Core::ELEMENT_CLOSE, '', str_repeat($curChar, $matchLen));
- $element = $target;
-
- // There's still opening tags left to search end for
- if ($matchLen < $element->len)
- {
- $open = $element->len - $matchLen;
- $element->modifyLen($matchLen);
-
- // Nested tag?
- if ($open >= $element->rule['min'])
- {
- $target = new WikiElement_Parser($this, $curChar, $open);
- $target->throwContent(Wiki_Parser_Core::ELEMENT_OPEN, str_repeat($element->char, $open));
- }
- // or just unnecassary character?
- else
- {
- $target = array_pop($stack);
- $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($element->char, $open));
- }
- }
- else
- $target = array_pop($stack);
-
- // Tell elment that it's really complete and let it finalize.
- $element->throwContentTo($target);
-
- // Not sure if necassary but let's do it anyway.
- unset($element);
-
- $i += $matchLen;
}
- // Start character for WikiElement
+ /*// Start character for WikiElement
elseif ($this->parse_bbc && isset(WikiElement_Parser::$rules[$curChar]))
{
- $rule = WikiElement_Parser::$rules[$curChar];
- $len = strspn($text, $curChar, $i);
-
- if ($len >= $rule['min'])
- {
- // Hash tag is special case
- if (!empty($target->rule['has_name']))
- {
- $nameLen = strcspn($text, ' ', $i);
-
- if (strpos($text, " ", $i) !== false && strpos($text, "\n", $i) !== false)
- {
- $item_name = strtolower(substr($text, $i + 1, $nameLen - 1));
-
- // If no such has tag exists
- if (!isset(Wiki_Parser_Core::$hashTags[$item_name]))
- {
- $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($curChar, $len));
- }
- else
- {
- $stack[] = $target;
-
- $target = new WikiElement_Parser($this, $curChar, $len);
- $target->throwContent(Wiki_Parser_Core::ELEMENT_NAME, $item_name);
-
- $i += $nameLen;
- }
- }
- else
- {
- $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($curChar, $len));
- }
- }
- else
- {
- $stack[] = $target;
- $target = new WikiElement_Parser($this, $curChar, $len);
- }
- }
- else
- {
- $target->throwContent(Wiki_Parser_Core::TEXT, str_repeat($curChar, $len));
- }
-
- $i += $len;
}
// Handle lists
elseif ($this->parse_bbc && $is_new_line && in_array($curChar, WikiList_Parser::$listTypes))
View
120 Sources/Wiki/Parser/SubParser.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ *
+ */
+
+/**
+ *
+ */
+abstract class Wiki_Parser_SubParser
+{
+ /**
+ * @var Wiki_Parser
+ */
+ protected $parser;
+
+ /**
+ *
+ */
+ private $content = array();
+
+ /**
+ *
+ */
+ static public function getStartChars()
+ {
+ trigger_error('getStartChars() not implemented!', E_USER_ERROR);
+ }
+
+ /**
+ *
+ */
+ static public function parseStart($parser, $curChar, &$text, &$i)
+ {
+ trigger_error('parseStart() not implemented!', E_USER_ERROR);
+ }
+
+ /**
+ *
+ */
+ abstract function getCloseChar();
+
+ /**
+ *
+ */
+ abstract function getWantedChars();
+
+ /**
+ *
+ */
+ abstract function checkEnd($parser, &$stack, $curChar, &$text, &$i);
+
+ /**
+ * Adds content to this tag
+ */
+ public final function throwContent($type, $content = '', $unparsed = null, $additonal = array())
+ {
+ $i = count($this->content);
+
+ if ($i > 0 && $type == Wiki_Parser_Core::TEXT && $this->content[$i - 1]['type'] == Wiki_Parser_Core::TEXT && empty($this->content[$i - 1]['additional']) && empty($additonal))
+ {
+ $this->content[$i - 1]['content'] .= $content;
+
+ // Does this part have "unparsed" content?
+ if (!empty($this->content[$i - 1]['unparsed']))
+ $this->content[$i - 1]['unparsed'] .= empty($unparsed) ? $content : $unparsed;
+ // Copy parsed as unparsed if we have but there is none. Done to save memory!
+ elseif (empty($this->content[$i - 1]['unparsed']) && !empty($unparsed))
+ $this->content[$i - 1]['unparsed'] = $this->content[$i - 1]['content'] . $unparsed;
+
+ return;
+ }
+
+ $this->content[$i] = array(
+ 'type' => $type,
+ 'content' => $content,
+ 'unparsed' => $unparsed,
+ 'additional' => $additonal,
+ );
+ }
+
+ /**
+ *
+ */
+ public final function throwContentArray($array)
+ {
+ foreach ($array as $cont)
+ $this->throwContent($cont['type'], $cont['content'], $cont['unparsed'], $cont['additional']);
+ }
+
+ /**
+ * Return original unparsed content
+ */
+ public function getUnparsed()
+ {
+ $return = '';
+ foreach ($this->content as $c)
+ $return .= !empty($c['unparsed'])? $c['unparsed'] : $c['content'];
+ return $return;
+ }
+
+ /**
+ * Fails
+ */
+ protected function fail($target)
+ {
+ global $context;
+
+ foreach ($this->content as $c)
+ {
+ $target->throwContent(
+ $c['type'],
+ $c['content'],
+ $c['unparsed'],
+ $c['additional']
+ );
+ }
+ }
+}
+
+?>
View
19 Sources/WikiExt-Base.php
@@ -13,10 +13,29 @@
*/
class WikiExtension
{
+ /**
+ *
+ */
static protected $variables = array();
+
+ /**
+ *
+ */
static protected $functions = array();
+
+ /**
+ *
+ */
static protected $xmlTags = array();
+
+ /**
+ *
+ */
static protected $magicwords = array();
+
+ /**
+ *
+ */
static protected $specialPages = array();
/**
Please sign in to comment.
Something went wrong with that request. Please try again.