UNPKG

jade

Version:

Jade template engine

673 lines (647 loc) 65.8 kB
<html> <head> <title>Jade</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <style>body { margin: 0; padding: 0; font: 14px/1.5 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; color: #252519; } a { color: #252519; } a:hover { text-decoration: underline; color: #19469D; } p { margin: 12px 0; } h1, h2, h3 { margin: 0; padding: 0; } table#source { width: 100%; border-collapse: collapse; } table#source td:first-child { padding: 30px 40px 30px 40px; vertical-align: top; } table#source td:first-child, table#source td:first-child pre { width: 450px; } table#source td:last-child { padding: 30px 0 30px 40px; border-left: 1px solid #E5E5EE; background: #F5F5FF; } table#source tr { border-bottom: 1px solid #E5E5EE; } table#source tr.filename { padding-top: 40px; border-top: 1px solid #E5E5EE; } table#source tr.filename td:first-child { text-transform: capitalize; } table#source tr.filename td:last-child { font-size: 12px; } table#source tr.filename h2 { margin: 0; padding: 0; cursor: pointer; } table#source tr.code h1, table#source tr.code h2, table#source tr.code h3 { margin-top: 30px; font-family: "Lucida Grande", "Helvetica Nueue", Arial, sans-serif; font-size: 18px; } table#source tr.code h2 { font-size: 16px; } table#source tr.code h3 { font-size: 14px; } table#source tr.code ul { margin: 15px 0 15px 35px; padding: 0; } table#source tr.code ul li { margin: 0; padding: 1px 0; } table#source tr.code ul li p { margin: 0; padding: 0; } table#source tr.code td:first-child pre { padding: 20px; } #ribbon { position: fixed; top: 0; right: 0; } code .string { color: #219161; } code .regexp { color: #219161; } code .keyword { color: #954121; } code .number { color: #19469D; } code .comment { color: #bbb; } code .this { color: #19469D; }</style> <script> $(function(){ $('tr.code').hide(); $('tr.filename').toggle(function(){ $(this).nextUntil('.filename').fadeIn(); }, function(){ $(this).nextUntil('.filename').fadeOut(); }); }); </script> </head> <body> <table id="source"><tbody><tr><td><h1>Jade</h1><p>Jade is a high performance template engine for <a href="http://nodejs.org">node</a>, inspired by <a href="http://haml-lang.com/">haml</a>, created by <a href="http://github.com/visionmedia">TJ Holowaychuk</a>.</p></td><td></td></tr><tr class="filename"><td><h2 id="lib/jade.js"><a href="#">jade</a></h2></td><td>lib/jade.js</td></tr><tr class="code"> <td class="docs"> <p>Library version. </p> </td> <td class="code"> <pre><code><span class="variable">exports</span>.<span class="variable">version</span> = <span class="string">'0.2.2'</span>;</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Module dependencies. </p> </td> <td class="code"> <pre><code><span class="keyword">var</span> <span class="variable">sys</span> = <span class="variable">require</span>(<span class="string">'sys'</span>), <span class="variable">fs</span> = <span class="variable">require</span>(<span class="string">'fs'</span>);</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Intermediate JavaScript cache.</p> <ul><li><p><strong>type</strong>: <em>Object</em></p></li></ul> </td> <td class="code"> <pre><code><span class="keyword">var</span> <span class="variable">cache</span> = <span class="variable">exports</span>.<span class="variable">cache</span> = {};</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Self closing tags.</p> <ul><li><p><strong>type</strong>: <em>Object</em></p></li></ul> </td> <td class="code"> <pre><code><span class="keyword">var</span> <span class="variable">selfClosing</span> = <span class="variable">exports</span>.<span class="variable">selfClosing</span> = [ <span class="string">'meta'</span>, <span class="string">'img'</span>, <span class="string">'link'</span>, <span class="string">'br'</span>, <span class="string">'hr'</span>, <span class="string">'input'</span>, <span class="string">'area'</span>, <span class="string">'base'</span> ];</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Default supported doctypes.</p> <ul><li><p><strong>type</strong>: <em>Object</em></p></li></ul> </td> <td class="code"> <pre><code><span class="keyword">var</span> <span class="variable">doctypes</span> = <span class="variable">exports</span>.<span class="variable">doctypes</span> = { <span class="string">'5'</span>: <span class="string">'&lt;!DOCTYPE html&gt;'</span>, <span class="string">'xml'</span>: <span class="string">'&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&gt;'</span>, <span class="string">'default'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;'</span>, <span class="string">'transitional'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;'</span>, <span class="string">'strict'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;'</span>, <span class="string">'frameset'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Frameset//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd&quot;&gt;'</span>, <span class="string">'1.1'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;'</span>, <span class="string">'basic'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML Basic 1.1//EN&quot; &quot;http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd&quot;&gt;'</span>, <span class="string">'mobile'</span>: <span class="string">'&lt;!DOCTYPE html PUBLIC &quot;-//WAPFORUM//DTD XHTML Mobile 1.2//EN&quot; &quot;http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd&quot;&gt;'</span> };</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Filters.</p> <ul><li><p><strong>type</strong>: <em>Object</em></p></li></ul> </td> <td class="code"> <pre><code><span class="keyword">var</span> <span class="variable">filters</span> = <span class="variable">exports</span>.<span class="variable">filters</span> = {</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Wrap text with CDATA block. </p> </td> <td class="code"> <pre><code><span class="variable">cdata</span>: <span class="keyword">function</span>(<span class="variable">str</span>){ <span class="keyword">return</span> <span class="string">'&lt;![CDATA[\\n'</span> + <span class="variable">str</span> + <span class="string">'\\n]]&gt;'</span>; },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Wrap text with script and CDATA tags. </p> </td> <td class="code"> <pre><code><span class="variable">javascript</span>: <span class="keyword">function</span>(<span class="variable">str</span>){ <span class="keyword">return</span> <span class="string">'&lt;script type=&quot;text/javascript&quot;&gt;\\n//&lt;![CDATA[\\n'</span> + <span class="variable">str</span> + <span class="string">'\\n//]]&gt;&lt;/script&gt;'</span>; },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Transform sass to css, wrapped in style tags. </p> </td> <td class="code"> <pre><code><span class="variable">sass</span>: <span class="keyword">function</span>(<span class="variable">str</span>){ <span class="variable">str</span> = <span class="variable">str</span>.<span class="variable">replace</span>(<span class="regexp">/\\n/g</span>, <span class="string">'\n'</span>); <span class="keyword">var</span> <span class="variable">sass</span> = <span class="variable">require</span>(<span class="string">'sass'</span>).<span class="variable">render</span>(<span class="variable">str</span>).<span class="variable">replace</span>(<span class="regexp">/\n/g</span>, <span class="string">'\\n'</span>); <span class="keyword">return</span> <span class="string">'&lt;style&gt;'</span> + <span class="variable">sass</span> + <span class="string">'&lt;/style&gt;'</span>; },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Transform sass to css, wrapped in style tags. </p> </td> <td class="code"> <pre><code><span class="variable">less</span>: <span class="keyword">function</span>(<span class="variable">str</span>){ <span class="keyword">var</span> <span class="variable">less</span>; <span class="variable">str</span> = <span class="variable">str</span>.<span class="variable">replace</span>(<span class="regexp">/\\n/g</span>, <span class="string">'\n'</span>); <span class="variable">require</span>(<span class="string">'less'</span>).<span class="variable">render</span>(<span class="variable">str</span>, <span class="keyword">function</span>(<span class="variable">err</span>, <span class="variable">css</span>){ <span class="variable">less</span> = <span class="string">'&lt;style&gt;'</span> + <span class="variable">css</span>.<span class="variable">replace</span>(<span class="regexp">/\n/g</span>, <span class="string">'\\n'</span>) + <span class="string">'&lt;/style&gt;'</span>; }); <span class="keyword">return</span> <span class="variable">less</span>; },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Transform markdown to html. </p> </td> <td class="code"> <pre><code><span class="variable">markdown</span>: <span class="keyword">function</span>(<span class="variable">str</span>){ <span class="keyword">var</span> <span class="variable">md</span> = <span class="variable">require</span>(<span class="string">'markdown'</span>); <span class="variable">str</span> = <span class="variable">str</span>.<span class="variable">replace</span>(<span class="regexp">/\\n/g</span>, <span class="string">'\n'</span>); <span class="keyword">return</span> (<span class="variable">md</span>.<span class="variable">toHTML</span> ? <span class="variable">md</span>.<span class="variable">toHTML</span>(<span class="variable">str</span>) : <span class="variable">md</span>.<span class="variable">parse</span>(<span class="variable">str</span>)).<span class="variable">replace</span>(<span class="regexp">/\n/g</span>, <span class="string">'\\n'</span>).<span class="variable">replace</span>(<span class="regexp">/'/g</span>,<span class="string">'&amp;#39;'</span>); } };</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Initialize jade parser with the given input string.</p> <h2></h2> <ul><li><p><strong>param</strong>: <em>String</em> str</p></li><li><p><strong>param</strong>: <em>String</em> filename</p></li><li><p><strong>api</strong>: <em>public</em></p></li></ul> </td> <td class="code"> <pre><code><span class="keyword">function</span> <span class="class">Parser</span>(<span class="variable">str</span>, <span class="variable">filename</span>){ <span class="this">this</span>.<span class="variable">input</span> = <span class="variable">str</span>.<span class="variable">replace</span>(<span class="regexp">/\r\n|\r/g</span>, <span class="string">'\n'</span>); <span class="this">this</span>.<span class="variable">filename</span> = <span class="variable">filename</span>; <span class="this">this</span>.<span class="variable">deferredTokens</span> = []; <span class="this">this</span>.<span class="variable">lastIndents</span> = <span class="number integer">0</span>; <span class="this">this</span>.<span class="variable">lineno</span> = <span class="number integer">1</span>; }</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Parser prototype. </p> </td> <td class="code"> <pre><code><span class="class">Parser</span>.<span class="variable">prototype</span> = {</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Generate token object. </p> </td> <td class="code"> <pre><code><span class="keyword">function</span> <span class="variable">token</span>(<span class="variable">type</span>){ <span class="variable">self</span>.<span class="variable">input</span> = <span class="variable">self</span>.<span class="variable">input</span>.<span class="variable">substr</span>(<span class="variable">captures</span>[<span class="number integer">0</span>].<span class="variable">length</span>); <span class="keyword">return</span> { <span class="variable">type</span>: <span class="variable">type</span>, <span class="variable">line</span>: <span class="variable">self</span>.<span class="variable">lineno</span>, <span class="variable">val</span>: <span class="variable">captures</span>[<span class="number integer">1</span>] }; } <span class="comment">// EOS</span> <span class="keyword">if</span> (!<span class="this">this</span>.<span class="variable">input</span>.<span class="variable">length</span>) { <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">lastIndents</span>-- &<span class="variable">gt</span>; <span class="number integer">0</span>) { <span class="keyword">return</span> { <span class="variable">type</span>: <span class="string">'outdent'</span>, <span class="variable">line</span>: <span class="this">this</span>.<span class="variable">lineno</span> }; } <span class="keyword">else</span> { <span class="keyword">return</span> { <span class="variable">type</span>: <span class="string">'eos'</span>, <span class="variable">line</span>: <span class="this">this</span>.<span class="variable">lineno</span> }; } } <span class="comment">// Tag</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^(\w[:\w]*)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">return</span> <span class="variable">token</span>(<span class="string">'tag'</span>); } <span class="comment">// Filter</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^:(\w+)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">return</span> <span class="variable">token</span>(<span class="string">'filter'</span>); } <span class="comment">// Each</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^- *each *(\w+)(?: *, *(\w+))? * in *([^\n]+)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">var</span> <span class="variable">tok</span> = <span class="variable">token</span>(<span class="string">'each'</span>); <span class="variable">tok</span>.<span class="variable">val</span> = <span class="variable">captures</span>[<span class="number integer">1</span>]; <span class="variable">tok</span>.<span class="variable">key</span> = <span class="variable">captures</span>[<span class="number integer">2</span>] || <span class="string">'index'</span>; <span class="variable">tok</span>.<span class="variable">code</span> = <span class="variable">captures</span>[<span class="number integer">3</span>]; <span class="keyword">return</span> <span class="variable">tok</span>; } <span class="comment">// Code</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^(!?=|-)([^\n]+)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">var</span> <span class="variable">flags</span> = <span class="variable">captures</span>[<span class="number integer">1</span>]; <span class="variable">captures</span>[<span class="number integer">1</span>] = <span class="variable">captures</span>[<span class="number integer">2</span>]; <span class="keyword">var</span> <span class="variable">tok</span> = <span class="variable">token</span>(<span class="string">'code'</span>); <span class="variable">tok</span>.<span class="variable">escape</span> = <span class="variable">flags</span>[<span class="number integer">0</span>] === <span class="string">'='</span>; <span class="variable">tok</span>.<span class="variable">buffer</span> = <span class="variable">flags</span>[<span class="number integer">0</span>] === <span class="string">'='</span> || <span class="variable">flags</span>[<span class="number integer">1</span>] === <span class="string">'='</span>; <span class="keyword">return</span> <span class="variable">tok</span>; } <span class="comment">// Doctype</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^!!! *(\w+)?/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">return</span> <span class="variable">token</span>(<span class="string">'doctype'</span>); } <span class="comment">// Id</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^#([\w-]+)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">return</span> <span class="variable">token</span>(<span class="string">'id'</span>); } <span class="comment">// Class</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^\.([\w-]+)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">return</span> <span class="variable">token</span>(<span class="string">'class'</span>); } <span class="comment">// Attributes</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^\( *(.+) *\)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">var</span> <span class="variable">tok</span> = <span class="variable">token</span>(<span class="string">'attrs'</span>), <span class="variable">attrs</span> = <span class="variable">tok</span>.<span class="variable">val</span>.<span class="variable">split</span>(<span class="regexp">/ *, *(?=[\w-]+ *[:=]|[\w-]+ *$)/</span>); <span class="variable">tok</span>.<span class="variable">attrs</span> = {}; <span class="keyword">for</span> (<span class="keyword">var</span> <span class="variable">i</span> = <span class="number integer">0</span>, <span class="variable">len</span> = <span class="variable">attrs</span>.<span class="variable">length</span>; <span class="variable">i</span> &<span class="variable">lt</span>; <span class="variable">len</span>; ++<span class="variable">i</span>) { <span class="keyword">var</span> <span class="variable">pair</span> = <span class="variable">attrs</span>[<span class="variable">i</span>]; <span class="comment">// Support = and :</span> <span class="keyword">var</span> <span class="variable">colon</span> = <span class="variable">pair</span>.<span class="variable">indexOf</span>(<span class="string">':'</span>), <span class="variable">equal</span> = <span class="variable">pair</span>.<span class="variable">indexOf</span>(<span class="string">'='</span>); <span class="comment">// Boolean</span> <span class="keyword">if</span> (<span class="variable">colon</span> &<span class="variable">lt</span>; <span class="number integer">0</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">equal</span> &<span class="variable">lt</span>; <span class="number integer">0</span>) { <span class="keyword">var</span> <span class="variable">key</span> = <span class="variable">pair</span>, <span class="variable">val</span> = <span class="variable">true</span>; } <span class="keyword">else</span> { <span class="comment">// Split on first = or :</span> <span class="keyword">var</span> <span class="variable">split</span> = <span class="variable">equal</span> &<span class="variable">gt</span>;= <span class="number integer">0</span> ? <span class="variable">equal</span> : <span class="variable">colon</span>; <span class="keyword">if</span> (<span class="variable">colon</span> &<span class="variable">gt</span>;= <span class="number integer">0</span> &<span class="variable">amp</span>;&<span class="variable">amp</span>; <span class="variable">colon</span> &<span class="variable">lt</span>; <span class="variable">equal</span>) <span class="variable">split</span> = <span class="variable">colon</span>; <span class="keyword">var</span> <span class="variable">key</span> = <span class="variable">pair</span>.<span class="variable">substr</span>(<span class="number integer">0</span>, <span class="variable">split</span>), <span class="variable">val</span> = <span class="variable">pair</span>.<span class="variable">substr</span>(++<span class="variable">split</span>, <span class="variable">pair</span>.<span class="variable">length</span>); } <span class="variable">tok</span>.<span class="variable">attrs</span>[<span class="variable">key</span>.<span class="variable">trim</span>().<span class="variable">replace</span>(<span class="regexp">/^['&quot;]|['&quot;]$/g</span>, <span class="string">''</span>)] = <span class="variable">val</span>; } <span class="keyword">return</span> <span class="variable">tok</span>; } <span class="comment">// Indent</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^\n( *)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { ++<span class="this">this</span>.<span class="variable">lineno</span>; <span class="keyword">var</span> <span class="variable">tok</span> = <span class="variable">token</span>(<span class="string">'indent'</span>), <span class="variable">indents</span> = <span class="variable">tok</span>.<span class="variable">val</span>.<span class="variable">length</span> / <span class="number integer">2</span>; <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">input</span>[<span class="number integer">0</span>] === <span class="string">'\n'</span>) { <span class="variable">tok</span>.<span class="variable">type</span> = <span class="string">'newline'</span>; <span class="keyword">return</span> <span class="variable">tok</span>; } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="variable">indents</span> % <span class="number integer">1</span> !== <span class="number integer">0</span>) { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class">Error</span>(<span class="string">'Invalid indentation, got '</span> + <span class="variable">tok</span>.<span class="variable">val</span>.<span class="variable">length</span> + <span class="string">' space'</span> + (<span class="variable">tok</span>.<span class="variable">val</span>.<span class="variable">length</span> &<span class="variable">gt</span>; <span class="number integer">1</span> ? <span class="string">'s'</span> : <span class="string">''</span>) + <span class="string">', must be a multiple of two.'</span>); } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="variable">indents</span> === <span class="this">this</span>.<span class="variable">lastIndents</span>) { <span class="variable">tok</span>.<span class="variable">type</span> = <span class="string">'newline'</span>; } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="variable">indents</span> &<span class="variable">gt</span>; <span class="this">this</span>.<span class="variable">lastIndents</span> + <span class="number integer">1</span>) { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class">Error</span>(<span class="string">'Invalid indentation, got '</span> + <span class="variable">indents</span> + <span class="string">' expected '</span> + (<span class="this">this</span>.<span class="variable">lastIndents</span> + <span class="number integer">1</span>) + <span class="string">'.'</span>); } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="variable">indents</span> &<span class="variable">lt</span>; <span class="this">this</span>.<span class="variable">lastIndents</span>) { <span class="keyword">var</span> <span class="variable">n</span> = <span class="this">this</span>.<span class="variable">lastIndents</span> - <span class="variable">indents</span>; <span class="variable">tok</span>.<span class="variable">type</span> = <span class="string">'outdent'</span>; <span class="keyword">while</span> (--<span class="variable">n</span>) { <span class="this">this</span>.<span class="variable">deferredTokens</span>.<span class="variable">push</span>({ <span class="variable">type</span>: <span class="string">'outdent'</span>, <span class="variable">line</span>: <span class="this">this</span>.<span class="variable">lineno</span> }); } } <span class="this">this</span>.<span class="variable">lastIndents</span> = <span class="variable">indents</span>; <span class="keyword">return</span> <span class="variable">tok</span>; } <span class="comment">// Text</span> <span class="keyword">if</span> (<span class="variable">captures</span> = <span class="regexp">/^(?:\| ?)?([^\n]+)/</span>.<span class="variable">exec</span>(<span class="this">this</span>.<span class="variable">input</span>)) { <span class="keyword">return</span> <span class="variable">token</span>(<span class="string">'text'</span>); } },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>Parse input returning a string of js for evaluation.</p> <h2></h2> <ul><li><p><strong>return</strong>: <em>String</em> </p></li><li><p><strong>api</strong>: <em>public</em></p><p> </p></li></ul> </td> <td class="code"> <pre><code><span class="variable">parse</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">buf</span> = [<span class="string">'var buf = [];'</span>]; <span class="keyword">while</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> !== <span class="string">'eos'</span>) { <span class="variable">buf</span>.<span class="variable">push</span>(<span class="this">this</span>.<span class="variable">parseExpr</span>()); } <span class="variable">buf</span>.<span class="variable">push</span>(&<span class="variable">quot</span>;<span class="keyword">return</span> <span class="variable">buf</span>.<span class="variable">join</span>(<span class="string">''</span>);&<span class="variable">quot</span>;); <span class="keyword">return</span> <span class="variable">buf</span>.<span class="variable">join</span>(<span class="string">'\n'</span>); },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p> tag | id | class | text | filter | doctype | each block | code block? | expr newline </p> </td> <td class="code"> <pre><code><span class="variable">parseExpr</span>: <span class="keyword">function</span>(){ <span class="keyword">switch</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span>) { <span class="keyword">case</span> <span class="string">'tag'</span>: <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">parseTag</span>(); <span class="keyword">case</span> <span class="string">'doctype'</span>: <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">parseDoctype</span>(); <span class="keyword">case</span> <span class="string">'filter'</span>: <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">parseFilter</span>(); <span class="keyword">case</span> <span class="string">'text'</span>: <span class="keyword">return</span> &<span class="variable">quot</span>;<span class="variable">buf</span>.<span class="variable">push</span>(<span class="string">'&quot; + interpolate(this.advance.val.replace(/'</span>/<span class="variable">g</span>, &<span class="variable">quot</span>;\\<span class="string">'&quot;)) + &quot; '</span>);&<span class="variable">quot</span>;; <span class="keyword">case</span> <span class="string">'id'</span>: <span class="keyword">case</span> <span class="string">'class'</span>: <span class="keyword">var</span> <span class="variable">tok</span> = <span class="this">this</span>.<span class="variable">advance</span>; <span class="this">this</span>.<span class="variable">deferredTokens</span>.<span class="variable">push</span>({ <span class="variable">val</span>: <span class="string">'div'</span>, <span class="variable">type</span>: <span class="string">'tag'</span>, <span class="variable">line</span>: <span class="this">this</span>.<span class="variable">lineno</span> }); <span class="this">this</span>.<span class="variable">deferredTokens</span>.<span class="variable">push</span>(<span class="variable">tok</span>); <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">parseExpr</span>(); <span class="keyword">case</span> <span class="string">'each'</span>: <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">parseEach</span>(); <span class="keyword">case</span> <span class="string">'code'</span>: <span class="keyword">var</span> <span class="variable">tok</span> = <span class="this">this</span>.<span class="variable">advance</span>, <span class="variable">val</span> = <span class="variable">tok</span>.<span class="variable">val</span>; <span class="keyword">var</span> <span class="variable">buf</span> = <span class="variable">tok</span>.<span class="variable">buffer</span> ? <span class="string">'buf.push('</span> + (<span class="variable">tok</span>.<span class="variable">escape</span> ? <span class="string">'escape('</span> + <span class="variable">val</span> + <span class="string">')'</span> : <span class="variable">val</span>) + <span class="string">')'</span> : <span class="variable">val</span>; <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> === <span class="string">'indent'</span> ? <span class="variable">buf</span> + <span class="string">'\n(function(){'</span> + <span class="this">this</span>.<span class="variable">parseBlock</span>() + <span class="string">'}).call(this);'</span> : <span class="variable">buf</span> + <span class="string">';'</span>; <span class="keyword">case</span> <span class="string">'newline'</span>: <span class="this">this</span>.<span class="variable">advance</span>; <span class="keyword">return</span> <span class="this">this</span>.<span class="variable">_</span> + <span class="this">this</span>.<span class="variable">parseExpr</span>(); } },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>doctype </p> </td> <td class="code"> <pre><code><span class="variable">parseDoctype</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">name</span> = <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'doctype'</span>).<span class="variable">val</span>; <span class="keyword">if</span> (<span class="variable">name</span> === <span class="string">'5'</span>) <span class="this">this</span>.<span class="variable">mode</span> = <span class="string">'html 5'</span>; <span class="keyword">return</span> &<span class="variable">quot</span>;<span class="variable">buf</span>.<span class="variable">push</span>(<span class="variable">default</span><span class="string">'] + &quot;'</span>);&<span class="variable">quot</span>;; },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>filter text </p> </td> <td class="code"> <pre><code><span class="variable">parseFilter</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">name</span> = <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'filter'</span>).<span class="variable">val</span>, <span class="variable">filter</span> = <span class="variable">filters</span>[<span class="variable">name</span>]; <span class="keyword">if</span> (<span class="variable">filter</span>) { <span class="keyword">var</span> <span class="variable">text</span> = <span class="variable">interpolate</span>(<span class="this">this</span>.<span class="variable">parseTextBlock</span>().<span class="variable">replace</span>(<span class="regexp">/'/g</span>, &<span class="variable">quot</span>;\\'&<span class="variable">quot</span>;)); <span class="keyword">return</span> &<span class="variable">quot</span>;<span class="variable">buf</span>.<span class="variable">push</span>(<span class="string">'&quot; + filter(text) + &quot;'</span>);&<span class="variable">quot</span>;; } <span class="keyword">else</span> { <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class">Error</span>(<span class="string">'unknown filter &quot;:'</span> + <span class="variable">name</span> + <span class="string">'&quot;'</span>); } },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>each block </p> </td> <td class="code"> <pre><code><span class="variable">parseEach</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">each</span> = <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'each'</span>); <span class="keyword">var</span> <span class="variable">fn</span> = <span class="string">'('</span> + <span class="variable">iterate</span> .<span class="variable">replace</span>(<span class="regexp">/__obj__/</span>, <span class="variable">each</span>.<span class="variable">code</span>) .<span class="variable">replace</span>(<span class="regexp">/__val__/g</span>, <span class="variable">each</span>.<span class="variable">val</span>) .<span class="variable">replace</span>(<span class="regexp">/__key__/g</span>, <span class="variable">each</span>.<span class="variable">key</span>) .<span class="variable">replace</span>(<span class="regexp">/__block__/g</span>, <span class="this">this</span>.<span class="variable">parseBlock</span>()) + <span class="string">').call(this);'</span>; <span class="keyword">return</span> <span class="variable">fn</span>; },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>indent (text | newline)* outdent </p> </td> <td class="code"> <pre><code><span class="variable">parseTextBlock</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">buf</span> = []; <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'indent'</span>); <span class="keyword">while</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> === <span class="string">'text'</span> || <span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> === <span class="string">'newline'</span>) { <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> === <span class="string">'newline'</span>) { <span class="this">this</span>.<span class="variable">advance</span>; <span class="variable">buf</span>.<span class="variable">push</span>(<span class="string">'\\n'</span>); } <span class="keyword">else</span> { <span class="variable">buf</span>.<span class="variable">push</span>(<span class="this">this</span>.<span class="variable">advance</span>.<span class="variable">val</span>); } } <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'outdent'</span>); <span class="keyword">return</span> <span class="variable">buf</span>.<span class="variable">join</span>(<span class="string">''</span>); },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>indent expr* outdent </p> </td> <td class="code"> <pre><code><span class="variable">parseBlock</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">buf</span> = []; <span class="variable">buf</span>.<span class="variable">push</span>(<span class="this">this</span>.<span class="variable">_</span>); <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'indent'</span>); <span class="keyword">while</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> !== <span class="string">'outdent'</span>) { <span class="variable">buf</span>.<span class="variable">push</span>(<span class="this">this</span>.<span class="variable">parseExpr</span>()); } <span class="this">this</span>.<span class="variable">expect</span>(<span class="string">'outdent'</span>); <span class="keyword">return</span> <span class="variable">buf</span>.<span class="variable">join</span>(<span class="string">'\n'</span>); },</code></pre> </td> </tr> <tr class="code"> <td class="docs"> <p>tag (attrs | class | id)* text? (code | block) </p> </td> <td class="code"> <pre><code><span class="variable">parseTag</span>: <span class="keyword">function</span>(){ <span class="keyword">var</span> <span class="variable">name</span> = <span class="this">this</span>.<span class="variable">advance</span>.<span class="variable">val</span>, <span class="variable">html5</span> = <span class="this">this</span>.<span class="variable">mode</span> === <span class="string">'html 5'</span>, <span class="variable">hasAttrs</span> = <span class="variable">false</span>, <span class="variable">attrBuf</span> = <span class="string">''</span>, <span class="variable">codeClass</span> = <span class="string">''</span>, <span class="variable">classes</span> = [], <span class="variable">attrs</span> = {}, <span class="variable">buf</span> = []; <span class="comment">// (attrs | class | id)*</span> <span class="variable">out</span>: <span class="keyword">while</span> (<span class="number integer">1</span>) { <span class="keyword">switch</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span>) { <span class="keyword">case</span> <span class="string">'id'</span>: <span class="variable">hasAttrs</span> = <span class="variable">true</span>; <span class="variable">attrs</span>.<span class="variable">id</span> = <span class="string">'&quot;'</span> + <span class="this">this</span>.<span class="variable">advance</span>.<span class="variable">val</span> + <span class="string">'&quot;'</span>; <span class="keyword">continue</span>; <span class="keyword">case</span> <span class="string">'class'</span>: <span class="variable">hasAttrs</span> = <span class="variable">true</span>; <span class="variable">classes</span>.<span class="variable">push</span>(<span class="this">this</span>.<span class="variable">advance</span>.<span class="variable">val</span>); <span class="keyword">continue</span>; <span class="keyword">case</span> <span class="string">'attrs'</span>: <span class="variable">hasAttrs</span> = <span class="variable">true</span>; <span class="keyword">var</span> <span class="variable">obj</span> = <span class="this">this</span>.<span class="variable">advance</span>.<span class="variable">attrs</span>, <span class="variable">keys</span> = <span class="class">Object</span>.<span class="variable">keys</span>(<span class="variable">obj</span>); <span class="keyword">for</span> (<span class="keyword">var</span> <span class="variable">i</span> = <span class="number integer">0</span>, <span class="variable">len</span> = <span class="variable">keys</span>.<span class="variable">length</span>; <span class="variable">i</span> &<span class="variable">lt</span>; <span class="variable">len</span>; ++<span class="variable">i</span>) { <span class="keyword">var</span> <span class="variable">key</span> = <span class="variable">keys</span>[<span class="variable">i</span>], <span class="variable">val</span> = <span class="variable">obj</span>[<span class="variable">key</span>]; <span class="keyword">if</span> (<span class="variable">key</span> === <span class="string">'class'</span>) { <span class="variable">codeClass</span> = <span class="variable">val</span>; } <span class="keyword">else</span> { <span class="variable">attrs</span>[<span class="variable">key</span>] = <span class="variable">val</span> === <span class="variable">undefined</span> ? <span class="variable">true</span> : <span class="variable">val</span>; <span class="variable">attrs</span>.<span class="variable">html5</span> = <span class="variable">html5</span>; } } <span class="keyword">continue</span>; <span class="keyword">default</span>: <span class="keyword">break</span> <span class="variable">out</span>; } } <span class="comment">// text?</span> <span class="keyword">if</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span> === <span class="string">'text'</span>) { <span class="variable">buf</span>.<span class="variable">push</span>(&<span class="variable">quot</span>;<span class="variable">buf</span>.<span class="variable">push</span>(<span class="string">'&quot; + interpolate(this.advance.val.replace(/^ */, '</span><span class="string">').replace(/'</span>/<span class="variable">g</span>, &<span class="variable">quot</span>;\\<span class="string">'&quot;)) + &quot;'</span>);&<span class="variable">quot</span>;); } <span class="comment">// (code | block)</span> <span class="keyword">switch</span> (<span class="this">this</span>.<span class="variable">peek</span>.<span class="variable">type</span>) { <span class="keyword">case</span> <span class="string">'code'</span>: <span class="keyword">var</span> <span class="variable">tok</span> = <span class="this">this</span>.<span class="variable">advance</span>; <span class="keyword">if</span> (<span class="variable">tok</span>.<span class="variable">buffer</span>) { <span class="variable">buf</span>.<span class="variable">push</span>(<span class="string">'buf.push('</span> + (<span class="variable">tok</span>.<span class="variable">escape</span> ? <span class="string">'escape('</span> + <span class="variable">tok</span>.<span class="variable">val</span> + <span class="string">')'</span> : <span class="variable">tok</span>.<span class="variable">val</span>) + <span class="string">');'</span>); } <span class="keyword">else</span> { <span class="variable">buf</span>.<span class="variable">push</span>(<span class="variable">tok</span>.<span class="variable">val</span> + <span class="string">';'</span>); } <span class="keyword">break</span>; <span class="keyword">case</span> <span class="string">'indent'</span>: <span class="variable">buf</span>.<span class="variable">push</span>(<span class="this">this</span>.<span class="variable">parseBlock</span>()); <span class="keyword">break</span>; } <span class="comment">// Build attrs</span> <span class="keyword">if</span> (<span class="variable">hasAttrs</span>) { <span class="comment">// Classes</span> <span class="keyword">if</span> (<span class="variable">classes</span>.<span class="variable">length</span>) { <span class="variable">attrs</span>[<span class="string">'class'</span>] = <span class="string">'&quot;'</span> + <span class="variable">classes</span>.<span class="variable">join</span>(<span class="string">' '</span>) + <span class="string">'&quot;'</span>; } <span class="keyword">if</span> (<span class="variable">codeClass</span>) { <span class="keyword">if</span> (<span class="variable">attrs</span>[<span class="string">'class'</span>]) { <span class="variable">attrs</span>[<span class="string">'class'</span>] += <span class="string">' + &quot; &quot; + ('</span> + <span class="variable">codeClass</span> + <span class="string">')'</span>; } <span class="keyword">else</span> { <span class="variable">attrs</span>[<span class="string">'class'</span>] = <span class="variable">codeClass</span>; } } <span class="comment">// Attributes</span> <span class="variable">attrBuf</span> += &<span class="variable">quot</span>;' + <span class="variable">attrs</span>({ &<span class="variable">quot</span>;; <span class="keyword">var</span> <span class="variable">keys</span> = <span class="class">Object</span>.<span class="variable">keys</span>(<span class="variable">attrs</span>); <span class="keyword">for</span> (<span class="keyword">var</span> <span class="variable">i</span> = <span class="number integer">0</span>, <span class="variable">len</span> = <span class="variable">keys</span>.<span class="variable">length</span>; <span class="variable">i</span> &<span class="variable">lt</span>; <span class="variable">len</span>; ++<span class="variable">i</span>) { <span class="keyword">var</span> <span class="variable">key</span> = <span class="variable">keys</span>[<span class="variable">i</span>], <span class="variable">val</span> = <span class="variable">attrs</span>[<span class="variable">key</span>]; <span class="variable">attrBuf</span> += &<span class="variable">quot</span>;<span class="string">'&quot; + key + &quot;'</span>: &<span class="variable">quot</span>; + <span class="variable">val</span> + (<span class="variable">i</span> === <span class="variable">len</span> - <span class="number integer">1</span> ? <span c