mirror of
https://github.com/mailscope/kumomta.git
synced 2026-08-24 13:18:18 +00:00
3a1b1053bd
Ideally there would be a good mkdocs based checker, but the one that is out there only validate absolute URLs, which makes it unsuitable for checking local relative links in the docs. Adjust the doc build so that we also generate the SUMMARY.md for mdbook, and use mdbook's link checker to check the links. Fixup the couple of broken links that it found.
236 lines
8.1 KiB
Python
Executable File
236 lines
8.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import base64
|
|
import glob
|
|
import json
|
|
import os
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
|
|
class Page(object):
|
|
"""A page in the TOC, and its optional children"""
|
|
|
|
def __init__(self, title, filename, children=None):
|
|
self.title = title
|
|
self.filename = filename
|
|
self.children = children or []
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
indent = " " * depth
|
|
bullet = "- " if depth > 0 else ""
|
|
if mode == "mdbook":
|
|
if self.filename:
|
|
output.write(f"{indent}{bullet}[{self.title}]({self.filename})\n")
|
|
elif mode == "mkdocs":
|
|
if depth > 0:
|
|
if len(self.children) == 0:
|
|
output.write(f'{indent}{bullet}"{self.title}": {self.filename}\n')
|
|
else:
|
|
output.write(f'{indent}{bullet}"{self.title}":\n')
|
|
if self.filename:
|
|
output.write(
|
|
f'{indent} {bullet}"{self.title}": {self.filename}\n'
|
|
)
|
|
for kid in self.children:
|
|
kid.render(output, depth + 1, mode)
|
|
|
|
|
|
class Gen(object):
|
|
"""autogenerate an index page from the contents of a directory"""
|
|
|
|
def __init__(self, title, dirname, index=None, extract_title=False, reverse=False):
|
|
self.title = title
|
|
self.dirname = dirname
|
|
self.index = index
|
|
self.extract_title = extract_title
|
|
self.reverse = reverse
|
|
|
|
def render(self, output, depth=0, mode="mdbook"):
|
|
names = sorted(glob.glob(f"{self.dirname}/*.md"), reverse=self.reverse)
|
|
children = []
|
|
for filename in names:
|
|
title = os.path.basename(filename).rsplit(".", 1)[0]
|
|
if title == "index" or title == "_index":
|
|
continue
|
|
|
|
if self.extract_title:
|
|
with open(filename, "r") as f:
|
|
title = f.readline().strip("#").strip()
|
|
|
|
children.append(Page(title, filename))
|
|
|
|
index_filename = f"{self.dirname}/index.md"
|
|
index_page = Page(self.title, index_filename, children=children)
|
|
index_page.render(output, depth, mode)
|
|
with open(index_filename, "w") as idx:
|
|
if self.index:
|
|
idx.write(self.index)
|
|
idx.write("\n\n")
|
|
else:
|
|
try:
|
|
with open(f"{self.dirname}/_index.md", "r") as f:
|
|
idx.write(f.read())
|
|
idx.write("\n\n")
|
|
except FileNotFoundError:
|
|
pass
|
|
for page in children:
|
|
idx.write(f" - [{page.title}]({os.path.basename(page.filename)})\n")
|
|
|
|
|
|
TOC = [
|
|
Page(
|
|
"Tutorial",
|
|
None,
|
|
children=[
|
|
Page("Getting Started", "tutorial/getting_started.md"),
|
|
Page(
|
|
"Environmental Considerations",
|
|
"tutorial/environment_consideration.md",
|
|
),
|
|
Page("System Preparation", "tutorial/system_preparation.md"),
|
|
Page(
|
|
"Installing with Docker Containers",
|
|
"tutorial/install_with_docker.md",
|
|
),
|
|
Page(
|
|
"Building from Source",
|
|
"tutorial/install_from_source.md",
|
|
),
|
|
Page("Your First Email", "tutorial/your_first_email.md"),
|
|
Page(
|
|
"Beyond Basics",
|
|
"tutorial/beyond_basics.md",
|
|
children=[
|
|
Page("Configuring DKIM", "tutorial/dkim.md"),
|
|
Page("Configuring TLS", "tutorial/tls.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Advanced Configurations",
|
|
"tutorial/advanced_config.md",
|
|
children=[
|
|
Page("Lua Resources", "tutorial/lua_resources.md"),
|
|
Page("Lua Functions", "tutorial/lua_functions.md"),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
Page(
|
|
"User Guide",
|
|
"userguide/index.md",
|
|
children=[
|
|
Page(
|
|
"General",
|
|
None,
|
|
children=[
|
|
Page("Preface and Legal Notices", "userguide/general/preface.md"),
|
|
Page("About This Manual", "userguide/general/about.md"),
|
|
Page(
|
|
"How to Report Bugs or Get Help", "userguide/general/report.md"
|
|
),
|
|
Page("Credits", "userguide/general/credits.md"),
|
|
Page("History", "userguide/general/history.md"),
|
|
Page("Architecture", "userguide/general/architecture.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Installation",
|
|
"userguide/installation/index.md",
|
|
children=[
|
|
Page(
|
|
"Deployment Architecture",
|
|
"userguide/installation/deployment.md",
|
|
),
|
|
Page("Server Environment", "userguide/installation/environment.md"),
|
|
Page("Server Hardware", "userguide/installation/hardware.md"),
|
|
Page(
|
|
"Operating System", "userguide/installation/operatingsystem.md"
|
|
),
|
|
Page("Installing in Docker", "userguide/installation/docker.md"),
|
|
Page("Installing on Linux", "userguide/installation/linux.md"),
|
|
Page("Upgrading", "userguide/installation/upgrading.md"),
|
|
],
|
|
),
|
|
Page(
|
|
"Configuration",
|
|
"userguide/configuration/index.md",
|
|
children=[
|
|
Page(
|
|
"Configuration Concepts", "userguide/configuration/concepts.md"
|
|
),
|
|
Page(
|
|
"An Example Configuration", "userguide/configuration/example.md"
|
|
),
|
|
Page("Configuring Spooling", "userguide/configuration/spool.md"),
|
|
Page(
|
|
"Configuring Listeners",
|
|
"userguide/configuration/smtplisteners.md",
|
|
),
|
|
Page(
|
|
"Configuring Traffic Shaping",
|
|
"userguide/configuration/trafficshaping.md",
|
|
),
|
|
Page("Configuring Logging", "userguide/configuration/logging.md"),
|
|
Page(
|
|
"Configuring HTTP Listeners",
|
|
"userguide/configuration/httplisteners.md",
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
Page(
|
|
"Reference Manual",
|
|
"reference/index.md",
|
|
children=[
|
|
Page("Queues", "reference/queues.md"),
|
|
Gen(
|
|
"module: kumo",
|
|
"reference/kumo",
|
|
),
|
|
Gen(
|
|
"module: kumo.dkim",
|
|
"reference/kumo.dkim",
|
|
),
|
|
Gen(
|
|
"module: sqlite",
|
|
"reference/sqlite",
|
|
),
|
|
Gen(
|
|
"module: redis",
|
|
"reference/redis",
|
|
),
|
|
Gen(
|
|
"object: address",
|
|
"reference/address",
|
|
),
|
|
Gen(
|
|
"object: message",
|
|
"reference/message",
|
|
),
|
|
Gen(
|
|
"events",
|
|
"reference/events",
|
|
),
|
|
Gen("HTTP API", "reference/http", extract_title=True),
|
|
],
|
|
),
|
|
Gen("Changelog", "changelog", extract_title=True, reverse=True),
|
|
]
|
|
|
|
os.chdir("docs")
|
|
|
|
with open("../mkdocs.yml", "w") as f:
|
|
f.write("# this is auto-generated by docs/generate-toc.py, do not edit\n")
|
|
f.write("INHERIT: mkdocs-base.yml\n")
|
|
f.write("nav:\n")
|
|
for page in TOC:
|
|
page.render(f, depth=1, mode="mkdocs")
|
|
|
|
with open("SUMMARY.md", "w") as f:
|
|
f.write("<!-- this is auto-generated by docs/generate-toc.py, do not edit -->\n")
|
|
f.write("[Home](index.md)\n")
|
|
for page in TOC:
|
|
page.render(f, depth=1, mode="mdbook")
|