docs: add style sheets and `scrubDerivations`

This adds style sheets and `scrubDerivations` from nmd, thereby
removing the need to download them separately.
This commit is contained in:
Robert Helgesson 2024-02-01 00:41:56 +01:00
parent d634c3abaf
commit 2db6a2a429
No known key found for this signature in database
GPG Key ID: 96E745BD17AA17ED
10 changed files with 464 additions and 48 deletions

View File

@ -7,28 +7,37 @@
let
nmdSrc = fetchTarball {
url = "https://git.sr.ht/~rycee/nmd/archive/v0.5.0.tar.gz";
sha256 = "0hnd86jd19zb5j3hmpwmdmdiasg65lgahqv7n8frl9p1vdqz6z67";
};
nmd = import nmdSrc {
inherit lib;
# The DocBook output of `nixos-render-docs` doesn't have the change
# `nmd` uses to work around the broken stylesheets in
# `docbook-xsl-ns`, so we restore the patched version here.
pkgs = pkgs // {
docbook-xsl-ns =
pkgs.docbook-xsl-ns.override { withManOptDedupPatch = true; };
};
};
# Recursively replace each derivation in the given attribute set
# with the same derivation but with the `outPath` attribute set to
# the string `"\${pkgs.attribute.path}"`. This allows the
# documentation to refer to derivations through their values without
# establishing an actual dependency on the derivation output.
#
# This is not 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}`.
scrubDerivations = prefixPath: attrs:
let
scrubDerivation = name: value:
let pkgAttrName = prefixPath + "." + name;
in if lib.isAttrs value then
scrubDerivations pkgAttrName value
// lib.optionalAttrs (lib.isDerivation value) {
outPath = "\${${pkgAttrName}}";
}
else
value;
in lib.mapAttrs scrubDerivation attrs;
# Make sure the used package is scrubbed to avoid actually
# instantiating derivations.
scrubbedPkgsModule = {
imports = [{
_module.args = {
pkgs = lib.mkForce (nmd.scrubDerivations "pkgs" pkgs);
pkgs = lib.mkForce (scrubDerivations "pkgs" pkgs);
pkgs_i686 = lib.mkForce { };
};
}];
@ -113,7 +122,6 @@ let
'';
# Generate the HTML manual pages
home-manager-manual = pkgs.callPackage ./home-manager-manual.nix {
nmd = nmdSrc;
home-manager-options = {
home-manager = hmOptionsDocs.optionsJSON;
nixos = nixosOptionsDocs.optionsJSON;
@ -124,8 +132,6 @@ let
html = home-manager-manual;
htmlOpenTool = pkgs.callPackage ./html-open-tool.nix { } { inherit html; };
in {
inherit nmdSrc;
options = {
# TODO: Use `hmOptionsDocs.optionsJSON` directly once upstream
# `nixosOptionsDoc` is more customizable.

45
docs/flake.lock Normal file
View File

@ -0,0 +1,45 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1706683685,
"narHash": "sha256-FtPPshEpxH/ewBOsdKBNhlsL2MLEFv1hEnQ19f/bFsQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5ad9903c16126a7d949101687af0aa589b1d7d3d",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixpkgs-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"scss-reset": "scss-reset"
}
},
"scss-reset": {
"flake": false,
"locked": {
"lastModified": 1683906868,
"narHash": "sha256-cif5Sx8Ca5vxdw/mNAgpulLH15TwmzyJFNM7JURpoaE=",
"owner": "andreymatin",
"repo": "scss-reset",
"rev": "5a7bd491ac82441e6283fb0d5d54644b913b30c7",
"type": "github"
},
"original": {
"owner": "andreymatin",
"ref": "1.4.2",
"repo": "scss-reset",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

54
docs/flake.nix Normal file
View File

@ -0,0 +1,54 @@
{
description = "Support developing Home Manager documentation";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
scss-reset = {
url = "github:andreymatin/scss-reset/1.4.2";
flake = false;
};
};
outputs = { self, nixpkgs, scss-reset }:
let
supportedSystems = [
"aarch64-darwin"
"aarch64-linux"
"i686-linux"
"x86_64-darwin"
"x86_64-linux"
];
lib = nixpkgs.lib;
forAllSystems = lib.genAttrs supportedSystems;
flakePkgs = pkgs: {
p-build = pkgs.writeShellScriptBin "p-build" ''
set -euo pipefail
export PATH=${lib.makeBinPath [ pkgs.coreutils pkgs.rsass ]}
tmpfile=$(mktemp -d)
trap "rm -r $tmpfile" EXIT
ln -s "${scss-reset}/build" "$tmpfile/scss-reset"
rsass --load-path="$tmpfile" --style compressed \
./static/style.scss > ./static/style.css
echo "Generated ./static/style.css"
'';
};
in {
devShells = forAllSystems (system:
let
pkgs = nixpkgs.legacyPackages.${system};
fpkgs = flakePkgs pkgs;
in {
default = pkgs.mkShell {
name = "hm-docs";
packages = [ fpkgs.p-build ];
};
});
};
}

View File

@ -1,8 +0,0 @@
pre {
padding: 0;
}
pre code.hljs {
border: none;
margin: 0;
}

View File

@ -1,4 +1,4 @@
{ stdenv, lib, documentation-highlighter, nmd, revision, home-manager-options
{ stdenv, lib, documentation-highlighter, revision, home-manager-options
, nixos-render-docs }:
let outputPath = "share/doc/home-manager";
in stdenv.mkDerivation {
@ -9,9 +9,8 @@ in stdenv.mkDerivation {
src = ./manual;
buildPhase = ''
mkdir -p out/media
mkdir -p out/{highlightjs,media}
mkdir -p out/highlightjs
cp -t out/highlightjs \
${documentation-highlighter}/highlight.pack.js \
${documentation-highlighter}/LICENSE \
@ -19,23 +18,21 @@ in stdenv.mkDerivation {
${documentation-highlighter}/loader.js
substituteInPlace ./options.md \
--replace \
'@OPTIONS_JSON@' \
--subst-var-by \
OPTIONS_JSON \
${home-manager-options.home-manager}/share/doc/nixos/options.json
substituteInPlace ./nixos-options.md \
--replace \
'@OPTIONS_JSON@' \
--subst-var-by \
OPTIONS_JSON \
${home-manager-options.nixos}/share/doc/nixos/options.json
substituteInPlace ./nix-darwin-options.md \
--replace \
'@OPTIONS_JSON@' \
--subst-var-by \
OPTIONS_JSON \
${home-manager-options.nix-darwin}/share/doc/nixos/options.json
cp ${nmd}/static/style.css out/style.css
cp -t out/highlightjs ${nmd}/static/highlightjs/tomorrow-night.min.css
cp ${./highlight-style.css} out/highlightjs/highlight-style.css
cp ${./static/style.css} out/style.css
cp -r ${./release-notes} release-notes
@ -43,8 +40,6 @@ in stdenv.mkDerivation {
--manpage-urls ./manpage-urls.json \
--revision ${lib.trivial.revisionWithDefault revision} \
--stylesheet style.css \
--stylesheet highlightjs/tomorrow-night.min.css \
--stylesheet highlightjs/highlight-style.css \
--script highlightjs/highlight.pack.js \
--script highlightjs/loader.js \
--toc-depth 1 \

7
docs/static/style.css vendored Normal file

File diff suppressed because one or more lines are too long

310
docs/static/style.scss vendored Normal file
View File

@ -0,0 +1,310 @@
:root {
--nmd-color0: #0A3E68;
--nmd-color1: #268598;
--nmd-color2: #B8D09E;
--nmd-color3: #F6CF5E;
--nmd-color4: #EC733B;
--nmd-color-info: #167cb9;
--nmd-color-warn: #ff6700;
}
// Copied from Tailwind CSS.
$color-gray-50: #F9FAFB;
$color-gray-100: #F3F4F6;
$color-gray-200: #E5E7EB;
$color-gray-300: #D1D5DB;
$color-gray-400: #9CA3AF;
$color-gray-500: #6B7280;
$color-gray-600: #4B5563;
$color-gray-700: #374151;
$color-gray-800: #1F2937;
$color-gray-900: #111827;
$color-blue-50: #EFF6FF;
$color-blue-100: #DBEAFE;
$color-blue-200: #BFDBFE;
$color-blue-300: #93C5FD;
$color-blue-400: #60A5FA;
$color-blue-500: #3B82F6;
$color-blue-600: #2563EB;
$color-blue-700: #1D4ED8;
$color-blue-800: #1E40AF;
$color-blue-900: #1E3A8A;
@use 'scss-reset/reset';
@mixin boxed {
background: $color-gray-50;
margin: 2rem 16px;
padding: 10px;
border: 1px solid $color-gray-200;
border-radius: 4px;
box-shadow: 4px 4px 8px $color-gray-200;
@media (prefers-color-scheme: dark) {
background: $color-gray-800;
border-color: black;
box-shadow: 4px 4px 8px black;
}
}
@mixin margined {
margin: 0.9rem 0;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
body {
background: white;
color: $color-gray-900;
max-width: min(100ch, 1024px);
margin: 0 auto;
padding: 10px;
font-family: 'Lucida Sans', Arial, sans-serif;
font-size: 16px;
line-height: 1.4em;
@media (prefers-color-scheme: dark) {
background: $color-gray-900;
color: $color-gray-50;
}
}
h1, h2, h3 {
color: var(--nmd-color0);
font-family: "Lato", sans-serif;
font-weight: 300;
line-height: 1.125;
@media (prefers-color-scheme: dark) {
color: var(--nmd-color4);
}
}
h1 {
font-size: 48px;
font-weight: 300;
margin: 4rem 0 1.5rem;
}
h2 {
font-size: 32px;
font-weight: 300;
margin: 2rem 0 1rem;
}
h3 {
font-size: 20px;
font-weight: 400;
margin: 0.5rem 0.25rem;
}
p {
@include margined;
}
a {
color: var(--nmd-color0); //$color-secondary-1-3;
text-decoration: underline;
text-underline-offset: 3px;
&:visited {
color: var(--nmd-color1);
}
&:hover {
color: var(--nmd-color1);
}
@media (prefers-color-scheme: dark) {
color: var(--nmd-color3);
&:visited {
color: var(--nmd-color2);
}
&:hover {
color: var(--nmd-color4);
}
}
}
code {
font-size: 90%;
}
span.command {
font-size: 90%;
font-family: monospace;
}
em {
font-style: italic;
}
strong {
font-weight: bold;
}
pre {
@include boxed;
font-size: 90%;
margin-bottom: 1.5rem;
padding: 6px;
overflow: auto;
// The callout markers should not be selectable.
span img {
user-select: none;
}
}
pre:has(code) {
padding: 0;
}
td, th {
padding: 2px 5px;
&:first-child {
padding-left: 0;
}
&:last-child {
padding-right: 0;
}
}
dt {
margin: 1.2rem 0 0.8rem;
}
dd {
margin-left: 2rem;
}
div.book {
}
ul {
@include margined;
padding-left: 30px;
list-style: disc;
}
ol {
@include margined;
padding-left: 30px;
list-style: decimal;
}
li {
@include margined;
padding-left: 5px;
}
.navheader, .navfooter {
hr {
margin: 1rem 0;
background: $color-gray-200;
@media (prefers-color-scheme: dark) {
background: $color-gray-600;
}
}
a {
text-decoration: none;
}
}
div.titlepage {
margin: 40px 0;
hr {
display: none;
}
}
div.toc {
@include boxed;
a {
text-decoration: none;
}
}
div.note, div.warning {
@include boxed;
font-style: italic;
h3 {
float: right;
margin: 0 0 1rem 1rem;
width: 42px;
height: 42px;
content: url();
}
h3 + p {
margin-top: 0;
}
}
div.note {
h3 {
background-color: var(--nmd-color-info);
// From https://tabler-icons.io/i/info-square-rounded
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 24 24' stroke-width='2' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M12 8h.01'%3E%3C/path%3E%3Cpath d='M11 12h1v4h1'%3E%3C/path%3E%3Cpath d='M12 3c7.2 0 9 1.8 9 9s-1.8 9 -9 9s-9 -1.8 -9 -9s1.8 -9 9 -9z'%3E%3C/path%3E%3C/svg%3E");
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 24 24' stroke-width='2' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M12 8h.01'%3E%3C/path%3E%3Cpath d='M11 12h1v4h1'%3E%3C/path%3E%3Cpath d='M12 3c7.2 0 9 1.8 9 9s-1.8 9 -9 9s-9 -1.8 -9 -9s1.8 -9 9 -9z'%3E%3C/path%3E%3C/svg%3E");
}
}
div.warning {
h3 {
background-color: var(--nmd-color-warn);
// From https://tabler-icons.io/i/alert-triangle
mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 24 24' stroke-width='2' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M12 9v2m0 4v.01'%3E%3C/path%3E%3Cpath d='M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75'%3E%3C/path%3E%3C/svg%3E");
-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='42' height='42' viewBox='0 0 24 24' stroke-width='2' stroke='black' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath stroke='none' d='M0 0h24v24H0z' fill='none'%3E%3C/path%3E%3Cpath d='M12 9v2m0 4v.01'%3E%3C/path%3E%3Cpath d='M5 19h14a2 2 0 0 0 1.84 -2.75l-7.1 -12.25a2 2 0 0 0 -3.5 0l-7.1 12.25a2 2 0 0 0 1.75 2.75'%3E%3C/path%3E%3C/svg%3E");
}
}
.term {
font-weight: 300;
}
.docbook .xref img[src^=images\/callouts\/],
.screen img,
.programlisting img {
width: 1em;
}
.calloutlist img {
width: 1.3em;
}
/** The console prompt, e.g., `$` and `#` should not be selectable. */
.programlisting.language-shell .hljs-meta.prompt_ {
user-select: none;
}
@import 'tomorrow.min.css';
@media (prefers-color-scheme: dark) {
@import 'tomorrow-night.min.css';
}

7
docs/static/tomorrow-night.min.css vendored Normal file
View File

@ -0,0 +1,7 @@
/*!
Theme: Tomorrow Night
Author: Chris Kempson (http://chriskempson.com)
License: ~ MIT (or more permissive) [via base16-schemes-source]
Maintainer: @highlightjs/core-team
Version: 2021.09.0
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#ccc;background:#2d2d2d}.hljs ::selection,.hljs::selection{background-color:#515151;color:#ccc}.hljs-comment{color:#999}.hljs-tag{color:#b4b7b4}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#ccc}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#f2777a}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#f99157}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#fc6}.hljs-strong{font-weight:700;color:#fc6}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#9c9}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#6cc}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#69c}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#c9c}.hljs-emphasis{color:#c9c;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#a3685a}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}

7
docs/static/tomorrow.min.css vendored Normal file
View File

@ -0,0 +1,7 @@
/*!
Theme: Tomorrow
Author: Chris Kempson (http://chriskempson.com)
License: ~ MIT (or more permissive) [via base16-schemes-source]
Maintainer: @highlightjs/core-team
Version: 2021.09.0
*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{color:#4d4d4c;background:#fff}.hljs ::selection,.hljs::selection{background-color:#d6d6d6;color:#4d4d4c}.hljs-comment{color:#8e908c}.hljs-tag{color:#969896}.hljs-operator,.hljs-punctuation,.hljs-subst{color:#4d4d4c}.hljs-operator{opacity:.7}.hljs-bullet,.hljs-deletion,.hljs-name,.hljs-selector-tag,.hljs-template-variable,.hljs-variable{color:#c82829}.hljs-attr,.hljs-link,.hljs-literal,.hljs-number,.hljs-symbol,.hljs-variable.constant_{color:#f5871f}.hljs-class .hljs-title,.hljs-title,.hljs-title.class_{color:#eab700}.hljs-strong{font-weight:700;color:#eab700}.hljs-addition,.hljs-code,.hljs-string,.hljs-title.class_.inherited__{color:#718c00}.hljs-built_in,.hljs-doctag,.hljs-keyword.hljs-atrule,.hljs-quote,.hljs-regexp{color:#3e999f}.hljs-attribute,.hljs-function .hljs-title,.hljs-section,.hljs-title.function_,.ruby .hljs-property{color:#4271ae}.diff .hljs-meta,.hljs-keyword,.hljs-template-tag,.hljs-type{color:#8959a8}.hljs-emphasis{color:#8959a8;font-style:italic}.hljs-meta,.hljs-meta .hljs-keyword,.hljs-meta .hljs-string{color:#a3685a}.hljs-meta .hljs-keyword,.hljs-meta-keyword{font-weight:700}

View File

@ -57,13 +57,6 @@ in {
(mkIf cfg.manpages.enable [ docs.manPages ])
(mkIf cfg.json.enable [ docs.options.json ])
];
# Whether a dependency on nmd should be introduced.
home.extraBuilderCommands =
mkIf (cfg.html.enable || cfg.manpages.enable || cfg.json.enable) ''
mkdir $out/lib
ln -s ${docs.nmdSrc} $out/lib/nmd
'';
};
}