Move dfhack-keybind role to tool_docs.py and call from dfhack-command

develop
lethosor 2022-08-07 01:37:14 -04:00
parent 5ef36d210f
commit ed95db27f5
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
2 changed files with 67 additions and 66 deletions

@ -21,6 +21,8 @@ import shlex # pylint:disable=unused-import
import sphinx import sphinx
import sys 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'): if os.environ.get('DFHACK_DOCS_BUILD_OFFLINE'):
# block attempted image downloads, particularly for the PDF builder # 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 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 ------------------------------- # -- Autodoc for DFhack plugins and scripts -------------------------------
def doc_dir(dirname, files, prefix): def doc_dir(dirname, files, prefix):

@ -3,6 +3,7 @@
# https://www.sphinx-doc.org/en/master/development/tutorials/recipe.html # https://www.sphinx-doc.org/en/master/development/tutorials/recipe.html
# https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#rst-directives # https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html#rst-directives
import os
from typing import List from typing import List
import docutils.nodes as nodes import docutils.nodes as nodes
@ -13,6 +14,63 @@ import sphinx.directives
import dfhack.util 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): class DFHackToolDirectiveBase(sphinx.directives.ObjectDescription):
has_content = False has_content = False
required_arguments = 0 required_arguments = 0
@ -77,14 +135,20 @@ class DFHackToolDirective(DFHackToolDirectiveBase):
class DFHackCommandDirective(DFHackToolDirectiveBase): class DFHackCommandDirective(DFHackToolDirectiveBase):
def render_content(self) -> List[nodes.Node]: def render_content(self) -> List[nodes.Node]:
command = self.get_name_or_docname()
return [ 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): 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)
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): def setup(app):
app.connect('builder-inited', register) app.connect('builder-inited', register)