From d407de4dc392e33e5d427231baa8afe5b8434a11 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 2 Oct 2016 13:11:49 +0200 Subject: [PATCH] Refactoring of the EvMore to use the new justifier functionality and also properly deal with very long single lines. --- evennia/utils/evmore.py | 58 ++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/evennia/utils/evmore.py b/evennia/utils/evmore.py index aa831da3ec..ac2e38e5f0 100644 --- a/evennia/utils/evmore.py +++ b/evennia/utils/evmore.py @@ -11,18 +11,20 @@ To use, simply pass the text through the EvMore object: from evennia.utils.evmore import EvMore text = some_long_text_output() - EvMore(caller, text, always_page=False, **kwargs) + EvMore(caller, text, always_page=False, session=None, justify_kwargs=None, **kwargs) One can also use the convenience function msg from this module: from evennia.utils import evmore text = some_long_text_output() - evmore.msg(caller, text, **kwargs) + evmore.msg(caller, text, always_page=False, session=None, justify_kwargs=None, **kwargs) Where always_page decides if the pager is used also if the text is not -long enough to need to scroll and **kwargs will be passed on to the -caller.msg() construct (text will be using the pager restrictor). +long enough to need to scroll, session is used to determine which session to relay to +and justify_kwargs are kwargs to pass to utils.utils.justify in order to change the formatting +of the text. The remaining **kwargs will be passed on to the +caller.msg() construct every time the page is updated. """ from builtins import object, range @@ -30,6 +32,7 @@ from builtins import object, range from django.conf import settings from evennia import Command, CmdSet from evennia.commands import cmdhandler +from evennia.utils.utils import justify _CMD_NOMATCH = cmdhandler.CMD_NOMATCH _CMD_NOINPUT = cmdhandler.CMD_NOINPUT @@ -42,7 +45,7 @@ _SCREEN_HEIGHT = settings.CLIENT_DEFAULT_HEIGHT _DISPLAY = \ """{text} -({{wmore{{n [{pageno}/{pagemax}] retur{{wn{{n|{{wb{{nack|{{wt{{nop|{{we{{nnd|{{wa{{nbort)""" +(|wmore|n [{pageno}/{pagemax}] retur|wn|n|||wb|nack|||wt|nop|||we|nnd|||wq|nuit)""" class CmdMore(Command): @@ -50,7 +53,8 @@ class CmdMore(Command): Manipulate the text paging """ key = _CMD_NOINPUT - aliases = ["abort", "a", "next", "n", "back", "b", "top", "t", "end", "e"] + aliases = ["quit", "q", "abort", "a", "next", "n", + "back", "b", "top", "t", "end", "e"] auto_help = False def func(self): @@ -66,7 +70,7 @@ class CmdMore(Command): cmd = self.cmdstring - if cmd in ("abort", "a"): + if cmd in ("abort", "a", "q"): more.page_quit() elif cmd in ("back", "b"): more.page_back() @@ -94,7 +98,7 @@ class EvMore(object): """ The main pager object """ - def __init__(self, caller, text, always_page=False, **kwargs): + def __init__(self, caller, text, always_page=False, session=None, justify_kwargs=None, **kwargs): """ Initialization of the text handler. @@ -110,17 +114,34 @@ class EvMore(object): """ self._caller = caller self._kwargs = kwargs - lines = text.split("\n") self._pages = [] self._npages = [] self._npos = [] - # we use the first session here - sessions = caller.sessions.get() - if not sessions: - return - session = sessions[0] + if not session: + # if not supplied, use the first session to + # determine screen size + sessions = caller.sessions.get() + if not sessions: + return + session = sessions[0] + self._session = session + # set up individual pages for different sessions height = session.protocol_flags.get("SCREENHEIGHT", {0:_SCREEN_HEIGHT})[0] - 2 + width = session.protocol_flags.get("SCREENWIDTH", {0:_SCREEN_WIDTH})[0] + + # we must break very long lines into multiple ones + justify_kwargs = justify_kwargs or {} + width = justify_kwargs.get("width", width) + justify_kwargs["width"] = width + justify_kwargs["align"] = justify_kwargs.get("align", 'l') + justify_kwargs["indent"] = justify_kwargs.get("indent", 0) + + lines = justify(text, **justify_kwargs).split("\n") + + # always limit number of chars to 10 000 per page + height = min(10000 // width, height) + self._pages = ["\n".join(lines[i:i+height]) for i in range(0, len(lines), height)] self._npages = len(self._pages) self._npos = 0 @@ -146,7 +167,7 @@ class EvMore(object): page = _DISPLAY.format(text=text, pageno=pos + 1, pagemax=self._npages) - self._caller.msg(text=page, **self._kwargs) + self._caller.msg(text=page, session=self._session, **self._kwargs) def page_top(self): """ @@ -187,13 +208,14 @@ class EvMore(object): """ del self._caller.ndb._more self._caller.cmdset.remove(CmdSetMore) + self._caller.msg("Exited |wmore|n pager.") -def msg(caller, text="", **kwargs): +def msg(caller, text="", always_page=False, session=None, justify_kwargs=None, **kwargs): """ More-supported version of msg, mimicking the normal msg method. """ - always_page = kwargs.pop("always_page", False) - EvMore(caller, text, always_page, **kwargs) + EvMore(caller, text, always_page=always_page, session=session, + justify_kwargs=justify_kwargs, **kwargs)