···23232424If the build succeeds, the manual will be in `./result/share/doc/nixpkgs/manual.html`.25252626+## devmode {#sec-contributing-devmode}2727+2828+The shell in the manual source directory makes available a command, `devmode`.2929+It is a daemon, that:3030+1. watches the manual's source for changes and when they occur — rebuilds3131+2. HTTP serves the manual, injecting a script that triggers reload on changes3232+3. opens the manual in the default browser3333+2634## Syntax {#sec-contributing-markup}27352836As per [RFC 0072](https://github.com/NixOS/rfcs/pull/72), all new documentation content should be written in [CommonMark](https://commonmark.org/) Markdown dialect.
···11111212If the build succeeds, the manual will be in `./result/share/doc/nixos/index.html`.13131414+There's also [a convenient development daemon](https://nixos.org/manual/nixpkgs/unstable/#sec-contributing-devmode).1515+1416**Contributing to the man pages**15171618The man pages are written in [DocBook] which is XML.
···11+{22+ pkgs,33+ # arguments to `nix-build`, e.g. `"foo.nix -A bar"`44+ buildArgs,55+ # what path to open a browser at66+ open,77+}: let88+ inherit (pkgs) lib;99+1010+ error_page = pkgs.writeShellScriptBin "error_page" ''1111+ echo "<!DOCTYPE html>1212+ <html>1313+ <head>1414+ <style>1515+ @media (prefers-color-scheme: dark) {1616+ :root { filter: invert(100%); }1717+ }1818+ </style>1919+ </head>2020+ <body><pre>$1</pre></body>2121+ </html>"2222+ '';2323+2424+ # The following would have been simpler:2525+ # 1. serve from `$serve`2626+ # 2. pass each build a `--out-link $serve/result`2727+ # But that way live-server does not seem to detect changes and therefore no2828+ # auto-reloads occur.2929+ # Instead, we copy the contents of each build to the `$serve` directory.3030+ # Using rsync here, instead of `cp`, to get as close to an atomic3131+ # directory copy operation as possible. `--delay-updates` should3232+ # also go towards that.3333+ build_and_copy = pkgs.writeShellScriptBin "build_and_copy" ''3434+ set -euxo pipefail3535+3636+ set +e3737+ stderr=$(2>&1 nix-build --out-link $out_link ${buildArgs})3838+ exit_status=$?3939+ set -e4040+4141+ if [ $exit_status -eq 0 ];4242+ then4343+ # setting permissions to be able to clean up4444+ ${lib.getBin pkgs.rsync}/bin/rsync \4545+ --recursive \4646+ --chmod=u=rwX \4747+ --delete-before \4848+ --delay-updates \4949+ $out_link/ \5050+ $serve/5151+ else5252+ set +x5353+ ${lib.getBin error_page}/bin/error_page "$stderr" > $error_page_absolute5454+ set -x5555+5656+ ${lib.getBin pkgs.findutils}/bin/find $serve \5757+ -type f \5858+ ! -name $error_page_relative \5959+ -delete6060+ fi6161+ '';6262+6363+ # https://watchexec.github.io/6464+ watcher = pkgs.writeShellScriptBin "watcher" ''6565+ set -euxo pipefail6666+6767+ ${lib.getBin pkgs.watchexec}/bin/watchexec \6868+ --shell=none \6969+ --restart \7070+ --print-events \7171+ ${lib.getBin build_and_copy}/bin/build_and_copy7272+ '';7373+7474+ # A Rust alternative to live-server exists, but it was not in nixpkgs.7575+ # `--no-css-inject`: without this it seems that only CSS is auto-reloaded.7676+ # https://www.npmjs.com/package/live-server7777+ server = pkgs.writeShellScriptBin "server" ''7878+ set -euxo pipefail7979+8080+ ${lib.getBin pkgs.nodePackages_latest.live-server}/bin/live-server \8181+ --host=127.0.0.1 \8282+ --verbose \8383+ --no-css-inject \8484+ --entry-file=$error_page_relative \8585+ --open=${open} \8686+ $serve8787+ '';8888+8989+ devmode =9090+ pkgs.writeShellScriptBin "devmode"9191+ ''9292+ set -euxo pipefail9393+9494+ function handle_exit {9595+ rm -rf "$tmpdir"9696+ }9797+9898+ tmpdir=$(mktemp -d)9999+ trap handle_exit EXIT100100+101101+ export out_link="$tmpdir/result"102102+ export serve="$tmpdir/serve"103103+ mkdir $serve104104+ export error_page_relative=error.html105105+ export error_page_absolute=$serve/$error_page_relative106106+ ${lib.getBin error_page}/bin/error_page "building …" > $error_page_absolute107107+108108+ ${lib.getBin pkgs.parallel}/bin/parallel \109109+ --will-cite \110110+ --line-buffer \111111+ --tagstr '{/}' \112112+ ::: \113113+ "${lib.getBin watcher}/bin/watcher" \114114+ "${lib.getBin server}/bin/server"115115+ '';116116+in117117+ devmode