Merge pull request #237557 from pennae/dedocbookify-nixos
nixos/doc: dedocbookify
This commit is contained in:
commit
c8b4e5d557
18 changed files with 106 additions and 724 deletions
21
.github/workflows/compare-manuals.sh
vendored
21
.github/workflows/compare-manuals.sh
vendored
|
@ -1,21 +0,0 @@
|
||||||
#!/usr/bin/env nix-shell
|
|
||||||
#! nix-shell -i bash -p html-tidy
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
shopt -s inherit_errexit
|
|
||||||
|
|
||||||
normalize() {
|
|
||||||
tidy \
|
|
||||||
--anchor-as-name no \
|
|
||||||
--coerce-endtags no \
|
|
||||||
--escape-scripts no \
|
|
||||||
--fix-backslash no \
|
|
||||||
--fix-style-tags no \
|
|
||||||
--fix-uri no \
|
|
||||||
--indent yes \
|
|
||||||
--wrap 0 \
|
|
||||||
< "$1" \
|
|
||||||
2> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
diff -U3 <(normalize "$1") <(normalize "$2")
|
|
10
.github/workflows/manual-nixos.yml
vendored
10
.github/workflows/manual-nixos.yml
vendored
|
@ -27,13 +27,5 @@ jobs:
|
||||||
# This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
|
# This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
|
||||||
name: nixpkgs-ci
|
name: nixpkgs-ci
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
||||||
- name: Building NixOS manual with DocBook options
|
- name: Building NixOS manual
|
||||||
run: NIX_PATH=nixpkgs=$(pwd) nix-build --option restrict-eval true nixos/release.nix -A manual.x86_64-linux
|
run: NIX_PATH=nixpkgs=$(pwd) nix-build --option restrict-eval true nixos/release.nix -A manual.x86_64-linux
|
||||||
- name: Building NixOS manual with Markdown options
|
|
||||||
run: |
|
|
||||||
export NIX_PATH=nixpkgs=$(pwd)
|
|
||||||
nix-build \
|
|
||||||
--option restrict-eval true \
|
|
||||||
--arg configuration '{ documentation.nixos.options.allowDocBook = false; }' \
|
|
||||||
nixos/release.nix \
|
|
||||||
-A manual.x86_64-linux
|
|
||||||
|
|
64
.github/workflows/manual-rendering.yml
vendored
64
.github/workflows/manual-rendering.yml
vendored
|
@ -1,64 +0,0 @@
|
||||||
name: "Check NixOS Manual DocBook rendering against MD rendering"
|
|
||||||
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
# * is a special character in YAML so you have to quote this string
|
|
||||||
# Check every 24 hours
|
|
||||||
- cron: '0 0 * * *'
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
check-rendering-equivalence:
|
|
||||||
permissions:
|
|
||||||
pull-requests: write # for peter-evans/create-or-update-comment to create or update comment
|
|
||||||
if: github.repository_owner == 'NixOS'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
- uses: cachix/install-nix-action@v21
|
|
||||||
with:
|
|
||||||
# explicitly enable sandbox
|
|
||||||
extra_nix_config: sandbox = true
|
|
||||||
- uses: cachix/cachix-action@v12
|
|
||||||
with:
|
|
||||||
# This cache is for the nixpkgs repo checks and should not be trusted or used elsewhere.
|
|
||||||
name: nixpkgs-ci
|
|
||||||
signingKey: '${{ secrets.CACHIX_SIGNING_KEY }}'
|
|
||||||
|
|
||||||
- name: Build DocBook and MD manuals
|
|
||||||
run: |
|
|
||||||
export NIX_PATH=nixpkgs=$(pwd)
|
|
||||||
nix-build \
|
|
||||||
--option restrict-eval true \
|
|
||||||
-o docbook nixos/release.nix \
|
|
||||||
-A manual.x86_64-linux
|
|
||||||
nix-build \
|
|
||||||
--option restrict-eval true \
|
|
||||||
--arg configuration '{ documentation.nixos.options.allowDocBook = false; }' \
|
|
||||||
-o md nixos/release.nix \
|
|
||||||
-A manual.x86_64-linux
|
|
||||||
|
|
||||||
- name: Compare DocBook and MD manuals
|
|
||||||
id: check
|
|
||||||
run: |
|
|
||||||
export NIX_PATH=nixpkgs=$(pwd)
|
|
||||||
.github/workflows/compare-manuals.sh \
|
|
||||||
docbook/share/doc/nixos/options.html \
|
|
||||||
md/share/doc/nixos/options.html
|
|
||||||
|
|
||||||
# if the manual can't be built we don't want to notify anyone.
|
|
||||||
# while this may temporarily hide rendering failures it will be a lot
|
|
||||||
# less noisy until all nixpkgs pull requests have stopped using
|
|
||||||
# docbook for option docs.
|
|
||||||
- name: Comment on failure
|
|
||||||
uses: peter-evans/create-or-update-comment@v3
|
|
||||||
if: ${{ failure() && steps.check.conclusion == 'failure' }}
|
|
||||||
with:
|
|
||||||
issue-number: 189318
|
|
||||||
body: |
|
|
||||||
Markdown and DocBook manuals do not agree.
|
|
||||||
|
|
||||||
Check https://github.com/NixOS/nixpkgs/actions/runs/${{ github.run_id }} for details.
|
|
|
@ -138,7 +138,7 @@ let
|
||||||
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
|
mergeDefaultOption mergeOneOption mergeEqualOption mergeUniqueOption
|
||||||
getValues getFiles
|
getValues getFiles
|
||||||
optionAttrSetToDocList optionAttrSetToDocList'
|
optionAttrSetToDocList optionAttrSetToDocList'
|
||||||
scrubOptionValue literalExpression literalExample literalDocBook
|
scrubOptionValue literalExpression literalExample
|
||||||
showOption showOptionWithDefLocs showFiles
|
showOption showOptionWithDefLocs showFiles
|
||||||
unknownModule mkOption mkPackageOption mkPackageOptionMD
|
unknownModule mkOption mkPackageOption mkPackageOptionMD
|
||||||
mdDoc literalMD;
|
mdDoc literalMD;
|
||||||
|
|
|
@ -134,11 +134,6 @@ let
|
||||||
${if prefix == []
|
${if prefix == []
|
||||||
then null # unset => visible
|
then null # unset => visible
|
||||||
else "internal"} = true;
|
else "internal"} = true;
|
||||||
# TODO: hidden during the markdown transition to not expose downstream
|
|
||||||
# users of the docs infra to markdown if they're not ready for it.
|
|
||||||
# we don't make this visible conditionally because it can impact
|
|
||||||
# performance (https://github.com/NixOS/nixpkgs/pull/208407#issuecomment-1368246192)
|
|
||||||
visible = false;
|
|
||||||
# TODO: Change the type of this option to a submodule with a
|
# TODO: Change the type of this option to a submodule with a
|
||||||
# freeformType, so that individual arguments can be documented
|
# freeformType, so that individual arguments can be documented
|
||||||
# separately
|
# separately
|
||||||
|
@ -1146,14 +1141,11 @@ let
|
||||||
use = id;
|
use = id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Transitional version of mkAliasOptionModule that uses MD docs. */
|
/* Transitional version of mkAliasOptionModule that uses MD docs.
|
||||||
mkAliasOptionModuleMD = from: to: doRename {
|
|
||||||
inherit from to;
|
This function is no longer necessary and merely an alias of `mkAliasOptionModule`.
|
||||||
visible = true;
|
*/
|
||||||
warn = false;
|
mkAliasOptionModuleMD = mkAliasOptionModule;
|
||||||
use = id;
|
|
||||||
markdown = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b
|
/* mkDerivedConfig : Option a -> (a -> Definition b) -> Definition b
|
||||||
|
|
||||||
|
@ -1175,7 +1167,7 @@ let
|
||||||
(opt.highestPrio or defaultOverridePriority)
|
(opt.highestPrio or defaultOverridePriority)
|
||||||
(f opt.value);
|
(f opt.value);
|
||||||
|
|
||||||
doRename = { from, to, visible, warn, use, withPriority ? true, markdown ? false }:
|
doRename = { from, to, visible, warn, use, withPriority ? true }:
|
||||||
{ config, options, ... }:
|
{ config, options, ... }:
|
||||||
let
|
let
|
||||||
fromOpt = getAttrFromPath from options;
|
fromOpt = getAttrFromPath from options;
|
||||||
|
@ -1186,9 +1178,7 @@ let
|
||||||
{
|
{
|
||||||
options = setAttrByPath from (mkOption {
|
options = setAttrByPath from (mkOption {
|
||||||
inherit visible;
|
inherit visible;
|
||||||
description = if markdown
|
description = "Alias of {option}`${showOption to}`.";
|
||||||
then lib.mdDoc "Alias of {option}`${showOption to}`."
|
|
||||||
else "Alias of <option>${showOption to}</option>.";
|
|
||||||
apply = x: use (toOf config);
|
apply = x: use (toOf config);
|
||||||
} // optionalAttrs (toType != null) {
|
} // optionalAttrs (toType != null) {
|
||||||
type = toType;
|
type = toType;
|
||||||
|
|
|
@ -100,10 +100,7 @@ rec {
|
||||||
name: mkOption {
|
name: mkOption {
|
||||||
default = false;
|
default = false;
|
||||||
example = true;
|
example = true;
|
||||||
description =
|
description = "Whether to enable ${name}.";
|
||||||
if name ? _type && name._type == "mdDoc"
|
|
||||||
then lib.mdDoc "Whether to enable ${name.text}."
|
|
||||||
else "Whether to enable ${name}.";
|
|
||||||
type = lib.types.bool;
|
type = lib.types.bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,10 +182,10 @@ rec {
|
||||||
(if isList example then "pkgs." + concatStringsSep "." example else example);
|
(if isList example then "pkgs." + concatStringsSep "." example else example);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Like mkPackageOption, but emit an mdDoc description instead of DocBook. */
|
/* Alias of mkPackageOption. Previously used to create options with markdown
|
||||||
mkPackageOptionMD = pkgs: name: extra:
|
documentation, which is no longer required.
|
||||||
let option = mkPackageOption pkgs name extra;
|
*/
|
||||||
in option // { description = lib.mdDoc option.description; };
|
mkPackageOptionMD = mkPackageOption;
|
||||||
|
|
||||||
/* This option accepts anything, but it does not produce any result.
|
/* This option accepts anything, but it does not produce any result.
|
||||||
|
|
||||||
|
@ -344,26 +341,12 @@ rec {
|
||||||
if ! isString text then throw "literalExpression expects a string."
|
if ! isString text then throw "literalExpression expects a string."
|
||||||
else { _type = "literalExpression"; inherit text; };
|
else { _type = "literalExpression"; inherit text; };
|
||||||
|
|
||||||
literalExample = lib.warn "literalExample is deprecated, use literalExpression instead, or use literalDocBook for a non-Nix description." literalExpression;
|
literalExample = lib.warn "literalExample is deprecated, use literalExpression instead, or use literalMD for a non-Nix description." literalExpression;
|
||||||
|
|
||||||
|
|
||||||
/* For use in the `defaultText` and `example` option attributes. Causes the
|
|
||||||
given DocBook text to be inserted verbatim in the documentation, for when
|
|
||||||
a `literalExpression` would be too hard to read.
|
|
||||||
*/
|
|
||||||
literalDocBook = text:
|
|
||||||
if ! isString text then throw "literalDocBook expects a string."
|
|
||||||
else
|
|
||||||
lib.warnIf (lib.isInOldestRelease 2211)
|
|
||||||
"literalDocBook is deprecated, use literalMD instead"
|
|
||||||
{ _type = "literalDocBook"; inherit text; };
|
|
||||||
|
|
||||||
/* Transition marker for documentation that's already migrated to markdown
|
/* Transition marker for documentation that's already migrated to markdown
|
||||||
syntax.
|
syntax. This is a no-op and no longer needed.
|
||||||
*/
|
*/
|
||||||
mdDoc = text:
|
mdDoc = lib.id;
|
||||||
if ! isString text then throw "mdDoc expects a string."
|
|
||||||
else { _type = "mdDoc"; inherit text; };
|
|
||||||
|
|
||||||
/* For use in the `defaultText` and `example` option attributes. Causes the
|
/* For use in the `defaultText` and `example` option attributes. Causes the
|
||||||
given MD text to be inserted verbatim in the documentation, for when
|
given MD text to be inserted verbatim in the documentation, for when
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
, extraSources ? []
|
, extraSources ? []
|
||||||
, baseOptionsJSON ? null
|
, baseOptionsJSON ? null
|
||||||
, warningsAreErrors ? true
|
, warningsAreErrors ? true
|
||||||
, allowDocBook ? true
|
|
||||||
, prefix ? ../../..
|
, prefix ? ../../..
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
@ -17,10 +16,6 @@ let
|
||||||
|
|
||||||
lib = pkgs.lib;
|
lib = pkgs.lib;
|
||||||
|
|
||||||
docbook_xsl_ns = pkgs.docbook-xsl-ns.override {
|
|
||||||
withManOptDedupPatch = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
manpageUrls = pkgs.path + "/doc/manpage-urls.json";
|
manpageUrls = pkgs.path + "/doc/manpage-urls.json";
|
||||||
|
|
||||||
# We need to strip references to /nix/store/* from options,
|
# We need to strip references to /nix/store/* from options,
|
||||||
|
@ -33,7 +28,7 @@ let
|
||||||
stripAnyPrefixes = lib.flip (lib.foldr lib.removePrefix) prefixesToStrip;
|
stripAnyPrefixes = lib.flip (lib.foldr lib.removePrefix) prefixesToStrip;
|
||||||
|
|
||||||
optionsDoc = buildPackages.nixosOptionsDoc {
|
optionsDoc = buildPackages.nixosOptionsDoc {
|
||||||
inherit options revision baseOptionsJSON warningsAreErrors allowDocBook;
|
inherit options revision baseOptionsJSON warningsAreErrors;
|
||||||
transformOptions = opt: opt // {
|
transformOptions = opt: opt // {
|
||||||
# Clean up declaration sites to not refer to the NixOS source tree.
|
# Clean up declaration sites to not refer to the NixOS source tree.
|
||||||
declarations = map stripAnyPrefixes opt.declarations;
|
declarations = map stripAnyPrefixes opt.declarations;
|
||||||
|
@ -68,73 +63,6 @@ let
|
||||||
optionIdPrefix = "test-opt-";
|
optionIdPrefix = "test-opt-";
|
||||||
};
|
};
|
||||||
|
|
||||||
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 chapter.autolabel 0"
|
|
||||||
"--param part.autolabel 0"
|
|
||||||
"--param preface.autolabel 0"
|
|
||||||
"--param reference.autolabel 0"
|
|
||||||
"--param section.autolabel 0"
|
|
||||||
"--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 0"
|
|
||||||
"--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}"
|
|
||||||
];
|
|
||||||
|
|
||||||
linterFunctions = ''
|
|
||||||
# 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
|
|
||||||
}
|
|
||||||
'';
|
|
||||||
|
|
||||||
prepareManualFromMD = ''
|
prepareManualFromMD = ''
|
||||||
cp -r --no-preserve=all $inputs/* .
|
cp -r --no-preserve=all $inputs/* .
|
||||||
|
|
||||||
|
@ -154,61 +82,13 @@ let
|
||||||
${testOptionsDoc.optionsJSON}/share/doc/nixos/options.json
|
${testOptionsDoc.optionsJSON}/share/doc/nixos/options.json
|
||||||
'';
|
'';
|
||||||
|
|
||||||
manual-combined = runCommand "nixos-manual-combined"
|
|
||||||
{ inputs = lib.sourceFilesBySuffices ./. [ ".xml" ".md" ];
|
|
||||||
nativeBuildInputs = [ pkgs.nixos-render-docs pkgs.libxml2.bin pkgs.libxslt.bin ];
|
|
||||||
meta.description = "The NixOS manual as plain docbook XML";
|
|
||||||
}
|
|
||||||
''
|
|
||||||
${prepareManualFromMD}
|
|
||||||
|
|
||||||
nixos-render-docs -j $NIX_BUILD_CORES manual docbook \
|
|
||||||
--manpage-urls ${manpageUrls} \
|
|
||||||
--revision ${lib.escapeShellArg revision} \
|
|
||||||
./manual.md \
|
|
||||||
./manual-combined-pre.xml
|
|
||||||
|
|
||||||
xsltproc \
|
|
||||||
-o manual-combined.xml ${./../../lib/make-options-doc/postprocess-option-descriptions.xsl} \
|
|
||||||
manual-combined-pre.xml
|
|
||||||
|
|
||||||
${linterFunctions}
|
|
||||||
|
|
||||||
mkdir $out
|
|
||||||
cp manual-combined.xml $out/
|
|
||||||
|
|
||||||
lintrng $out/manual-combined.xml
|
|
||||||
'';
|
|
||||||
|
|
||||||
manpages-combined = runCommand "nixos-manpages-combined.xml"
|
|
||||||
{ nativeBuildInputs = [ buildPackages.libxml2.bin buildPackages.libxslt.bin ];
|
|
||||||
meta.description = "The NixOS manpages as plain docbook XML";
|
|
||||||
}
|
|
||||||
''
|
|
||||||
mkdir generated
|
|
||||||
cp -prd ${./man-pages.xml} man-pages.xml
|
|
||||||
ln -s ${optionsDoc.optionsDocBook} generated/options-db.xml
|
|
||||||
|
|
||||||
xmllint --xinclude --noxincludenode --output $out ./man-pages.xml
|
|
||||||
|
|
||||||
${linterFunctions}
|
|
||||||
|
|
||||||
lintrng $out
|
|
||||||
'';
|
|
||||||
|
|
||||||
in rec {
|
in rec {
|
||||||
inherit (optionsDoc) optionsJSON optionsNix optionsDocBook optionsUsedDocbook;
|
inherit (optionsDoc) optionsJSON optionsNix optionsDocBook;
|
||||||
|
|
||||||
# Generate the NixOS manual.
|
# Generate the NixOS manual.
|
||||||
manualHTML = runCommand "nixos-manual-html"
|
manualHTML = runCommand "nixos-manual-html"
|
||||||
{ nativeBuildInputs =
|
{ nativeBuildInputs = [ buildPackages.nixos-render-docs ];
|
||||||
if allowDocBook then [
|
inputs = lib.sourceFilesBySuffices ./. [ ".md" ];
|
||||||
buildPackages.libxml2.bin
|
|
||||||
buildPackages.libxslt.bin
|
|
||||||
] else [
|
|
||||||
buildPackages.nixos-render-docs
|
|
||||||
];
|
|
||||||
inputs = lib.optionals (! allowDocBook) (lib.sourceFilesBySuffices ./. [ ".md" ]);
|
|
||||||
meta.description = "The NixOS manual in HTML format";
|
meta.description = "The NixOS manual in HTML format";
|
||||||
allowedReferences = ["out"];
|
allowedReferences = ["out"];
|
||||||
}
|
}
|
||||||
|
@ -221,38 +101,21 @@ in rec {
|
||||||
cp ${../../../doc/overrides.css} $dst/overrides.css
|
cp ${../../../doc/overrides.css} $dst/overrides.css
|
||||||
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
|
cp -r ${pkgs.documentation-highlighter} $dst/highlightjs
|
||||||
|
|
||||||
${if allowDocBook then ''
|
${prepareManualFromMD}
|
||||||
xsltproc \
|
|
||||||
${manualXsltprocOptions} \
|
|
||||||
--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
|
nixos-render-docs -j $NIX_BUILD_CORES manual html \
|
||||||
cp ${docbook_xsl_ns}/xml/xsl/docbook/images/callouts/*.svg $dst/images/callouts/
|
--manpage-urls ${manpageUrls} \
|
||||||
'' else ''
|
--revision ${lib.escapeShellArg revision} \
|
||||||
${prepareManualFromMD}
|
--generator "nixos-render-docs ${lib.version}" \
|
||||||
|
--stylesheet style.css \
|
||||||
# TODO generator is set like this because the docbook/md manual compare workflow will
|
--stylesheet overrides.css \
|
||||||
# trigger if it's different
|
--stylesheet highlightjs/mono-blue.css \
|
||||||
nixos-render-docs -j $NIX_BUILD_CORES manual html \
|
--script ./highlightjs/highlight.pack.js \
|
||||||
--manpage-urls ${manpageUrls} \
|
--script ./highlightjs/loader.js \
|
||||||
--revision ${lib.escapeShellArg revision} \
|
--toc-depth 1 \
|
||||||
--generator "DocBook XSL Stylesheets V${docbook_xsl_ns.version}" \
|
--chunk-toc-depth 1 \
|
||||||
--stylesheet style.css \
|
./manual.md \
|
||||||
--stylesheet overrides.css \
|
$dst/index.html
|
||||||
--stylesheet highlightjs/mono-blue.css \
|
|
||||||
--script ./highlightjs/highlight.pack.js \
|
|
||||||
--script ./highlightjs/loader.js \
|
|
||||||
--toc-depth 1 \
|
|
||||||
--chunk-toc-depth 1 \
|
|
||||||
./manual.md \
|
|
||||||
$dst/index.html
|
|
||||||
''}
|
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
|
echo "nix-build out $out" >> $out/nix-support/hydra-build-products
|
||||||
|
@ -318,10 +181,6 @@ in rec {
|
||||||
manpages = runCommand "nixos-manpages"
|
manpages = runCommand "nixos-manpages"
|
||||||
{ nativeBuildInputs = [
|
{ nativeBuildInputs = [
|
||||||
buildPackages.installShellFiles
|
buildPackages.installShellFiles
|
||||||
] ++ lib.optionals allowDocBook [
|
|
||||||
buildPackages.libxml2.bin
|
|
||||||
buildPackages.libxslt.bin
|
|
||||||
] ++ lib.optionals (! allowDocBook) [
|
|
||||||
buildPackages.nixos-render-docs
|
buildPackages.nixos-render-docs
|
||||||
];
|
];
|
||||||
allowedReferences = ["out"];
|
allowedReferences = ["out"];
|
||||||
|
@ -330,24 +189,11 @@ in rec {
|
||||||
# Generate manpages.
|
# Generate manpages.
|
||||||
mkdir -p $out/share/man/man8
|
mkdir -p $out/share/man/man8
|
||||||
installManPage ${./manpages}/*
|
installManPage ${./manpages}/*
|
||||||
${if allowDocBook
|
mkdir -p $out/share/man/man5
|
||||||
then ''
|
nixos-render-docs -j $NIX_BUILD_CORES options manpage \
|
||||||
xsltproc --nonet \
|
--revision ${lib.escapeShellArg revision} \
|
||||||
--maxdepth 6000 \
|
${optionsJSON}/share/doc/nixos/options.json \
|
||||||
--param man.output.in.separate.dir 1 \
|
$out/share/man/man5/configuration.nix.5
|
||||||
--param man.output.base.dir "'$out/share/man/'" \
|
|
||||||
--param man.endnotes.are.numbered 0 \
|
|
||||||
--param man.break.after.slash 1 \
|
|
||||||
${docbook_xsl_ns}/xml/xsl/docbook/manpages/docbook.xsl \
|
|
||||||
${manpages-combined}
|
|
||||||
''
|
|
||||||
else ''
|
|
||||||
mkdir -p $out/share/man/man5
|
|
||||||
nixos-render-docs -j $NIX_BUILD_CORES options manpage \
|
|
||||||
--revision ${lib.escapeShellArg revision} \
|
|
||||||
${optionsJSON}/share/doc/nixos/options.json \
|
|
||||||
$out/share/man/man5/configuration.nix.5
|
|
||||||
''}
|
|
||||||
'';
|
'';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
<reference xmlns="http://docbook.org/ns/docbook"
|
|
||||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
|
||||||
<title>NixOS Reference Pages</title>
|
|
||||||
<info>
|
|
||||||
<author>
|
|
||||||
<personname><firstname>Eelco</firstname><surname>Dolstra</surname></personname>
|
|
||||||
<contrib>Author</contrib>
|
|
||||||
</author>
|
|
||||||
<author>
|
|
||||||
<personname><othername>The Nixpkgs/NixOS contributors</othername></personname>
|
|
||||||
<contrib>Author</contrib>
|
|
||||||
</author>
|
|
||||||
<copyright><year>2007-2022</year><holder>Eelco Dolstra and the Nixpkgs/NixOS contributors</holder>
|
|
||||||
</copyright>
|
|
||||||
</info>
|
|
||||||
<refentry>
|
|
||||||
<refmeta>
|
|
||||||
<refentrytitle><filename>configuration.nix</filename>
|
|
||||||
</refentrytitle><manvolnum>5</manvolnum>
|
|
||||||
<refmiscinfo class="source">NixOS</refmiscinfo>
|
|
||||||
<!-- <refmiscinfo class="version"><xi:include href="version.txt" parse="text"/></refmiscinfo> -->
|
|
||||||
</refmeta>
|
|
||||||
<refnamediv>
|
|
||||||
<refname><filename>configuration.nix</filename></refname>
|
|
||||||
<refpurpose>NixOS system configuration specification</refpurpose>
|
|
||||||
</refnamediv>
|
|
||||||
<refsection>
|
|
||||||
<title>Description</title>
|
|
||||||
<para>
|
|
||||||
The file <filename>/etc/nixos/configuration.nix</filename> contains the
|
|
||||||
declarative specification of your NixOS system configuration. The command
|
|
||||||
<command>nixos-rebuild</command> takes this file and realises the system
|
|
||||||
configuration specified therein.
|
|
||||||
</para>
|
|
||||||
</refsection>
|
|
||||||
<refsection>
|
|
||||||
<title>Options</title>
|
|
||||||
<para>
|
|
||||||
You can use the following options in <filename>configuration.nix</filename>.
|
|
||||||
</para>
|
|
||||||
<xi:include href="./generated/options-db.xml"
|
|
||||||
xpointer="configuration-variable-list" />
|
|
||||||
</refsection>
|
|
||||||
</refentry>
|
|
||||||
</reference>
|
|
|
@ -58,6 +58,8 @@
|
||||||
|
|
||||||
- A new option was added to the virtualisation module that enables specifying explicitly named network interfaces in QEMU VMs. The existing `virtualisation.vlans` is still supported for cases where the name of the network interface is irrelevant.
|
- A new option was added to the virtualisation module that enables specifying explicitly named network interfaces in QEMU VMs. The existing `virtualisation.vlans` is still supported for cases where the name of the network interface is irrelevant.
|
||||||
|
|
||||||
|
- DocBook option documentation is no longer supported, all module documentation now uses markdown.
|
||||||
|
|
||||||
- `services.nginx` gained a `defaultListen` option at server-level with support for PROXY protocol listeners, also `proxyProtocol` is now exposed in `services.nginx.virtualHosts.<name>.listen` option. It is now possible to run PROXY listeners and non-PROXY listeners at a server-level, see [#213510](https://github.com/NixOS/nixpkgs/pull/213510/) for more details.
|
- `services.nginx` gained a `defaultListen` option at server-level with support for PROXY protocol listeners, also `proxyProtocol` is now exposed in `services.nginx.virtualHosts.<name>.listen` option. It is now possible to run PROXY listeners and non-PROXY listeners at a server-level, see [#213510](https://github.com/NixOS/nixpkgs/pull/213510/) for more details.
|
||||||
|
|
||||||
## Nixpkgs internals {#sec-release-23.11-nixpkgs-internals}
|
## Nixpkgs internals {#sec-release-23.11-nixpkgs-internals}
|
||||||
|
|
|
@ -39,12 +39,17 @@
|
||||||
# allow docbook option docs if `true`. only markdown documentation is allowed when set to
|
# allow docbook option docs if `true`. only markdown documentation is allowed when set to
|
||||||
# `false`, and a different renderer may be used with different bugs and performance
|
# `false`, and a different renderer may be used with different bugs and performance
|
||||||
# characteristics but (hopefully) indistinguishable output.
|
# characteristics but (hopefully) indistinguishable output.
|
||||||
, allowDocBook ? true
|
# deprecated since 23.11.
|
||||||
|
# TODO remove in a while.
|
||||||
|
, allowDocBook ? false
|
||||||
# whether lib.mdDoc is required for descriptions to be read as markdown.
|
# whether lib.mdDoc is required for descriptions to be read as markdown.
|
||||||
# !!! when this is eventually flipped to true, `lib.doRename` should also default to emitting Markdown
|
# deprecated since 23.11.
|
||||||
, markdownByDefault ? false
|
# TODO remove in a while.
|
||||||
|
, markdownByDefault ? true
|
||||||
}:
|
}:
|
||||||
|
|
||||||
|
assert markdownByDefault && ! allowDocBook;
|
||||||
|
|
||||||
let
|
let
|
||||||
rawOpts = lib.optionAttrSetToDocList options;
|
rawOpts = lib.optionAttrSetToDocList options;
|
||||||
transformedOpts = map transformOptions rawOpts;
|
transformedOpts = map transformOptions rawOpts;
|
||||||
|
@ -134,10 +139,17 @@ in rec {
|
||||||
TOUCH_IF_DB=$dst/.used-docbook \
|
TOUCH_IF_DB=$dst/.used-docbook \
|
||||||
python ${./mergeJSON.py} \
|
python ${./mergeJSON.py} \
|
||||||
${lib.optionalString warningsAreErrors "--warnings-are-errors"} \
|
${lib.optionalString warningsAreErrors "--warnings-are-errors"} \
|
||||||
${if allowDocBook then "--warn-on-docbook" else "--error-on-docbook"} \
|
|
||||||
$baseJSON $options \
|
$baseJSON $options \
|
||||||
> $dst/options.json
|
> $dst/options.json
|
||||||
|
|
||||||
|
if grep /nixpkgs/nixos/modules $dst/options.json; then
|
||||||
|
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
|
||||||
|
echo "since this prevents sharing via the NixOS channel. This is typically"
|
||||||
|
echo "caused by an option default that refers to a relative path (see above"
|
||||||
|
echo "for hints about the offending path)."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
brotli -9 < $dst/options.json > $dst/options.json.br
|
brotli -9 < $dst/options.json > $dst/options.json.br
|
||||||
|
|
||||||
mkdir -p $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
|
@ -145,38 +157,19 @@ in rec {
|
||||||
echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products
|
echo "file json-br $dst/options.json.br" >> $out/nix-support/hydra-build-products
|
||||||
'';
|
'';
|
||||||
|
|
||||||
optionsUsedDocbook = pkgs.runCommand "options-used-docbook" {} ''
|
optionsDocBook = lib.warn "optionsDocBook is deprecated since 23.11 and will be removed in 24.05"
|
||||||
if [ -e ${optionsJSON}/share/doc/nixos/.used-docbook ]; then
|
(pkgs.runCommand "options-docbook.xml" {
|
||||||
echo 1
|
nativeBuildInputs = [
|
||||||
else
|
pkgs.nixos-render-docs
|
||||||
echo 0
|
];
|
||||||
fi >"$out"
|
} ''
|
||||||
'';
|
nixos-render-docs -j $NIX_BUILD_CORES options docbook \
|
||||||
|
--manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \
|
||||||
optionsDocBook = pkgs.runCommand "options-docbook.xml" {
|
--revision ${lib.escapeShellArg revision} \
|
||||||
nativeBuildInputs = [
|
--document-type ${lib.escapeShellArg documentType} \
|
||||||
pkgs.nixos-render-docs
|
--varlist-id ${lib.escapeShellArg variablelistId} \
|
||||||
];
|
--id-prefix ${lib.escapeShellArg optionIdPrefix} \
|
||||||
} ''
|
${optionsJSON}/share/doc/nixos/options.json \
|
||||||
nixos-render-docs -j $NIX_BUILD_CORES options docbook \
|
"$out"
|
||||||
--manpage-urls ${pkgs.path + "/doc/manpage-urls.json"} \
|
'');
|
||||||
--revision ${lib.escapeShellArg revision} \
|
|
||||||
--document-type ${lib.escapeShellArg documentType} \
|
|
||||||
--varlist-id ${lib.escapeShellArg variablelistId} \
|
|
||||||
--id-prefix ${lib.escapeShellArg optionIdPrefix} \
|
|
||||||
${lib.optionalString markdownByDefault "--markdown-by-default"} \
|
|
||||||
${optionsJSON}/share/doc/nixos/options.json \
|
|
||||||
options.xml
|
|
||||||
|
|
||||||
if grep /nixpkgs/nixos/modules options.xml; then
|
|
||||||
echo "The manual appears to depend on the location of Nixpkgs, which is bad"
|
|
||||||
echo "since this prevents sharing via the NixOS channel. This is typically"
|
|
||||||
echo "caused by an option default that refers to a relative path (see above"
|
|
||||||
echo "for hints about the offending path)."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
${pkgs.libxslt.bin}/bin/xsltproc \
|
|
||||||
-o "$out" ${./postprocess-option-descriptions.xsl} options.xml
|
|
||||||
'';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,19 +43,11 @@ def unpivot(options: Dict[Key, Option]) -> Dict[str, JSON]:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
warningsAreErrors = False
|
warningsAreErrors = False
|
||||||
warnOnDocbook = False
|
|
||||||
errorOnDocbook = False
|
|
||||||
optOffset = 0
|
optOffset = 0
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
if arg == "--warnings-are-errors":
|
if arg == "--warnings-are-errors":
|
||||||
optOffset += 1
|
optOffset += 1
|
||||||
warningsAreErrors = True
|
warningsAreErrors = True
|
||||||
if arg == "--warn-on-docbook":
|
|
||||||
optOffset += 1
|
|
||||||
warnOnDocbook = True
|
|
||||||
elif arg == "--error-on-docbook":
|
|
||||||
optOffset += 1
|
|
||||||
errorOnDocbook = True
|
|
||||||
|
|
||||||
options = pivot(json.load(open(sys.argv[1 + optOffset], 'r')))
|
options = pivot(json.load(open(sys.argv[1 + optOffset], 'r')))
|
||||||
overrides = pivot(json.load(open(sys.argv[2 + optOffset], 'r')))
|
overrides = pivot(json.load(open(sys.argv[2 + optOffset], 'r')))
|
||||||
|
@ -84,38 +76,10 @@ for (k, v) in overrides.items():
|
||||||
|
|
||||||
severity = "error" if warningsAreErrors else "warning"
|
severity = "error" if warningsAreErrors else "warning"
|
||||||
|
|
||||||
def is_docbook(o, key):
|
|
||||||
val = o.get(key, {})
|
|
||||||
if not isinstance(val, dict):
|
|
||||||
return False
|
|
||||||
return val.get('_type', '') == 'literalDocBook'
|
|
||||||
|
|
||||||
# check that every option has a description
|
# check that every option has a description
|
||||||
hasWarnings = False
|
hasWarnings = False
|
||||||
hasErrors = False
|
hasErrors = False
|
||||||
hasDocBook = False
|
|
||||||
for (k, v) in options.items():
|
for (k, v) in options.items():
|
||||||
if warnOnDocbook or errorOnDocbook:
|
|
||||||
kind = "error" if errorOnDocbook else "warning"
|
|
||||||
if isinstance(v.value.get('description', {}), str):
|
|
||||||
hasErrors |= errorOnDocbook
|
|
||||||
hasDocBook = True
|
|
||||||
print(
|
|
||||||
f"\x1b[1;31m{kind}: option {v.name} description uses DocBook\x1b[0m",
|
|
||||||
file=sys.stderr)
|
|
||||||
elif is_docbook(v.value, 'defaultText'):
|
|
||||||
hasErrors |= errorOnDocbook
|
|
||||||
hasDocBook = True
|
|
||||||
print(
|
|
||||||
f"\x1b[1;31m{kind}: option {v.name} default uses DocBook\x1b[0m",
|
|
||||||
file=sys.stderr)
|
|
||||||
elif is_docbook(v.value, 'example'):
|
|
||||||
hasErrors |= errorOnDocbook
|
|
||||||
hasDocBook = True
|
|
||||||
print(
|
|
||||||
f"\x1b[1;31m{kind}: option {v.name} example uses DocBook\x1b[0m",
|
|
||||||
file=sys.stderr)
|
|
||||||
|
|
||||||
if v.value.get('description', None) is None:
|
if v.value.get('description', None) is None:
|
||||||
hasWarnings = True
|
hasWarnings = True
|
||||||
print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr)
|
print(f"\x1b[1;31m{severity}: option {v.name} has no description\x1b[0m", file=sys.stderr)
|
||||||
|
@ -126,30 +90,6 @@ for (k, v) in options.items():
|
||||||
f"\x1b[1;31m{severity}: option {v.name} has no type. Please specify a valid type, see " +
|
f"\x1b[1;31m{severity}: option {v.name} has no type. Please specify a valid type, see " +
|
||||||
"https://nixos.org/manual/nixos/stable/index.html#sec-option-types\x1b[0m", file=sys.stderr)
|
"https://nixos.org/manual/nixos/stable/index.html#sec-option-types\x1b[0m", file=sys.stderr)
|
||||||
|
|
||||||
if hasDocBook:
|
|
||||||
(why, what) = (
|
|
||||||
("disallowed for in-tree modules", "contribution") if errorOnDocbook
|
|
||||||
else ("deprecated for option documentation", "module")
|
|
||||||
)
|
|
||||||
print("Explanation: The documentation contains descriptions, examples, or defaults written in DocBook. " +
|
|
||||||
"NixOS is in the process of migrating from DocBook to Markdown, and " +
|
|
||||||
f"DocBook is {why}. To change your {what} to "+
|
|
||||||
"use Markdown, apply mdDoc and literalMD and use the *MD variants of option creation " +
|
|
||||||
"functions where they are available. For example:\n" +
|
|
||||||
"\n" +
|
|
||||||
" example.foo = mkOption {\n" +
|
|
||||||
" description = lib.mdDoc ''your description'';\n" +
|
|
||||||
" defaultText = lib.literalMD ''your description of default'';\n" +
|
|
||||||
" };\n" +
|
|
||||||
"\n" +
|
|
||||||
" example.enable = mkEnableOption (lib.mdDoc ''your thing'');\n" +
|
|
||||||
" example.package = mkPackageOptionMD pkgs \"your-package\" {};\n" +
|
|
||||||
" imports = [ (mkAliasOptionModuleMD [ \"example\" \"args\" ] [ \"example\" \"settings\" ]) ];",
|
|
||||||
file = sys.stderr)
|
|
||||||
with open(os.getenv('TOUCH_IF_DB'), 'x'):
|
|
||||||
# just make sure it exists
|
|
||||||
pass
|
|
||||||
|
|
||||||
if hasErrors:
|
if hasErrors:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if hasWarnings and warningsAreErrors:
|
if hasWarnings and warningsAreErrors:
|
||||||
|
|
|
@ -1,115 +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:exsl="http://exslt.org/common"
|
|
||||||
xmlns:db="http://docbook.org/ns/docbook"
|
|
||||||
xmlns:nixos="tag:nixos.org"
|
|
||||||
extension-element-prefixes="str exsl">
|
|
||||||
<xsl:output method='xml' encoding="UTF-8" />
|
|
||||||
|
|
||||||
<xsl:template match="@*|node()">
|
|
||||||
<xsl:copy>
|
|
||||||
<xsl:apply-templates select="@*|node()" />
|
|
||||||
</xsl:copy>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template name="break-up-description">
|
|
||||||
<xsl:param name="input" />
|
|
||||||
<xsl:param name="buffer" />
|
|
||||||
|
|
||||||
<!-- Every time we have two newlines following each other, we want to
|
|
||||||
break it into </para><para>. -->
|
|
||||||
<xsl:variable name="parbreak" select="'

'" />
|
|
||||||
|
|
||||||
<!-- Similar to "(head:tail) = input" in Haskell. -->
|
|
||||||
<xsl:variable name="head" select="$input[1]" />
|
|
||||||
<xsl:variable name="tail" select="$input[position() > 1]" />
|
|
||||||
|
|
||||||
<xsl:choose>
|
|
||||||
<xsl:when test="$head/self::text() and contains($head, $parbreak)">
|
|
||||||
<!-- If the haystack provided to str:split() directly starts or
|
|
||||||
ends with $parbreak, it doesn't generate a <token/> for that,
|
|
||||||
so we are doing this here. -->
|
|
||||||
<xsl:variable name="splitted-raw">
|
|
||||||
<xsl:if test="starts-with($head, $parbreak)"><token /></xsl:if>
|
|
||||||
<xsl:for-each select="str:split($head, $parbreak)">
|
|
||||||
<token><xsl:value-of select="node()" /></token>
|
|
||||||
</xsl:for-each>
|
|
||||||
<!-- Something like ends-with($head, $parbreak), but there is
|
|
||||||
no ends-with() in XSLT, so we need to use substring(). -->
|
|
||||||
<xsl:if test="
|
|
||||||
substring($head, string-length($head) -
|
|
||||||
string-length($parbreak) + 1) = $parbreak
|
|
||||||
"><token /></xsl:if>
|
|
||||||
</xsl:variable>
|
|
||||||
<xsl:variable name="splitted"
|
|
||||||
select="exsl:node-set($splitted-raw)/token" />
|
|
||||||
<!-- The buffer we had so far didn't contain any text nodes that
|
|
||||||
contain a $parbreak, so we can put the buffer along with the
|
|
||||||
first token of $splitted into a para element. -->
|
|
||||||
<para xmlns="http://docbook.org/ns/docbook">
|
|
||||||
<xsl:apply-templates select="exsl:node-set($buffer)" />
|
|
||||||
<xsl:apply-templates select="$splitted[1]/node()" />
|
|
||||||
</para>
|
|
||||||
<!-- We have already emitted the first splitted result, so the
|
|
||||||
last result is going to be set as the new $buffer later
|
|
||||||
because its contents may not be directly followed up by a
|
|
||||||
$parbreak. -->
|
|
||||||
<xsl:for-each select="$splitted[position() > 1
|
|
||||||
and position() < last()]">
|
|
||||||
<para xmlns="http://docbook.org/ns/docbook">
|
|
||||||
<xsl:apply-templates select="node()" />
|
|
||||||
</para>
|
|
||||||
</xsl:for-each>
|
|
||||||
<xsl:call-template name="break-up-description">
|
|
||||||
<xsl:with-param name="input" select="$tail" />
|
|
||||||
<xsl:with-param name="buffer" select="$splitted[last()]/node()" />
|
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:when>
|
|
||||||
<!-- Either non-text node or one without $parbreak, which we just
|
|
||||||
want to buffer and continue recursing. -->
|
|
||||||
<xsl:when test="$input">
|
|
||||||
<xsl:call-template name="break-up-description">
|
|
||||||
<xsl:with-param name="input" select="$tail" />
|
|
||||||
<!-- This essentially appends $head to $buffer. -->
|
|
||||||
<xsl:with-param name="buffer">
|
|
||||||
<xsl:if test="$buffer">
|
|
||||||
<xsl:for-each select="exsl:node-set($buffer)">
|
|
||||||
<xsl:apply-templates select="." />
|
|
||||||
</xsl:for-each>
|
|
||||||
</xsl:if>
|
|
||||||
<xsl:apply-templates select="$head" />
|
|
||||||
</xsl:with-param>
|
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:when>
|
|
||||||
<!-- No more $input, just put the remaining $buffer in a para. -->
|
|
||||||
<xsl:otherwise>
|
|
||||||
<para xmlns="http://docbook.org/ns/docbook">
|
|
||||||
<xsl:apply-templates select="exsl:node-set($buffer)" />
|
|
||||||
</para>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
<xsl:template match="nixos:option-description">
|
|
||||||
<xsl:choose>
|
|
||||||
<!--
|
|
||||||
Only process nodes that are comprised of a single <para/> element,
|
|
||||||
because if that's not the case the description already contains
|
|
||||||
</para><para> in between and we need no further processing.
|
|
||||||
-->
|
|
||||||
<xsl:when test="count(db:para) > 1">
|
|
||||||
<xsl:apply-templates select="node()" />
|
|
||||||
</xsl:when>
|
|
||||||
<xsl:otherwise>
|
|
||||||
<xsl:call-template name="break-up-description">
|
|
||||||
<xsl:with-param name="input"
|
|
||||||
select="exsl:node-set(db:para/node())" />
|
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:otherwise>
|
|
||||||
</xsl:choose>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
</xsl:stylesheet>
|
|
|
@ -107,7 +107,7 @@ let
|
||||||
} >&2
|
} >&2
|
||||||
'';
|
'';
|
||||||
|
|
||||||
inherit (cfg.nixos.options) warningsAreErrors allowDocBook;
|
inherit (cfg.nixos.options) warningsAreErrors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,6 +160,9 @@ in
|
||||||
(mkRenamedOptionModule [ "programs" "info" "enable" ] [ "documentation" "info" "enable" ])
|
(mkRenamedOptionModule [ "programs" "info" "enable" ] [ "documentation" "info" "enable" ])
|
||||||
(mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ])
|
(mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ])
|
||||||
(mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ])
|
(mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ])
|
||||||
|
(mkRemovedOptionModule
|
||||||
|
[ "documentation" "nixos" "options" "allowDocBook" ]
|
||||||
|
"DocBook option documentation is no longer supported")
|
||||||
];
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
|
@ -264,23 +267,6 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
nixos.options.allowDocBook = mkOption {
|
|
||||||
type = types.bool;
|
|
||||||
default = true;
|
|
||||||
description = lib.mdDoc ''
|
|
||||||
Whether to allow DocBook option docs. When set to `false` all option using
|
|
||||||
DocBook documentation will cause a manual build error; additionally a new
|
|
||||||
renderer may be used.
|
|
||||||
|
|
||||||
::: {.note}
|
|
||||||
The `false` setting for this option is not yet fully supported. While it
|
|
||||||
should work fine and produce the same output as the previous toolchain
|
|
||||||
using DocBook it may not work in all circumstances. Whether markdown option
|
|
||||||
documentation is allowed is independent of this option.
|
|
||||||
:::
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
nixos.options.warningsAreErrors = mkOption {
|
nixos.options.warningsAreErrors = mkOption {
|
||||||
type = types.bool;
|
type = types.bool;
|
||||||
default = true;
|
default = true;
|
||||||
|
@ -359,14 +345,6 @@ in
|
||||||
(mkIf cfg.nixos.enable {
|
(mkIf cfg.nixos.enable {
|
||||||
system.build.manual = manual;
|
system.build.manual = manual;
|
||||||
|
|
||||||
system.activationScripts.check-manual-docbook = ''
|
|
||||||
if [[ $(cat ${manual.optionsUsedDocbook}) = 1 ]]; then
|
|
||||||
echo -e "\e[31;1mwarning\e[0m: This configuration contains option documentation in docbook." \
|
|
||||||
"Support for docbook is deprecated and will be removed after NixOS 23.05." \
|
|
||||||
"See nix-store --read-log ${builtins.unsafeDiscardStringContext manual.optionsJSON.drvPath}"
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
|
|
||||||
environment.systemPackages = []
|
environment.systemPackages = []
|
||||||
++ optional cfg.man.enable manual.manpages
|
++ optional cfg.man.enable manual.manpages
|
||||||
++ optionals cfg.doc.enable [ manual.manualHTML nixos-help ];
|
++ optionals cfg.doc.enable [ manual.manualHTML nixos-help ];
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{ lib, stdenv, substituteAll, fetchurl, fetchpatch, findXMLCatalogs, writeScriptBin, ruby, bash, withManOptDedupPatch ? false }:
|
{ lib, stdenv, substituteAll, fetchurl, fetchpatch, findXMLCatalogs, writeScriptBin, ruby, bash }:
|
||||||
|
|
||||||
let
|
let
|
||||||
|
|
||||||
|
@ -36,10 +36,6 @@ let
|
||||||
src = ./catalog-legacy-uris.patch;
|
src = ./catalog-legacy-uris.patch;
|
||||||
inherit legacySuffix suffix version;
|
inherit legacySuffix suffix version;
|
||||||
})
|
})
|
||||||
] ++ lib.optionals withManOptDedupPatch [
|
|
||||||
# Fixes https://github.com/NixOS/nixpkgs/issues/166304
|
|
||||||
# https://github.com/docbook/xslt10-stylesheets/pull/241
|
|
||||||
./fix-man-options-duplication.patch
|
|
||||||
];
|
];
|
||||||
|
|
||||||
propagatedBuildInputs = [ findXMLCatalogs ];
|
propagatedBuildInputs = [ findXMLCatalogs ];
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
--- a/manpages/lists.xsl
|
|
||||||
+++ b/manpages/lists.xsl
|
|
||||||
@@ -110,7 +110,7 @@
|
|
||||||
<xsl:text>.RE </xsl:text>
|
|
||||||
</xsl:template>
|
|
||||||
|
|
||||||
-<xsl:template match="d:varlistentry/d:term"/>
|
|
||||||
+<xsl:template match="d:varlistentry/d:term" priority="1"/>
|
|
||||||
<xsl:template match="d:glossentry/d:glossterm"/>
|
|
||||||
|
|
||||||
<xsl:template match="d:variablelist[ancestor::d:listitem or ancestor::d:step or ancestor::d:glossdef]|
|
|
|
@ -207,7 +207,7 @@ class ManualDocBookRenderer(RendererMixin, DocBookRenderer):
|
||||||
raise RuntimeError(f"rendering {path}") from e
|
raise RuntimeError(f"rendering {path}") from e
|
||||||
return "".join(result)
|
return "".join(result)
|
||||||
def included_options(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
def included_options(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||||
conv = options.DocBookConverter(self._manpage_urls, self._revision, False, 'fragment',
|
conv = options.DocBookConverter(self._manpage_urls, self._revision, 'fragment',
|
||||||
token.meta['list-id'], token.meta['id-prefix'])
|
token.meta['list-id'], token.meta['id-prefix'])
|
||||||
conv.add_options(token.meta['source'])
|
conv.add_options(token.meta['source'])
|
||||||
return conv.finalize(fragment=True)
|
return conv.finalize(fragment=True)
|
||||||
|
@ -469,7 +469,7 @@ class ManualHTMLRenderer(RendererMixin, HTMLRenderer):
|
||||||
return "".join(outer)
|
return "".join(outer)
|
||||||
|
|
||||||
def included_options(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
def included_options(self, token: Token, tokens: Sequence[Token], i: int) -> str:
|
||||||
conv = options.HTMLConverter(self._manpage_urls, self._revision, False,
|
conv = options.HTMLConverter(self._manpage_urls, self._revision,
|
||||||
token.meta['list-id'], token.meta['id-prefix'],
|
token.meta['list-id'], token.meta['id-prefix'],
|
||||||
self._xref_targets)
|
self._xref_targets)
|
||||||
conv.add_options(token.meta['source'])
|
conv.add_options(token.meta['source'])
|
||||||
|
|
|
@ -37,11 +37,10 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
|
||||||
|
|
||||||
_options: dict[str, RenderedOption]
|
_options: dict[str, RenderedOption]
|
||||||
|
|
||||||
def __init__(self, revision: str, markdown_by_default: bool):
|
def __init__(self, revision: str):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._options = {}
|
self._options = {}
|
||||||
self._revision = revision
|
self._revision = revision
|
||||||
self._markdown_by_default = markdown_by_default
|
|
||||||
|
|
||||||
def _sorted_options(self) -> list[tuple[str, RenderedOption]]:
|
def _sorted_options(self) -> list[tuple[str, RenderedOption]]:
|
||||||
keys = list(self._options.keys())
|
keys = list(self._options.keys())
|
||||||
|
@ -106,7 +105,7 @@ class BaseConverter(Converter[md.TR], Generic[md.TR]):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def _render_description(self, desc: str | dict[str, str]) -> list[str]:
|
def _render_description(self, desc: str | dict[str, str]) -> list[str]:
|
||||||
if isinstance(desc, str) and self._markdown_by_default:
|
if isinstance(desc, str):
|
||||||
return [ self._render(desc) ] if desc else []
|
return [ self._render(desc) ] if desc else []
|
||||||
elif isinstance(desc, dict) and desc.get('_type') == 'mdDoc':
|
elif isinstance(desc, dict) and desc.get('_type') == 'mdDoc':
|
||||||
return [ self._render(desc['text']) ] if desc['text'] else []
|
return [ self._render(desc['text']) ] if desc['text'] else []
|
||||||
|
@ -198,35 +197,22 @@ class DocBookConverter(BaseConverter[OptionsDocBookRenderer]):
|
||||||
|
|
||||||
def __init__(self, manpage_urls: Mapping[str, str],
|
def __init__(self, manpage_urls: Mapping[str, str],
|
||||||
revision: str,
|
revision: str,
|
||||||
markdown_by_default: bool,
|
|
||||||
document_type: str,
|
document_type: str,
|
||||||
varlist_id: str,
|
varlist_id: str,
|
||||||
id_prefix: str):
|
id_prefix: str):
|
||||||
super().__init__(revision, markdown_by_default)
|
super().__init__(revision)
|
||||||
self._renderer = OptionsDocBookRenderer(manpage_urls)
|
self._renderer = OptionsDocBookRenderer(manpage_urls)
|
||||||
self._document_type = document_type
|
self._document_type = document_type
|
||||||
self._varlist_id = varlist_id
|
self._varlist_id = varlist_id
|
||||||
self._id_prefix = id_prefix
|
self._id_prefix = id_prefix
|
||||||
|
|
||||||
def _parallel_render_prepare(self) -> Any:
|
def _parallel_render_prepare(self) -> Any:
|
||||||
return (self._renderer._manpage_urls, self._revision, self._markdown_by_default, self._document_type,
|
return (self._renderer._manpage_urls, self._revision, self._document_type,
|
||||||
self._varlist_id, self._id_prefix)
|
self._varlist_id, self._id_prefix)
|
||||||
@classmethod
|
@classmethod
|
||||||
def _parallel_render_init_worker(cls, a: Any) -> DocBookConverter:
|
def _parallel_render_init_worker(cls, a: Any) -> DocBookConverter:
|
||||||
return cls(*a)
|
return cls(*a)
|
||||||
|
|
||||||
def _render_code(self, option: dict[str, Any], key: str) -> list[str]:
|
|
||||||
if lit := option_is(option, key, 'literalDocBook'):
|
|
||||||
return [ f"<para><emphasis>{key.capitalize()}:</emphasis> {lit['text']}</para>" ]
|
|
||||||
else:
|
|
||||||
return super()._render_code(option, key)
|
|
||||||
|
|
||||||
def _render_description(self, desc: str | dict[str, Any]) -> list[str]:
|
|
||||||
if isinstance(desc, str) and not self._markdown_by_default:
|
|
||||||
return [ f"<nixos:option-description><para>{desc}</para></nixos:option-description>" ]
|
|
||||||
else:
|
|
||||||
return super()._render_description(desc)
|
|
||||||
|
|
||||||
def _related_packages_header(self) -> list[str]:
|
def _related_packages_header(self) -> list[str]:
|
||||||
return [
|
return [
|
||||||
"<para>",
|
"<para>",
|
||||||
|
@ -300,19 +286,19 @@ class ManpageConverter(BaseConverter[OptionsManpageRenderer]):
|
||||||
_options_by_id: dict[str, str]
|
_options_by_id: dict[str, str]
|
||||||
_links_in_last_description: Optional[list[str]] = None
|
_links_in_last_description: Optional[list[str]] = None
|
||||||
|
|
||||||
def __init__(self, revision: str, markdown_by_default: bool,
|
def __init__(self, revision: str,
|
||||||
*,
|
*,
|
||||||
# only for parallel rendering
|
# only for parallel rendering
|
||||||
_options_by_id: Optional[dict[str, str]] = None):
|
_options_by_id: Optional[dict[str, str]] = None):
|
||||||
super().__init__(revision, markdown_by_default)
|
super().__init__(revision)
|
||||||
self._options_by_id = _options_by_id or {}
|
self._options_by_id = _options_by_id or {}
|
||||||
self._renderer = OptionsManpageRenderer({}, self._options_by_id)
|
self._renderer = OptionsManpageRenderer({}, self._options_by_id)
|
||||||
|
|
||||||
def _parallel_render_prepare(self) -> Any:
|
def _parallel_render_prepare(self) -> Any:
|
||||||
return ((self._revision, self._markdown_by_default), { '_options_by_id': self._options_by_id })
|
return (self._revision, { '_options_by_id': self._options_by_id })
|
||||||
@classmethod
|
@classmethod
|
||||||
def _parallel_render_init_worker(cls, a: Any) -> ManpageConverter:
|
def _parallel_render_init_worker(cls, a: Any) -> ManpageConverter:
|
||||||
return cls(*a[0], **a[1])
|
return cls(a[0], **a[1])
|
||||||
|
|
||||||
def _render_option(self, name: str, option: dict[str, Any]) -> RenderedOption:
|
def _render_option(self, name: str, option: dict[str, Any]) -> RenderedOption:
|
||||||
links = self._renderer.link_footnotes = []
|
links = self._renderer.link_footnotes = []
|
||||||
|
@ -326,20 +312,11 @@ class ManpageConverter(BaseConverter[OptionsManpageRenderer]):
|
||||||
return super().add_options(options)
|
return super().add_options(options)
|
||||||
|
|
||||||
def _render_code(self, option: dict[str, Any], key: str) -> list[str]:
|
def _render_code(self, option: dict[str, Any], key: str) -> list[str]:
|
||||||
if lit := option_is(option, key, 'literalDocBook'):
|
try:
|
||||||
raise RuntimeError("can't render manpages in the presence of docbook")
|
self._renderer.inline_code_is_quoted = False
|
||||||
else:
|
return super()._render_code(option, key)
|
||||||
try:
|
finally:
|
||||||
self._renderer.inline_code_is_quoted = False
|
self._renderer.inline_code_is_quoted = True
|
||||||
return super()._render_code(option, key)
|
|
||||||
finally:
|
|
||||||
self._renderer.inline_code_is_quoted = True
|
|
||||||
|
|
||||||
def _render_description(self, desc: str | dict[str, Any]) -> list[str]:
|
|
||||||
if isinstance(desc, str) and not self._markdown_by_default:
|
|
||||||
raise RuntimeError("can't render manpages in the presence of docbook")
|
|
||||||
else:
|
|
||||||
return super()._render_description(desc)
|
|
||||||
|
|
||||||
def _related_packages_header(self) -> list[str]:
|
def _related_packages_header(self) -> list[str]:
|
||||||
return [
|
return [
|
||||||
|
@ -420,32 +397,16 @@ class OptionsCommonMarkRenderer(OptionDocsRestrictions, CommonMarkRenderer):
|
||||||
class CommonMarkConverter(BaseConverter[OptionsCommonMarkRenderer]):
|
class CommonMarkConverter(BaseConverter[OptionsCommonMarkRenderer]):
|
||||||
__option_block_separator__ = ""
|
__option_block_separator__ = ""
|
||||||
|
|
||||||
def __init__(self, manpage_urls: Mapping[str, str], revision: str, markdown_by_default: bool):
|
def __init__(self, manpage_urls: Mapping[str, str], revision: str):
|
||||||
super().__init__(revision, markdown_by_default)
|
super().__init__(revision)
|
||||||
self._renderer = OptionsCommonMarkRenderer(manpage_urls)
|
self._renderer = OptionsCommonMarkRenderer(manpage_urls)
|
||||||
|
|
||||||
def _parallel_render_prepare(self) -> Any:
|
def _parallel_render_prepare(self) -> Any:
|
||||||
return (self._renderer._manpage_urls, self._revision, self._markdown_by_default)
|
return (self._renderer._manpage_urls, self._revision)
|
||||||
@classmethod
|
@classmethod
|
||||||
def _parallel_render_init_worker(cls, a: Any) -> CommonMarkConverter:
|
def _parallel_render_init_worker(cls, a: Any) -> CommonMarkConverter:
|
||||||
return cls(*a)
|
return cls(*a)
|
||||||
|
|
||||||
def _render_code(self, option: dict[str, Any], key: str) -> list[str]:
|
|
||||||
# NOTE this duplicates the old direct-paste behavior, even if it is somewhat
|
|
||||||
# incorrect, since users rely on it.
|
|
||||||
if lit := option_is(option, key, 'literalDocBook'):
|
|
||||||
return [ f"*{key.capitalize()}:* {lit['text']}" ]
|
|
||||||
else:
|
|
||||||
return super()._render_code(option, key)
|
|
||||||
|
|
||||||
def _render_description(self, desc: str | dict[str, Any]) -> list[str]:
|
|
||||||
# NOTE this duplicates the old direct-paste behavior, even if it is somewhat
|
|
||||||
# incorrect, since users rely on it.
|
|
||||||
if isinstance(desc, str) and not self._markdown_by_default:
|
|
||||||
return [ desc ]
|
|
||||||
else:
|
|
||||||
return super()._render_description(desc)
|
|
||||||
|
|
||||||
def _related_packages_header(self) -> list[str]:
|
def _related_packages_header(self) -> list[str]:
|
||||||
return [ "*Related packages:*" ]
|
return [ "*Related packages:*" ]
|
||||||
|
|
||||||
|
@ -476,32 +437,16 @@ class OptionsAsciiDocRenderer(OptionDocsRestrictions, AsciiDocRenderer):
|
||||||
class AsciiDocConverter(BaseConverter[OptionsAsciiDocRenderer]):
|
class AsciiDocConverter(BaseConverter[OptionsAsciiDocRenderer]):
|
||||||
__option_block_separator__ = ""
|
__option_block_separator__ = ""
|
||||||
|
|
||||||
def __init__(self, manpage_urls: Mapping[str, str], revision: str, markdown_by_default: bool):
|
def __init__(self, manpage_urls: Mapping[str, str], revision: str):
|
||||||
super().__init__(revision, markdown_by_default)
|
super().__init__(revision)
|
||||||
self._renderer = OptionsAsciiDocRenderer(manpage_urls)
|
self._renderer = OptionsAsciiDocRenderer(manpage_urls)
|
||||||
|
|
||||||
def _parallel_render_prepare(self) -> Any:
|
def _parallel_render_prepare(self) -> Any:
|
||||||
return (self._renderer._manpage_urls, self._revision, self._markdown_by_default)
|
return (self._renderer._manpage_urls, self._revision)
|
||||||
@classmethod
|
@classmethod
|
||||||
def _parallel_render_init_worker(cls, a: Any) -> AsciiDocConverter:
|
def _parallel_render_init_worker(cls, a: Any) -> AsciiDocConverter:
|
||||||
return cls(*a)
|
return cls(*a)
|
||||||
|
|
||||||
def _render_code(self, option: dict[str, Any], key: str) -> list[str]:
|
|
||||||
# NOTE this duplicates the old direct-paste behavior, even if it is somewhat
|
|
||||||
# incorrect, since users rely on it.
|
|
||||||
if lit := option_is(option, key, 'literalDocBook'):
|
|
||||||
return [ f"*{key.capitalize()}:* {lit['text']}" ]
|
|
||||||
else:
|
|
||||||
return super()._render_code(option, key)
|
|
||||||
|
|
||||||
def _render_description(self, desc: str | dict[str, Any]) -> list[str]:
|
|
||||||
# NOTE this duplicates the old direct-paste behavior, even if it is somewhat
|
|
||||||
# incorrect, since users rely on it.
|
|
||||||
if isinstance(desc, str) and not self._markdown_by_default:
|
|
||||||
return [ desc ]
|
|
||||||
else:
|
|
||||||
return super()._render_description(desc)
|
|
||||||
|
|
||||||
def _related_packages_header(self) -> list[str]:
|
def _related_packages_header(self) -> list[str]:
|
||||||
return [ "__Related packages:__" ]
|
return [ "__Related packages:__" ]
|
||||||
|
|
||||||
|
@ -541,33 +486,21 @@ class OptionsHTMLRenderer(OptionDocsRestrictions, HTMLRenderer):
|
||||||
class HTMLConverter(BaseConverter[OptionsHTMLRenderer]):
|
class HTMLConverter(BaseConverter[OptionsHTMLRenderer]):
|
||||||
__option_block_separator__ = ""
|
__option_block_separator__ = ""
|
||||||
|
|
||||||
def __init__(self, manpage_urls: Mapping[str, str], revision: str, markdown_by_default: bool,
|
def __init__(self, manpage_urls: Mapping[str, str], revision: str,
|
||||||
varlist_id: str, id_prefix: str, xref_targets: Mapping[str, XrefTarget]):
|
varlist_id: str, id_prefix: str, xref_targets: Mapping[str, XrefTarget]):
|
||||||
super().__init__(revision, markdown_by_default)
|
super().__init__(revision)
|
||||||
self._xref_targets = xref_targets
|
self._xref_targets = xref_targets
|
||||||
self._varlist_id = varlist_id
|
self._varlist_id = varlist_id
|
||||||
self._id_prefix = id_prefix
|
self._id_prefix = id_prefix
|
||||||
self._renderer = OptionsHTMLRenderer(manpage_urls, self._xref_targets)
|
self._renderer = OptionsHTMLRenderer(manpage_urls, self._xref_targets)
|
||||||
|
|
||||||
def _parallel_render_prepare(self) -> Any:
|
def _parallel_render_prepare(self) -> Any:
|
||||||
return (self._renderer._manpage_urls, self._revision, self._markdown_by_default,
|
return (self._renderer._manpage_urls, self._revision,
|
||||||
self._varlist_id, self._id_prefix, self._xref_targets)
|
self._varlist_id, self._id_prefix, self._xref_targets)
|
||||||
@classmethod
|
@classmethod
|
||||||
def _parallel_render_init_worker(cls, a: Any) -> HTMLConverter:
|
def _parallel_render_init_worker(cls, a: Any) -> HTMLConverter:
|
||||||
return cls(*a)
|
return cls(*a)
|
||||||
|
|
||||||
def _render_code(self, option: dict[str, Any], key: str) -> list[str]:
|
|
||||||
if lit := option_is(option, key, 'literalDocBook'):
|
|
||||||
raise RuntimeError("can't render html in the presence of docbook")
|
|
||||||
else:
|
|
||||||
return super()._render_code(option, key)
|
|
||||||
|
|
||||||
def _render_description(self, desc: str | dict[str, Any]) -> list[str]:
|
|
||||||
if isinstance(desc, str) and not self._markdown_by_default:
|
|
||||||
raise RuntimeError("can't render html in the presence of docbook")
|
|
||||||
else:
|
|
||||||
return super()._render_description(desc)
|
|
||||||
|
|
||||||
def _related_packages_header(self) -> list[str]:
|
def _related_packages_header(self) -> list[str]:
|
||||||
return [
|
return [
|
||||||
'<p><span class="emphasis"><em>Related packages:</em></span></p>',
|
'<p><span class="emphasis"><em>Related packages:</em></span></p>',
|
||||||
|
@ -635,7 +568,6 @@ def _build_cli_db(p: argparse.ArgumentParser) -> None:
|
||||||
p.add_argument('--document-type', required=True)
|
p.add_argument('--document-type', required=True)
|
||||||
p.add_argument('--varlist-id', required=True)
|
p.add_argument('--varlist-id', required=True)
|
||||||
p.add_argument('--id-prefix', required=True)
|
p.add_argument('--id-prefix', required=True)
|
||||||
p.add_argument('--markdown-by-default', default=False, action='store_true')
|
|
||||||
p.add_argument("infile")
|
p.add_argument("infile")
|
||||||
p.add_argument("outfile")
|
p.add_argument("outfile")
|
||||||
|
|
||||||
|
@ -647,14 +579,12 @@ def _build_cli_manpage(p: argparse.ArgumentParser) -> None:
|
||||||
def _build_cli_commonmark(p: argparse.ArgumentParser) -> None:
|
def _build_cli_commonmark(p: argparse.ArgumentParser) -> None:
|
||||||
p.add_argument('--manpage-urls', required=True)
|
p.add_argument('--manpage-urls', required=True)
|
||||||
p.add_argument('--revision', required=True)
|
p.add_argument('--revision', required=True)
|
||||||
p.add_argument('--markdown-by-default', default=False, action='store_true')
|
|
||||||
p.add_argument("infile")
|
p.add_argument("infile")
|
||||||
p.add_argument("outfile")
|
p.add_argument("outfile")
|
||||||
|
|
||||||
def _build_cli_asciidoc(p: argparse.ArgumentParser) -> None:
|
def _build_cli_asciidoc(p: argparse.ArgumentParser) -> None:
|
||||||
p.add_argument('--manpage-urls', required=True)
|
p.add_argument('--manpage-urls', required=True)
|
||||||
p.add_argument('--revision', required=True)
|
p.add_argument('--revision', required=True)
|
||||||
p.add_argument('--markdown-by-default', default=False, action='store_true')
|
|
||||||
p.add_argument("infile")
|
p.add_argument("infile")
|
||||||
p.add_argument("outfile")
|
p.add_argument("outfile")
|
||||||
|
|
||||||
|
@ -663,7 +593,6 @@ def _run_cli_db(args: argparse.Namespace) -> None:
|
||||||
md = DocBookConverter(
|
md = DocBookConverter(
|
||||||
json.load(manpage_urls),
|
json.load(manpage_urls),
|
||||||
revision = args.revision,
|
revision = args.revision,
|
||||||
markdown_by_default = args.markdown_by_default,
|
|
||||||
document_type = args.document_type,
|
document_type = args.document_type,
|
||||||
varlist_id = args.varlist_id,
|
varlist_id = args.varlist_id,
|
||||||
id_prefix = args.id_prefix)
|
id_prefix = args.id_prefix)
|
||||||
|
@ -674,11 +603,7 @@ def _run_cli_db(args: argparse.Namespace) -> None:
|
||||||
f.write(md.finalize())
|
f.write(md.finalize())
|
||||||
|
|
||||||
def _run_cli_manpage(args: argparse.Namespace) -> None:
|
def _run_cli_manpage(args: argparse.Namespace) -> None:
|
||||||
md = ManpageConverter(
|
md = ManpageConverter(revision = args.revision)
|
||||||
revision = args.revision,
|
|
||||||
# manpage rendering only works if there's no docbook, so we can
|
|
||||||
# also set markdown_by_default with no ill effects.
|
|
||||||
markdown_by_default = True)
|
|
||||||
|
|
||||||
with open(args.infile, 'r') as f:
|
with open(args.infile, 'r') as f:
|
||||||
md.add_options(json.load(f))
|
md.add_options(json.load(f))
|
||||||
|
@ -687,10 +612,7 @@ def _run_cli_manpage(args: argparse.Namespace) -> None:
|
||||||
|
|
||||||
def _run_cli_commonmark(args: argparse.Namespace) -> None:
|
def _run_cli_commonmark(args: argparse.Namespace) -> None:
|
||||||
with open(args.manpage_urls, 'r') as manpage_urls:
|
with open(args.manpage_urls, 'r') as manpage_urls:
|
||||||
md = CommonMarkConverter(
|
md = CommonMarkConverter(json.load(manpage_urls), revision = args.revision)
|
||||||
json.load(manpage_urls),
|
|
||||||
revision = args.revision,
|
|
||||||
markdown_by_default = args.markdown_by_default)
|
|
||||||
|
|
||||||
with open(args.infile, 'r') as f:
|
with open(args.infile, 'r') as f:
|
||||||
md.add_options(json.load(f))
|
md.add_options(json.load(f))
|
||||||
|
@ -699,10 +621,7 @@ def _run_cli_commonmark(args: argparse.Namespace) -> None:
|
||||||
|
|
||||||
def _run_cli_asciidoc(args: argparse.Namespace) -> None:
|
def _run_cli_asciidoc(args: argparse.Namespace) -> None:
|
||||||
with open(args.manpage_urls, 'r') as manpage_urls:
|
with open(args.manpage_urls, 'r') as manpage_urls:
|
||||||
md = AsciiDocConverter(
|
md = AsciiDocConverter(json.load(manpage_urls), revision = args.revision)
|
||||||
json.load(manpage_urls),
|
|
||||||
revision = args.revision,
|
|
||||||
markdown_by_default = args.markdown_by_default)
|
|
||||||
|
|
||||||
with open(args.infile, 'r') as f:
|
with open(args.infile, 'r') as f:
|
||||||
md.add_options(json.load(f))
|
md.add_options(json.load(f))
|
||||||
|
|
|
@ -4,7 +4,7 @@ from markdown_it.token import Token
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
def test_option_headings() -> None:
|
def test_option_headings() -> None:
|
||||||
c = nixos_render_docs.options.DocBookConverter({}, 'local', False, 'none', 'vars', 'opt-')
|
c = nixos_render_docs.options.DocBookConverter({}, 'local', 'none', 'vars', 'opt-')
|
||||||
with pytest.raises(RuntimeError) as exc:
|
with pytest.raises(RuntimeError) as exc:
|
||||||
c._render("# foo")
|
c._render("# foo")
|
||||||
assert exc.value.args[0] == 'md token not supported in options doc'
|
assert exc.value.args[0] == 'md token not supported in options doc'
|
||||||
|
|
Loading…
Reference in a new issue