about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2021-03-11T14·16+0100
committersterni <sternenseemann@systemli.org>2021-03-11T14·31+0000
commitb3f686995fe3321b7f62f0247391cc2afd8b4d8c (patch)
tree3108af52e23fc73ebd112f78d211f1250e431e6f
parent2cd2b58a04cd86e8bf1d72e9c0a67ad8c8e9c8dd (diff)
feat(users/sterni/htmlman): hyperlink .Xr macro in output r/2277
We make use of the -O man=… option of mandoc(1) which allows to convert
cross references via the .Xr macro into actual hyperlinks in the output.
This can be disabled (by passing "none") or done in two modes:

* all: links all .Xr cross references as if they were in
  $out/%N.%S.html. This will lead to broken links of course.
* inManDir: only link to files in $out if the man page is found in
  manDir, use the template defined in linkXrFallback if not.

all is the default, since we don't require all man pages to be in
manDir, so it would be potentially confusing if the path attribute was
used in the pages list.

linkXrFallback uses the debian online man viewer by default currently,
since it can be decently hyperlinked and debian has a lot of packages.
Other options would be:

* https://manpages.ubuntu.com/manpages/latest/en/man%S/%N.%S.html
* https://man.archlinux.org/man/%N.%S.en
* https://man.openbsd.org/%N.%S
* https://www.man7.org/linux/man-pages/man%S/%N.%S.html

Change-Id: I1363b9dfdda25cb7383c7310b8115c335444bd3d
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2597
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
-rw-r--r--users/sterni/htmlman/default.nix34
1 files changed, 32 insertions, 2 deletions
diff --git a/users/sterni/htmlman/default.nix b/users/sterni/htmlman/default.nix
index c528a29006..b88bc26410 100644
--- a/users/sterni/htmlman/default.nix
+++ b/users/sterni/htmlman/default.nix
@@ -4,6 +4,7 @@ let
   inherit (depot.nix)
     getBins
     runExecline
+    yants
     ;
 
   inherit (depot.tools)
@@ -156,16 +157,42 @@ let
     # CSS to use as a string
     , normalizeCss ? true
     # whether to include normalize.css before the custom CSS
+    , linkXr ? "all"
+    # How to handle cross references in the html output:
+    #
+    # * none:     don't convert cross references into hyperlinks
+    # * all:      link all cross references as if they were
+    #             rendered into $out by htmlman
+    # * inManDir: link to all man pages which have their source
+    #             in `manDir` and use the format string defined
+    #             in linkXrFallback for all other cross references.
+    , linkXrFallback ? "https://manpages.debian.org/unstable/%N.%S.en.html"
+    # fallback link to use if linkXr == "inManDir" and the man
+    # page is not in ${manDir}. Placeholders %N (name of page)
+    # and %S (section of page) can be used. See mandoc(1) for
+    # more information.
     }:
 
     let
+      linkXrEnum = yants.enum "linkXr" [ "all" "inManDir" "none" ];
+
       index = indexTemplate {
         inherit title description pages;
       };
+
       resolvePath = { path ? null, name, section }:
         if path != null
         then path
         else "${manDir}/${name}.${toString section}";
+
+      mandocOpts = lib.concatStringsSep "," ([
+        "style=style.css"
+      ] ++ linkXrEnum.match linkXr {
+        all      = [ "man=./%N.%S.html" ];
+        inManDir = [ "man=./%N.%S.html;${linkXrFallback}" ];
+        none     = [ ];
+      });
+
       html =
         runExecline.local "htmlman-${title}" {
           derivationArgs = {
@@ -188,12 +215,15 @@ let
               "$style"
             ])
           ])
+          # let mandoc check for available man pages
+          "execline-cd" "${manDir}"
         ] ++ lib.concatMap ({ name, section, ... }@p:
           execlineStdoutInto "\${out}/${name}.${toString section}.html" [
           "if" [
             bins.mandoc
-            "-T" "html" "-mdoc"
-            "-O" "style=style.css"
+            "-mdoc"
+            "-T" "html"
+            "-O" mandocOpts
             (resolvePath p)
           ]
         ]) pages);