refactor(docs): switch to nixos-render-docs for nix options generation

- Use nixos-render-docs commonmark as the rendering engine
- Add GitHub source links (Declared by) for each option
- Fix installation.md links pointing to /docs/nix-module -> /docs/nix-options
This commit is contained in:
Ruixi-rebirth 2026-05-13 11:06:59 +08:00
parent 0b39255831
commit d7c5b603eb
5 changed files with 380 additions and 193 deletions

View file

@ -1,22 +1,9 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" # Post-processes nixos-render-docs commonmark output into a single docs page.
Converts NixOS options JSON into clean Markdown documentation. # Input: two pre-rendered .md files (NixOS and HM), produced by nixos-render-docs.
""" # Steps: strip internal _module.args section, promote ## headings to ###.
import json
import sys
import re import re
import sys
SECTIONS = [
{
"title": "NixOS",
"subtitle": "**System-level options via `programs.mango`.**",
},
{
"title": "Home Manager",
"subtitle": "**Configure mangowm declaratively via `wayland.windowManager.mango`.**",
},
]
HEADER = ( HEADER = (
"---\n" "---\n"
@ -26,87 +13,36 @@ HEADER = (
"> **Note:** This document is automatically generated from the Nix module source code.\n\n" "> **Note:** This document is automatically generated from the Nix module source code.\n\n"
) )
def clean_description(desc: str) -> str: SECTIONS = [
"""Strips Nix inline markup tags, fixes dangling periods, and formats blockquotes.""" ("NixOS", "**System-level options via `programs.mango`.**"),
if not desc: ("Home Manager", "**Configure mangowm declaratively via `wayland.windowManager.mango`.**"),
return "*No description provided.*" ]
# Strip Nix inline markup: {tag}`content` → `content`; bare tags → ""
desc = re.sub(r'\{(?:var|option|manpage|file|env|command|program)\}(`[^`]+`)', r'\1', desc)
desc = re.sub(r'\{(?:var|option|manpage|file|env|command|program)\}', '', desc)
# Remove period left on its own line after tag removal
desc = re.sub(r'\n\s*\.(\s|$)', r'.\1', desc)
lines = desc.splitlines() def process(md):
cleaned = [] # Remove internal _module.args option injected by the module system
in_block = False md = re.sub(r'## _module\\\.args.*?(?=\n## |\Z)', '', md, flags=re.DOTALL)
# Promote option headings (##) to subheadings (###) under the section (##)
md = re.sub(r'^## ', '### ', md, flags=re.MULTILINE)
return md.strip()
for line in lines:
m = re.match(r':::\s*\{\.(\w+)\}', line)
if m:
block_type = m.group(1).capitalize()
in_block = True
cleaned.append(f"> **{block_type}:**\n>")
elif line.startswith(":::"):
in_block = False
else:
cleaned.append(f"> {line}" if in_block else line)
return "\n".join(cleaned)
def format_value(val_data) -> str:
"""Formats a value as inline code or a nix code block."""
if val_data is None:
return None
if isinstance(val_data, dict) and val_data.get("_type") == "literalMD":
return val_data.get("text", "").strip()
elif isinstance(val_data, dict) and val_data.get("_type") == "literalExpression":
text = val_data.get("text", "").strip()
elif isinstance(val_data, bool):
text = "true" if val_data else "false"
elif val_data == {} or val_data == []:
text = "{ }" if val_data == {} else "[ ]"
else:
text = str(val_data).strip()
if '\n' in text:
return f"\n```nix\n{text}\n```"
return f"`{text}`"
def write_section(out, data, title, subtitle):
out.write(f"## {title}\n\n{subtitle}\n\n")
for key, opt in sorted(data.items()):
if key.startswith("_module"):
continue
desc = clean_description(opt.get("description", ""))
opt_type = str(opt.get("type", "unknown"))
default_val = format_value(opt.get("default"))
example_val = format_value(opt.get("example"))
block = f"### `{key}`\n\n{desc}\n\n**Type:** `{opt_type}`\n\n"
if default_val is not None:
block += f"**Default:** {default_val}\n\n"
if example_val is not None:
block += f"**Example:** {example_val}\n\n"
block += "---\n\n"
out.write(block)
def main(): def main():
if len(sys.argv) != 4: if len(sys.argv) != 4:
sys.exit("Usage: generate-nix-options-docs.py <nixos.json> <hm.json> <output.md>") sys.exit("Usage: generate-nix-options-docs.py <nixos.md> <hm.md> <output.md>")
nixos_json, hm_json, output_md = sys.argv[1:4] nixos_md, hm_md, output_md = sys.argv[1:4]
inputs = [nixos_json, hm_json]
with open(output_md, 'w', encoding='utf-8') as out: with open(output_md, 'w', encoding='utf-8') as out:
out.write(HEADER) out.write(HEADER)
for path, section in zip(inputs, SECTIONS): for path, (title, subtitle) in zip([nixos_md, hm_md], SECTIONS):
with open(path, 'r', encoding='utf-8') as f: with open(path, 'r', encoding='utf-8') as f:
data = json.load(f) md = f.read()
write_section(out, data, section["title"], section["subtitle"]) out.write(f"## {title}\n\n{subtitle}\n\n")
print(f"Written {section['title']} section.") out.write(process(md))
out.write('\n\n')
print(f"Written {title} section.")
if __name__ == "__main__": if __name__ == "__main__":
main() main()

View file

@ -34,11 +34,25 @@ jobs:
nix build .#nixos-options-json --out-link result-nixos nix build .#nixos-options-json --out-link result-nixos
nix build .#hm-options-json --out-link result-hm nix build .#hm-options-json --out-link result-hm
- name: Render to CommonMark
run: |
echo '{}' > /tmp/manpage-urls.json
nix run nixpkgs#nixos-render-docs -- options commonmark \
--manpage-urls /tmp/manpage-urls.json \
--revision nightly \
result-nixos/share/doc/nixos/options.json \
/tmp/nixos-raw.md
nix run nixpkgs#nixos-render-docs -- options commonmark \
--manpage-urls /tmp/manpage-urls.json \
--revision nightly \
result-hm/share/doc/nixos/options.json \
/tmp/hm-raw.md
- name: Format to Markdown - name: Format to Markdown
run: | run: |
python3 ./.github/scripts/generate-nix-options-docs.py \ python3 ./.github/scripts/generate-nix-options-docs.py \
result-nixos/share/doc/nixos/options.json \ /tmp/nixos-raw.md \
result-hm/share/doc/nixos/options.json \ /tmp/hm-raw.md \
docs/nix-options.md docs/nix-options.md
- name: Auto-commit changes - name: Auto-commit changes

View file

@ -202,7 +202,7 @@ The repository provides a Flake with a NixOS module.
}; };
``` ```
**Option B — Display manager autologin:** Autologin via an existing display manager (e.g. SDDM, GDM). [`addLoginEntry`](/docs/nix-module#addloginentry) (default: `true`) automatically registers mango as a session. **Option B — Display manager autologin:** Autologin via an existing display manager (e.g. SDDM, GDM). [`addLoginEntry`](/docs/nix-options#addloginentry) (default: `true`) automatically registers mango as a session.
```nix ```nix
services.displayManager = { services.displayManager = {
@ -240,7 +240,7 @@ The repository provides a Flake with a NixOS module.
5. **All available options** 5. **All available options**
See [Nix Module Options](/docs/nix-module) for the full list of NixOS and Home Manager options. See [Nix Module Options](/docs/nix-options) for the full list of NixOS and Home Manager options.
--- ---

View file

@ -9,55 +9,163 @@ description: NixOS and Home Manager configuration options for mangowm.
**System-level options via `programs.mango`.** **System-level options via `programs.mango`.**
### `addLoginEntry` ### enable
Whether to add a login entry to the display manager for mango. Only has effect if a display manager is configured (e.g. SDDM, GDM via `services.displayManager`).
**Type:** `boolean`
**Default:** `true` Whether to enable mango, a wayland compositor based on dwl\.
---
### `enable`
Whether to enable mango, a wayland compositor based on dwl. *Type:*
boolean
**Type:** `boolean`
**Default:** `false`
**Example:** `true` *Default:*
```nix
false
```
*Example:*
```nix
true
```
*Declared by:*
- [\<mango/nix/nixos-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/nixos-modules.nix)
### package
---
### `package`
The mango package to use The mango package to use
**Type:** `package`
**Default:** `<derivation mango-nightly>`
--- *Type:*
package
*Default:*
```nix
<derivation mango-nightly>
```
*Declared by:*
- [\<mango/nix/nixos-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/nixos-modules.nix)
### addLoginEntry
Whether to add a login entry to the display manager for mango\. Only has effect if a display manager is configured (e\.g\. SDDM, GDM via ` services.displayManager `)\.
*Type:*
boolean
*Default:*
```nix
true
```
*Declared by:*
- [\<mango/nix/nixos-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/nixos-modules.nix)
## Home Manager ## Home Manager
**Configure mangowm declaratively via `wayland.windowManager.mango`.** **Configure mangowm declaratively via `wayland.windowManager.mango`.**
### `autostart_sh` ### enable
Shell script to run on mango startup. No shebang needed.
Whether to enable mangowm, a Wayland compositor based on dwl\.
*Type:*
boolean
*Default:*
```nix
false
```
*Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### package
The mango package to use
*Type:*
package
*Default:*
```nix
<derivation mango-nightly>
```
*Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### autostart_sh
Shell script to run on mango startup\. No shebang needed\.
When this option is set, the script will be written to When this option is set, the script will be written to
`~/.config/mango/autostart.sh` and an `exec-once` line ` ~/.config/mango/autostart.sh ` and an ` exec-once ` line
will be automatically added to the config to execute it. will be automatically added to the config to execute it\.
**Type:** `strings concatenated with "\n"`
**Default:** `""`
**Example:** *Type:*
strings concatenated with “\\n”
*Default:*
```nix
""
```
*Example:*
```nix ```nix
'' ''
waybar & waybar &
@ -65,47 +173,71 @@ will be automatically added to the config to execute it.
'' ''
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### `bottomPrefixes`
List of prefixes for attributes that should appear at the bottom of the config file.
Attributes starting with these prefixes will be sorted to the end.
**Type:** `list of string` ### bottomPrefixes
**Default:** `[ ]`
**Example:**
List of prefixes for attributes that should appear at the bottom of the config file\.
Attributes starting with these prefixes will be sorted to the end\.
*Type:*
list of string
*Default:*
```nix
[ ]
```
*Example:*
```nix ```nix
[ [
"source" "source"
] ]
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### `enable`
Whether to enable mangowm, a Wayland compositor based on dwl.
**Type:** `boolean` ### extraConfig
**Default:** `false`
---
### `extraConfig` Extra configuration lines to add to ` ~/.config/mango/config.conf `\.
This is useful for advanced configurations that dont fit the structured
settings format, or for options that arent yet supported by the module\.
Extra configuration lines to add to `~/.config/mango/config.conf`.
This is useful for advanced configurations that don't fit the structured
settings format, or for options that aren't yet supported by the module.
**Type:** `strings concatenated with "\n"`
**Default:** `""` *Type:*
strings concatenated with “\\n”
*Default:*
```nix
""
```
*Example:*
**Example:**
```nix ```nix
'' ''
# Advanced config that doesn't fit structured format # Advanced config that doesn't fit structured format
@ -113,38 +245,43 @@ settings format, or for options that aren't yet supported by the module.
'' ''
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### `package`
The mango package to use
**Type:** `package` ### settings
**Default:** `<derivation mango-nightly>`
---
### `settings` Mango configuration written in Nix\. Entries with the same key
should be written as lists\. Variables and colors names should be
quoted\. See [https://mangowm\.github\.io/docs](https://mangowm\.github\.io/docs) for more examples\.
Mango configuration written in Nix. Entries with the same key **Note:** This option uses a structured format that is converted to Mangos
should be written as lists. Variables and colors names should be configuration syntax\. Nested attributes are flattened with underscore separators\.
quoted. See <https://mangowm.github.io/docs> for more examples. For example: ` animation.duration_open = 400 ` becomes ` animation_duration_open = 400 `
> **Note:** Keymodes (submaps) are supported via the special ` keymode ` attribute\. Each keymode
> is a nested attribute set under ` keymode ` that contains its own bindings\.
> This option uses a structured format that is converted to Mango's
> configuration syntax. Nested attributes are flattened with underscore separators.
> For example: `animation.duration_open = 400` becomes `animation_duration_open = 400`
>
> Keymodes (submaps) are supported via the special `keymode` attribute. Each keymode
> is a nested attribute set under `keymode` that contains its own bindings.
**Type:** `Mango configuration value`
**Default:** `{ }`
**Example:** *Type:*
Mango configuration value
*Default:*
```nix
{ }
```
*Example:*
```nix ```nix
{ {
# Window effects # Window effects
@ -193,39 +330,72 @@ quoted. See <https://mangowm.github.io/docs> for more examples.
}; };
}; };
} }
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### `systemd.enable`
Whether to enable `mango-session.target` on
mango startup. This links to ### systemd\.enable
`graphical-session.target`.
Whether to enable ` mango-session.target ` on
mango startup\. This links to
` graphical-session.target `\.
Some important environment variables will be imported to systemd Some important environment variables will be imported to systemd
and dbus user environment before reaching the target, including and dbus user environment before reaching the target, including
* `DISPLAY`
* `WAYLAND_DISPLAY`
* `XDG_CURRENT_DESKTOP`
* `XDG_SESSION_TYPE`
* `NIXOS_OZONE_WL`
You can extend this list using the `systemd.variables` option.
**Type:** `boolean` - ` DISPLAY `
- ` WAYLAND_DISPLAY `
- ` XDG_CURRENT_DESKTOP `
- ` XDG_SESSION_TYPE `
- ` NIXOS_OZONE_WL `
You can extend this list using the ` systemd.variables ` option\.
**Default:** `true`
**Example:** `false`
--- *Type:*
boolean
### `systemd.extraCommands`
Extra commands to run after D-Bus activation.
**Type:** `list of string` *Default:*
```nix
true
```
*Example:*
```nix
false
```
*Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### systemd\.extraCommands
Extra commands to run after D-Bus activation\.
*Type:*
list of string
*Default:*
**Default:**
```nix ```nix
[ [
"systemctl --user reset-failed" "systemctl --user reset-failed"
@ -233,15 +403,26 @@ Extra commands to run after D-Bus activation.
] ]
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### `systemd.variables`
Environment variables imported into the systemd and D-Bus user environment.
**Type:** `list of string` ### systemd\.variables
Environment variables imported into the systemd and D-Bus user environment\.
*Type:*
list of string
*Default:*
**Default:**
```nix ```nix
[ [
"DISPLAY" "DISPLAY"
@ -254,43 +435,85 @@ Environment variables imported into the systemd and D-Bus user environment.
] ]
``` ```
**Example:**
*Example:*
```nix ```nix
[ [
"--all" "--all"
] ]
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### systemd\.xdgAutostart
### `systemd.xdgAutostart`
Whether to enable autostart of applications using Whether to enable autostart of applications using
`systemd-xdg-autostart-generator(8)`. ` systemd-xdg-autostart-generator(8) `
\.
**Type:** `boolean`
**Default:** `false`
**Example:** `true` *Type:*
boolean
---
### `topPrefixes`
List of prefixes for attributes that should appear at the top of the config file. *Default:*
Attributes starting with these prefixes will be sorted to the beginning.
**Type:** `list of string` ```nix
false
```
**Default:** `[ ]`
**Example:**
*Example:*
```nix
true
```
*Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)
### topPrefixes
List of prefixes for attributes that should appear at the top of the config file\.
Attributes starting with these prefixes will be sorted to the beginning\.
*Type:*
list of string
*Default:*
```nix
[ ]
```
*Example:*
```nix ```nix
[ [
"source" "source"
] ]
``` ```
--- *Declared by:*
- [\<mango/nix/hm-modules\.nix>](https://github.com/mangowm/mango/blob/main/nix/hm-modules.nix)

View file

@ -6,6 +6,9 @@ self:
optionPrefix, optionPrefix,
}: }:
let let
# Absolute store path of the flake root, used to compute relative subpaths
repoPath = toString self;
eval = lib.evalModules { eval = lib.evalModules {
modules = [ modules = [
(import module self) (import module self)
@ -14,6 +17,15 @@ let
specialArgs = { inherit pkgs; }; specialArgs = { inherit pkgs; };
}; };
# Relative path of the module file within the repo (e.g. "nix/hm-modules.nix")
moduleSubpath = lib.removePrefix "/" (lib.removePrefix repoPath (toString module));
# Declaration entry linking each option back to its source file on GitHub
moduleDeclaration = {
url = "https://github.com/mangowm/mango/blob/main/${moduleSubpath}";
name = "<mango/${moduleSubpath}>";
};
optionsDoc = pkgs.nixosOptionsDoc { optionsDoc = pkgs.nixosOptionsDoc {
options = eval.options; options = eval.options;
transformOptions = transformOptions =
@ -21,7 +33,9 @@ let
opt opt
// { // {
visible = opt.visible && !opt.internal; visible = opt.visible && !opt.internal;
# Strip the option prefix so docs show "enable" instead of "programs.mango.enable"
name = lib.removePrefix optionPrefix opt.name; name = lib.removePrefix optionPrefix opt.name;
declarations = [ moduleDeclaration ];
}; };
}; };
in in