summary refs log tree commit diff
path: root/nixos/doc/manual/default.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/doc/manual/default.nix')
-rw-r--r--nixos/doc/manual/default.nix264
1 files changed, 264 insertions, 0 deletions
diff --git a/nixos/doc/manual/default.nix b/nixos/doc/manual/default.nix
new file mode 100644
index 00000000000..e96bc47b4a5
--- /dev/null
+++ b/nixos/doc/manual/default.nix
@@ -0,0 +1,264 @@
+{ pkgs
+, options
+, config
+, version
+, revision
+, extraSources ? []
+, baseOptionsJSON ? null
+, warningsAreErrors ? true
+, prefix ? ../../..
+}:
+
+with pkgs;
+
+let
+  lib = pkgs.lib;
+
+  # We need to strip references to /nix/store/* from options,
+  # including any `extraSources` if some modules came from elsewhere,
+  # or else the build will fail.
+  #
+  # E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
+  # you'd need to include `extraSources = [ pkgs.customModules ]`
+  prefixesToStrip = map (p: "${toString p}/") ([ prefix ] ++ extraSources);
+  stripAnyPrefixes = lib.flip (lib.foldr lib.removePrefix) prefixesToStrip;
+
+  optionsDoc = buildPackages.nixosOptionsDoc {
+    inherit options revision baseOptionsJSON warningsAreErrors;
+    transformOptions = opt: opt // {
+      # Clean up declaration sites to not refer to the NixOS source tree.
+      declarations = map stripAnyPrefixes opt.declarations;
+    };
+  };
+
+  sources = lib.sourceFilesBySuffices ./. [".xml"];
+
+  modulesDoc = builtins.toFile "modules.xml" ''
+    <section xmlns:xi="http://www.w3.org/2001/XInclude" id="modules">
+    ${(lib.concatMapStrings (path: ''
+      <xi:include href="${path}" />
+    '') (lib.catAttrs "value" config.meta.doc))}
+    </section>
+  '';
+
+  generatedSources = runCommand "generated-docbook" {} ''
+    mkdir $out
+    ln -s ${modulesDoc} $out/modules.xml
+    ln -s ${optionsDoc.optionsDocBook} $out/options-db.xml
+    printf "%s" "${version}" > $out/version
+  '';
+
+  copySources =
+    ''
+      cp -prd $sources/* . # */
+      ln -s ${generatedSources} ./generated
+      chmod -R u+w .
+    '';
+
+  toc = builtins.toFile "toc.xml"
+    ''
+      <toc role="chunk-toc">
+        <d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-nixos-manual"><?dbhtml filename="index.html"?>
+          <d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
+          <d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
+        </d:tocentry>
+      </toc>
+    '';
+
+  manualXsltprocOptions = toString [
+    "--param section.autolabel 1"
+    "--param section.label.includes.component.label 1"
+    "--stringparam html.stylesheet 'style.css overrides.css highlightjs/mono-blue.css'"
+    "--stringparam html.script './highlightjs/highlight.pack.js ./highlightjs/loader.js'"
+    "--param xref.with.number.and.title 1"
+    "--param toc.section.depth 0"
+    "--param generate.consistent.ids 1"
+    "--stringparam admon.style ''"
+    "--stringparam callout.graphics.extension .svg"
+    "--stringparam current.docid manual"
+    "--param chunk.section.depth 0"
+    "--param chunk.first.sections 1"
+    "--param use.id.as.filename 1"
+    "--stringparam chunk.toc ${toc}"
+  ];
+
+  manual-combined = runCommand "nixos-manual-combined"
+    { inherit sources;
+      nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
+      meta.description = "The NixOS manual as plain docbook XML";
+    }
+    ''
+      ${copySources}
+
+      xmllint --xinclude --output ./manual-combined.xml ./manual.xml
+      xmllint --xinclude --noxincludenode \
+         --output ./man-pages-combined.xml ./man-pages.xml
+
+      # outputs the context of an xmllint error output
+      # LEN lines around the failing line are printed
+      function context {
+        # length of context
+        local LEN=6
+        # lines to print before error line
+        local BEFORE=4
+
+        # xmllint output lines are:
+        # file.xml:1234: there was an error on line 1234
+        while IFS=':' read -r file line rest; do
+          echo
+          if [[ -n "$rest" ]]; then
+            echo "$file:$line:$rest"
+            local FROM=$(($line>$BEFORE ? $line - $BEFORE : 1))
+            # number lines & filter context
+            nl --body-numbering=a "$file" | sed -n "$FROM,+$LEN p"
+          else
+            if [[ -n "$line" ]]; then
+              echo "$file:$line"
+            else
+              echo "$file"
+            fi
+          fi
+        done
+      }
+
+      function lintrng {
+        xmllint --debug --noout --nonet \
+          --relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
+          "$1" \
+          2>&1 | context 1>&2
+          # ^ redirect assumes xmllint doesn’t print to stdout
+      }
+
+      lintrng manual-combined.xml
+      lintrng man-pages-combined.xml
+
+      mkdir $out
+      cp manual-combined.xml $out/
+      cp man-pages-combined.xml $out/
+    '';
+
+  olinkDB = runCommand "manual-olinkdb"
+    { inherit sources;
+      nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
+    }
+    ''
+      xsltproc \
+        ${manualXsltprocOptions} \
+        --stringparam collect.xref.targets only \
+        --stringparam targets.filename "$out/manual.db" \
+        --nonet \
+        ${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \
+        ${manual-combined}/manual-combined.xml
+
+      cat > "$out/olinkdb.xml" <<EOF
+      <?xml version="1.0" encoding="utf-8"?>
+      <!DOCTYPE targetset SYSTEM
+        "file://${docbook_xsl_ns}/xml/xsl/docbook/common/targetdatabase.dtd" [
+        <!ENTITY manualtargets SYSTEM "file://$out/manual.db">
+      ]>
+      <targetset>
+        <targetsetinfo>
+            Allows for cross-referencing olinks between the manpages
+            and manual.
+        </targetsetinfo>
+
+        <document targetdoc="manual">&manualtargets;</document>
+      </targetset>
+      EOF
+    '';
+
+in rec {
+  inherit generatedSources;
+
+  inherit (optionsDoc) optionsJSON optionsNix optionsDocBook;
+
+  # Generate the NixOS manual.
+  manualHTML = runCommand "nixos-manual-html"
+    { inherit sources;
+      nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
+      meta.description = "The NixOS manual in HTML format";
+      allowedReferences = ["out"];
+    }
+    ''
+      # Generate the HTML manual.
+      dst=$out/share/doc/nixos
+      mkdir -p $dst
+      xsltproc \
+        ${manualXsltprocOptions} \
+        --stringparam target.database.document "${olinkDB}/olinkdb.xml" \
+        --stringparam id.warnings "1" \
+        --nonet --output $dst/ \
+        ${docbook_xsl_ns}/xml/xsl/docbook/xhtml/chunktoc.xsl \
+        ${manual-combined}/manual-combined.xml \
+        |& tee xsltproc.out
+      grep "^ID recommended on" xsltproc.out &>/dev/null && echo "error: some IDs are missing" && false
+      rm xsltproc.out
+
+      mkdir -p $dst/images/callouts
+      cp ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
+
+      cp ${../../../doc/style.css} $dst/style.css
+      cp ${../../../doc/overrides.css} $dst/overrides.css
+      cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
+
+      mkdir -p $out/nix-support
+      echo "nix-build out $out" >> $out/nix-support/hydra-build-products
+      echo "doc manual $dst" >> $out/nix-support/hydra-build-products
+    ''; # */
+
+  # Alias for backward compatibility. TODO(@oxij): remove eventually.
+  manual = manualHTML;
+
+  # Index page of the NixOS manual.
+  manualHTMLIndex = "${manualHTML}/share/doc/nixos/index.html";
+
+  manualEpub = runCommand "nixos-manual-epub"
+    { inherit sources;
+      nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin buildPackages.zip ];
+    }
+    ''
+      # Generate the epub manual.
+      dst=$out/share/doc/nixos
+
+      xsltproc \
+        ${manualXsltprocOptions} \
+        --stringparam target.database.document "${olinkDB}/olinkdb.xml" \
+        --nonet --xinclude --output $dst/epub/ \
+        ${docbook_xsl_ns}/xml/xsl/docbook/epub/docbook.xsl \
+        ${manual-combined}/manual-combined.xml
+
+      mkdir -p $dst/epub/OEBPS/images/callouts
+      cp -r ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
+      echo "application/epub+zip" > mimetype
+      manual="$dst/nixos-manual.epub"
+      zip -0Xq "$manual" mimetype
+      cd $dst/epub && zip -Xr9D "$manual" *
+
+      rm -rf $dst/epub
+
+      mkdir -p $out/nix-support
+      echo "doc-epub manual $manual" >> $out/nix-support/hydra-build-products
+    '';
+
+
+  # Generate the NixOS manpages.
+  manpages = runCommand "nixos-manpages"
+    { inherit sources;
+      nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
+      allowedReferences = ["out"];
+    }
+    ''
+      # Generate manpages.
+      mkdir -p $out/share/man
+      xsltproc --nonet \
+        --maxdepth 6000 \
+        --param man.output.in.separate.dir 1 \
+        --param man.output.base.dir "'$out/share/man/'" \
+        --param man.endnotes.are.numbered 0 \
+        --param man.break.after.slash 1 \
+        --stringparam target.database.document "${olinkDB}/olinkdb.xml" \
+        ${docbook_xsl_ns}/xml/xsl/docbook/manpages/docbook.xsl \
+        ${manual-combined}/man-pages-combined.xml
+    '';
+
+}