From 01f701cb1b955c162dde212d8a38a58948e050ee Mon Sep 17 00:00:00 2001 From: Sk7Str1p3 Date: Sun, 19 Apr 2026 22:58:59 +0300 Subject: [PATCH] feat: documentation generation --- docs/book.toml | 5 ++ docs/default.nix | 29 +++++++++++ docs/docgen.nix | 122 ++++++++++++++++++++++++++++++++++++++++++++++ docs/src/404.md | 3 ++ flake/default.nix | 1 + 5 files changed, 160 insertions(+) create mode 100644 docs/book.toml create mode 100644 docs/default.nix create mode 100644 docs/docgen.nix create mode 100644 docs/src/404.md diff --git a/docs/book.toml b/docs/book.toml new file mode 100644 index 0000000..ad11955 --- /dev/null +++ b/docs/book.toml @@ -0,0 +1,5 @@ +[book] +title = "SkyOS Documentation" +authors = ["Sk7Str1p3"] +description = "Documentation for Sk7Str1p3's custom NixOS configuration" +language = "en" diff --git a/docs/default.nix b/docs/default.nix new file mode 100644 index 0000000..6c321c3 --- /dev/null +++ b/docs/default.nix @@ -0,0 +1,29 @@ +# Documentation +/** + Docs are generated from comments in `.nix` files. + This results in kind of weird config format, but + makes it easier to track configuration changes + and add/remove docs as required. + + ## How docs are generated + + `nixdoc` utility enables us to generate documentation + from comments in `.nix` file, like `doxygen` and `rustdoc` do. + + `nixdoc` requires this flags: + - category (derived from file's path) + - description (derived from file's first line if it's commented) + + most hard part is to generate SUMMARY.md. + generator uses orderKey of type "{num}|{mdPath}" and derives indentation from path's depth, + so chapters have proper order. + + run `nix build .#docBuild` to build documentation +*/ +{ + perSystem = + { pkgs, ... }: + rec { + packages.docBuild = pkgs.callPackage ../docs/docgen.nix { }; + }; +} diff --git a/docs/docgen.nix b/docs/docgen.nix new file mode 100644 index 0000000..e5e1b9e --- /dev/null +++ b/docs/docgen.nix @@ -0,0 +1,122 @@ +{ + stdenvNoCC, + mdbook, + nixdoc, + lib, +}: +stdenvNoCC.mkDerivation { + name = "SkyOS-book"; + src = ./.; + buildInputs = [ + mdbook + nixdoc + ]; + patchPhase = + let + excluded = [ + ".*flake\\.nix$" + + "docs/docgen.nix" + ]; + + shouldExclude = relPath: lib.any (pattern: builtins.match pattern relPath != null) excluded; + + nixFiles = + with lib.fileset; + let + allFiles = toList (fileFilter (f: f.hasExt "nix") ../.); + in + lib.filter ( + file: + let + relPath = lib.removePrefix (toString ../. + "/") (toString file); + in + !shouldExclude relPath + ) allFiles; + + chapters = lib.sort (a: b: a.sortKey < b.sortKey) ( + map ( + file: + let + + relPath = lib.removePrefix (toString ../. + "/") (toString file); + mdPath = + ( + if baseNameOf file == "default.nix" then + lib.removeSuffix "/" (dirOf relPath) + else + lib.removeSuffix ".nix" relPath + ) + + ".md"; + + orderMap = { + docs = 0; + flake = 1; + devShells = 2; + }; + order = orderMap.${lib.head (lib.splitString "/" relPath)}; + + category = lib.removeSuffix ".md" (lib.replaceStrings [ "/" ] [ "." ] mdPath); + title = + let + head = builtins.head (lib.splitString "\n" (builtins.readFile file)); + in + if builtins.match "^# (.*)" head != null then + lib.trim (lib.removePrefix "#" head) + else + lib.removeSuffix ".nix" (baseNameOf file); + + depth = + let + dirPart = dirOf mdPath; + in + if dirPart == "." then 0 else lib.length (lib.splitString "/" dirPart); + indent = lib.concatStringsSep "" (lib.genList (x: " ") depth); + in + { + script = '' + mkdir -p "src/${dirOf mdPath}" + nixdoc \ + --prefix "" \ + --category "${category}" \ + --description "${title}" \ + --anchor-prefix "" \ + --file "${file}" > "src/${mdPath}" + ''; + summaryLine = "${indent}- [${title}](${mdPath})"; + sortKey = builtins.toString order + mdPath; + } + ) nixFiles + ); + + summaryContent = + "# Summary\n\n" + + "[Introduction](README.md)\n" + + builtins.concatStringsSep "\n" (map (c: c.summaryLine) chapters) + + "\n"; + + nixdocScripts = builtins.concatStringsSep "\n" (map (c: c.script) chapters); + in + '' + cp ${../README.md} src/README.md + cp -r ${../assets} src/assets + cp src/assets/logo.png theme/favicon.png + + ${nixdocScripts} + + cat > src/SUMMARY.md <