Files
gnatcoll-core/docs/generate_reference_guides
Nicolas Roche 6913a5f627 Generate reference doc for GNATCOLL packages
eng/toolchain/gnatcoll-core#80
2024-10-10 16:43:53 +02:00

94 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python
import os
import re
import shutil
import sys
SOURCE_DIRS = {
"minimal": ["../minimal/src"],
"core": ["../core/src", "../core/src/os"],
"projects": ["../projects/src"],
}
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
REF_GUIDES_DIR = os.path.join(ROOT_DIR, "refs")
SOURCE_REGEXP = re.compile(
"|".join(
[
"(?:package|function|procedure) (?P<entity_name>[^ ]+)",
"(?P<output>generic|end )",
"(?P<no_output>private$)",
"(?P<skip_src>private package)",
]
)
)
if __name__ == "__main__":
if os.path.isdir(REF_GUIDES_DIR):
shutil.rmtree(REF_GUIDES_DIR)
os.mkdir(REF_GUIDES_DIR)
for project in ("minimal", "core", "projects"):
print(f"Generate reference docs for gnatcoll {project}")
os.mkdir(os.path.join(REF_GUIDES_DIR, project))
for source_dir in SOURCE_DIRS[project]:
for src in os.listdir(source_dir):
# Consider only specifications
if not src.endswith(".ads"):
continue
base = os.path.basename(src)[:-4]
# Detect package variants
if "__" in base:
variant = base.split("__", 1)[1]
else:
variant = ""
# Parse the source file and extract the public API
with open(os.path.join(source_dir, src)) as fd:
content = fd.read().splitlines()
entity_name = None
skip_src = False
with open(f"refs/{project}/{os.path.basename(src)}", "w") as fd:
output_line = False
for line in content:
m = re.match(SOURCE_REGEXP, line)
if m is not None:
if m.group("entity_name") is not None:
output_line = True
entity_name = m.group("entity_name")
elif m.group("no_output"):
output_line = False
elif m.group("output"):
output_line = True
elif m.group("skip_src"):
skip_src = True
break
if output_line:
fd.write(line + "\n")
if skip_src:
print(f" Skip reference doc {base}")
continue
print(f" Generate reference doc for {base}")
if entity_name is None:
print("Error while parsing Ada sources")
sys.exit(1)
# Generate a ReST file that includes the generated Ada extract
with open(f"refs/{project}/ref-{base}-A.rst", "w") as fd:
title = entity_name
if variant:
title += f" ({variant})"
fd.write(f"{title}\n")
fd.write(len(title) * "=" + "\n\n")
fd.write(f".. literalinclude:: {os.path.basename(src)}\n")
fd.write(" :language: ada\n")
fd.write("\n")