From ed95db27f5bd7b13e556fc2ca15b4f68f38cdcb7 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sun, 7 Aug 2022 01:37:14 -0400 Subject: [PATCH] Move dfhack-keybind role to tool_docs.py and call from dfhack-command --- conf.py | 67 +--------------------- docs/sphinx_extensions/dfhack/tool_docs.py | 66 ++++++++++++++++++++- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/conf.py b/conf.py index 49d005f46..775f94b68 100644 --- a/conf.py +++ b/conf.py @@ -21,6 +21,8 @@ import shlex # pylint:disable=unused-import import sphinx import sys +sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'docs', 'sphinx_extensions')) +from dfhack.util import write_file_if_changed if os.environ.get('DFHACK_DOCS_BUILD_OFFLINE'): # block attempted image downloads, particularly for the PDF builder @@ -38,71 +40,6 @@ if os.environ.get('DFHACK_DOCS_BUILD_OFFLINE'): requests.get = request_disabled -# -- Support :dfhack-keybind:`command` ------------------------------------ -# this is a custom directive that pulls info from default keybindings - -from docutils import nodes -from docutils.parsers.rst import roles - -sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'docs', 'sphinx_extensions')) -from dfhack.util import write_file_if_changed - - -def get_keybinds(root, files, keybindings): - """Add keybindings in the specified files to the - given keybindings dict. - """ - for file in files: - with open(os.path.join(root, file)) as f: - lines = [l.replace('keybinding add', '').strip() for l in f.readlines() - if l.startswith('keybinding add')] - for k in lines: - first, command = k.split(' ', 1) - bind, context = (first.split('@') + [''])[:2] - if ' ' not in command: - command = command.replace('"', '') - tool = command.split(' ')[0].replace('"', '') - keybindings[tool] = keybindings.get(tool, []) + [ - (command, bind.split('-'), context)] - -def get_all_keybinds(root_dir): - """Get the implemented keybinds, and return a dict of - {tool: [(full_command, keybinding, context), ...]}. - """ - keybindings = dict() - for root, _, files in os.walk(root_dir): - get_keybinds(root, files, keybindings) - return keybindings - -KEYBINDS = get_all_keybinds('data/init') - - -# pylint:disable=unused-argument,dangerous-default-value,too-many-arguments -def dfhack_keybind_role_func(role, rawtext, text, lineno, inliner, - options={}, content=[]): - """Custom role parser for DFHack default keybinds.""" - roles.set_classes(options) - if text not in KEYBINDS: - return [], [] - newnode = nodes.paragraph() - for cmd, key, ctx in KEYBINDS[text]: - n = nodes.paragraph() - newnode += n - n += nodes.strong('Keybinding:', 'Keybinding:') - n += nodes.inline(' ', ' ') - for k in key: - n += nodes.inline(k, k, classes=['kbd']) - if cmd != text: - n += nodes.inline(' -> ', ' -> ') - n += nodes.literal(cmd, cmd, classes=['guilabel']) - if ctx: - n += nodes.inline(' in ', ' in ') - n += nodes.literal(ctx, ctx) - return [newnode], [] - - -roles.register_canonical_role('dfhack-keybind', dfhack_keybind_role_func) - # -- Autodoc for DFhack plugins and scripts ------------------------------- def doc_dir(dirname, files, prefix): diff --git a/docs/sphinx_extensions/dfhack/tool_docs.py b/docs/sphinx_extensions/dfhack/tool_docs.py index 28876c36a..d1bdec8bf 100644 --- a/docs/sphinx_extensions/dfhack/tool_docs.py +++ b/docs/sphinx_extensions/dfhack/tool_docs.py @@ -3,6 +3,7 @@ # https://www.sphinx-doc.org/en/master/development/tutorials/recipe.html # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#rst-directives +import os from typing import List import docutils.nodes as nodes @@ -13,6 +14,63 @@ import sphinx.directives import dfhack.util + +_KEYBINDS = {} + +def scan_keybinds(root, files, keybindings): + """Add keybindings in the specified files to the + given keybindings dict. + """ + for file in files: + with open(os.path.join(root, file)) as f: + lines = [l.replace('keybinding add', '').strip() for l in f.readlines() + if l.startswith('keybinding add')] + for k in lines: + first, command = k.split(' ', 1) + bind, context = (first.split('@') + [''])[:2] + if ' ' not in command: + command = command.replace('"', '') + tool = command.split(' ')[0].replace('"', '') + keybindings[tool] = keybindings.get(tool, []) + [ + (command, bind.split('-'), context)] + +def scan_all_keybinds(root_dir): + """Get the implemented keybinds, and return a dict of + {tool: [(full_command, keybinding, context), ...]}. + """ + keybindings = dict() + for root, _, files in os.walk(root_dir): + scan_keybinds(root, files, keybindings) + return keybindings + + +def render_dfhack_keybind(command) -> List[nodes.paragraph]: + if command not in _KEYBINDS: + return [] + newnode = nodes.paragraph() + for keycmd, key, ctx in _KEYBINDS[command]: + n = nodes.paragraph() + newnode += n + n += nodes.strong('Keybinding:', 'Keybinding:') + n += nodes.inline(' ', ' ') + for k in key: + n += nodes.inline(k, k, classes=['kbd']) + if keycmd != command: + n += nodes.inline(' -> ', ' -> ') + n += nodes.literal(keycmd, keycmd, classes=['guilabel']) + if ctx: + n += nodes.inline(' in ', ' in ') + n += nodes.literal(ctx, ctx) + return [newnode] + + +# pylint:disable=unused-argument,dangerous-default-value,too-many-arguments +def dfhack_keybind_role(role, rawtext, text, lineno, inliner, + options={}, content=[]): + """Custom role parser for DFHack default keybinds.""" + return render_dfhack_keybind(text), [] + + class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription): has_content = False required_arguments = 0 @@ -77,14 +135,20 @@ class DFHackToolDirective(DFHackToolDirectiveBase): class DFHackCommandDirective(DFHackToolDirectiveBase): def render_content(self) -> List[nodes.Node]: + command = self.get_name_or_docname() return [ - self.make_labeled_paragraph('Command', self.get_name_or_docname(), content_class=nodes.literal), + self.make_labeled_paragraph('Command', command, content_class=nodes.literal), + *render_dfhack_keybind(command), ] def register(app): app.add_directive('dfhack-tool', DFHackToolDirective) app.add_directive('dfhack-command', DFHackCommandDirective) + app.add_role('dfhack-keybind', dfhack_keybind_role) + + _KEYBINDS.update(scan_all_keybinds(os.path.join(dfhack.util.DFHACK_ROOT, 'data', 'init'))) + def setup(app): app.connect('builder-inited', register)