nix/doc/manual/generate-manpage.nix

116 lines
3.8 KiB
Nix
Raw Normal View History

2022-10-07 16:07:22 +00:00
{ toplevel }:
2020-09-16 12:55:24 +00:00
with builtins;
with import ./utils.nix;
let
2022-10-07 16:07:22 +00:00
showCommand = { command, details, filename, toplevel }:
let
result = ''
> **Warning** \
> This program is **experimental** and its interface is subject to change.
# Name
2022-08-27 01:25:12 +00:00
`${command}` - ${details.description}
# Synopsis
2022-08-27 01:25:12 +00:00
${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}
'';
2022-08-27 01:25:12 +00:00
maybeSubcommands = if details ? commands && details.commands != {}
then ''
where *subcommand* is one of the following:
${subcommands}
''
else "";
subcommands = if length categories > 1
then listCategories
2022-08-27 01:25:12 +00:00
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}:**
2022-08-27 01:25:12 +00:00
${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}
'';
2022-08-27 01:25:12 +00:00
maybeDocumentation = if details ? doc then details.doc else "";
maybeOptions = if details.flags == {} then "" else ''
# Options
2022-10-07 16:07:22 +00:00
${showOptions details.flags toplevel.flags}
'';
2022-10-07 16:07:22 +00:00
showOptions = options: commonOptions:
let
2022-10-07 16:07:22 +00:00
allOptions = options // commonOptions;
showCategory = cat: ''
${if cat != "" then "**${cat}:**" else ""}
2022-10-07 16:07:22 +00:00
${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}
'';
2022-10-07 16:07:22 +00:00
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;
2020-09-16 12:55:24 +00:00
2022-10-07 16:07:22 +00:00
processCommand = { command, details, filename, toplevel }:
2022-08-27 01:25:12 +00:00
let
cmd = {
inherit command;
name = filename + ".md";
2022-10-07 16:07:22 +00:00
value = showCommand { inherit command details filename toplevel; };
2022-08-27 01:25:12 +00:00
};
subcommand = subCmd: processCommand {
command = command + " " + subCmd;
details = details.commands.${subCmd};
filename = appendName filename subCmd;
2022-10-07 16:07:22 +00:00
inherit toplevel;
2022-08-27 01:25:12 +00:00
};
in [ cmd ] ++ concatMap subcommand (attrNames details.commands or {});
2022-10-07 16:07:22 +00:00
parsedToplevel = builtins.fromJSON toplevel;
2022-08-27 01:25:12 +00:00
manpages = processCommand {
command = "nix";
2022-10-07 16:07:22 +00:00
details = parsedToplevel;
2022-08-27 01:25:12 +00:00
filename = "nix";
2022-10-07 16:07:22 +00:00
toplevel = parsedToplevel;
2022-08-27 01:25:12 +00:00
};
tableOfContents = let
showEntry = page:
" - [${page.command}](command-ref/new-cli/${page.name})";
2022-09-29 23:41:56 +00:00
in concatStringsSep "\n" (map showEntry manpages) + "\n";
2022-08-27 01:25:12 +00:00
in (listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }