1{ pkgs, options, version, revision, extraSources ? [] }:
2
3with pkgs;
4with pkgs.lib;
5
6let
7
8 # Remove invisible and internal options.
9 optionsList = filter (opt: opt.visible && !opt.internal) (optionAttrSetToDocList options);
10
11 # Replace functions by the string <function>
12 substFunction = x:
13 if builtins.isAttrs x then mapAttrs (name: substFunction) x
14 else if builtins.isList x then map substFunction x
15 else if builtins.isFunction x then "<function>"
16 else x;
17
18 # Clean up declaration sites to not refer to the NixOS source tree.
19 optionsList' = flip map optionsList (opt: opt // {
20 declarations = map stripAnyPrefixes opt.declarations;
21 }
22 // optionalAttrs (opt ? example) { example = substFunction opt.example; }
23 // optionalAttrs (opt ? default) { default = substFunction opt.default; }
24 // optionalAttrs (opt ? type) { type = substFunction opt.type; });
25
26 # We need to strip references to /nix/store/* from options,
27 # including any `extraSources` if some modules came from elsewhere,
28 # or else the build will fail.
29 #
30 # E.g. if some `options` came from modules in ${pkgs.customModules}/nix,
31 # you'd need to include `extraSources = [ pkgs.customModules ]`
32 prefixesToStrip = map (p: "${toString p}/") ([ ../../.. ] ++ extraSources);
33 stripAnyPrefixes = flip (fold removePrefix) prefixesToStrip;
34
35 # Convert the list of options into an XML file.
36 optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList');
37
38 optionsDocBook = runCommand "options-db.xml" {} ''
39 optionsXML=${optionsXML}
40 if grep /nixpkgs/nixos/modules $optionsXML; then
41 echo "The manual appears to depend on the location of Nixpkgs, which is bad"
42 echo "since this prevents sharing via the NixOS channel. This is typically"
43 echo "caused by an option default that refers to a relative path (see above"
44 echo "for hints about the offending path)."
45 exit 1
46 fi
47 ${libxslt}/bin/xsltproc \
48 --stringparam revision '${revision}' \
49 -o $out ${./options-to-docbook.xsl} $optionsXML
50 '';
51
52 sources = sourceFilesBySuffices ./. [".xml"];
53
54 copySources =
55 ''
56 cp -prd $sources/* . # */
57 chmod -R u+w .
58 cp ${../../modules/services/databases/postgresql.xml} configuration/postgresql.xml
59 cp ${../../modules/services/misc/gitlab.xml} configuration/gitlab.xml
60 cp ${../../modules/security/acme.xml} configuration/acme.xml
61 ln -s ${optionsDocBook} options-db.xml
62 echo "${version}" > version
63 '';
64
65 toc = builtins.toFile "toc.xml"
66 ''
67 <toc role="chunk-toc">
68 <d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-nixos-manual"><?dbhtml filename="index.html"?>
69 <d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
70 <d:tocentry linkend="ch-release-notes"><?dbhtml filename="release-notes.html"?></d:tocentry>
71 </d:tocentry>
72 </toc>
73 '';
74
75in rec {
76
77 # The NixOS options in JSON format.
78 optionsJSON = stdenv.mkDerivation {
79 name = "options-json";
80
81 buildCommand = ''
82 # Export list of options in different format.
83 dst=$out/share/doc/nixos
84 mkdir -p $dst
85
86 cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
87 (listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList'))))
88 } $dst/options.json
89
90 mkdir -p $out/nix-support
91 echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
92 ''; # */
93
94 meta.description = "List of NixOS options in JSON format";
95 };
96
97 # Generate the NixOS manual.
98 manual = stdenv.mkDerivation {
99 name = "nixos-manual";
100
101 inherit sources;
102
103 buildInputs = [ libxml2 libxslt ];
104
105 buildCommand = ''
106 ${copySources}
107
108 # Check the validity of the manual sources.
109 xmllint --noout --nonet --xinclude --noxincludenode \
110 --relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
111 manual.xml
112
113 # Generate the HTML manual.
114 dst=$out/share/doc/nixos
115 mkdir -p $dst
116 xsltproc \
117 --param section.autolabel 1 \
118 --param section.label.includes.component.label 1 \
119 --stringparam html.stylesheet style.css \
120 --param xref.with.number.and.title 1 \
121 --param toc.section.depth 3 \
122 --stringparam admon.style "" \
123 --stringparam callout.graphics.extension .gif \
124 --param chunk.section.depth 0 \
125 --param chunk.first.sections 1 \
126 --param use.id.as.filename 1 \
127 --stringparam generate.toc "book toc appendix toc" \
128 --stringparam chunk.toc ${toc} \
129 --nonet --xinclude --output $dst/ \
130 ${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl ./manual.xml
131
132 mkdir -p $dst/images/callouts
133 cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.gif $dst/images/callouts/
134
135 cp ${./style.css} $dst/style.css
136
137 mkdir -p $out/nix-support
138 echo "nix-build out $out" >> $out/nix-support/hydra-build-products
139 echo "doc manual $dst" >> $out/nix-support/hydra-build-products
140 ''; # */
141
142 meta.description = "The NixOS manual in HTML format";
143
144 allowedReferences = ["out"];
145 };
146
147 manualPDF = stdenv.mkDerivation {
148 name = "nixos-manual-pdf";
149
150 inherit sources;
151
152 buildInputs = [ libxml2 libxslt dblatex dblatex.tex ];
153
154 buildCommand = ''
155 ${copySources}
156
157 dst=$out/share/doc/nixos
158 mkdir -p $dst
159 xmllint --xinclude manual.xml | dblatex -o $dst/manual.pdf - \
160 -P doc.collab.show=0 \
161 -P latex.output.revhistory=0
162
163 mkdir -p $out/nix-support
164 echo "doc-pdf manual $dst/manual.pdf" >> $out/nix-support/hydra-build-products
165 '';
166 };
167
168 # Generate the NixOS manpages.
169 manpages = stdenv.mkDerivation {
170 name = "nixos-manpages";
171
172 inherit sources;
173
174 buildInputs = [ libxml2 libxslt ];
175
176 buildCommand = ''
177 ${copySources}
178
179 # Check the validity of the manual sources.
180 xmllint --noout --nonet --xinclude --noxincludenode \
181 --relaxng ${docbook5}/xml/rng/docbook/docbook.rng \
182 ./man-pages.xml
183
184 # Generate manpages.
185 mkdir -p $out/share/man
186 xsltproc --nonet --xinclude \
187 --param man.output.in.separate.dir 1 \
188 --param man.output.base.dir "'$out/share/man/'" \
189 --param man.endnotes.are.numbered 0 \
190 ${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
191 ./man-pages.xml
192 '';
193
194 allowedReferences = ["out"];
195 };
196
197}