doc/nav: add explicit ids to every doc resource

We need stable resource ids for docs.nixos.org
this commit enrolls initial resource ids for every documented 'thing'

leaf id are inert for now
group ids are targets for open state

html output is not effected by this change yet
This commit is contained in:
Johannes Kirschbauer
2026-10-04 13:14:29 +02:00
parent f9a6e5bba8
commit 09e0ae43ef
5 changed files with 361 additions and 44 deletions

View File

@@ -2,598 +2,776 @@
"open": [],
"items": [
{
"id": "preface",
"file": "preface.chapter.md"
},
{
"label": "Getting started",
"id": "getting-started",
"label": "Getting started",
"children": [
{
"id": "index",
"file": "getting-started/getting-started.part.md"
},
{
"id": "first-package",
"file": "getting-started/first-package.chapter.md"
},
{
"id": "dev-environments",
"file": "getting-started/dev-environments.md"
}
]
},
{
"label": "Guides",
"id": "guides",
"label": "Guides",
"children": [
{
"id": "using-nixpkgs",
"file": "using-nixpkgs.md"
},
{
"id": "channels",
"file": "channels.chapter.md"
},
{
"id": "platform-support",
"file": "using/platform-support.chapter.md"
},
{
"id": "configuration",
"file": "using/configuration.chapter.md"
},
{
"id": "overlays",
"file": "using/overlays.chapter.md"
},
{
"id": "overrides",
"file": "using/overrides.chapter.md"
},
{
"id": "stdenv",
"label": "Standard environment",
"id": "part-stdenv",
"children": [
{
"id": "index",
"file": "stdenv.md"
},
{
"id": "stdenv",
"file": "stdenv/stdenv.chapter.md"
},
{
"id": "meta",
"file": "stdenv/meta.chapter.md"
},
{
"id": "passthru",
"file": "stdenv/passthru.chapter.md"
},
{
"id": "multiple-output",
"file": "stdenv/multiple-output.chapter.md"
},
{
"id": "cross-compilation",
"file": "stdenv/cross-compilation.chapter.md"
},
{
"id": "platform-notes",
"file": "stdenv/platform-notes.chapter.md"
}
]
},
{
"id": "languages",
"label": "Languages and frameworks",
"id": "chap-language-support",
"children": [
{
"id": "index",
"file": "languages-frameworks/index.md"
},
{
"id": "agda",
"file": "languages-frameworks/agda.section.md"
},
{
"id": "android",
"file": "languages-frameworks/android.section.md"
},
{
"id": "astal",
"file": "languages-frameworks/astal.section.md"
},
{
"id": "beam",
"file": "languages-frameworks/beam.section.md"
},
{
"id": "chicken",
"file": "languages-frameworks/chicken.section.md"
},
{
"id": "cosmic",
"file": "languages-frameworks/cosmic.section.md"
},
{
"id": "crystal",
"file": "languages-frameworks/crystal.section.md"
},
{
"id": "cuda",
"file": "languages-frameworks/cuda.section.md"
},
{
"id": "cuelang",
"file": "languages-frameworks/cuelang.section.md"
},
{
"id": "dart",
"file": "languages-frameworks/dart.section.md"
},
{
"id": "dhall",
"file": "languages-frameworks/dhall.section.md"
},
{
"id": "dlang",
"file": "languages-frameworks/dlang.section.md"
},
{
"id": "dotnet",
"file": "languages-frameworks/dotnet.section.md"
},
{
"id": "emscripten",
"file": "languages-frameworks/emscripten.section.md"
},
{
"id": "factor",
"file": "languages-frameworks/factor.section.md"
},
{
"id": "gnome",
"file": "languages-frameworks/gnome.section.md"
},
{
"id": "go",
"file": "languages-frameworks/go.section.md"
},
{
"id": "gradle",
"file": "languages-frameworks/gradle.section.md"
},
{
"id": "hare",
"file": "languages-frameworks/hare.section.md"
},
{
"id": "haskell",
"file": "languages-frameworks/haskell.section.md"
},
{
"id": "hy",
"file": "languages-frameworks/hy.section.md"
},
{
"id": "idris",
"file": "languages-frameworks/idris.section.md"
},
{
"id": "idris2",
"file": "languages-frameworks/idris2.section.md"
},
{
"id": "ios",
"file": "languages-frameworks/ios.section.md"
},
{
"id": "java",
"file": "languages-frameworks/java.section.md"
},
{
"id": "javascript",
"file": "languages-frameworks/javascript.section.md"
},
{
"id": "julia",
"file": "languages-frameworks/julia.section.md"
},
{
"id": "lean4",
"file": "languages-frameworks/lean4.section.md"
},
{
"id": "lisp",
"file": "languages-frameworks/lisp.section.md"
},
{
"id": "lua",
"file": "languages-frameworks/lua.section.md"
},
{
"id": "maven",
"file": "languages-frameworks/maven.section.md"
},
{
"id": "nim",
"file": "languages-frameworks/nim.section.md"
},
{
"id": "ocaml",
"file": "languages-frameworks/ocaml.section.md"
},
{
"id": "octave",
"file": "languages-frameworks/octave.section.md"
},
{
"id": "perl",
"file": "languages-frameworks/perl.section.md"
},
{
"id": "php",
"file": "languages-frameworks/php.section.md"
},
{
"id": "pkg-config",
"file": "languages-frameworks/pkg-config.section.md"
},
{
"id": "python",
"file": "languages-frameworks/python.section.md"
},
{
"id": "qt",
"file": "languages-frameworks/qt.section.md"
},
{
"id": "r",
"file": "languages-frameworks/r.section.md"
},
{
"id": "rocq",
"file": "languages-frameworks/rocq.section.md"
},
{
"id": "ruby",
"file": "languages-frameworks/ruby.section.md"
},
{
"id": "rust",
"file": "languages-frameworks/rust.section.md"
},
{
"id": "scheme",
"file": "languages-frameworks/scheme.section.md"
},
{
"id": "swift",
"file": "languages-frameworks/swift.section.md"
},
{
"id": "tcl",
"file": "languages-frameworks/tcl.section.md"
},
{
"id": "texlive",
"file": "languages-frameworks/texlive.section.md"
},
{
"id": "typst",
"file": "languages-frameworks/typst.section.md"
},
{
"id": "vim",
"file": "languages-frameworks/vim.section.md"
},
{
"id": "neovim",
"file": "languages-frameworks/neovim.section.md"
}
]
},
{
"id": "toolchains",
"label": "Toolchains",
"id": "part-toolchains",
"children": [
{
"id": "index",
"file": "toolchains.md"
},
{
"id": "llvm",
"file": "toolchains/llvm.chapter.md"
}
]
},
{
"id": "build-helpers",
"label": "Build helpers",
"id": "part-builders",
"children": [
{
"id": "index",
"file": "build-helpers.md"
},
{
"id": "fixed-point-arguments",
"file": "build-helpers/fixed-point-arguments.chapter.md"
},
{
"id": "fetchers",
"file": "build-helpers/fetchers.chapter.md"
},
{
"id": "trivial-build-helpers",
"file": "build-helpers/trivial-build-helpers.chapter.md"
},
{
"id": "testers",
"file": "build-helpers/testers.chapter.md"
},
{
"id": "dev-shell-tools",
"file": "build-helpers/dev-shell-tools.chapter.md"
},
{
"id": "special",
"label": "Special build helpers",
"id": "chap-special",
"children": [
{
"id": "index",
"file": "build-helpers/special.md"
},
{
"id": "buildenv",
"file": "build-helpers/special/buildenv.section.md"
},
{
"id": "fakenss",
"file": "build-helpers/special/fakenss.section.md"
},
{
"id": "fhs-environments",
"file": "build-helpers/special/fhs-environments.section.md"
},
{
"id": "makesetuphook",
"file": "build-helpers/special/makesetuphook.section.md"
},
{
"id": "mkshell",
"file": "build-helpers/special/mkshell.section.md"
},
{
"id": "vm-tools",
"file": "build-helpers/special/vm-tools.section.md"
},
{
"id": "checkpoint-build",
"file": "build-helpers/special/checkpoint-build.section.md"
}
]
},
{
"id": "images",
"label": "Images",
"id": "chap-images",
"children": [
{
"id": "index",
"file": "build-helpers/images.md"
},
{
"id": "appimagetools",
"file": "build-helpers/images/appimagetools.section.md"
},
{
"id": "dockertools",
"file": "build-helpers/images/dockertools.section.md"
},
{
"id": "ocitools",
"file": "build-helpers/images/ocitools.section.md"
},
{
"id": "portableservice",
"file": "build-helpers/images/portableservice.section.md"
},
{
"id": "makediskimage",
"file": "build-helpers/images/makediskimage.section.md"
},
{
"id": "binarycache",
"file": "build-helpers/images/binarycache.section.md"
}
]
},
{
"id": "hooks",
"label": "Hooks reference",
"id": "chap-hooks",
"children": [
{
"id": "index",
"file": "hooks/index.md"
},
{
"id": "autoconf",
"file": "hooks/autoconf.section.md"
},
{
"id": "automake",
"file": "hooks/automake.section.md"
},
{
"id": "autopatchcil",
"file": "hooks/autopatchcil.section.md"
},
{
"id": "autopatchelf",
"file": "hooks/autopatchelf.section.md"
},
{
"id": "aws-c-common",
"file": "hooks/aws-c-common.section.md"
},
{
"id": "bmake",
"file": "hooks/bmake.section.md"
},
{
"id": "breakpoint",
"file": "hooks/breakpoint.section.md"
},
{
"id": "cernlib",
"file": "hooks/cernlib.section.md"
},
{
"id": "check-phase-thread-limit-hook",
"file": "hooks/check-phase-thread-limit-hook.section.md"
},
{
"id": "cmake",
"file": "hooks/cmake.section.md"
},
{
"id": "desktop-file-utils",
"file": "hooks/desktop-file-utils.section.md"
},
{
"id": "gdk-pixbuf",
"file": "hooks/gdk-pixbuf.section.md"
},
{
"id": "gnome",
"file": "hooks/gnome.section.md"
},
{
"id": "haredo",
"file": "hooks/haredo.section.md"
},
{
"id": "installagentskills",
"file": "hooks/installAgentSkills.section.md"
},
{
"id": "installshellfiles",
"file": "hooks/installShellFiles.section.md"
},
{
"id": "installfonts",
"file": "hooks/installFonts.section.md"
},
{
"id": "juce",
"file": "hooks/juce.section.md"
},
{
"id": "julec",
"file": "hooks/julec.section.md"
},
{
"id": "just",
"file": "hooks/just.section.md"
},
{
"id": "libglycin",
"file": "hooks/libglycin.section.md"
},
{
"id": "libiconv",
"file": "hooks/libiconv.section.md"
},
{
"id": "libxml2",
"file": "hooks/libxml2.section.md"
},
{
"id": "memcached-test-hook",
"file": "hooks/memcached-test-hook.section.md"
},
{
"id": "meson",
"file": "hooks/meson.section.md"
},
{
"id": "mpi-check-hook",
"file": "hooks/mpi-check-hook.section.md"
},
{
"id": "ninja",
"file": "hooks/ninja.section.md"
},
{
"id": "nodejs-install-executables",
"file": "hooks/nodejs-install-executables.section.md"
},
{
"id": "nodejs-install-manuals",
"file": "hooks/nodejs-install-manuals.section.md"
},
{
"id": "npm-build-hook",
"file": "hooks/npm-build-hook.section.md"
},
{
"id": "npm-config-hook",
"file": "hooks/npm-config-hook.section.md"
},
{
"id": "npm-install-hook",
"file": "hooks/npm-install-hook.section.md"
},
{
"id": "patch-rc-path-hooks",
"file": "hooks/patch-rc-path-hooks.section.md"
},
{
"id": "perl",
"file": "hooks/perl.section.md"
},
{
"id": "pkg-config",
"file": "hooks/pkg-config.section.md"
},
{
"id": "postgresql-test-hook",
"file": "hooks/postgresql-test-hook.section.md"
},
{
"id": "premake",
"file": "hooks/premake.section.md"
},
{
"id": "python",
"file": "hooks/python.section.md"
},
{
"id": "redis-test-hook",
"file": "hooks/redis-test-hook.section.md"
},
{
"id": "scons",
"file": "hooks/scons.section.md"
},
{
"id": "tauri",
"file": "hooks/tauri.section.md"
},
{
"id": "tetex-tex-live",
"file": "hooks/tetex-tex-live.section.md"
},
{
"id": "udevcheckhook",
"file": "hooks/udevCheckHook.section.md"
},
{
"id": "unzip",
"file": "hooks/unzip.section.md"
},
{
"id": "validatepkgconfig",
"file": "hooks/validatePkgConfig.section.md"
},
{
"id": "versioncheckhook",
"file": "hooks/versionCheckHook.section.md"
},
{
"id": "waf",
"file": "hooks/waf.section.md"
},
{
"id": "writable-tmpdir-as-home-hook",
"file": "hooks/writable-tmpdir-as-home-hook.section.md"
},
{
"id": "zig",
"file": "hooks/zig.section.md"
},
{
"id": "xcbuild",
"file": "hooks/xcbuild.section.md"
},
{
"id": "xfce4-dev-tools",
"file": "hooks/xfce4-dev-tools.section.md"
}
]
},
{
"id": "packages",
"label": "Packages",
"id": "chap-packages",
"children": [
{
"id": "index",
"file": "packages/index.md"
},
{
"id": "citrix",
"file": "packages/citrix.section.md"
},
{
"id": "darwin-builder",
"file": "packages/darwin-builder.section.md"
},
{
"id": "dlib",
"file": "packages/dlib.section.md"
},
{
"id": "eclipse",
"file": "packages/eclipse.section.md"
},
{
"id": "elm",
"file": "packages/elm.section.md"
},
{
"id": "emacs",
"file": "packages/emacs.section.md"
},
{
"id": "firefox",
"file": "packages/firefox.section.md"
},
{
"id": "friction-graphics",
"file": "packages/friction-graphics.section.md"
},
{
"id": "fish",
"file": "packages/fish.section.md"
},
{
"id": "fuse",
"file": "packages/fuse.section.md"
},
{
"id": "geant4",
"file": "packages/geant4.section.md"
},
{
"id": "ibus",
"file": "packages/ibus.section.md"
},
{
"id": "inkscape",
"file": "packages/inkscape.section.md"
},
{
"id": "kakoune",
"file": "packages/kakoune.section.md"
},
{
"id": "krita",
"file": "packages/krita.section.md"
},
{
"id": "linux",
"file": "packages/linux.section.md"
},
{
"id": "lhapdf",
"file": "packages/lhapdf.section.md"
},
{
"id": "locales",
"file": "packages/locales.section.md"
},
{
"id": "etc-files",
"file": "packages/etc-files.section.md"
},
{
"id": "nginx",
"file": "packages/nginx.section.md"
},
{
"id": "nrfutil",
"file": "packages/nrfutil.section.md"
},
{
"id": "opengl",
"file": "packages/opengl.section.md"
},
{
"id": "packer",
"file": "packages/packer.section.md"
},
{
"id": "shell-helpers",
"file": "packages/shell-helpers.section.md"
},
{
"id": "python-tree-sitter",
"file": "packages/python-tree-sitter.section.md"
},
{
"label": "treefmt",
"id": "treefmt",
"label": "treefmt",
"children": [
{
"id": "index",
"file": "packages/treefmt.section.md"
},
{
"id": "treefmt-functions",
"id-prefix": "auto-generated-treefmt-functions",
"file": "packages/treefmt-functions.section.md"
}
]
},
{
"id": "steam",
"file": "packages/steam.section.md"
},
{
"id": "cataclysm-dda",
"file": "packages/cataclysm-dda.section.md"
},
{
"id": "urxvt",
"file": "packages/urxvt.section.md"
},
{
"id": "vcpkg",
"file": "packages/vcpkg.section.md"
},
{
"id": "weechat",
"file": "packages/weechat.section.md"
},
{
"id": "uv",
"file": "packages/uv.section.md"
},
{
"id": "build-support",
"file": "packages/build-support.md"
}
]
@@ -601,13 +779,15 @@
]
},
{
"label": "Modules",
"id": "modules",
"label": "Modules",
"children": [
{
"id": "index",
"file": "modules/index.md"
},
{
"id": "generic",
"file": "modules/generic.chapter.md"
}
]
@@ -615,16 +795,19 @@
]
},
{
"label": "Reference",
"id": "reference",
"label": "Reference",
"children": [
{
"id": "lib",
"file": "lib.md"
},
{
"id": "functions",
"file": "functions.md"
},
{
"id": "library",
"file": "functions/library.md"
},
{
@@ -632,28 +815,35 @@
"type": "nixdoc"
},
{
"id": "generators",
"file": "functions/generators.section.md"
},
{
"id": "debug",
"file": "functions/debug.section.md"
},
{
"id": "prefer-remote-fetch",
"file": "functions/prefer-remote-fetch.section.md"
},
{
"id": "nix-gitignore",
"file": "functions/nix-gitignore.section.md"
},
{
"id": "module-system",
"file": "module-system/module-system.chapter.md"
},
{
"id": "interoperability",
"label": "Interoperability Standards",
"id": "part-interoperability",
"children": [
{
"id": "index",
"file": "interoperability.md"
},
{
"id": "cyclonedx",
"file": "interoperability/cyclonedx.md"
}
]
@@ -661,6 +851,7 @@
]
},
{
"id": "contributing",
"file": "contributing.md"
}
]

View File

@@ -18,6 +18,7 @@ let
evalModules
hasPrefix
removePrefix
removeSuffix
flip
foldr
types
@@ -41,6 +42,13 @@ let
prefixesToStrip = map (p: "${toString p}/") ([ prefix ] ++ extraSources);
stripAnyPrefixes = flip (foldr removePrefix) prefixesToStrip;
moduleChapterId =
p:
let
stem = removeSuffix ".nix" (baseNameOf p.file);
in
if stem == "default" then baseNameOf (dirOf p.file) else stem;
optionsDoc = buildPackages.nixosOptionsDoc {
inherit
options
@@ -113,7 +121,9 @@ let
--replace-fail \
'"@MODULE_CHAPTERS@"' \
${escapeShellArg (
concatMapStringsSep ",\n" (p: ''{ "file": "${p.value}" }'') (sortOn (p: p.file) config.meta.doc)
concatMapStringsSep ",\n" (p: ''{ "id": "${moduleChapterId p}", "file": "${p.value}" }'') (
sortOn (p: p.file) config.meta.doc
)
)}
substituteInPlace ./nixos-options.md \
--replace-fail \

View File

@@ -2,251 +2,311 @@
"open": [],
"items": [
{
"id": "preface",
"file": "preface.md"
},
{
"id": "getting-started",
"label": "Getting started",
"id": "ch-installation",
"children": [
{
"id": "index",
"file": "installation/installation.md"
},
{
"id": "obtaining",
"file": "installation/obtaining.chapter.md"
},
{
"id": "installing",
"label": "Installing NixOS",
"id": "sec-installation",
"children": [
{
"id": "index",
"file": "installation/installing.chapter.md"
},
{
"id": "installing-usb",
"file": "installation/installing-usb.section.md"
},
{
"id": "installing-pxe",
"file": "installation/installing-pxe.section.md"
},
{
"id": "installing-kexec",
"file": "installation/installing-kexec.section.md"
},
{
"id": "installing-virtualbox-guest",
"file": "installation/installing-virtualbox-guest.section.md"
},
{
"id": "installing-from-other-distro",
"file": "installation/installing-from-other-distro.section.md"
},
{
"id": "installing-behind-a-proxy",
"file": "installation/installing-behind-a-proxy.section.md"
}
]
},
{
"id": "changing-config",
"file": "installation/changing-config.chapter.md"
},
{
"id": "upgrading",
"file": "installation/upgrading.chapter.md"
}
]
},
{
"id": "guides",
"label": "Guides",
"id": "ch-configuration",
"children": [
{
"id": "index",
"file": "configuration/configuration.md"
},
{
"id": "configuration-syntax",
"label": "Configuration Syntax",
"id": "sec-configuration-syntax",
"children": [
{
"id": "index",
"file": "configuration/config-syntax.chapter.md"
},
{
"id": "config-file",
"file": "configuration/config-file.section.md"
},
{
"id": "abstractions",
"file": "configuration/abstractions.section.md"
},
{
"id": "modularity",
"file": "configuration/modularity.section.md"
}
]
},
{
"id": "package-management",
"label": "Package Management",
"id": "sec-package-management",
"children": [
{
"id": "index",
"file": "configuration/package-mgmt.chapter.md"
},
{
"id": "declarative-packages",
"file": "configuration/declarative-packages.section.md"
},
{
"id": "customizing-packages",
"file": "configuration/customizing-packages.section.md"
},
{
"id": "adding-custom-packages",
"file": "configuration/adding-custom-packages.section.md"
},
{
"id": "ad-hoc-packages",
"file": "configuration/ad-hoc-packages.section.md"
}
]
},
{
"id": "user-mgmt",
"file": "configuration/user-mgmt.chapter.md"
},
{
"id": "file-systems",
"label": "File Systems",
"id": "ch-file-systems",
"children": [
{
"id": "index",
"file": "configuration/file-systems.chapter.md"
},
{
"id": "luks-file-systems",
"file": "configuration/luks-file-systems.section.md"
},
{
"id": "sshfs-file-systems",
"file": "configuration/sshfs-file-systems.section.md"
},
{
"id": "nfs-file-systems",
"file": "configuration/nfs-file-systems.section.md"
},
{
"id": "overlayfs",
"file": "configuration/overlayfs.section.md"
}
]
},
{
"id": "networking",
"label": "Networking",
"id": "sec-networking",
"children": [
{
"id": "index",
"file": "configuration/networking.chapter.md"
},
{
"id": "network-manager",
"file": "configuration/network-manager.section.md"
},
{
"id": "ssh",
"file": "configuration/ssh.section.md"
},
{
"id": "ipv4-config",
"file": "configuration/ipv4-config.section.md"
},
{
"id": "ipv6-config",
"file": "configuration/ipv6-config.section.md"
},
{
"id": "firewall",
"file": "configuration/firewall.section.md"
},
{
"id": "wireless",
"file": "configuration/wireless.section.md"
},
{
"id": "ad-hoc-network-config",
"file": "configuration/ad-hoc-network-config.section.md"
},
{
"id": "renaming-interfaces",
"file": "configuration/renaming-interfaces.section.md"
}
]
},
{
"id": "desktops",
"label": "Graphical Desktops",
"id": "sec-x11",
"children": [
{
"id": "index",
"file": "configuration/x-windows.chapter.md"
},
{
"id": "wayland",
"file": "configuration/wayland.chapter.md"
},
{
"id": "gpu-accel",
"file": "configuration/gpu-accel.chapter.md"
},
{
"id": "xfce",
"file": "configuration/xfce.chapter.md"
}
]
},
{
"id": "building-images",
"label": "Building Images",
"id": "sec-building-image",
"children": [
{
"id": "index",
"file": "installation/building-nixos.chapter.md"
},
{
"id": "building-images-via-nixos-rebuild-build-image",
"file": "installation/building-images-via-nixos-rebuild-build-image.chapter.md"
},
{
"id": "building-images-via-systemd-repart",
"file": "installation/building-images-via-systemd-repart.chapter.md"
}
]
},
{
"id": "administration",
"label": "Administration",
"id": "ch-running",
"children": [
{
"id": "index",
"file": "administration/running.md"
},
{
"id": "service-mgmt",
"file": "administration/service-mgmt.chapter.md"
},
{
"id": "rebooting",
"file": "administration/rebooting.chapter.md"
},
{
"id": "user-sessions",
"file": "administration/user-sessions.chapter.md"
},
{
"id": "logging",
"file": "administration/logging.chapter.md"
},
{
"id": "cleaning-store",
"file": "administration/cleaning-store.chapter.md"
}
]
},
{
"id": "containers",
"label": "Container Management",
"id": "ch-containers",
"children": [
{
"id": "index",
"file": "administration/containers.chapter.md"
},
{
"id": "imperative-containers",
"file": "administration/imperative-containers.section.md"
},
{
"id": "declarative-containers",
"file": "administration/declarative-containers.section.md"
},
{
"id": "container-networking",
"file": "administration/container-networking.section.md"
}
]
},
{
"id": "troubleshooting",
"label": "Troubleshooting",
"id": "ch-troubleshooting",
"children": [
{
"id": "index",
"file": "administration/troubleshooting.chapter.md"
},
{
"id": "boot-problems",
"file": "administration/boot-problems.section.md"
},
{
"id": "maintenance-mode",
"file": "administration/maintenance-mode.section.md"
},
{
"id": "rollback",
"file": "administration/rollback.section.md"
},
{
"id": "store-corruption",
"file": "administration/store-corruption.section.md"
},
{
"id": "network-problems",
"file": "administration/network-problems.section.md"
}
]
@@ -254,212 +314,266 @@
]
},
{
"id": "services",
"label": "Services and Programs",
"id": "ch-services",
"children": [
{
"id": "index",
"file": "services.md"
},
"@MODULE_CHAPTERS@",
{
"id": "subversion",
"file": "configuration/subversion.chapter.md"
},
{
"id": "mattermost",
"file": "configuration/mattermost.chapter.md"
},
{
"id": "kubernetes",
"file": "configuration/kubernetes.chapter.md"
}
]
},
{
"id": "reference",
"label": "Reference",
"id": "ch-reference",
"children": [
{
"id": "index",
"file": "reference.md"
},
{
"id": "profiles",
"label": "Profiles",
"id": "ch-profiles",
"children": [
{
"id": "index",
"file": "configuration/profiles.chapter.md"
},
{
"id": "all-hardware",
"file": "configuration/profiles/all-hardware.section.md"
},
{
"id": "base",
"file": "configuration/profiles/base.section.md"
},
{
"id": "clone-config",
"file": "configuration/profiles/clone-config.section.md"
},
{
"id": "demo",
"file": "configuration/profiles/demo.section.md"
},
{
"id": "docker-container",
"file": "configuration/profiles/docker-container.section.md"
},
{
"id": "graphical",
"file": "configuration/profiles/graphical.section.md"
},
{
"id": "headless",
"file": "configuration/profiles/headless.section.md"
},
{
"id": "installation-device",
"file": "configuration/profiles/installation-device.section.md"
},
{
"id": "perlless",
"file": "configuration/profiles/perlless.section.md"
},
{
"id": "minimal",
"file": "configuration/profiles/minimal.section.md"
},
{
"id": "qemu-guest",
"file": "configuration/profiles/qemu-guest.section.md"
}
]
},
{
"id": "linux-kernel",
"file": "configuration/linux-kernel.chapter.md"
},
{
"id": "system-state",
"label": "Necessary system state",
"id": "ch-system-state",
"children": [
{
"id": "index",
"file": "administration/system-state.chapter.md"
},
{
"id": "nixos-state",
"file": "administration/nixos-state.section.md"
},
{
"id": "systemd-state",
"file": "administration/systemd-state.section.md"
},
{
"id": "zfs-state",
"file": "administration/zfs-state.section.md"
}
]
},
{
"id": "system-switch",
"label": "What happens during a system switch?",
"id": "sec-switching-systems",
"children": [
{
"id": "index",
"file": "development/what-happens-during-a-system-switch.chapter.md"
},
{
"id": "unit-handling",
"file": "development/unit-handling.section.md"
},
{
"id": "activation-script",
"file": "development/activation-script.section.md"
},
{
"id": "non-switchable-systems",
"file": "development/non-switchable-systems.section.md"
},
{
"id": "etc-overlay",
"file": "development/etc-overlay.section.md"
}
]
},
{
"id": "control-groups",
"file": "administration/control-groups.chapter.md"
},
{
"id": "bootspec",
"file": "development/bootspec.chapter.md"
},
{
"id": "modular-services",
"file": "development/modular-services.md"
}
]
},
{
"id": "contributing",
"label": "Contributing",
"id": "ch-development",
"children": [
{
"id": "index",
"file": "development/development.md"
},
{
"id": "sources",
"file": "development/sources.chapter.md"
},
{
"id": "writing-modules",
"label": "Writing NixOS Modules",
"id": "sec-writing-modules",
"children": [
{
"id": "index",
"file": "development/writing-modules.chapter.md"
},
{
"id": "option-declarations",
"file": "development/option-declarations.section.md"
},
{
"id": "option-types",
"file": "development/option-types.section.md"
},
{
"id": "option-def",
"file": "development/option-def.section.md"
},
{
"id": "assertions",
"file": "development/assertions.section.md"
},
{
"id": "meta-attributes",
"file": "development/meta-attributes.section.md"
},
{
"id": "importing-modules",
"file": "development/importing-modules.section.md"
},
{
"id": "replace-modules",
"file": "development/replace-modules.section.md"
},
{
"id": "freeform-modules",
"file": "development/freeform-modules.section.md"
},
{
"id": "settings-options",
"file": "development/settings-options.section.md"
},
{
"id": "state-revision",
"file": "development/state-revision.section.md"
}
]
},
{
"id": "nixos-tests",
"label": "NixOS Tests",
"id": "sec-nixos-tests",
"children": [
{
"id": "index",
"file": "development/nixos-tests.chapter.md"
},
{
"id": "writing-nixos-tests",
"file": "development/writing-nixos-tests.section.md"
},
{
"id": "running-nixos-tests",
"file": "development/running-nixos-tests.section.md"
},
{
"id": "running-nixos-tests-interactively",
"file": "development/running-nixos-tests-interactively.section.md"
},
{
"id": "linking-nixos-tests-to-packages",
"file": "development/linking-nixos-tests-to-packages.section.md"
},
{
"id": "testing-hardware-features",
"file": "development/testing-hardware-features.section.md"
}
]
},
{
"id": "building-parts",
"file": "development/building-parts.chapter.md"
},
{
"id": "developing-the-test-driver",
"file": "development/developing-the-test-driver.chapter.md"
},
{
"id": "testing-installer",
"file": "development/testing-installer.chapter.md"
},
{
"id": "writing-documentation",
"file": "development/writing-documentation.chapter.md"
},
{
"id": "contributing-to-this-manual",
"file": "contributing-to-this-manual.chapter.md"
}
]

View File

@@ -618,7 +618,7 @@ def _to_base26(n: int) -> str:
return (_to_base26(n // 26) if n > 26 else "") + chr(ord("A") + n % 26)
# lowercase words joined by dashes
_ID_SEGMENT = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*")
_ID_SEGMENT = re.compile(r"[a-z][a-z0-9]*(?:-[a-z0-9]+)*")
_NON_ALNUM = re.compile(r"[^a-z0-9]+")
def _id_segment(fname: str) -> str:
@@ -726,7 +726,7 @@ class HTMLConverter(BaseConverter[ManualHTMLRenderer]):
nid = item.get("id")
if nid:
if nid in seen:
raise SrcError(src=src, description=f"{where}: id must be unique, got {nid}")
raise SrcError(src=src, description=f"{where}: `id` must be unique within `children`, got duplicate `{nid!r}`")
seen.add(nid)
return nodes
@@ -763,7 +763,8 @@ class HTMLConverter(BaseConverter[ManualHTMLRenderer]):
if not isinstance(nid, str) or not _ID_SEGMENT.fullmatch(nid):
raise SrcError(
src=src,
description=f"{where}: 'id' must be lowercase letters, digits and dashes, got {nid!r}")
description=f"{where}: 'id' must be lowercase letters and digits optionally separated by dashes (regex {_ID_SEGMENT!r}), got {nid!r}"
)
if kinds[0] == 'file':
if not isinstance(item['file'], str):

View File

@@ -5,7 +5,6 @@ from html.entities import name2codepoint
from pathlib import Path
import pytest
from nixos_render_docs.manual import HTMLConverter, HTMLParameters
@@ -512,10 +511,12 @@ def test_config_id_prefix_fails(tmp_path: Path) -> None:
def test_config_id_must_be_url_safe(tmp_path: Path) -> None:
for bad in (
{"file": "intro.md"},
{"id": "Intro", "file": "intro.md"},
{"id": "a/b", "file": "intro.md"},
{"id": "", "file": "intro.md"},
{"file": "intro.md"}, # missing id
{"id": "Intro", "file": "intro.md"}, # No uppercase
{"id": "a/b", "file": "intro.md"}, # no "/" (or other special characters)
{"id": "", "file": "intro.md"}, # no empty strings
{"id": "0a", "file": "intro.md"}, # no leading number
{"id": "foo-bar-", "file": "intro.md"}, # no trailing -
):
with pytest.raises(RuntimeError) as excinfo:
_render_with_config(
@@ -523,7 +524,7 @@ def test_config_id_must_be_url_safe(tmp_path: Path) -> None:
{"items": [bad]},
{"intro.md": "# Introduction {#intro}\n\nBody.\n"},
)
assert "'id' must be lowercase letters, digits and dashes" in str(excinfo.value.__cause__)
assert "'id' must be lowercase letters and digits optionally separated by dashes" in str(excinfo.value.__cause__)
_NIXDOC_EXPORT = {