mirror of
https://github.com/evennia/evennia.git
synced 2026-03-29 12:07:17 +02:00
Start add help subtopics
This commit is contained in:
parent
3236421143
commit
7043634e5b
3 changed files with 192 additions and 5 deletions
|
|
@ -76,7 +76,14 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
channel/unban[/quiet] channelname[, channelname, ...] = subscribername
|
||||
channel/who channelname
|
||||
|
||||
This handles all operations on channels.
|
||||
# help-subcategories
|
||||
## channel/list
|
||||
|
||||
This handles all operations on channels. Note that the default operation is to
|
||||
assign a nick/alias for sending to a channel. This would mean you can send
|
||||
using 'foo Hello world' instead of using 'channel foo = Hello world'. Note that
|
||||
aliases set when creating the channel are made available as aliases to subscribers
|
||||
automatically.
|
||||
|
||||
"""
|
||||
key = "channel"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ set. The normal, database-tied help system is used for collaborative
|
|||
creation of other help topics such as RP help or game-world aides.
|
||||
"""
|
||||
|
||||
import re
|
||||
from django.conf import settings
|
||||
from collections import defaultdict
|
||||
from evennia.utils.utils import fill, dedent
|
||||
|
|
@ -25,6 +26,12 @@ COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
|
|||
HELP_MORE = settings.HELP_MORE
|
||||
CMD_IGNORE_PREFIXES = settings.CMD_IGNORE_PREFIXES
|
||||
|
||||
_RE_HELP_SUBTOPICS_START = re.compile(
|
||||
r"^\s*?#\s*?help[- ]subtopics\s*?$", re.I + re.M)
|
||||
_RE_HELP_SUBTOPIC_SPLIT = re.compile(r"^\s*?(\#{2,6}\s*?\w+?)$", re.M)
|
||||
_RE_HELP_SUBTOPIC_PARSE = re.compile(
|
||||
r"^(?P<nesting>\#{2,6})\s*?(?P<name>.*?)$", re.I + re.M)
|
||||
|
||||
# limit symbol import for API
|
||||
__all__ = ("CmdHelp", "CmdSetHelp")
|
||||
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
|
||||
|
|
@ -152,6 +159,122 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
self.msg(text=(text, {"type": "help"}))
|
||||
|
||||
@staticmethod
|
||||
def parse_entry_for_subcategories(entry):
|
||||
"""
|
||||
Parse a command docstring for special sub-category blocks:
|
||||
|
||||
Args:
|
||||
entry (str): A help entry to parse
|
||||
|
||||
Returns:
|
||||
dict: A mapping that splits the entry into subcategories. This
|
||||
will always hold a key `None` for the main help entry and
|
||||
zero or more keys holding the subcategories. Each is itself
|
||||
a dict with a key `None` for the main text of that subcategory
|
||||
followed by any sub-sub-categories down to a max-depth of 5.
|
||||
|
||||
Example:
|
||||
::
|
||||
|
||||
'''
|
||||
Main topic text
|
||||
|
||||
# help-subcategories
|
||||
|
||||
## foo
|
||||
|
||||
A subcategory of the main entry, accessible as `help topic foo`
|
||||
(or using /, like `help topic/foo`)
|
||||
|
||||
## bar
|
||||
|
||||
Another subcategory, accessed as `help topic bar`
|
||||
(or `help topic/bar`)
|
||||
|
||||
### moo
|
||||
|
||||
A subcategory of bar, accessed as `help bar moo`
|
||||
(or `help bar/moo`)
|
||||
|
||||
#### dum
|
||||
|
||||
A subcategory of moo, accessed `help bar moo dum`
|
||||
(or `help bar/moo/dum`)
|
||||
|
||||
'''
|
||||
|
||||
This will result in this returned entry structure:
|
||||
::
|
||||
|
||||
{
|
||||
None: "Main topic text":
|
||||
"foo": {
|
||||
None: "main topic/foo text"
|
||||
},
|
||||
"bar": {
|
||||
None: "Main topic/bar text",
|
||||
"moo": {
|
||||
None: "topic/bar/moo text"
|
||||
"dum": {
|
||||
None: "topic/bar/moo/dum text"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Apart from making
|
||||
sub-categories at the bottom of the entry.
|
||||
|
||||
This will be applied both to command docstrings and database-based help
|
||||
entries.
|
||||
|
||||
"""
|
||||
topic, *subcategories = _RE_HELP_SUBTOPICS_START.split(entry, maxsplit=1)
|
||||
structure = {None: topic.strip()}
|
||||
|
||||
if subcategories:
|
||||
subcategories = subcategories[0]
|
||||
else:
|
||||
return structure
|
||||
|
||||
keypath = []
|
||||
current_nesting = 0
|
||||
subtopic = None
|
||||
|
||||
for part in _RE_HELP_SUBTOPIC_SPLIT.split(subcategories):
|
||||
subtopic_match = _RE_HELP_SUBTOPIC_PARSE.match(part)
|
||||
if subtopic_match:
|
||||
# a new sub(-sub..) category starts.
|
||||
mdict = subtopic_match.groupdict()
|
||||
subtopic = mdict['name'].strip()
|
||||
new_nesting = len(mdict['nesting']) - 1
|
||||
nestdiff = new_nesting - current_nesting
|
||||
if nestdiff < 0:
|
||||
# jumping back up in nesting
|
||||
for _ in range(abs(nestdiff) + 1):
|
||||
try:
|
||||
keypath.pop()
|
||||
except IndexError:
|
||||
pass
|
||||
keypath.append(subtopic)
|
||||
current_nesting = new_nesting
|
||||
else:
|
||||
# an entry belonging to a subtopic - find the nested location
|
||||
dct = structure
|
||||
if not keypath and subtopic is not None:
|
||||
structure[subtopic] = part.strip()
|
||||
else:
|
||||
for key in keypath:
|
||||
if key in dct:
|
||||
dct = dct[key]
|
||||
else:
|
||||
dct[key] = {
|
||||
None: part.strip()
|
||||
}
|
||||
return structure
|
||||
|
||||
@staticmethod
|
||||
def format_help_entry(title, help_text, aliases=None, suggested=None):
|
||||
"""
|
||||
|
|
@ -260,6 +383,7 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
|||
self.original_args = self.args.strip()
|
||||
self.args = self.args.strip().lower()
|
||||
|
||||
|
||||
def func(self):
|
||||
"""
|
||||
Run the dynamic help entry creator.
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from evennia import DefaultRoom, DefaultExit, ObjectDB
|
|||
from evennia.commands.default.cmdset_character import CharacterCmdSet
|
||||
from evennia.utils.test_resources import EvenniaTest
|
||||
from evennia.commands.default import (
|
||||
help,
|
||||
help as help_module,
|
||||
general,
|
||||
system,
|
||||
admin,
|
||||
|
|
@ -407,6 +407,9 @@ class TestGeneral(CommandTest):
|
|||
|
||||
|
||||
class TestHelp(CommandTest):
|
||||
|
||||
maxDiff = None
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
# we need to set up a logger here since lunr takes over the logger otherwise
|
||||
|
|
@ -421,15 +424,68 @@ class TestHelp(CommandTest):
|
|||
logging.disable(level=logging.ERROR)
|
||||
|
||||
def test_help(self):
|
||||
self.call(help.CmdHelp(), "", "Admin", cmdset=CharacterCmdSet())
|
||||
self.call(help_module.CmdHelp(), "", "Admin", cmdset=CharacterCmdSet())
|
||||
|
||||
def test_set_help(self):
|
||||
self.call(
|
||||
help.CmdSetHelp(),
|
||||
help_module.CmdSetHelp(),
|
||||
"testhelp, General = This is a test",
|
||||
"Topic 'testhelp' was successfully created.",
|
||||
)
|
||||
self.call(help.CmdHelp(), "testhelp", "Help for testhelp", cmdset=CharacterCmdSet())
|
||||
self.call(help_module.CmdHelp(), "testhelp", "Help for testhelp", cmdset=CharacterCmdSet())
|
||||
|
||||
def test_parse_entry(self):
|
||||
"""
|
||||
Test for subcategories
|
||||
|
||||
"""
|
||||
entry = """
|
||||
Main topic text
|
||||
|
||||
# help-subtopics
|
||||
|
||||
## foo
|
||||
|
||||
Foo sub-category
|
||||
|
||||
### moo
|
||||
|
||||
Foo/Moo subsub-category
|
||||
|
||||
#### dum
|
||||
|
||||
Foo/Moo/Dum subsubsub-category
|
||||
|
||||
## bar
|
||||
|
||||
Bar subcategory
|
||||
|
||||
### moo
|
||||
|
||||
Bar/Moo subcategory
|
||||
|
||||
"""
|
||||
expected = {
|
||||
None: "Main topic text",
|
||||
"foo": {
|
||||
None: "Foo sub-category",
|
||||
"moo": {
|
||||
None: "Foo/Moo subsub-category",
|
||||
"dum": {
|
||||
None: "Foo/Moo/Dum subsubsub-category",
|
||||
}
|
||||
},
|
||||
},
|
||||
"bar": {
|
||||
None: "Bar subcategory",
|
||||
"moo": {
|
||||
None: "Bar/Moo subcategory"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
actual_result = help_module.CmdHelp.parse_entry_for_subcategories(entry)
|
||||
self.assertEqual(expected, actual_result)
|
||||
|
||||
|
||||
class TestSystem(CommandTest):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue