mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
250 lines
6.8 KiB
Python
250 lines
6.8 KiB
Python
"""
|
|
Convert contribs' README files to proper documentation pages along with
|
|
an index.
|
|
|
|
"""
|
|
from collections import defaultdict
|
|
from glob import glob
|
|
from os.path import abspath, dirname
|
|
from os.path import join as pathjoin
|
|
from os.path import sep
|
|
|
|
_EVENNIA_PATH = pathjoin(dirname(dirname(dirname(abspath(__file__)))))
|
|
_DOCS_PATH = pathjoin(_EVENNIA_PATH, "docs")
|
|
|
|
_SOURCE_DIR = pathjoin(_EVENNIA_PATH, "evennia", "contrib")
|
|
_OUT_DIR = pathjoin(_DOCS_PATH, "source", "Contribs")
|
|
_OUT_INDEX_FILE = pathjoin(_OUT_DIR, "Contribs-Overview.md")
|
|
|
|
_FILENAME_MAP = {"rpsystem": "RPSystem", "xyzgrid": "XYZGrid", "awsstorage": "AWSStorage"}
|
|
|
|
# ---------------------------------------------------------------------------------------------
|
|
|
|
_FILE_STRUCTURE = """{header}
|
|
{categories}
|
|
{footer}"""
|
|
|
|
_CATEGORY_DESCS = {
|
|
"base_systems": """
|
|
Systems that are not necessarily tied to a specific
|
|
in-game mechanic but which are useful for the game as a whole. Examples include
|
|
login systems, new command syntaxes, and build helpers.
|
|
""",
|
|
"full_systems": """
|
|
'Complete' game engines that can be used directly to start creating content
|
|
without no further additions (unless you want to).
|
|
""",
|
|
"game_systems": """
|
|
In-game gameplay systems like crafting, mail, combat and more.
|
|
Each system is meant to be adopted piecemeal and adopted for your game.
|
|
This does not include roleplaying-specific systems, those are found in
|
|
the `rpg` category.
|
|
""",
|
|
"grid": """
|
|
Systems related to the game world's topology and structure. Contribs related
|
|
to rooms, exits and map building.
|
|
""",
|
|
"rpg": """
|
|
Systems specifically related to roleplaying
|
|
and rule implementation like character traits, dice rolling and emoting.
|
|
""",
|
|
"tutorials": """
|
|
Helper resources specifically meant to teach a development concept or
|
|
to exemplify an Evennia system. Any extra resources tied to documentation
|
|
tutorials are found here. Also the home of the Tutorial-World and Evadventure
|
|
demo codes.
|
|
""",
|
|
"utils": """
|
|
Miscellaneous, tools for manipulating text, security auditing, and more.
|
|
""",
|
|
}
|
|
|
|
|
|
HEADER = """# Contribs
|
|
|
|
```{{sidebar}} More contributions
|
|
Additional Evennia code snippets and contributions can be found
|
|
in the [Community Contribs & Snippets][forum] forum.
|
|
```
|
|
_Contribs_ are optional code snippets and systems contributed by
|
|
the Evennia community. They vary in size and complexity and
|
|
may be more specific about game types and styles than 'core' Evennia.
|
|
This page is auto-generated and summarizes all **{ncontribs}** contribs currently included
|
|
with the Evennia distribution.
|
|
|
|
All contrib categories are imported from `evennia.contrib`, such as
|
|
|
|
from evennia.contrib.base_systems import building_menu
|
|
|
|
Each contrib contains installation instructions for how to integrate it
|
|
with your other code. If you want to tweak the code of a contrib, just
|
|
copy its entire folder to your game directory and modify/use it from there.
|
|
|
|
If you want to add a contrib, see [the contrib guidelines](Contribs-Guidelines)!
|
|
|
|
[forum]: https://github.com/evennia/evennia/discussions/categories/community-contribs-snippets
|
|
|
|
## Index
|
|
{category_index}
|
|
{index}
|
|
"""
|
|
|
|
|
|
TOCTREE = """
|
|
```{{toctree}}
|
|
:hidden:
|
|
Contribs-Guidelines.md
|
|
```
|
|
```{{toctree}}
|
|
:maxdepth: 1
|
|
|
|
{listing}
|
|
```"""
|
|
|
|
CATEGORY = """
|
|
## {category}
|
|
|
|
_{category_desc}_
|
|
|
|
{toctree}
|
|
|
|
{blurbs}
|
|
|
|
|
|
"""
|
|
|
|
BLURB = """
|
|
### `{name}`
|
|
|
|
_{credits}_
|
|
|
|
{blurb}
|
|
|
|
[Read the documentation](./{filename}) - [Browse the Code](api:{code_location})
|
|
|
|
"""
|
|
|
|
FOOTER = """
|
|
|
|
----
|
|
|
|
<small>This document page is generated from `{path}`. Changes to this
|
|
file will be overwritten, so edit that file rather than this one.</small>
|
|
"""
|
|
|
|
INDEX_FOOTER = """
|
|
|
|
----
|
|
|
|
<small>This document page is auto-generated. Manual changes
|
|
will be overwritten.</small>
|
|
"""
|
|
|
|
|
|
def build_table(datalist, ncols):
|
|
"""Build a Markdown table-grid for compact display"""
|
|
|
|
nlen = len(datalist)
|
|
table_heading = "| " * (ncols) + "|"
|
|
table_sep = "|---" * (ncols) + "|"
|
|
table = ""
|
|
for ir in range(0, nlen, ncols):
|
|
table += "| " + " | ".join(datalist[ir : ir + ncols]) + " |\n"
|
|
return f"{table_heading}\n{table_sep}\n{table}"
|
|
|
|
|
|
def readmes2docs(directory=_SOURCE_DIR):
|
|
"""
|
|
Parse directory for README files and convert them to doc pages.
|
|
|
|
"""
|
|
|
|
ncount = 0
|
|
index = []
|
|
category_index = []
|
|
categories = defaultdict(list)
|
|
|
|
glob_path = f"{directory}{sep}*{sep}*{sep}README.md"
|
|
|
|
for file_path in glob(glob_path):
|
|
# paths are e.g. evennia/contrib/utils/auditing/README.md
|
|
_, category, name, _ = file_path.rsplit(sep, 3)
|
|
|
|
index.append(f"[{name}](#{name.lower()})")
|
|
category_index.append(f"[{category}](#{category.lower()})")
|
|
|
|
pypath = f"evennia.contrib.{category}.{name}"
|
|
|
|
filename = (
|
|
"Contrib-"
|
|
+ "-".join(
|
|
_FILENAME_MAP.get(part, part.capitalize() if part[0].islower() else part)
|
|
for part in name.split("_")
|
|
)
|
|
+ ".md"
|
|
)
|
|
outfile = pathjoin(_OUT_DIR, filename)
|
|
|
|
with open(file_path) as fil:
|
|
data = fil.read()
|
|
|
|
clean_file_path = f"evennia{sep}contrib{file_path[len(directory):]}"
|
|
data += FOOTER.format(path=clean_file_path)
|
|
|
|
try:
|
|
credits = data.split("\n\n", 3)[1]
|
|
blurb = data.split("\n\n", 3)[2]
|
|
except IndexError:
|
|
blurb = name
|
|
|
|
with open(outfile, "w") as fil:
|
|
fil.write(data)
|
|
|
|
categories[category].append((name, credits, blurb, filename, pypath))
|
|
ncount += 1
|
|
|
|
# build the list of categories with blurbs
|
|
|
|
category_sections = []
|
|
for category in sorted(categories):
|
|
filenames = []
|
|
contrib_tups = categories[category]
|
|
catlines = []
|
|
for tup in sorted(contrib_tups, key=lambda tup: tup[0].lower()):
|
|
catlines.append(
|
|
BLURB.format(
|
|
name=tup[0], credits=tup[1], blurb=tup[2], filename=tup[3], code_location=tup[4]
|
|
)
|
|
)
|
|
filenames.append(f"{tup[3]}")
|
|
toctree = TOCTREE.format(listing="\n".join(filenames))
|
|
category_sections.append(
|
|
CATEGORY.format(
|
|
category=category,
|
|
category_desc=_CATEGORY_DESCS[category].strip(),
|
|
blurbs="\n".join(catlines),
|
|
toctree=toctree,
|
|
)
|
|
)
|
|
|
|
# build the header, with two tables and a count
|
|
header = HEADER.format(
|
|
ncontribs=len(index),
|
|
category_index=build_table(sorted(set(category_index)), 7),
|
|
index=build_table(sorted(index), 5),
|
|
)
|
|
|
|
# build the final file
|
|
|
|
text = _FILE_STRUCTURE.format(
|
|
header=header, categories="\n".join(category_sections), footer=INDEX_FOOTER
|
|
)
|
|
|
|
with open(_OUT_INDEX_FILE, "w") as fil:
|
|
fil.write(text)
|
|
|
|
print(f" -- Converted Contrib READMEs to {ncount} doc pages + index.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
readmes2docs(_SOURCE_DIR)
|