You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
8.1 KiB
279 lines
8.1 KiB
<?php
|
|
|
|
/**
|
|
* NWiki parser implementation
|
|
*
|
|
* @author Josep Arús
|
|
*
|
|
* @license http://www.gnu.org/copyleft/gpl.html GNU Public License
|
|
* @package mod_wiki
|
|
*/
|
|
|
|
include_once("wikimarkup.php");
|
|
|
|
class nwiki_parser extends wiki_markup_parser {
|
|
|
|
protected $blockrules = array(
|
|
'nowiki' => array(
|
|
'expression' => "/^<nowiki>(.*?)<\/nowiki>/ims",
|
|
'tags' => array(),
|
|
'token' => array('<nowiki>', '</nowiki>')
|
|
),
|
|
'header' => array(
|
|
'expression' => "/^\ *(={1,6})\ *(.+?)(={1,6})\ *$/ims",
|
|
'tags' => array(), //none
|
|
'token' => '='
|
|
),
|
|
'line_break' => array(
|
|
'expression' => "/^-{3,4}\s*$/im",
|
|
'tags' => array(),
|
|
'token' => '---'
|
|
),
|
|
'desc_list' => array(
|
|
'expression' => "/(?:^.+?\:.+?\;\n)+/ims",
|
|
'tags' => array(),
|
|
'token' => array(':', ';'),
|
|
'tag' => 'dl'
|
|
),
|
|
'table' => array(
|
|
'expression' => "/\{\|(.+?)\|\}/ims"
|
|
),
|
|
'tab_paragraph' => array(
|
|
'expression' => "/^(\:+)(.+?)$/ims",
|
|
'tag' => 'p'
|
|
),
|
|
'list' => array(
|
|
'expression' => "/^((?:\ *[\*|#]{1,5}\ *.+?)+)(\n\s*(?:\n|<(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)\ *\/?>))/ims",
|
|
'tags' => array(),
|
|
'token' => array('*', '#')
|
|
),
|
|
'paragraph' => array(
|
|
'expression' => "/^\ *((?:<(?!\ *\/?(?:h\d|pre|table|tbody|thead|tr|th|td|ul|li|ol|hr)\ *\/?>)|[^<\s]).+?)\n\s*\n/ims",
|
|
//not specified -> all tags (null or unset)
|
|
'tag' => 'p'
|
|
)
|
|
);
|
|
|
|
protected $tagrules = array(
|
|
'nowiki' => array(
|
|
'expression' => "/<nowiki>(.*?)<\/nowiki>/is",
|
|
'token' => array('<nowiki>', '</nowiki>')
|
|
),
|
|
'image' => array(
|
|
'expression' => "/\[\[image:(.+?)\|(.+?)\]\]/is",
|
|
'token' => array("[[image:", "|alt]]")
|
|
),
|
|
'attach' => array(
|
|
'expression' => "/\[\[attach:(.+?)\]\]/is",
|
|
'token' => array("[[attach:", "|name]]")
|
|
),
|
|
'link' => array(
|
|
'expression' => "/\[\[(.+?)\]\]/is",
|
|
'tag' => 'a',
|
|
'token' => array("[[", "]]")
|
|
),
|
|
'url_tag' => array(
|
|
'expression' => "/\[(.+?)\]/is",
|
|
'tag' => 'a',
|
|
'token' => array("[", "]")
|
|
),
|
|
'url' => array(
|
|
'expression' => "/(?<!=\")((?:https?|ftp):\/\/[^\s\n]+[^,\.\?!:;\"\'\n\ ])/i",
|
|
'tag' => 'a',
|
|
'token' => 'http://'
|
|
),
|
|
'italic' => array(
|
|
'expression' => "/\'{3}(.+?)(\'{3}(?:\'{2})?)/is",
|
|
'tag' => 'em',
|
|
'token' => array("'''", "'''")
|
|
),
|
|
'bold' => array(
|
|
'expression' => "/\'{2}(.+?)\'{2}/is",
|
|
'tag' => 'strong',
|
|
'token' => array("''", "''")
|
|
)
|
|
);
|
|
|
|
protected function after_parsing() {
|
|
parent::after_parsing();
|
|
}
|
|
|
|
/**
|
|
* Block hooks
|
|
*/
|
|
|
|
protected function header_block_rule($match) {
|
|
if($match[1] != $match[3]) {
|
|
return $match[0];
|
|
}
|
|
|
|
$num = strlen($match[1]);
|
|
|
|
return $this->generate_header($match[2], $num);
|
|
}
|
|
|
|
protected function table_block_rule($match) {
|
|
$rows = explode("\n|-", $match[1]);
|
|
$table = array();
|
|
foreach($rows as $r) {
|
|
$colsendline = explode("\n", $r);
|
|
$cols = array();
|
|
foreach($colsendline as $ce) {
|
|
$cols = array_merge($cols, $this->get_table_cells($ce));
|
|
}
|
|
|
|
if(!empty($cols)) {
|
|
$table[] = $cols;
|
|
}
|
|
}
|
|
return $this->generate_table($table);
|
|
}
|
|
|
|
private function get_table_cells($string) {
|
|
$string = ltrim($string);
|
|
$type = (!empty($string) && $string[0] == "!") ? 'header' : 'normal';
|
|
$string = substr($string, 1);
|
|
if(empty($string)) {
|
|
$normalcells = array();
|
|
}
|
|
else {
|
|
$normalcells = explode("||", $string);
|
|
}
|
|
$cells = array();
|
|
foreach($normalcells as $nc) {
|
|
$headercells = explode("!!", $nc);
|
|
$countheadercells = count($headercells);
|
|
for($i = 0; $i < $countheadercells; $i++) {
|
|
$cells[] = array($type, $headercells[$i]);
|
|
$type = 'header';
|
|
}
|
|
$type = 'normal';
|
|
}
|
|
|
|
return $cells;
|
|
}
|
|
|
|
protected function tab_paragraph_block_rule($match) {
|
|
$num = strlen($match[1]);
|
|
$text = $match[2];
|
|
$html = "";
|
|
for($i = 0; $i < $num - 1; $i++) {
|
|
$html = parser_utils::h('p', $html, array('class' => 'wiki_tab_paragraph'));
|
|
}
|
|
|
|
return parser_utils::h('p', $text, array('class' => 'wiki_tab_paragraph'));
|
|
}
|
|
|
|
protected function desc_list_block_rule($match) {
|
|
preg_match_all("/^(.+?)\:(.+?)\;$/ims", $match[0], $listitems, PREG_SET_ORDER);
|
|
|
|
$list = "";
|
|
foreach($listitems as $li) {
|
|
$term = $li[1];
|
|
$this->rules($term);
|
|
|
|
$description = $li[2];
|
|
$this->rules($description);
|
|
|
|
$list .= parser_utils::h('dt', $term).parser_utils::h('dd', $description);
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
|
|
/**
|
|
* Tag functions
|
|
*/
|
|
|
|
/**
|
|
* Bold and italic similar to creole...
|
|
*/
|
|
protected function italic_tag_rule($match) {
|
|
$text = $match[1];
|
|
if(strlen($match[2]) == 5) {
|
|
$text .= "''";
|
|
}
|
|
|
|
$this->rules($text, array('only' => array('bold')));
|
|
if(strpos($text, "''") !== false) {
|
|
$text = str_replace("''", $this->protect("''"), $text);
|
|
}
|
|
|
|
return array($text, array());
|
|
}
|
|
|
|
/**
|
|
* Link tag functions
|
|
*/
|
|
|
|
protected function link_tag_rule($match) {
|
|
return $this->format_link($match[1]);
|
|
}
|
|
|
|
protected function url_tag_tag_rule($match) {
|
|
$text = trim($match[1]);
|
|
if(preg_match("/(.+?)\|(.+)/is", $text, $matches)) {
|
|
$link = $matches[1];
|
|
$text = $matches[2];
|
|
}
|
|
else if(preg_match("/(.+?)\ (.+)/is", $text, $matches)) {
|
|
$link = $matches[1];
|
|
$text = $matches[2];
|
|
}
|
|
else {
|
|
$link = $text;
|
|
}
|
|
return array($this->protect($text), array('href' => $this->protect($link)));
|
|
}
|
|
|
|
protected function url_tag_rule($match) {
|
|
$url = $this->protect($match[1]);
|
|
$options = array('href' => $url);
|
|
|
|
return array($url, $options);
|
|
}
|
|
|
|
/**
|
|
* Attachments & images
|
|
*/
|
|
|
|
protected function image_tag_rule($match) {
|
|
return $this->format_image($match[1], $match[2]);
|
|
}
|
|
|
|
protected function attach_tag_rule($match) {
|
|
$parts = explode("|", $match[1]);
|
|
|
|
$url = array_shift($parts);
|
|
|
|
if(count($parts) > 0) {
|
|
$text = array_shift($parts);
|
|
}
|
|
|
|
$extension = substr($url, strrpos($url, "."));
|
|
$text = empty($text) ? $url : $text;
|
|
|
|
$imageextensions = array('jpg', 'jpeg', 'png', 'bmp', 'gif', 'tif');
|
|
if(in_array($extension, $imageextensions)) {
|
|
$align = 'left';
|
|
if(count($parts) > 0) {
|
|
switch(strtolower($text)) {
|
|
case 'right':
|
|
$align = 'right';
|
|
break;
|
|
case 'center':
|
|
$align = 'center';
|
|
break;
|
|
default:
|
|
$align = 'left';
|
|
}
|
|
$text = $parts[0];
|
|
}
|
|
return $this->format_image($url, $text, $text, $align);
|
|
}
|
|
else {
|
|
$url = $this->real_path($url);
|
|
return parser_utils::h('a', $text, array('href' => $url, 'class' => 'wiki-attachment'));
|
|
}
|
|
}
|
|
}
|
|
|