<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged syntax</title>
    <link href="https://passingcuriosity.com/tags/syntax/syntax.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/syntax/syntax.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2009-03-11T00:00:00Z</updated>
    <entry>
    <title>Dynamic tags, fake arguments, and AST mangling in SPIP</title>
    <link href="https://passingcuriosity.com/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/" />
    <id>https://passingcuriosity.com/2009/dynamic-tags-fake-arguments-ast-mangling-in-spip/</id>
    <published>2009-03-11T00:00:00Z</published>
    <updated>2009-03-11T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>One occasion in which <a href="/2009/creating-custom-tags-spip-dynamic/">SPIP’s dynamic tag
facilities</a> is a little lacking is
when you need to access details of the AST – perhaps the name of the template
file, perhaps something else – to generate your content. In this post I’ll
describe the obvious (but wrong) approach to passing values into a dynamic tag
and another technique that actually works.</p>
<p>You should know about the <a href="http://www.spip.net/">SPIP</a>, its <a href="/2008/spip-template-languag/">template
language</a>, <a href="/2008/creating-custom-tags-spip-static/">static
tags</a>, <a href="/2009/creating-custom-tags-spip-dynamic/">dynamic
tags</a> and be comfortable with
<a href="http://www.php.net/">PHP</a> before reading this article.</p>
<p>Unlike static tags – which are implemented by a single function – dynamic
tags are comprised of a set of three functions (in a magically named file)
which are called by the SPIP engine as appropriate. This first of these three
functions (identical to the single function of static tags) is called
something like <code>balise_FOO()</code> and is responsible asking SPIP to call the other
two functions: <code>balise_FOO_stat()</code> – which performs whatever static
calculations are required – and <code>balise_FOO_dyn()</code> which performs the dynamic
calculations and display the final content to the user.</p>
<p>An example might make this more clearer. Suppose I’m creating a <code>#HITS</code> tag to
output the number of hits an article has received. My <code>balise_HITS</code> function
arranges for SPIP to call the <code>balise_HITS_*</code> functions like so:</p>
<ol type="1">
<li><p>It calls <code>balise_HITS_stat</code> to determine the static parameters for the tag
(e.g. “id_article=36”).</p></li>
<li><p>It arranges to call <code>balise_HITS_dyn</code>, passing it the static parameters as
determined by <code>balise_HITS_stat</code>.</p></li>
<li><p><code>balise_HITS_dyn</code> uses the static parameters to query the database, etc.
and produces the appropriate output.</p></li>
</ol>
<p>The code to implement the <code>#HITS</code> tag might look like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HITS(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="op">=</span><span class="st">'HITS'</span>) {</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="va">$args</span> <span class="op">=</span> <span class="dt">array</span>(<span class="st">'id_article'</span>)<span class="ot">;</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> calculer_balise_dynamique(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="ot">,</span> <span class="va">$args</span>)<span class="ot">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HITS_stat(<span class="va">$args</span><span class="ot">,</span> <span class="va">$filters</span>) {</span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dt">array</span>(<span class="va">$args</span>[<span class="dv">0</span>])<span class="ot">;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>}</span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_HITS_dyn(<span class="va">$id_article</span>) {</span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="va">$now</span> <span class="op">=</span> <span class="fu">date</span>(<span class="st">'c'</span>)<span class="ot">;</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="st">&quot;Article </span><span class="va">$id_article</span><span class="st"> has had 1,000,000 hits as of </span><span class="va">$now</span><span class="st">!&quot;</span><span class="ot">;</span></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>One way this can fall down is if I want to access details of, for example, the
SPIP templates in determining my static parameters. By the time I’m
determining the parameters, I no longer have access to the abstract-syntax
tree node passed to <code>balise_FOO</code>. All I’ve got at this point, is an array of
arguments to the tag and an array of filters applied to the tag.</p>
<h3 id="the-obvious-solution">The obvious solution</h3>
<p>The obvious solution is to add the value to the “<code>$args</code>” array I pass to
<code>calculer_balise_dynamique()</code>. Alas, this will not work as <code>$args</code> is not (in
spite of its usual name) an array of arguments. It is, in fact, an array of
the names of arguments which SPIP is to automatically fetch and pass on the
the <code>balise_*_stat()</code> call. Appending the name of the template file
(<code>"squelettes/foo.html"</code>, for instance) to <code>$args</code> tells SPIP to look for a
variable called <code>squelettes/foo.html</code> in the context the tag is being used and
pass it through to the next function. Needless to say, this doesn’t work.</p>
<h3 id="the-correct-solution">The correct solution</h3>
<p>The correct solution to this problem is to arrange for SPIP to add the values
you want to the <code>$arguments</code> array (or perhaps the <code>$filters</code> array, but this
may not be a good idea). This array contains the values I requested in the
call to <code>calculer_balise_dynamique</code> along with the values of the parameters
passed into the tag in the template. If I can’t use the former route, then
it’ll have to be the second – I’ll need to add a another “fake” parameter to
the AST node before I call <code>calculer_balise_dynamique</code>. (Yes, I agree. This is
a rather odd way to accomplish my goal, but that’s how it goes in SPIP-land).</p>
<p>There are two parts of the SPIP AST that are relevant here: the <code>Champ</code> nodes
that represent tags, and the <code>Texte</code> nodes the represent “strings” (amongst
other things). The <code>$p</code> that is passed to my <code>balise_*</code> functions is an
instance of the <code>Champ</code> class and I’m going to add a new instance of the
<code>Texte</code> class representing my new “fake” parameter. Creating the new object is
pretty simple, just construct it and set it’s <code>type</code> and <code>texte</code> members. The
following example adds a new parameter containing the name of the template
file:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode php"><code class="sourceCode php"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="kw">function</span> balise_TEMPLATE(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="op">=</span><span class="st">'TEMPLATE'</span>) {</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="va">$file</span> <span class="op">=</span> <span class="va">$p</span>-&gt;descr[<span class="st">'sourcefile'</span>]<span class="ot">;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Create the new object</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    <span class="va">$t</span> <span class="op">=</span> <span class="kw">new</span> Texte<span class="ot">;</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    <span class="va">$t</span>-&gt;type <span class="op">=</span> <span class="st">'texte'</span><span class="ot">;</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="va">$t</span>-&gt;texte <span class="op">=</span> <span class="va">$file</span><span class="ot">;</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Make sure that $p-param is an array (of the right dimensions)</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> (<span class="op">!</span> <span class="fu">is_array</span>(<span class="va">$p</span>-&gt;param) ) {</span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>        <span class="va">$p</span>-&gt;param <span class="op">=</span> <span class="dt">array</span>(<span class="dt">array</span>(<span class="dv">0</span>=&gt;<span class="kw">NULL</span>))<span class="ot">;</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    }</span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Append the object to the tag parameters</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="va">$p</span>-&gt;param[<span class="dv">0</span>][] <span class="op">=</span> <span class="dt">array</span>(<span class="va">$t</span>)<span class="ot">;</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Call SPIP's dynamic tags code</span></span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>    <span class="va">$args</span> <span class="op">=</span> <span class="dt">array</span>()<span class="ot">;</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> calculer_balise_dynamique(<span class="va">$p</span><span class="ot">,</span> <span class="va">$nom</span><span class="ot">,</span> <span class="va">$args</span>)<span class="ot">;</span></span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>}</span></code></pre></div>
<p>First the previous code gets the name of the template file from the AST node
for the tag being processed. Then it creates a new <code>Texte</code> object with the
filename as its value. It ensures that the <code>$p-&gt;param</code> member of the <code>Champ</code>
object is an array (and yes, it <em>does</em> seem to start with a <code>NULL</code> so that we
can pretend that the arrays are 1-indexed) and then appends the new object to
it. All that’s left is to call <code>calculer_balise_dynamique</code> as usual.</p>
<p>With this done, the value of the new “fake” parameter will be evaluated and
passed to the <code>balise_TEMPLATE_stat()</code> call in the <code>$args</code> array and then (if
I choose) passed on to the <code>balise_TEMPLATE_dyn()</code> call.</p>
<h3 id="conclusion">Conclusion</h3>
<p>This technique still strikes me as a bit odd, but it’s the only way I can see
to implement this effect without introducing global variables. In my opinion,
<code>calculer_balise_dynamique</code> should take an array of argument values as an
optional fourth argument, but needing to do this sort of thing is probably
fairly rare (though I have seen it in the code for one or two built-in tags).
Even if this technique is the “Right Way(TM)” to pass extra values around,
then it really does need a helper function like <code>interprete_argument_balise</code>
instead of mucking around with AST internals in every tag that need it.</p>]]></summary>
</entry>
<entry>
    <title>Literate Haskell with Markdown and Syntax Highlighting</title>
    <link href="https://passingcuriosity.com/2008/literate-haskell-with-markdown-syntax-hightlighting/" />
    <id>https://passingcuriosity.com/2008/literate-haskell-with-markdown-syntax-hightlighting/</id>
    <published>2008-12-08T00:00:00Z</published>
    <updated>2008-12-08T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>There are two schools of thought when it comes to documenting programs and
libraries: some embed fragments of code within the documentation (so called
“<em>literate</em> programming”) and others embed fragments of documentation in their
code (i.e. comments). The “comments” approach makes it easy to generate API
documentation and the like (a feature <a href="http://haskell.org/haddock/" title="Haddock: A Haskell Documentation Tool">built-in to Haskell’s Hackage
system</a>) but help me write blog posts and other documents containing
code, which is where literate programming shines. Happily, Haskell supports
both of these approaches and has a few rather useful tools available to make
both easier. In this post, I’ll describe how to take literate Haskell with
Markdown formatted text and produce syntax highlighted documents in HTML and
PDF.</p>
<p>The basic idea of literate programming is that my document is a sequence of
code “chunks” and documentation “chunks”. Haskell tools can ignore the
documentation chunks when compiling the code and documentation tools can
ignore or, hopefully, prettyify the code when preparing the document for
publishing. The <a href="http://www.haskell.org/onlinereport/literate.html" title="Haskell 98 Report -- 9.6 Literate comments">Haskell 98 report</a> describes two ways to denote
code chunks in a literate Haskell file: the TeX way and with “Bird tracks”. In
the TeX way, each block of code is wrapped with TeX macros:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode latex"><code class="sourceCode latex"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="kw">\begin</span>{<span class="ex">code</span>}</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>-- Some Haskell</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="kw">\end</span>{<span class="ex">code</span>}</span></code></pre></div>
<p>whereas with “Bird tracks” each code line begins with a <code>&gt;</code>:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode literatehaskell"><code class="sourceCode literatehaskell"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="ot">&gt;</span> <span class="co">-- Some Haskell</span></span></code></pre></div>
<p>TeX style code chunks are excellent when my document is a TeX (common for
academic papers), and “Bird tracks” are more convenient when I’m writing
pretty much anything else (such as blog posts).</p>
<p><a href="http://daringfireball.net/projects/markdown/syntax">Markdown</a> is a simple plain text syntax created by <a href="http://daringfireball.com/">John
Gruber</a> designed to resemble the conventions of
e-mail so the “Bird tracks” style of literate Haskell is a good fit. It’s
reasonably simply to learn so I won’t bother to say any more about Markdown
itself.</p>
<p>Once I’ve got some literate Haskell all documented in Markdown I’m ready to
produce a document. The first step is to add syntax highlighting to the code
chunks using <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hscolour" title="The hscolour package on Hackage">hscolour</a>. <code>hscolour</code> can generate its output in several
formats, but we’ll use HTML with CSS styles. I’m a UNIX person, so I usually
use <code>hscolour</code> as a filter:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a>    <span class="fu">cat</span> blah.lhs <span class="kw">|</span> <span class="ex">hscolour</span> <span class="at">-lit</span> <span class="at">-css</span> <span class="op">&gt;</span> blah.mkd</span></code></pre></div>
<p>This pipeline takes <code>blah.lhs</code>, performs syntax highlighting on it
(interpreting it as literate Haskell), generates HTML for use with CSS and
stores the result in <code>blah.mkd</code>. I’ve now got a file with with literate chunks
untouched (they’re still Markdown) and the code chunks converted into HTML.
The next step is to convert this Markdown+HTML file into “pure” HTML for
publishing.</p>
<p>There are a few ways to convert Markdown into HTML: use the <a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/pandoc" title="The Pandoc package on Hackage">pandoc</a> Haskell
program, use the original
<a href="http://daringfireball.net/projects/markdown/"><code>markdown</code></a> perl program, rely
on your blogging software (many packages support <a href="http://michelf.com/projects/php-markdown/">PHP
Markdown</a>), etc. <code>pandoc</code> is a
Haskell program, very fast, and can generate more than just HTML output, so I
use it quite a bit. Again, I tend to use <code>pandoc</code> as a filter:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>    <span class="fu">cat</span> blah.mkd <span class="kw">|</span> <span class="ex">pandoc</span> <span class="at">-sS</span> <span class="at">--no-wrap</span> <span class="at">-c</span> hscolour.css <span class="op">&gt;</span> blah.html</span></code></pre></div>
<p>This pipeline takes <code>blah.mkd</code>, translates it from Markdown to HTML (both
options are the implicit defaults) and puts the result into <code>blah.html</code>. It
also uses fancy typography (<code>-S</code>), creates a complete document (‘-s’),
includes a link to the <code>hscolour.css</code> stylesheet, and does <em>not</em> wrap the
code. This last point is essential if the document contains <code>hscolour</code> output
– if it <em>does</em> wrap the code, then the highlighted Haskell code will be
displayed incorrectly.</p>
<p>I often combine both steps into a single pipeline:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> blah.lhs <span class="kw">|</span> <span class="ex">hscolour</span> <span class="at">-lit</span> <span class="at">-css</span> <span class="kw">|</span> <span class="ex">pandoc</span> <span class="at">--no-wrap</span> <span class="at">-sS</span> <span class="at">-c</span> hscolour.css <span class="dt">\</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> blah.html</span></code></pre></div>
<p>Generating a PDF by way of LaTeX is simple – just change the output format
for both <code>hscolour</code> and <code>pandoc</code>:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">cat</span> blah.lhs <span class="kw">|</span> <span class="ex">hscolour</span> <span class="at">-lit</span> <span class="at">-latex</span> <span class="kw">|</span> <span class="ex">pandoc</span> <span class="at">--no-wrap</span> <span class="at">-sS</span> <span class="at">-t</span> latex <span class="dt">\</span></span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true" tabindex="-1"></a><span class="op">&gt;</span> blah.tex</span></code></pre></div>
<p>and then do whatever you normally do to get a PDF:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="ex">pdflatex</span> blah.tex <span class="kw">&amp;&amp;</span> <span class="ex">pdflatex</span> blah.tex <span class="kw">&amp;&amp;</span> <span class="ex">pdflatex</span> blah.tex </span></code></pre></div>
<p>But I usually cram all of this into a <code>Makefile</code>:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode makefile"><code class="sourceCode makefile"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="ot">.SUFFIXES:</span><span class="dt"> .lhs .mkd .html .tex .pdf</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a><span class="dt">PANDOC</span> <span class="ch">:=</span><span class="st"> pandoc --no-wrap -sS</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="dt">HSCOLOUR</span> <span class="ch">:=</span><span class="st"> hscolour -lit</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a><span class="ot">.lhs.mkd:</span></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="er">    </span>cat <span class="ch">$&lt;</span> | <span class="ch">$(</span><span class="dt">HSCOLOUR</span><span class="ch">)</span> -css &gt; <span class="ch">$@</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a><span class="ot">.lhs.html:</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a><span class="er">    </span>cat <span class="ch">$&lt;</span> | <span class="ch">$(</span><span class="dt">HSCOLOUR</span><span class="ch">)</span> -css | <span class="ch">$(</span><span class="dt">PANDOC</span><span class="ch">)</span> -t html -c hscolour.css &gt; <span class="ch">$@</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a><span class="ot">.lhs.tex:</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a><span class="er">    </span>cat <span class="ch">$&lt;</span> | <span class="ch">$(</span><span class="dt">HSCOLOUR</span><span class="ch">)</span> -latex | <span class="ch">$(</span><span class="dt">PANDOC</span><span class="ch">)</span> -t latex&gt; <span class="ch">$@</span></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a><span class="ot">.tex.pdf:</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true" tabindex="-1"></a><span class="er">    </span>pdflatex <span class="ch">$&lt;</span> &amp;&amp; pdflatex <span class="ch">$&lt;</span> &amp;&amp; pdflatex <span class="ch">$&lt;</span></span></code></pre></div>
<p>And call <code>make</code> to sort it all out for me:</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> blah.html</span></code></pre></div>]]></summary>
</entry>

</feed>
