implement basic domain index structure

develop
myk002 2022-09-21 17:53:51 -07:00
parent 4913637b62
commit 278b7528ac
No known key found for this signature in database
GPG Key ID: 8A39CA0FA0C16E78
6 changed files with 94 additions and 89 deletions

@ -58,9 +58,6 @@ def doc_dir(dirname, files, prefix):
def doc_all_dirs(): def doc_all_dirs():
"""Collect the commands and paths to include in our docs.""" """Collect the commands and paths to include in our docs."""
tools = [] tools = []
# TODO: as we scan the docs, parse out the tags and short descriptions and
# build a map for use in generating the tags pages and links in the tool
# doc footers
for root, _, files in os.walk('docs/builtins'): for root, _, files in os.walk('docs/builtins'):
tools.extend(doc_dir(root, files, os.path.relpath(root, 'docs/builtins'))) tools.extend(doc_dir(root, files, os.path.relpath(root, 'docs/builtins')))
for root, _, files in os.walk('docs/plugins'): for root, _, files in os.walk('docs/plugins'):
@ -69,59 +66,16 @@ def doc_all_dirs():
tools.extend(doc_dir(root, files, os.path.relpath(root, 'scripts/docs'))) tools.extend(doc_dir(root, files, os.path.relpath(root, 'scripts/docs')))
return tuple(tools) return tuple(tools)
DOC_ALL_DIRS = doc_all_dirs()
def get_tags():
groups = {}
group_re = re.compile(r'"([^"]+)"')
tag_re = re.compile(r'- `tag/([^`]+)`: (.*)')
with open('docs/Tags.rst') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
m = re.match(group_re, line)
if m:
group = m.group(1)
groups[group] = []
continue
m = re.match(tag_re, line)
if m:
tag = m.group(1)
desc = m.group(2)
groups[group].append((tag, desc))
return groups
def generate_tag_indices():
os.makedirs('docs/tags', mode=0o755, exist_ok=True)
tag_groups = get_tags()
for tag_group in tag_groups:
with write_file_if_changed(('docs/tags/by{group}.rst').format(group=tag_group)) as topidx:
for tag_tuple in tag_groups[tag_group]:
tag = tag_tuple[0]
with write_file_if_changed(('docs/tags/{name}.rst').format(name=tag)) as tagidx:
tagidx.write('TODO: add links to the tools that have this tag')
topidx.write(('.. _tag/{name}:\n\n').format(name=tag))
topidx.write(('{name}\n').format(name=tag))
topidx.write(('{underline}\n').format(underline='*'*len(tag)))
topidx.write(('{desc}\n\n').format(desc=tag_tuple[1]))
topidx.write(('.. include:: /docs/tags/{name}.rst\n\n').format(name=tag))
def write_tool_docs(): def write_tool_docs():
""" """
Creates a file for each tool with the ".. include::" directives to pull in Creates a file for each tool with the ".. include::" directives to pull in
the original documentation. Then we generate a label and useful info in the the original documentation.
footer.
""" """
for k in DOC_ALL_DIRS: for k in doc_all_dirs():
header = ':orphan:\n' header = ':orphan:\n'
label = ('.. _{name}:\n\n').format(name=k[0]) label = ('.. _{name}:\n\n').format(name=k[0])
include = ('.. include:: /{path}\n\n').format(path=k[1]) include = ('.. include:: /{path}\n\n').format(path=k[1])
# TODO: generate a footer with links to tools that share at least one
# tag with this tool. Just the tool names, strung across the bottom of
# the page in one long wrapped line, similar to how the wiki does it
os.makedirs(os.path.join('docs/tools', os.path.dirname(k[0])), os.makedirs(os.path.join('docs/tools', os.path.dirname(k[0])),
mode=0o755, exist_ok=True) mode=0o755, exist_ok=True)
with write_file_if_changed('docs/tools/{}.rst'.format(k[0])) as outfile: with write_file_if_changed('docs/tools/{}.rst'.format(k[0])) as outfile:
@ -131,9 +85,8 @@ def write_tool_docs():
outfile.write(include) outfile.write(include)
# Actually call the docs generator and run test
write_tool_docs() write_tool_docs()
generate_tag_indices()
# -- General configuration ------------------------------------------------ # -- General configuration ------------------------------------------------
@ -315,11 +268,9 @@ html_sidebars = {
] ]
} }
# If false, no module index is generated. # generate indices
html_domain_indices = False
# If false, no genindex.html is generated.
html_use_index = True html_use_index = True
html_domain_indices = True
# don't link to rst sources in the generated pages # don't link to rst sources in the generated pages
html_show_sourcelink = False html_show_sourcelink = False

@ -185,7 +185,7 @@ where ``*`` can be any string, including the empty string.
A world being loaded can mean a fortress, an adventurer, or legends mode. A world being loaded can mean a fortress, an adventurer, or legends mode.
These files are best used for non-persistent commands, such as setting These files are best used for non-persistent commands, such as setting
a `tag/bugfix` script to run on `repeat`. a `bugfix-tag-index` script to run on `repeat`.
.. _onMapLoad.init: .. _onMapLoad.init:

@ -63,7 +63,7 @@ are not built by default, but can be built by setting the ``BUILD_DEVEL``
Scripts Scripts
~~~~~~~ ~~~~~~~
Several `development tools <tag/dev>` can be useful for memory research. Several `development tools <dev-tag-index>` can be useful for memory research.
These include (but are not limited to): These include (but are not limited to):
- `devel/dump-offsets` - `devel/dump-offsets`

@ -13,36 +13,36 @@ for the tag assignment spreadsheet.
"when" tags "when" tags
----------- -----------
- `tag/adventure`: Tools that are useful while in adventure mode. Note that some tools only tagged with "fort" might also work in adventure mode, but not always in expected ways. Feel free to experiment, though! - `adventure-tag-index`: Tools that are useful while in adventure mode. Note that some tools only tagged with "fort" might also work in adventure mode, but not always in expected ways. Feel free to experiment, though!
- `tag/dfhack`: Tools that you use to run DFHack commands or interact with the DFHack library. This tag also includes tools that help you manage the DF game itself (e.g. settings, saving, etc.) - `dfhack-tag-index`: Tools that you use to run DFHack commands or interact with the DFHack library. This tag also includes tools that help you manage the DF game itself (e.g. settings, saving, etc.)
- `tag/embark`: Tools that are useful while on the fort embark screen or while creating an adventurer. - `embark-tag-index`: Tools that are useful while on the fort embark screen or while creating an adventurer.
- `tag/fort`: Tools that are useful while in fort mode. - `fort-tag-index`: Tools that are useful while in fort mode.
- `tag/legends`: Tools that are useful while in legends mode. - `legends-tag-index`: Tools that are useful while in legends mode.
"why" tags "why" tags
---------- ----------
- `tag/armok`: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden. - `armok-tag-index`: Tools that give you complete control over an aspect of the game or provide access to information that the game intentionally keeps hidden.
- `tag/auto`: Tools that run in the background and automatically manage routine, toilsome aspects of your fortress. - `auto-tag-index`: Tools that run in the background and automatically manage routine, toilsome aspects of your fortress.
- `tag/bugfix`: Tools that fix specific bugs, either permanently or on-demand. - `bugfix-tag-index`: Tools that fix specific bugs, either permanently or on-demand.
- `tag/design`: Tools that help you design your fort. - `design-tag-index`: Tools that help you design your fort.
- `tag/dev`: Tools that are useful when developing scripts or mods. - `dev-tag-index`: Tools that are useful when developing scripts or mods.
- `tag/fps`: Tools that help you manage FPS drop. - `fps-tag-index`: Tools that help you manage FPS drop.
- `tag/gameplay`: Tools that introduce new gameplay elements. - `gameplay-tag-index`: Tools that introduce new gameplay elements.
- `tag/inspection`: Tools that let you view information that is otherwise difficult to find. - `inspection-tag-index`: Tools that let you view information that is otherwise difficult to find.
- `tag/productivity`: Tools that help you do things that you could do manually, but using the tool is better and faster. - `productivity-tag-index`: Tools that help you do things that you could do manually, but using the tool is better and faster.
"what" tags "what" tags
----------- -----------
- `tag/animals`: Tools that interact with animals. - `animals-tag-index`: Tools that interact with animals.
- `tag/buildings`: Tools that interact with buildings and furniture. - `buildings-tag-index`: Tools that interact with buildings and furniture.
- `tag/graphics`: Tools that interact with game graphics. - `graphics-tag-index`: Tools that interact with game graphics.
- `tag/interface`: Tools that interact with or extend the DF user interface. - `interface-tag-index`: Tools that interact with or extend the DF user interface.
- `tag/items`: Tools that interact with in-game items. - `items-tag-index`: Tools that interact with in-game items.
- `tag/jobs`: Tools that interact with jobs. - `jobs-tag-index`: Tools that interact with jobs.
- `tag/labors`: Tools that deal with labor assignment. - `labors-tag-index`: Tools that deal with labor assignment.
- `tag/map`: Tools that interact with the game map. - `map-tag-index`: Tools that interact with the game map.
- `tag/military`: Tools that interact with the military. - `military-tag-index`: Tools that interact with the military.
- `tag/plants`: Tools that interact with trees, shrubs, and crops. - `plants-tag-index`: Tools that interact with trees, shrubs, and crops.
- `tag/stockpiles`: Tools that interact wtih stockpiles. - `stockpiles-tag-index`: Tools that interact wtih stockpiles.
- `tag/units`: Tools that interact with units. - `units-tag-index`: Tools that interact with units.
- `tag/workorders`: Tools that interact with workorders. - `workorders-tag-index`: Tools that interact with workorders.

@ -5,7 +5,8 @@
import logging import logging
import os import os
from typing import List, Optional, Type import re
from typing import Iterable, List, Optional, Tuple, Type
import docutils.nodes as nodes import docutils.nodes as nodes
from docutils.nodes import Node from docutils.nodes import Node
@ -13,13 +14,13 @@ import docutils.parsers.rst.directives as rst_directives
import sphinx import sphinx
import sphinx.addnodes as addnodes import sphinx.addnodes as addnodes
import sphinx.directives import sphinx.directives
from sphinx.domains import Domain, Index, IndexEntry
from sphinx.util.docutils import SphinxDirective from sphinx.util.docutils import SphinxDirective
from sphinx.util.nodes import process_index_entry from sphinx.util.nodes import process_index_entry
import dfhack.util import dfhack.util
logger = sphinx.util.logging.getLogger(__name__) logger = sphinx.util.logging.getLogger(__name__)
@ -165,7 +166,7 @@ class DFHackToolDirective(DFHackToolDirectiveBase):
addnodes.pending_xref(tag, nodes.inline(text=tag), **{ addnodes.pending_xref(tag, nodes.inline(text=tag), **{
'reftype': 'ref', 'reftype': 'ref',
'refdomain': 'std', 'refdomain': 'std',
'reftarget': 'tag/' + tag, 'reftarget': tag + '-tag-index',
'refexplicit': False, 'refexplicit': False,
'refwarn': True, 'refwarn': True,
}), }),
@ -202,6 +203,56 @@ class DFHackCommandDirective(DFHackToolDirectiveBase):
return ret_nodes return ret_nodes
def get_tags():
groups = {}
group_re = re.compile(r'"([^"]+)"')
tag_re = re.compile(r'- `([^`]+)-tag-index`: (.*)')
with open('docs/Tags.rst') as f:
lines = f.readlines()
for line in lines:
line = line.strip()
m = re.match(group_re, line)
if m:
group = m.group(1)
groups[group] = []
continue
m = re.match(tag_re, line)
if m:
tag = m.group(1)
desc = m.group(2)
groups[group].append((tag, desc))
return groups
def generate_tag_index(self, docnames: Optional[Iterable[str]] = None) -> Tuple[List[Tuple[str, List[IndexEntry]]], bool]:
return [('A', [['name', 0, '', '', '', '', '']])], False
def init_tag_indices(app):
os.makedirs('docs/tags', mode=0o755, exist_ok=True)
tag_groups = get_tags()
for tag_group in tag_groups:
with dfhack.util.write_file_if_changed(('docs/tags/by{group}.rst').format(group=tag_group)) as topidx:
for tag_tuple in tag_groups[tag_group]:
tag, desc = tag_tuple[0], tag_tuple[1]
topidx.write(('- `{name} <{name}-tag-index>`\n').format(name=tag))
topidx.write((' {desc}\n').format(desc=desc))
domain_class = type(tag+'Domain', (Domain, ), {
'name': tag,
'label': 'Container domain for tag: ' + tag,
})
index_class = type(tag+'Index', (Index, ), {
'name': 'tag-index',
'localname': tag + ' tag index',
'shortname': tag,
'desc': desc,
'generate': generate_tag_index,
})
app.add_domain(domain_class)
app.add_index_to_domain(tag, index_class)
def register(app): def register(app):
app.add_directive('dfhack-tool', DFHackToolDirective) app.add_directive('dfhack-tool', DFHackToolDirective)
app.add_directive('dfhack-command', DFHackCommandDirective) app.add_directive('dfhack-command', DFHackCommandDirective)
@ -212,11 +263,14 @@ def register(app):
def setup(app): def setup(app):
app.connect('builder-inited', register) app.connect('builder-inited', register)
init_tag_indices(app)
# TODO: re-enable once detection is corrected # TODO: re-enable once detection is corrected
# app.connect('build-finished', lambda *_: check_missing_keybinds()) # app.connect('build-finished', lambda *_: check_missing_keybinds())
# TODO: implement parallel builds so we can set these back to True
return { return {
'version': '0.1', 'version': '0.1',
'parallel_read_safe': True, 'parallel_read_safe': False,
'parallel_write_safe': True, 'parallel_write_safe': False,
} }

@ -396,7 +396,7 @@ local function initialize_tags()
desc = desc .. ' ' .. line desc = desc .. ' ' .. line
tag_index[tag].description = desc tag_index[tag].description = desc
else else
_,_,tag,desc = line:find('^%* (%w+): (.+)') _,_,tag,desc = line:find('^%* (%w+)[^:]*: (.+)')
if not tag then goto continue end if not tag then goto continue end
tag_index[tag] = {description=desc} tag_index[tag] = {description=desc}
in_desc = true in_desc = true