mirror of
https://github.com/nix-community/home-manager
synced 2024-11-26 21:19:45 +01:00
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
7 changed files with 42 additions and 887 deletions
343
doc/default.nix
343
doc/default.nix
|
@ -1,122 +1,33 @@
|
|||
{ pkgs, options, config, version, revision, extraSources ? [] }:
|
||||
|
||||
with pkgs;
|
||||
{ pkgs }:
|
||||
|
||||
let
|
||||
|
||||
lib = pkgs.lib;
|
||||
|
||||
# Remove invisible and internal options.
|
||||
optionsListVisible = lib.filter (opt: opt.visible && !opt.internal) (lib.optionAttrSetToDocList options);
|
||||
nmdSrc = pkgs.fetchFromGitLab {
|
||||
owner = "rycee";
|
||||
repo = "nmd";
|
||||
rev = "b57fc6657b6645086a286e62a05a1795f258daa6";
|
||||
sha256 = "1b6bdgn6d4awxi8al5hbw8vycxp4laf63l29rjrvxi2j2g69rgvc";
|
||||
};
|
||||
|
||||
# Replace functions by the string <function>
|
||||
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;
|
||||
nmd = import nmdSrc { inherit pkgs; };
|
||||
|
||||
# Generate DocBook documentation for a list of packages. This is
|
||||
# what `relatedPackages` option of `mkOption` from
|
||||
# ../../../lib/options.nix influences.
|
||||
#
|
||||
# Each element of `relatedPackages` can be either
|
||||
# - a string: that will be interpreted as an attribute name from `pkgs`,
|
||||
# - a list: that will be interpreted as an attribute path from `pkgs`,
|
||||
# - 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>";
|
||||
hmModulesDocs = nmd.buildModulesDocs {
|
||||
modules = import ../modules/modules.nix { inherit lib pkgs; };
|
||||
moduleRootPaths = [ ./.. ];
|
||||
mkModuleUrl = path:
|
||||
"https://github.com/rycee/home-manager/blob/master/${path}#blob-path";
|
||||
channelName = "home-manager";
|
||||
docBook.id = "home-manager-options";
|
||||
};
|
||||
|
||||
optionsListDesc = lib.flip map optionsListVisible (opt: opt // {
|
||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||
declarations = map stripAnyPrefixes opt.declarations;
|
||||
}
|
||||
// lib.optionalAttrs (opt ? example) { example = substFunction opt.example; }
|
||||
// lib.optionalAttrs (opt ? default) { default = substFunction opt.default; }
|
||||
// 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">
|
||||
docs = nmd.buildDocBookDocs {
|
||||
pathName = "home-manager";
|
||||
modulesDocs = [ hmModulesDocs ];
|
||||
documentsDirectory = ./.;
|
||||
chunkToc = ''
|
||||
<toc>
|
||||
<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-tools"><?dbhtml filename="tools.html"?></d:tocentry>
|
||||
|
@ -124,206 +35,22 @@ let
|
|||
</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 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}"
|
||||
];
|
||||
in
|
||||
|
||||
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
|
||||
xmllint --xinclude --noxincludenode \
|
||||
--output ./man-pages-combined.xml ./man-pages.xml
|
||||
options = {
|
||||
json = hmModulesDocs.json.override {
|
||||
path = "share/doc/home-manager/options.json";
|
||||
};
|
||||
};
|
||||
|
||||
# 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
|
||||
manPages = docs.manPages;
|
||||
|
||||
# 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 \
|
||||
${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
|
||||
'';
|
||||
manual = {
|
||||
inherit (docs) html htmlOpenTool;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
You can use the following options in
|
||||
<filename>home-configuration.nix</filename>:
|
||||
</para>
|
||||
<xi:include href="./generated/options-db.xml" xpointer="configuration-variable-list" />
|
||||
<xi:include href="./nmd-result/home-manager-options.xml" />
|
||||
</refsection>
|
||||
<refsection>
|
||||
<title>See also</title>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<xi:include href="installation.xml" />
|
||||
<appendix xml:id="ch-options">
|
||||
<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 xml:id="ch-tools">
|
||||
<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;
|
||||
|
||||
|
@ -6,55 +6,7 @@ let
|
|||
|
||||
cfg = config.manual;
|
||||
|
||||
/* For the purpose of generating docs, evaluate options with each derivation
|
||||
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}
|
||||
'';
|
||||
docs = import ../doc { inherit pkgs; };
|
||||
|
||||
in
|
||||
|
||||
|
@ -100,15 +52,10 @@ in
|
|||
|
||||
config = {
|
||||
home.packages = mkMerge [
|
||||
(mkIf cfg.html.enable [ helpScript homeManagerManual.manual ])
|
||||
(mkIf cfg.manpages.enable [ homeManagerManual.manpages ])
|
||||
(mkIf cfg.json.enable [ homeManagerManual.optionsJSON ])
|
||||
(mkIf cfg.html.enable [ docs.manual.html docs.manual.htmlOpenTool ])
|
||||
(mkIf cfg.manpages.enable [ docs.manPages ])
|
||||
(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