<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[cons-trained]]></title>
<description><![CDATA[cons-trained]]></description>
<link>https://iki.fi/newcup/cons-trained/</link>
<lastBuildDate>Tue, 09 Feb 2021 21:09:05 +0200</lastBuildDate>
<item>
  <title><![CDATA[Neat, simple VCS friendly images]]></title>
  <description><![CDATA[
<p>
Sometimes a picture says a thousand words. In software documentation
maybe even ten times that. And even a thousand words can be an
impenetrable wall for software collaborators to comprehend correctly,
and in software details truly matter. Hence, pictures are invaluable!
</p>

<p>
But how to explain your project with pictures? You detest the idea of
adding binary images to your pristine git repository. They're also
difficult to modify or to diff. How about a diagram drawing tool?
Will all your collaborators have access to it?
</p>

<p>
I've been wrestling with this problem for a long time but now think
I'm closer to a solution: <a href="https://en.wikipedia.org/wiki/PIC_(markup_language)">pic language</a>! It's been around from since
1982, but I've completely missed it.<sup><a id="fnr.1" class="footref" href="#fn.1">1</a></sup>
</p>

<div id="outline-container-org1b5e6f8" class="outline-3">
<h3 id="org1b5e6f8">Pros</h3>
<div class="outline-text-3" id="text-org1b5e6f8">
<ul class="org-ul">
<li>At least three implementations that are easy to install and have
a small footprint.</li>
<li>Fast to learn, in my opinion.</li>
<li>The language is from the 80s; probably will be supported in some
form for another couple of decades.</li>
<li>Has macros! (See <a href="#org7d78ee6">Cherry on top: macros!</a>)</li>
</ul>
</div>
</div>

<div id="outline-container-orga10d4bc" class="outline-3">
<h3 id="orga10d4bc">Cons</h3>
<div class="outline-text-3" id="text-orga10d4bc">
<ul class="org-ul">
<li>No GitHub or GitLab preview implementation (at the
moment). Preview exists for <a href="https://www.fossil-scm.org/home/doc/trunk/www/pikchr.md">Fossil</a>, though.</li>
</ul>
</div>
</div>

<div id="outline-container-org455ec7a" class="outline-2">
<h2 id="org455ec7a">Demo time!</h2>
<div class="outline-text-2" id="text-org455ec7a">

<figure>
<img src="./static/pic-preview-emacs.gif" alt="pic-preview-emacs.gif">

<figcaption><span class="figure-number">Figure 1: </span>Drawing a simple image interactively from within the editor</figcaption>
</figure>

<p>
I edit pic code saving after each step as I go. I've configured
Emacs to run a shell command to run pic conversion to <a href="https://en.wikipedia.org/wiki/Scalable_Vector_Graphics">SVG</a> file after
each save and to (re-)open the resulting SVG file.
</p>
</div>
</div>

<div id="outline-container-org14a5f02" class="outline-2">
<h2 id="org14a5f02">How to get started</h2>
<div class="outline-text-2" id="text-org14a5f02">
<ol class="org-ol">
<li>Install <code>pic2plot</code> (<code>apt install plotutils</code>).</li>
<li><p>
Write your pic code or take the snippet from below and save it
to <code>image.pic</code>.
</p>
<div class="org-src-container">
<pre class="src src-text">.PS
box "Lovely" "box!"
arrow
ellipse "Beautiful" "ellipse!"
spline down from last ellipse .s down left then to last box .s -&gt;
.PE
</pre>
</div></li>
<li>Run <code>pic2plot -T svg &lt; image.pic &gt; image.svg</code></li>
</ol>

<p>
And then add the pic-source to your git repository. And why not the
image as well until GitHub or GitLab add preview feature for pic
images — it's SVG, so it's almost fine, isn't it? Just tweak the
bounding box, width and height first.
</p>

<p>
I chose <code>pic2plot</code> as that was the first thing I found. If your
distro or OS doesn't come with <code>pic2plot</code>, there are other
implementations as well that your OS might have or you could compile
yourself:
</p>
<ul class="org-ul">
<li><a href="https://ece.uwaterloo.ca/~aplevich/dpic/">dpic</a> (<code>apt install dpic</code>). Run <code>dpic -v image.pic &gt; image.svg</code>.</li>
<li><a href="https://pikchr.org/home/doc/trunk/homepage.md">pikchr</a>: A new-ish implementation. There isn't yet an apt package
for it. It comes in a single C source file, seems easy to compile
(<code>gcc -DPIKCHR_SHELL -o pikchr pikchr.c -lm</code>). Definitely worth
checking out! Note that you need to drop the <code>.PS</code> and <code>.PE</code> troff
requests from <code>image.pic</code>. Run <code>pikchr --svg-only image.pic &gt;
    image.svg</code>.</li>
<li>GNU pic for translating pic to groff or TeX toolchain. The
downside of course is that you need groff or TeX toolchain
installed. Comes as a part of <a href="https://packages.debian.org/buster/groff">groff</a> toolchain in Debian at
least. Doesn't produce SVG, but PS or PDF. Run <code>pic image.pic |
    groff -T pdf &gt; image.pdf</code>.</li>
</ul>

<p>
The aforementioned implementations are worth checking out also
because <code>pic2plot</code> has no UTF-8 support (ISO-8859-1 works for what
it's worth). Dpic and pikchr can handle UTF-8 out of the box. I
guess groff as well after some setup.
</p>
</div>
</div>

<div id="outline-container-org93db987" class="outline-2">
<h2 id="org93db987">My Emacs demo setup</h2>
<div class="outline-text-2" id="text-org93db987">
<p>
This is a quick hack, but works for me.<sup><a id="fnr.2" class="footref" href="#fn.2">2</a></sup>
</p>

<div class="org-src-container">
<pre class="src src-elisp">(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">pic-name-as-svg</span> (pic-file-name)
  (concat (file-name-sans-extension pic-file-name) <span style="color: #8b2252;">".svg"</span>))

(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">pic-make-svg-of</span> (pic-file-name)
  (shell-command
     (format <span style="color: #8b2252;">"pic2plot -T svg &lt; %s &gt; %s"</span> pic-file-name
             (pic-name-as-svg pic-file-name))))

(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">pic-preview</span> (pic-file-name)
  (<span style="color: #a020f0;">save-selected-window</span>
    (<span style="color: #a020f0;">let*</span> ((svg-file-name (pic-name-as-svg pic-file-name))
           (revert-without-query
            (list (regexp-quote (abbreviate-file-name svg-file-name)))))
      (find-file-other-window (pic-name-as-svg pic-file-name) t))))

(<span style="color: #a020f0;">defun</span> <span style="color: #0000ff;">pic-after-save</span> ()
  (<span style="color: #a020f0;">let</span> ((pic-file-name (buffer-file-name)))
    (<span style="color: #a020f0;">when</span> (equalp (file-name-extension pic-file-name) <span style="color: #8b2252;">"pic"</span>)
      (pic-make-svg-of pic-file-name)
      (pic-preview pic-file-name))))

(add-hook 'after-save-hook #'pic-after-save)
</pre>
</div>

<p>
Your Emacs needs to have SVG preview capability
(<code>(image-type-available-p 'svg)</code> returns <code>t</code> — or just load an SVG
image with Emacs and see). I think most out of the box Emacsen
have. At least Debian Emacs does. You can change the output (the
<code>-T</code> option) to png, gif, ps etc. if they work better.
</p>

<p>
Depending on your Emacs window size, you might want to modify how
Emacs' <code>find-file-other-window</code> splits the window; see <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Choice.html">emacs manual</a>,
and particularly <code>split-height-threshold</code> and
<code>split-width-threshold</code> (which you can conveniently dynamically bind
with <code>let</code>, like <code>revert-without-query</code>, before calling
<code>find-file-other-window</code>).
</p>
</div>
</div>

<div id="outline-container-org67d9917" class="outline-2">
<h2 id="org67d9917">Other roughly comparable software</h2>
<div class="outline-text-2" id="text-org67d9917">
<p>
I've tried <a href="https://mermaid-js.github.io/mermaid/">Mermaid</a> for markdown-like image creation and <a href="http://ditaa.sourceforge.net/">ditaa</a>,
<a href="https://github.com/ivanceras/svgbob">svgbob</a> for converting ascii-art to diagrams.
</p>

<p>
Now, to me, Mermaid is more difficult to install for standalone use
(no apt package, brings down a bunch of node packages); doesn't
produce as slick output as pic; and isn't as flexible as pic.
</p>

<p>
The other tools convert ascii art to diagrams. To me they have a
couple of fundamental problems. First, no smooth curves, and
resolution (text positioning, text size) is defined by the character
grid. The other problem is that making changes to the ascii art,
e.g. moving everything a couple of characters down to make space for
a new box, is cumbersome even with e.g. Emacs artist mode. But in
general I really like svgbob's <i>laissez-faire</i> style!  See the
extravagant <a href="https://svgbob-editor.netlify.app/">demos</a>!
</p>

<p>
There's also <a href="https://graphviz.org/">graphviz</a> but it's best for visualizing graphs, not for
generic drawing.
</p>
</div>
</div>

<div id="outline-container-org7d78ee6" class="outline-2">
<h2 id="org7d78ee6">Cherry on top: macros!</h2>
<div class="outline-text-2" id="text-org7d78ee6">
<div class="org-src-container">
<pre class="src src-text">.PS
define actor {
  $1: box $2;
  ypos = last box .s.y - 0.5;
  move right 1 from last box .e;
}

define action {
  arrow from ($1.x, ypos) to ($2.x, ypos) $3;
  ypos = last arrow .end.y - 0.5;
}

define finish {
  line down from $1.s to ($1.x, ypos);
}

actor(USER, "elisp" "programmer");
actor(CLERK, "clerk");
actor(DRAWER, "drawer");

action(USER, CLERK, "Could I please have" "some closing parens?");
action(CLERK, DRAWER, "search for" "available )))s");
action(DRAWER, CLERK, "Grab a bunch" "of )))s");
action(CLERK, USER, "Here you go! )))" "Have a nice day!");

finish(USER);
finish(CLERK);
finish(DRAWER);
.PE
</pre>
</div>

<p>
The simple macros I've defined automatically create and move a
global y-coordinate <code>ypos</code> and draw action arrows between boxes
labelled with <code>USER</code>, <code>CLERK</code>, <code>DRAWER</code> defined with <code>actor</code> macro.
</p>

<p>
Resulting SVG image:
</p>


<figure>
<object type="image/svg+xml" data="./static/macro-demo.svg" class="org-svg">
Sorry, your browser does not support SVG.</object>

<figcaption><span class="figure-number">Figure 2: </span>Simple sequence diagram, created using macros</figcaption>
</figure>

<p>
Since pic can import other files you could basically create a
library of macros for certain specific tasks like this. In fact,
that's what e.g. Kernighan has done with <a href="https://dl.acm.org/doi/abs/10.1145/6424.6429">grap</a>. There are many other
examples in the troff toolchain.
</p>
</div>
</div>

<div id="outline-container-org83fcb08" class="outline-2">
<h2 id="org83fcb08">Useful links</h2>
<div class="outline-text-2" id="text-org83fcb08">
<ul class="org-ul">
<li><a href="https://pikchr.org/home/uv/pic.pdf">https://pikchr.org/home/uv/pic.pdf</a> — Brian W Kernighan's PIC-manual</li>
</ul>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">

<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara">It's been a part of <a href="https://en.wikipedia.org/wiki/Troff">troff</a> but
I started with <a href="https://en.wikipedia.org/wiki/LaTeX">LaTeX</a> and remained completely oblivious to tools in
troff toolchain.</div></div>

<div class="footdef"><sup><a id="fn.2" class="footnum" href="#fnr.2">2</a></sup> <div class="footpara">Edit 2021-02-09: This
had a bug earlier. <code>find-file</code> et al. operate on <i>abbreviated</i> file
names, so call <code>abbreviate-file-name</code> to make sure
<code>revert-without-query</code> holds an abbreviated file name.</div></div>


</div>
</div><div class="taglist"><a href="https://iki.fi/newcup/cons-trained/tags.html">Tags</a>: <a href="https://iki.fi/newcup/cons-trained/tag-emacs.html">emacs</a> <a href="https://iki.fi/newcup/cons-trained/tag-pic.html">pic</a> <a href="https://iki.fi/newcup/cons-trained/tag-images.html">images</a> <a href="https://iki.fi/newcup/cons-trained/tag-documentation.html">documentation</a> </div>]]></description>
  <category><![CDATA[emacs]]></category>
  <category><![CDATA[pic]]></category>
  <category><![CDATA[images]]></category>
  <category><![CDATA[documentation]]></category>
  <link>https://iki.fi/newcup/cons-trained/2021-02-03-neat,-simple-vcs-friendly-images.html</link>
  <pubDate>Wed, 03 Feb 2021 23:15:00 +0200</pubDate>
</item>
</channel>
</rss>
