:date: 2019-06-01 19:15 .. index:: shell, gnu, pic, pic2graph .. .. seealso:: :ref:`` .. _2019-compile_pictures_with_gnu_pic: Compile pictures with gnu pic ============================= `dot`_ is covering the rendering of flow diagrams. Raw text files are compiled into diagrams. What was missing was a tool that could create just simple graphics or single shapes. This gap got now closed by :command:`GNU PIC`. The tool was already installed on my system, but so far unknown to me. The use-case ------------ I recently had measured our garden in order to do some planning. The crude diagram did its job and provided the information I needed for my particular case, but I wanted to keep this documented a bit longer. Cleaner preferably. .. image:: /_images/images/gallery/2019/gnu_pic/20190601-handdrawing.jpg :align: center This image was no good for documentation. In less than half a year I surely will not be able to make out my own handwriting. GNU PIC ------- :command:`GNU PIC` takes some input and graphic specifications (like :command:`dot`) and compiles it into some rendered output for :command:`Tex` or `groff`_. DESCRIPTION This manual page describes the GNU version of pic, which is part of the groff document formatting system. pic compiles descriptions of pictures embedded within troff or TeX input files into commands that are under‐ stood by TeX or troff. Each picture starts with a line beginning with .PS and ends with a line beginning with .PE. Anything outside of .PS and .PE is passed through without change. The syntax and usage is well documented, e.g. in the document `PIC A Graphics Language for Typesetting Revised User Manual`_. The following example will draw a triangle with a side length of three inches: .. code:: bash :number-lines: .PS line right 3 up 3 "c"; line down 3 "a"; line left 3 "b"; .PE I am gonna use this to see if this can be rendered into a presentable image. So this needs to be fed into the next tool .. code:: bash $ cat input.me pic2graph --------- The second player in the assemble is :command:`pic2graph`. DESCRIPTION Reads a PIC program as input; produces an image file (by default in Portable Network Graphics format) suit‐ able for the Web as output. Also translates eqn(1) constructs, so it can be used for generating images of mathematical formulae. Using this, the input language from :command:`PIC` can be used to generate images from compiled text files. It makes use of :command:`pic`, :command:`convert` (from ImageMagick), :command:`gs`, :command:`eqn` and :command:`groff` to drop the graphic file. The important detail is a bit further down the man-page: Your input PIC code should not be wrapped with the .PS and .PE macros that normally guard it within groff(1) macros. Otherwise :command:`pic2graph` does not have many parameters available. Any additional parameter will be forwarded to :command:`convert`. Something that makes it easy to put some adjustments in when necessary. .. code:: bash $ cat input.me | pic2graph > output.png This creates a transparent PNG file with the triangle defined. That means some more parameters need to be passed to :command:`convert`. .. image:: /_images/images/gallery/2019/gnu_pic/20190601-triangle_transparent.jpg :align: center The transparent PNG images shows up with a white background on this web-page. convert ------- The generated image is a transparent PNG image. So some nice white background would be nice. The parameter `-background`_ will actually do that and set the background color to the default color *white*. Additionally we have to remove the alpha channel to make the change visible. .. code:: -background white -alpha remove -alpha off .. image:: /_images/images/gallery/2019/gnu_pic/20190601-triangle_bgwhite.jpg :align: center On the right image border and top, I could use some more space. The parameter `-border`_ will force `convert` to add additional space. The default color unfortunately is not *white*, so we use `-bordercolor`_ to change that. .. code:: -border 10 -bordercolor white This needs to be passed to convert from :command:`pic2graph`: .. code:: bash cat input.me | pic2graph -background white -alpha remove -alpha off -border 10 -bordercolor gray > output.png .. image:: /_images/images/gallery/2019/gnu_pic/20190601-triangle_bgwhite_border.jpg :align: center The drawing ----------- The following code for the :file:`input.me` generates the handwritten diagram as PNG file. .. code:: bash :number-lines: # Gardenshape line right 26.50 "2650cm" below; line dotted down 2 "200cm" rjust; move right 5; move left 5; line down 0.5 "50cm" ljust; line left 2.5 "250cm" below; line up 0.5 "50cm" ljust; line left 6.5 "650cm" below; line down 0.5 "50cm" rjust; line left 3 "300cm" below; line down 2 "200cm" ljust; line left 3 "300cm" below; line down 6 left 1.5 "600cm" ljust; line down 4 "400cm" ljust; move down 3 left 3; arc up 3 right 3 rad 3 "300cm"; move down 3 left 3; line left 2 "200cm" below; line to 0,0 "2200cm" ljust; .. image:: /_images/images/gallery/2019/gnu_pic/20190601-pic_generated.png :align: center At this point the whole chain from a) putting the code in there to getting the z) getting the image rendered works. Time to put the real world code into the file :file:`input.me`. Lessons learned --------------- During looking and playing with :command:`pic`, :command:`pic2graph` and :command:`convert` and writing this article, I've been forced to look quite close on the commands and parameters to use to make sure everything is correct. These are the lessons I've learned during this: * :command:`pic`: The syntax is quite straight forward. Define an object, its dimensions and the following object will continue where the previous one will left of. However: I initially started in the lower left corner of the drawing. That left me with the problem of the left straight line that has an angle. I would have to guess the target coordinates. After I changes this and put the start location in the top left corner and work around the drawing clockwise, the last line `line to 0,0` automatically completes the drawing. * :command:`pic2graph`: Not sure why, but rendering the graph cuts off parts on the right hand side. I've addressed this with the lines four and five (`move right 5; move left 5`). That puts the next object exactly at the location where the previous left off, but executes a kind of side-step to increase the defined image size. * :command:`-flatten`: Initially I used the parameter :command:`-flatten` for :command:`convert` to assign the default background color. This also had the side-effect on unnecessarily increasing the canvas size. Replacing this with `-background`, `-backgroundcolor`, and `-alpha` created a better sized image. * There was no need to look at :command:`groff` or :command:`pic` in details. The syntax in combination with :command:`pic2graph` was enough to get it working. Bonus ----- I've just put the rendering command in a :file:`Makefile` to make it easy to render in the future: .. code:: :number-lines: %.png: %.me cat $< | pic2graph -background white -alpha remove -alpha off -border 10 -bordercolor white > $@ .. _PIC A Graphics Language for Typesetting Revised User Manual: https://doc.cat-v.org/unix/v8/picmemo.pdf .. _-repage: https://imagemagick.org/script/command-line-options.php#repage .. _-flatten: https://imagemagick.org/script/command-line-options.php#flatten .. _-background: https://imagemagick.org/script/command-line-options.php#background .. _-border: https://imagemagick.org/script/command-line-options.php#border .. _-bordercolor: https://imagemagick.org/script/command-line-options.php#bordercolor .. _dot: http://www.graphviz.org/pdf/dotguide.pdf .. _groff: http://www.gnu.org/software/groff