Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

172 lines (146 sloc) 5.223 kb
<?php
/*
This filter plugin implements minimal html tag balancing, and can also
convert ewiki_page() output into (hopefully) valid xhtml. It just works
around some markup problems found in ewiki and that may arise from Wiki
markup abuse; it however provides no fix for <ul> inside <ul> or even
<h2> inside <p> problems (this should rather be fixed in the ewiki_format
function). So following code is not meant to fix any possible html file,
and it certainly won't make valid html files out of random binary data.
So for full html spec conformance you should rather utilize w3c tidy (by
using your Webservers "Filter" directive).
*/
define("EWIKI_XHTML", 1);
$ewiki_plugins["page_final"][] = "ewiki_html_tag_balancer";
function ewiki_html_tag_balancer(&$html) {
#-- vars
$html_standalone = array(
"img", "br", "hr",
"input", "meta", "link",
);
$html_tags = array(
"a", "abbr", "acronym", "address", "applet", "area", "b", "base",
"basefont", "bdo", "big", "blockquote", "body", "br", "button",
"caption", "center", "cite", "code", "col", "colgroup", "dd", "del",
"dfn", "dir", "div", "dl", "dt", "em", "fieldset", "font", "form",
"h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html", "i",
"iframe", "img", "input", "ins", "kbd", "label", "legend", "li",
"link", "map", "menu", "meta", "noframes", "noscript", "object", "ol",
"optgroup", "option", "p", "param", "pre", "q", "s", "samp", "script",
"select", "small", "span", "strike", "strong", "style", "sub", "sup",
"table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title",
"tr", "tt", "u", "ul", "var",
#-- H2.0 "nextid", "listing", "xmp", "plaintext",
#-- H3.2 "frame", "frameset",
#-- X1.1 "rb", "rbc", "rp", "rt", "rtc", "ruby",
);
$close_opened_when = array(
"p", "div", "ul", "td", "table", "tr",
);
if (!EWIKI_XHTML) {
$html_tags = array_merge( (array) $html_tags, array(
"bgsound", "embed", "layer", "multicol", "nobr", "noembed",
));
}
#-- walk through all tags
$tree = array();
$len = strlen($html);
$done = "";
$pos = 0;
$loop = 1000;
while (($pos < $len) && $loop--) {
#-- search next tag
$l = strpos($html, "<", $pos);
$r = strpos($html, ">", $l);
if (($l===false) or ($r===false)) {
# finish
$done .= substr($html, $pos);
break;
}
#-- copy plain text part
if ($l >= $pos) {
$done .= substr($html, $pos, $l-$pos);
$pos = $l;
}
#-- analyze current html tag
if ($r >= $pos) {
$pos = $r + 1;
$tag = substr($html, $l + 1, $r - $l - 1);
#-- split into name and attributes
$tname = strtolower(strtok($tag, " \t\n>")); // LOWERCASING not needed here really
($tattr = strtok(">")) && ($tattr = " $tattr");
// attribute checking could go here
// (here we just assume good output from ewiki core)
// ...
#-- html comment
if (substr($tname, 0, 3) == "!--") {
$r = strpos($html, "-->", $l+4);
$pos = $r + 3;
$done .= substr($html, $l, $r-$l+3);
continue;
}
#-- opening tag?
elseif ($tname[0] != "/") {
#-- standalone tag
if (in_array($tname, $html_standalone)) {
$tattr = rtrim(rtrim($tattr, "/"));
if (EWIKI_XHTML) {
$tattr .= " /";
}
}
#-- normal tag
else {
if (in_array($tname, $html_tags)) {
#-- ok
}
else {
#$tattr .= " class=\"$tname\"";
#$tname = "div";
}
array_push($tree, $tname);
}
$tag = "$tname$tattr";
}
#-- closing tag
else {
$tname = substr($tname, 1);
if (!in_array($tname, $html_tags)) {
$tname= "div";
}
#-- check if this is allowed
if (!$tree) {
continue; // ignore closing tag
}
$last = array_pop($tree);
if ($last != $tname) {
#-- close until last opened block element
if (in_array($tname, $close_opened_when)) {
do {
$done .= "</$last>";
}
while (($last = array_pop($tree)) && ($last!=$tname));
}
#-- close last, close current, reopen last
else {
array_push($tree, $last);
$done .= "</$last></$tname><$last>";
continue;
}
}
else {
#-- all ok
}
#-- readd closing-slash to tag name
$tag = "/$tname";
}
$done .= "<$tag>";
}
}
#-- close still open tags
while ($tree && ($last = array_pop($tree))) {
$done .= "</$last>";
}
#-- copy back changes
$html = $done;
}
?>
Jump to Line
Something went wrong with that request. Please try again.