From 3fd0b6768bf7f649d77c937e399f578d7add7637 Mon Sep 17 00:00:00 2001
From: andi
Date: Fri, 29 Apr 2005 13:49:25 +0200
Subject: comments and cleanup
darcs-hash:20050429114925-9977f-ff5b6dcf702b533a2dd64397522da7cd7b97f092.gz
---
inc/confutils.php | 4 +
inc/format.php | 593 -----------------------------------
inc/format.php.bak | 593 +++++++++++++++++++++++++++++++++++
inc/parser.php | 862 ---------------------------------------------------
inc/parser.php.bak | 862 +++++++++++++++++++++++++++++++++++++++++++++++++++
inc/parser/xhtml.php | 329 +++++++-------------
inc/parserutils.php | 1 -
7 files changed, 1578 insertions(+), 1666 deletions(-)
delete mode 100644 inc/format.php
create mode 100644 inc/format.php.bak
delete mode 100644 inc/parser.php
create mode 100644 inc/parser.php.bak
(limited to 'inc')
diff --git a/inc/confutils.php b/inc/confutils.php
index 4a38eeaac..a0ad322fb 100644
--- a/inc/confutils.php
+++ b/inc/confutils.php
@@ -98,7 +98,11 @@ function getInterwiki() {
/**
* Builds a hash from a configfile
*
+ * If $lower is set to true all hash keys are converted to
+ * lower case.
+ *
* @author Harry Fuecks
+ * @author Andreas Gohr
*/
function confToHash($file,$lower=false) {
$conf = array();
diff --git a/inc/format.php b/inc/format.php
deleted file mode 100644
index 0a20b566c..000000000
--- a/inc/format.php
+++ /dev/null
@@ -1,593 +0,0 @@
-
- * @deprecated part of the XHTML renderer
- */
-
-trigger_error('deprecated parser.php included');
-
- if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
- require_once(DOKU_INC.'conf/dokuwiki.php');
- require_once(DOKU_INC.'inc/common.php');
-
-
-/**
- * Assembles all parts defined by the link formater below
- * Returns HTML for the link
- *
- * @author Andreas Gohr
- */
-function format_link_build($link){
- //make sure the url is XHTML compliant (skip mailto)
- if(substr($link['url'],0,7) != 'mailto:'){
- $link['url'] = str_replace('&','&',$link['url']);
- $link['url'] = str_replace('&','&',$link['url']);
- }
- //remove double encodings in titles
- $link['title'] = str_replace('&','&',$link['title']);
-
- $ret = '';
- $ret .= $link['pre'];
- $ret .= ' with proper special char encoding
- * $link['class'] CSS class to set on link
- * $link['target'] which target to use (blank) for current window
- * $link['style'] Additonal style attribute set with style=""
- * $link['title'] Title to set with title=""
- * $link['pre'] HTML to prepend to link
- * $link['suf'] HTML to append to link
- * $link['more'] Additonal HTML to include into the anchortag
- *
- */
-
-/**
- * format wiki links
- *
- * @author Andreas Gohr
- */
-function format_link_wiki($link){
- global $conf;
- global $ID; //we use this to get the current namespace
- //obvious setup
- $link['target'] = $conf['target']['wiki'];
- $link['style'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
-
- $ns = getNS($ID);
-
- //if links starts with . add current namespace
- if(strpos($link['url'],'.')===0){
- $link['url'] = $ns.':'.substr($link['url'],1);
- }
-
- //if link contains no namespace. add current namespace (if any)
- if($ns !== false && strpos($link['url'],':') === false){
- $link['url'] = $ns.':'.$link['url'];
- }
-
- //keep hashlink if exists
- list($link['url'],$hash) = split('#',$link['url'],2);
- $hash = cleanID($hash);
-
- $file = wikiFN($link['url']);
- $url = cleanID($link['url']);
-
- //check alternative plural/nonplural form
- if(!@file_exists($file) && $conf['autoplural']){
- if(substr($url,-1) == 's'){
- $try = substr($url,0,-1);
- }else{
- $try = $url.'s';
- }
- $tryfile = wikiFN($try);
- if(@file_exists($tryfile)){
- $file = $tryfile;
- $url = $try;
- }
- }
-
- //set class and name depending on file existence and content
- if(@file_exists($file)){
- $link['class']="wikilink1";
- if ($conf['useheading'] && empty($link['name'])) {
- $hl = getFirstHeading(io_readFile($file));
- if ($hl) $link['name'] = $hl;
- }
- }else{
- $link['class']="wikilink2";
- }
-
- //if no name set yet, use (unclean) link without namespace
- if(empty($link['name'])){
- if($conf['useslash']){
- $nssep = '[:;/]';
- }else{
- $nssep = '[:;]';
- }
- $link['name'] = preg_replace('!.*'.$nssep.'!','',$link['url']);
- }
- $link['name'] = htmlspecialchars($link['name']);
-
- //set title
- $link['title'] = $url;
-
- //construct the full link
- $link['url'] = wl($url);
-
- //add hash if exists
- if($hash) $link['url'] .= '#'.$hash;
-
- return $link;
-}
-
-/**
- * format external URLs
- *
- * @author Andreas Gohr
- */
-function format_link_externalurl($link){
- global $conf;
- //simple setup
- $link['class'] = 'urlextern';
- $link['target'] = $conf['target']['extern'];
- $link['pre'] = '';
- $link['suf'] = '';
- $link['style'] = '';
- $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
- $link['url'] = $link['url']; //keep it
- $link['title'] = htmlspecialchars($link['url']);
- if(!$link['name']) $link['name'] = htmlspecialchars($link['url']);
- if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"';
- //thats it :-)
- return $link;
-}
-
-/**
- * format windows share links
- *
- * this only works in IE :-(
- *
- * @author Andreas Gohr
- */
-function format_link_windows($link){
- global $conf;
- global $lang;
- //simple setup
- $link['class'] = 'windows';
- $link['target'] = $conf['target']['windows'];
- $link['pre'] = '';
- $link['suf'] = '';
- $link['style'] = '';
- //Display error on browsers other than IE
- $link['more'] = 'onclick="if(document.all == null){alert(\''.htmlspecialchars($lang['nosmblinks'],ENT_QUOTES).'\');}" onkeypress="if(document.all == null){alert(\''.htmlspecialchars($lang['nosmblinks'],ENT_QUOTES).'\');}"';
-
- if(!$link['name']) $link['name'] = htmlspecialchars($link['url']);
- $link['title'] = htmlspecialchars($link['url']);
- $link['url'] = str_replace('\\','/',$link['url']);
- $link['url'] = 'file:///'.$link['url'];
-
- return $link;
-}
-
-/**
- * format email addresses
- *
- * @author Andreas Gohr
- */
-function format_link_email($link){
- global $conf;
- //simple setup
- $link['class'] = 'mail';
- $link['target'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- $link['style'] = '';
- $link['more'] = '';
-
- $link['name'] = htmlspecialchars($link['name']);
-
- //shields up
- if($conf['mailguard']=='visible'){
- //the mail name gets some visible encoding
- $link['url'] = str_replace('@',' [at] ',$link['url']);
- $link['url'] = str_replace('.',' [dot] ',$link['url']);
- $link['url'] = str_replace('-',' [dash] ',$link['url']);
- }elseif($conf['mailguard']=='hex'){
- for ($x=0; $x < strlen($link['url']); $x++) {
- $encode .= '' . bin2hex($link['url'][$x]).';';
- }
- $link['url'] = $encode;
- }
-
- $link['title'] = $link['url'];
- if(!$link['name']) $link['name'] = $link['url'];
- $link['url'] = 'mailto:'.$link['url'];
-
- return $link;
-}
-
-/**
- * format interwiki links
- *
- * @author Andreas Gohr
- */
-function format_link_interwiki($link){
- global $conf;
-
- //obvious ones
- $link['class'] = 'interwiki';
- $link['target'] = $conf['target']['interwiki'];
- $link['pre'] = '';
- $link['suf'] = '';
- $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
-
- //get interwiki short name
- list($wiki,$link['url']) = split('>',$link['url'],2);
- $wiki = strtolower(trim($wiki)); //always use lowercase
- $link['url'] = trim($link['url']);
- if(!$link['name']) $link['name'] = $link['url'];
-
- //encode special chars
- $link['name'] = htmlspecialchars($link['name']);
-
- //set default to google
- $url = 'http://www.google.com/search?q=';
- $ico = 'google';
-
- // Initialize as NULL - for the first fn call
- static $iwlinks = NULL;
-
- // load interwikilinks if needed
- if (!$iwlinks) $iwlinks = file('conf/interwiki.conf');
-
- //add special case 'this'
- $iwlinks[] = 'this '.DOKU_URL.'{NAME}';
-
- //go through iwlinks and find URL for wiki
- foreach ($iwlinks as $line){
- $line = preg_replace('/#.*/','',$line); //skip comments
- $line = trim($line);
- list($iw,$iwurl) = preg_split('/\s+/',$line);
- if(!$iw or !$iwurl) continue; //skip broken or empty lines
- //check for match
- if(strtolower($iw) == $wiki){
- $ico = $wiki;
- $url = $iwurl;
- break;
- }
- }
-
- //if ico exists set additonal style
- if(@file_exists('interwiki/'.$ico.'.png')){
- $link['style']='background: transparent url('.DOKU_BASE.'interwiki/'.$ico.'.png) 0px 1px no-repeat;';
- }elseif(@file_exists('interwiki/'.$ico.'.gif')){
- $link['style']='background: transparent url('.DOKU_BASE.'interwiki/'.$ico.'.gif) 0px 1px no-repeat;';
- }
-
- //do we stay at the same server? Use local target
- if( strpos($url,DOKU_URL) === 0 ){
- $link['target'] = $conf['target']['wiki'];
- }
-
- //replace placeholder
- if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#',$url)){
- //use placeholders
- $url = str_replace('{URL}',urlencode($link['url']),$url);
- $url = str_replace('{NAME}',$link['url'],$url);
- $parsed = parse_url($link['url']);
- if(!$parsed['port']) $parsed['port'] = 80;
- $url = str_replace('{SCHEME}',$parsed['scheme'],$url);
- $url = str_replace('{HOST}',$parsed['host'],$url);
- $url = str_replace('{PORT}',$parsed['port'],$url);
- $url = str_replace('{PATH}',$parsed['path'],$url);
- $url = str_replace('{QUERY}',$parsed['query'],$url);
- $link['url'] = $url;
- }else{
- //default
- $link['url'] = $url.urlencode($link['url']);
- }
-
- $link['title'] = htmlspecialchars($link['url']);
-
- //done :-)
- return $link;
-}
-
-/**
- * format embedded media
- *
- * @author Andreas Gohr
- */
-function format_link_media($link){
- global $conf;
- global $ID;
-
- $link['class'] = 'media';
- $link['style'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
- $class = 'media';
-
- list($link['name'],$title) = split('\|',$link['name'],2);
- $t = htmlspecialchars($title);
-
- //set alignment from spaces
- if(substr($link['name'],0,1)==' ' && substr($link['name'],-1,1)==' '){
- $link['pre'] = "
\n";
- $link['suf'] = "
\n";
- }elseif(substr($link['name'],0,1)==' '){
- #$a = ' align="right"';
- $class = 'mediaright';
- }elseif(substr($link['name'],-1,1)==' '){
- #$a = ' align="left"';
- $class = 'medialeft';
- }else{
- $a = ' align="middle"';
- }
- $link['name'] = trim($link['name']);
-
- //split into src and parameters (using the very last questionmark)
- $pos = strrpos($link['name'], '?');
- if($pos !== false){
- $src = substr($link['name'],0,$pos);
- $param = substr($link['name'],$pos+1);
- }else{
- $src = $link['name'];
- $param = '';
- }
-
- //parse width and height
- if(preg_match('#(\d+)(x(\d+))?#i',$param,$size)){
- if($size[1]) $w = $size[1];
- if($size[3]) $h = $size[3];
- }
-
- //namespace mangling for internal images
- if(!preg_match('#^https?://#i',$src)){
- $ns = getNS($ID);
- //if src starts with . add current namespace
- if(strpos($src,'.') === 0){
- $src = $ns.':'.substr($src,1);
- }
- //if src contains no namespace add current namespace if any
- if($ns !== false && strpos($src,':') === false ){
- $src = $ns.':'.$src;
- }
- }
-
- //check for nocache/recache param
- preg_match('/(nocache|recache)/i',$param,$cachemode);
-
- //do image caching, resizing and src rewriting
- $cache = $src;
- $isimg = img_cache($cache,$src,$w,$h,$cachemode[1]);
-
- //set link to src if none given
- if(!$link['url']){
- $link['url'] = $src;
- $link['target'] = $conf['target']['media'];
- }
-
- //prepare name
- if($isimg){
- $link['name'] = ' ';
- }else{
- if($t){
- $link['name'] = $t;
- }else{
- $link['name'] = basename($src);
- }
- }
-
- return $link;
-}
-
-/**
- * Build an URL list from a RSS feed
- *
- * Uses magpie
- *
- * @author Andreas Gohr
- */
-function format_rss($url){
- global $lang;
- define('MAGPIE_CACHE_ON', false); //we do our own caching
- define('MAGPIE_DIR', 'inc/magpie/');
- define('MAGPIE_OUTPUT_ENCODING','UTF-8'); //return all feeds as UTF-8
- require_once(MAGPIE_DIR.'/rss_fetch.inc');
-
- //disable warning while fetching
- $elvl = error_reporting(E_ERROR);
- $rss = fetch_rss($url);
- error_reporting($elvl);
-
- $ret = '';
- return $ret;
-}
-
-/**
- * Create cache images
- *
- * @author Andreas Gohr
- */
-function img_cache(&$csrc,&$src,&$w,&$h,$cachemode){
- global $conf;
-
- //container for various paths
- $f['full']['web'] = $src;
- $f['resz']['web'] = $src;
- $f['full']['fs'] = $src;
- $f['resz']['fs'] = $src;
-
- //generate cachename
- $md5 = md5($src);
-
- //check if it is an image
- if(preg_match('#\.(jpe?g|gif|png)$#i',$src,$match)){
- $ext = strtolower($match[1]);
- $isimg = true;
- }
-
- //check if it is external or a local mediafile
- if(preg_match('#^([a-z0-9]+?)://#i',$src)){
- $isurl = true;
- }else{
- $src = str_replace(':','/',$src);
- $src = utf8_encodeFN($src);
- $f['full']['web'] = $conf['mediaweb'].'/'.$src;
- $f['resz']['web'] = $conf['mediaweb'].'/'.$src;
- $f['full']['fs'] = $conf['mediadir'].'/'.$src;
- $f['resz']['fs'] = $conf['mediadir'].'/'.$src;
- }
-
- //download external images if allowed
- if($isurl && $isimg && $cachemode != 'nocache'){
- $cache = $conf['mediadir']."/_cache/$md5.$ext";
- if ( ($cachemode == 'recache' && io_download($src,$cache)) ||
- @file_exists($cache) || io_download($src,$cache)){
- $f['full']['web'] = $conf['mediaweb']."/_cache/$md5.$ext";
- $f['resz']['web'] = $conf['mediaweb']."/_cache/$md5.$ext";
- $f['full']['fs'] = $conf['mediadir']."/_cache/$md5.$ext";
- $f['resz']['fs'] = $conf['mediadir']."/_cache/$md5.$ext";
- $isurl = false;
- }
- }
-
- //for local images (cached or media) do resizing
- if($isimg && (!$isurl)){
- if($w){
- $info = getImageSize($f['full']['fs']);
- //if $h not given calcualte it with correct aspect ratio
- if(!$h){
- $h = round(($w * $info[1]) / $info[0]);
- }
- $cache = $conf['mediadir'].'/_cache/'.$md5.'.'.$w.'x'.$h.'.'.$ext;
- //delete outdated cachefile
- if(@file_exists($cache) && (filemtime($cache)
- */
-function img_resize($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){
- global $conf;
-
- if($conf['gdlib'] < 1) return false; //no GDlib available or wanted
-
- // create an image of the given filetype
- if ($ext == 'jpg' || $ext == 'jpeg'){
- if(!function_exists("imagecreatefromjpeg")) return false;
- $image = @imagecreateFromjpeg($from);
- }elseif($ext == 'png') {
- if(!function_exists("imagecreatefrompng")) return false;
- $image = @imagecreatefrompng($from);
- }elseif($ext == 'gif') {
- if(!function_exists("imagecreatefromgif")) return false;
- $image = @imagecreatefromgif($from);
- }
- if(!$image) return false;
-
- if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor")){
- $newimg = @imagecreatetruecolor ($to_w, $to_h);
- }
- if(!$newimg) $newimg = @imagecreate($to_w, $to_h);
- if(!$newimg) return false;
-
- // create cachedir
- io_makeFileDir($to);
-
- //try resampling first
- if(function_exists("imagecopyresampled")){
- if(!@imagecopyresampled($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h)) {
- imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h);
- }
- }else{
- imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h);
- }
-
- if ($ext == 'jpg' || $ext == 'jpeg'){
- if(!function_exists("imagejpeg")) return false;
- return imagejpeg($newimg, $to, 70);
- }elseif($ext == 'png') {
- if(!function_exists("imagepng")) return false;
- return imagepng($newimg, $to);
- }elseif($ext == 'gif') {
- if(!function_exists("imagegif")) return false;
- return imagegif($newimg, $to);
- }
-
- return false;
-}
-
-
-//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/format.php.bak b/inc/format.php.bak
new file mode 100644
index 000000000..0a20b566c
--- /dev/null
+++ b/inc/format.php.bak
@@ -0,0 +1,593 @@
+
+ * @deprecated part of the XHTML renderer
+ */
+
+trigger_error('deprecated parser.php included');
+
+ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+ require_once(DOKU_INC.'conf/dokuwiki.php');
+ require_once(DOKU_INC.'inc/common.php');
+
+
+/**
+ * Assembles all parts defined by the link formater below
+ * Returns HTML for the link
+ *
+ * @author Andreas Gohr
+ */
+function format_link_build($link){
+ //make sure the url is XHTML compliant (skip mailto)
+ if(substr($link['url'],0,7) != 'mailto:'){
+ $link['url'] = str_replace('&','&',$link['url']);
+ $link['url'] = str_replace('&','&',$link['url']);
+ }
+ //remove double encodings in titles
+ $link['title'] = str_replace('&','&',$link['title']);
+
+ $ret = '';
+ $ret .= $link['pre'];
+ $ret .= ' with proper special char encoding
+ * $link['class'] CSS class to set on link
+ * $link['target'] which target to use (blank) for current window
+ * $link['style'] Additonal style attribute set with style=""
+ * $link['title'] Title to set with title=""
+ * $link['pre'] HTML to prepend to link
+ * $link['suf'] HTML to append to link
+ * $link['more'] Additonal HTML to include into the anchortag
+ *
+ */
+
+/**
+ * format wiki links
+ *
+ * @author Andreas Gohr
+ */
+function format_link_wiki($link){
+ global $conf;
+ global $ID; //we use this to get the current namespace
+ //obvious setup
+ $link['target'] = $conf['target']['wiki'];
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
+
+ $ns = getNS($ID);
+
+ //if links starts with . add current namespace
+ if(strpos($link['url'],'.')===0){
+ $link['url'] = $ns.':'.substr($link['url'],1);
+ }
+
+ //if link contains no namespace. add current namespace (if any)
+ if($ns !== false && strpos($link['url'],':') === false){
+ $link['url'] = $ns.':'.$link['url'];
+ }
+
+ //keep hashlink if exists
+ list($link['url'],$hash) = split('#',$link['url'],2);
+ $hash = cleanID($hash);
+
+ $file = wikiFN($link['url']);
+ $url = cleanID($link['url']);
+
+ //check alternative plural/nonplural form
+ if(!@file_exists($file) && $conf['autoplural']){
+ if(substr($url,-1) == 's'){
+ $try = substr($url,0,-1);
+ }else{
+ $try = $url.'s';
+ }
+ $tryfile = wikiFN($try);
+ if(@file_exists($tryfile)){
+ $file = $tryfile;
+ $url = $try;
+ }
+ }
+
+ //set class and name depending on file existence and content
+ if(@file_exists($file)){
+ $link['class']="wikilink1";
+ if ($conf['useheading'] && empty($link['name'])) {
+ $hl = getFirstHeading(io_readFile($file));
+ if ($hl) $link['name'] = $hl;
+ }
+ }else{
+ $link['class']="wikilink2";
+ }
+
+ //if no name set yet, use (unclean) link without namespace
+ if(empty($link['name'])){
+ if($conf['useslash']){
+ $nssep = '[:;/]';
+ }else{
+ $nssep = '[:;]';
+ }
+ $link['name'] = preg_replace('!.*'.$nssep.'!','',$link['url']);
+ }
+ $link['name'] = htmlspecialchars($link['name']);
+
+ //set title
+ $link['title'] = $url;
+
+ //construct the full link
+ $link['url'] = wl($url);
+
+ //add hash if exists
+ if($hash) $link['url'] .= '#'.$hash;
+
+ return $link;
+}
+
+/**
+ * format external URLs
+ *
+ * @author Andreas Gohr
+ */
+function format_link_externalurl($link){
+ global $conf;
+ //simple setup
+ $link['class'] = 'urlextern';
+ $link['target'] = $conf['target']['extern'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+ $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
+ $link['url'] = $link['url']; //keep it
+ $link['title'] = htmlspecialchars($link['url']);
+ if(!$link['name']) $link['name'] = htmlspecialchars($link['url']);
+ if($conf['relnofollow']) $link['more'] .= ' rel="nofollow"';
+ //thats it :-)
+ return $link;
+}
+
+/**
+ * format windows share links
+ *
+ * this only works in IE :-(
+ *
+ * @author Andreas Gohr
+ */
+function format_link_windows($link){
+ global $conf;
+ global $lang;
+ //simple setup
+ $link['class'] = 'windows';
+ $link['target'] = $conf['target']['windows'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+ //Display error on browsers other than IE
+ $link['more'] = 'onclick="if(document.all == null){alert(\''.htmlspecialchars($lang['nosmblinks'],ENT_QUOTES).'\');}" onkeypress="if(document.all == null){alert(\''.htmlspecialchars($lang['nosmblinks'],ENT_QUOTES).'\');}"';
+
+ if(!$link['name']) $link['name'] = htmlspecialchars($link['url']);
+ $link['title'] = htmlspecialchars($link['url']);
+ $link['url'] = str_replace('\\','/',$link['url']);
+ $link['url'] = 'file:///'.$link['url'];
+
+ return $link;
+}
+
+/**
+ * format email addresses
+ *
+ * @author Andreas Gohr
+ */
+function format_link_email($link){
+ global $conf;
+ //simple setup
+ $link['class'] = 'mail';
+ $link['target'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['style'] = '';
+ $link['more'] = '';
+
+ $link['name'] = htmlspecialchars($link['name']);
+
+ //shields up
+ if($conf['mailguard']=='visible'){
+ //the mail name gets some visible encoding
+ $link['url'] = str_replace('@',' [at] ',$link['url']);
+ $link['url'] = str_replace('.',' [dot] ',$link['url']);
+ $link['url'] = str_replace('-',' [dash] ',$link['url']);
+ }elseif($conf['mailguard']=='hex'){
+ for ($x=0; $x < strlen($link['url']); $x++) {
+ $encode .= '' . bin2hex($link['url'][$x]).';';
+ }
+ $link['url'] = $encode;
+ }
+
+ $link['title'] = $link['url'];
+ if(!$link['name']) $link['name'] = $link['url'];
+ $link['url'] = 'mailto:'.$link['url'];
+
+ return $link;
+}
+
+/**
+ * format interwiki links
+ *
+ * @author Andreas Gohr
+ */
+function format_link_interwiki($link){
+ global $conf;
+
+ //obvious ones
+ $link['class'] = 'interwiki';
+ $link['target'] = $conf['target']['interwiki'];
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
+
+ //get interwiki short name
+ list($wiki,$link['url']) = split('>',$link['url'],2);
+ $wiki = strtolower(trim($wiki)); //always use lowercase
+ $link['url'] = trim($link['url']);
+ if(!$link['name']) $link['name'] = $link['url'];
+
+ //encode special chars
+ $link['name'] = htmlspecialchars($link['name']);
+
+ //set default to google
+ $url = 'http://www.google.com/search?q=';
+ $ico = 'google';
+
+ // Initialize as NULL - for the first fn call
+ static $iwlinks = NULL;
+
+ // load interwikilinks if needed
+ if (!$iwlinks) $iwlinks = file('conf/interwiki.conf');
+
+ //add special case 'this'
+ $iwlinks[] = 'this '.DOKU_URL.'{NAME}';
+
+ //go through iwlinks and find URL for wiki
+ foreach ($iwlinks as $line){
+ $line = preg_replace('/#.*/','',$line); //skip comments
+ $line = trim($line);
+ list($iw,$iwurl) = preg_split('/\s+/',$line);
+ if(!$iw or !$iwurl) continue; //skip broken or empty lines
+ //check for match
+ if(strtolower($iw) == $wiki){
+ $ico = $wiki;
+ $url = $iwurl;
+ break;
+ }
+ }
+
+ //if ico exists set additonal style
+ if(@file_exists('interwiki/'.$ico.'.png')){
+ $link['style']='background: transparent url('.DOKU_BASE.'interwiki/'.$ico.'.png) 0px 1px no-repeat;';
+ }elseif(@file_exists('interwiki/'.$ico.'.gif')){
+ $link['style']='background: transparent url('.DOKU_BASE.'interwiki/'.$ico.'.gif) 0px 1px no-repeat;';
+ }
+
+ //do we stay at the same server? Use local target
+ if( strpos($url,DOKU_URL) === 0 ){
+ $link['target'] = $conf['target']['wiki'];
+ }
+
+ //replace placeholder
+ if(preg_match('#\{(URL|NAME|SCHEME|HOST|PORT|PATH|QUERY)\}#',$url)){
+ //use placeholders
+ $url = str_replace('{URL}',urlencode($link['url']),$url);
+ $url = str_replace('{NAME}',$link['url'],$url);
+ $parsed = parse_url($link['url']);
+ if(!$parsed['port']) $parsed['port'] = 80;
+ $url = str_replace('{SCHEME}',$parsed['scheme'],$url);
+ $url = str_replace('{HOST}',$parsed['host'],$url);
+ $url = str_replace('{PORT}',$parsed['port'],$url);
+ $url = str_replace('{PATH}',$parsed['path'],$url);
+ $url = str_replace('{QUERY}',$parsed['query'],$url);
+ $link['url'] = $url;
+ }else{
+ //default
+ $link['url'] = $url.urlencode($link['url']);
+ }
+
+ $link['title'] = htmlspecialchars($link['url']);
+
+ //done :-)
+ return $link;
+}
+
+/**
+ * format embedded media
+ *
+ * @author Andreas Gohr
+ */
+function format_link_media($link){
+ global $conf;
+ global $ID;
+
+ $link['class'] = 'media';
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = 'onclick="return svchk()" onkeypress="return svchk()"';
+ $class = 'media';
+
+ list($link['name'],$title) = split('\|',$link['name'],2);
+ $t = htmlspecialchars($title);
+
+ //set alignment from spaces
+ if(substr($link['name'],0,1)==' ' && substr($link['name'],-1,1)==' '){
+ $link['pre'] = "
\n";
+ $link['suf'] = "
\n";
+ }elseif(substr($link['name'],0,1)==' '){
+ #$a = ' align="right"';
+ $class = 'mediaright';
+ }elseif(substr($link['name'],-1,1)==' '){
+ #$a = ' align="left"';
+ $class = 'medialeft';
+ }else{
+ $a = ' align="middle"';
+ }
+ $link['name'] = trim($link['name']);
+
+ //split into src and parameters (using the very last questionmark)
+ $pos = strrpos($link['name'], '?');
+ if($pos !== false){
+ $src = substr($link['name'],0,$pos);
+ $param = substr($link['name'],$pos+1);
+ }else{
+ $src = $link['name'];
+ $param = '';
+ }
+
+ //parse width and height
+ if(preg_match('#(\d+)(x(\d+))?#i',$param,$size)){
+ if($size[1]) $w = $size[1];
+ if($size[3]) $h = $size[3];
+ }
+
+ //namespace mangling for internal images
+ if(!preg_match('#^https?://#i',$src)){
+ $ns = getNS($ID);
+ //if src starts with . add current namespace
+ if(strpos($src,'.') === 0){
+ $src = $ns.':'.substr($src,1);
+ }
+ //if src contains no namespace add current namespace if any
+ if($ns !== false && strpos($src,':') === false ){
+ $src = $ns.':'.$src;
+ }
+ }
+
+ //check for nocache/recache param
+ preg_match('/(nocache|recache)/i',$param,$cachemode);
+
+ //do image caching, resizing and src rewriting
+ $cache = $src;
+ $isimg = img_cache($cache,$src,$w,$h,$cachemode[1]);
+
+ //set link to src if none given
+ if(!$link['url']){
+ $link['url'] = $src;
+ $link['target'] = $conf['target']['media'];
+ }
+
+ //prepare name
+ if($isimg){
+ $link['name'] = ' ';
+ }else{
+ if($t){
+ $link['name'] = $t;
+ }else{
+ $link['name'] = basename($src);
+ }
+ }
+
+ return $link;
+}
+
+/**
+ * Build an URL list from a RSS feed
+ *
+ * Uses magpie
+ *
+ * @author Andreas Gohr
+ */
+function format_rss($url){
+ global $lang;
+ define('MAGPIE_CACHE_ON', false); //we do our own caching
+ define('MAGPIE_DIR', 'inc/magpie/');
+ define('MAGPIE_OUTPUT_ENCODING','UTF-8'); //return all feeds as UTF-8
+ require_once(MAGPIE_DIR.'/rss_fetch.inc');
+
+ //disable warning while fetching
+ $elvl = error_reporting(E_ERROR);
+ $rss = fetch_rss($url);
+ error_reporting($elvl);
+
+ $ret = '';
+ return $ret;
+}
+
+/**
+ * Create cache images
+ *
+ * @author Andreas Gohr
+ */
+function img_cache(&$csrc,&$src,&$w,&$h,$cachemode){
+ global $conf;
+
+ //container for various paths
+ $f['full']['web'] = $src;
+ $f['resz']['web'] = $src;
+ $f['full']['fs'] = $src;
+ $f['resz']['fs'] = $src;
+
+ //generate cachename
+ $md5 = md5($src);
+
+ //check if it is an image
+ if(preg_match('#\.(jpe?g|gif|png)$#i',$src,$match)){
+ $ext = strtolower($match[1]);
+ $isimg = true;
+ }
+
+ //check if it is external or a local mediafile
+ if(preg_match('#^([a-z0-9]+?)://#i',$src)){
+ $isurl = true;
+ }else{
+ $src = str_replace(':','/',$src);
+ $src = utf8_encodeFN($src);
+ $f['full']['web'] = $conf['mediaweb'].'/'.$src;
+ $f['resz']['web'] = $conf['mediaweb'].'/'.$src;
+ $f['full']['fs'] = $conf['mediadir'].'/'.$src;
+ $f['resz']['fs'] = $conf['mediadir'].'/'.$src;
+ }
+
+ //download external images if allowed
+ if($isurl && $isimg && $cachemode != 'nocache'){
+ $cache = $conf['mediadir']."/_cache/$md5.$ext";
+ if ( ($cachemode == 'recache' && io_download($src,$cache)) ||
+ @file_exists($cache) || io_download($src,$cache)){
+ $f['full']['web'] = $conf['mediaweb']."/_cache/$md5.$ext";
+ $f['resz']['web'] = $conf['mediaweb']."/_cache/$md5.$ext";
+ $f['full']['fs'] = $conf['mediadir']."/_cache/$md5.$ext";
+ $f['resz']['fs'] = $conf['mediadir']."/_cache/$md5.$ext";
+ $isurl = false;
+ }
+ }
+
+ //for local images (cached or media) do resizing
+ if($isimg && (!$isurl)){
+ if($w){
+ $info = getImageSize($f['full']['fs']);
+ //if $h not given calcualte it with correct aspect ratio
+ if(!$h){
+ $h = round(($w * $info[1]) / $info[0]);
+ }
+ $cache = $conf['mediadir'].'/_cache/'.$md5.'.'.$w.'x'.$h.'.'.$ext;
+ //delete outdated cachefile
+ if(@file_exists($cache) && (filemtime($cache)
+ */
+function img_resize($ext,$from,$from_w,$from_h,$to,$to_w,$to_h){
+ global $conf;
+
+ if($conf['gdlib'] < 1) return false; //no GDlib available or wanted
+
+ // create an image of the given filetype
+ if ($ext == 'jpg' || $ext == 'jpeg'){
+ if(!function_exists("imagecreatefromjpeg")) return false;
+ $image = @imagecreateFromjpeg($from);
+ }elseif($ext == 'png') {
+ if(!function_exists("imagecreatefrompng")) return false;
+ $image = @imagecreatefrompng($from);
+ }elseif($ext == 'gif') {
+ if(!function_exists("imagecreatefromgif")) return false;
+ $image = @imagecreatefromgif($from);
+ }
+ if(!$image) return false;
+
+ if(($conf['gdlib']>1) && function_exists("imagecreatetruecolor")){
+ $newimg = @imagecreatetruecolor ($to_w, $to_h);
+ }
+ if(!$newimg) $newimg = @imagecreate($to_w, $to_h);
+ if(!$newimg) return false;
+
+ // create cachedir
+ io_makeFileDir($to);
+
+ //try resampling first
+ if(function_exists("imagecopyresampled")){
+ if(!@imagecopyresampled($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h)) {
+ imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h);
+ }
+ }else{
+ imagecopyresized($newimg, $image, 0, 0, 0, 0, $to_w, $to_h, $from_w, $from_h);
+ }
+
+ if ($ext == 'jpg' || $ext == 'jpeg'){
+ if(!function_exists("imagejpeg")) return false;
+ return imagejpeg($newimg, $to, 70);
+ }elseif($ext == 'png') {
+ if(!function_exists("imagepng")) return false;
+ return imagepng($newimg, $to);
+ }elseif($ext == 'gif') {
+ if(!function_exists("imagegif")) return false;
+ return imagegif($newimg, $to);
+ }
+
+ return false;
+}
+
+
+//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/parser.php b/inc/parser.php
deleted file mode 100644
index 8f4a188b7..000000000
--- a/inc/parser.php
+++ /dev/null
@@ -1,862 +0,0 @@
-
- * @deprecated replaced by the new parser
- */
-
-trigger_error('deprecated parser.php included');
-
- if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
- include_once(DOKU_INC.'inc/common.php');
- include_once(DOKU_INC.'inc/html.php');
- include_once(DOKU_INC.'inc/format.php');
- require_once(DOKU_INC.'lang/en/lang.php');
- require_once(DOKU_INC.'lang/'.$conf['lang'].'/lang.php');
-
-/**
- * The main parser function.
- *
- * Accepts raw data and returns valid xhtml
- *
- * @author Andreas Gohr
- */
-function parse($text){
- global $parser;
- global $conf;
- $table = array();
- $hltable = array();
-
- //preparse
- $text = preparse($text,$table,$hltable);
-
- //padding with a newline
- $text = "\n".$text."\n";
-
- #for link matching
- $urls = '(https?|telnet|gopher|file|wais|ftp|ed2k|irc)';
- $ltrs = '\w';
- $gunk = '/\#~:.?+=&%@!\-';
- $punc = '.:?\-;,';
- $host = $ltrs.$punc;
- $any = $ltrs.$gunk.$punc;
-
- /* first pass */
-
- //preformated texts
- firstpass($table,$text,"#(.*?) #se","preformat('\\1','nowiki')");
- firstpass($table,$text,"#%%(.*?)%%#se","preformat('\\1','nowiki')");
- firstpass($table,$text,"#(.*?)
#se","preformat('\\3','code','\\2')");
- firstpass($table,$text,"#(.*?) #se","preformat('\\1','file')");
-
- // html and php includes
- firstpass($table,$text,"#(.*?)#se","preformat('\\1','html')");
- firstpass($table,$text,"#(.*?) #se","preformat('\\1','php')");
-
- // codeblocks
- firstpass($table,$text,"/(\n( {2,}|\t)[^\*\-\n ][^\n]+)(\n( {2,}|\t)[^\n]*)*/se","preformat('\\0','block')","\n");
-
- //check if toc is wanted
- if(!isset($parser['toc'])){
- if(strpos($text,'~~NOTOC~~')!== false){
- $text = str_replace('~~NOTOC~~','',$text);
- $parser['toc'] = false;
- }else{
- $parser['toc'] = true;
- }
- }
-
- //check if this file may be cached
- if(!isset($parser['cache'])){
- if(strpos($text,'~~NOCACHE~~')!=false){
- $text = str_replace('~~NOCACHE~~','',$text);
- $parser['cache'] = false;
- }else{
- $parser['cache'] = true;
- }
- }
-
- //headlines
- format_headlines($table,$hltable,$text);
-
- //links
- firstpass($table,$text,"#\[\[([^\]]+?)\]\]#ie","linkformat('\\1')");
-
- //media
- firstpass($table,$text,"/\{\{([^\}]+)\}\}/se","mediaformat('\\1')");
-
- //match full URLs (adapted from Perl cookbook)
- firstpass($table,$text,"#(\b)($urls://[$any]+?)([$punc]*[^$any])#ie","linkformat('\\2')",'\1','\4');
-
- //short www URLs
- firstpass($table,$text,"#(\b)(www\.[$host]+?\.[$host]+?[$any]+?)([$punc]*[^$any])#ie","linkformat('http://\\2|\\2')",'\1','\3');
-
- //windows shares
- firstpass($table,$text,"#([$gunk$punc\s])(\\\\\\\\[$host]+?\\\\[$any]+?)([$punc]*[^$any])#ie","linkformat('\\2')",'\1','\3');
-
- //short ftp URLs
- firstpass($table,$text,"#(\b)(ftp\.[$host]+?\.[$host]+?[$any]+?)([$punc]*[^$any])#ie","linkformat('ftp://\\2')",'\1','\3');
-
- // email@domain.tld
- firstpass($table,$text,"#<([\w0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)>#ie", "linkformat('\\1@\\2')");
-
- //CamelCase if wanted
- if($conf['camelcase']){
- firstpass($table,$text,"#(\b)([A-Z]+[a-z]+[A-Z][A-Za-z]*)(\b)#se","linkformat('\\2')",'\1','\3');
- }
-
- $text = htmlspecialchars($text);
-
- //smileys
- smileys($table,$text);
-
- //acronyms
- acronyms($table,$text);
-
- /* second pass for simple formating */
- $text = simpleformat($text);
-
- /* third pass - insert the matches from 1st pass */
- reset($table);
- while (list($key, $val) = each($table)) {
- $text = str_replace($key,$val,$text);
- }
-
- /* remove empty paragraphs */
- $text = preg_replace('"\n*
"','',$text);
-
- /* remove padding */
- $text = trim($text);
- return $text;
-}
-
-/**
- * Line by line preparser
- *
- * This preparses the text by walking it line by line. This
- * is the only place where linenumbers are still available (needed
- * for section edit. Some precautions have to be taken to not change
- * any noparse block.
- *
- * @author Andreas Gohr
- */
-function preparse($text,&$table,&$hltable){
- $lines = split("\n",$text);
-
- //prepare a tokens for paragraphs
- $po = mkToken();
- $table[$po] = "";
- $pc = mkToken();
- $table[$pc] = "
";
-
- for ($l=0; $l(.*?)#","",$line);
- $line = preg_replace("#%%(.*?)%%#","",$line);
- $line = preg_replace("#(.*?)
#","",$line);
- $line = preg_replace("#<(file|html|php)>(.*?)\\1>#","",$line);
- //check for start of multiline noparse areas
- if(preg_match('#^.*?<(nowiki|code|php|html|file)( (\w+))?>#',$line,$matches)){
- list($noparse) = split(" ",$matches[1]); //remove options
- $noparse = ''.$noparse.'>';
- continue;
- }elseif(preg_match('#^.*?%%#',$line)){
- $noparse = '%%';
- continue;
- }
- }
-
- //handle headlines
- if(preg_match('/^(\s)*(==+)(.+?)(==+)(\s*)$/',$lines[$l],$matches)){
- //get token
- $tk = tokenize_headline($hltable,$matches[2],$matches[3],$l);
- //replace line with token
- $lines[$l] = $tk;
- }
-
- //handle paragraphs
- if(empty($lines[$l])){
- $lines[$l] = "$pc\n$po";
- }
- }
-
- //reassemble full text
- $text = join("\n",$lines);
- //open first and close last paragraph
- $text = "$po\n$text\n$pc";
-
- return $text;
-}
-
-/**
- * Build TOC lookuptable
- *
- * This function adds some information about the given headline
- * to a lookuptable to be processed later. Returns a unique token
- * that idetifies the headline later
- *
- * @author Andreas Gohr
- */
-function tokenize_headline(&$hltable,$pre,$hline,$lno){
- switch (strlen($pre)){
- case 2:
- $lvl = 5;
- break;
- case 3:
- $lvl = 4;
- break;
- case 4:
- $lvl = 3;
- break;
- case 5:
- $lvl = 2;
- break;
- default:
- $lvl = 1;
- break;
- }
- $token = mkToken();
- $hltable[] = array( 'name' => htmlspecialchars(trim($hline)),
- 'level' => $lvl,
- 'line' => $lno,
- 'token' => $token );
- return $token;
-}
-
-/**
- * Headline formatter
- *
- * @author Andreas Gohr
- */
-function format_headlines(&$table,&$hltable,&$text){
- global $parser;
- global $conf;
- global $lang;
- global $ID;
-
- // walk the headline table prepared in preparsing
- $last = 0;
- $cnt = 0;
- $hashs = array();
- foreach($hltable as $hl){
- $cnt++;
-
- //make unique headlinehash
- $hash = cleanID($hl['name']);
- $i=2;
- while(in_array($hash,$hashs))
- $hash = cleanID($hl['name']).$i++;
- $hashs[] = $hash;
-
- // build headline
- $headline = "
\n"; //close paragraph
- if($cnt - 1) $headline .= ''; //no close on first HL
- $headline .= ' ';
- $headline .= '';
- $headline .= $hl['name'];
- $headline .= ' ';
- $headline .= '';
- $headline .= "\n
"; //open new paragraph
-
- //remember for autoTOC
- if($hl['level'] <= $conf['maxtoclevel']){
- $content[] = array('id' => $hash,
- 'name' => $hl['name'],
- 'level' => $hl['level']);
- }
-
- //add link for section edit for HLs 1, and 3
- if( ($hl['level'] <= $conf['maxseclevel']) &&
- ($hl['line'] - $last > 1)){
- $secedit = '';
- $headline = $secedit.$headline;
- $last = $hl['line'];
- }
-
- //put headline into firstpasstable
- $table[$hl['token']] = $headline;
- }
-
- //add link for editing the last section
- if($last){
- $secedit = '';
- $token = mktoken();
- $text .= $token;
- $table[$token] = $secedit;
- }
-
- //close last div
- if ($cnt){
- $token = mktoken();
- $text .= $token;
- $table[$token] = '
';
- }
-
- //prepend toc
- if ($parser['toc'] && count($content) > 2){
- $token = mktoken();
- $text = $token.$text;
- $table[$token] = html_toc($content);
- }
-}
-
-/**
- * Formats various link types using the functions from format.php
- *
- * @author Andreas Gohr
- */
-function linkformat($match){
- global $conf;
- //unescape
- $match = str_replace('\\"','"',$match);
-
- //prepare variables for the formaters
- $link = array();
- list($link['url'],$link['name']) = split('\|',$match,2);
- $link['url'] = trim($link['url']);
- $link['name'] = trim($link['name']);
- $link['class'] = '';
- $link['target'] = '';
- $link['style'] = '';
- $link['pre'] = '';
- $link['suf'] = '';
- $link['more'] = '';
-
- //save real name for image check
- $realname = $link['name'];
-
- /* put it into the right formater */
- if(strpos($link['url'],'>')){
- // InterWiki
- $link = format_link_interwiki($link);
- }elseif(preg_match('#^([a-z0-9]+?)://#i',$link['url'])){
- // external URL
- $link = format_link_externalurl($link);
- }elseif(preg_match("/^\\\\\\\\([a-z0-9\-_.]+)\\\\(.+)$/",$link['url'])){
- // windows shares
- $link = format_link_windows($link);
- }elseif(preg_match('#([a-z0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i',$link['url'])){
- // email
- $link = format_link_email($link);
- }else{
- // wiki link
- $link = format_link_wiki($link);
- }
-
- //is realname an image? use media formater
- if(preg_match('#^{{.*?\.(gif|png|jpe?g)(\?.*?)?\s*(\|.*?)?}}$#',$realname)){
- $link['name'] = substr($realname,2,-2);
- $link = format_link_media($link);
- }
-
- // build the replacement with the variables set by the formaters
- return format_link_build($link);
-}
-
-/**
- * Simple text formating and typography is done here
- *
- * @author Andreas Gohr
- */
-function simpleformat($text){
- global $conf;
-
- $text = preg_replace('/__(.+?)__/s','\1 ',$text); //underline
- $text = preg_replace('/\/\/(.+?)\/\//s','\1 ',$text); //emphasize
- $text = preg_replace('/\*\*(.+?)\*\*/s','\1 ',$text); //bold
- $text = preg_replace('/\'\'(.+?)\'\'/s','\1
',$text); //code
- $text = preg_replace('#<del>(.*?)</del>#is','\1',$text); //deleted
- $text = preg_replace('/^\s*----+\s*$/m',"\n \n",$text); //hr
-
- //sub and superscript
- $text = preg_replace('#<su([bp])>(.*?)</su\1>#is','\2 ',$text);
-
- //do quoting
- $text = preg_replace("/\n((>)[^\n]*?\n)+/se","'\n'.quoteformat('\\0').'\n'",$text);
-
- // Typography
- if($conf['typography']){
- $text = preg_replace('/(?>
- $text = preg_replace('/<</i','«',$text); // <<
-
- $text = preg_replace('/<->/i','↔',$text); // <->
- $text = preg_replace('/<-/i','←',$text); // <-
- $text = preg_replace('/->/i','→',$text); // ->
-
- $text = preg_replace('/<=>/i','⇔',$text); // <=>
- $text = preg_replace('/<=/i','⇐',$text); // <=
- $text = preg_replace('/=>/i','⇒',$text); // =>
-
- $text = preg_replace('/\(c\)/i','©',$text); // copyrigtht
- $text = preg_replace('/\(r\)/i','®',$text); // registered
- $text = preg_replace('/\(tm\)/i','™',$text); // trademark
- }
-
- //forced linebreaks
- $text = preg_replace('#\\\\\\\\(?=\s)#'," ",$text);
-
- // lists (blocks leftover after blockformat)
- $text = preg_replace("/(\n( {2,}|\t)[\*\-][^\n]+)(\n( {2,}|\t)[^\n]*)*/se","\"\\n\".listformat('\\0')",$text);
-
- // tables
- $text = preg_replace("/\n(([\|\^][^\n]*?)+[\|\^] *\n)+/se","\"\\n\".tableformat('\\0')",$text);
-
- // footnotes
- $text = footnotes($text);
-
- // run custom text replacements
- $text = customs($text);
-
- return $text;
-}
-
-/**
- * Footnote formating
- *
- * @author Andreas Gohr
- */
-function footnotes($text){
- $num = 0;
- while (preg_match('/\(\((.+?)\)\)/s',$text,$match)){
- $num++;
- $fn = $match[1];
- $linkt = ''.$num.') ';
- $linkb = ''.$num.') ';
-
- $text = preg_replace('/ ?\(\((.+?)\)\)/s',$linkt,$text,1);
- if($num == 1) $text .= '';
- return $text;
-}
-
-/**
- * Replace smileys with their graphic equivalents
- *
- * @author Andreas Gohr
- */
-function smileys(&$table,&$text){
- $smileys = file('conf/smileys.conf');
- foreach($smileys as $smiley){
- $smiley = preg_replace('/#.*$/','',$smiley); //ignore comments
- $smiley = trim($smiley);
- if(empty($smiley)) continue;
- $sm = preg_split('/\s+/',$smiley,2);
- $sm[1] = ' ';
- $sm[0] = preg_quote($sm[0],'/');
- firstpass($table,$text,'/(?
- */
-function acronyms(&$table,&$text){
- $acronyms = file('conf/acronyms.conf');
- foreach($acronyms as $acro){
- $acro = preg_replace('/#.*$/','',$acro); //ignore comments
- $acro = trim($acro);
- if(empty($acro)) continue;
- list($ac,$desc) = preg_split('/\s+/',$acro,2);
- $ac = preg_quote($ac,'/');
- firstpass($table,$text,'/\b('.$ac.')\b/s',"\\1 ");
- }
-}
-
-/**
- * Apply custom text replacements
- *
- * @author Andreas Gohr
- */
-function customs($text){
- $reps = file ('conf/custom.conf');
- foreach($reps as $rep){
- //strip comments only outside a regexp
- $rep = preg_replace('/#[^\/]*$/','',$rep); //ignore comments
- $rep = trim($rep);
- if(empty($rep)) continue;
- if(preg_match('#^(/.+/\w*)\s+\'(.*)\'$#',$rep,$matches)){
- $text = preg_replace($matches[1],$matches[2],$text);
- }
- }
- return $text;
-}
-
-/**
- * Replace regexp with token
- *
- * @author Andreas Gohr
- */
-function firstpass(&$table,&$text,$regexp,$replace,$lpad='',$rpad=''){
- //extended regexps have to be disabled for inserting the token
- //and later reenabled when handling the actual code:
- $ext='';
- if(substr($regexp,-1) == 'e'){
- $ext='e';
- $regexp = substr($regexp,0,-1);
- }
-
- while(preg_match($regexp,$text,$matches)){
- $token = mkToken();
- $match = $matches[0];
- $text = preg_replace($regexp,$lpad.$token.$rpad,$text,1);
- $table[$token] = preg_replace($regexp.$ext,$replace,$match);
- }
-}
-
-/**
- * create a random and hopefully unique token
- *
- * @author Andreas Gohr
- */
-function mkToken(){
- return '~'.md5(uniqid(rand(), true)).'~';
-}
-
-/**
- * Do quote blocks
- *
- * @author Andreas Gohr
- */
-function quoteformat($block){
- $block = trim($block);
- $lines = split("\n",$block);
-
- $lvl = 0;
- $ret = "";
- foreach ($lines as $line){
- //remove '>' and count them
- $cnt = 0;
- while(substr($line,0,4) == '>'){
- $line = substr($line,4);
- $cnt++;
- }
- //compare to last level and open or close new divs if needed
- if($cnt > $lvl){
- $ret .= "
\n";
- for ($i=0; $i< $cnt - $lvl; $i++){
- $ret .= '';
- }
- $ret .= "\n
";
- }elseif($cnt < $lvl){
- $ret .= "\n
";
- for ($i=0; $i< $lvl - $cnt; $i++){
- $ret .= "
\n";
- }
- $ret .= "\n";
- }elseif(empty($line)){
- $ret .= "
\n";
- }
- //keep rest of line but trim left whitespaces
- $ret .= ltrim($line)."\n";
- //remember level
- $lvl = $cnt;
- }
-
- //close remaining divs
- $ret .= "
\n";
- for ($i=0; $i< $lvl; $i++){
- $ret .= "\n";
- }
- $ret .= "\n";
-
- return "$ret";
-}
-
-/**
- * format inline tables
- *
- * @author Andreas Gohr
- * @author Aaron Evans
- */
-function tableformat($block) {
- $block = trim($block);
- $lines = split("\n",$block);
- $ret = "";
- //build a row array
- $rows = array();
- for($r=0; $r < count($lines); $r++){
- $line = $lines[$r];
- //remove last seperator and trailing whitespace
- $line = preg_replace('/[\|\^]\s*$/', '', $line);
- $c = -1; //prepare colcounter)
- for($chr=0; $chr < strlen($line); $chr++){
- if($line[$chr] == '^'){
- $c++;
- $rows[$r][$c]['head'] = true;
- $rows[$r][$c]['data'] = '';
- }elseif($line[$chr] == '|'){
- $c++;
- $rows[$r][$c]['head'] = false;
- $rows[$r][$c]['data'] = '';
- }else{
- $rows[$r][$c]['data'].= $line[$chr];
- }
- }
- }
-
- //build table
- $ret .= "
\n\n";
- for($r=0; $r < count($rows); $r++){
- $ret .= " \n";
-
- for ($c=0; $c < count($rows[$r]); $c++){
- $cspan=1;
- $data = $rows[$r][$c]['data'];
- $head = $rows[$r][$c]['head'];
-
- //join cells if next is empty
- while($c < count($rows[$r])-1 && $rows[$r][$c+1]['data'] == ''){
- $c++;
- $cspan++;
- }
- if($cspan > 1){
- $cspan = 'colspan="'.$cspan.'"';
- }else{
- $cspan = '';
- }
-
- //determine alignment from whitespace
- if (preg_match('/^\s\s/', $data)) { // right indentation
- $td_class = "rightalign";
- if (preg_match('/\s\s$/', $data)) { // both left and right indentation
- $td_class = "centeralign";
- }
- } else { // left indentation (default)
- $td_class = "leftalign";
- }
-
- $data = trim($data);
- if ($head) {
- $ret .= " $data \n"; // set css class for alignment
- } else {
- $ret .= " $data \n"; // set css class for alignment
- }
- }
- $ret .= " \n";
- }
- $ret .= "
\n";
-
- return $ret;
-}
-
-/**
- * format lists
- *
- * @author Andreas Gohr
- */
-function listformat($block){
- //remove 1st newline
- $block = substr($block,1);
- //unescape
- $block = str_replace('\\"','"',$block);
-
-//dbg($block);
-
- //walk line by line
- $ret='';
- $lst=0;
- $lvl=0;
- $enc=0;
- $lines = split("\n",$block);
-
- //build an item array
- $cnt=0;
- $items = array();
- foreach ($lines as $line){
- //get intendion level
- $lvl = 0;
- $lvl += floor(strspn($line,' ')/2);
- $lvl += strspn($line,"\t");
- //remove indents
- $line = preg_replace('/^[ \t]+/','',$line);
- //get type of list
- (substr($line,0,1) == '-') ? $type='ol' : $type='ul';
- // remove bullet and following spaces
- $line = preg_replace('/^[*\-]\s*/','',$line);
- //add item to the list
- $items[$cnt]['level'] = $lvl;
- $items[$cnt]['type'] = $type;
- $items[$cnt]['text'] = $line;
- //increase counter
- $cnt++;
- }
-
- $level = 0;
- $opens = array();
-
- foreach ($items as $item){
- if( $item['level'] > $level ){
- //open new list
- $ret .= "\n<".$item['type'].">\n";
- array_push($opens,$item['type']);
- }elseif( $item['level'] < $level ){
- //close last item
- $ret .= "\n";
- for ($i=0; $i<($level - $item['level']); $i++){
- //close higher lists
- $ret .= ''.array_pop($opens).">\n\n";
- }
- }elseif($item['type'] != $opens[count($opens)-1]){
- //close last list and open new
- $ret .= ''.array_pop($opens).">\n\n";
- $ret .= "\n<".$item['type'].">\n";
- array_push($opens,$item['type']);
- }else{
- //close last item
- $ret .= "\n";
- }
-
- //remember current level and type
- $level = $item['level'];
-
- //print item
- $ret .= '';
- $ret .= ''.$item['text'].' ';
- }
-
- //close remaining items and lists
- while ($open = array_pop($opens)){
- $ret .= " \n";
- $ret .= ''.$open.">\n";
- }
- return "
\n".$ret."\n";
-}
-
-/**
- * Handle preformatted blocks
- *
- * Uses GeSHi for syntax highlighting
- *
- * @author Andreas Gohr
- */
-function preformat($text,$type,$option=''){
- global $conf;
- global $lang;
- //unescape
- $text = str_replace('\\"','"',$text);
-
- if($type == 'php' && !$conf['phpok']) $type='file';
- if($type == 'html' && !$conf['htmlok']) $type='file';
-
- switch ($type){
- case 'php':
- ob_start();
- eval($text);
- $text = ob_get_contents();
- ob_end_clean();
- break;
- case 'html':
- break;
- case 'nowiki':
- $text = htmlspecialchars($text);
- break;
- case 'file':
- $text = htmlspecialchars($text);
- $text = "
\n".$text." \n";
- break;
- case 'code':
- if(empty($option)){
- $text = htmlspecialchars($text);
- $text = '
'.$text.' ';
- }else{
- //strip leading blank line
- $text = preg_replace('/^\s*?\n/','',$text);
- //use geshi for highlighting
- require_once("inc/geshi.php");
- $geshi = new GeSHi($text, strtolower($option), "inc/geshi");
- $geshi->set_encoding($lang['encoding']);
- $geshi->enable_classes();
- $geshi->set_header_type(GESHI_HEADER_PRE);
- $geshi->set_overall_class('code');
- $geshi->set_link_target($conf['target']['extern']);
- $text = $geshi->parse_code();
- }
- $text = "\n".$text."\n";
- break;
- case 'block':
- $text = substr($text,1); //remove 1st newline
- $lines = split("\n",$text); //break into lines
- $text = '';
- foreach($lines as $line){
- $text .= substr($line,2)."\n"; //remove indents
- }
- $text = htmlspecialchars($text);
- $text = "
\n".$text." \n";
- break;
- }
- return $text;
-}
-
-/**
- * Format embedded media (images)
- *
- * @author Andreas Gohr
- */
-function mediaformat($text){
- global $conf;
-
- //unescape
- $text = str_replace('\\"','"',$text);
-
- // format RSS
- if(substr($text,0,4) == 'rss>'){
- return format_rss(substr($text,4));
- }
-
- //handle normal media stuff
- $link = array();
- $link['name'] = $text;
- $link = format_link_media($link);
- return format_link_build($link);
-}
-
-/**
- * Get first heading, to be used as a page title
- *
- * @author Jan Decaluwe
- */
-function getFirstHeading($text){
- $title = '';
- $lines = split("\n",$text);
- foreach($lines as $line){
- if(preg_match('/^\s*==+(.+?)==+\s*$/',$line,$matches)){
- $title = $matches[1];
- break;
- }
- }
- return $title;
-}
-
-
-//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/parser.php.bak b/inc/parser.php.bak
new file mode 100644
index 000000000..8f4a188b7
--- /dev/null
+++ b/inc/parser.php.bak
@@ -0,0 +1,862 @@
+
+ * @deprecated replaced by the new parser
+ */
+
+trigger_error('deprecated parser.php included');
+
+ if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
+ include_once(DOKU_INC.'inc/common.php');
+ include_once(DOKU_INC.'inc/html.php');
+ include_once(DOKU_INC.'inc/format.php');
+ require_once(DOKU_INC.'lang/en/lang.php');
+ require_once(DOKU_INC.'lang/'.$conf['lang'].'/lang.php');
+
+/**
+ * The main parser function.
+ *
+ * Accepts raw data and returns valid xhtml
+ *
+ * @author Andreas Gohr
+ */
+function parse($text){
+ global $parser;
+ global $conf;
+ $table = array();
+ $hltable = array();
+
+ //preparse
+ $text = preparse($text,$table,$hltable);
+
+ //padding with a newline
+ $text = "\n".$text."\n";
+
+ #for link matching
+ $urls = '(https?|telnet|gopher|file|wais|ftp|ed2k|irc)';
+ $ltrs = '\w';
+ $gunk = '/\#~:.?+=&%@!\-';
+ $punc = '.:?\-;,';
+ $host = $ltrs.$punc;
+ $any = $ltrs.$gunk.$punc;
+
+ /* first pass */
+
+ //preformated texts
+ firstpass($table,$text,"#(.*?) #se","preformat('\\1','nowiki')");
+ firstpass($table,$text,"#%%(.*?)%%#se","preformat('\\1','nowiki')");
+ firstpass($table,$text,"#(.*?)
#se","preformat('\\3','code','\\2')");
+ firstpass($table,$text,"#(.*?) #se","preformat('\\1','file')");
+
+ // html and php includes
+ firstpass($table,$text,"#(.*?)#se","preformat('\\1','html')");
+ firstpass($table,$text,"#(.*?) #se","preformat('\\1','php')");
+
+ // codeblocks
+ firstpass($table,$text,"/(\n( {2,}|\t)[^\*\-\n ][^\n]+)(\n( {2,}|\t)[^\n]*)*/se","preformat('\\0','block')","\n");
+
+ //check if toc is wanted
+ if(!isset($parser['toc'])){
+ if(strpos($text,'~~NOTOC~~')!== false){
+ $text = str_replace('~~NOTOC~~','',$text);
+ $parser['toc'] = false;
+ }else{
+ $parser['toc'] = true;
+ }
+ }
+
+ //check if this file may be cached
+ if(!isset($parser['cache'])){
+ if(strpos($text,'~~NOCACHE~~')!=false){
+ $text = str_replace('~~NOCACHE~~','',$text);
+ $parser['cache'] = false;
+ }else{
+ $parser['cache'] = true;
+ }
+ }
+
+ //headlines
+ format_headlines($table,$hltable,$text);
+
+ //links
+ firstpass($table,$text,"#\[\[([^\]]+?)\]\]#ie","linkformat('\\1')");
+
+ //media
+ firstpass($table,$text,"/\{\{([^\}]+)\}\}/se","mediaformat('\\1')");
+
+ //match full URLs (adapted from Perl cookbook)
+ firstpass($table,$text,"#(\b)($urls://[$any]+?)([$punc]*[^$any])#ie","linkformat('\\2')",'\1','\4');
+
+ //short www URLs
+ firstpass($table,$text,"#(\b)(www\.[$host]+?\.[$host]+?[$any]+?)([$punc]*[^$any])#ie","linkformat('http://\\2|\\2')",'\1','\3');
+
+ //windows shares
+ firstpass($table,$text,"#([$gunk$punc\s])(\\\\\\\\[$host]+?\\\\[$any]+?)([$punc]*[^$any])#ie","linkformat('\\2')",'\1','\3');
+
+ //short ftp URLs
+ firstpass($table,$text,"#(\b)(ftp\.[$host]+?\.[$host]+?[$any]+?)([$punc]*[^$any])#ie","linkformat('ftp://\\2')",'\1','\3');
+
+ // email@domain.tld
+ firstpass($table,$text,"#<([\w0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)>#ie", "linkformat('\\1@\\2')");
+
+ //CamelCase if wanted
+ if($conf['camelcase']){
+ firstpass($table,$text,"#(\b)([A-Z]+[a-z]+[A-Z][A-Za-z]*)(\b)#se","linkformat('\\2')",'\1','\3');
+ }
+
+ $text = htmlspecialchars($text);
+
+ //smileys
+ smileys($table,$text);
+
+ //acronyms
+ acronyms($table,$text);
+
+ /* second pass for simple formating */
+ $text = simpleformat($text);
+
+ /* third pass - insert the matches from 1st pass */
+ reset($table);
+ while (list($key, $val) = each($table)) {
+ $text = str_replace($key,$val,$text);
+ }
+
+ /* remove empty paragraphs */
+ $text = preg_replace('"\n*
"','',$text);
+
+ /* remove padding */
+ $text = trim($text);
+ return $text;
+}
+
+/**
+ * Line by line preparser
+ *
+ * This preparses the text by walking it line by line. This
+ * is the only place where linenumbers are still available (needed
+ * for section edit. Some precautions have to be taken to not change
+ * any noparse block.
+ *
+ * @author Andreas Gohr
+ */
+function preparse($text,&$table,&$hltable){
+ $lines = split("\n",$text);
+
+ //prepare a tokens for paragraphs
+ $po = mkToken();
+ $table[$po] = "";
+ $pc = mkToken();
+ $table[$pc] = "
";
+
+ for ($l=0; $l(.*?)#","",$line);
+ $line = preg_replace("#%%(.*?)%%#","",$line);
+ $line = preg_replace("#(.*?)
#","",$line);
+ $line = preg_replace("#<(file|html|php)>(.*?)\\1>#","",$line);
+ //check for start of multiline noparse areas
+ if(preg_match('#^.*?<(nowiki|code|php|html|file)( (\w+))?>#',$line,$matches)){
+ list($noparse) = split(" ",$matches[1]); //remove options
+ $noparse = ''.$noparse.'>';
+ continue;
+ }elseif(preg_match('#^.*?%%#',$line)){
+ $noparse = '%%';
+ continue;
+ }
+ }
+
+ //handle headlines
+ if(preg_match('/^(\s)*(==+)(.+?)(==+)(\s*)$/',$lines[$l],$matches)){
+ //get token
+ $tk = tokenize_headline($hltable,$matches[2],$matches[3],$l);
+ //replace line with token
+ $lines[$l] = $tk;
+ }
+
+ //handle paragraphs
+ if(empty($lines[$l])){
+ $lines[$l] = "$pc\n$po";
+ }
+ }
+
+ //reassemble full text
+ $text = join("\n",$lines);
+ //open first and close last paragraph
+ $text = "$po\n$text\n$pc";
+
+ return $text;
+}
+
+/**
+ * Build TOC lookuptable
+ *
+ * This function adds some information about the given headline
+ * to a lookuptable to be processed later. Returns a unique token
+ * that idetifies the headline later
+ *
+ * @author Andreas Gohr
+ */
+function tokenize_headline(&$hltable,$pre,$hline,$lno){
+ switch (strlen($pre)){
+ case 2:
+ $lvl = 5;
+ break;
+ case 3:
+ $lvl = 4;
+ break;
+ case 4:
+ $lvl = 3;
+ break;
+ case 5:
+ $lvl = 2;
+ break;
+ default:
+ $lvl = 1;
+ break;
+ }
+ $token = mkToken();
+ $hltable[] = array( 'name' => htmlspecialchars(trim($hline)),
+ 'level' => $lvl,
+ 'line' => $lno,
+ 'token' => $token );
+ return $token;
+}
+
+/**
+ * Headline formatter
+ *
+ * @author Andreas Gohr
+ */
+function format_headlines(&$table,&$hltable,&$text){
+ global $parser;
+ global $conf;
+ global $lang;
+ global $ID;
+
+ // walk the headline table prepared in preparsing
+ $last = 0;
+ $cnt = 0;
+ $hashs = array();
+ foreach($hltable as $hl){
+ $cnt++;
+
+ //make unique headlinehash
+ $hash = cleanID($hl['name']);
+ $i=2;
+ while(in_array($hash,$hashs))
+ $hash = cleanID($hl['name']).$i++;
+ $hashs[] = $hash;
+
+ // build headline
+ $headline = "
\n"; //close paragraph
+ if($cnt - 1) $headline .= ''; //no close on first HL
+ $headline .= ' ';
+ $headline .= '';
+ $headline .= $hl['name'];
+ $headline .= ' ';
+ $headline .= '';
+ $headline .= "\n
"; //open new paragraph
+
+ //remember for autoTOC
+ if($hl['level'] <= $conf['maxtoclevel']){
+ $content[] = array('id' => $hash,
+ 'name' => $hl['name'],
+ 'level' => $hl['level']);
+ }
+
+ //add link for section edit for HLs 1, and 3
+ if( ($hl['level'] <= $conf['maxseclevel']) &&
+ ($hl['line'] - $last > 1)){
+ $secedit = '';
+ $headline = $secedit.$headline;
+ $last = $hl['line'];
+ }
+
+ //put headline into firstpasstable
+ $table[$hl['token']] = $headline;
+ }
+
+ //add link for editing the last section
+ if($last){
+ $secedit = '';
+ $token = mktoken();
+ $text .= $token;
+ $table[$token] = $secedit;
+ }
+
+ //close last div
+ if ($cnt){
+ $token = mktoken();
+ $text .= $token;
+ $table[$token] = '
';
+ }
+
+ //prepend toc
+ if ($parser['toc'] && count($content) > 2){
+ $token = mktoken();
+ $text = $token.$text;
+ $table[$token] = html_toc($content);
+ }
+}
+
+/**
+ * Formats various link types using the functions from format.php
+ *
+ * @author Andreas Gohr
+ */
+function linkformat($match){
+ global $conf;
+ //unescape
+ $match = str_replace('\\"','"',$match);
+
+ //prepare variables for the formaters
+ $link = array();
+ list($link['url'],$link['name']) = split('\|',$match,2);
+ $link['url'] = trim($link['url']);
+ $link['name'] = trim($link['name']);
+ $link['class'] = '';
+ $link['target'] = '';
+ $link['style'] = '';
+ $link['pre'] = '';
+ $link['suf'] = '';
+ $link['more'] = '';
+
+ //save real name for image check
+ $realname = $link['name'];
+
+ /* put it into the right formater */
+ if(strpos($link['url'],'>')){
+ // InterWiki
+ $link = format_link_interwiki($link);
+ }elseif(preg_match('#^([a-z0-9]+?)://#i',$link['url'])){
+ // external URL
+ $link = format_link_externalurl($link);
+ }elseif(preg_match("/^\\\\\\\\([a-z0-9\-_.]+)\\\\(.+)$/",$link['url'])){
+ // windows shares
+ $link = format_link_windows($link);
+ }elseif(preg_match('#([a-z0-9\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i',$link['url'])){
+ // email
+ $link = format_link_email($link);
+ }else{
+ // wiki link
+ $link = format_link_wiki($link);
+ }
+
+ //is realname an image? use media formater
+ if(preg_match('#^{{.*?\.(gif|png|jpe?g)(\?.*?)?\s*(\|.*?)?}}$#',$realname)){
+ $link['name'] = substr($realname,2,-2);
+ $link = format_link_media($link);
+ }
+
+ // build the replacement with the variables set by the formaters
+ return format_link_build($link);
+}
+
+/**
+ * Simple text formating and typography is done here
+ *
+ * @author Andreas Gohr
+ */
+function simpleformat($text){
+ global $conf;
+
+ $text = preg_replace('/__(.+?)__/s','\1 ',$text); //underline
+ $text = preg_replace('/\/\/(.+?)\/\//s','\1 ',$text); //emphasize
+ $text = preg_replace('/\*\*(.+?)\*\*/s','\1 ',$text); //bold
+ $text = preg_replace('/\'\'(.+?)\'\'/s','\1
',$text); //code
+ $text = preg_replace('#<del>(.*?)</del>#is','\1',$text); //deleted
+ $text = preg_replace('/^\s*----+\s*$/m',"\n \n",$text); //hr
+
+ //sub and superscript
+ $text = preg_replace('#<su([bp])>(.*?)</su\1>#is','\2 ',$text);
+
+ //do quoting
+ $text = preg_replace("/\n((>)[^\n]*?\n)+/se","'\n'.quoteformat('\\0').'\n'",$text);
+
+ // Typography
+ if($conf['typography']){
+ $text = preg_replace('/(?>
+ $text = preg_replace('/<</i','«',$text); // <<
+
+ $text = preg_replace('/<->/i','↔',$text); // <->
+ $text = preg_replace('/<-/i','←',$text); // <-
+ $text = preg_replace('/->/i','→',$text); // ->
+
+ $text = preg_replace('/<=>/i','⇔',$text); // <=>
+ $text = preg_replace('/<=/i','⇐',$text); // <=
+ $text = preg_replace('/=>/i','⇒',$text); // =>
+
+ $text = preg_replace('/\(c\)/i','©',$text); // copyrigtht
+ $text = preg_replace('/\(r\)/i','®',$text); // registered
+ $text = preg_replace('/\(tm\)/i','™',$text); // trademark
+ }
+
+ //forced linebreaks
+ $text = preg_replace('#\\\\\\\\(?=\s)#'," ",$text);
+
+ // lists (blocks leftover after blockformat)
+ $text = preg_replace("/(\n( {2,}|\t)[\*\-][^\n]+)(\n( {2,}|\t)[^\n]*)*/se","\"\\n\".listformat('\\0')",$text);
+
+ // tables
+ $text = preg_replace("/\n(([\|\^][^\n]*?)+[\|\^] *\n)+/se","\"\\n\".tableformat('\\0')",$text);
+
+ // footnotes
+ $text = footnotes($text);
+
+ // run custom text replacements
+ $text = customs($text);
+
+ return $text;
+}
+
+/**
+ * Footnote formating
+ *
+ * @author Andreas Gohr
+ */
+function footnotes($text){
+ $num = 0;
+ while (preg_match('/\(\((.+?)\)\)/s',$text,$match)){
+ $num++;
+ $fn = $match[1];
+ $linkt = ''.$num.') ';
+ $linkb = ''.$num.') ';
+
+ $text = preg_replace('/ ?\(\((.+?)\)\)/s',$linkt,$text,1);
+ if($num == 1) $text .= '';
+ return $text;
+}
+
+/**
+ * Replace smileys with their graphic equivalents
+ *
+ * @author Andreas Gohr
+ */
+function smileys(&$table,&$text){
+ $smileys = file('conf/smileys.conf');
+ foreach($smileys as $smiley){
+ $smiley = preg_replace('/#.*$/','',$smiley); //ignore comments
+ $smiley = trim($smiley);
+ if(empty($smiley)) continue;
+ $sm = preg_split('/\s+/',$smiley,2);
+ $sm[1] = ' ';
+ $sm[0] = preg_quote($sm[0],'/');
+ firstpass($table,$text,'/(?
+ */
+function acronyms(&$table,&$text){
+ $acronyms = file('conf/acronyms.conf');
+ foreach($acronyms as $acro){
+ $acro = preg_replace('/#.*$/','',$acro); //ignore comments
+ $acro = trim($acro);
+ if(empty($acro)) continue;
+ list($ac,$desc) = preg_split('/\s+/',$acro,2);
+ $ac = preg_quote($ac,'/');
+ firstpass($table,$text,'/\b('.$ac.')\b/s',"\\1 ");
+ }
+}
+
+/**
+ * Apply custom text replacements
+ *
+ * @author Andreas Gohr
+ */
+function customs($text){
+ $reps = file ('conf/custom.conf');
+ foreach($reps as $rep){
+ //strip comments only outside a regexp
+ $rep = preg_replace('/#[^\/]*$/','',$rep); //ignore comments
+ $rep = trim($rep);
+ if(empty($rep)) continue;
+ if(preg_match('#^(/.+/\w*)\s+\'(.*)\'$#',$rep,$matches)){
+ $text = preg_replace($matches[1],$matches[2],$text);
+ }
+ }
+ return $text;
+}
+
+/**
+ * Replace regexp with token
+ *
+ * @author Andreas Gohr
+ */
+function firstpass(&$table,&$text,$regexp,$replace,$lpad='',$rpad=''){
+ //extended regexps have to be disabled for inserting the token
+ //and later reenabled when handling the actual code:
+ $ext='';
+ if(substr($regexp,-1) == 'e'){
+ $ext='e';
+ $regexp = substr($regexp,0,-1);
+ }
+
+ while(preg_match($regexp,$text,$matches)){
+ $token = mkToken();
+ $match = $matches[0];
+ $text = preg_replace($regexp,$lpad.$token.$rpad,$text,1);
+ $table[$token] = preg_replace($regexp.$ext,$replace,$match);
+ }
+}
+
+/**
+ * create a random and hopefully unique token
+ *
+ * @author Andreas Gohr
+ */
+function mkToken(){
+ return '~'.md5(uniqid(rand(), true)).'~';
+}
+
+/**
+ * Do quote blocks
+ *
+ * @author Andreas Gohr
+ */
+function quoteformat($block){
+ $block = trim($block);
+ $lines = split("\n",$block);
+
+ $lvl = 0;
+ $ret = "";
+ foreach ($lines as $line){
+ //remove '>' and count them
+ $cnt = 0;
+ while(substr($line,0,4) == '>'){
+ $line = substr($line,4);
+ $cnt++;
+ }
+ //compare to last level and open or close new divs if needed
+ if($cnt > $lvl){
+ $ret .= "
\n";
+ for ($i=0; $i< $cnt - $lvl; $i++){
+ $ret .= '';
+ }
+ $ret .= "\n
";
+ }elseif($cnt < $lvl){
+ $ret .= "\n
";
+ for ($i=0; $i< $lvl - $cnt; $i++){
+ $ret .= "
\n";
+ }
+ $ret .= "\n";
+ }elseif(empty($line)){
+ $ret .= "
\n";
+ }
+ //keep rest of line but trim left whitespaces
+ $ret .= ltrim($line)."\n";
+ //remember level
+ $lvl = $cnt;
+ }
+
+ //close remaining divs
+ $ret .= "
\n";
+ for ($i=0; $i< $lvl; $i++){
+ $ret .= "\n";
+ }
+ $ret .= "\n";
+
+ return "$ret";
+}
+
+/**
+ * format inline tables
+ *
+ * @author Andreas Gohr
+ * @author Aaron Evans
+ */
+function tableformat($block) {
+ $block = trim($block);
+ $lines = split("\n",$block);
+ $ret = "";
+ //build a row array
+ $rows = array();
+ for($r=0; $r < count($lines); $r++){
+ $line = $lines[$r];
+ //remove last seperator and trailing whitespace
+ $line = preg_replace('/[\|\^]\s*$/', '', $line);
+ $c = -1; //prepare colcounter)
+ for($chr=0; $chr < strlen($line); $chr++){
+ if($line[$chr] == '^'){
+ $c++;
+ $rows[$r][$c]['head'] = true;
+ $rows[$r][$c]['data'] = '';
+ }elseif($line[$chr] == '|'){
+ $c++;
+ $rows[$r][$c]['head'] = false;
+ $rows[$r][$c]['data'] = '';
+ }else{
+ $rows[$r][$c]['data'].= $line[$chr];
+ }
+ }
+ }
+
+ //build table
+ $ret .= "
\n\n";
+ for($r=0; $r < count($rows); $r++){
+ $ret .= " \n";
+
+ for ($c=0; $c < count($rows[$r]); $c++){
+ $cspan=1;
+ $data = $rows[$r][$c]['data'];
+ $head = $rows[$r][$c]['head'];
+
+ //join cells if next is empty
+ while($c < count($rows[$r])-1 && $rows[$r][$c+1]['data'] == ''){
+ $c++;
+ $cspan++;
+ }
+ if($cspan > 1){
+ $cspan = 'colspan="'.$cspan.'"';
+ }else{
+ $cspan = '';
+ }
+
+ //determine alignment from whitespace
+ if (preg_match('/^\s\s/', $data)) { // right indentation
+ $td_class = "rightalign";
+ if (preg_match('/\s\s$/', $data)) { // both left and right indentation
+ $td_class = "centeralign";
+ }
+ } else { // left indentation (default)
+ $td_class = "leftalign";
+ }
+
+ $data = trim($data);
+ if ($head) {
+ $ret .= " $data \n"; // set css class for alignment
+ } else {
+ $ret .= " $data \n"; // set css class for alignment
+ }
+ }
+ $ret .= " \n";
+ }
+ $ret .= "
\n";
+
+ return $ret;
+}
+
+/**
+ * format lists
+ *
+ * @author Andreas Gohr
+ */
+function listformat($block){
+ //remove 1st newline
+ $block = substr($block,1);
+ //unescape
+ $block = str_replace('\\"','"',$block);
+
+//dbg($block);
+
+ //walk line by line
+ $ret='';
+ $lst=0;
+ $lvl=0;
+ $enc=0;
+ $lines = split("\n",$block);
+
+ //build an item array
+ $cnt=0;
+ $items = array();
+ foreach ($lines as $line){
+ //get intendion level
+ $lvl = 0;
+ $lvl += floor(strspn($line,' ')/2);
+ $lvl += strspn($line,"\t");
+ //remove indents
+ $line = preg_replace('/^[ \t]+/','',$line);
+ //get type of list
+ (substr($line,0,1) == '-') ? $type='ol' : $type='ul';
+ // remove bullet and following spaces
+ $line = preg_replace('/^[*\-]\s*/','',$line);
+ //add item to the list
+ $items[$cnt]['level'] = $lvl;
+ $items[$cnt]['type'] = $type;
+ $items[$cnt]['text'] = $line;
+ //increase counter
+ $cnt++;
+ }
+
+ $level = 0;
+ $opens = array();
+
+ foreach ($items as $item){
+ if( $item['level'] > $level ){
+ //open new list
+ $ret .= "\n<".$item['type'].">\n";
+ array_push($opens,$item['type']);
+ }elseif( $item['level'] < $level ){
+ //close last item
+ $ret .= "\n";
+ for ($i=0; $i<($level - $item['level']); $i++){
+ //close higher lists
+ $ret .= ''.array_pop($opens).">\n\n";
+ }
+ }elseif($item['type'] != $opens[count($opens)-1]){
+ //close last list and open new
+ $ret .= ''.array_pop($opens).">\n\n";
+ $ret .= "\n<".$item['type'].">\n";
+ array_push($opens,$item['type']);
+ }else{
+ //close last item
+ $ret .= "\n";
+ }
+
+ //remember current level and type
+ $level = $item['level'];
+
+ //print item
+ $ret .= '';
+ $ret .= ''.$item['text'].' ';
+ }
+
+ //close remaining items and lists
+ while ($open = array_pop($opens)){
+ $ret .= " \n";
+ $ret .= ''.$open.">\n";
+ }
+ return "
\n".$ret."\n";
+}
+
+/**
+ * Handle preformatted blocks
+ *
+ * Uses GeSHi for syntax highlighting
+ *
+ * @author Andreas Gohr
+ */
+function preformat($text,$type,$option=''){
+ global $conf;
+ global $lang;
+ //unescape
+ $text = str_replace('\\"','"',$text);
+
+ if($type == 'php' && !$conf['phpok']) $type='file';
+ if($type == 'html' && !$conf['htmlok']) $type='file';
+
+ switch ($type){
+ case 'php':
+ ob_start();
+ eval($text);
+ $text = ob_get_contents();
+ ob_end_clean();
+ break;
+ case 'html':
+ break;
+ case 'nowiki':
+ $text = htmlspecialchars($text);
+ break;
+ case 'file':
+ $text = htmlspecialchars($text);
+ $text = "
\n".$text." \n";
+ break;
+ case 'code':
+ if(empty($option)){
+ $text = htmlspecialchars($text);
+ $text = '
'.$text.' ';
+ }else{
+ //strip leading blank line
+ $text = preg_replace('/^\s*?\n/','',$text);
+ //use geshi for highlighting
+ require_once("inc/geshi.php");
+ $geshi = new GeSHi($text, strtolower($option), "inc/geshi");
+ $geshi->set_encoding($lang['encoding']);
+ $geshi->enable_classes();
+ $geshi->set_header_type(GESHI_HEADER_PRE);
+ $geshi->set_overall_class('code');
+ $geshi->set_link_target($conf['target']['extern']);
+ $text = $geshi->parse_code();
+ }
+ $text = "\n".$text."\n";
+ break;
+ case 'block':
+ $text = substr($text,1); //remove 1st newline
+ $lines = split("\n",$text); //break into lines
+ $text = '';
+ foreach($lines as $line){
+ $text .= substr($line,2)."\n"; //remove indents
+ }
+ $text = htmlspecialchars($text);
+ $text = "
\n".$text." \n";
+ break;
+ }
+ return $text;
+}
+
+/**
+ * Format embedded media (images)
+ *
+ * @author Andreas Gohr
+ */
+function mediaformat($text){
+ global $conf;
+
+ //unescape
+ $text = str_replace('\\"','"',$text);
+
+ // format RSS
+ if(substr($text,0,4) == 'rss>'){
+ return format_rss(substr($text,4));
+ }
+
+ //handle normal media stuff
+ $link = array();
+ $link['name'] = $text;
+ $link = format_link_media($link);
+ return format_link_build($link);
+}
+
+/**
+ * Get first heading, to be used as a page title
+ *
+ * @author Jan Decaluwe
+ */
+function getFirstHeading($text){
+ $title = '';
+ $lines = split("\n",$text);
+ foreach($lines as $line){
+ if(preg_match('/^\s*==+(.+?)==+\s*$/',$line,$matches)){
+ $title = $matches[1];
+ break;
+ }
+ }
+ return $title;
+}
+
+
+//Setup VIM: ex: et ts=2 enc=utf-8 :
diff --git a/inc/parser/xhtml.php b/inc/parser/xhtml.php
index 8f414c2d6..a132d4f4b 100644
--- a/inc/parser/xhtml.php
+++ b/inc/parser/xhtml.php
@@ -193,6 +193,15 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$this->doc .= '';
}
+ /**
+ * Callback for footnote start syntax
+ *
+ * All following content will go to the footnote instead of
+ * the document. To achive this the previous rendered content
+ * is moved to $store and $doc is cleared
+ *
+ * @author Andreas Gohr
+ */
function footnote_open() {
$id = $this->_newFootnoteId();
$this->doc .= ''.$id.') ';
@@ -206,17 +215,15 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$this->doc .= $id.') '.DOKU_LF;
}
+ /**
+ * Callback for footnote end syntax
+ *
+ * All rendered content is moved to the $footnotes array and the old
+ * content is restored from $store again
+ *
+ * @author Andreas Gohr
+ */
function footnote_close() {
- # $contents = ob_get_contents();
- # ob_end_clean();
- # $id = array_pop($this->footnoteIdStack);
-
- # $contents = '' . DOKU_LF;
- # $this->footnotes[$id] = $contents;
-
-
$this->doc .= '' . DOKU_LF;
// put recorded footnote into the stack and restore old content
@@ -262,18 +269,27 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
}
/**
- */
+ * Execute PHP code if allowed
+ *
+ * @author Andreas Gohr
+ */
function php($text) {
global $conf;
if($conf['phpok']){
+ ob_start;
eval($text);
+ $this->doc .= ob_get_contents();
+ ob_end_clean;
}else{
$this->file($text);
}
}
/**
- */
+ * Insert HTML if allowed
+ *
+ * @author Andreas Gohr
+ */
function html($text) {
global $conf;
if($conf['htmlok']){
@@ -292,7 +308,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
}
/**
- * @TODO Shouldn't this output ?
*/
function quote_open() {
$this->doc .= ''.DOKU_LF;
@@ -306,7 +322,12 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
}
/**
- */
+ * Callback for code text
+ *
+ * Uses GeSHi to highlight language syntax
+ *
+ * @author Andreas Gohr
+ */
function code($text, $language = NULL) {
global $conf;
@@ -402,8 +423,12 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
}
/**
+ * Render an internal Wiki Link
+ *
* $search and $returnonly are not for the renderer but are used
* elsewhere - no need to implement them in other renderers
+ *
+ * @author Andreas Gohr
*/
function internallink($id, $name = NULL, $search=NULL,$returnonly=false) {
global $conf;
@@ -548,35 +573,8 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$this->doc .= $this->_formatLink($link);
}
- /*
- * @deprecated not used!!!
- * @TODO Correct the CSS class for files? (not windows)
- * @TODO Remove hard coded URL to splitbrain.org
- function filelink($link, $title = NULL) {
- $this->doc .= '_getLinkTitle($title, $link, $isImage);
-
- if ( !$isImage ) {
- $this->doc .= ' class="windows"';
- } else {
- $this->doc .= ' class="media"';
- }
-
- $this->doc .= ' href="'.$this->_xmlEntities($link).'"';
-
- $this->doc .= ' style="background: transparent url(http://wiki.splitbrain.org/images/windows.gif) 0px 1px no-repeat;"';
-
- $this->doc .= ' onclick="return svchk()" onkeypress="return svchk()">';
-
- $this->doc .= $title;
-
- $this->doc .= ' ';
- }
- */
-
/**
- */
+ */
function windowssharelink($url, $name = NULL) {
global $conf;
global $lang;
@@ -720,7 +718,7 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
}
/**
- * Renders an RSS feed using magpie
+ * Renders an RSS feed using Magpie
*
* @author Andreas Gohr
*/
@@ -752,71 +750,6 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
$this->doc .= '';
}
- /**
- * Renders internal and external media
- *
- * @author Andreas Gohr
- * @todo handle center align
- * @todo move to bottom
- */
- function _media ($src, $title=NULL, $align=NULL, $width=NULL,
- $height=NULL, $cache=NULL) {
-
- $ret = '';
-
- list($ext,$mime) = mimetype($src);
- if(substr($mime,0,5) == 'image'){
- //add image tag
- $ret .= ' _xmlEntities($title).'"';
- $ret .= ' alt="'.$this->_xmlEntities($title).'"';
- }else{
- $ret .= ' alt=""';
- }
-
- if ( !is_null($width) )
- $ret .= ' width="'.$this->_xmlEntities($width).'"';
-
- if ( !is_null($height) )
- $ret .= ' height="'.$this->_xmlEntities($height).'"';
-
- $ret .= ' />';
-
- }elseif($mime == 'application/x-shockwave-flash'){
- //FIXME default to a higher flash version?
-
- $ret .= '_xmlEntities($width).'"';
- if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"';
- $ret .= '>'.DOKU_LF;
- $ret .= ' '.DOKU_LF;
- $ret .= ' '.DOKU_LF;
- $ret .= '_xmlEntities($width).'"';
- if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"';
- $ret .= ' type="application/x-shockwave-flash"'.
- ' pluginspage="http://www.macromedia.com/shockwave/download/index.cgi'.
- '?P1_Prod_Version=ShockwaveFlash"> '.DOKU_LF;
- $ret .= ' '.DOKU_LF;
-
- }elseif(!is_null($title)){
- // well at least we have a title to display
- $ret .= $this->_xmlEntities($title);
- }else{
- // just show the source
- $ret .= $this->_xmlEntities($src);
- }
-
- return $ret;
- }
-
// $numrows not yet implemented
function table_open($maxcols = NULL, $numrows = NULL){
$this->doc .= ''.DOKU_LF;
@@ -868,8 +801,9 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
// Utils
/**
- * Assembles all parts defined by the link formater below
- * Returns HTML for the link
+ * Build a link
+ *
+ * Assembles all parts defined in $link returns HTML for the link
*
* @author Andreas Gohr
*/
@@ -913,6 +847,66 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
return preg_replace('!.*'.$nssep.'!','',$name);
}
+
+ /**
+ * Renders internal and external media
+ *
+ * @author Andreas Gohr
+ */
+ function _media ($src, $title=NULL, $align=NULL, $width=NULL,
+ $height=NULL, $cache=NULL) {
+
+ $ret = '';
+
+ list($ext,$mime) = mimetype($src);
+ if(substr($mime,0,5) == 'image'){
+ //add image tag
+ $ret .= ' _xmlEntities($title).'"';
+ $ret .= ' alt="'.$this->_xmlEntities($title).'"';
+ }else{
+ $ret .= ' alt=""';
+ }
+
+ if ( !is_null($width) )
+ $ret .= ' width="'.$this->_xmlEntities($width).'"';
+
+ if ( !is_null($height) )
+ $ret .= ' height="'.$this->_xmlEntities($height).'"';
+
+ $ret .= ' />';
+
+ }elseif($mime == 'application/x-shockwave-flash'){
+ $ret .= '_xmlEntities($width).'"';
+ if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"';
+ $ret .= '>'.DOKU_LF;
+ $ret .= ' '.DOKU_LF;
+ $ret .= ' '.DOKU_LF;
+ $ret .= '_xmlEntities($width).'"';
+ if ( !is_null($height) ) $ret .= ' height="'.$this->_xmlEntities($height).'"';
+ $ret .= ' type="application/x-shockwave-flash"'.
+ ' pluginspage="http://www.macromedia.com/go/getflashplayer"> '.DOKU_LF;
+ $ret .= ' '.DOKU_LF;
+
+ }elseif(!is_null($title)){
+ // well at least we have a title to display
+ $ret .= $this->_xmlEntities($title);
+ }else{
+ // just show the source
+ $ret .= $this->_xmlEntities($src);
+ }
+
+ return $ret;
+ }
function _newFootnoteId() {
static $id = 1;
@@ -929,16 +923,25 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
/**
* Adds code for section editing button
+ *
+ * This is just aplaceholder and gets replace by the button if
+ * section editing is allowed
+ *
+ * @author Andreas Gohr
*/
function _secedit($f, $t){
$this->doc .= '';
}
-
+
+ /**
+ * Construct a title and handle images in titles
+ *
+ * @author Harry Fuecks
+ */
function _getLinkTitle($title, $default, & $isImage, $id=NULL) {
global $conf;
$isImage = FALSE;
-
if ( is_null($title) ) {
if ($conf['useheading'] && $id) {
$heading = p_get_first_heading($id);
@@ -947,122 +950,28 @@ class Doku_Renderer_xhtml extends Doku_Renderer {
}
}
return $this->_xmlEntities($default);
-
} else if ( is_string($title) ) {
-
return $this->_xmlEntities($title);
-
} else if ( is_array($title) ) {
-
$isImage = TRUE;
return $this->_imageTitle($title);
-
}
}
/**
- * @TODO Resolve namespace on internal images
+ * Returns an HTML code for images used in link titles
+ *
+ * @todo Resolve namespace on internal images
+ * @author Andreas Gohr
*/
function _imageTitle($img) {
-
- //FIXME resolve internal links
-
return $this->_media($img['src'],
$img['title'],
$img['align'],
$img['width'],
$img['height'],
$img['cache']);
-
-/*
- if ( $img['type'] == 'internalmedia' ) {
-
- // Resolve here...
- if ( strpos($img['src'],':') ) {
- $src = explode(':',$img['src']);
- $src = $src[1];
- } else {
- $src = $img['src'];
- }
-
- $imgStr = ' _xmlEntities($img['title']).'"';
- } else {
- $imgStr .= ' alt=""';
- }
-
- if ( !is_null($img['align']) ) {
- $imgStr .= ' align="'.$img['align'].'"';
- }
-
- if ( !is_null($img['width']) ) {
- $imgStr .= ' width="'.$this->_xmlEntities($img['width']).'"';
- }
-
- if ( !is_null($img['height']) ) {
- $imgStr .= ' height="'.$this->_xmlEntities($img['height']).'"';
- }
-
- $imgStr .= '/>';
-
- return $imgStr;
-*/
}
}
-/**
-* Test whether there's an image to display with this interwiki link
-*/
-function interwikiImgExists($name) {
-
- static $exists = array();
-
- if ( array_key_exists($name,$exists) ) {
- return $exists[$name];
- }
-
- if( @file_exists( DOKU. 'interwiki/'.$name.'.png') ) {
- $exists[$name] = 'png';
- } else if ( @file_exists( DOKU . 'interwiki/'.$name.'.gif') ) {
- $exists[$name] = 'gif';
- } else {
- $exists[$name] = FALSE;
- }
-
- return $exists[$name];
-}
-
-/**
- * For determining whether to use CSS class "wikilink1" or "wikilink2"
- * @todo use configinstead of DOKU_DATA
- * @deprecated -> resolve_pagename should be used
- */
-function wikiPageExists($name) {
-msg("deprecated wikiPageExists called",-1);
- static $pages = array();
-
- if ( array_key_exists($name,$pages) ) {
- return $pages[$name];
- }
-
- $file = str_replace(':','/',$name).'.txt';
-
- if ( @file_exists( DOKU_DATA . $file ) ) {
- $pages[$name] = TRUE;
- } else {
- $pages[$name] = FALSE;
- }
-
- return $pages[$name];
-}
-
-
//Setup VIM: ex: et ts=4 enc=utf-8 :
diff --git a/inc/parserutils.php b/inc/parserutils.php
index 3c7803b16..4f90364aa 100644
--- a/inc/parserutils.php
+++ b/inc/parserutils.php
@@ -256,7 +256,6 @@ function p_render($mode,$instructions){
*
* @author Jan Decaluwe
*/
-
function p_get_first_heading($id){
$file = wikiFN($id);
if (@file_exists($file)) {
--
cgit v1.2.3