Thicket data repository for the EEG
1{
2 "id": "https://mort.io/blog/just-latex/",
3 "title": "`just` LaTeX it!",
4 "link": "https://mort.io/blog/just-latex/",
5 "updated": "2025-01-18T00:00:00",
6 "published": "2025-01-18T00:00:00",
7 "summary": "<p>I have recently become a fan of <a href=\"https://just.systems/\"><code>just</code></a> as a replacement for the venerable\n<a href=\"https://www.gnu.org/software/make/manual/make.html\"><code>make</code></a>. I find that nowadays I rarely need the built-in dependency rules\nthat <a href=\"https://www.gnu.org/software/make/manual/make.html\"><code>make</code></a> provides. Perhaps more radically, I also rarely need to write my\nown as the prevelance of format-specific build tools such as <a href=\"https://doc.rust-lang.org/stable/cargo/\"><code>cargo</code></a>,\n<a href=\"https://docs.astral.sh/uv/\"><code>uv</code></a>, <a href=\"https://ctan.org/pkg/latexmk/\"><code>latexmk</code></a> and the like mean I don’t need to write my own either.</p>\n<p>Recently, while writing references and then helping out get submissions for\n<a href=\"https://www.cl.cam.ac.uk/events/rossfest/\">Rossfest</a> consistently formatted and building cleanly, I found myself\nextending my various <a href=\"https://just.systems/\"><code>just</code></a> targets for <a href=\"https://www.latex-project.org/\">LaTeX</a>. So I thought I’d document\nthem here.</p>\n<p>I always begin my <code>Justfile</code> with the apparently idiomatic “just show me the\ntargets and associated help text” target:</p>\n<pre><code><span><span><span>_default</span></span>:\n</span><span> <span>@</span>just --list\n</span></code></pre>\n<p>This seems considerably easier – and more powerful – than the equivalent hack\nI used to use in a <code>Makefile</code>!</p>\n<pre><code><span><span><span>.DEFAULT</span></span><span>:</span> <span><span>help</span></span><span>\n</span></span><span><span></span>\n</span><span><span><span>.PHONY</span></span><span>:</span> <span><span>help</span></span><span>\n</span></span><span><span></span><span><span>help</span></span><span>:</span>\n<span></span><span></span></span><span><span></span><span>\t<span>@</span><span><span><span>echo</span></span><span> <span><span>"</span>Targets are:<span>"</span></span></span></span>\n</span></span><span><span>\t<span>@</span><span><span><span>grep</span></span><span><span><span> -</span>E</span> <span><span>'</span>^(^## |[^.#][ a-zA-Z0-9-]+:.*#)<span>'</span></span> Makefile <span>\\\n</span></span></span></span></span><span><span><span><span></span>\t<span>|</span> <span><span>sed</span></span><span><span><span> -</span>E</span> <span><span>'</span>s/:[[:print:]]+#/:/;s/^([^#])/-- <span>\\1</span>/<span>'</span></span></span></span>\n</span></span></code></pre>\n<p>Next setup up some useful variables: the command we’ll use (<code>latex</code>) plus\nsources (<code>texs</code>) and targets (<code>pdfs</code>), and droppings that might be produced but\nnot cleaned up by <code>latexmk -[cC]</code>:</p>\n<pre><code><span><span>latex</span> <span>:=</span> <span><span>"</span>latexmk -pdf<span>"</span></span>\n</span><span>\n</span><span><span>texs</span> <span>:=</span> <span><span><span>`</span>echo [0-9][0-9]-*.tex<span>`</span></span></span>\n</span><span><span>pdfs</span> <span>:=</span> <span><span>replace</span></span><span><span>(</span><span>texs</span><span>,</span> <span><span>'</span>.tex<span>'</span></span><span>,</span> <span><span>'</span>.pdf<span>'</span></span><span>)</span></span>\n</span><span><span>droppings</span> <span>:=</span> <span><span>"</span>$f.nav $f.snm $f.bbl<span>"</span></span>\n</span></code></pre>\n<p>Now to actually building and cleaning things; first, individual targets:</p>\n<pre><code><span><span><span># </span>build a PDF</span>\n</span><span><span><span>pdf</span></span> tgt:\n</span><span> <span><span>{{</span><span>latex</span><span>}}</span></span> <span><span>{{</span><span><span>file_stem</span></span><span><span>(</span><span>tgt</span><span>)</span></span><span>}}</span></span>.tex\n</span><span>\n</span><span><span><span># </span>clean generated files</span>\n</span><span><span><span>clean</span></span> tgt:\n</span><span> <span><span>{{</span><span>latex</span><span>}}</span></span> -C <span><span>{{</span><span><span>file_stem</span></span><span><span>(</span><span>tgt</span><span>)</span></span><span>}}</span></span>.tex\n</span><span> for f in <span><span>{{</span><span><span>file_stem</span></span><span><span>(</span><span>tgt</span><span>)</span></span><span>}}</span></span>; do rm -f <span><span>{{</span><span>droppings</span><span>}}</span></span> ; done\n</span></code></pre>\n<p>(Yes, ok, so it seems a bit silly to have to wrap a <code>for</code> loop around simply to\npropagate a variable from the <code>Justfile</code> into the shell. But no matter.)</p>\n<p>Next, all available targets:</p>\n<pre><code><span><span><span># </span>build all PDFs</span>\n</span><span><span><span>pdfs</span></span>:\n</span><span> for f in <span><span>{{</span><span>texs</span><span>}}</span></span>; do just pdf $f ; done\n</span><span>\n</span><span><span><span># </span>clean all PDFs</span>\n</span><span><span><span>clean-pdfs</span></span>:\n</span><span> for f in <span><span>{{</span><span>pdfs</span><span>}}</span></span>; do just clean $f ; done\n</span></code></pre>\n<p>Finally, <em>watch</em> a target, rebuilding on save – it may be helpful therefore to\navoid automatically saving the source while in a state in which it will not\nsuccessfully build!</p>\n<pre><code><span><span><span># </span>watch a file, rebuilding when saved</span>\n</span><span><span><span>watch</span></span> tgt:\n</span><span> while inotifywait -e close_write <span><span>{{</span><span>tgt</span><span>}}</span></span>* ; do just pdf <span><span>{{</span><span>tgt</span><span>}}</span></span> ; done\n</span></code></pre>",
8 "content": "<p>I have recently become a fan of <a href=\"https://just.systems/\"><code>just</code></a> as a replacement for the venerable\n<a href=\"https://www.gnu.org/software/make/manual/make.html\"><code>make</code></a>. I find that nowadays I rarely need the built-in dependency rules\nthat <a href=\"https://www.gnu.org/software/make/manual/make.html\"><code>make</code></a> provides. Perhaps more radically, I also rarely need to write my\nown as the prevelance of format-specific build tools such as <a href=\"https://doc.rust-lang.org/stable/cargo/\"><code>cargo</code></a>,\n<a href=\"https://docs.astral.sh/uv/\"><code>uv</code></a>, <a href=\"https://ctan.org/pkg/latexmk/\"><code>latexmk</code></a> and the like mean I don’t need to write my own either.</p>\n<p>Recently, while writing references and then helping out get submissions for\n<a href=\"https://www.cl.cam.ac.uk/events/rossfest/\">Rossfest</a> consistently formatted and building cleanly, I found myself\nextending my various <a href=\"https://just.systems/\"><code>just</code></a> targets for <a href=\"https://www.latex-project.org/\">LaTeX</a>. So I thought I’d document\nthem here.</p>\n<p>I always begin my <code>Justfile</code> with the apparently idiomatic “just show me the\ntargets and associated help text” target:</p>\n<pre><code><span><span><span>_default</span></span>:\n</span><span> <span>@</span>just --list\n</span></code></pre>\n<p>This seems considerably easier – and more powerful – than the equivalent hack\nI used to use in a <code>Makefile</code>!</p>\n<pre><code><span><span><span>.DEFAULT</span></span><span>:</span> <span><span>help</span></span><span>\n</span></span><span><span></span>\n</span><span><span><span>.PHONY</span></span><span>:</span> <span><span>help</span></span><span>\n</span></span><span><span></span><span><span>help</span></span><span>:</span>\n<span></span><span></span></span><span><span></span><span>\t<span>@</span><span><span><span>echo</span></span><span> <span><span>"</span>Targets are:<span>"</span></span></span></span>\n</span></span><span><span>\t<span>@</span><span><span><span>grep</span></span><span><span><span> -</span>E</span> <span><span>'</span>^(^## |[^.#][ a-zA-Z0-9-]+:.*#)<span>'</span></span> Makefile <span>\\\n</span></span></span></span></span><span><span><span><span></span>\t<span>|</span> <span><span>sed</span></span><span><span><span> -</span>E</span> <span><span>'</span>s/:[[:print:]]+#/:/;s/^([^#])/-- <span>\\1</span>/<span>'</span></span></span></span>\n</span></span></code></pre>\n<p>Next setup up some useful variables: the command we’ll use (<code>latex</code>) plus\nsources (<code>texs</code>) and targets (<code>pdfs</code>), and droppings that might be produced but\nnot cleaned up by <code>latexmk -[cC]</code>:</p>\n<pre><code><span><span>latex</span> <span>:=</span> <span><span>"</span>latexmk -pdf<span>"</span></span>\n</span><span>\n</span><span><span>texs</span> <span>:=</span> <span><span><span>`</span>echo [0-9][0-9]-*.tex<span>`</span></span></span>\n</span><span><span>pdfs</span> <span>:=</span> <span><span>replace</span></span><span><span>(</span><span>texs</span><span>,</span> <span><span>'</span>.tex<span>'</span></span><span>,</span> <span><span>'</span>.pdf<span>'</span></span><span>)</span></span>\n</span><span><span>droppings</span> <span>:=</span> <span><span>"</span>$f.nav $f.snm $f.bbl<span>"</span></span>\n</span></code></pre>\n<p>Now to actually building and cleaning things; first, individual targets:</p>\n<pre><code><span><span><span># </span>build a PDF</span>\n</span><span><span><span>pdf</span></span> tgt:\n</span><span> <span><span>{{</span><span>latex</span><span>}}</span></span> <span><span>{{</span><span><span>file_stem</span></span><span><span>(</span><span>tgt</span><span>)</span></span><span>}}</span></span>.tex\n</span><span>\n</span><span><span><span># </span>clean generated files</span>\n</span><span><span><span>clean</span></span> tgt:\n</span><span> <span><span>{{</span><span>latex</span><span>}}</span></span> -C <span><span>{{</span><span><span>file_stem</span></span><span><span>(</span><span>tgt</span><span>)</span></span><span>}}</span></span>.tex\n</span><span> for f in <span><span>{{</span><span><span>file_stem</span></span><span><span>(</span><span>tgt</span><span>)</span></span><span>}}</span></span>; do rm -f <span><span>{{</span><span>droppings</span><span>}}</span></span> ; done\n</span></code></pre>\n<p>(Yes, ok, so it seems a bit silly to have to wrap a <code>for</code> loop around simply to\npropagate a variable from the <code>Justfile</code> into the shell. But no matter.)</p>\n<p>Next, all available targets:</p>\n<pre><code><span><span><span># </span>build all PDFs</span>\n</span><span><span><span>pdfs</span></span>:\n</span><span> for f in <span><span>{{</span><span>texs</span><span>}}</span></span>; do just pdf $f ; done\n</span><span>\n</span><span><span><span># </span>clean all PDFs</span>\n</span><span><span><span>clean-pdfs</span></span>:\n</span><span> for f in <span><span>{{</span><span>pdfs</span><span>}}</span></span>; do just clean $f ; done\n</span></code></pre>\n<p>Finally, <em>watch</em> a target, rebuilding on save – it may be helpful therefore to\navoid automatically saving the source while in a state in which it will not\nsuccessfully build!</p>\n<pre><code><span><span><span># </span>watch a file, rebuilding when saved</span>\n</span><span><span><span>watch</span></span> tgt:\n</span><span> while inotifywait -e close_write <span><span>{{</span><span>tgt</span><span>}}</span></span>* ; do just pdf <span><span>{{</span><span>tgt</span><span>}}</span></span> ; done\n</span></code></pre>",
9 "content_type": "html",
10 "author": {
11 "name": "Unknown",
12 "email": null,
13 "uri": null
14 },
15 "categories": [],
16 "source": "https://mort.io/atom.xml"
17}