From: Geoffrey T. D. <da...@us...> - 2001-03-02 00:22:53
|
Update of /cvsroot/phpwiki/phpwiki/lib In directory usw-pr-cvs1:/tmp/cvs-serv19995/lib Modified Files: transform.php Log Message: Attempts to clean up generated HTML. WikiTransform::SetHTMLMode(): Eliminate the $tagtype argument, since somewhere along the line it had lost all meaning. Check when pushing nested elements that the top-level element is of a type which can contain other block-level elements. Elements of type <p>, and <pre>, among others, are not allowed to contain other block-level elements. wtm_list_dl: Fix bug (which manifested itself only with non-empty <dt>s). Some remaining problems which perhaps should be addressed: Wtm_title_search, wtm_fulltext_search, wtm_mostpopular as well as some of the the magic phpwiki: links (the ones which generate forms) all generate some sort of block-level HTML element (either <form>s or <dl>s.) As noted above, these are not allowed within <p> elements (and others). Bold/italics: __Bold ''BoldItalic__ Italic'' ... it's contrived, but it will generate improperly nested HTML. Index: transform.php =================================================================== RCS file: /cvsroot/phpwiki/phpwiki/lib/transform.php,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** transform.php 2001/02/15 21:37:08 1.17 --- transform.php 2001/03/02 00:24:17 1.18 *************** *** 33,50 **** function SetHTMLMode($tag, $tagtype, $level) ! Wiki HTML output can, at any given time, be in only one mode. ! It will be something like Unordered List, Preformatted Text, ! plain text etc. When we change modes we have to issue close tags ! for one mode and start tags for another. ! SetHTMLMode takes care of this. ! ! $tag ... HTML tag to insert ! If $tag is an array, first element give tag, second element ! is a hash containing arguments for the tag. ! $tagtype ... ZERO_LEVEL - close all open tags before inserting $tag ! NESTED_LEVEL - close tags until depths match ! $level ... nesting level (depth) of $tag ! nesting is arbitrary limited to 10 levels function do_transform($html, $content) contains main-loop and calls transformer functions --- 33,64 ---- function SetHTMLMode($tag, $tagtype, $level) ! This is a helper function used to keep track of what HTML ! block-level element we are currently processing. ! Block-level elements are things like paragraphs "<p>", ! pre-formatted text "<pre>", and the various list elements: ! "<ul>", "<ol>" and "<dl>". Note that some of these elements ! can be nested, while others can not. (In particular, according to ! the HTML 4.01 specification, a paragraph "<p>" element is not ! allowed to contain any other block-level elements. Also <pre>, ! <li>, <dt>, <dd>, <h1> ... have this same restriction.) ! ! SetHTMLMode generates whatever HTML is necessary to get us into ! the requested element type at the requested nesting level. ! ! $tag ... type of HTML element to open. ! If $tag is an array, $tag[0] gives the element type, ! and $tag[1] should be a hash containing attribute-value ! pairs for the element. ! ! If $tag is the empty string, all open elements (down to the ! level requested by $level) are closed. Use ! SetHTMLMode('',0) to close all open block-level elements. ! ! $level ... requested nesting level for current element. ! The nesting level for top level block is one (which is ! the default). + Nesting is arbitrary limited to 10 levels + function do_transform($html, $content) contains main-loop and calls transformer functions *************** *** 82,86 **** // sets current mode like list, preformatted text, plain text, ... // takes care of closing (open) tags ! function SetHTMLMode($tag, $tagtype, $level) { if (is_array($tag)) { --- 96,100 ---- // sets current mode like list, preformatted text, plain text, ... // takes care of closing (open) tags ! function SetHTMLMode($tag, $level = 1) { if (is_array($tag)) { *************** *** 96,153 **** $retvar = ''; ! if ($tagtype == ZERO_LEVEL) { ! // empty the stack until $level == 0; ! if ($tag == $this->stack->top()) { ! return; // same tag? -> nothing to do ! } ! while ($this->stack->cnt() > 0) { ! $closetag = $this->stack->pop(); ! $retvar .= "</$closetag>\n"; ! } ! ! if ($tag) { ! $retvar .= StartTag($tag, $args) . "\n"; ! $this->stack->push($tag); ! } ! ! } elseif ($tagtype == NESTED_LEVEL) { ! if ($level <= $this->stack->cnt()) { ! // $tag has fewer nestings (old: tabs) than stack, ! // reduce stack to that tab count ! while ($this->stack->cnt() > $level) { ! $closetag = $this->stack->pop(); ! if ($closetag == false) { ! //echo "bounds error in tag stack"; ! break; ! } ! $retvar .= "</$closetag>\n"; ! } ! ! // if list type isn't the same, ! // back up one more and push new tag ! if ($tag != $this->stack->top()) { ! $closetag = $this->stack->pop(); ! $retvar .= "</$closetag>" . StartTag($tag, $args) . "\n"; ! $this->stack->push($tag); ! } ! } else { // $level > $this->stack->cnt() ! // we add the diff to the stack ! // stack might be zero ! while ($this->stack->cnt() < $level) { ! $retvar .= StartTag($tag, $args) . "\n"; ! $this->stack->push($tag); ! if ($this->stack->cnt() > 10) { ! // arbitrarily limit tag nesting ! ExitWiki(gettext ("Stack bounds exceeded in SetHTMLOutputMode")); ! } ! } } - - } else { // unknown $tagtype - ExitWiki ("Passed bad tag type value in SetHTMLOutputMode"); } ! return $this->token($retvar); } --- 110,152 ---- $retvar = ''; ! if ($level <= $this->stack->cnt()) { ! // $tag has fewer nestings (old: tabs) than stack, ! // reduce stack to that tab count ! while ($this->stack->cnt() > $level) { ! $closetag = $this->stack->pop(); ! assert('$closetag != false'); ! $retvar .= "</$closetag>\n"; ! } ! // if list type isn't the same, ! // back up one more and push new tag ! if ($tag && $tag != $this->stack->top()) { ! $closetag = $this->stack->pop(); ! $retvar .= "</$closetag>" . StartTag($tag, $args) . "\n"; ! $this->stack->push($tag); ! } ! } else {// $level > $this->stack->cnt() ! // Test for and close top level elements which are not allowed to contain ! // other block-level elements. ! if ($this->stack->cnt() == 1 and ! preg_match('/^(p|pre|h\d)$/i', $this->stack->top())) ! { ! $closetag = $this->stack->pop(); ! $retvar .= "</$closetag>"; ! } ! ! // we add the diff to the stack ! // stack might be zero ! while ($this->stack->cnt() < $level) { ! $retvar .= StartTag($tag, $args) . "\n"; ! $this->stack->push($tag); ! if ($this->stack->cnt() > 10) { ! // arbitrarily limit tag nesting ! ExitWiki(gettext ("Stack bounds exceeded in SetHTMLOutputMode")); ! } } } ! return $this->token($retvar); } *************** *** 173,179 **** $line = $this->content[$lnum]; ! // blank lines clear the current mode if (!strlen($line) || $line == "\r") { ! $html .= $this->SetHTMLMode('', ZERO_LEVEL, 0); continue; } --- 172,178 ---- $line = $this->content[$lnum]; ! // blank lines clear the current mode (to force new paragraph) if (!strlen($line) || $line == "\r") { ! $html .= $this->SetHTMLMode('', 0); continue; } *************** *** 206,210 **** } // close all tags ! $html .= $this->SetHTMLMode('', ZERO_LEVEL, 0); return $this->untokenize($html); --- 205,209 ---- } // close all tags ! $html .= $this->SetHTMLMode('', 0); return $this->untokenize($html); *************** *** 486,493 **** // has to be registereed before list OL function wtm_list_ul($line, &$trfrm) { ! if (preg_match("/^([#*]*\*)[^#]/", $line, $matches)) { $numtabs = strlen($matches[1]); $line = preg_replace("/^([#*]*\*)/", '', $line); ! $html = $trfrm->SetHTMLMode('ul', NESTED_LEVEL, $numtabs) . '<li>'; $line = $html . $line; } --- 485,492 ---- // has to be registereed before list OL function wtm_list_ul($line, &$trfrm) { ! if (preg_match("/^([#*;]*\*)[^#]/", $line, $matches)) { $numtabs = strlen($matches[1]); $line = preg_replace("/^([#*]*\*)/", '', $line); ! $html = $trfrm->SetHTMLMode('ul', $numtabs) . '<li>'; $line = $html . $line; } *************** *** 497,504 **** // ordered lists <OL>: "#" function wtm_list_ol($line, &$trfrm) { ! if (preg_match("/^([#*]*\#)/", $line, $matches)) { $numtabs = strlen($matches[1]); $line = preg_replace("/^([#*]*\#)/", "", $line); ! $html = $trfrm->SetHTMLMode('ol', NESTED_LEVEL, $numtabs) . '<li>'; $line = $html . $line; } --- 496,503 ---- // ordered lists <OL>: "#" function wtm_list_ol($line, &$trfrm) { ! if (preg_match("/^([#*;]*\#)/", $line, $matches)) { $numtabs = strlen($matches[1]); $line = preg_replace("/^([#*]*\#)/", "", $line); ! $html = $trfrm->SetHTMLMode('ol', $numtabs) . '<li>'; $line = $html . $line; } *************** *** 509,517 **** // definition lists <DL>: ";text:text" function wtm_list_dl($line, &$trfrm) { ! if (preg_match("/(^;+)(.*?):(.*$)/", $line, $matches)) { $numtabs = strlen($matches[1]); ! $line = $trfrm->SetHTMLMode('dl', NESTED_LEVEL, $numtabs); if(trim($matches[2])) ! $line = '<dt>' . $matches[2]; $line .= '<dd>' . $matches[3]; } --- 508,516 ---- // definition lists <DL>: ";text:text" function wtm_list_dl($line, &$trfrm) { ! if (preg_match("/^([#*;]*;)(.*?):(.*$)/", $line, $matches)) { $numtabs = strlen($matches[1]); ! $line = $trfrm->SetHTMLMode('dl', $numtabs); if(trim($matches[2])) ! $line .= '<dt>' . $matches[2]; $line .= '<dd>' . $matches[3]; } *************** *** 522,526 **** function wtm_preformatted($line, &$trfrm) { if (preg_match("/^\s+/", $line)) { ! $line = $trfrm->SetHTMLMode('pre', ZERO_LEVEL, 0) . $line; } return $line; --- 521,525 ---- function wtm_preformatted($line, &$trfrm) { if (preg_match("/^\s+/", $line)) { ! $line = $trfrm->SetHTMLMode('pre') . $line; } return $line; *************** *** 535,539 **** elseif($whichheading[1] == '!!!') $heading = 'h1'; $line = preg_replace("/^!+/", '', $line); ! $line = $trfrm->SetHTMLMode($heading, ZERO_LEVEL, 0) . $line; } return $line; --- 534,538 ---- elseif($whichheading[1] == '!!!') $heading = 'h1'; $line = preg_replace("/^!+/", '', $line); ! $line = $trfrm->SetHTMLMode($heading) . $line; } return $line; *************** *** 572,577 **** 'cellpadding' => 1, 'cellspacing' => 1, ! 'border' => 1)), ! ZERO_LEVEL, 0) . $row; } --- 571,575 ---- 'cellpadding' => 1, 'cellspacing' => 1, ! 'border' => 1))) . $row; } *************** *** 582,588 **** function wtm_hr($line, &$trfrm) { if (preg_match('/^-{4,}(.*)$/', $line, $m)) { ! $line = $trfrm->SetHTMLMode('', ZERO_LEVEL, 0) . '<hr>'; if ($m[1]) ! $line .= $trfrm->SetHTMLMode('p', ZERO_LEVEL, 0) . $m[1]; } return $line; --- 580,586 ---- function wtm_hr($line, &$trfrm) { if (preg_match('/^-{4,}(.*)$/', $line, $m)) { ! $line = $trfrm->SetHTMLMode('', 0) . '<hr>'; if ($m[1]) ! $line .= $trfrm->SetHTMLMode('p') . $m[1]; } return $line; *************** *** 591,595 **** // default mode: simple text paragraph function wtm_paragraph($line, &$trfrm) { ! $line = $trfrm->SetHTMLMode('p', ZERO_LEVEL, 0) . $line; return $line; } --- 589,593 ---- // default mode: simple text paragraph function wtm_paragraph($line, &$trfrm) { ! $line = $trfrm->SetHTMLMode('p') . $line; return $line; } |