Refactoring of the EvMore to use the new justifier functionality and also properly deal with very long single lines.

This commit is contained in:
Griatch 2016-10-02 13:11:49 +02:00
parent 4e9d070b64
commit d407de4dc3

View file

@ -11,18 +11,20 @@ To use, simply pass the text through the EvMore object:
from evennia.utils.evmore import EvMore from evennia.utils.evmore import EvMore
text = some_long_text_output() 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: One can also use the convenience function msg from this module:
from evennia.utils import evmore from evennia.utils import evmore
text = some_long_text_output() 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 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 long enough to need to scroll, session is used to determine which session to relay to
caller.msg() construct (text will be using the pager restrictor). 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 from builtins import object, range
@ -30,6 +32,7 @@ from builtins import object, range
from django.conf import settings from django.conf import settings
from evennia import Command, CmdSet from evennia import Command, CmdSet
from evennia.commands import cmdhandler from evennia.commands import cmdhandler
from evennia.utils.utils import justify
_CMD_NOMATCH = cmdhandler.CMD_NOMATCH _CMD_NOMATCH = cmdhandler.CMD_NOMATCH
_CMD_NOINPUT = cmdhandler.CMD_NOINPUT _CMD_NOINPUT = cmdhandler.CMD_NOINPUT
@ -42,7 +45,7 @@ _SCREEN_HEIGHT = settings.CLIENT_DEFAULT_HEIGHT
_DISPLAY = \ _DISPLAY = \
"""{text} """{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): class CmdMore(Command):
@ -50,7 +53,8 @@ class CmdMore(Command):
Manipulate the text paging Manipulate the text paging
""" """
key = _CMD_NOINPUT 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 auto_help = False
def func(self): def func(self):
@ -66,7 +70,7 @@ class CmdMore(Command):
cmd = self.cmdstring cmd = self.cmdstring
if cmd in ("abort", "a"): if cmd in ("abort", "a", "q"):
more.page_quit() more.page_quit()
elif cmd in ("back", "b"): elif cmd in ("back", "b"):
more.page_back() more.page_back()
@ -94,7 +98,7 @@ class EvMore(object):
""" """
The main pager 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. Initialization of the text handler.
@ -110,17 +114,34 @@ class EvMore(object):
""" """
self._caller = caller self._caller = caller
self._kwargs = kwargs self._kwargs = kwargs
lines = text.split("\n")
self._pages = [] self._pages = []
self._npages = [] self._npages = []
self._npos = [] self._npos = []
# we use the first session here if not session:
sessions = caller.sessions.get() # if not supplied, use the first session to
if not sessions: # determine screen size
return sessions = caller.sessions.get()
session = sessions[0] if not sessions:
return
session = sessions[0]
self._session = session
# set up individual pages for different sessions # set up individual pages for different sessions
height = session.protocol_flags.get("SCREENHEIGHT", {0:_SCREEN_HEIGHT})[0] - 2 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._pages = ["\n".join(lines[i:i+height]) for i in range(0, len(lines), height)]
self._npages = len(self._pages) self._npages = len(self._pages)
self._npos = 0 self._npos = 0
@ -146,7 +167,7 @@ class EvMore(object):
page = _DISPLAY.format(text=text, page = _DISPLAY.format(text=text,
pageno=pos + 1, pageno=pos + 1,
pagemax=self._npages) pagemax=self._npages)
self._caller.msg(text=page, **self._kwargs) self._caller.msg(text=page, session=self._session, **self._kwargs)
def page_top(self): def page_top(self):
""" """
@ -187,13 +208,14 @@ class EvMore(object):
""" """
del self._caller.ndb._more del self._caller.ndb._more
self._caller.cmdset.remove(CmdSetMore) 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 More-supported version of msg, mimicking the
normal msg method. normal msg method.
""" """
always_page = kwargs.pop("always_page", False) EvMore(caller, text, always_page=always_page, session=session,
EvMore(caller, text, always_page, **kwargs) justify_kwargs=justify_kwargs, **kwargs)