1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#!/bin/env python3
# This script converts API YAML files into markdown documentation
# and prints it to standard out.
from datetime import datetime
import re
import yaml
def escape(text, spaces=False):
"""
Escapes text for safe inclusion in groff documents.
- Escapes backslashes as '\\e'
- Escapes periods at the start of a line as '\\&.'
"""
escaped_lines = []
for line in text.splitlines():
# Escape backslashes
line = line.replace("\\", r"\[rs]")
# Escape leading period or apostrophe (groff macro triggers)
if line.startswith('.'):
line = r'\&' + line
elif line.startswith("'"):
line = r'\&' + line
if spaces:
line = line.replace(' ', '\\ ')
escaped_lines.append(line)
return '\n'.join(escaped_lines)
def arg_signature(name, arg):
sig = name
if "type" in arg:
sig = sig + ": " + arg["type"]
if "default" in arg:
sig = sig + " = " + arg["default"]
return sig
def get_signature(name, info):
if "type" in info:
return ".BI " +escape(f'{name} : {info["type"]}', spaces=True)
sig = f'{name} : func('
if info["args"]:
sig += ", ".join(arg_signature(name,arg) for name,arg in info["args"].items())
sig += " -> " + info["return"].get("type", "Void")
else:
sig += "-> " + info["return"].get("type", "Void")
sig += ')'
return ".BI " + escape(sig, spaces=True)
template = ''''\\" t
.\\" Copyright (c) {year} Bruce Hill
.\\" All rights reserved.
.\\"
.TH {name} 3 {date} "Tomo man-pages"
.SH NAME
{name} \\- {short}
.SH LIBRARY
Tomo Standard Library
.SH SYNOPSIS
.nf
{signature}
.fi
.SH DESCRIPTION
{description}
'''
arg_prefix = '''
.TS
allbox;
lb lb lbx lb
l l l l.
Name Type Description Default'''
def write_method(f, name, info):
def add_line(line): f.write(line + "\n")
year = datetime.now().strftime("%Y")
date = datetime.now().strftime("%Y-%m-%d")
signature = get_signature(name, info)
add_line(template.format(year=year, date=date, name=name, short=info["short"], description=info["description"], signature=signature))
if "args" in info and info["args"]:
add_line(".SH ARGUMENTS")
add_line(arg_prefix)
for arg,arg_info in info["args"].items():
default = escape(arg_info['default'], spaces=True) if 'default' in arg_info else '-'
description = arg_info['description'].replace('\n', ' ')
add_line(f"{arg}\t{arg_info.get('type', '')}\t{description}\t{default}")
add_line(".TE")
if "return" in info:
add_line(".SH RETURN")
add_line(info['return'].get('description', 'Nothing.'))
if "note" in info:
add_line(".SH NOTES")
add_line(info["note"])
if "errors" in info:
add_line(".SH ERRORS")
add_line(info["errors"])
if "example" in info:
add_line(".SH EXAMPLES")
add_line(".EX")
add_line(escape(info['example']))
add_line(".EE")
def convert_to_markdown(yaml_doc:str)->str:
data = yaml.safe_load(yaml_doc)
for name,info in data.items():
with open(f"man/man3/tomo-{name}.3", "w") as f:
print(f"Wrote to man/man3/tomo-{name}.3")
write_method(f, name, data[name])
if __name__ == "__main__":
import sys
if len(sys.argv) > 1:
all_files = ""
for filename in sys.argv[1:]:
print(f"Making mandoc for {filename}")
with open(filename, "r") as f:
all_files += f.read()
convert_to_markdown(all_files)
else:
convert_to_markdown(sys.stdin.read())
|