mirror of
https://github.com/moodle/moodle.git
synced 2025-02-21 01:48:45 +01:00
292 lines
8.9 KiB
PHP
292 lines
8.9 KiB
PHP
<?php
|
||
|
||
/*
|
||
* Wiki-Engine from "ErfurtWiki", Mario Salzer <milky@erphesfurt.de>
|
||
* Adapted by Frank Luithle <sigi@fsinfo.cs.uni-sb.de>
|
||
*
|
||
* WikiLinks and binary already stripped off -> just the rendering core
|
||
*/
|
||
|
||
// URL prefixes
|
||
$ewiki_idf_url = array( "http://",
|
||
"mailto:",
|
||
"ftp://",
|
||
"irc://",
|
||
"telnet://",
|
||
"news://",
|
||
"internal://",
|
||
"chrome://",
|
||
"file://" );
|
||
|
||
// allowed wikinames
|
||
//define( "EWIKI_CHARS_L", "a-z<><7A><EFBFBD><EFBFBD>_<EFBFBD><5F>$" );
|
||
//define( "EWIKI_CHARS_U", "A-Z<><5A><EFBFBD>" );
|
||
|
||
function wiki_format( $wiki_source,
|
||
$strip_slashes = true,
|
||
$safe_html_allowed = true,
|
||
$table_html_allowed = false ) {
|
||
|
||
if ( $strip_slashes ) {
|
||
$wiki_source = stripslashes( $wiki_source );
|
||
}
|
||
|
||
// formatted output
|
||
$o = "<p>\n";
|
||
|
||
// state vars
|
||
$li_o = "";
|
||
$tbl_o = 0;
|
||
$post = "";
|
||
|
||
$wm_whole_line = array( "!!!" => "h2",
|
||
"!!" => "h3",
|
||
"!" => "h4",
|
||
" " => "tt",
|
||
";:" => 'div style="left-margin:10pt;"' );
|
||
|
||
$table_defaults = 'cellpadding="2" border="1" cellspacing="0"';
|
||
|
||
// these tags will be preserved if the $safe_html_allowed argument
|
||
// is set to 'true'
|
||
$rescue_html = array( "tt", "b", "i", "strong", "em", "s", "kbd", "var",
|
||
"xmp", "sup", "sub", "pre", "q", "h2", "h3", "h4",
|
||
"h5", "h6", "cite", "code", "u" );
|
||
|
||
$syn_htmlentities = array( "&" => "&",
|
||
">" => ">",
|
||
"<" => "<",
|
||
"%%%" => "<br/>" );
|
||
|
||
$wm_list = array( "-" => array('ul type="square"', "", "li"),
|
||
"*" => array('ul type="circle"', "", "li"),
|
||
"#" => array("ol", "", "li"),
|
||
":" => array("dl", "dt", "dd") );
|
||
|
||
$wm_text_style = array( "'''" => array("''__", "__''"),
|
||
"___" => array("''__", "__''"),
|
||
"''" => array("<em>", "</em>"),
|
||
"__" => array("<strong>", "</strong>"),
|
||
// "^^" => array("<sup>", "</sup>"),
|
||
// "***" => array("<b><i>", "</i></b>"),
|
||
// "###" => array("<big><b>", "</b></big>"),
|
||
"**" => array("<b>", "</b>"),
|
||
"##" => array("<big>", "</big>"),
|
||
"<EFBFBD><EFBFBD>" => array("<small>", "</small>") );
|
||
|
||
$link_regex = "#(!?\[[^[\]\n]+\])|((?:!?[a-z]{2,6}://|mailto:)[^\s\[\]\'\"\)\,<]+)#";
|
||
|
||
#$link_regex = "#(!?\[[^[\]\n]+\])|((?:!?[".EWIKI_CHARS_U."]+[".EWIKI_CHARS_L.
|
||
# ":]+){2}[\w\d]*)|((?:!?[a-z]{2,6}://|mailto:)[^\s\[\]\'\"\)\,<]+)#";
|
||
|
||
// eliminate html
|
||
foreach ( $syn_htmlentities as $find => $replace ) {
|
||
$wiki_source = str_replace( $find, $replace, $wiki_source );
|
||
}
|
||
array_pop( $syn_htmlentities );
|
||
|
||
// unescape allowed html
|
||
if ( $safe_html_allowed ) {
|
||
foreach ( $rescue_html as $tag ) {
|
||
foreach( array( $tag, "/$tag", ( $tag = strtoupper($tag) ), "/$tag" )
|
||
as $tag ) {
|
||
$wiki_source = str_replace( '<' . $tag . '>',
|
||
"<" . $tag . ">",
|
||
$wiki_source );
|
||
}
|
||
}
|
||
}
|
||
|
||
$wiki_source = trim( $wiki_source ) . "\n";
|
||
|
||
foreach ( explode( "\n", $wiki_source ) as $line ) {
|
||
$line = rtrim( $line );
|
||
$post = "";
|
||
|
||
// paragraphs
|
||
if ( empty($line) ) {
|
||
$post .= "</p>\n\n<p>";
|
||
} elseif ( strpos( $line, "----" ) === 0 ) {
|
||
$o .= "<hr>\n";
|
||
continue;
|
||
} elseif ( strpos( $line, "<!--" ) === 0 ) {
|
||
$o .= "<!-- " . s( str_replace( "--", "__", substr($line, 7) ) ) . " -->\n";
|
||
continue;
|
||
}
|
||
|
||
// unescape html markup || tables wiki markup
|
||
if ( strlen( $line ) && ( $line[0] == "|" ) ) {
|
||
if ( strlen( $line ) >
|
||
strlen( trim( $line, "|" ) ) + 1 ) {
|
||
$line = substr( $line, 1, strlen( $line ) - 2 );
|
||
if ( !$tbl_o ) {
|
||
$o .= "<table " . $table_defaults . ">\n";
|
||
}
|
||
$line = "<tr>\n<td>" . str_replace("|", "</td>\n<td>", $line) . "</td>\n</tr>";
|
||
$tbl_o = 1;
|
||
} elseif ( $table_html_allowed ) {
|
||
$line = ltrim( substr( $line, 1 ) );
|
||
foreach ( array_flip( $syn_htmlentities ) as $find => $replace ) {
|
||
$line = str_replace( $find, $replace, $line );
|
||
}
|
||
}
|
||
} elseif ($tbl_o) {
|
||
$o .= "</table>\n";
|
||
$tbl_o = 0;
|
||
}
|
||
|
||
// whole-line wikimarkup
|
||
foreach ( $wm_whole_line as $find => $replace ) {
|
||
if ( substr( $line, 0, strlen($find) ) == $find ) {
|
||
$line = ltrim( substr( $line, strlen($find) ) );
|
||
$o .= "<$replace>";
|
||
$post = "</" . strtok( $replace, " " ) . ">" . $post;
|
||
}
|
||
}
|
||
|
||
// wiki list markup
|
||
if ( strlen( $li_o ) ||
|
||
strlen( $line ) && isset( $wm_list[@$line[0]] ) ) {
|
||
$n = 0;
|
||
$li = "";
|
||
// count differences to previous list wikimarkup
|
||
while ( strlen( $line ) && ( $li0 = $line[0] ) && isset( $wm_list[$li0] ) ) {
|
||
$li .= $li0;
|
||
$n++;
|
||
$line = substr($line, 1);
|
||
}
|
||
$line = ltrim($line);
|
||
|
||
// fetch list definition
|
||
if ( strlen( $li ) && ( $last_list_i = $li[strlen($li)-1] ) )
|
||
list( $list_tag, $list_dt0, $list_entry_tag ) = $wm_list[$last_list_i];
|
||
|
||
// output <ul> until new list wikimarkup rule matched
|
||
while ( strlen($li_o) < strlen($li) ) {
|
||
$add = $li[ strlen($li_o) ];
|
||
$o .= "<" . $wm_list[ $add ][ 0 ] . ">\n";
|
||
$li_o .= $add;
|
||
}
|
||
|
||
// close </ul> lists until "$li_o" == "$li" (list wikimarkup state var)
|
||
while ( strlen($li_o) > strlen($li) ) {
|
||
$del = $li_o[ strlen($li_o) - 1 ];
|
||
$o .= "</" . strtok( $wm_list[$del][0], " " ) . ">\n";
|
||
$li_o = substr( $li_o, 0, strlen($li_o) - 1 );
|
||
}
|
||
|
||
// more work for <dl> lists
|
||
if ( !empty($list_dt0) ) {
|
||
list( $line_dt, $line ) = explode( $last_list_i, $line, 2 );
|
||
$o .= "<$list_dt0>$line_dt</$list_dt0>";
|
||
$list_dt0 = $last_list_i = false;
|
||
}
|
||
|
||
// finally enclose current line in <li>...</li>
|
||
if ( !empty($line) ) {
|
||
$o .= "<$list_entry_tag>";
|
||
$post = "</$list_entry_tag>" . $post;
|
||
}
|
||
|
||
$li_o = $li;
|
||
}
|
||
|
||
// link-regex here??
|
||
// (was formerly, may be faster if applied to the whole formatted
|
||
// page, but this could also introduce some rendering bugs)
|
||
|
||
// text style triggers
|
||
foreach ( $wm_text_style as $find => $replace ) {
|
||
$n = strlen( $find );
|
||
$loop = 20;
|
||
while( ( $loop-- ) &&
|
||
( ($l = strpos($line, $find)) !== false ) &&
|
||
( $r = strpos($line, $find, $l + $n) ) ) {
|
||
$line = substr( $line, 0, $l ) . $replace[0] .
|
||
substr( $line, $l + strlen($find), $r - $l - $n ) .
|
||
$replace[1] . substr( $line, $r + $n );
|
||
}
|
||
}
|
||
|
||
// add formatted line to page-output
|
||
$o .= $line . $post . "\n";
|
||
|
||
}
|
||
|
||
// close last line
|
||
$o .= "</p>\n";
|
||
|
||
// finally the link-detection-regex
|
||
// (impossible to do with simple string arithmetics)
|
||
$o = preg_replace_callback( $link_regex, "wiki_link_regex_callback", $o );
|
||
|
||
return( $o );
|
||
}
|
||
|
||
|
||
function wiki_link_regex_callback( $uu ) {
|
||
|
||
global $ewiki_idf_url;
|
||
|
||
$str = $uu[0];
|
||
|
||
// link bracket '[' escaped with '!'
|
||
if ( $str[0] == "!" ) {
|
||
return(substr($str, 1));
|
||
} elseif ( $str[0] == "[" ) {
|
||
$str = substr( $str, 1, strlen($str) - 2 );
|
||
}
|
||
|
||
// explicit title given via [ foo | bar ]
|
||
$href = $title = strtok( $str, "|" );
|
||
if ( $uu = strtok("|") ) {
|
||
$href = $uu;
|
||
}
|
||
|
||
// title and href swapped: swap back
|
||
if ( strpos( "://", $title ) ||
|
||
strpos( $title, ":" ) && !strpos( $href, ":" ) ) {
|
||
$uu = $title;
|
||
$title = $href;
|
||
$href = $uu;
|
||
}
|
||
|
||
$title = trim($title);
|
||
$href = trim($href);
|
||
|
||
/* create _no_ WikiLinks */
|
||
if ( false ){
|
||
// interwiki links
|
||
if ( strpos($href, ":") &&
|
||
!strpos($href, "//") &&
|
||
($p1 = @$ewiki_interwiki[strtok($href, ":")]) ) {
|
||
while ($p1_alias = @$ewiki_interwiki[$p1]) {
|
||
$p1 = $p1_alias;
|
||
}
|
||
$href = $p1 . strtok("\000");
|
||
} elseif (($ewiki_links === true) ||
|
||
@$ewiki_links[$href] ||
|
||
@$ewiki_internal_pages[$href]) {
|
||
// ordinary internal WikiLinks
|
||
$str = '<a href="' . EWIKI_SCRIPT .
|
||
urlencode($href) . '">' . $title . '</a>';
|
||
} else {
|
||
$str = '<b>' . $title . '</b><a href="' .
|
||
EWIKI_SCRIPT . urlencode($href) /*.EWIKI_ADDPARAMDELIM.'edit'*/ .
|
||
' ">?</a>';
|
||
}
|
||
}
|
||
|
||
// convert normal URLs
|
||
foreach ( $ewiki_idf_url as $find ) {
|
||
if ( strpos( $href, $find ) === 0 ) {
|
||
$str = '<a href="' . $href . '">' . $title . '</a>';
|
||
break;
|
||
}
|
||
}
|
||
|
||
return($str);
|
||
}
|
||
|
||
|