mirror of
https://github.com/nix-community/nixvim.git
synced 2025-06-24 09:48:42 +02:00
docs/lib: init
Generate reference docs for functions that have RFC145 style doc-comments. 1. function locations `docs/lib/function-locations.nix` scans nixvim's extended lib, extracting "position entries" via `unsafeGetAttrPos`. This is then converted into a nixdoc `locations.json` map of "function name" → "markdown location string". 2. mdbook menu `docs/lib/menu.nix` renders a mdbook menu representing all page entries. 3. markdown pages `docs/lib/default.nix` expects a set of "page entries", which come from `docs/lib/pages.nix` by default. It passes this data to `function-locations.nix` and `menu.nix`, and uses it internally to render markdown pages. Page entries can contain a `file` to render using `nixdoc`, and also a `markdown` attribute which will be included at the top of the docs. Additionally, a `title` can be included. This forms the heading `$name: $title`, where `name` is derived from the page's attr-path. See https://github.com/nix-community/nixdoc
This commit is contained in:
parent
563fdaeef9
commit
dfaea5982e
6 changed files with 299 additions and 0 deletions
168
docs/lib/default.nix
Normal file
168
docs/lib/default.nix
Normal file
|
@ -0,0 +1,168 @@
|
|||
# Generates the documentation for library functions using nixdoc.
|
||||
# See https://github.com/nix-community/nixdoc
|
||||
{
|
||||
lib,
|
||||
runCommand,
|
||||
writers,
|
||||
nixdoc,
|
||||
nixvim,
|
||||
pageSpecs ? import ./pages.nix,
|
||||
}:
|
||||
|
||||
let
|
||||
# Some pages are just menu entries, others have an actual markdown page that
|
||||
# needs rendering.
|
||||
shouldRenderPage = page: page ? file || page ? markdown;
|
||||
|
||||
# Normalise a page node, recursively normalise its children
|
||||
elaboratePage =
|
||||
loc:
|
||||
{
|
||||
title ? "",
|
||||
markdown ? null,
|
||||
file ? null,
|
||||
pages ? { },
|
||||
}@page:
|
||||
{
|
||||
name = lib.attrsets.showAttrPath loc;
|
||||
loc = lib.throwIfNot (
|
||||
builtins.head loc == "lib"
|
||||
) "All pages must be within `lib`, unexpected root `${builtins.head loc}`" (builtins.tail loc);
|
||||
}
|
||||
// lib.optionalAttrs (shouldRenderPage page) {
|
||||
inherit
|
||||
file
|
||||
title
|
||||
;
|
||||
markdown =
|
||||
if builtins.isString markdown then
|
||||
builtins.toFile "${lib.strings.replaceStrings [ "/" "-" ] (lib.lists.last loc)}.md" markdown
|
||||
else
|
||||
markdown;
|
||||
outFile = lib.strings.concatStringsSep "/" (loc ++ [ "index.md" ]);
|
||||
}
|
||||
// lib.optionalAttrs (page ? pages) {
|
||||
pages = elaboratePages loc pages;
|
||||
};
|
||||
|
||||
# Recursively normalise page nodes
|
||||
elaboratePages = prefix: builtins.mapAttrs (name: elaboratePage (prefix ++ [ name ]));
|
||||
|
||||
# Collect all page nodes into a list of page entries
|
||||
collectPages =
|
||||
pages:
|
||||
builtins.concatMap (
|
||||
page:
|
||||
[ (builtins.removeAttrs page [ "pages" ]) ]
|
||||
++ lib.optionals (page ? pages) (collectPages page.pages)
|
||||
) (builtins.attrValues pages);
|
||||
|
||||
# Normalised page specs
|
||||
elaboratedPageSpecs = elaboratePages [ ] pageSpecs;
|
||||
pageList = collectPages elaboratedPageSpecs;
|
||||
pagesToRender = builtins.filter (page: page ? outFile) pageList;
|
||||
pagesWithFunctions = builtins.filter (page: page.file or null != null) pageList;
|
||||
in
|
||||
|
||||
runCommand "nixvim-lib-docs"
|
||||
{
|
||||
nativeBuildInputs = [
|
||||
nixdoc
|
||||
];
|
||||
|
||||
locations = writers.writeJSON "locations.json" (
|
||||
import ./function-locations.nix {
|
||||
inherit lib;
|
||||
rootPath = nixvim;
|
||||
functionSet = lib.extend nixvim.lib.overlay;
|
||||
pathsToScan = builtins.catAttrs "loc" pagesWithFunctions;
|
||||
revision = nixvim.rev or "main";
|
||||
}
|
||||
);
|
||||
|
||||
passthru.menu = import ./menu.nix {
|
||||
inherit lib;
|
||||
pageSpecs = elaboratedPageSpecs;
|
||||
};
|
||||
}
|
||||
''
|
||||
function docgen {
|
||||
md_file="$1"
|
||||
in_file="$2"
|
||||
name="$3"
|
||||
out_file="$out/$4"
|
||||
title="$5"
|
||||
|
||||
if [[ -z "$in_file" ]]; then
|
||||
if [[ -z "$md_file" ]]; then
|
||||
>&2 echo "No markdown or nix file for $name"
|
||||
exit 1
|
||||
fi
|
||||
elif [[ -f "$in_file/default.nix" ]]; then
|
||||
in_file+="/default.nix"
|
||||
elif [[ ! -f "$in_file" ]]; then
|
||||
>&2 echo "File not found: $in_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -n "$in_file" ]]; then
|
||||
nixdoc \
|
||||
--file "$in_file" \
|
||||
--locs "$locations" \
|
||||
--category "$name" \
|
||||
--description "REMOVED BY TAIL" \
|
||||
--prefix "" \
|
||||
--anchor-prefix "" \
|
||||
| tail --lines +2 \
|
||||
> functions.md
|
||||
fi
|
||||
|
||||
default_heading="# $name"
|
||||
if [[ -n "$title" ]]; then
|
||||
default_heading+=": $title"
|
||||
fi
|
||||
|
||||
print_heading=true
|
||||
if [[ -f "$md_file" ]] && [[ "$(head --lines 1 "$md_file")" == '# '* ]]; then
|
||||
>&2 echo "NOTE: markdown file for $name starts with a <h1> heading. Skipping default heading \"$default_heading\"."
|
||||
>&2 echo " Found \"$(head --lines 1 "$md_file")\" in: $md_file"
|
||||
print_heading=false
|
||||
fi
|
||||
|
||||
mkdir -p $(dirname "$out_file")
|
||||
(
|
||||
if [[ "$print_heading" = true ]]; then
|
||||
echo "$default_heading"
|
||||
echo
|
||||
fi
|
||||
if [[ -f "$md_file" ]]; then
|
||||
cat "$md_file"
|
||||
echo
|
||||
fi
|
||||
if [[ -f functions.md ]]; then
|
||||
cat functions.md
|
||||
fi
|
||||
) > "$out_file"
|
||||
}
|
||||
|
||||
mkdir -p "$out"
|
||||
|
||||
${lib.concatMapStringsSep "\n" (
|
||||
{
|
||||
name,
|
||||
file,
|
||||
markdown,
|
||||
outFile,
|
||||
title ? "",
|
||||
...
|
||||
}:
|
||||
lib.escapeShellArgs [
|
||||
"docgen"
|
||||
"${lib.optionalString (markdown != null) markdown}" # md_file
|
||||
"${lib.optionalString (file != null) file}" # in_file
|
||||
name # name
|
||||
outFile # out_file
|
||||
title # title
|
||||
]
|
||||
) pagesToRender}
|
||||
''
|
Loading…
Add table
Add a link
Reference in a new issue