*/
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('#<sub>(.*?)</sub>#is','\1',$text);
$text = preg_replace('#<sup>(.*?)</sup>#is','\1',$text);
//do quoting
$text = preg_replace("/\n((>)[^\n]*?\n)+/se","'\n'.quoteformat('\\0').'\n'",$text);
// Typography
if($conf['typography']){
$text = preg_replace('/([^-])--([^-])/s','\1–\2',$text); //endash
$text = preg_replace('/([^-])---([^-])/s','\1—\2',$text); //emdash
$text = preg_replace('/"([^\"]+?)"/s','“\1”',$text); //curly quotes
$text = preg_replace('/(\s)\'(\S)/m','\1‘\2',$text); //single open quote
$text = preg_replace('/(\S)\'/','\1’',$text); //single closing quote or apostroph
$text = preg_replace('/\.\.\./','\1…\2',$text); //ellipse
$text = preg_replace('/(\d+)x(\d+)/i','\1×\2',$text); //640x480
$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('/=>/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)#',"
\\1",$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,'/(\W)'.$sm[0].'(\W)/s',$sm[1],"\\1","\\2");
}
}
/**
* Add acronym tags to known acronyms
*
* @author Andreas Gohr
*/
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',"\\2","\\1","\\3");
}
}
/**
* 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
*/
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 = trim($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 = '';
}
if ($head) {
$ret .= " $data | \n";
} else {
$ret .= " $data | \n";
}
}
$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);
}
?>