<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>SithTemplate: CompilerEx.php Source File</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.7.2 -->
<div class="navigation" id="top">
<div class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li class="current"><a href="files.html"><span>Files</span></a></li>
<li><a href="examples.html"><span>Examples</span></a></li>
</ul>
</div>
<div class="tabs2">
<ul class="tablist">
<li><a href="files.html"><span>File List</span></a></li>
<li><a href="globals.html"><span>File Members</span></a></li>
</ul>
</div>
<div class="header">
<div class="headertitle">
<h1>CompilerEx.php</h1> </div>
</div>
<div class="contents">
<a href="_compiler_ex_8php.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <?php
<a name="l00029"></a><a class="code" href="class_template_compiler_ex.html">00029</a> <span class="keyword">class </span><a class="code" href="class_template_compiler_ex.html" title="Primary compiler driver.">TemplateCompilerEx</a> {
<a name="l00033"></a><a class="code" href="class_template_compiler_ex.html#a7436ce4d99eb25b14012d0fea3329545">00033</a> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#a7436ce4d99eb25b14012d0fea3329545" title="Current settings (reference to TemplateEnviron::$settings).">$settings</a> = null;
<a name="l00034"></a>00034
<a name="l00035"></a>00035 <span class="comment">// Plugins part</span>
<a name="l00039"></a><a class="code" href="class_template_compiler_ex.html#ac6a93435059bcde30df1f24bfbfa53e3">00039</a> <span class="comment"></span> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#ac6a93435059bcde30df1f24bfbfa53e3" title="Registry of available plugins.">$plugins</a> = null;
<a name="l00043"></a><a class="code" href="class_template_compiler_ex.html#ae1e96f5d9cdab5a8cef660e9bd0347c1">00043</a> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#ae1e96f5d9cdab5a8cef660e9bd0347c1" title="Registry of loaded plugins (per-template).">$loadedPlugins</a> = array();
<a name="l00044"></a>00044
<a name="l00045"></a>00045 <span class="comment">// Parser part</span>
<a name="l00050"></a><a class="code" href="class_template_compiler_ex.html#a96c1fa9a15fb7c1a36a3a212073f97f4">00050</a> <span class="comment"></span> <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#a96c1fa9a15fb7c1a36a3a212073f97f4" title="Currently processed token.">$parserCurrentToken</a> = null;
<a name="l00054"></a><a class="code" href="class_template_compiler_ex.html#a04c4c26c3f5b84a7f2743fd6253fbce9">00054</a> <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#a04c4c26c3f5b84a7f2743fd6253fbce9" title="Currently processed line (approx).">$parserCurrentLine</a> = 1;
<a name="l00058"></a><a class="code" href="class_template_compiler_ex.html#af3d5cc74f7c0cc06676b50a5efe95112">00058</a> <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#af3d5cc74f7c0cc06676b50a5efe95112" title="Currently processed template.">$parserCurrentFile</a> = null;
<a name="l00062"></a><a class="code" href="class_template_compiler_ex.html#ab61b2762e9cea921fd26a4153067f983">00062</a> <span class="keyword">private</span> <a class="code" href="class_template_compiler_ex.html#ab61b2762e9cea921fd26a4153067f983" title="Regular expression used to split template into tokens.">$parserTokenRegexp</a> = <span class="stringliteral">'~(\{\%.*?\%\})|(\{\{.*?\}\})|(\{\#.*?\#\})~u'</span>;
<a name="l00063"></a>00063
<a name="l00064"></a>00064 <span class="comment">// CodeGen part</span>
<a name="l00068"></a><a class="code" href="class_template_compiler_ex.html#a6c58447a001891500c54f1e9afc30b20">00068</a> <span class="comment"></span> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#a6c58447a001891500c54f1e9afc30b20" title="Already constructed code blocks.">$blocks</a> = array();
<a name="l00072"></a><a class="code" href="class_template_compiler_ex.html#aa33edba89e0e64230b47973bbf33ef4e">00072</a> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#aa33edba89e0e64230b47973bbf33ef4e" title="Template&#39;s metadata.">$metadata</a> = array();
<a name="l00076"></a><a class="code" href="class_template_compiler_ex.html#a47169b58844fe3ddabd63f7d6af5067d">00076</a> <span class="keyword">public</span> <a class="code" href="class_template_compiler_ex.html#a47169b58844fe3ddabd63f7d6af5067d" title="Template&#39;s classname.">$className</a> = null;
<a name="l00077"></a>00077
<a name="l00078"></a>00078 <span class="comment">// public API</span>
<a name="l00082"></a><a class="code" href="class_template_compiler_ex.html#a1e3e1ada9beabf25c6ae30b2978b44c2">00082</a> <span class="comment"></span> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a1e3e1ada9beabf25c6ae30b2978b44c2" title="Constructor.">__construct</a>() {
<a name="l00083"></a>00083 <span class="comment">// create plugins registry, and register built-ins</span>
<a name="l00084"></a>00084 $this->plugins = <span class="keyword">new</span> <a class="code" href="class_template_plugins.html" title="Handles discovery, registration and utilization of plugins.">TemplatePlugins</a>(array(
<a name="l00085"></a>00085 <span class="stringliteral">'tags'</span> => array(
<a name="l00086"></a>00086 <span class="stringliteral">'load'</span> => array(
<a name="l00087"></a>00087 <span class="stringliteral">'plugin'</span> => null, <span class="stringliteral">'type'</span> => <span class="stringliteral">'inline'</span>, <span class="stringliteral">'handler'</span> => array($this, <span class="stringliteral">'handleLoadBuiltin'</span>), <span class="stringliteral">'minArgs'</span> => 1
<a name="l00088"></a>00088 ),
<a name="l00089"></a>00089 <span class="stringliteral">'comment'</span> => array(
<a name="l00090"></a>00090 <span class="stringliteral">'plugin'</span> => null, <span class="stringliteral">'type'</span> => <span class="stringliteral">'ignore'</span>, <span class="stringliteral">'handler'</span> => array($this, <span class="stringliteral">'handleCommentBuiltin'</span>), <span class="stringliteral">'minArgs'</span> => 0
<a name="l00091"></a>00091 ),
<a name="l00092"></a>00092 ),
<a name="l00093"></a>00093 <span class="stringliteral">'filters'</span> => array(),
<a name="l00094"></a>00094 <span class="stringliteral">'hooks'</span> => array(),
<a name="l00095"></a>00095 ));
<a name="l00096"></a>00096 }
<a name="l00097"></a>00097
<a name="l00102"></a><a class="code" href="class_template_compiler_ex.html#a8d7a65c59cb37d96d9ebc5c655a8a1e7">00102</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a8d7a65c59cb37d96d9ebc5c655a8a1e7" title="Resets compiler to pristine state, and loads plugins specified in &#39;loadPlugins&#39; setting...">reset</a>() {
<a name="l00103"></a>00103 $this->plugins->searchPaths = &$this->settings[<span class="stringliteral">'pluginsPaths'</span>];
<a name="l00104"></a>00104 $this->blocks = $this->metadata = $this->loadedPlugins = array();
<a name="l00105"></a>00105 $this->className = $this->parserCurrentToken = $this->parserCurrentFile = null;
<a name="l00106"></a>00106 $this->parserCurrentLine = 1;
<a name="l00107"></a>00107
<a name="l00108"></a>00108 $this->plugins->loadMultiple($this, null, $this->settings[<span class="stringliteral">'loadPlugins'</span>]);
<a name="l00109"></a>00109 }
<a name="l00110"></a>00110
<a name="l00117"></a><a class="code" href="class_template_compiler_ex.html#a13570ae4a6d834431eeb3c84a5051ac3">00117</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a13570ae4a6d834431eeb3c84a5051ac3" title="Compiles given template into output package.">compile</a>(<a class="code" href="interface_i_template_i_o_driver.html" title="Interface required for all I/O drivers.">ITemplateIODriver</a> $io, $template) {
<a name="l00118"></a>00118 $this-><a class="code" href="class_template_compiler_ex.html#a8d7a65c59cb37d96d9ebc5c655a8a1e7" title="Resets compiler to pristine state, and loads plugins specified in &#39;loadPlugins&#39; setting...">reset</a>();
<a name="l00119"></a>00119
<a name="l00120"></a>00120 <span class="keywordflow">if</span> (($tpl = $io-><a class="code" href="interface_i_template_i_o_driver.html#a58d4f66a849626b7341eafeb3f456c03" title="Should read template source code as whole, and return it.">loadTemplate</a>($this->settings, $template)) === <span class="keyword">false</span>) {
<a name="l00121"></a>00121 <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(<span class="stringliteral">'Could not load template "'</span>.$in.<span class="charliteral">'"'</span>, <a class="code" href="class_template_error.html#a1c6f0bf460ba23e1593231b9dca910a1" title="An I/O read error.">TemplateError::E_IO_LOAD_FAILURE</a>);
<a name="l00122"></a>00122 }
<a name="l00123"></a>00123
<a name="l00124"></a>00124 $this->className = $io-><a class="code" href="interface_i_template_i_o_driver.html#a4422ce31a10074ea6af13594efd757b1" title="Should return template&#39;s classname.">className</a>($this->settings, $template);
<a name="l00125"></a>00125 $this->parserCurrentFile = $template;
<a name="l00126"></a>00126 $this->metadata[<span class="stringliteral">'usedIO'</span>] = $io->driverID;
<a name="l00127"></a>00127
<a name="l00128"></a>00128 $genAST = $this-><a class="code" href="class_template_compiler_ex.html#a8c314644ad54b574e55cce1e56bf5d33" title="Creates and returns an Abstract Syntax Tree of given template.">createAST</a>($tpl);
<a name="l00129"></a>00129 $genCode = $this-><a class="code" href="class_template_compiler_ex.html#a3f16537377363532ad1d4fd33b6a4fca" title="Constructs blocks and generates code for the entire AST.">generateCode</a>($genAST);
<a name="l00130"></a>00130
<a name="l00131"></a>00131 <span class="comment">// determine template's parent class</span>
<a name="l00132"></a>00132 $classCode = <span class="stringliteral">'<?php class '</span>.$this->className.<span class="stringliteral">' extends '</span>;
<a name="l00133"></a>00133 <span class="keywordflow">if</span> (isset($this->metadata[<span class="stringliteral">'parentTemplate'</span>])) {
<a name="l00134"></a>00134 list($parentIO,$parent) = <a class="code" href="class_template_utils.html#a3c4884dc20fe80e13a23f36f09663220" title="Splits I/O DSN, and creates correct driver object.">TemplateUtils::parseIODSN</a>($this->settings, $this->metadata[<span class="stringliteral">'parentTemplate'</span>]);
<a name="l00135"></a>00135 $classCode .= $parentIO->className($this->settings, $parent);
<a name="l00136"></a>00136 <span class="comment">// main content is ignored, when template extends another</span>
<a name="l00137"></a>00137 unset($genCode[<span class="stringliteral">'main'</span>]);
<a name="l00138"></a>00138 } <span class="keywordflow">else</span> {
<a name="l00139"></a>00139 $classCode .= <span class="stringliteral">'Template'</span>;
<a name="l00140"></a>00140 }
<a name="l00141"></a>00141
<a name="l00142"></a>00142 $classCode .= <span class="charliteral">'{'</span>;
<a name="l00143"></a>00143 <span class="keywordflow">foreach</span> ($genCode as $blockName => &$blockCode) {
<a name="l00144"></a>00144 $classCode .= <span class="stringliteral">'function _'</span>.TemplateUtils::sanitize($blockName).<span class="stringliteral">'($e){'</span>;
<a name="l00145"></a>00145 <span class="comment">// TODO: is constructor support really needed?</span>
<a name="l00146"></a>00146 <span class="keywordflow">if</span> ($blockName == <span class="stringliteral">'_constructor'</span>) $classCode .= <span class="stringliteral">'parent::__constructor();'</span>;
<a name="l00147"></a>00147 $classCode .= $blockCode.<span class="charliteral">'}'</span>;
<a name="l00148"></a>00148 }
<a name="l00149"></a>00149 $classCode .= <span class="charliteral">'}'</span>;
<a name="l00150"></a>00150
<a name="l00151"></a>00151 <span class="keywordflow">if</span> ($io-><a class="code" href="interface_i_template_i_o_driver.html#a09fcd13602951d6617d9af68118ef851" title="Should save template metadata.">saveMetadata</a>($this->settings, $template, $this->metadata) === <span class="keyword">false</span>) {
<a name="l00152"></a>00152 <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00153"></a>00153 <span class="stringliteral">'Could not save template metadata (compiled from "'</span>.$template.<span class="stringliteral">'")'</span>,
<a name="l00154"></a>00154 <a class="code" href="class_template_error.html#a9bb22dc143f3bc58bd4db9f87fae4178" title="An I/O save error.">TemplateError::E_IO_SAVE_FAILURE</a>
<a name="l00155"></a>00155 );
<a name="l00156"></a>00156 }
<a name="l00157"></a>00157
<a name="l00158"></a>00158 <span class="keywordflow">if</span> ($io-><a class="code" href="interface_i_template_i_o_driver.html#ace0d5330b5b82578b4d3a5021eb1cdd7" title="Should save compiled template code.">saveTemplate</a>($this->settings, $template, $classCode) === <span class="keyword">false</span>) {
<a name="l00159"></a>00159 <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00160"></a>00160 <span class="stringliteral">'Could not save template code (compiled from "'</span>.$template.<span class="stringliteral">'").'</span>,
<a name="l00161"></a>00161 <a class="code" href="class_template_error.html#a9bb22dc143f3bc58bd4db9f87fae4178" title="An I/O save error.">TemplateError::E_IO_SAVE_FAILURE</a>
<a name="l00162"></a>00162 );
<a name="l00163"></a>00163 }
<a name="l00164"></a>00164 }
<a name="l00165"></a>00165
<a name="l00166"></a>00166 <span class="comment">// Parser part</span>
<a name="l00174"></a><a class="code" href="class_template_compiler_ex.html#a8c314644ad54b574e55cce1e56bf5d33">00174</a> <span class="comment"></span> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a8c314644ad54b574e55cce1e56bf5d33" title="Creates and returns an Abstract Syntax Tree of given template.">createAST</a>(&$tpl) {
<a name="l00175"></a>00175 $root = <span class="keyword">new</span> <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a>(<span class="stringliteral">'root'</span>, null, null, $this->parserCurrentFile, -1);
<a name="l00176"></a>00176
<a name="l00177"></a>00177 $tokens = preg_split($this->parserTokenRegexp, $tpl, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
<a name="l00178"></a>00178 $this-><a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10" title="Parses token stream until it runs out of tokens, or when it encounters given tag name.">parseTokenStream</a>($root, $tokens);
<a name="l00179"></a>00179
<a name="l00180"></a>00180 <span class="keywordflow">return</span> $root;
<a name="l00181"></a>00181 }
<a name="l00182"></a>00182
<a name="l00191"></a><a class="code" href="class_template_compiler_ex.html#a2138fe87678a9a13b2d6f7da426a7459">00191</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a2138fe87678a9a13b2d6f7da426a7459" title="Fetches next token from given stream, preprocesses it, and stores it in TemplateCompilerEx::$parserCu...">parserGetNextToken</a>(array &$tokens) {
<a name="l00192"></a>00192 $this->parserCurrentToken = array_shift($tokens);
<a name="l00193"></a>00193
<a name="l00194"></a>00194 <span class="keywordflow">if</span> ($this->parserCurrentToken === null) {
<a name="l00195"></a>00195 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00196"></a>00196 } elseif (mb_substr($this->parserCurrentToken, 0, 2) == <span class="stringliteral">'{%'</span>) {
<a name="l00197"></a>00197 $this->parserCurrentToken = array(
<a name="l00198"></a>00198 <span class="stringliteral">'type'</span> => <span class="stringliteral">'tag'</span>,
<a name="l00199"></a>00199 <span class="stringliteral">'content'</span> => <a class="code" href="class_template_utils.html#a28bd46df8e8547dd387e2047733d8f87" title="Properly splits given expression using given delimiter.">TemplateUtils::splitEscaped</a>(
<a name="l00200"></a>00200 <span class="charliteral">' '</span>, trim(mb_substr($this->parserCurrentToken, 2, -2))
<a name="l00201"></a>00201 )
<a name="l00202"></a>00202 );
<a name="l00203"></a>00203 } elseif (mb_substr($this->parserCurrentToken, 0, 2) == <span class="stringliteral">'{{'</span>) {
<a name="l00204"></a>00204 $this->parserCurrentToken = array(
<a name="l00205"></a>00205 <span class="stringliteral">'type'</span> => <span class="stringliteral">'var'</span>,
<a name="l00206"></a>00206 <span class="stringliteral">'content'</span> => <a class="code" href="class_template_utils.html#ad8600ee16ab4bcfc0575696c8e2520d2" title="Split string into two.">TemplateUtils::split</a>(
<a name="l00207"></a>00207 <span class="charliteral">'|'</span>, trim(mb_substr($this->parserCurrentToken, 2, -2))
<a name="l00208"></a>00208 ),
<a name="l00209"></a>00209 );
<a name="l00210"></a>00210 } elseif (mb_substr($this->parserCurrentToken, 0, 2) == <span class="stringliteral">'{#'</span>) {
<a name="l00211"></a>00211 $this->parserCurrentToken = array(
<a name="l00212"></a>00212 <span class="stringliteral">'type'</span> => <span class="stringliteral">'comment'</span>,
<a name="l00213"></a>00213 <span class="stringliteral">'content'</span> => null,
<a name="l00214"></a>00214 );
<a name="l00215"></a>00215 } <span class="keywordflow">else</span> {
<a name="l00216"></a>00216 $this->parserCurrentToken = array(
<a name="l00217"></a>00217 <span class="stringliteral">'type'</span> => <span class="stringliteral">'text'</span>,
<a name="l00218"></a>00218 <span class="stringliteral">'content'</span> => $this->parserCurrentToken,
<a name="l00219"></a>00219 );
<a name="l00220"></a>00220 }
<a name="l00221"></a>00221
<a name="l00222"></a>00222 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00223"></a>00223 }
<a name="l00224"></a>00224
<a name="l00235"></a><a class="code" href="class_template_compiler_ex.html#adb1366c4bf94900c7b8e765caf1d43a6">00235</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#adb1366c4bf94900c7b8e765caf1d43a6" title="Checks whether the parser has encountered ending tag with given name.">parserEncounteredEndTag</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $tag, $type) {
<a name="l00236"></a>00236 <span class="keywordflow">if</span> ($tag === null || $this->parserCurrentToken[<span class="stringliteral">'type'</span>] != <span class="stringliteral">'tag'</span>) <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00237"></a>00237
<a name="l00238"></a>00238 $gotTag = &$this->parserCurrentToken[<span class="stringliteral">'content'</span>][0];
<a name="l00239"></a>00239 $tag = <span class="stringliteral">'end'</span>.$tag;
<a name="l00240"></a>00240
<a name="l00241"></a>00241 <span class="keywordflow">if</span> (mb_substr($gotTag, 0, 3) != <span class="stringliteral">'end'</span>) {
<a name="l00242"></a>00242 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00243"></a>00243 } elseif ($gotTag != $tag && $type == <span class="stringliteral">'block'</span>) {
<a name="l00244"></a>00244 $this-><span class="keyword">raise</span>(
<a name="l00245"></a>00245 $node,
<a name="l00246"></a>00246 <span class="stringliteral">'Invalid ending tag encountered - expected "'</span>.$tag.<span class="stringliteral">'", got "'</span>.$gotTag.<span class="charliteral">'"'</span>,
<a name="l00247"></a>00247 <a class="code" href="class_template_error.html#ac502ffee5019e6d870c25083af550454" title="An invalid syntax error.">TemplateError::E_INVALID_SYNTAX</a>
<a name="l00248"></a>00248 );
<a name="l00249"></a>00249 } elseif ($gotTag == $tag) {
<a name="l00250"></a>00250 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00251"></a>00251 }
<a name="l00252"></a>00252 <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00253"></a>00253 }
<a name="l00254"></a>00254
<a name="l00261"></a><a class="code" href="class_template_compiler_ex.html#ac14ed87a62f7b5a59b0e9fe5ce72b4b6">00261</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#ac14ed87a62f7b5a59b0e9fe5ce72b4b6" title="Converts current token&#39;s array into the node, and adds it to given node&#39;s children...">createNodeFromToken</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node) {
<a name="l00262"></a>00262 $token = &$this->parserCurrentToken;
<a name="l00263"></a>00263 $node-><a class="code" href="class_template_node_ex.html#ac4a2737627e12bace528ee449b45943f" title="Creates a new TemplateNodeEx instance and adds it to this node children.">addChild</a>($token[<span class="stringliteral">'type'</span>], $token[<span class="stringliteral">'content'</span>], $this->parserCurrentFile, $this->parserCurrentLine);
<a name="l00264"></a>00264 }
<a name="l00265"></a>00265
<a name="l00274"></a><a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10">00274</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10" title="Parses token stream until it runs out of tokens, or when it encounters given tag name.">parseTokenStream</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, array &$tokens, $parseUntil = null, $blockTagType = null) {
<a name="l00275"></a>00275 <span class="keywordflow">while</span> ($this-><a class="code" href="class_template_compiler_ex.html#a2138fe87678a9a13b2d6f7da426a7459" title="Fetches next token from given stream, preprocesses it, and stores it in TemplateCompilerEx::$parserCu...">parserGetNextToken</a>($tokens) && !$this-><a class="code" href="class_template_compiler_ex.html#adb1366c4bf94900c7b8e765caf1d43a6" title="Checks whether the parser has encountered ending tag with given name.">parserEncounteredEndTag</a>($node, $parseUntil, $blockTagType)) {
<a name="l00276"></a>00276 <span class="keywordflow">switch</span> ($this->parserCurrentToken[<span class="stringliteral">'type'</span>]) {
<a name="l00277"></a>00277 <span class="keywordflow">case</span> <span class="stringliteral">'tag'</span>:
<a name="l00278"></a>00278 $tag = array_shift($this->parserCurrentToken[<span class="stringliteral">'content'</span>]);
<a name="l00279"></a>00279 $args = &$this->parserCurrentToken[<span class="stringliteral">'content'</span>];
<a name="l00280"></a>00280
<a name="l00281"></a>00281 <span class="keywordflow">if</span> (!$this->plugins->known(<span class="stringliteral">'tag'</span>, $tag)) {
<a name="l00282"></a>00282 <span class="comment">// if doesn't exist, assume inline</span>
<a name="l00283"></a>00283 $tagInfo = array(<span class="stringliteral">'type'</span> => <span class="stringliteral">'inline'</span>);
<a name="l00284"></a>00284 } <span class="keywordflow">else</span> {
<a name="l00285"></a>00285 $tagInfo = $this->plugins->get(<span class="stringliteral">'tag'</span>, $tag);
<a name="l00286"></a>00286 }
<a name="l00287"></a>00287
<a name="l00288"></a>00288 $newNode = <span class="keyword">new</span> <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a>(<span class="stringliteral">'inlineTag'</span>, $node, array($tag, $args), $this->parserCurrentFile, $this->parserCurrentLine);
<a name="l00289"></a>00289 <span class="keywordflow">if</span> (in_array($tagInfo[<span class="stringliteral">'type'</span>], array(<span class="stringliteral">'block'</span>, <span class="stringliteral">'ignore'</span>))) {
<a name="l00290"></a>00290 $newNode->nodeID = <span class="stringliteral">'blockTag'</span>;
<a name="l00291"></a>00291 <span class="comment">// capture block content</span>
<a name="l00292"></a>00292 $this-><a class="code" href="class_template_compiler_ex.html#a9cc09b0d1f776e7f4361e9e41dd3bb10" title="Parses token stream until it runs out of tokens, or when it encounters given tag name.">parseTokenStream</a>($newNode, $tokens, $tag, ($blockTagType == <span class="stringliteral">'ignore'</span> ? <span class="stringliteral">'ignore'</span> : $tagInfo[<span class="stringliteral">'type'</span>]));
<a name="l00293"></a>00293 }
<a name="l00294"></a>00294
<a name="l00295"></a>00295 $node->nodeChildren[] = $newNode;
<a name="l00296"></a>00296 <span class="keywordflow">break</span>;
<a name="l00297"></a>00297 <span class="keywordflow">case</span> <span class="stringliteral">'var'</span>:
<a name="l00298"></a>00298 <span class="keywordflow">case</span> <span class="stringliteral">'text'</span>:
<a name="l00299"></a>00299 $this-><a class="code" href="class_template_compiler_ex.html#ac14ed87a62f7b5a59b0e9fe5ce72b4b6" title="Converts current token&#39;s array into the node, and adds it to given node&#39;s children...">createNodeFromToken</a>($node);
<a name="l00300"></a>00300 <span class="keywordflow">if</span> ($this->parserCurrentToken[<span class="stringliteral">'type'</span>] == <span class="stringliteral">'text'</span>) {
<a name="l00301"></a>00301 <span class="comment">// update current line counter</span>
<a name="l00302"></a>00302 $this->parserCurrentLine += mb_substr_count($this->parserCurrentToken[<span class="stringliteral">'content'</span>], <span class="stringliteral">"\n"</span>);
<a name="l00303"></a>00303 }
<a name="l00304"></a>00304 <span class="keywordflow">break</span>;
<a name="l00305"></a>00305 }
<a name="l00306"></a>00306 }
<a name="l00307"></a>00307 }
<a name="l00308"></a>00308
<a name="l00309"></a>00309 <span class="comment">// CodeGen part</span>
<a name="l00317"></a><a class="code" href="class_template_compiler_ex.html#a3f16537377363532ad1d4fd33b6a4fca">00317</a> <span class="comment"></span> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a3f16537377363532ad1d4fd33b6a4fca" title="Constructs blocks and generates code for the entire AST.">generateCode</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $root) {
<a name="l00318"></a>00318 $this-><a class="code" href="class_template_compiler_ex.html#a616eb81be4f686387ecd3f778eca26a5" title="Creates code block from raw node.">createBlock</a>(<span class="stringliteral">'main'</span>, $root);
<a name="l00319"></a>00319 <span class="keywordflow">return</span> $this->blocks;
<a name="l00320"></a>00320 }
<a name="l00321"></a>00321
<a name="l00330"></a><a class="code" href="class_template_compiler_ex.html#a91899408f7ddf3173a8932bb8277aad7">00330</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a91899408f7ddf3173a8932bb8277aad7" title="Generates code from given node&#39;s children.">handleChildren</a>(array &$children) {
<a name="l00331"></a>00331 $code = <span class="stringliteral">''</span>;
<a name="l00332"></a>00332 <span class="keywordflow">foreach</span> ($children as $child) {
<a name="l00333"></a>00333 $code .= $this-><a class="code" href="class_template_compiler_ex.html#a773e98ffac99fdbe9f8934768f840d3c" title="Creates code from given node.">handleNode</a>($child);
<a name="l00334"></a>00334 }
<a name="l00335"></a>00335 <span class="keywordflow">return</span> $code;
<a name="l00336"></a>00336 }
<a name="l00337"></a>00337
<a name="l00345"></a><a class="code" href="class_template_compiler_ex.html#a616eb81be4f686387ecd3f778eca26a5">00345</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a616eb81be4f686387ecd3f778eca26a5" title="Creates code block from raw node.">createBlock</a>($block, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node) {
<a name="l00346"></a>00346 $this->blocks[$block] = <span class="stringliteral">'$b=\'\';'</span>.$this->handleChildren($node->nodeChildren).<span class="stringliteral">'return $b;'</span>;
<a name="l00347"></a>00347 }
<a name="l00348"></a>00348
<a name="l00356"></a><a class="code" href="class_template_compiler_ex.html#a773e98ffac99fdbe9f8934768f840d3c">00356</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a773e98ffac99fdbe9f8934768f840d3c" title="Creates code from given node.">handleNode</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node) {
<a name="l00357"></a>00357 <span class="keywordflow">switch</span> ($node->nodeID) {
<a name="l00358"></a>00358 <span class="keywordflow">case</span> <span class="stringliteral">'text'</span> : <span class="keywordflow">return</span> <span class="stringliteral">'$b.=\''</span>.TemplateUtils::escape($node->nodeContent).<span class="charliteral">'\'</span>;<span class="stringliteral">';</span>
<a name="l00359"></a>00359 <span class="stringliteral"> case '</span>var<span class="stringliteral">' : return $this->handleVariable($node);</span>
<a name="l00360"></a>00360 <span class="stringliteral"> case '</span>blockTag<span class="stringliteral">' :</span>
<a name="l00361"></a>00361 <span class="stringliteral"> case '</span>inlineTag<span class="stringliteral">': return $this->handleTag($node);</span>
<a name="l00362"></a>00362 <span class="stringliteral"> }</span>
<a name="l00363"></a>00363 <span class="stringliteral"> }</span>
<a name="l00364"></a>00364 <span class="stringliteral"> </span>
<a name="l00372"></a><a class="code" href="class_template_compiler_ex.html#af0951cb966c81753464771dfaeffa625">00372</a> <span class="stringliteral"> private function handleTag(TemplateNodeEx $node) {</span>
<a name="l00373"></a>00373 <span class="stringliteral"> $tag = &$node->nodeContent[0];</span>
<a name="l00374"></a>00374 <span class="stringliteral"> $args = &$node->nodeContent[1];</span>
<a name="l00375"></a>00375 <span class="stringliteral"> </span>
<a name="l00376"></a>00376 <span class="stringliteral"> $tagInfo = $this->commonVerifyElement($node, '</span>tag<span class="stringliteral">', $tag, $args);</span>
<a name="l00377"></a>00377 <span class="stringliteral"> </span>
<a name="l00378"></a>00378 <span class="stringliteral"> if (isset($tagInfo['</span>parent<span class="stringliteral">'])) {</span>
<a name="l00379"></a>00379 <span class="stringliteral"> $pattern = '</span>~^<span class="stringliteral">'.str_replace('</span>\\*<span class="stringliteral">', '</span>.*?<span class="stringliteral">', preg_quote($tagInfo['</span>parent<span class="stringliteral">'], '</span>~<span class="stringliteral">')).'</span>$~su<span class="stringliteral">';</span>
<a name="l00380"></a>00380 <span class="stringliteral"> </span>
<a name="l00381"></a>00381 <span class="stringliteral"> $this->raiseIf(</span>
<a name="l00382"></a>00382 <span class="stringliteral"> (!($node->nodeParent instanceof TemplateNodeEx) || !preg_match($pattern, $node->nodeParent->nodeContent[0])),</span>
<a name="l00383"></a>00383 <span class="stringliteral"> $node,</span>
<a name="l00384"></a>00384 <span class="stringliteral"> '</span>Invalid tag nesting - tag <span class="stringliteral">"'.$tag.'"</span> requires <span class="stringliteral">"'.$tagInfo['parent'].'"</span> tag as immediate parent, <span class="stringliteral">'.</span>
<a name="l00385"></a>00385 <span class="stringliteral"> '</span><span class="stringliteral">"'.$node->nodeParent->nodeContent[0].'"</span> found<span class="stringliteral">',</span>
<a name="l00386"></a>00386 <span class="stringliteral"> TemplateError::E_INVALID_SYNTAX</span>
<a name="l00387"></a>00387 <span class="stringliteral"> );</span>
<a name="l00388"></a>00388 <span class="stringliteral"> </span>
<a name="l00389"></a>00389 <span class="stringliteral"> unset($pattern);</span>
<a name="l00390"></a>00390 <span class="stringliteral"> }</span>
<a name="l00391"></a>00391 <span class="stringliteral"> </span>
<a name="l00392"></a>00392 <span class="stringliteral"> return call_user_func_array($tagInfo['</span>handler<span class="stringliteral">'], array($this, $node, &$tag, &$args));</span>
<a name="l00393"></a>00393 <span class="stringliteral"> }</span>
<a name="l00394"></a>00394 <span class="stringliteral"> </span>
<a name="l00401"></a><a class="code" href="class_template_compiler_ex.html#ad4a05c2ff0b4e3ae9ee530780dc129b1">00401</a> <span class="stringliteral"> private function handleVariable(TemplateNodeEx $node) {</span>
<a name="l00402"></a>00402 <span class="stringliteral"> list($variable, $filters) = $node->nodeContent;</span>
<a name="l00403"></a>00403 <span class="stringliteral"> $noCheck = false;</span>
<a name="l00404"></a>00404 <span class="stringliteral"> </span>
<a name="l00405"></a>00405 <span class="stringliteral"> if (mb_substr($variable, 0, 1) == '</span>@<span class="stringliteral">') {</span>
<a name="l00406"></a>00406 <span class="stringliteral"> $noCheck = true;</span>
<a name="l00407"></a>00407 <span class="stringliteral"> $variable = mb_substr($variable, 1);</span>
<a name="l00408"></a>00408 <span class="stringliteral"> }</span>
<a name="l00409"></a>00409 <span class="stringliteral"> </span>
<a name="l00410"></a>00410 <span class="stringliteral"> list($variableCode, $variableCheck) = $this->parseVariableExpression($node, $variable);</span>
<a name="l00411"></a>00411 <span class="stringliteral"> $variableCode = $this->parseFilterChain($node, $filters, '</span>@<span class="stringliteral">'.$variableCode);</span>
<a name="l00412"></a>00412 <span class="stringliteral"> </span>
<a name="l00413"></a>00413 <span class="stringliteral"> return ($noCheck ? '</span><span class="stringliteral">' : $variableCheck).'</span>$b.=<span class="stringliteral">'.$variableCode.'</span>;<span class="stringliteral">';</span>
<a name="l00414"></a>00414 <span class="stringliteral"> }</span>
<a name="l00415"></a>00415 <span class="stringliteral"> </span>
<a name="l00423"></a><a class="code" href="class_template_compiler_ex.html#a8efc4fef1f377e69631fe3de4c2033e3">00423</a> <span class="stringliteral"> public function parseVariableExpression(TemplateNodeEx $node, $variable) {</span>
<a name="l00424"></a>00424 <span class="stringliteral"> $ast = $this->generateVariableAST($variable);</span>
<a name="l00425"></a>00425 <span class="stringliteral"> $code = $this->generateVariableCode($node, $ast);</span>
<a name="l00426"></a>00426 <span class="stringliteral"> $check = '</span><span class="keywordflow">if</span>(!isset(<span class="stringliteral">'.$code.'</span>)&&!is_null(@<span class="stringliteral">'.$code.'</span>)){$this->warnVar(\<span class="stringliteral">''</span>.<a class="code" href="class_template_utils.html#aa3553ef2c1e54e0e99ad38a7fe931efa" title="Escape string to use in template class.">TemplateUtils::escape</a>($variable).<span class="charliteral">'\'</span>);}<span class="stringliteral">';</span>
<a name="l00427"></a>00427 <span class="stringliteral"> </span>
<a name="l00428"></a>00428 <span class="stringliteral"> // Hook-point: parseVariableExpression:postCodeGen</span>
<a name="l00429"></a>00429 <span class="stringliteral"> $this->runHooks('</span><a class="code" href="class_template_compiler_ex.html#a8efc4fef1f377e69631fe3de4c2033e3" title="Parses variable expression, and creates runtime PHP access code.">parseVariableExpression</a>:postCodeGen<span class="stringliteral">', array($node, &$code, &$check));</span>
<a name="l00430"></a>00430 <span class="stringliteral"> //</span>
<a name="l00431"></a>00431 <span class="stringliteral"> </span>
<a name="l00432"></a>00432 <span class="stringliteral"> return array($code, $check);</span>
<a name="l00433"></a>00433 <span class="stringliteral"> }</span>
<a name="l00434"></a>00434 <span class="stringliteral"> </span>
<a name="l00442"></a><a class="code" href="class_template_compiler_ex.html#a9e9d99501cd4def7eb25dc93cbef94b5">00442</a> <span class="stringliteral"> private function generateVariableAST($variable) {</span>
<a name="l00443"></a>00443 <span class="stringliteral"> $chunks = preg_split(</span>
<a name="l00444"></a>00444 <span class="stringliteral"> '</span>/(\[.*?\]|\.|\-\>)/s<span class="stringliteral">', $variable, -1,</span>
<a name="l00445"></a>00445 <span class="stringliteral"> PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY</span>
<a name="l00446"></a>00446 <span class="stringliteral"> );</span>
<a name="l00447"></a>00447 <span class="stringliteral"> </span>
<a name="l00448"></a>00448 <span class="stringliteral"> foreach ($chunks as &$chunk) {</span>
<a name="l00449"></a>00449 <span class="stringliteral"> if (mb_substr($chunk, 0, 1) == '</span>[<span class="stringliteral">') {</span>
<a name="l00450"></a>00450 <span class="stringliteral"> $chunk = $this->generateVariableAST(mb_substr($chunk, 1, -1));</span>
<a name="l00451"></a>00451 <span class="stringliteral"> }</span>
<a name="l00452"></a>00452 <span class="stringliteral"> }</span>
<a name="l00453"></a>00453 <span class="stringliteral"> </span>
<a name="l00454"></a>00454 <span class="stringliteral"> return array_filter($chunks, array('</span><a class="code" href="class_template_utils.html" title="Namespace-acting all-static class.">TemplateUtils</a><span class="stringliteral">', '</span>filterEmpty<span class="stringliteral">'));</span>
<a name="l00455"></a>00455 <span class="stringliteral"> }</span>
<a name="l00456"></a>00456 <span class="stringliteral"> </span>
<a name="l00464"></a><a class="code" href="class_template_compiler_ex.html#af68b6944da2fc99dfda0c7a89f11656d">00464</a> <span class="stringliteral"> private function generateVariableCode(TemplateNodeEx $node, &$ast) {</span>
<a name="l00465"></a>00465 <span class="stringliteral"> $code = '</span>$this->ctx<span class="stringliteral">';</span>
<a name="l00466"></a>00466 <span class="stringliteral"> $nextChunk = '</span>array<span class="stringliteral">'; // array, object or operator</span>
<a name="l00467"></a>00467 <span class="stringliteral"> $operators = array('</span>.<span class="stringliteral">' => '</span>array<span class="stringliteral">', '</span>-><span class="stringliteral">' => '</span><span class="keywordtype">object</span><span class="stringliteral">');</span>
<a name="l00468"></a>00468 <span class="stringliteral"> </span>
<a name="l00469"></a>00469 <span class="stringliteral"> while (($currentChunk = array_shift($ast)) !== null) {</span>
<a name="l00470"></a>00470 <span class="stringliteral"> if ($nextChunk == '</span><span class="keyword">operator</span><span class="stringliteral">') {</span>
<a name="l00471"></a>00471 <span class="stringliteral"> $this->raiseIf(</span>
<a name="l00472"></a>00472 <span class="stringliteral"> (!isset($operators[$currentChunk])),</span>
<a name="l00473"></a>00473 <span class="stringliteral"> $node,</span>
<a name="l00474"></a>00474 <span class="stringliteral"> '</span>Variable access <span class="keyword">operator</span> expected (<span class="stringliteral">"."</span> or <span class="stringliteral">"->"</span>), but <span class="stringliteral">"'.$currentChunk.'"</span> found<span class="stringliteral">',</span>
<a name="l00475"></a>00475 <span class="stringliteral"> TemplateError::E_INVALID_SYNTAX</span>
<a name="l00476"></a>00476 <span class="stringliteral"> );</span>
<a name="l00477"></a>00477 <span class="stringliteral"> </span>
<a name="l00478"></a>00478 <span class="stringliteral"> $nextChunk = $operators[$currentChunk];</span>
<a name="l00479"></a>00479 <span class="stringliteral"> } else {</span>
<a name="l00480"></a>00480 <span class="stringliteral"> switch ($nextChunk) {</span>
<a name="l00481"></a>00481 <span class="stringliteral"> case '</span>array<span class="stringliteral">':</span>
<a name="l00482"></a>00482 <span class="stringliteral"> $chunkTemplate = '</span>[%s]<span class="stringliteral">';</span>
<a name="l00483"></a>00483 <span class="stringliteral"> $chunkVariableTemplate = '</span>@%s<span class="stringliteral">';</span>
<a name="l00484"></a>00484 <span class="stringliteral"> $chunkNumberTemplate = '</span>%d<span class="stringliteral">';</span>
<a name="l00485"></a>00485 <span class="stringliteral"> $chunkStringTemplate = '</span>\<span class="stringliteral">'%s\''</span>;
<a name="l00486"></a>00486 <span class="keywordflow">break</span>;
<a name="l00487"></a>00487 <span class="keywordflow">case</span> <span class="stringliteral">'object'</span>:
<a name="l00488"></a>00488 $chunkTemplate = <span class="stringliteral">'->%s'</span>;
<a name="l00489"></a>00489 $chunkVariableTemplate = <span class="stringliteral">'{@%s}'</span>;
<a name="l00490"></a>00490 $chunkNumberTemplate = <span class="stringliteral">'{%d}'</span>;
<a name="l00491"></a>00491 $chunkStringTemplate = null;
<a name="l00492"></a>00492 <span class="keywordflow">break</span>;
<a name="l00493"></a>00493 <span class="keywordflow">default</span>:
<a name="l00494"></a>00494 <a class="code" href="class_template_utils.html#a9756a1cc5232e00302a0b52c3a1e8e10" title="Panics.">TemplateUtils::panic</a>(__FILE__, __LINE__);
<a name="l00495"></a>00495 <span class="keywordflow">break</span>;
<a name="l00496"></a>00496 }
<a name="l00497"></a>00497
<a name="l00498"></a>00498 <span class="keywordflow">if</span> (is_array($currentChunk)) {
<a name="l00499"></a>00499 <span class="comment">// variable index</span>
<a name="l00500"></a>00500 $chunkCode = sprintf($chunkVariableTemplate, $this-><a class="code" href="class_template_compiler_ex.html#af68b6944da2fc99dfda0c7a89f11656d" title="Recursively parses variable AST, and generates PHP access code.">generateVariableCode</a>($node, $currentChunk));
<a name="l00501"></a>00501 } elseif (ctype_digit($currentChunk)) {
<a name="l00502"></a>00502 <span class="comment">// integer index</span>
<a name="l00503"></a>00503 $chunkCode = sprintf($chunkNumberTemplate, $currentChunk);
<a name="l00504"></a>00504 } <span class="keywordflow">else</span> {
<a name="l00505"></a>00505 <span class="keywordflow">if</span> ($chunkStringTemplate) {
<a name="l00506"></a>00506 $currentChunk = sprintf($chunkStringTemplate, <a class="code" href="class_template_utils.html#aa3553ef2c1e54e0e99ad38a7fe931efa" title="Escape string to use in template class.">TemplateUtils::escape</a>($currentChunk));
<a name="l00507"></a>00507 }
<a name="l00508"></a>00508 $chunkCode = $currentChunk;
<a name="l00509"></a>00509 }
<a name="l00510"></a>00510
<a name="l00511"></a>00511 $code .= sprintf($chunkTemplate, $chunkCode);
<a name="l00512"></a>00512
<a name="l00513"></a>00513 $nextChunk = <span class="stringliteral">'operator'</span>;
<a name="l00514"></a>00514 }
<a name="l00515"></a>00515 }
<a name="l00516"></a>00516
<a name="l00517"></a>00517 <span class="keywordflow">return</span> $code;
<a name="l00518"></a>00518 }
<a name="l00519"></a>00519
<a name="l00528"></a><a class="code" href="class_template_compiler_ex.html#a0e954efa4b344518798797fe3bc6dd14">00528</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a0e954efa4b344518798797fe3bc6dd14" title="Handles filter chains.">parseFilterChain</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $filterExpr, $code) {
<a name="l00529"></a>00529 $filterChain = <a class="code" href="class_template_utils.html#a28bd46df8e8547dd387e2047733d8f87" title="Properly splits given expression using given delimiter.">TemplateUtils::splitEscaped</a>(<span class="charliteral">'|'</span>, $filterExpr);
<a name="l00530"></a>00530 $resultCode = $code;
<a name="l00531"></a>00531
<a name="l00532"></a>00532 <span class="comment">// Hook-point: parseFilterChain:entry</span>
<a name="l00533"></a>00533 $this->runHooks(<span class="stringliteral">'parseFilterChain:entry'</span>, array(&$filterChain));
<a name="l00534"></a>00534 <span class="comment">//</span>
<a name="l00535"></a>00535
<a name="l00536"></a>00536 <span class="keywordflow">foreach</span> ($filterChain as &$filter) {
<a name="l00537"></a>00537 list($name, $args) = <a class="code" href="class_template_utils.html#ad8600ee16ab4bcfc0575696c8e2520d2" title="Split string into two.">TemplateUtils::split</a>(<span class="charliteral">':'</span>, $filter);
<a name="l00538"></a>00538 <span class="keywordflow">if</span> ($args) {
<a name="l00539"></a>00539 $args = <a class="code" href="class_template_utils.html#a28bd46df8e8547dd387e2047733d8f87" title="Properly splits given expression using given delimiter.">TemplateUtils::splitEscaped</a>(<span class="charliteral">','</span>, $args);
<a name="l00540"></a>00540 } <span class="keywordflow">else</span> {
<a name="l00541"></a>00541 $args = array();
<a name="l00542"></a>00542 }
<a name="l00543"></a>00543
<a name="l00544"></a>00544 <span class="keywordflow">foreach</span> ($args as &$arg) {
<a name="l00545"></a>00545 <span class="keywordflow">if</span> (mb_substr($arg, 0, 1) == <span class="charliteral">'"'</span>) {
<a name="l00546"></a>00546 $arg = array(<span class="stringliteral">'string'</span>, <span class="charliteral">'\''</span>.<a class="code" href="class_template_utils.html#aa3553ef2c1e54e0e99ad38a7fe931efa" title="Escape string to use in template class.">TemplateUtils::escape</a>(mb_substr($arg, 1, -1)).<span class="charliteral">'\''</span>);
<a name="l00547"></a>00547 } elseif (preg_match(<span class="stringliteral">'~^\-?[0-9]+(?:\.[0-9]+)?$~'</span>, $arg)) {
<a name="l00548"></a>00548 $arg = array(<span class="stringliteral">'number'</span>, $arg);
<a name="l00549"></a>00549 } <span class="keywordflow">else</span> {
<a name="l00550"></a>00550 list($code,) = $this->parseVariableExpression($node, $arg);
<a name="l00551"></a>00551 $arg = array(<span class="stringliteral">'variable'</span>, <span class="charliteral">'@'</span>.$code);
<a name="l00552"></a>00552 }
<a name="l00553"></a>00553 }
<a name="l00554"></a>00554
<a name="l00555"></a>00555 $filterInfo = $this->commonVerifyElement($node, <span class="stringliteral">'filter'</span>, $name, $args);
<a name="l00556"></a>00556 $filterCode = call_user_func_array(
<a name="l00557"></a>00557 $filterInfo[<span class="stringliteral">'handler'</span>], array($this, $node, &$name, &$args)
<a name="l00558"></a>00558 );
<a name="l00559"></a>00559
<a name="l00560"></a>00560 $resultCode = sprintf($filterCode, $resultCode);
<a name="l00561"></a>00561 }
<a name="l00562"></a>00562
<a name="l00563"></a>00563 <span class="keywordflow">return</span> $resultCode;
<a name="l00564"></a>00564 }
<a name="l00565"></a>00565
<a name="l00580"></a><a class="code" href="class_template_compiler_ex.html#aa45b715a26c3bd45064f4eee890c1dad">00580</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#aa45b715a26c3bd45064f4eee890c1dad" title="Verifies correctness of given element.">commonVerifyElement</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $element, &$name, array &$args) {
<a name="l00581"></a>00581 <span class="keywordflow">if</span> (!in_array($element, array(<span class="stringliteral">'tag'</span>, <span class="stringliteral">'filter'</span>))) {
<a name="l00582"></a>00582 <a class="code" href="class_template_utils.html#a9756a1cc5232e00302a0b52c3a1e8e10" title="Panics.">TemplateUtils::panic</a>(__FILE__, __LINE__);
<a name="l00583"></a>00583 }
<a name="l00584"></a>00584
<a name="l00585"></a>00585 $this->raiseIf(
<a name="l00586"></a>00586 (!$this->plugins->known($element, $name)),
<a name="l00587"></a>00587 $node,
<a name="l00588"></a>00588 <span class="stringliteral">'Unknown '</span>.$element.<span class="stringliteral">' "'</span>.$name.<span class="stringliteral">'" encountered'</span>,
<a name="l00589"></a>00589 ($element == <span class="stringliteral">'tag'</span> ? <a class="code" href="class_template_error.html#ae678eee4aca2972c0490ac727ef5416f" title="An unknown tag error.">TemplateError::E_UNKNOWN_TAG</a> : <a class="code" href="class_template_error.html#a3846fc5ce9f8f386092174ca142be11e" title="An unknown filter error.">TemplateError::E_UNKNOWN_FILTER</a>)
<a name="l00590"></a>00590 );
<a name="l00591"></a>00591
<a name="l00592"></a>00592 $elementInfo = $this->plugins->get($element, $name);
<a name="l00593"></a>00593
<a name="l00594"></a>00594 <a class="code" href="class_template_utils.html#a9ded2c07232134c25d3cf9300822e7d8" title="Checks whether element is allowed.">TemplateUtils::checkIfAllowed</a>($this, $element, $name, $node);
<a name="l00595"></a>00595
<a name="l00596"></a>00596 <span class="keywordflow">if</span> (!is_callable($elementInfo[<span class="stringliteral">'handler'</span>])) {
<a name="l00597"></a>00597 <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00598"></a>00598 <span class="stringliteral">'Invalid handler ['</span>.<a class="code" href="class_template_utils.html#a486a01915d89b3a87095461329a3a7e6" title="Strip newlines and spaces from string.">TemplateUtils::strip</a>(var_export($elementInfo[<span class="stringliteral">'handler'</span>], <span class="keyword">true</span>)).
<a name="l00599"></a>00599 <span class="stringliteral">'] supplied for '</span>.$element.<span class="stringliteral">' "'</span>.$name.<span class="stringliteral">'" by plugin "'</span>.$elementInfo[<span class="stringliteral">'plugin'</span>].<span class="charliteral">'"'</span>,
<a name="l00600"></a>00600 <a class="code" href="class_template_error.html#a197d3675b19ddab587d765167ba142d2" title="An invalid handler error.">TemplateError::E_INVALID_HANDLER</a>
<a name="l00601"></a>00601 );
<a name="l00602"></a>00602 }
<a name="l00603"></a>00603
<a name="l00604"></a>00604 <span class="keywordflow">if</span> (isset($elementInfo[<span class="stringliteral">'minArgs'</span>])) {
<a name="l00605"></a>00605 $this->raiseIf(
<a name="l00606"></a>00606 (count($args) < $elementInfo[<span class="stringliteral">'minArgs'</span>]),
<a name="l00607"></a>00607 $node,
<a name="l00608"></a>00608 <span class="stringliteral">'Invalid '</span>.$element.<span class="stringliteral">' call - '</span>.$element.<span class="stringliteral">' "'</span>.$name.<span class="stringliteral">'" requires at least '</span>.
<a name="l00609"></a>00609 <span class="charliteral">'"'</span>.$elementInfo[<span class="stringliteral">'minArgs'</span>].<span class="stringliteral">'" arguments '</span>,
<a name="l00610"></a>00610 <a class="code" href="class_template_error.html#ac502ffee5019e6d870c25083af550454" title="An invalid syntax error.">TemplateError::E_INVALID_SYNTAX</a>
<a name="l00611"></a>00611 );
<a name="l00612"></a>00612 }
<a name="l00613"></a>00613
<a name="l00614"></a>00614 <span class="keywordflow">return</span> $elementInfo;
<a name="l00615"></a>00615 }
<a name="l00616"></a>00616
<a name="l00617"></a>00617 <span class="comment">// Bulitins part</span>
<a name="l00618"></a>00618
<a name="l00628"></a><a class="code" href="class_template_compiler_ex.html#a49ac9c78629669903684589ebcd76033">00628</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#a49ac9c78629669903684589ebcd76033" title="Handler for load built-in tag.">handleLoadBuiltin</a>(<a class="code" href="class_template_compiler_ex.html" title="Primary compiler driver.">TemplateCompilerEx</a> $compiler, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, &$tag, array &$args) {
<a name="l00629"></a>00629 $this->raiseIf(
<a name="l00630"></a>00630 ($this->plugins->load($this, $node, $args[0], null, <span class="keyword">true</span>) === <span class="keyword">false</span>),
<a name="l00631"></a>00631 $node,
<a name="l00632"></a>00632 <span class="stringliteral">'Tried to load non-existant or invalid plugin "'</span>.$args[0].<span class="charliteral">'"'</span>,
<a name="l00633"></a>00633 <a class="code" href="class_template_error.html#adcc81c7e44a611c01e633f0c7f88a89d" title="An unknown plugin error.">TemplateError::E_UNKNOWN_PLUGIN</a>
<a name="l00634"></a>00634 );
<a name="l00635"></a>00635
<a name="l00636"></a>00636 <span class="comment">// {% load %} generates no code</span>
<a name="l00637"></a>00637 <span class="keywordflow">return</span> <span class="stringliteral">''</span>;
<a name="l00638"></a>00638 }
<a name="l00639"></a>00639
<a name="l00649"></a><a class="code" href="class_template_compiler_ex.html#ac5ba453fe0497c6a97e01b3ecc7b9c30">00649</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#ac5ba453fe0497c6a97e01b3ecc7b9c30" title="Handler for comment built-in tag.">handleCommentBuiltin</a>(<a class="code" href="class_template_compiler_ex.html" title="Primary compiler driver.">TemplateCompilerEx</a> $compiler, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, &$tag, array &$args) {
<a name="l00650"></a>00650 <span class="comment">// no block-level code generated</span>
<a name="l00651"></a>00651 <span class="keywordflow">return</span> <span class="stringliteral">''</span>;
<a name="l00652"></a>00652 }
<a name="l00653"></a>00653
<a name="l00654"></a>00654 <span class="comment">// Compiler-specific utils</span>
<a name="l00655"></a>00655
<a name="l00665"></a><a class="code" href="class_template_compiler_ex.html#a8f7f10bdd17ee4be906b39cff3f0d13d">00665</a> <span class="keyword">public</span> function <span class="keyword">raise</span>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $message, $code) {
<a name="l00666"></a>00666 <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00667"></a>00667 $message.<span class="stringliteral">' (in template "'</span>.$node->nodeFile.<span class="stringliteral">'" somewhere around line '</span>.$node->nodeLine.<span class="charliteral">')'</span>,
<a name="l00668"></a>00668 $code
<a name="l00669"></a>00669 );
<a name="l00670"></a>00670 }
<a name="l00671"></a>00671
<a name="l00682"></a><a class="code" href="class_template_compiler_ex.html#af8bc3411f0f8bcfbd153a8d56f0ae2e7">00682</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#af8bc3411f0f8bcfbd153a8d56f0ae2e7" title="Shorthand for conditional call to TemplateCompilerEx::raise.">raiseIf</a>($cond, <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $message, $code) {
<a name="l00683"></a>00683 <span class="keywordflow">if</span> ($cond === <span class="keyword">true</span>) $this-><span class="keyword">raise</span>($node, $message, $code);
<a name="l00684"></a>00684 }
<a name="l00685"></a>00685
<a name="l00695"></a><a class="code" href="class_template_compiler_ex.html#a9ce1b5f9a87d8fdbadfad18bb440efff">00695</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a9ce1b5f9a87d8fdbadfad18bb440efff" title="Used to find and isolate alternative branch of given node, starting with given inline tag...">findAlternativeBranch</a>(<a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> $node, $tag) {
<a name="l00696"></a>00696 $alternativeIdx = null;
<a name="l00697"></a>00697
<a name="l00698"></a>00698 <span class="keywordflow">foreach</span> ($node->nodeChildren as $idx => $childNode) {
<a name="l00699"></a>00699 <span class="keywordflow">if</span> ($childNode->nodeID == <span class="stringliteral">'inlineTag'</span> && $childNode->nodeContent[0] == $tag) {
<a name="l00700"></a>00700 $alternativeIdx = $idx;
<a name="l00701"></a>00701 <span class="keywordflow">break</span>;
<a name="l00702"></a>00702 }
<a name="l00703"></a>00703 }
<a name="l00704"></a>00704
<a name="l00705"></a>00705 <span class="keywordflow">if</span> ($alternativeIdx) {
<a name="l00706"></a>00706 $mainNodes = array_slice($node->nodeChildren, 0, $alternativeIdx);
<a name="l00707"></a>00707 $alternativeNodes = array_slice($node->nodeChildren, $alternativeIdx + 1);
<a name="l00708"></a>00708 } <span class="keywordflow">else</span> {
<a name="l00709"></a>00709 $mainNodes = &$node->nodeChildren;
<a name="l00710"></a>00710 $alternativeNodes = array();
<a name="l00711"></a>00711 }
<a name="l00712"></a>00712
<a name="l00713"></a>00713 <span class="keywordflow">return</span> array($mainNodes, $alternativeNodes);
<a name="l00714"></a>00714 }
<a name="l00715"></a>00715
<a name="l00729"></a><a class="code" href="class_template_compiler_ex.html#a0cee437cbd376a2ad926de8b745e120c">00729</a> <span class="keyword">public</span> function <a class="code" href="class_template_compiler_ex.html#a0cee437cbd376a2ad926de8b745e120c" title="Generates prefixed block name that is guaranteed to be unique in current template.">generateUniqueBlock</a>($idPrefix, $blockPrefix = <span class="stringliteral">'custom:'</span>, $keyLength = 5) {
<a name="l00730"></a>00730 <span class="keywordflow">if</span> (32 - $keyLength <= 0) {
<a name="l00731"></a>00731 <a class="code" href="class_template_utils.html#a9756a1cc5232e00302a0b52c3a1e8e10" title="Panics.">TemplateUtils::panic</a>(__FILE__, __LINE__);
<a name="l00732"></a>00732 }
<a name="l00733"></a>00733
<a name="l00734"></a>00734 <span class="keywordflow">do</span> {
<a name="l00735"></a>00735 $generatedID = md5(uniqid($idPrefix, <span class="keyword">true</span>));
<a name="l00736"></a>00736 $randomOffset = mt_rand(0, 32 - $keyLength);
<a name="l00737"></a>00737
<a name="l00738"></a>00738 $blockName = $blockPrefix.mb_substr($generatedID, $randomOffset, $keyLength);
<a name="l00739"></a>00739 } <span class="keywordflow">while</span> (isset($this->blocks[$blockName]));
<a name="l00740"></a>00740
<a name="l00741"></a>00741 <span class="keywordflow">return</span> $blockName;
<a name="l00742"></a>00742 }
<a name="l00743"></a>00743
<a name="l00744"></a>00744 <span class="comment">// Hooks</span>
<a name="l00745"></a>00745
<a name="l00756"></a><a class="code" href="class_template_compiler_ex.html#adb76060dfb9e369b12ee21bea4a51b8d">00756</a> <span class="keyword">private</span> function <a class="code" href="class_template_compiler_ex.html#adb76060dfb9e369b12ee21bea4a51b8d" title="Runs handlers associated with given hook-point.">runHooks</a>($hookPoint, array $args) {
<a name="l00757"></a>00757 array_unshift($args, $this);
<a name="l00758"></a>00758 $handlers = $this->plugins->get(<span class="stringliteral">'hook'</span>, $hookPoint);
<a name="l00759"></a>00759
<a name="l00760"></a>00760 <span class="keywordflow">foreach</span> ($handlers as &$hookInfo) {
<a name="l00761"></a>00761 $handler = &$hookInfo[<span class="stringliteral">'handler'</span>];
<a name="l00762"></a>00762
<a name="l00763"></a>00763 <span class="keywordflow">if</span> (!is_callable($handler)) {
<a name="l00764"></a>00764 <span class="keywordflow">throw</span> <span class="keyword">new</span> <a class="code" href="class_template_error.html" title="Main and currently the only exception type thrown by SithTemplate internals.">TemplateError</a>(
<a name="l00765"></a>00765 <span class="stringliteral">'Invalid handler ['</span>.<a class="code" href="class_template_utils.html#a486a01915d89b3a87095461329a3a7e6" title="Strip newlines and spaces from string.">TemplateUtils::strip</a>(var_export($hookInfo[<span class="stringliteral">'handler'</span>], <span class="keyword">true</span>)).
<a name="l00766"></a>00766 <span class="stringliteral">'] hooked into "'</span>.$hookPoint.<span class="stringliteral">'" point by plugin "'</span>.$hookInfo[<span class="stringliteral">'plugin'</span>].<span class="charliteral">'"'</span>,
<a name="l00767"></a>00767 <a class="code" href="class_template_error.html#a197d3675b19ddab587d765167ba142d2" title="An invalid handler error.">TemplateError::E_INVALID_HANDLER</a>
<a name="l00768"></a>00768 );
<a name="l00769"></a>00769 }
<a name="l00770"></a>00770
<a name="l00771"></a>00771 <span class="keywordflow">if</span> (call_user_func_array($handler, $args) === <span class="keyword">true</span>) <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00772"></a>00772 }
<a name="l00773"></a>00773
<a name="l00774"></a>00774 <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00775"></a>00775 }
<a name="l00776"></a>00776 }
<a name="l00777"></a>00777
<a name="l00784"></a><a class="code" href="class_template_node_ex.html">00784</a> <span class="keyword">class </span><a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a> {
<a name="l00790"></a><a class="code" href="class_template_node_ex.html#a197e9a2189b3f2e5da6960792c2b0bc2">00790</a> <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a197e9a2189b3f2e5da6960792c2b0bc2" title="Type of this node.">$nodeID</a> = <span class="stringliteral">''</span>;
<a name="l00794"></a><a class="code" href="class_template_node_ex.html#a52572f655c352c200900c661fced7c7f">00794</a> <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a52572f655c352c200900c661fced7c7f" title="Parent of this node.">$nodeParent</a> = null;
<a name="l00798"></a><a class="code" href="class_template_node_ex.html#a11071f5a75e8b01504b94c70b20a16f9">00798</a> <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a11071f5a75e8b01504b94c70b20a16f9" title="Children of this node.">$nodeChildren</a> = array();
<a name="l00803"></a><a class="code" href="class_template_node_ex.html#a02b43357ebf9a8c78a4b7ed6d50f666a">00803</a> <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a02b43357ebf9a8c78a4b7ed6d50f666a" title="Content of this node.">$nodeContent</a> = null;
<a name="l00807"></a><a class="code" href="class_template_node_ex.html#a90a4bddb119982b9e11fd7293768e387">00807</a> <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#a90a4bddb119982b9e11fd7293768e387" title="Aid for template debugging, source line where the parser constructed this node.">$nodeLine</a> = 0;
<a name="l00811"></a><a class="code" href="class_template_node_ex.html#aa00e50823c505da795c0b2381badc312">00811</a> <span class="keyword">public</span> <a class="code" href="class_template_node_ex.html#aa00e50823c505da795c0b2381badc312" title="Aid for template debugging, source file where the parser constructed this node.">$nodeFile</a> = null;
<a name="l00812"></a>00812
<a name="l00822"></a><a class="code" href="class_template_node_ex.html#aa44f330a0ecb8832f1990f5e3b6de712">00822</a> <span class="keyword">public</span> function <a class="code" href="class_template_node_ex.html#aa44f330a0ecb8832f1990f5e3b6de712" title="Constructor.">__construct</a>($id, $parent = null, $content = null, $file = null, $line = 0) {
<a name="l00823"></a>00823 $this->nodeID = $id;
<a name="l00824"></a>00824 $this->nodeParent = $parent;
<a name="l00825"></a>00825 $this->nodeContent = $content;
<a name="l00826"></a>00826 $this->nodeLine = $line;
<a name="l00827"></a>00827 $this->nodeFile = $file;
<a name="l00828"></a>00828 }
<a name="l00829"></a>00829
<a name="l00838"></a><a class="code" href="class_template_node_ex.html#ac4a2737627e12bace528ee449b45943f">00838</a> <span class="keyword">public</span> function <a class="code" href="class_template_node_ex.html#ac4a2737627e12bace528ee449b45943f" title="Creates a new TemplateNodeEx instance and adds it to this node children.">addChild</a>($id, $content = null, $file = null, $line = 0) {
<a name="l00839"></a>00839 $this->nodeChildren[] = <span class="keyword">new</span> <a class="code" href="class_template_node_ex.html" title="Class-container for AST nodes.">TemplateNodeEx</a>($id, $this, $content, $file, $line);
<a name="l00840"></a>00840 }
<a name="l00841"></a>00841
<a name="l00848"></a><a class="code" href="class_template_node_ex.html#a91391755954ef38c641ba68c1f752871">00848</a> <span class="keyword">public</span> function <a class="code" href="class_template_node_ex.html#a91391755954ef38c641ba68c1f752871" title="Debugging aid.">dump</a>($level = 0) {
<a name="l00849"></a>00849 $out = <span class="stringliteral">''</span>;
<a name="l00850"></a>00850 <span class="keywordflow">for</span> ($i = 0; $i < $level; ++$i) { $out .= <span class="charliteral">' '</span>; }
<a name="l00851"></a>00851 $out .= <span class="stringliteral">'ast<'</span>.$this->nodeID.<span class="charliteral">'>'</span>;
<a name="l00852"></a>00852 <span class="keywordflow">if</span> (is_array($this->nodeContent)) {
<a name="l00853"></a>00853 $out .= <span class="charliteral">'('</span>.$this->nodeContent[0];
<a name="l00854"></a>00854 <span class="keywordflow">if</span> (count($this->nodeContent[1]) > 0) {
<a name="l00855"></a>00855 $out .= <span class="stringliteral">', '</span>.implode(<span class="stringliteral">', '</span>, $this->nodeContent[1]);
<a name="l00856"></a>00856 }
<a name="l00857"></a>00857 $out .= <span class="charliteral">')'</span>;
<a name="l00858"></a>00858 } <span class="keywordflow">else</span> {
<a name="l00859"></a>00859 $s = str_replace(<span class="stringliteral">"\n"</span>, <span class="charliteral">'\n'</span>, $this->nodeContent);
<a name="l00860"></a>00860 <span class="keywordflow">if</span> (mb_strlen($s) > 30) $s = mb_substr($s, 0, 30).<span class="stringliteral">'[...]'</span>;
<a name="l00861"></a>00861 $out .= <span class="stringliteral">'("'</span>.$s.<span class="stringliteral">'")'</span>;
<a name="l00862"></a>00862 }
<a name="l00863"></a>00863 $out .= <span class="stringliteral">' @ '</span>.$this->nodeFile.<span class="charliteral">':'</span>.$this->nodeLine.<span class="stringliteral">" => [\n"</span>;
<a name="l00864"></a>00864 <span class="keywordflow">foreach</span> ($this->nodeChildren as $child) { $out .= $child->dump($level + 1); }
<a name="l00865"></a>00865 <span class="keywordflow">for</span> ($i = 0; $i < $level; ++$i) { $out .= <span class="charliteral">' '</span>; }
<a name="l00866"></a>00866 <span class="keywordflow">return</span> $out . <span class="stringliteral">"]\n"</span>;
<a name="l00867"></a>00867 }
<a name="l00868"></a>00868 }
</pre></div></div>
</div>
<hr class="footer"/><address class="footer"><small>Generated on Fri Jan 14 2011 20:08:36 for SithTemplate by 
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.2 </small></address>
</body>
</html>