aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-21 14:55:19 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-21 14:55:19 -0400
commit3b1acb8ac5788061b90aeb9069ddecacf265f20c (patch)
tree22b9a03a9046690683cb9d29aeedf4a9f4d2f5d9
parentaa5578ffe8fb2a9e6d24b0077f5d7ced630b7dfa (diff)
Add missing files
-rw-r--r--man/man3/tomo-List.where.3 (renamed from man/man3/tomo-List.first.3)10
-rwxr-xr-xscripts/mandoc_gen.py125
2 files changed, 130 insertions, 5 deletions
diff --git a/man/man3/tomo-List.first.3 b/man/man3/tomo-List.where.3
index a8183cc8..88520918 100644
--- a/man/man3/tomo-List.first.3
+++ b/man/man3/tomo-List.where.3
@@ -2,14 +2,14 @@
.\" Copyright (c) 2025 Bruce Hill
.\" All rights reserved.
.\"
-.TH List.first 3 2025-04-21T14:44:34.258746 "Tomo man-pages"
+.TH List.where 3 2025-04-21T14:54:02.045598 "Tomo man-pages"
.SH NAME
-List.first \- find an index where a predicate matches
+List.where \- find an index where a predicate matches
.SH LIBRARY
Tomo Standard Library
.SH SYNOPSIS
.nf
-.BI List.first\ :\ func(list:\ [T],\ predicate:\ func(item:&T\ ->\ Bool)\ ->\ Int)
+.BI List.where\ :\ func(list:\ [T],\ predicate:\ func(item:&T\ ->\ Bool)\ ->\ Int)
.fi
.SH DESCRIPTION
Find the index of the first item that matches a predicate function (if any).
@@ -23,14 +23,14 @@ lb lb lbx lb
l l l l.
Name Type Description Default
list [T] The list to search through. -
-predicate func(item:&T -> Bool) A function that returns `yes` if the item should be returned or `no` if it should not. -
+predicate func(item:&T -> Bool) A function that returns `yes` if the item's index should be returned or `no` if it should not. -
.TE
.SH RETURN
Returns the index of the first item where the predicate is true or `!Int` if no item matches.
.SH EXAMPLES
.EX
->> [4, 5, 6].find(func(i:&Int): i.is_prime())
+>> [4, 5, 6].where(func(i:&Int): i.is_prime())
= 5 : Int?
>> [4, 6, 8].find(func(i:&Int): i.is_prime())
= none : Int?
diff --git a/scripts/mandoc_gen.py b/scripts/mandoc_gen.py
new file mode 100755
index 00000000..66db07be
--- /dev/null
+++ b/scripts/mandoc_gen.py
@@ -0,0 +1,125 @@
+#!/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().isoformat()
+ 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:]:
+ with open(filename, "r") as f:
+ all_files += f.read()
+ convert_to_markdown(all_files)
+ else:
+ convert_to_markdown(sys.stdin.read())