Skip to content

doc: init#1891

Merged
imincik merged 1 commit into
ngi-nix:mainfrom
ju1m:doc
Jan 22, 2026
Merged

doc: init#1891
imincik merged 1 commit into
ngi-nix:mainfrom
ju1m:doc

Conversation

@ju1m
Copy link
Copy Markdown

@ju1m ju1m commented Dec 8, 2025

This PR introduces a demo of what could be used to make documentation for NGIpkgs, currently three documents:

  • NGIpkgs User Manual
  • NGIpkgs Contributor Manual
  • NGIpkgs Options, generated from documentation bits in modules.

State

Based upon:

  • The tooling used by https://nix.dev:
    • MyST;
    • sphinx.
  • Custom MyST rendition of programs and services options from optionsNix.

Build and read with:

$ nix -L build -f . manuals.singlehtml
$ xdg-open result/index.html

$ nix -L build -f . manuals.html
$ xdg-open result/index.html

$ nix -L build -f . manuals.latexpdf
$ xdg-open result/NGIpkgs_*.pdf

$ nix -L build -f . manuals.man
$ man ./result/share/man/man5/*.5.gz

$ nix -L build -f . manuals.info
$ pinfo ./result/share/info/*.info

Related

RoadMap

  • Host the HTML rendition somewhere online.

Copy link
Copy Markdown
Contributor

@imincik imincik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ju1m , thanks for this PR. I am getting the principals of Diataxis now and it makes a sense for me. I think we can make a use of it. I'll create a user story for it.

@imincik
Copy link
Copy Markdown
Contributor

imincik commented Dec 11, 2025

User story created: #1893

@ju1m ju1m force-pushed the doc branch 4 times, most recently from 6d515aa to d81f918 Compare December 12, 2025 22:07
@ju1m ju1m force-pushed the doc branch 3 times, most recently from c8a17b1 to 485707a Compare December 27, 2025 15:19
@ju1m ju1m marked this pull request as ready for review January 6, 2026 06:34
@ju1m ju1m mentioned this pull request Jan 7, 2026
8 tasks
Copy link
Copy Markdown
Contributor

@eljamm eljamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only had a brief look at the manual entrypoint and will have a more in-depth one once these comments have been addressed and I can build it locally.

Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Copy link
Copy Markdown
Contributor

@eljamm eljamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are probably more things to address, but let's go through this step by step. I've included a patch for most of the things I reviewed for convenience:

0001-Review-suggestions.patch

From ac9e7ca0a18acade0b93b1dfed4b81743ca50248 Mon Sep 17 00:00:00 2001
From: eljamm <fedi.jamoussi@protonmail.ch>
Date: Thu, 8 Jan 2026 10:13:30 +0100
Subject: [PATCH] Review suggestions

---
 default.nix                    |   3 +-
 maintainers/shells/default.nix |  11 +++
 manuals/default.nix            | 125 +++++++++------------------------
 3 files changed, 45 insertions(+), 94 deletions(-)

diff --git a/default.nix b/default.nix
index 6dc3ac13..a52a8990 100644
--- a/default.nix
+++ b/default.nix
@@ -57,10 +57,9 @@ let
       options = self.optionsDoc.optionsNix;
     };
 
-    manuals = pkgs.callPackage manuals/default.nix rec {
+    manuals = self.call manuals/default.nix rec {
       version = "0.0.0"; # FixMe(maint): use something better, alas self.rev is not available there.
       revision = "release-${version}";
-      inherit (self.project-utils.raw-projects.config) projects;
       modulesPath = "${sources.nixpkgs}/nixos/modules";
     };
 
diff --git a/maintainers/shells/default.nix b/maintainers/shells/default.nix
index 0fc85b65..c88fc682 100644
--- a/maintainers/shells/default.nix
+++ b/maintainers/shells/default.nix
@@ -12,6 +12,17 @@ pkgs.mkShellNoCC {
       buildArgs = "-A overview --show-trace -v";
     })
 
+    (pkgs.writeShellApplication {
+      name = "devmode-manual";
+      text = ''
+        ${lib.getExe (
+          pkgs.devmode.override {
+            buildArgs = "-A manuals --show-trace -v";
+          }
+        )}
+      '';
+    })
+
     (pkgs.writeShellApplication {
       # TODO: have the program list available tests
       name = "ngipkgs-test";
diff --git a/manuals/default.nix b/manuals/default.nix
index 928835aa..67092afd 100644
--- a/manuals/default.nix
+++ b/manuals/default.nix
@@ -1,78 +1,20 @@
 {
-  callPackage,
   lib,
+  callPackage,
+  nixosOptionsDoc,
+  perl,
   python3,
   stdenv,
   texlive,
-  version,
-  projects,
-  nixosOptionsDoc,
+
   modulesPath,
-  pkgs,
+  nixos-modules,
+  version,
   ...
 }:
-let
-  pythonPackages = python3.withPackages (
-    pyPkgs: with pyPkgs; [
-      linkify-it-py
-      myst-parser
-      sphinx
-      #sphinx-argparse
-      #sphinx-autoapi
-      #sphinx-autobuild
-      #sphinx-autodoc-typehints
-      #sphinx-autodoc2
-      #sphinx-automodapi
-      #sphinx-basic-ng
-      #sphinx-better-theme
-      sphinx-book-theme
-      #sphinx-click
-      #sphinx-codeautolink
-      #sphinx-comments
-      sphinx-copybutton
-      sphinx-design
-      #sphinx-external-toc
-      #sphinx-favicon
-      #sphinx-fortran
-      #sphinx-hoverxref
-      #sphinx-inline-tabs
-      #sphinx-intl
-      #sphinx-issues
-      #sphinx-jinja
-      #sphinx-jinja2-compat
-      #sphinx-jquery
-      #sphinx-jupyterbook-latex
-      #sphinx-last-updated-by-git
-      #sphinx-lv2-theme
-      #sphinx-markdown-builder
-      #sphinx-markdown-parser
-      #sphinx-markdown-tables
-      #sphinx-material
-      #sphinx-mdinclude
-      #sphinx-multitoc-numbering
-      #sphinx-multiversion
-      sphinx-notfound-page
-      #sphinx-prompt
-      #sphinx-pytest
-      #sphinx-remove-toctrees
-      #sphinx-reredirects
-      #sphinx-rtd-dark-mode
-      #sphinx-rtd-theme
-      #sphinx-serve
-      sphinx-sitemap
-      #sphinx-tabs
-      #sphinx-testing
-      #sphinx-thebe
-      #sphinx-tippy
-      #sphinx-togglebutton
-      #sphinx-toolbox
-      #sphinx-version-warning
-      #sphinx-versions
-    ]
-  );
-in
-stdenv.mkDerivation {
+stdenv.mkDerivation (finalAttrs: {
   name = "NGIpkgs-Manuals";
+  inherit version;
   src =
     with lib.fileset;
     toSource {
@@ -98,14 +40,9 @@ stdenv.mkDerivation {
       ];
     };
   nativeBuildInputs = [
-    pythonPackages
-    pkgs.perl
-    # Explanation: generated with nix run github:rgri/tex2nix -- *.tex *.sty
-    (callPackage ./tex-env.nix {
-      extraTexPackages = {
-        inherit (texlive) latexmk gnu-freefont;
-      };
-    })
+    finalAttrs.passthru.pythonPackages
+    finalAttrs.passthru.texEnv
+    perl
   ];
   patchPhase = ''
     substituteInPlace manuals/index.md \
@@ -127,34 +64,38 @@ stdenv.mkDerivation {
     popd
   '';
   passthru = {
+    pythonPackages = python3.withPackages (
+      pyPkgs: with pyPkgs; [
+        linkify-it-py
+        myst-parser
+        sphinx
+        sphinx-book-theme
+        sphinx-copybutton
+        sphinx-design
+        sphinx-notfound-page
+        sphinx-sitemap
+      ]
+    );
+    # generated with: nix run github:rgri/tex2nix -- *.tex *.sty
+    texEnv = callPackage ./tex-env.nix {
+      extraTexPackages = {
+        inherit (texlive) latexmk gnu-freefont;
+      };
+    };
     optionsDoc = nixosOptionsDoc {
       options =
         lib.flip builtins.removeAttrs [ "_module" ]
           (lib.evalModules {
             class = "nixos";
-            specialArgs = {
-              inherit pkgs modulesPath;
-            };
+            specialArgs = { inherit modulesPath; };
             modules = [
               {
                 config = {
-                  # Explanation: do not check anything
-                  # because NixOS options are not included.
+                  # Do not check anything because NixOS options are not included.
                   # See also comment in NixOS' `noCheckForDocsModule`.
                   _module.check = false;
                 };
-                imports = lib.flatten (
-                  lib.attrValues (
-                    lib.mapAttrs (
-                      name: project:
-                      lib.attrValues (
-                        lib.filterAttrs (_: module: module != null) (
-                          lib.mapAttrs (n: p: p.module or null) (project.nixos.modules.services or { })
-                        )
-                      )
-                    ) projects
-                  )
-                );
+                imports = lib.attrValues nixos-modules.services;
                 #options = (import projects/types.nix { inherit lib; }).options;
                 #inherit (self.project-utils.eval-projects) options;
               }
@@ -162,4 +103,4 @@ stdenv.mkDerivation {
           }).options;
     };
   };
-}
+})
-- 
2.51.2

Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment thread default.nix Outdated
Comment thread default.nix
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add a manuals devmode to shells/default.nix:

    (pkgs.writeShellApplication {
      name = "devmode-manuals";
      text = ''
        ${lib.getExe (
          pkgs.devmode.override {
            buildArgs = "-A manuals --show-trace -v";
          }
        )}
      '';
    })

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're introducing more dev tools I think #1880 (comment) is needed more than ever.

Comment thread manuals/_static/_img/nix.pdf Outdated
@imincik
Copy link
Copy Markdown
Contributor

imincik commented Jan 12, 2026

@ju1m , is it possible to split this PR to multiple smaller ones ? It is very hard to review or approve 180 files.

  1. First PR could only contain working, but empty documentation structure - just working implementation of documentation framework
  2. Next we can integrate it to our GitHub pages website
  3. After that we can start merging some real content

@imincik imincik linked an issue Jan 12, 2026 that may be closed by this pull request
@ju1m ju1m force-pushed the doc branch 2 times, most recently from 63240fa to c14a92d Compare January 12, 2026 13:05
@ju1m
Copy link
Copy Markdown
Author

ju1m commented Jan 13, 2026

Comment thread default.nix Outdated
manuals = self.call manuals/default.nix rec {
version = "0.0.0"; # FixMe(maint): use something better, alas self.rev is not available there.
revision = "release-${version}";
inherit (self.project-utils.raw-projects.config) projects;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used

Suggested change
inherit (self.project-utils.raw-projects.config) projects;

Comment thread default.nix Outdated

manuals = self.call manuals/default.nix rec {
version = "0.0.0"; # FixMe(maint): use something better, alas self.rev is not available there.
revision = "release-${version}";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem to be used in manuals/default.nix

Comment thread manuals/default.nix Outdated
Comment on lines +258 to +261
# Explanation: do not check anything
# because NixOS options are not included.
# See also comment in NixOS' `noCheckForDocsModule`.
_module.check = false;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been meaning to ask, why do you always append Explanation: to comments? I think it's a bit redundant since their purpose is to explain things, in the first place.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave you my rationale there
They are all kind of comments, not all of them explain things, so I classify them to ease their digesting, facilitate their browsing and keeping their content in focus.
The current taxonomy is not perfect, always up for discussion, I hope you can agree with me, but of course you have the final word.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave you my rationale there

Oh, I didn't notice.

They are all kind of comments, not all of them explain things, so I classify them to ease their digesting, facilitate their browsing and keeping their content in focus.

I don't know about other contributors, but personally I find Explanation: a bit distracting, especially since comments are meant to document and explain things by default. To me, it doesn't make much sense to be explicit like that in situations where this is self-implied.

Explanation: is a classification header that I consider as important as ToDo:, Warning:, Issue: , FixMe:, Description:, Documentation:.

This is surely up to preference, but the TODO-comments are usually short (FIX, WARN, NOTE, ...) that it's not so distracting for me, whereas the length and capitalization in these stick out too much, IMO.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comments are meant to document and explain things by default.

I browsed the comments and you're perfectly right that most untagged comments
in packages and services are explanations (answering "why?")
with some exceptions here and there which are rather:

As an aside, in libraries (eg. pkgs/lib.nix or overview.utils)
untagged comments are most often descriptions (answering "what?").

Now, since having this classifier does not have the expected effect of helping you
to parse/browse/check-existence-of explaining comments,
I'll fallback to untagged comments for explanations.

For the record, it's because explanations are dignified
with their own separate category in https://diataxis.fr
that I logically introduced this new classifier
(sometimes tagged further down with a scope between parenthesis),
to nudge me to actually explain things, instead of not writing any explaination,
or just describing what the code already states.

Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix Outdated
Comment on lines +209 to +217
writeText "options.md" (
''
{#User_What_is_the_tree_of_options}
# What is the tree of options?

The following tree of options is provided by importing:
- `inputs.NGIpkgs.nixosModules.programs`
- `inputs.NGIpkgs.nixosModules.services`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want/need the list of options when we already this in the overview? The biggest disadvantage to me for this approach is that the list is too long and encumbered, making it difficult to read.

I think it would be better to split this into a separate PR where we can discuss how we should present this without blocking this PR, since options aren't really essential for the manual. And ideally, we should have a user story to state what the manual is accomplishing and what value it adds to users.

What do you think @imincik?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the list of options in the overview?
Note that it could not have been generated without the fixes from #1942
The options' sections are hidden from the ToC, still available in the document ToC in a PDF viewer's side-window.
Funny, for me options are like the most essential thing I'm expecting from a User manual.
Anyway, I'll split in another PR.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of options in ngipkgs might not be that relevant as for example in nixpkgs. Our users will find available options listed in project instructions in ngi.nixos.org and we don't expect them to configure multiple projects at once.

But I am ok with having the list options in manual if they don't flood content.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ju1m , I just built the manual and I definitely don't think we should have configuration options listed on the home page as I see it now. Are you able to move them to separate (Configuration options) page ? Thanks.

Comment thread manuals/default.nix Outdated
Comment thread manuals/tex-env.nix
Comment thread manuals/default.nix Outdated
Comment thread manuals/default.nix
Comment thread manuals/default.nix Outdated
Comment thread manuals/_static/css/custom.css Outdated
Comment thread manuals/index.md Outdated
Comment thread manuals/index.md Outdated
Comment thread manuals/default.nix Outdated
Comment on lines +209 to +217
writeText "options.md" (
''
{#User_What_is_the_tree_of_options}
# What is the tree of options?

The following tree of options is provided by importing:
- `inputs.NGIpkgs.nixosModules.programs`
- `inputs.NGIpkgs.nixosModules.services`

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ju1m , I just built the manual and I definitely don't think we should have configuration options listed on the home page as I see it now. Are you able to move them to separate (Configuration options) page ? Thanks.

@ju1m
Copy link
Copy Markdown
Author

ju1m commented Jan 22, 2026

  • Introduce proper version and revision
  • Remove unused arguments to manuals/default.nix
  • Remove manuals/_ext/extractable_code_block.py in favor of {literalinclude}
  • Move options into their own document.
  • Fix typos.
  • Compress logo in PDF, getting their size down from 6MB to ~200kB
  • Generate favicon.ico
  • Disable unavailable search field in singlehtml
  • Enable manuals.man rendition
  • Enable manuals.info rendition

eljamm
eljamm previously approved these changes Jan 22, 2026
Copy link
Copy Markdown
Contributor

@eljamm eljamm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the awesome work, @ju1m, this looks really good! There are no blockers from me, only a few small comments. We can make followups for any improvements or refactors after we merge this.

Comment thread manuals/default.nix Outdated
Comment thread default.nix
Comment thread default.nix
@imincik
Copy link
Copy Markdown
Contributor

imincik commented Jan 22, 2026

@ju1m , I am getting following error when trying to build manual

nix -L build -f . manuals.singlehtml
error:
       … while calling the 'derivationStrict' builtin
         at <nix/derivation-internal.nix>:37:12:
           36|
           37|   strict = derivationStrict drvAttrs;
             |            ^
           38|

       … while evaluating derivation 'NGIpkgs-Manuals-singlehtml-26.05'
         whose name attribute is located at /nix/store/snxcfmlvhnkclvsd1rasskqhq0v0y7fh-source/pkgs/stdenv/generic/make-derivation.nix:541:13

       … while evaluating attribute 'patchPhase' of derivation 'NGIpkgs-Manuals-singlehtml-26.05'
         at /home/imincik/Projects/ngi/ngipkgs/code/manuals/default.nix:56:5:
           55|
           56|     patchPhase = ''
             |     ^
           57|       runHook prePatch

       (stack trace truncated; use '--show-trace' to show the full, detailed trace)

       error: attribute 'dirtyShortRev' missing
       at /home/imincik/Projects/ngi/ngipkgs/code/default.nix:18:43:
           17|   version = "26.05";
           18|   revision = flake.sourceInfo.shortRev or flake.sourceInfo.dirtyShortRev;
             |                                           ^
           19|

@imincik
Copy link
Copy Markdown
Contributor

imincik commented Jan 22, 2026

@ju1m ,

  • Remove all content from home page - we should populate it with some NGIpkgs introduction
  • Remove "XYZ as [PDF]" links on the left side and add link to "Configuration Options" page instead. I don't think we need PDFs.
  • Is it possible to add search to the left panel as we have at nix.dev ?

@imincik
Copy link
Copy Markdown
Contributor

imincik commented Jan 22, 2026

I have just discovered that singlehtml renders very differently to html. html result looks much better to me and it contains search. Maybe we should disable singlehtml then.

Copy link
Copy Markdown
Contributor

@imincik imincik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have few small ideas for improvements but we can implement them in next PRs. Great work @ju1m . Thank you. Let's merge it.

@imincik imincik merged commit 3870756 into ngi-nix:main Jan 22, 2026
12 checks passed
@github-project-automation github-project-automation Bot moved this to Done in Nix@NGI Jan 22, 2026
@ju1m ju1m mentioned this pull request Jan 22, 2026
2 tasks
@ju1m ju1m deleted the doc branch January 22, 2026 16:19
Comment thread manuals/Options.nix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Build initial web documentation interface (nix.dev like website)

5 participants