From 926afb6f1c9bcca568eaf12fdd9d16c138a26136 Mon Sep 17 00:00:00 2001 From: sandydoo Date: Mon, 5 Dec 2022 16:05:06 +0000 Subject: [PATCH 1/2] nixos/make-options-doc: pretty-print literals Unlike the XML doc renderer, the AsciiDoc and CommonMark renderers don't pretty-print certain complex types, like literal expressions, DocBook literals, and derivations. These types are dumped into the documentation as JSON. This commit parses and unwraps these types when loading the JSON-formatted NixOS options. The AsciiDoc and CommonMark renders have also been combined into a single script to allow code reuse. --- nixos/lib/make-options-doc/default.nix | 10 +- .../lib/make-options-doc/generateAsciiDoc.py | 37 ------ .../make-options-doc/generateCommonMark.py | 27 ----- nixos/lib/make-options-doc/generateDoc.py | 106 ++++++++++++++++++ 4 files changed, 112 insertions(+), 68 deletions(-) delete mode 100644 nixos/lib/make-options-doc/generateAsciiDoc.py delete mode 100644 nixos/lib/make-options-doc/generateCommonMark.py create mode 100644 nixos/lib/make-options-doc/generateDoc.py diff --git a/nixos/lib/make-options-doc/default.nix b/nixos/lib/make-options-doc/default.nix index e097aa5eebd..694512115d4 100644 --- a/nixos/lib/make-options-doc/default.nix +++ b/nixos/lib/make-options-doc/default.nix @@ -111,14 +111,16 @@ in rec { inherit optionsNix; optionsAsciiDoc = pkgs.runCommand "options.adoc" {} '' - ${pkgs.python3Minimal}/bin/python ${./generateAsciiDoc.py} \ - < ${optionsJSON}/share/doc/nixos/options.json \ + ${pkgs.python3Minimal}/bin/python ${./generateDoc.py} \ + --format asciidoc \ + ${optionsJSON}/share/doc/nixos/options.json \ > $out ''; optionsCommonMark = pkgs.runCommand "options.md" {} '' - ${pkgs.python3Minimal}/bin/python ${./generateCommonMark.py} \ - < ${optionsJSON}/share/doc/nixos/options.json \ + ${pkgs.python3Minimal}/bin/python ${./generateDoc.py} \ + --format commonmark \ + ${optionsJSON}/share/doc/nixos/options.json \ > $out ''; diff --git a/nixos/lib/make-options-doc/generateAsciiDoc.py b/nixos/lib/make-options-doc/generateAsciiDoc.py deleted file mode 100644 index 48eadd248c5..00000000000 --- a/nixos/lib/make-options-doc/generateAsciiDoc.py +++ /dev/null @@ -1,37 +0,0 @@ -import json -import sys - -options = json.load(sys.stdin) -# TODO: declarations: link to github -for (name, value) in options.items(): - print(f'== {name}') - print() - print(value['description']) - print() - print('[discrete]') - print('=== details') - print() - print(f'Type:: {value["type"]}') - if 'default' in value: - print('Default::') - print('+') - print('----') - print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':'))) - print('----') - print() - else: - print('No Default:: {blank}') - if value['readOnly']: - print('Read Only:: {blank}') - else: - print() - if 'example' in value: - print('Example::') - print('+') - print('----') - print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':'))) - print('----') - print() - else: - print('No Example:: {blank}') - print() diff --git a/nixos/lib/make-options-doc/generateCommonMark.py b/nixos/lib/make-options-doc/generateCommonMark.py deleted file mode 100644 index bf487bd89c3..00000000000 --- a/nixos/lib/make-options-doc/generateCommonMark.py +++ /dev/null @@ -1,27 +0,0 @@ -import json -import sys - -options = json.load(sys.stdin) -for (name, value) in options.items(): - print('##', name.replace('<', '<').replace('>', '>')) - print(value['description']) - print() - if 'type' in value: - print('*_Type_*:') - print(value['type']) - print() - print() - if 'default' in value: - print('*_Default_*') - print('```') - print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':'))) - print('```') - print() - print() - if 'example' in value: - print('*_Example_*') - print('```') - print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':'))) - print('```') - print() - print() diff --git a/nixos/lib/make-options-doc/generateDoc.py b/nixos/lib/make-options-doc/generateDoc.py new file mode 100644 index 00000000000..dffa8cd6140 --- /dev/null +++ b/nixos/lib/make-options-doc/generateDoc.py @@ -0,0 +1,106 @@ +import argparse +import json +import sys + +formats = ['commonmark', 'asciidoc'] + +parser = argparse.ArgumentParser( + description = 'Generate documentation for a set of JSON-formatted NixOS options' +) +parser.add_argument( + 'nix_options_path', + help = 'a path to a JSON file containing the NixOS options' +) +parser.add_argument( + '-f', + '--format', + choices = formats, + required = True, + help = f'the documentation format to generate' +) + +args = parser.parse_args() + +# Pretty-print certain Nix types, like literal expressions. +def render_types(obj): + if '_type' not in obj: return obj + + _type = obj['_type'] + if _type == 'literalExpression' or _type == 'literalDocBook': + return obj['text'] + + if _type == 'derivation': + return obj['name'] + + raise Exception(f'Unexpected type `{_type}` in {json.dumps(obj)}') + +def generate_commonmark(options): + for (name, value) in options.items(): + print('##', name.replace('<', '<').replace('>', '>')) + print(value['description']) + print() + if 'type' in value: + print('*_Type_*:') + print(value['type']) + print() + print() + if 'default' in value: + print('*_Default_*') + print('```') + print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':'))) + print('```') + print() + print() + if 'example' in value: + print('*_Example_*') + print('```') + print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':'))) + print('```') + print() + print() + +# TODO: declarations: link to github +def generate_asciidoc(options): + for (name, value) in options.items(): + print(f'== {name}') + print() + print(value['description']) + print() + print('[discrete]') + print('=== details') + print() + print(f'Type:: {value["type"]}') + if 'default' in value: + print('Default::') + print('+') + print('----') + print(json.dumps(value['default'], ensure_ascii=False, separators=(',', ':'))) + print('----') + print() + else: + print('No Default:: {blank}') + if value['readOnly']: + print('Read Only:: {blank}') + else: + print() + if 'example' in value: + print('Example::') + print('+') + print('----') + print(json.dumps(value['example'], ensure_ascii=False, separators=(',', ':'))) + print('----') + print() + else: + print('No Example:: {blank}') + print() + +with open(args.nix_options_path) as nix_options_json: + options = json.load(nix_options_json, object_hook=render_types) + + if args.format == 'commonmark': + generate_commonmark(options) + elif args.format == 'asciidoc': + generate_asciidoc(options) + else: + raise Exception(f'Unsupported documentation format `--format {args.format}`') + From 3564228a10873061ee75d1278f3bc8c7ed1a1fa9 Mon Sep 17 00:00:00 2001 From: sandydoo Date: Wed, 7 Dec 2022 14:39:26 +0000 Subject: [PATCH 2/2] nixos/make-options-doc: improve CommonMark formatting Render the `type` attribute in a code block to match the rest of the attributes. --- nixos/lib/make-options-doc/generateDoc.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/nixos/lib/make-options-doc/generateDoc.py b/nixos/lib/make-options-doc/generateDoc.py index dffa8cd6140..1fe4eb0253a 100644 --- a/nixos/lib/make-options-doc/generateDoc.py +++ b/nixos/lib/make-options-doc/generateDoc.py @@ -40,9 +40,11 @@ def generate_commonmark(options): print(value['description']) print() if 'type' in value: - print('*_Type_*:') + print('*_Type_*') + print ('```') print(value['type']) - print() + print ('```') + print() print() if 'default' in value: print('*_Default_*')