800bf95755
This puts the important facts first and pulls the description way down to the end of the option documentation.
121 lines
2.8 KiB
Python
121 lines
2.8 KiB
Python
import json
|
|
import sys
|
|
from textwrap import indent
|
|
from typing import Any, Mapping
|
|
|
|
header = """
|
|
# Mailserver options
|
|
|
|
## `mailserver`
|
|
|
|
"""
|
|
|
|
template = """
|
|
({key})=
|
|
`````{{option}} {key}
|
|
{type}
|
|
{default}
|
|
{example}
|
|
|
|
{description}
|
|
`````
|
|
"""
|
|
|
|
f = open(sys.argv[1])
|
|
options = json.load(f)
|
|
|
|
groups = [
|
|
"mailserver.accounts",
|
|
"mailserver.x509",
|
|
"mailserver.storage",
|
|
"mailserver.dkim",
|
|
"mailserver.srs",
|
|
"mailserver.dmarcReporting",
|
|
"mailserver.tlsrpt",
|
|
"mailserver.fullTextSearch",
|
|
"mailserver.quota",
|
|
"mailserver.redis",
|
|
"mailserver.ldap",
|
|
"mailserver.monitoring",
|
|
"mailserver.backup",
|
|
"mailserver.borgbackup",
|
|
]
|
|
|
|
|
|
def md_literal(value: str) -> str:
|
|
return f"`{value}`"
|
|
|
|
|
|
def md_codefence(value: str, language: str = "nix") -> str:
|
|
return indent(
|
|
f"\n```{language}\n{value}\n```",
|
|
prefix=2 * " ",
|
|
)
|
|
|
|
|
|
def render_option_value(option: Mapping[str, Any], key: str) -> str:
|
|
if key not in option:
|
|
return ""
|
|
|
|
value = None
|
|
|
|
if isinstance(option[key], dict) and "_type" in option[key]:
|
|
if option[key]["_type"] == "literalExpression":
|
|
# multi-line codeblock
|
|
if "\n" in option[key]["text"]:
|
|
text = option[key]["text"].rstrip("\n")
|
|
value = md_codefence(text)
|
|
# inline codeblock
|
|
else:
|
|
value = md_literal(option[key]["text"])
|
|
# literal markdown
|
|
elif option[key]["_type"] == "literalMD":
|
|
value = option[key]["text"]
|
|
else:
|
|
assert RuntimeError(f"Unhandled option type {option[key]['_type']}")
|
|
else:
|
|
text = str(option[key])
|
|
if text == "":
|
|
value = md_literal('""')
|
|
elif "\n" in text:
|
|
value = md_codefence(text.rstrip("\n"))
|
|
else:
|
|
value = md_literal(text)
|
|
|
|
assert value is not None
|
|
|
|
return f"- {key}: {value}"
|
|
|
|
|
|
def print_option(option):
|
|
if (
|
|
isinstance(option["description"], dict) and "_type" in option["description"]
|
|
): # mdDoc
|
|
description = option["description"]["text"]
|
|
else:
|
|
description = option["description"]
|
|
print(
|
|
template.format(
|
|
key=option["name"],
|
|
description=description or "",
|
|
type=f"- type: {md_literal(option['type'])}",
|
|
default=render_option_value(option, "defaultText")
|
|
if "defaultText" in option
|
|
else render_option_value(option, "default"),
|
|
example=render_option_value(option, "example"),
|
|
)
|
|
)
|
|
|
|
|
|
print(header)
|
|
for opt in options:
|
|
if any([opt["name"].startswith(c) for c in groups]):
|
|
continue
|
|
print_option(opt)
|
|
|
|
for c in groups:
|
|
print(f"## `{c}`\n")
|
|
for opt in options:
|
|
if opt["name"].startswith(c):
|
|
print_option(opt)
|