[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/mod/wiki/ewiki/plugins/moodle/ -> f_fixhtml.php (source)

   1  <?php // $Id: f_fixhtml.php,v 1.7 2007/05/08 16:12:10 poltawski Exp $
   2  
   3  /*
   4     This filter plugin implements minimal html tag balancing, and can also
   5     convert ewiki_page() output into (hopefully) valid xhtml. It just works
   6     around some markup problems found in ewiki and that may arise from Wiki
   7     markup abuse; it however provides no fix for <ul> inside <ul> or even
   8     <h2> inside <p> problems (this should rather be fixed in the ewiki_format
   9     function).  So following code is not meant to fix any possible html file,
  10     and it certainly won't make valid html files out of random binary data. 
  11     So for full html spec conformance you should rather utilize w3c tidy (by
  12     using your Webservers "Filter" directive).
  13  */
  14  
  15  
  16  define("EWIKI_XHTML", 1);
  17  $ewiki_plugins["page_final"][] = "ewiki_html_tag_balancer";
  18  
  19  
  20  function ewiki_html_tag_balancer(&$html) {
  21  
  22     #-- vars
  23     $html_standalone = array(
  24        "img", "br", "hr",
  25        "input", "meta", "link",
  26     );
  27     $html_tags = array(
  28        "a", "abbr", "acronym", "address", "applet", "area", "b", "base",
  29        "basefont", "bdo", "big", "blockquote", "body", "br", "button",
  30        "caption", "center", "cite", "code", "col", "colgroup", "dd", "del",
  31        "dfn", "dir", "div", "dl", "dt", "em", "fieldset", "font", "form",
  32        "h1", "h2", "h3", "h4", "h5", "h6", "head", "hr", "html", "i",
  33        "iframe", "img", "input", "ins", "kbd", "label", "legend", "li",
  34        "link", "map", "menu", "meta", "noframes", "noscript", "object", "ol",
  35        "optgroup", "option", "p", "param", "pre", "q", "s", "samp", "script",
  36        "select", "small", "span", "strike", "strong", "style", "sub", "sup",
  37        "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "title",
  38        "tr", "tt", "u", "ul", "var",
  39        #-- H2.0  "nextid", "listing", "xmp", "plaintext",
  40        #-- H3.2  "frame", "frameset",
  41        #-- X1.1  "rb", "rbc", "rp", "rt", "rtc", "ruby",
  42     );
  43     $close_opened_when = array(
  44        "p", "div", "ul", "td", "table", "tr",
  45     );
  46     if (!EWIKI_XHTML) {
  47        $html_tags = array_merge(  (array) $html_tags, array(
  48           "bgsound", "embed", "layer", "multicol", "nobr", "noembed",
  49        ));
  50     }
  51  
  52     #-- walk through all tags
  53     $tree = array();
  54     $len = strlen($html);
  55     $done = "";
  56     $pos = 0;
  57     $loop = (int)$len / 3;
  58     while (($pos < $len) && $loop--) {
  59  
  60        #-- search next tag
  61        $l = strpos($html, "<", $pos);
  62        $r = strpos($html, ">", $l);
  63        if (($l===false) or ($r===false)) {
  64           # finish
  65           $done .= substr($html, $pos);
  66           break;
  67        }
  68  
  69        #-- copy plain text part
  70        if ($l >= $pos) {
  71           $done .= substr($html, $pos, $l-$pos);
  72           $pos = $l;
  73        }
  74  
  75        #-- analyze current html tag
  76        if ($r >= $pos) {
  77           $pos = $r + 1;
  78           $tag = substr($html, $l + 1, $r - $l - 1);
  79  
  80           #-- split into name and attributes
  81           $tname = strtolower(strtok($tag, " \t\n>"));     // LOWERCASING not needed here really
  82           ($tattr = strtok(">")) && ($tattr = " $tattr");
  83  
  84           // attribute checking could go here
  85           // (here we just assume good output from ewiki core)
  86           // ...
  87  
  88           #-- html comment
  89           if (substr($tname, 0, 3) == "!--") {
  90              $r = strpos($html, "-->", $l+4);
  91              $pos = $r + 3;
  92              $done .= substr($html, $l, $r-$l+3);
  93              continue;
  94           }
  95  
  96           #-- opening tag?
  97           elseif ($tname[0] != "/") {
  98  
  99              #-- cdata
 100              if($tname=='![cdata[') {
 101                  $tname = strtoupper($tname); // Needs to be uppercase for XHTML compliance
 102                  // LEAVE THE POOR THING ALONE!
 103              }
 104              #-- standalone tag
 105              else if (in_array($tname, $html_standalone)) {
 106                 $tattr = rtrim(rtrim($tattr, "/"));
 107                 if (EWIKI_XHTML) {
 108                    $tattr .= " /";
 109                 }
 110              }
 111              #-- normal tag
 112              else {
 113                 if (in_array($tname, $html_tags)) {
 114                    #-- ok
 115                 }
 116                 else {
 117                    #$tattr .= " class=\"$tname\"";
 118                    #$tname = "div";
 119                 }
 120                 array_push($tree, $tname);
 121              }
 122  
 123              $tag = "$tname$tattr";
 124           }
 125           #-- closing tag
 126           else {
 127              $tname = substr($tname, 1);
 128  
 129              if (!in_array($tname, $html_tags)) {
 130                 $tname= "div";
 131              }
 132  
 133              #-- check if this is allowed
 134              if (!$tree) {
 135                 continue;   // ignore closing tag
 136              }
 137              $last = array_pop($tree);
 138              if ($last != $tname) {
 139  
 140                 #-- close until last opened block element
 141                 if (in_array($tname, $close_opened_when)) {
 142                    do {
 143                       $done .= "</$last>";
 144                    }
 145                    while (($last = array_pop($tree)) && ($last!=$tname));
 146                 }
 147                 #-- close last, close current, reopen last
 148                 else {
 149                    array_push($tree, $last);
 150                    $done .= "</$last></$tname><$last>";
 151                    continue;
 152                 }
 153              }
 154              else {
 155                 #-- all ok
 156              }
 157  
 158              #-- readd closing-slash to tag name
 159              $tag = "/$tname";
 160           }
 161  
 162           $done .= "<$tag>";
 163        }
 164     }
 165  
 166     #-- close still open tags
 167     while ($tree && ($last = array_pop($tree))) {
 168        $done .= "</$last>";
 169     }
 170  
 171     #-- copy back changes
 172     $html = $done;
 173  
 174  }
 175  
 176  
 177  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7