aboutsummaryrefslogtreecommitdiff
path: root/doc/manual/generate-manpage.nix
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2022-11-03 17:43:40 +0100
committerEelco Dolstra <edolstra@gmail.com>2022-11-03 17:43:40 +0100
commitb95faccf03e5213b6087626ab8d46e0704aad6b5 (patch)
treef9d560f2004f951d8efbf1024292a88366d8efd7 /doc/manual/generate-manpage.nix
parent47dec825c5daeeb9d615eb4d1eead3dbaa06c7c9 (diff)
parentdd1970c233a82328445b69e903574e14115ee933 (diff)
Merge remote-tracking branch 'origin/master' into auto-uid-allocation
Diffstat (limited to 'doc/manual/generate-manpage.nix')
-rw-r--r--doc/manual/generate-manpage.nix191
1 files changed, 103 insertions, 88 deletions
diff --git a/doc/manual/generate-manpage.nix b/doc/manual/generate-manpage.nix
index 244cfa0c2..057719e34 100644
--- a/doc/manual/generate-manpage.nix
+++ b/doc/manual/generate-manpage.nix
@@ -1,99 +1,114 @@
-{ command, renderLinks ? false }:
+{ toplevel }:
with builtins;
with import ./utils.nix;
let
- showCommand =
- { command, def, filename }:
- ''
- **Warning**: This program is **experimental** and its interface is subject to change.
- ''
- + "# Name\n\n"
- + "`${command}` - ${def.description}\n\n"
- + "# Synopsis\n\n"
- + showSynopsis { inherit command; args = def.args; }
- + (if def.commands or {} != {}
- then
- let
- categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues def.commands)));
- listCommands = cmds:
- concatStrings (map (name:
- "* "
- + (if renderLinks
- then "[`${command} ${name}`](./${appendName filename name}.md)"
- else "`${command} ${name}`")
- + " - ${cmds.${name}.description}\n")
- (attrNames cmds));
- in
- "where *subcommand* is one of the following:\n\n"
- # FIXME: group by category
- + (if length categories > 1
- then
- concatStrings (map
- (cat:
- "**${toString cat.description}:**\n\n"
- + listCommands (filterAttrs (n: v: v.category == cat) def.commands)
- + "\n"
- ) categories)
- + "\n"
- else
- listCommands def.commands
- + "\n")
- else "")
- + (if def ? doc
- then def.doc + "\n\n"
- else "")
- + (let s = showOptions def.flags; in
- if s != ""
- then "# Options\n\n${s}"
- else "")
- ;
+ showCommand = { command, details, filename, toplevel }:
+ let
+ result = ''
+ > **Warning** \
+ > This program is **experimental** and its interface is subject to change.
+
+ # Name
+
+ `${command}` - ${details.description}
+
+ # Synopsis
+
+ ${showSynopsis command details.args}
+
+ ${maybeSubcommands}
+
+ ${maybeDocumentation}
+
+ ${maybeOptions}
+ '';
+ showSynopsis = command: args:
+ let
+ showArgument = arg: "*${arg.label}*" + (if arg ? arity then "" else "...");
+ arguments = concatStringsSep " " (map showArgument args);
+ in ''
+ `${command}` [*option*...] ${arguments}
+ '';
+ maybeSubcommands = if details ? commands && details.commands != {}
+ then ''
+ where *subcommand* is one of the following:
+
+ ${subcommands}
+ ''
+ else "";
+ subcommands = if length categories > 1
+ then listCategories
+ else listSubcommands details.commands;
+ categories = sort (x: y: x.id < y.id) (unique (map (cmd: cmd.category) (attrValues details.commands)));
+ listCategories = concatStrings (map showCategory categories);
+ showCategory = cat: ''
+ **${toString cat.description}:**
+
+ ${listSubcommands (filterAttrs (n: v: v.category == cat) details.commands)}
+ '';
+ listSubcommands = cmds: concatStrings (attrValues (mapAttrs showSubcommand cmds));
+ showSubcommand = name: subcmd: ''
+ * [`${command} ${name}`](./${appendName filename name}.md) - ${subcmd.description}
+ '';
+ maybeDocumentation = if details ? doc then details.doc else "";
+ maybeOptions = if details.flags == {} then "" else ''
+ # Options
+
+ ${showOptions details.flags toplevel.flags}
+ '';
+ showOptions = options: commonOptions:
+ let
+ allOptions = options // commonOptions;
+ showCategory = cat: ''
+ ${if cat != "" then "**${cat}:**" else ""}
+
+ ${listOptions (filterAttrs (n: v: v.category == cat) allOptions)}
+ '';
+ listOptions = opts: concatStringsSep "\n" (attrValues (mapAttrs showOption opts));
+ showOption = name: option:
+ let
+ shortName = if option ? shortName then "/ `-${option.shortName}`" else "";
+ labels = if option ? labels then (concatStringsSep " " (map (s: "*${s}*") option.labels)) else "";
+ in trim ''
+ - `--${name}` ${shortName} ${labels}
+
+ ${option.description}
+ '';
+ categories = sort builtins.lessThan (unique (map (cmd: cmd.category) (attrValues allOptions)));
+ in concatStrings (map showCategory categories);
+ in squash result;
appendName = filename: name: (if filename == "nix" then "nix3" else filename) + "-" + name;
- showOptions = flags:
+ processCommand = { command, details, filename, toplevel }:
let
- categories = sort builtins.lessThan (unique (map (cmd: cmd.category) (attrValues flags)));
- in
- concatStrings (map
- (cat:
- (if cat != ""
- then "**${cat}:**\n\n"
- else "")
- + concatStrings
- (map (longName:
- let
- flag = flags.${longName};
- in
- " - `--${longName}`"
- + (if flag ? shortName then " / `-${flag.shortName}`" else "")
- + (if flag ? labels then " " + (concatStringsSep " " (map (s: "*${s}*") flag.labels)) else "")
- + " \n"
- + " " + flag.description + "\n\n"
- ) (attrNames (filterAttrs (n: v: v.category == cat) flags))))
- categories);
-
- showSynopsis =
- { command, args }:
- "`${command}` [*option*...] ${concatStringsSep " "
- (map (arg: "*${arg.label}*" + (if arg ? arity then "" else "...")) args)}\n\n";
-
- processCommand = { command, def, filename }:
- [ { name = filename + ".md"; value = showCommand { inherit command def filename; }; inherit command; } ]
- ++ concatMap
- (name: processCommand {
- filename = appendName filename name;
- command = command + " " + name;
- def = def.commands.${name};
- })
- (attrNames def.commands or {});
-
-in
+ cmd = {
+ inherit command;
+ name = filename + ".md";
+ value = showCommand { inherit command details filename toplevel; };
+ };
+ subcommand = subCmd: processCommand {
+ command = command + " " + subCmd;
+ details = details.commands.${subCmd};
+ filename = appendName filename subCmd;
+ inherit toplevel;
+ };
+ in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
-let
- manpages = processCommand { filename = "nix"; command = "nix"; def = builtins.fromJSON command; };
- summary = concatStrings (map (manpage: " - [${manpage.command}](command-ref/new-cli/${manpage.name})\n") manpages);
-in
-(listToAttrs manpages) // { "SUMMARY.md" = summary; }
+ parsedToplevel = builtins.fromJSON toplevel;
+ manpages = processCommand {
+ command = "nix";
+ details = parsedToplevel;
+ filename = "nix";
+ toplevel = parsedToplevel;
+ };
+
+ tableOfContents = let
+ showEntry = page:
+ " - [${page.command}](command-ref/new-cli/${page.name})";
+ in concatStringsSep "\n" (map showEntry manpages) + "\n";
+
+in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }