lix/doc/manual/generate-manpage.nix

231 lines
6 KiB
Nix
Raw Normal View History

let
inherit (builtins)
attrNames
attrValues
fromJSON
listToAttrs
mapAttrs
concatStringsSep
concatMap
length
lessThan
replaceStrings
sort
;
inherit (import ./utils.nix)
concatStrings
optionalString
filterAttrs
trim
squash
unique
showSettings
;
in
2023-11-10 19:22:42 +01:00
inlineHTML: commandDump:
2020-09-16 14:55:24 +02:00
let
commandInfo = fromJSON commandDump;
showCommand =
{
command,
details,
filename,
toplevel,
}:
let
result = ''
> **Warning** \
> This program is
> [**experimental**](@docroot@/contributing/experimental-features.md#xp-feature-nix-command)
> and its interface is subject to change.
# Name
2022-08-27 03:25:12 +02:00
`${command}` - ${details.description}
# Synopsis
2022-08-27 03:25:12 +02:00
${showSynopsis command details.args}
${maybeSubcommands}
2023-11-10 19:22:42 +01:00
${maybeStoreDocs}
${maybeOptions}
'';
showSynopsis =
command: args:
let
showArgument = arg: "*${arg.label}*" + optionalString (!arg ? arity) "...";
arguments = concatStringsSep " " (map showArgument args);
in
''
`${command}` [*option*...] ${arguments}
'';
maybeSubcommands = optionalString (details ? commands && details.commands != { }) ''
where *subcommand* is one of the following:
${subcommands}
'';
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}:**
2022-08-27 03:25:12 +02: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}
'';
# TODO: move this confusing special case out of here when implementing #8496
maybeStoreDocs = optionalString (details ? doc) (
replaceStrings [ "@stores@" ] [ storeDocs ] details.doc
);
maybeOptions = optionalString (details.flags != { }) ''
# Options
2022-10-07 18:07:22 +02:00
${showOptions details.flags toplevel.flags}
> **Note**
>
> See [`man nix.conf`](@docroot@/command-ref/conf-file.md#command-line-flags) for overriding configuration settings with command line flags.
'';
showOptions =
options: commonOptions:
let
2022-10-07 18:07:22 +02:00
allOptions = options // commonOptions;
showCategory = cat: ''
${optionalString (cat != "") "**${cat}:**"}
2022-10-07 18:07:22 +02:00
${listOptions (filterAttrs (n: v: v.category == cat) allOptions)}
'';
listOptions = opts: concatStringsSep "\n" (attrValues (mapAttrs showOption opts));
showOption =
name: option:
let
2023-11-10 19:22:42 +01:00
result = trim ''
- ${item}
${option.description}
'';
item =
if inlineHTML then
''<span id="opt-${name}">[`--${name}`](#opt-${name})</span> ${shortName} ${labels}''
else
"`--${name}` ${shortName} ${labels}";
shortName = optionalString (option ? shortName) ("/ `-${option.shortName}`");
labels = optionalString (option ? labels) (concatStringsSep " " (map (s: "*${s}*") option.labels));
in
result;
categories = sort 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 14:55:24 +02:00
processCommand =
{
command,
details,
filename,
toplevel,
}:
2022-08-27 03:25:12 +02:00
let
cmd = {
inherit command;
name = filename + ".md";
value = showCommand {
inherit
command
details
filename
toplevel
;
};
2022-08-27 03:25:12 +02:00
};
subcommand =
subCmd:
processCommand {
command = command + " " + subCmd;
details = details.commands.${subCmd};
filename = appendName filename subCmd;
inherit toplevel;
};
in
[ cmd ] ++ concatMap subcommand (attrNames details.commands or { });
2022-08-27 03:25:12 +02:00
manpages = processCommand {
command = "nix";
details = commandInfo.args;
2022-08-27 03:25:12 +02:00
filename = "nix";
toplevel = commandInfo.args;
2022-08-27 03:25:12 +02:00
};
tableOfContents =
let
showEntry = page: " - [${page.command}](command-ref/new-cli/${page.name})";
in
concatStringsSep "\n" (map showEntry manpages) + "\n";
2022-08-27 03:25:12 +02:00
storeDocs =
let
showStore =
name:
{
settings,
doc,
experimentalFeature,
}:
let
experimentalFeatureNote = optionalString (experimentalFeature != null) ''
> **Warning**
> This store is part of an
> [experimental feature](@docroot@/contributing/experimental-features.md).
To use this store, you need to make sure the corresponding experimental feature,
[`${experimentalFeature}`](@docroot@/contributing/experimental-features.md#xp-feature-${experimentalFeature}),
is enabled.
For example, include the following in [`nix.conf`](@docroot@/command-ref/conf-file.md):
```
extra-experimental-features = ${experimentalFeature}
```
'';
in
''
## ${name}
${doc}
${experimentalFeatureNote}
**Settings**:
2023-11-10 19:22:42 +01:00
${showSettings { inherit inlineHTML; } settings}
'';
in
concatStrings (attrValues (mapAttrs showStore commandInfo.stores));
in
(listToAttrs manpages) // { "SUMMARY.md" = tableOfContents; }