From 1e27a3df0b445590e791a353b62159ad5ae4c0c3 Mon Sep 17 00:00:00 2001 From: thiagokokada Date: Thu, 5 Dec 2024 08:34:29 +0000 Subject: [PATCH] README/rss: update --- rss.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rss.xml b/rss.xml index b07118f..108ab7a 100644 --- a/rss.xml +++ b/rss.xml @@ -6,7 +6,7 @@ Praise to scdoc to generate man pages https://github.com/thiagokokada/blog/blob/main/posts/2024-12-04/01-praise-to-scdoc-to-generate-man-pages.md - <p>Hey, its been a long time since my <a href="posts/2024-10-07/01-enabling-le-audio-lc3-in-wf-1000xm5.md">last blog post</a>. It is mostly because I ran out of things to write, but I expected this. This is probably more likely how I am actually going to post from now. At least, it shows that my plan to have a <a href="https://github.com/thiagokokada/blog/blob/main/posts/2024-08-24/01-making-a-blog-for-the-next-10-years.md">blog for a long time</a>, that is easy to go back when I wanted is working fine, but I digress.</p> <p>Going back to the theme of the today blog post, I needed to write a <a href="https://en.wikipedia.org/wiki/Man_page">man page</a> for the first time in years. I hate <a href="https://en.wikipedia.org/wiki/Troff">troff</a>, the typesetting system used for man pages (similar to <a href="https://en.wikipedia.org/wiki/LaTeX">LaTeX</a> for documents). It is one of the weirdest languages that I ever saw, and even the example in Wikipedia shows that:</p> <pre><code class="language-troff">.ND &quot;January 10, 1993&quot; .AU &quot;Ms. Jane Smith&quot; .AT &quot;Upcoming appointment&quot; .MT 5 .DS Reference #A12345 .sp 4 Mr. Samuel Jones Field director, Bureau of Inspections 1010 Government Plaza Capitoltown, ST .sp 3 Dear Mr. Jones, .sp 2 .P Making reference to the noted obligation to submit for state inspection our newly created production process, we request that you consider the possible inappropriateness of subjecting the innovative technologies of tomorrow to the largely antiquated requirements of yesterday. If our great state is to prosper in the twenty-first century, we must take steps .B now , in .I this year of .I this decade, to prepare our industrial base for the interstate and international competition that is sure to appear. Our new process does precisely that. Please do not let it be undone by a regulatory environment that is no longer apt. .P Thank you for your consideration of our position. .FC Sincerely .SG </code></pre> <p>Keep in mind that the break lines are necessary every time you introduce a macro, like <code>.I this</code> (that I <em>think</em> it is for italics). Yes, this format is as illegible as hell, and it is worse that the format lacks good tooling (or at least I didn't find any good ones).</p> <p>Most people when they need to write a man page nowadays ends up using some other format that generates a man page. For example, in the past I used <a href="https://pandoc.org/">Pandoc</a> to convert Markdown to a man page, but even if Pandoc is a great project the result is sub-optimal at best: Markdowns are, at the end, designed for generating HTML (and a subset of it), and not man pages, so you basically ends up fighting the format for it to do what you want. Also, Pandoc is a big project, with a ~200MB binary (at least it is the default Pandoc binary in Nix).</p> <p>For this specific project I needed something small. I am trying to replace one of the most essential pieces inside NixOS, <code>nixos-rebuild</code>, written in Bash, with a <a href="https://discourse.nixos.org/t/nixos-rebuild-ng-a-nixos-rebuild-rewrite/55606/">full rewritten in Python</a> (sorry Rust zealots!), called <code>nixos-rebuild-ng</code>.</p> <p>Since this project will eventually (if successful) be in the critical path for NixOS, I want to reduce the number of dependencies as much as possible, so something as big as Pandoc is out. I could use <a href="https://asciidoc.org/">AsciiDoc</a>, but it is a big complicated Python project (this may seem ironic, but <code>nixos-rebuild-ng</code> has only one runtime dependency, that is optional). And I also hated the last time I tried to use it to generate man pages: it more flexible than Markdown, but still far from optimal.</p> <p>Thanks to Drew DeVault (creator of <a href="https://swaywm.org/">SwayWM</a>) that seems it had the same issues in the past and created <a href="https://drewdevault.com/2018/05/13/scdoc.html"><code>scdoc</code></a>, a very simple man page generator in using a DSL inspired in Markdown but specific to generate manpages. The binary is written in C and has no dependencies, so it fits the requirement.</p> <p>While the language suffers from being a niche project for a niche segment, the <a href="https://man.archlinux.org/man/scdoc.5.en">manpage</a> for it is actually really nice. It is terse though and lacks examples, and this is what this blog post will try to accomplish.</p> <p>To start, let's have a quick summary of the syntax, written in <code>scdoc</code> as comments:</p> <pre><code class="language-scdoc">; quick summary: ; # new section ; comments starts with ; ; - this is a list ; - sub-list ; - *bold*: _underline_, force a line break++ ; - [tables], \[ can be used to force an actual [ ; . numbered list ; please configure your editor to use hard tabs ; see `man 5 scdoc` for more information about syntax ; or https://man.archlinux.org/man/scdoc.5.en </code></pre> <p>I actually added this summary in the <code>.scd</code> (the <code>scdoc</code> extension) files that I wrote, so it is easy for someone that never saw the format to start collaborating.</p> <p>And here an example of a (summarised) man page in <code>.scd</code> format:</p> <html> <body style="color:#f8f8f2;background-color:#272822"> <pre tabindex="0" style="color:#f8f8f2;background-color:#272822;"><code><span style="display:flex;"><span>nixos-rebuild-ng(8) </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># NAME </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>nixos-rebuild - reconfigure a NixOS machine </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># SYNOPSIS </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">_nixos-rebuild_</span> \[--upgrade] [--upgrade-all]++ </span></span><span style="display:flex;"><span> \[{switch,boot}] </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># DESCRIPTION </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>This command has one required argument, which specifies the desired operation. </span></span><span style="display:flex;"><span>It must be one of the following: </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">*switch*</span> </span></span><span style="display:flex;"><span> Build and activate the new configuration, and make it the boot default. </span></span><span style="display:flex;"><span> That is, the configuration is added to the GRUB boot menu as the </span></span><span style="display:flex;"><span> default menu entry, so that subsequent reboots will boot the system </span></span><span style="display:flex;"><span> into the new configuration. Previous configurations activated with </span></span><span style="display:flex;"><span> nixos-rebuild switch or nixos-rebuild boot remain available in the GRUB </span></span><span style="display:flex;"><span> menu. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">*boot*</span> </span></span><span style="display:flex;"><span> Build the new configuration and make it the boot default (as with </span></span><span style="display:flex;"><span> <span style="font-style:italic">*nixos-rebuild switch*</span>), but do not activate it. That is, the system </span></span><span style="display:flex;"><span> continues to run the previous configuration until the next reboot. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># OPTIONS </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">*--upgrade, --upgrade-all*</span> </span></span><span style="display:flex;"><span> Update the root user&#39;s channel named &#39;nixos&#39; before rebuilding the </span></span><span style="display:flex;"><span> system. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> In addition to the &#39;nixos&#39; channel, the root user&#39;s channels which have </span></span><span style="display:flex;"><span> a file named &#39;.update-on-nixos-rebuild&#39; in their base directory will </span></span><span style="display:flex;"><span> also be updated. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> Passing <span style="font-style:italic">*--upgrade-all*</span> updates all of the root user&#39;s channels. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>See the Nix manual, <span style="font-style:italic">*nix flake lock --help*</span> or <span style="font-style:italic">*nix-build --help*</span> for details. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># ENVIRONMENT </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>NIXOS_CONFIG </span></span><span style="display:flex;"><span> Path to the main NixOS configuration module. Defaults to </span></span><span style="display:flex;"><span> <span style="font-style:italic">_/etc/nixos/configuration.nix_</span>. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># FILES </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>/etc/nixos/flake.nix </span></span><span style="display:flex;"><span> If this file exists, then <span style="font-style:italic">*nixos-rebuild*</span> will use it as if the </span></span><span style="display:flex;"><span> <span style="font-style:italic">*--flake*</span> option was given. This file may be a symlink to a </span></span><span style="display:flex;"><span> flake.nix in an actual flake; thus <span style="font-style:italic">_/etc/nixos_</span> need not be a </span></span><span style="display:flex;"><span> flake. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># AUTHORS </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>Nixpkgs/NixOS contributors </span></span></code></pre> </body> </html> <p>And here is a screenshot of the result:</p> <p><a href="https://github.com/thiagokokada/blog/raw/main/posts/2024-12-04/2024-12-04-230955_hyprshot.png"><img src="https://github.com/thiagokokada/blog/raw/main/posts/2024-12-04/2024-12-04-230955_hyprshot.png" alt="Man page rendered from scd file"></a></p> <p>One of nice things that I found is how looking at the plain text looks kind like the man page result already. And if you know Markdown, you can basically understand most things that is happening. There are a few differences, like <code>*bold*</code> instead of <code>**bold**</code>, and while they're unfortunate they're not the end of the world.</p> <p>Now, the format has its quirks. The first line being the name of the program and section in parenthesis is required, but this makes sense, since you need this information for the corners. But for one, it requires the usage of hard tabs to create indentation, and the error messages are awful, in a situation that kind remembers me of <code>Makefile</code>. Also the choice of <code>[</code> to start a table means that the traditional <code>app [command]</code> needs in many cases to be escaped as <code>app \[command]</code>. I found this a strange choice since this is supposed to be a format that is only used for man pages, and using <code>[command]</code> to indicate an optional is common, but at least it is easy to escape.</p> <p>In the end, I think all that matters is the result. And for the first time for all those years trying to write a man page, I am satisfied with the result. The man page looks exactly as I wanted once rendered, and the <code>.scd</code> file looks reasonable good that it can work as a documentation for someone that for one reason or another can't use the man page. Also, it is really easy for someone to just go there and update the man page, even without experience in the format (except for maybe the requirement of tabs). So all in all, I really liked the format, and will use it again if I need to write another man page in the future.</p> + <p>Hey, its been a long time since my <a href="posts/2024-10-07/01-enabling-le-audio-lc3-in-wf-1000xm5.md">last blog post</a>. It is mostly because I ran out of things to write, but I expected this. This is probably more likely how I am actually going to post from now. At least, it shows that my plan to have a <a href="https://github.com/thiagokokada/blog/blob/main/posts/2024-08-24/01-making-a-blog-for-the-next-10-years.md">blog for a long time</a>, that is easy to go back when I wanted is working fine, but I digress.</p> <p>Going back to the theme of the today blog post, I needed to write a <a href="https://en.wikipedia.org/wiki/Man_page">man page</a> for the first time in years. I hate <a href="https://en.wikipedia.org/wiki/Troff">troff</a>, the typesetting system used for man pages (similar to <a href="https://en.wikipedia.org/wiki/LaTeX">LaTeX</a> for documents). It is one of the weirdest languages that I ever saw, and even the example in Wikipedia shows that:</p> <pre><code class="language-troff">.ND &quot;January 10, 1993&quot; .AU &quot;Ms. Jane Smith&quot; .AT &quot;Upcoming appointment&quot; .MT 5 .DS Reference #A12345 .sp 4 Mr. Samuel Jones Field director, Bureau of Inspections 1010 Government Plaza Capitoltown, ST .sp 3 Dear Mr. Jones, .sp 2 .P Making reference to the noted obligation to submit for state inspection our newly created production process, we request that you consider the possible inappropriateness of subjecting the innovative technologies of tomorrow to the largely antiquated requirements of yesterday. If our great state is to prosper in the twenty-first century, we must take steps .B now , in .I this year of .I this decade, to prepare our industrial base for the interstate and international competition that is sure to appear. Our new process does precisely that. Please do not let it be undone by a regulatory environment that is no longer apt. .P Thank you for your consideration of our position. .FC Sincerely .SG </code></pre> <p>Keep in mind that the break lines are necessary every time you introduce a macro, like <code>.I this</code> (that I <em>think</em> it is for italics). Yes, this format is as illegible as hell, and it is worse that the format lacks good tooling (or at least I didn't find any good ones).</p> <p>Most people when they need to write a man page nowadays ends up using some other format that generates a man page. For example, in the past I used <a href="https://pandoc.org/">Pandoc</a> to convert Markdown to a man page, but even if Pandoc is a great project the result is sub-optimal at best: Markdowns are, at the end, designed for generating HTML (and a subset of it), and not man pages, so you basically ends up fighting the format for it to do what you want. Also, Pandoc is a big project, with a ~200MB binary (at least it is the default Pandoc binary in Nix).</p> <p>For this specific project I needed something small. I am trying to replace one of the most essential pieces inside NixOS, <code>nixos-rebuild</code>, written in Bash, with a <a href="https://discourse.nixos.org/t/nixos-rebuild-ng-a-nixos-rebuild-rewrite/55606/">full rewritten in Python</a> (sorry Rust zealots!), called <code>nixos-rebuild-ng</code>.</p> <p>Since this project will eventually (if successful) be in the critical path for NixOS, I want to reduce the number of dependencies as much as possible, so something as big as Pandoc is out. I could use <a href="https://asciidoc.org/">AsciiDoc</a>, but it is a big complicated Python project (this may seem ironic, but <code>nixos-rebuild-ng</code> has only one runtime dependency, that is optional). And I also hated the last time I tried to use it to generate man pages: it more flexible than Markdown, but still far from optimal.</p> <p>Thanks to Drew DeVault (creator of <a href="https://swaywm.org/">SwayWM</a>) that seems it had the same issues in the past and created <a href="https://drewdevault.com/2018/05/13/scdoc.html"><code>scdoc</code></a>, a very simple man page generator using a DSL inspired in Markdown, but specific to generate man pages. The binary is written in C (and advantage in this case since it means it is easier to bootstrap), is small (~1 Kloc) and has no dependencies, so it fits the requirement.</p> <p>While the language suffers from being a niche project for a niche segment, the <a href="https://man.archlinux.org/man/scdoc.5.en">man page</a> for it is actually really nice. It is terse though and lacks examples, and this is what this blog post will try to accomplish.</p> <p>To start, let's have a quick summary of the syntax, written in <code>scdoc</code> as comments:</p> <pre><code class="language-scdoc">; quick summary: ; # new section ; comments starts with ; ; - this is a list ; - sub-list ; - *bold*: _underline_, force a line break++ ; - [tables], \[ can be used to force an actual [ ; . numbered list ; please configure your editor to use hard tabs ; see `man 5 scdoc` for more information about syntax ; or https://man.archlinux.org/man/scdoc.5.en </code></pre> <p>I actually added this summary in the <code>.scd</code> (the <code>scdoc</code> extension) files that I wrote, so it is easy for someone that never saw the format to start collaborating.</p> <p>And here an example of a (summarised) man page in <code>.scd</code> format:</p> <html> <body style="color:#f8f8f2;background-color:#272822"> <pre tabindex="0" style="color:#f8f8f2;background-color:#272822;"><code><span style="display:flex;"><span>nixos-rebuild-ng(8) </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># NAME </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>nixos-rebuild - reconfigure a NixOS machine </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># SYNOPSIS </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">_nixos-rebuild_</span> \[--upgrade] [--upgrade-all]++ </span></span><span style="display:flex;"><span> \[{switch,boot}] </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># DESCRIPTION </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>This command has one required argument, which specifies the desired operation. </span></span><span style="display:flex;"><span>It must be one of the following: </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">*switch*</span> </span></span><span style="display:flex;"><span> Build and activate the new configuration, and make it the boot default. </span></span><span style="display:flex;"><span> That is, the configuration is added to the GRUB boot menu as the </span></span><span style="display:flex;"><span> default menu entry, so that subsequent reboots will boot the system </span></span><span style="display:flex;"><span> into the new configuration. Previous configurations activated with </span></span><span style="display:flex;"><span> nixos-rebuild switch or nixos-rebuild boot remain available in the GRUB </span></span><span style="display:flex;"><span> menu. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">*boot*</span> </span></span><span style="display:flex;"><span> Build the new configuration and make it the boot default (as with </span></span><span style="display:flex;"><span> <span style="font-style:italic">*nixos-rebuild switch*</span>), but do not activate it. That is, the system </span></span><span style="display:flex;"><span> continues to run the previous configuration until the next reboot. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># OPTIONS </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span><span style="font-style:italic">*--upgrade, --upgrade-all*</span> </span></span><span style="display:flex;"><span> Update the root user&#39;s channel named &#39;nixos&#39; before rebuilding the </span></span><span style="display:flex;"><span> system. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> In addition to the &#39;nixos&#39; channel, the root user&#39;s channels which have </span></span><span style="display:flex;"><span> a file named &#39;.update-on-nixos-rebuild&#39; in their base directory will </span></span><span style="display:flex;"><span> also be updated. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span> Passing <span style="font-style:italic">*--upgrade-all*</span> updates all of the root user&#39;s channels. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>See the Nix manual, <span style="font-style:italic">*nix flake lock --help*</span> or <span style="font-style:italic">*nix-build --help*</span> for details. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># ENVIRONMENT </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>NIXOS_CONFIG </span></span><span style="display:flex;"><span> Path to the main NixOS configuration module. Defaults to </span></span><span style="display:flex;"><span> <span style="font-style:italic">_/etc/nixos/configuration.nix_</span>. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># FILES </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>/etc/nixos/flake.nix </span></span><span style="display:flex;"><span> If this file exists, then <span style="font-style:italic">*nixos-rebuild*</span> will use it as if the </span></span><span style="display:flex;"><span> <span style="font-style:italic">*--flake*</span> option was given. This file may be a symlink to a </span></span><span style="display:flex;"><span> flake.nix in an actual flake; thus <span style="font-style:italic">_/etc/nixos_</span> need not be a </span></span><span style="display:flex;"><span> flake. </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span># AUTHORS </span></span><span style="display:flex;"><span> </span></span><span style="display:flex;"><span>Nixpkgs/NixOS contributors </span></span></code></pre> </body> </html> <p>And here is a screenshot of the result:</p> <p><a href="https://github.com/thiagokokada/blog/raw/main/posts/2024-12-04/2024-12-04-230955_hyprshot.png"><img src="https://github.com/thiagokokada/blog/raw/main/posts/2024-12-04/2024-12-04-230955_hyprshot.png" alt="Man page rendered from scd file"></a></p> <p>One of nice things that I found is how looking at the plain text looks kind like the man page result already. And if you know Markdown, you can basically understand most things that is happening. There are a few differences, like <code>*bold*</code> instead of <code>**bold**</code>, and while they're unfortunate they're not the end of the world.</p> <p>Now, the format has its quirks. The first line being the name of the program and section in parenthesis is required, but this makes sense, since you need this information for the corners. But for one, it requires the usage of hard tabs to create indentation, and the error messages are awful, in a situation that kind remembers me of <code>Makefile</code>. Also the choice of <code>[</code> to start a table means that the traditional <code>app [command]</code> needs in many cases to be escaped as <code>app \[command]</code>. I found this a strange choice since this is supposed to be a format that is only used for man pages, and using <code>[command]</code> to indicate an optional is common, but at least it is easy to escape.</p> <p>In the end, I think all that matters is the result. And for the first time for all those years trying to write a man page, I am satisfied with the result. The man page looks exactly as I wanted once rendered, and the <code>.scd</code> file looks reasonable good that it can work as a documentation for someone that for one reason or another can't use the man page (can't say the same for the troff version). Also, it is really easy for someone to just go there and update the man page, even without experience in the format (except for maybe the requirement of tabs). So all in all, I really liked the format, and will use it again if I need to write another man page in the future.</p> https://github.com/thiagokokada/blog/blob/main/posts/2024-12-04/01-praise-to-scdoc-to-generate-man-pages.md Wed, 04 Dec 2024 00:00:00 +0000