Thread: [phpwebapp-commits] CVS: web_app/parser test.php,NONE,1.1 parser.txt,NONE,1.1 class.WebPage.php,1.8,
Brought to you by:
dashohoxha
From: Dashamir H. <das...@us...> - 2004-07-13 13:18:19
|
Update of /cvsroot/phpwebapp/web_app/parser In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4377/parser Modified Files: class.WebPage.php class.WebObjectTpl.php class.Template.php class.Render.php class.Parser.php class.MainTpl.php class.FileTpl.php Added Files: test.php parser.txt Log Message: xml parser --- NEW FILE: test.php --- <?php $str = "test abc&&test1;;def xyz uvt &&test2;; "; //if there are 2 or more empty lines, replace them by a single one $str = preg_replace('/\n([ \t]*\n){2,}/', "\n\n", $str); //remove any empty lines in the begining $str = preg_replace('/^\s*\n/', '', $str); //remove any empty lines in the end $str = preg_replace('/\s*$/', '', $str); //Trim the indentation from the beginning of each line. //get the indentation of each line preg_match_all("/^( *)[^\n]/m", $str, $arr_matches); $arr_indents = $arr_matches[1]; //sort them asort($arr_indents); $arr_indents = array_values($arr_indents); //get the smallest one $smallest_indent = $arr_indents[0]; //remove it from the begining of each line $str = preg_replace("/^$smallest_indent/m", '', $str); //split the string back to the content array $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE; $arr = preg_split('/(&&[^;]+;;)/', $str, -1, $flags); $str1 = " djdj name='test3' <form jjdjdj name='form1' jd> ksksk name='test2' "; $pattern = '/<form[^>]*name=("|\')([^\\1]+)\\1/'; //ToDo: test it preg_match($pattern, $str1, $matches); $form_name = $matches[2]; $str2 = " hhhsh \n jksksks\n "; preg_match('/([ \t]*)$/', $str2, $matches); $indent = $matches[1]; print "<xmp>\n"; //print "'$form_name'\n"; //print "'$indent'\n"; print "'$str' \n"; print_r($arr); print "</xmp>\n"; ?> --- NEW FILE: parser.txt --- ---------------------------------------------------------------------- There are two parsing modes: 1. Normal mode. During this mode template objects are constructed for the relevant elements and they are added to the structure of the page ($webPage). 2. Copy mode. During this mode no new template objects are constructed and everything that is parsed is copied verbatim to the content of the current template. The copy mode is used for parsing WebClass-es (and WebBox-es, which are a special case of WebClass-es) in order to copy its content for later processing. This is due to the fact that a WebClass by itself does not add anything in the structure of the page. Only when an object (WebObject) of this WebClass is declared, the content of the WebClass is parsed in the normal mode. This content is reparsed for each WebObject that is declared in the page. ---------------------------------------------------------------------- Templates include each-other using the element <include>. For each template that is parsed, a new xml_parser is created. Also, when a <WebObject> element is found in a template, then the content of the corresponding WebClass is parsed as if it was included or pasted in that place. A new xml parser is created too, for parsing the content of the WebClass. Trick: Since the content of a template or the content of a WebClass may not be well-formed xml (because often it does not have a single root element), before sending it to the xml parser it is enclosed in a dummy element, which serves as its root element and which is just ignored by the parser. Sometimes the xml parser needs to know the name of the file that it is parsing, in order to display it in error messages, in case that there are xml errors in the file. For this reason, the name of the file that is being parsed is saved in a global array that keeps data related to each parser. ---------------------------------------------------------------------- The parser reads the templates and constructs an object representation of the web page that will be displayed. This is a tree structure where each object in the tree has the content of a template and references to other objects that are contained in this template. For each framework element like <if>, <repeat>, <webbox> etc. there is an object that represents it in the structure and which keeps its string content. It is like a DOM (Document Object Model) for the framework elements. Most of these objects are inheritors of the class 'Template'. The Template class has a member variable 'content' that contains the string content of the template. It is an array of chunks and references. A chunk of data is a string that contains a part of the template; it may have new lines inside as well and may not be terminated by a new line. A reference is a string like this: '&&tpl_id;;', where tpl_id is the id of the template that is linked (or referenced) in this place. When the parser is parsing a template (e.g. a file), whatever string that it finds is appended to the content of the current_template object. When if finds a framework element that indicates that a new object must be created, then it creates a new template object, pushes the current template in a stack, makes the new template as current, and continues parsing. Now whatever is parsed is appended to the new template object. Once it is done (indicated by a closing tag, e.g. </if>), then the previous template (which is not finished yet) is poped from the stack and made current_template, a reference from the previous template to the new template is added and the new template is added in the page structure, then the parsing of the previous template continues. ---------------------------------------------------------------------- Index: class.WebPage.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.WebPage.php,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** class.WebPage.php 25 Aug 2003 13:18:32 -0000 1.8 --- class.WebPage.php 13 Jul 2004 13:18:08 -0000 1.9 *************** *** 68,81 **** } ! /** Append the given line to the content of the <head> element. */ ! function append_to_head($line) { ! $this->tpl_collection["HeadTpl"]->content[] = $line; } ! /** Append the given line to the content of the <body> element. */ ! function append_to_body($line) { ! $this->tpl_collection["BodyTpl"]->content[] = $line; } --- 68,90 ---- } ! /** Append the given string to the content of the <head> element. */ ! function append_to_head($str) { ! $this->tpl_collection["HeadTpl"]->contents .= $str; } ! /** Append the given string to the content of the <body> element. */ ! function append_to_body($str) { ! $this->tpl_collection["BodyTpl"]->contents .= $str; ! } ! ! /** ! * Append a reference to the given template ! * at the end of the content of the <body> element. ! */ ! function link_to_body(&$tpl) ! { ! $this->tpl_collection["BodyTpl"]->contents .= '&&'.$tpl->id.';;'; } Index: class.WebObjectTpl.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.WebObjectTpl.php,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** class.WebObjectTpl.php 24 Sep 2003 14:20:08 -0000 1.7 --- class.WebObjectTpl.php 13 Jul 2004 13:18:08 -0000 1.8 *************** *** 42,46 **** /** Helps to render the template with a good indentation. */ ! var $indentation; /** Constructor */ --- 42,46 ---- /** Helps to render the template with a good indentation. */ ! var $indent; /** Constructor */ Index: class.Template.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.Template.php,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** class.Template.php 25 Aug 2003 13:18:32 -0000 1.7 --- class.Template.php 13 Jul 2004 13:18:08 -0000 1.8 *************** *** 40,45 **** var $vars; ! /** The lines of the template (array of lines). */ ! var $content; --- 40,48 ---- var $vars; ! /** The contents of the template. */ ! var $contents; ! ! /** The indentation of the template relative to the parent. */ ! var $indent; *************** *** 52,56 **** $this->type = $type; $this->vars = array(); - $this->content = array(); } --- 55,58 ---- *************** *** 74,85 **** return $tplVars; } /**#@+ Debug function. */ function toHtmlTable() { $htmlTable = " <br> <a name='$this->id'> </a>[<a href='javascript: back()'>Back</a>] ! <table width='90%' bgcolor='#aaaaaa' border='0' cellspacing='1' cellpadding='2'> <tr> <td bgcolor='#eeeeee' align='right' width='1%'>ID:</td> --- 76,163 ---- return $tplVars; } + + /** + * Returns an array of ids of the templates that are referenced + * from the contents of this template. + */ + function get_subtemplates() + { + $pattern = '/&&([^;]+);;/'; + preg_match_all($pattern, $this->contents, $matches); + $arr_tpl_id = $matches[1]; + return $arr_tpl_id; + } + + /** Split the contents to an array, according to the references. */ + function get_arr_contents() + { + $pattern = '/(&&[^;]+;;)/'; + $flags = PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE; + $arr_contents = preg_split($pattern, $this->contents, -1, $flags); + return $arr_contents; + } + + /** + * Replaces multiple empty lines by just one empty line, + * trims the indentation from the beginning of each line, etc. + */ + function normalize_space() + { + $str = $this->contents; + + //if there are 2 or more empty lines, replace them by a single one + $str = preg_replace('/\n([ \t]*\n){2,}/', "\n\n", $str); + + //remove any empty lines in the begining + $str = preg_replace('/^\s*\n/', '', $str); + + //remove any empty lines in the end + $str = preg_replace('/\n\s*$/', '', $str); + + //Trim the indentation from the beginning of each line. + //get the indentation of each line + preg_match_all("/^( *)[^\n]/m", $str, $arr_matches); + $arr_indents = $arr_matches[1]; + //sort them + asort($arr_indents); + $arr_indents = array_values($arr_indents); + //get the smallest one + $smallest_indent = $arr_indents[0]; + //remove it from the begining of each line + $str = preg_replace("/^$smallest_indent/m", '', $str); + + //set the indentation of the subtemplates + global $webPage; + $arr_tpl_id = $this->get_subtemplates(); + for ($i=0; $i < sizeof($arr_tpl_id); $i++) + { + $tpl_id = $arr_tpl_id[$i]; + + //get the indentation of the reference + $pattern = "|^( *)&&{$tpl_id};;|m"; + preg_match($pattern, $str, $matches); + $indent = $matches[1]; + + //remove it from the line of the reference + $str = preg_replace($pattern, "&&$tpl_id;;", $str); + + //set it as the indentation of the subtemplate + $tpl = $webPage->getTemplate($tpl_id); + $tpl->indent = $indent; + $webPage->addTemplate($tpl); + } + + //save the normalized string back to contents + $this->contents = $str; + } /**#@+ Debug function. */ function toHtmlTable() { + $indent = strtr($this->indent, ' ', '#'); $htmlTable = " <br> <a name='$this->id'> </a>[<a href='javascript: back()'>Back</a>] ! <table class='webapp' width='90%' bgcolor='#aaaaaa' border='0' cellspacing='1' cellpadding='2'> <tr> <td bgcolor='#eeeeee' align='right' width='1%'>ID:</td> *************** *** 90,96 **** <td bgcolor='#f9f9f9'>$this->type</td> </tr> ! " . $this->attribs2html() . " <tr><td colspan='2' bgcolor='#f9f9ff'> ! " . $this->content2html() . " </td></tr> </table> --- 168,180 ---- <td bgcolor='#f9f9f9'>$this->type</td> </tr> ! <tr> ! <td bgcolor='#eeeeee' align='right'>Indent:</td> ! <td bgcolor='#f9f9f9'> ! <pre><span style='background-color: #888888;'>$indent</span></pre> ! </td> ! </tr> ! " . $this->vars2html() . " <tr><td colspan='2' bgcolor='#f9f9ff'> ! " . $this->contents2html() . " </td></tr> </table> *************** *** 101,105 **** /** @see toHtmlTable() */ ! function attribs2html() { reset($this->vars); --- 185,189 ---- /** @see toHtmlTable() */ ! function vars2html() { reset($this->vars); *************** *** 118,137 **** /** @see toHtmlTable() */ ! function content2html() { $html = "\n<pre class='webapp'>"; ! $i = 0; ! while ($i < sizeof($this->content)) { ! $line = $this->content[$i++]; ! if (trim($line)=="##") { ! $line = $this->content[$i++]; ! $tpl_id = trim($line); ! $html .= "<a href='#$tpl_id'>##\n$tpl_id</a>\n"; } else { ! $html .= htmlentities($line); } } --- 202,224 ---- /** @see toHtmlTable() */ ! function contents2html() { + global $webPage; + + $arr_contents = $this->get_arr_contents(); $html = "\n<pre class='webapp'>"; ! for ($i=0; $i < sizeof($arr_contents); $i++) { ! $str = $arr_contents[$i]; ! if (preg_match('/^&&(.+);;$/', $str, $matches)) { ! $tpl_id = $matches[1]; ! $tpl = $webPage->getTemplate($tpl_id); ! //$html .= $tpl->indent; ! $html .= "<a href='#$tpl_id'>&&$tpl_id;;</a>"; } else { ! $html .= htmlentities($str); } } *************** *** 145,149 **** { //don't output the appended boxes ! if (ereg("web_app/append/append.html\$", $this->id)) return; global $webPage; --- 232,236 ---- { //don't output the appended boxes ! if (ereg("append/append.html\$", $this->id)) return; global $webPage; *************** *** 152,183 **** $tree .= $indent."+--<a href='#".$this->id."'>".$this->id."</a>" . " (".$this->type.")\n"; ! $i = 0; ! while ($i < sizeof($this->content)) { ! $line = $this->content[$i++]; ! if (trim($line)=="##") ! { ! $line = $this->content[$i++]; ! $tpl_id = trim($line); ! $tpl = $webPage->getTemplate($tpl_id); ! $tree .= $tpl->to_tree($indent."| "); ! } } return $tree; } - - /** - * Prints a preview of this template only (without processing - * subtemplates), for the benefit of the designer. - */ - function print_preview() - { - for ($i=0; $i < count($this->content); $i++) - { - $line = $this->content[$i]; - $line = WebApp::replaceVars($line); - print "\t\t".$line; - } - } /**#@-*/ } --- 239,252 ---- $tree .= $indent."+--<a href='#".$this->id."'>".$this->id."</a>" . " (".$this->type.")\n"; ! ! $arr_tpl_id = $this->get_subtemplates(); ! for ($i=0; $i < sizeof($arr_tpl_id); $i++) { ! $tpl_id = $arr_tpl_id[$i]; ! $tpl = $webPage->getTemplate($tpl_id); ! $tree .= $tpl->to_tree($indent."| "); } return $tree; } /**#@-*/ } Index: class.Render.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.Render.php,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** class.Render.php 24 Sep 2003 14:20:08 -0000 1.7 --- class.Render.php 13 Jul 2004 13:18:08 -0000 1.8 *************** *** 47,61 **** /** ! * Either sends the line to the browser or concats it ! * to the variable $this->html_page. */ ! function print_line($line) { ! if ($this->collect) ! $this->html_page .= $this->indent.$line; ! else ! print $this->indent.$line; } /** * Renders the given template, replacing all variables --- 47,79 ---- /** ! * Replace all {{tpl_vars}} in the given string ! * and then print it out. */ ! function render_string($str) { ! //replace all {{tpl_vars}} ! $str = WebApp::replaceVars($str); ! ! //add indentation at the beginning of each line ! $str = preg_replace('/^/m', $this->indent, $str); ! ! //print the string ! if ($this->collect) $this->html_page .= $str; ! else print $str; } + /** + * Returns the tpl_id from a string like this: '&&tpl_id;;' + * If this pattern does not match, than it returns UNDEFINED. + */ + function get_tpl_id($str) + { + $pattern = '/^&&(.+);;$/'; + if (preg_match($pattern, $str, $matches)) + return $matches[1]; + else + return UNDEFINED; + } + /** * Renders the given template, replacing all variables *************** *** 69,89 **** $tplVars->addVars($tpl->getVars()); ! $i = 0; ! while ($i < sizeof($tpl->content)) { ! $line = $tpl->content[$i++]; ! if (chop($line)<>"##") { ! $this->render_line($line); } ! else //subtemplate indicator found { ! //get the subtemplate ! $line = $tpl->content[$i++]; ! $subtpl_id = trim($line); ! $subtpl = $webPage->getTemplate($subtpl_id); ! ! //render the subtemplate $this->render_subtpl($subtpl); } } --- 87,107 ---- $tplVars->addVars($tpl->getVars()); ! $arr_contents = $tpl->get_arr_contents(); ! for ($i=0; $i < sizeof($arr_contents); $i++) { ! $chunk = $arr_contents[$i]; ! $tpl_id = $this->get_tpl_id($chunk); ! if ($tpl_id==UNDEFINED) { ! $this->render_string($chunk); } ! else { ! //get and render the subtemplate ! $subtpl = $webPage->getTemplate($tpl_id); ! $prev_indent = $this->indent; ! $this->indent .= $subtpl->indent; $this->render_subtpl($subtpl); + $this->indent = $prev_indent; } } *************** *** 92,107 **** } - /** - * Replace all {{tpl_vars}} in the given line - * and then print it out. - */ - function render_line($line) - { - //replace all {{tpl_vars}} - $line = WebApp::replaceVars($line); - //output the line - $this->print_line($line); - } - /** * Dispatcher function: according to the type of --- 110,113 ---- *************** *** 167,181 **** $tpl_path = WebApp::to_url($tpl_path); $tplVars->addVar("./", $tpl_path); - - //increase indentation - $prev_indent = $this->indent; - $this->indent .= $file_tpl->indentation; //render the FileTpl $this->render_tpl($file_tpl); - //revert to previous indentation - $this->indent = $prev_indent; - $tplVars->popScope(); } --- 173,180 ---- *************** *** 186,192 **** function render_MainTpl($main_tpl) { ! array_unshift($main_tpl->head->content, "<head>\n"); ! array_push($main_tpl->head->content, "</head>\n"); ! array_push($main_tpl->body->content, "</body>\n"); $this->render_FileTpl($main_tpl); } --- 185,191 ---- function render_MainTpl($main_tpl) { ! $main_tpl->head->contents = '<head>'.$main_tpl->head->contents; ! $main_tpl->head->contents .= '</head>'; ! $main_tpl->body->contents .= '</body>'; $this->render_FileTpl($main_tpl); } *************** *** 223,235 **** $wobj_tpl->onRender(); - //increase indentation - $prev_indent = $this->indent; - $this->indent .= $wobj_tpl->indentation; - $this->render_tpl($wobj_tpl); //render it to HTML - //revert to previous indentation - $this->indent = $prev_indent; - $tplVars->popScope(); } --- 222,227 ---- *************** *** 256,260 **** { $err_msg = WebApp::error_msg("Recordset '$rs_id' is undefined."); ! $this->print_line($err_msg); $this->render_Template($tpl); return; --- 248,252 ---- { $err_msg = WebApp::error_msg("Recordset '$rs_id' is undefined."); ! $this->render_string($err_msg); $this->render_Template($tpl); return; Index: class.Parser.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.Parser.php,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** class.Parser.php 24 Sep 2003 14:20:08 -0000 1.8 --- class.Parser.php 13 Jul 2004 13:18:08 -0000 1.9 *************** *** 21,933 **** ! /** ! * Parses the templates and constructs $webPage, which ! * keeps the structure of the page. ! * ! * @package parser ! * @see WebPage, Render ! */ ! class Parser [...1812 lines suppressed...] ! /** Output the state of the stack. */ ! function print_stack() ! { ! print "\$this->current_tpl".$this->current_tpl->toHtmlTable(); ! for ($i=sizeof($this->tpl_stack)-1; $i >= 0; $i--) ! { ! if (gettype($this->tpl_stack[$i])=="object") ! { ! print "\$this->tpl_stack[$i]"; ! print $this->tpl_stack[$i]->toHtmlTable(); ! } ! else ! { ! print "\$this->tpl_stack[$i]='".$this->tpl_stack[$i]."'<br>\n"; ! } ! } ! } ! } ?> \ No newline at end of file Index: class.MainTpl.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.MainTpl.php,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** class.MainTpl.php 25 Aug 2003 13:18:32 -0000 1.6 --- class.MainTpl.php 13 Jul 2004 13:18:08 -0000 1.7 *************** *** 53,66 **** . " (".$this->type.")\n"; $i = 0; ! while ($i < sizeof($this->content)) { ! $line = $this->content[$i++]; ! if (trim($line)=="##") ! { ! $line = $this->content[$i++]; ! $tpl_id = trim($line); ! $tpl = $webPage->getTemplate($tpl_id); ! $tree .= $tpl->to_tree($indent." "); ! } } return $tree; --- 53,63 ---- . " (".$this->type.")\n"; $i = 0; ! ! $arr_tpl_id = $this->get_subtemplates(); ! for ($i=0; $i < sizeof($arr_tpl_id); $i++) { ! $tpl_id = $arr_tpl_id[$i]; ! $tpl = $webPage->getTemplate($tpl_id); ! $tree .= $tpl->to_tree($indent." "); } return $tree; Index: class.FileTpl.php =================================================================== RCS file: /cvsroot/phpwebapp/web_app/parser/class.FileTpl.php,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** class.FileTpl.php 25 Aug 2003 13:18:32 -0000 1.5 --- class.FileTpl.php 13 Jul 2004 13:18:08 -0000 1.6 *************** *** 29,33 **** { var $filename; ! var $indentation; function FileTpl($filename) --- 29,33 ---- { var $filename; ! var $indent; function FileTpl($filename) *************** *** 37,52 **** Template::Template($id, "FileTpl"); $this->filename = $filename; ! $this->indentation = ""; ! } ! ! /** Trims the indentation from the beginning of each line. */ ! function unindent() ! { ! for ($i=0; $i < sizeof($this->content); $i++) ! { ! $line = $this->content[$i]; ! $line = ereg_replace("^".$this->indentation, "", $line); ! $this->content[$i] = $line; ! } } --- 37,41 ---- Template::Template($id, "FileTpl"); $this->filename = $filename; ! $this->indent = ""; } |