docs: use nmd for generating documentation
The nmd library is an external library for generating Nix-centric documentation.
This commit is contained in:
parent
35752e07fa
commit
eb0ccf7286
343
doc/default.nix
343
doc/default.nix
|
@ -1,122 +1,33 @@
|
||||||
{ pkgs, options, config, version, revision, extraSources ? [] }:
|
{ pkgs }:
|
||||||
|
|
||||||
with pkgs;
|
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
lib = pkgs.lib;
|
lib = pkgs.lib;
|
||||||
|
|
||||||
# Remove invisible and internal options.
|
nmdSrc = pkgs.fetchFromGitLab {
|
||||||
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
owner = "rycee";
|
||||||
|
repo = "nmd";
|
||||||
|
rev = "b57fc6657b6645086a286e62a05a1795f258daa6";
|
||||||
|
sha256 = "1b6bdgn6d4awxi8al5hbw8vycxp4laf63l29rjrvxi2j2g69rgvc";
|
||||||
|
};
|
||||||
|
|
||||||
# Replace functions by the string <function>
|
nmd = import nmdSrc { inherit pkgs; };
|
||||||
substFunction = x:
|
|
||||||
if builtins.isAttrs x then lib.mapAttrs (name: substFunction) x
|
|
||||||
else if builtins.isList x then map substFunction x
|
|
||||||
else if lib.isFunction x then "<function>"
|
|
||||||
else x;
|
|
||||||
|
|
||||||
# Generate DocBook documentation for a list of packages. This is
|
hmModulesDocs = nmd.buildModulesDocs {
|
||||||
# what `relatedPackages` option of `mkOption` from
|
modules = import ../modules/modules.nix { inherit lib pkgs; };
|
||||||
# ../../../lib/options.nix influences.
|
moduleRootPaths = [ ./.. ];
|
||||||
#
|
mkModuleUrl = path:
|
||||||
# Each element of `relatedPackages` can be either
|
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
|
||||||
# - a string: that will be interpreted as an attribute name from `pkgs`,
|
channelName = "home-manager";
|
||||||
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
docBook.id = "home-manager-options";
|
||||||
# - an attrset: that can specify `name`, `path`, `package`, `comment`
|
};
|
||||||
# (either of `name`, `path` is required, the rest are optional).
|
|
||||||
genRelatedPackages = packages:
|
|
||||||
let
|
|
||||||
unpack = p: if lib.isString p then { name = p; }
|
|
||||||
else if lib.isList p then { path = p; }
|
|
||||||
else p;
|
|
||||||
describe = args:
|
|
||||||
let
|
|
||||||
name = args.name or (lib.concatStringsSep "." args.path);
|
|
||||||
path = args.path or [ args.name ];
|
|
||||||
package = args.package or (lib.attrByPath path (throw "Invalid package attribute path `${toString path}'") pkgs);
|
|
||||||
in "<listitem>"
|
|
||||||
+ "<para><literal>pkgs.${name} (${package.meta.name})</literal>"
|
|
||||||
+ lib.optionalString (!package.meta.available) " <emphasis>[UNAVAILABLE]</emphasis>"
|
|
||||||
+ ": ${package.meta.description or "???"}.</para>"
|
|
||||||
+ lib.optionalString (args ? comment) "\n<para>${args.comment}</para>"
|
|
||||||
# Lots of `longDescription's break DocBook, so we just wrap them into <programlisting>
|
|
||||||
+ lib.optionalString (package.meta ? longDescription) "\n<programlisting>${package.meta.longDescription}</programlisting>"
|
|
||||||
+ "</listitem>";
|
|
||||||
in "<itemizedlist>${lib.concatStringsSep "\n" (map (p: describe (unpack p)) packages)}</itemizedlist>";
|
|
||||||
|
|
||||||
optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
|
docs = nmd.buildDocBookDocs {
|
||||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
pathName = "home-manager";
|
||||||
declarations = map stripAnyPrefixes opt.declarations;
|
modulesDocs = [ hmModulesDocs ];
|
||||||
}
|
documentsDirectory = ./.;
|
||||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
chunkToc = ''
|
||||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
<toc>
|
||||||
// lib.optionalAttrs (opt ? type) { type = substFunction opt.type; }
|
|
||||||
// lib.optionalAttrs (opt ? relatedPackages) { relatedPackages = genRelatedPackages opt.relatedPackages; });
|
|
||||||
|
|
||||||
# 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}/") ([ ./.. ] ++ extraSources);
|
|
||||||
stripAnyPrefixes = lib.flip (lib.fold lib.removePrefix) prefixesToStrip;
|
|
||||||
|
|
||||||
# Custom "less" that pushes up all the things ending in ".enable*"
|
|
||||||
# and ".package*"
|
|
||||||
optionLess = a: b:
|
|
||||||
let
|
|
||||||
ise = lib.hasPrefix "enable";
|
|
||||||
isp = lib.hasPrefix "package";
|
|
||||||
cmp = lib.splitByAndCompare ise lib.compare
|
|
||||||
(lib.splitByAndCompare isp lib.compare lib.compare);
|
|
||||||
in lib.compareLists cmp a.loc b.loc < 0;
|
|
||||||
|
|
||||||
# Customly sort option list for the man page.
|
|
||||||
optionsList = lib.sort optionLess optionsListDesc;
|
|
||||||
|
|
||||||
# Convert the list of options into an XML file.
|
|
||||||
optionsXML = builtins.toFile "options.xml" (builtins.toXML optionsList);
|
|
||||||
|
|
||||||
optionsDocBook = runCommand "options-db.xml"
|
|
||||||
{
|
|
||||||
nativeBuildInputs = [ buildPackages.libxslt.bin ];
|
|
||||||
}
|
|
||||||
''
|
|
||||||
optionsXML=${optionsXML}
|
|
||||||
xsltproc \
|
|
||||||
--stringparam program 'home-manager' \
|
|
||||||
--stringparam revision '${revision}' \
|
|
||||||
-o $out ${./options-to-docbook.xsl} $optionsXML
|
|
||||||
'';
|
|
||||||
|
|
||||||
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 ${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-home-manager-manual"><?dbhtml filename="index.html"?>
|
<d:tocentry xmlns:d="http://docbook.org/ns/docbook" linkend="book-home-manager-manual"><?dbhtml filename="index.html"?>
|
||||||
<d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
|
<d:tocentry linkend="ch-options"><?dbhtml filename="options.html"?></d:tocentry>
|
||||||
<d:tocentry linkend="ch-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
<d:tocentry linkend="ch-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
||||||
|
@ -124,206 +35,22 @@ let
|
||||||
</d:tocentry>
|
</d:tocentry>
|
||||||
</toc>
|
</toc>
|
||||||
'';
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
manualXsltprocOptions = toString [
|
in
|
||||||
"--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 3"
|
|
||||||
"--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 generate.toc 'book toc appendix toc'"
|
|
||||||
"--stringparam chunk.toc ${toc}"
|
|
||||||
];
|
|
||||||
|
|
||||||
manual-combined = runCommand "home-manager-manual-combined"
|
{
|
||||||
{ inherit sources;
|
|
||||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
|
||||||
meta.description = "The Home Manager manual as plain docbook XML";
|
|
||||||
}
|
|
||||||
''
|
|
||||||
${copySources}
|
|
||||||
|
|
||||||
xmllint --xinclude --output ./manual-combined.xml ./manual.xml
|
options = {
|
||||||
xmllint --xinclude --noxincludenode \
|
json = hmModulesDocs.json.override {
|
||||||
--output ./man-pages-combined.xml ./man-pages.xml
|
path = "share/doc/home-manager/options.json";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
# outputs the context of an xmllint error output
|
manPages = docs.manPages;
|
||||||
# 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:
|
manual = {
|
||||||
# file.xml:1234: there was an error on line 1234
|
inherit (docs) html htmlOpenTool;
|
||||||
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 \
|
|
||||||
${docbook5_xsl}/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://${docbook5_xsl}/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;
|
|
||||||
|
|
||||||
# The Home Manager options in JSON format.
|
|
||||||
optionsJSON = runCommand "options-json"
|
|
||||||
{ meta.description = "List of Home Manager options in JSON format";
|
|
||||||
}
|
|
||||||
''
|
|
||||||
# Export list of options in different format.
|
|
||||||
dst=$out/share/doc/home-manager
|
|
||||||
mkdir -p $dst
|
|
||||||
|
|
||||||
cp ${builtins.toFile "options.json" (builtins.unsafeDiscardStringContext (builtins.toJSON
|
|
||||||
(builtins.listToAttrs (map (o: { name = o.name; value = removeAttrs o ["name" "visible" "internal"]; }) optionsList))))
|
|
||||||
} $dst/options.json
|
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
|
||||||
echo "file json $dst/options.json" >> $out/nix-support/hydra-build-products
|
|
||||||
''; # */
|
|
||||||
|
|
||||||
# Generate the Home Manager manual.
|
|
||||||
manual = runCommand "home-manager-manual"
|
|
||||||
{ inherit sources;
|
|
||||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
|
||||||
meta.description = "The Home Manager manual in HTML format";
|
|
||||||
allowedReferences = ["out"];
|
|
||||||
}
|
|
||||||
''
|
|
||||||
# Generate the HTML manual.
|
|
||||||
dst=$out/share/doc/home-manager
|
|
||||||
mkdir -p $dst
|
|
||||||
xsltproc \
|
|
||||||
${manualXsltprocOptions} \
|
|
||||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
|
||||||
--nonet --output $dst/ \
|
|
||||||
${docbook5_xsl}/xml/xsl/docbook/xhtml/chunktoc.xsl \
|
|
||||||
${manual-combined}/manual-combined.xml
|
|
||||||
|
|
||||||
mkdir -p $dst/images/callouts
|
|
||||||
cp ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
|
|
||||||
|
|
||||||
cp ${./style.css} $dst/style.css
|
|
||||||
cp ${./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
|
|
||||||
''; # */
|
|
||||||
|
|
||||||
|
|
||||||
manualEpub = runCommand "home-manager-manual-epub"
|
|
||||||
{ inherit sources;
|
|
||||||
buildInputs = [ libxml2.bin libxslt.bin zip ];
|
|
||||||
}
|
|
||||||
''
|
|
||||||
# Generate the epub manual.
|
|
||||||
dst=$out/share/doc/home-manager
|
|
||||||
|
|
||||||
xsltproc \
|
|
||||||
${manualXsltprocOptions} \
|
|
||||||
--stringparam target.database.document "${olinkDB}/olinkdb.xml" \
|
|
||||||
--nonet --xinclude --output $dst/epub/ \
|
|
||||||
${docbook5_xsl}/xml/xsl/docbook/epub/docbook.xsl \
|
|
||||||
${manual-combined}/manual-combined.xml
|
|
||||||
|
|
||||||
mkdir -p $dst/epub/OEBPS/images/callouts
|
|
||||||
cp -r ${docbook5_xsl}/xml/xsl/docbook/images/callouts/*.svg $dst/epub/OEBPS/images/callouts # */
|
|
||||||
echo "application/epub+zip" > mimetype
|
|
||||||
manual="$dst/home-manager-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 Home Manager manpages.
|
|
||||||
manpages = runCommand "home-manager-manpages"
|
|
||||||
{ inherit sources;
|
|
||||||
nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
|
||||||
allowedReferences = ["out"];
|
|
||||||
}
|
|
||||||
''
|
|
||||||
# Generate manpages.
|
|
||||||
mkdir -p $out/share/man
|
|
||||||
xsltproc --nonet \
|
|
||||||
--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" \
|
|
||||||
${docbook5_xsl}/xml/xsl/docbook/manpages/docbook.xsl \
|
|
||||||
${manual-combined}/man-pages-combined.xml
|
|
||||||
'';
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
You can use the following options in
|
You can use the following options in
|
||||||
<filename>home-configuration.nix</filename>:
|
<filename>home-configuration.nix</filename>:
|
||||||
</para>
|
</para>
|
||||||
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
|
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||||
</refsection>
|
</refsection>
|
||||||
<refsection>
|
<refsection>
|
||||||
<title>See also</title>
|
<title>See also</title>
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
<xi:include href="installation.xml" />
|
<xi:include href="installation.xml" />
|
||||||
<appendix xml:id="ch-options">
|
<appendix xml:id="ch-options">
|
||||||
<title>Configuration Options</title>
|
<title>Configuration Options</title>
|
||||||
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
|
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||||
</appendix>
|
</appendix>
|
||||||
<appendix xml:id="ch-tools">
|
<appendix xml:id="ch-tools">
|
||||||
<title>Tools</title>
|
<title>Tools</title>
|
||||||
|
|
|
@ -1,239 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
|
|
||||||
<xsl:stylesheet version="1.0"
|
|
||||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
|
||||||
xmlns:str="http://exslt.org/strings"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns="http://docbook.org/ns/docbook"
|
|
||||||
extension-element-prefixes="str"
|
|
||||||
>
|
|
||||||
|
|
||||||
<xsl:output method='xml' encoding="UTF-8" />
|
|
||||||
|
|
||||||
<xsl:param name="revision" />
|
|
||||||
<xsl:param name="program" />
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="/expr/list">
|
|
||||||
<appendix>
|
|
||||||
<title>Configuration Options</title>
|
|
||||||
<variablelist xml:id="configuration-variable-list">
|
|
||||||
<xsl:for-each select="attrs">
|
|
||||||
<xsl:variable name="id" select="concat('opt-', str:replace(str:replace(str:replace(str:replace(attr[@name = 'name']/string/@value, '*', '_'), '<', '_'), '>', '_'), '?', '_'))" />
|
|
||||||
<varlistentry>
|
|
||||||
<term xlink:href="#{$id}">
|
|
||||||
<xsl:attribute name="xml:id"><xsl:value-of select="$id"/></xsl:attribute>
|
|
||||||
<option>
|
|
||||||
<xsl:value-of select="attr[@name = 'name']/string/@value" />
|
|
||||||
</option>
|
|
||||||
</term>
|
|
||||||
|
|
||||||
<listitem>
|
|
||||||
|
|
||||||
<para>
|
|
||||||
<xsl:value-of disable-output-escaping="yes"
|
|
||||||
select="attr[@name = 'description']/string/@value" />
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'type']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Type:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:value-of select="attr[@name = 'type']/string/@value"/>
|
|
||||||
<xsl:if test="attr[@name = 'readOnly']/bool/@value = 'true'">
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<emphasis>(read only)</emphasis>
|
|
||||||
</xsl:if>
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'default']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Default:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'default']" mode="top" />
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'example']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Example:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="attr[@name = 'example']/attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
|
||||||
<programlisting><xsl:value-of select="attr[@name = 'example']/attrs/attr[@name = 'text']/string/@value" /></programlisting>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'example']" mode="top" />
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="attr[@name = 'relatedPackages']">
|
|
||||||
<para>
|
|
||||||
<emphasis>Related packages:</emphasis>
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
<xsl:value-of disable-output-escaping="yes"
|
|
||||||
select="attr[@name = 'relatedPackages']/string/@value" />
|
|
||||||
</para>
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="count(attr[@name = 'declarations']/list/*) != 0">
|
|
||||||
<para>
|
|
||||||
<emphasis>Declared by:</emphasis>
|
|
||||||
</para>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'declarations']" />
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
<xsl:if test="count(attr[@name = 'definitions']/list/*) != 0">
|
|
||||||
<para>
|
|
||||||
<emphasis>Defined by:</emphasis>
|
|
||||||
</para>
|
|
||||||
<xsl:apply-templates select="attr[@name = 'definitions']" />
|
|
||||||
</xsl:if>
|
|
||||||
|
|
||||||
</listitem>
|
|
||||||
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
</xsl:for-each>
|
|
||||||
|
|
||||||
</variablelist>
|
|
||||||
</appendix>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="*" mode="top">
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="string[contains(@value, '
')]">
|
|
||||||
<programlisting>
|
|
||||||
<xsl:text>''
|
|
||||||
</xsl:text><xsl:value-of select='str:replace(string/@value, "${", "''${")' /><xsl:text>''</xsl:text></programlisting>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<literal><xsl:apply-templates /></literal>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="null">
|
|
||||||
<xsl:text>null</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="string">
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="(contains(@value, '"') or contains(@value, '\')) and not(contains(@value, '
'))">
|
|
||||||
<xsl:text>''</xsl:text><xsl:value-of select='str:replace(@value, "${", "''${")' /><xsl:text>''</xsl:text>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:text>"</xsl:text><xsl:value-of select="str:replace(str:replace(str:replace(str:replace(@value, '\', '\\'), '"', '\"'), '
', '\n'), '$', '\$')" /><xsl:text>"</xsl:text>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="int">
|
|
||||||
<xsl:value-of select="@value" />
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="bool[@value = 'true']">
|
|
||||||
<xsl:text>true</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="bool[@value = 'false']">
|
|
||||||
<xsl:text>false</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="list">
|
|
||||||
[
|
|
||||||
<xsl:for-each select="*">
|
|
||||||
<xsl:apply-templates select="." />
|
|
||||||
<xsl:text> </xsl:text>
|
|
||||||
</xsl:for-each>
|
|
||||||
]
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="attrs[attr[@name = '_type' and string[@value = 'literalExample']]]">
|
|
||||||
<xsl:value-of select="attr[@name = 'text']/string/@value" />
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="attrs">
|
|
||||||
{
|
|
||||||
<xsl:for-each select="attr">
|
|
||||||
<xsl:value-of select="@name" />
|
|
||||||
<xsl:text> = </xsl:text>
|
|
||||||
<xsl:apply-templates select="*" /><xsl:text>; </xsl:text>
|
|
||||||
</xsl:for-each>
|
|
||||||
}
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="derivation">
|
|
||||||
<replaceable>(build of <xsl:value-of select="attr[@name = 'name']/string/@value" />)</replaceable>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="attr[@name = 'declarations' or @name = 'definitions']">
|
|
||||||
<simplelist>
|
|
||||||
<xsl:for-each select="list/string">
|
|
||||||
<member><filename>
|
|
||||||
<!-- Hyperlink the filename either to the NixOS Subversion
|
|
||||||
repository (if it’s a module and we have a revision number),
|
|
||||||
or to the local filesystem. -->
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="not(starts-with(@value, '/'))">
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="$program = 'home-manager'">
|
|
||||||
<xsl:attribute name="xlink:href">https://github.com/rycee/home-manager/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/>#blob-path</xsl:attribute>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="$revision = 'local'">
|
|
||||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/master/<xsl:value-of select="@value"/></xsl:attribute>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixpkgs/blob/<xsl:value-of select="$revision"/>/<xsl:value-of select="@value"/></xsl:attribute>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="$revision != 'local' and $program = 'nixops' and contains(@value, '/nix/')">
|
|
||||||
<xsl:attribute name="xlink:href">https://github.com/NixOS/nixops/blob/<xsl:value-of select="$revision"/>/nix/<xsl:value-of select="substring-after(@value, '/nix/')"/></xsl:attribute>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:attribute name="xlink:href">file://<xsl:value-of select="@value"/></xsl:attribute>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
<!-- Print the filename and make it user-friendly by replacing the
|
|
||||||
/nix/store/<hash> prefix by the default location of nixos
|
|
||||||
sources. -->
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="$program = 'home-manager'">
|
|
||||||
<home-manager/<xsl:value-of select="@value"/>>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="not(starts-with(@value, '/'))">
|
|
||||||
<nixpkgs/<xsl:value-of select="@value"/>>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:when test="contains(@value, 'nixops') and contains(@value, '/nix/')">
|
|
||||||
<nixops/<xsl:value-of select="substring-after(@value, '/nix/')"/>>
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:value-of select="@value" />
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</filename></member>
|
|
||||||
</xsl:for-each>
|
|
||||||
</simplelist>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
<xsl:template match="function">
|
|
||||||
<xsl:text>λ</xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
|
|
@ -1,9 +0,0 @@
|
||||||
.docbook .xref img[src^=images\/callouts\/],
|
|
||||||
.screen img,
|
|
||||||
.programlisting img {
|
|
||||||
width: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.calloutlist img {
|
|
||||||
width: 1.5em;
|
|
||||||
}
|
|
271
doc/style.css
271
doc/style.css
|
@ -1,271 +0,0 @@
|
||||||
/* Copied from http://bakefile.sourceforge.net/, which appears
|
|
||||||
licensed under the GNU GPL. */
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Basic headers and text:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
body
|
|
||||||
{
|
|
||||||
font-family: "Nimbus Sans L", sans-serif;
|
|
||||||
background: white;
|
|
||||||
margin: 2em 1em 2em 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4
|
|
||||||
{
|
|
||||||
color: #005aa0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 /* title */
|
|
||||||
{
|
|
||||||
font-size: 200%;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 /* chapters, appendices, subtitle */
|
|
||||||
{
|
|
||||||
font-size: 180%;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extra space between chapters, appendices. */
|
|
||||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
|
||||||
{
|
|
||||||
margin-top: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.section > div.titlepage h2 /* sections */
|
|
||||||
{
|
|
||||||
font-size: 150%;
|
|
||||||
margin-top: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 /* subsections */
|
|
||||||
{
|
|
||||||
font-size: 125%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.simplesect h2
|
|
||||||
{
|
|
||||||
font-size: 110%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.appendix h3
|
|
||||||
{
|
|
||||||
font-size: 150%;
|
|
||||||
margin-top: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
|
|
||||||
{
|
|
||||||
margin-top: 1.4em;
|
|
||||||
font-size: 125%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.refsection h3
|
|
||||||
{
|
|
||||||
font-size: 110%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Examples:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
div.example
|
|
||||||
{
|
|
||||||
border: 1px solid #b0b0b0;
|
|
||||||
padding: 6px 6px;
|
|
||||||
margin-left: 1.5em;
|
|
||||||
margin-right: 1.5em;
|
|
||||||
background: #f4f4f8;
|
|
||||||
border-radius: 0.4em;
|
|
||||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.example p.title
|
|
||||||
{
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.example pre
|
|
||||||
{
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Screen dumps:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
pre.screen, pre.programlisting
|
|
||||||
{
|
|
||||||
border: 1px solid #b0b0b0;
|
|
||||||
padding: 3px 3px;
|
|
||||||
margin-left: 1.5em;
|
|
||||||
margin-right: 1.5em;
|
|
||||||
|
|
||||||
background: #f4f4f8;
|
|
||||||
font-family: monospace;
|
|
||||||
border-radius: 0.4em;
|
|
||||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.example pre.programlisting
|
|
||||||
{
|
|
||||||
border: 0px;
|
|
||||||
padding: 0 0;
|
|
||||||
margin: 0 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Notes, warnings etc:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
.note, .warning
|
|
||||||
{
|
|
||||||
border: 1px solid #b0b0b0;
|
|
||||||
padding: 3px 3px;
|
|
||||||
margin-left: 1.5em;
|
|
||||||
margin-right: 1.5em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
padding: 0.3em 0.3em 0.3em 0.3em;
|
|
||||||
background: #fffff5;
|
|
||||||
border-radius: 0.4em;
|
|
||||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note, div.warning
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note h3, div.warning h3
|
|
||||||
{
|
|
||||||
color: red;
|
|
||||||
font-size: 100%;
|
|
||||||
padding-right: 0.5em;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note p, div.warning p
|
|
||||||
{
|
|
||||||
margin-bottom: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note h3 + p, div.warning h3 + p
|
|
||||||
{
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.note h3
|
|
||||||
{
|
|
||||||
color: blue;
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.navfooter *
|
|
||||||
{
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Links colors and highlighting:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
a { text-decoration: none; }
|
|
||||||
a:hover { text-decoration: underline; }
|
|
||||||
a:link { color: #0048b3; }
|
|
||||||
a:visited { color: #002a6a; }
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Table of contents:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
div.toc
|
|
||||||
{
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.toc dl
|
|
||||||
{
|
|
||||||
margin-top: 0em;
|
|
||||||
margin-bottom: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
Special elements:
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
tt, code
|
|
||||||
{
|
|
||||||
color: #400000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.term
|
|
||||||
{
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
div.variablelist dd p, div.glosslist dd p
|
|
||||||
{
|
|
||||||
margin-top: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.variablelist dd, div.glosslist dd
|
|
||||||
{
|
|
||||||
margin-left: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.glosslist dt
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.varname
|
|
||||||
{
|
|
||||||
color: #400000;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.command strong
|
|
||||||
{
|
|
||||||
font-weight: normal;
|
|
||||||
color: #400000;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.calloutlist table
|
|
||||||
{
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
border-collapse: collapse;
|
|
||||||
box-shadow: 0.4em 0.4em 0.5em #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.simplelist
|
|
||||||
{
|
|
||||||
text-align: left;
|
|
||||||
color: #005aa0;
|
|
||||||
border: 0;
|
|
||||||
padding: 5px;
|
|
||||||
background: #fffff5;
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: italic;
|
|
||||||
box-shadow: none;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.navheader table, div.navfooter table {
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.affiliation
|
|
||||||
{
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ config, lib, pkgs, baseModules, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
with lib;
|
with lib;
|
||||||
|
|
||||||
|
@ -6,55 +6,7 @@ let
|
||||||
|
|
||||||
cfg = config.manual;
|
cfg = config.manual;
|
||||||
|
|
||||||
/* For the purpose of generating docs, evaluate options with each derivation
|
docs = import ../doc { inherit pkgs; };
|
||||||
in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}".
|
|
||||||
It isn't perfect, but it seems to cover a vast majority of use cases.
|
|
||||||
Caveat: even if the package is reached by a different means,
|
|
||||||
the path above will be shown and not e.g. `${config.services.foo.package}`. */
|
|
||||||
homeManagerManual = import ../doc {
|
|
||||||
inherit pkgs config;
|
|
||||||
version = "0.1";
|
|
||||||
revision = "master";
|
|
||||||
options =
|
|
||||||
let
|
|
||||||
scrubbedEval = evalModules {
|
|
||||||
modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules;
|
|
||||||
args = (config._module.args) // { modules = [ ]; };
|
|
||||||
specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; };
|
|
||||||
};
|
|
||||||
scrubDerivations = namePrefix: pkgSet: mapAttrs
|
|
||||||
(name: value:
|
|
||||||
let wholeName = "${namePrefix}.${name}"; in
|
|
||||||
if isAttrs value then
|
|
||||||
scrubDerivations wholeName value
|
|
||||||
// (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; })
|
|
||||||
else value
|
|
||||||
)
|
|
||||||
pkgSet;
|
|
||||||
in scrubbedEval.options;
|
|
||||||
};
|
|
||||||
|
|
||||||
manualHtmlRoot = "${homeManagerManual.manual}/share/doc/home-manager/index.html";
|
|
||||||
|
|
||||||
helpScript = pkgs.writeShellScriptBin "home-manager-help" ''
|
|
||||||
#!${pkgs.bash}/bin/bash -e
|
|
||||||
|
|
||||||
if [ -z "$BROWSER" ]; then
|
|
||||||
for candidate in xdg-open open w3m; do
|
|
||||||
BROWSER="$(type -P $candidate || true)"
|
|
||||||
if [ -x "$BROWSER" ]; then
|
|
||||||
break;
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$BROWSER" ]; then
|
|
||||||
echo "$0: unable to start a web browser; please set \$BROWSER"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$BROWSER" ${manualHtmlRoot}
|
|
||||||
'';
|
|
||||||
|
|
||||||
in
|
in
|
||||||
|
|
||||||
|
@ -100,15 +52,10 @@ in
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
home.packages = mkMerge [
|
home.packages = mkMerge [
|
||||||
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
|
(mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ])
|
||||||
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
|
(mkIf cfg.manpages.enable [ docs.manPages ])
|
||||||
(mkIf cfg.json.enable [ homeManagerManual.optionsJSON ])
|
(mkIf cfg.json.enable [ docs.options.json ])
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
# To fix error during manpage build.
|
|
||||||
meta = {
|
|
||||||
maintainers = [ maintainers.rycee ];
|
|
||||||
doc = builtins.toFile "nothingness" "";
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue