mirror of
https://github.com/evennia/evennia.git
synced 2026-04-01 05:27:17 +02:00
Merge branch 'master' into develop
This commit is contained in:
commit
a8891b44a6
9 changed files with 189 additions and 135 deletions
|
|
@ -417,7 +417,7 @@ class CmdSay(COMMAND_DEFAULT_CLASS):
|
|||
return
|
||||
|
||||
# Call the at_after_say hook on the character
|
||||
caller.at_say(speech)
|
||||
caller.at_say(speech, msg_self=True)
|
||||
|
||||
|
||||
class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
||||
|
|
@ -425,10 +425,11 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
|||
Speak privately as your character to another
|
||||
|
||||
Usage:
|
||||
whisper <player> = <message>
|
||||
whisper <character> = <message>
|
||||
whisper <char1>, <char2> = <message?
|
||||
|
||||
Talk privately to those in your current location, without
|
||||
others being informed.
|
||||
Talk privately to one or more characters in your current location, without
|
||||
others in the room being informed.
|
||||
"""
|
||||
|
||||
key = "whisper"
|
||||
|
|
@ -440,24 +441,25 @@ class CmdWhisper(COMMAND_DEFAULT_CLASS):
|
|||
caller = self.caller
|
||||
|
||||
if not self.lhs or not self.rhs:
|
||||
caller.msg("Usage: whisper <account> = <message>")
|
||||
caller.msg("Usage: whisper <character> = <message>")
|
||||
return
|
||||
|
||||
receiver = caller.search(self.lhs)
|
||||
receivers = [recv.strip() for recv in self.lhs.split(",")]
|
||||
|
||||
if not receiver:
|
||||
return
|
||||
receivers = [caller.search(receiver) for receiver in receivers]
|
||||
receivers = [recv for recv in receivers if recv]
|
||||
|
||||
speech = self.rhs
|
||||
# Call a hook to change the speech before whispering
|
||||
speech = caller.at_before_say(speech, whisper=True, receiver=receiver)
|
||||
|
||||
# If the speech is empty, abort the command
|
||||
if not speech:
|
||||
if not speech or not receivers:
|
||||
return
|
||||
|
||||
# Call the at_after_whisper hook for feedback
|
||||
caller.at_say(speech, receiver=receiver, whisper=True)
|
||||
# Call a hook to change the speech before whispering
|
||||
speech = caller.at_before_say(speech, whisper=True, receivers=receivers)
|
||||
|
||||
# no need for self-message if we are whispering to ourselves (for some reason)
|
||||
msg_self = None if caller in receivers else True
|
||||
caller.at_say(speech, msg_self=msg_self, receivers=receivers, whisper=True)
|
||||
|
||||
|
||||
class CmdPose(COMMAND_DEFAULT_CLASS):
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
@mail/delete 6
|
||||
@mail/forward feend78 Griatch=4/You guys should read this.
|
||||
@mail/reply 9=Thanks for the info!
|
||||
|
||||
"""
|
||||
key = "@mail"
|
||||
aliases = ["mail"]
|
||||
|
|
@ -86,6 +87,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
|
||||
Returns:
|
||||
messages (list): list of Msg objects.
|
||||
|
||||
"""
|
||||
# mail_messages = Msg.objects.get_by_tag(category="mail")
|
||||
# messages = []
|
||||
|
|
@ -105,6 +107,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
subject (str): The header or subject of the message to be delivered.
|
||||
message (str): The body of the message being sent.
|
||||
caller (obj): The object (or Account or Character) that is sending the message.
|
||||
|
||||
"""
|
||||
for recipient in recipients:
|
||||
recipient.msg("You have received a new @mail from %s" % caller)
|
||||
|
|
@ -130,7 +133,8 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
return
|
||||
else:
|
||||
all_mail = self.get_all_mail()
|
||||
mind = int(self.lhs) - 1
|
||||
mind_max = all_mail.count() - 1
|
||||
mind = max(0, min(mind_max, int(self.lhs) - 1))
|
||||
if all_mail[mind]:
|
||||
all_mail[mind].delete()
|
||||
self.caller.msg("Message %s deleted" % self.lhs)
|
||||
|
|
@ -150,9 +154,10 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
return
|
||||
else:
|
||||
all_mail = self.get_all_mail()
|
||||
mind_max = all_mail.count() - 1
|
||||
if "/" in self.rhs:
|
||||
message_number, message = self.rhs.split("/")
|
||||
mind = int(message_number) - 1
|
||||
message_number, message = self.rhs.split("/", 1)
|
||||
mind = max(0, min(mind_max, int(message_number) - 1))
|
||||
|
||||
if all_mail[mind]:
|
||||
old_message = all_mail[mind]
|
||||
|
|
@ -164,7 +169,7 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
else:
|
||||
raise IndexError
|
||||
else:
|
||||
mind = int(self.rhs) - 1
|
||||
mind = max(0, min(mind_max, int(self.rhs) - 1))
|
||||
if all_mail[mind]:
|
||||
old_message = all_mail[mind]
|
||||
self.send_mail(self.search_targets(self.lhslist), "FWD: " + old_message.header,
|
||||
|
|
@ -188,7 +193,8 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
return
|
||||
else:
|
||||
all_mail = self.get_all_mail()
|
||||
mind = int(self.lhs) - 1
|
||||
mind_max = all_mail.count() - 1
|
||||
mind = max(0, min(mind_max, int(self.lhs) - 1))
|
||||
if all_mail[mind]:
|
||||
old_message = all_mail[mind]
|
||||
self.send_mail(old_message.senders, "RE: " + old_message.header,
|
||||
|
|
@ -211,8 +217,11 @@ class CmdMail(default_cmds.MuxCommand):
|
|||
body = self.rhs
|
||||
self.send_mail(self.search_targets(self.lhslist), subject, body, self.caller)
|
||||
else:
|
||||
all_mail = self.get_all_mail()
|
||||
mind_max = all_mail.count() - 1
|
||||
try:
|
||||
message = self.get_all_mail()[int(self.lhs) - 1]
|
||||
mind = max(0, min(mind_max, self.lhs - 1))
|
||||
message = all_mail[mind]
|
||||
except (ValueError, IndexError):
|
||||
self.caller.msg("'%s' is not a valid mail id." % self.lhs)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ also adds the short descriptions and the `sdesc` command).
|
|||
Installation:
|
||||
|
||||
Edit `mygame/commands/default_cmdsets.py` and add
|
||||
`from contrib.multidesc import CmdMultiDesc` to the top.
|
||||
`from evennia.contrib.multidescer import CmdMultiDesc` to the top.
|
||||
|
||||
Next, look up the `at_cmdset_create` method of the `CharacterCmdSet`
|
||||
class and add a line `self.add(CmdMultiDesc())` to the end
|
||||
|
|
|
|||
|
|
@ -858,7 +858,7 @@ class CmdSay(RPCommand): # replaces standard say
|
|||
return
|
||||
|
||||
# calling the speech hook on the location
|
||||
speech = caller.location.at_say(caller, self.args)
|
||||
speech = caller.location.at_before_say(caller, self.args)
|
||||
# preparing the speech with sdesc/speech parsing.
|
||||
speech = "/me says, \"{speech}\"".format(speech=speech)
|
||||
targets = self.caller.location.contents
|
||||
|
|
|
|||
|
|
@ -822,10 +822,8 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
returns the new clone name on the form keyXX
|
||||
"""
|
||||
key = self.key
|
||||
num = 1
|
||||
for inum in (obj for obj in self.location.contents
|
||||
if obj.key.startswith(key) and obj.key.lstrip(key).isdigit()):
|
||||
num += 1
|
||||
num = sum(1 for obj in self.location.contents
|
||||
if obj.key.startswith(key) and obj.key.lstrip(key).isdigit())
|
||||
return "%s%03i" % (key, num)
|
||||
new_key = new_key or find_clone_key()
|
||||
return ObjectDB.objects.copy_object(self, new_key=new_key)
|
||||
|
|
@ -1205,7 +1203,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
|
||||
mapping.update({
|
||||
"object": self,
|
||||
"exit": exits[0] if exits else "somwhere",
|
||||
"exit": exits[0] if exits else "somewhere",
|
||||
"origin": location or "nowhere",
|
||||
"destination": destination or "nowhere",
|
||||
})
|
||||
|
|
@ -1562,7 +1560,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
a say. This is sent by the whisper command by default.
|
||||
Other verbal commands could use this hook in similar
|
||||
ways.
|
||||
receiver (Object): If set, this is a target for the say/whisper.
|
||||
receivers (Object or iterable): If set, this is the target or targets for the say/whisper.
|
||||
|
||||
Returns:
|
||||
message (str): The (possibly modified) text to be spoken.
|
||||
|
|
@ -1571,7 +1569,7 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
return message
|
||||
|
||||
def at_say(self, message, msg_self=None, msg_location=None,
|
||||
receiver=None, msg_receiver=None, mapping=None, **kwargs):
|
||||
receivers=None, msg_receivers=None, **kwargs):
|
||||
"""
|
||||
Display the actual say (or whisper) of self.
|
||||
|
||||
|
|
@ -1582,69 +1580,98 @@ class DefaultObject(with_metaclass(TypeclassBase, ObjectDB)):
|
|||
re-writing it completely.
|
||||
|
||||
Args:
|
||||
message (str): The text to be conveyed by self.
|
||||
msg_self (str, optional): The message to echo to self.
|
||||
message (str): The message to convey.
|
||||
msg_self (bool or str, optional): If boolean True, echo `message` to self. If a string,
|
||||
return that message. If False or unset, don't echo to self.
|
||||
msg_location (str, optional): The message to echo to self's location.
|
||||
receiver (Object, optional): An eventual receiver of the message
|
||||
receivers (Object or iterable, optional): An eventual receiver or receivers of the message
|
||||
(by default only used by whispers).
|
||||
msg_receiver(str, optional): Specific message for receiver only.
|
||||
mapping (dict, optional): Additional mapping in messages.
|
||||
msg_receivers(str): Specific message to pass to the receiver(s). This will parsed
|
||||
with the {receiver} placeholder replaced with the given receiver.
|
||||
Kwargs:
|
||||
whisper (bool): If this is a whisper rather than a say. Kwargs
|
||||
can be used by other verbal commands in a similar way.
|
||||
mapping (dict): Pass an additional mapping to the message.
|
||||
|
||||
Notes:
|
||||
|
||||
Messages can contain {} markers, which must
|
||||
If used, `msg_self`, `msg_receiver` and `msg_location` should contain
|
||||
references to other objects between braces, the way `location.msg_contents`
|
||||
would allow. For instance:
|
||||
|
||||
Messages can contain {} markers. These are substituted against the values
|
||||
passed in the `mapping` argument.
|
||||
|
||||
msg_self = 'You say: "{speech}"'
|
||||
msg_location = '{object} says: "{speech}"'
|
||||
msg_receiver = '{object} whispers: "{speech}"'
|
||||
msg_receivers = '{object} whispers: "{speech}"'
|
||||
|
||||
The following mappings can be used in both messages:
|
||||
object: the object speaking.
|
||||
location: the location where object is.
|
||||
speech: the text spoken by self.
|
||||
|
||||
You can use additional mappings if you want to add other
|
||||
information in your messages.
|
||||
Supported markers by default:
|
||||
{self}: text to self-reference with (default 'You')
|
||||
{speech}: the text spoken/whispered by self.
|
||||
{object}: the object speaking.
|
||||
{receiver}: replaced with a single receiver only for strings meant for a specific
|
||||
receiver (otherwise 'None').
|
||||
{all_receivers}: comma-separated list of all receivers,
|
||||
if more than one, otherwise same as receiver
|
||||
{location}: the location where object is.
|
||||
|
||||
"""
|
||||
msg_type = 'say'
|
||||
if kwargs.get("whisper", False):
|
||||
# whisper mode
|
||||
msg_self = msg_self or 'You whisper to {receiver}, "{speech}"|n'
|
||||
msg_receiver = msg_receiver or '{object} whispers: "{speech}"|n'
|
||||
msg_type = 'whisper'
|
||||
msg_self = '{self} whisper to {all_receivers}, "{speech}"' if msg_self is True else msg_self
|
||||
msg_receivers = '{object} whispers: "{speech}"'
|
||||
msg_location = None
|
||||
else:
|
||||
msg_self = msg_self or 'You say, "{speech}"|n'
|
||||
msg_receiver = None
|
||||
msg_location = msg_location or '{object} says, "{speech}"|n'
|
||||
msg_self = '{self} say, "{speech}"' if msg_self is True else msg_self
|
||||
msg_receivers = None
|
||||
msg_location = msg_location or '{object} says, "{speech}"'
|
||||
|
||||
mapping = mapping or {}
|
||||
mapping.update({
|
||||
"object": self,
|
||||
"location": self.location,
|
||||
"speech": message,
|
||||
"receiver": receiver
|
||||
})
|
||||
custom_mapping = kwargs.get('mapping', {})
|
||||
receivers = make_iter(receivers) if receivers else None
|
||||
location = self.location
|
||||
|
||||
if msg_self:
|
||||
self_mapping = {key: "yourself" if key == "receiver" and val is self
|
||||
else val.get_display_name(self) if hasattr(val, "get_display_name")
|
||||
else str(val) for key, val in mapping.items()}
|
||||
self.msg(msg_self.format(**self_mapping))
|
||||
self_mapping = {"self": "You",
|
||||
"object": self.get_display_name(self),
|
||||
"location": location.get_display_name(self) if location else None,
|
||||
"receiver": None,
|
||||
"all_receivers": ", ".join(
|
||||
recv.get_display_name(self)
|
||||
for recv in receivers) if receivers else None,
|
||||
"speech": message}
|
||||
self_mapping.update(custom_mapping)
|
||||
self.msg(text=(msg_self.format(**self_mapping), {"type": msg_type}))
|
||||
|
||||
if receiver and msg_receiver:
|
||||
receiver_mapping = {key: val.get_display_name(receiver)
|
||||
if hasattr(val, "get_display_name")
|
||||
else str(val) for key, val in mapping.items()}
|
||||
receiver.msg(msg_receiver.format(**receiver_mapping))
|
||||
if receivers and msg_receivers:
|
||||
receiver_mapping = {"self": "You",
|
||||
"object": None,
|
||||
"location": None,
|
||||
"receiver": None,
|
||||
"all_receivers": None,
|
||||
"speech": message}
|
||||
for receiver in make_iter(receivers):
|
||||
individual_mapping = {"object": self.get_display_name(receiver),
|
||||
"location": location.get_display_name(receiver),
|
||||
"receiver": receiver.get_display_name(receiver),
|
||||
"all_receivers": ", ".join(
|
||||
recv.get_display_name(recv)
|
||||
for recv in receivers) if receivers else None}
|
||||
receiver_mapping.update(individual_mapping)
|
||||
receiver_mapping.update(custom_mapping)
|
||||
receiver.msg(text=(msg_receivers.format(**receiver_mapping), {"type": msg_type}))
|
||||
|
||||
if self.location and msg_location:
|
||||
self.location.msg_contents(msg_location, exclude=(self, ),
|
||||
mapping=mapping)
|
||||
location_mapping = {"self": "You",
|
||||
"object": self,
|
||||
"location": location,
|
||||
"all_receivers": ", ".join(recv for recv in receivers) if receivers else None,
|
||||
"receiver": None,
|
||||
"speech": message}
|
||||
location_mapping.update(custom_mapping)
|
||||
self.location.msg_contents(text=(msg_location, {"type": msg_type}),
|
||||
from_obj=self,
|
||||
exclude=(self, ) if msg_self else None,
|
||||
mapping=location_mapping)
|
||||
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ from __future__ import unicode_literals
|
|||
|
||||
from django.db import migrations, connection
|
||||
|
||||
_ENGINE = None
|
||||
|
||||
def _table_exists(db_cursor, tablename):
|
||||
"Returns bool if table exists or not"
|
||||
|
|
@ -11,9 +12,25 @@ def _table_exists(db_cursor, tablename):
|
|||
|
||||
|
||||
def _drop_table(db_cursor, table_name):
|
||||
global _ENGINE
|
||||
if not _ENGINE:
|
||||
from django.conf import settings
|
||||
try:
|
||||
_ENGINE = settings.DATABASES["default"]["ENGINE"]
|
||||
except KeyError:
|
||||
_ENGINE = settings.DATABASE_ENGINE
|
||||
|
||||
if _table_exists(db_cursor, table_name):
|
||||
sql_drop = "DROP TABLE %s;" % table_name
|
||||
db_cursor.execute(sql_drop)
|
||||
if _ENGINE == "django.db.backends.mysql":
|
||||
db_cursor.execute("SET FOREIGN_KEY_CHECKS=0;")
|
||||
db_cursor.execute("DROP TABLE {table};".format(table=table_name))
|
||||
db_cursor.execute("SET FOREIGN_KEY_CHECKS=1;")
|
||||
elif _ENGINE == "postgresql_psycopg2":
|
||||
db_cursor.execute("ALTER TABLE {table} DISABLE TRIGGER ALL;".format(table=table_name))
|
||||
db_cursor.execute("DROP TABLE {table};".format(table=table_name))
|
||||
db_cursor.execute("ALTER TABLE {table} ENABLE TRIGGER ALL;".format(table=table_name))
|
||||
else: # sqlite3, other databases
|
||||
db_cursor.execute("DROP TABLE {table};".format(table=table_name))
|
||||
|
||||
|
||||
def drop_tables(apps, schema_migrator):
|
||||
|
|
@ -23,6 +40,9 @@ def drop_tables(apps, schema_migrator):
|
|||
_drop_table(db_cursor, "players_playerdb_db_tags")
|
||||
_drop_table(db_cursor, "players_playerdb_groups")
|
||||
_drop_table(db_cursor, "players_playerdb_user_permissions")
|
||||
_drop_table(db_cursor, "comms_msg_db_sender_players")
|
||||
_drop_table(db_cursor, "comms_msg_db_receivers_players")
|
||||
_drop_table(db_cursor, "comms_msg_db_hide_from_players")
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
|
|
|||
|
|
@ -674,8 +674,9 @@ class TypedObject(SharedMemoryModel):
|
|||
Displays the name of the object in a viewer-aware manner.
|
||||
|
||||
Args:
|
||||
looker (TypedObject): The object or account that is looking
|
||||
at/getting inforamtion for this object.
|
||||
looker (TypedObject, optional): The object or account that is looking
|
||||
at/getting inforamtion for this object. If not given, some
|
||||
'safe' minimum level should be returned.
|
||||
|
||||
Returns:
|
||||
name (str): A string containing the name of the object,
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ from django.conf import settings
|
|||
from evennia.utils import utils
|
||||
|
||||
_ENCODINGS = settings.ENCODINGS
|
||||
_RE_INSERT = re.compile(r"^\#INSERT (.*)", re.MULTILINE)
|
||||
_RE_INSERT = re.compile(r"^\#INSERT (.*)$", re.MULTILINE)
|
||||
_RE_CLEANBLOCK = re.compile(r"^\#.*?$|^\s*$", re.MULTILINE)
|
||||
_RE_CMD_SPLIT = re.compile(r"^\#.*?$", re.MULTILINE)
|
||||
_RE_CODE_OR_HEADER = re.compile(r"((?:\A|^)#CODE|(?:/A|^)#HEADER|\A)(.*?)$(.*?)(?=^#CODE.*?$|^#HEADER.*?$|\Z)",
|
||||
|
|
@ -273,15 +273,10 @@ class BatchCommandProcessor(object):
|
|||
|
||||
def replace_insert(match):
|
||||
"""Map replace entries"""
|
||||
return "\n#".join(self.parse_file(match.group(1)))
|
||||
return "\n#\n".join(self.parse_file(match.group(1)))
|
||||
|
||||
# insert commands from inserted files
|
||||
text = _RE_INSERT.sub(replace_insert, text)
|
||||
# re.sub(r"^\#INSERT (.*?)", replace_insert, text, flags=re.MULTILINE)
|
||||
# get all commands
|
||||
commands = _RE_CMD_SPLIT.split(text)
|
||||
# re.split(r"^\#.*?$", text, flags=re.MULTILINE)
|
||||
# remove eventual newline at the end of commands
|
||||
commands = [c.strip('\r\n') for c in commands]
|
||||
commands = [c for c in commands if c]
|
||||
|
||||
|
|
|
|||
|
|
@ -283,64 +283,64 @@ def parse_inlinefunc(string, strip=False, **kwargs):
|
|||
# no cached stack; build a new stack and continue
|
||||
stack = ParseStack()
|
||||
|
||||
# process string on stack
|
||||
ncallable = 0
|
||||
for match in _RE_TOKEN.finditer(string):
|
||||
gdict = match.groupdict()
|
||||
if gdict["singlequote"]:
|
||||
stack.append(gdict["singlequote"])
|
||||
elif gdict["doublequote"]:
|
||||
stack.append(gdict["doublequote"])
|
||||
elif gdict["end"]:
|
||||
if ncallable <= 0:
|
||||
stack.append(")")
|
||||
continue
|
||||
args = []
|
||||
while stack:
|
||||
operation = stack.pop()
|
||||
if callable(operation):
|
||||
if not strip:
|
||||
stack.append((operation, [arg for arg in reversed(args)]))
|
||||
ncallable -= 1
|
||||
break
|
||||
# process string on stack
|
||||
ncallable = 0
|
||||
for match in _RE_TOKEN.finditer(string):
|
||||
gdict = match.groupdict()
|
||||
if gdict["singlequote"]:
|
||||
stack.append(gdict["singlequote"])
|
||||
elif gdict["doublequote"]:
|
||||
stack.append(gdict["doublequote"])
|
||||
elif gdict["end"]:
|
||||
if ncallable <= 0:
|
||||
stack.append(")")
|
||||
continue
|
||||
args = []
|
||||
while stack:
|
||||
operation = stack.pop()
|
||||
if callable(operation):
|
||||
if not strip:
|
||||
stack.append((operation, [arg for arg in reversed(args)]))
|
||||
ncallable -= 1
|
||||
break
|
||||
else:
|
||||
args.append(operation)
|
||||
elif gdict["start"]:
|
||||
funcname = _RE_STARTTOKEN.match(gdict["start"]).group(1)
|
||||
try:
|
||||
# try to fetch the matching inlinefunc from storage
|
||||
stack.append(_INLINE_FUNCS[funcname])
|
||||
except KeyError:
|
||||
stack.append(_INLINE_FUNCS["nomatch"])
|
||||
stack.append(funcname)
|
||||
ncallable += 1
|
||||
elif gdict["escaped"]:
|
||||
# escaped tokens
|
||||
token = gdict["escaped"].lstrip("\\")
|
||||
stack.append(token)
|
||||
elif gdict["comma"]:
|
||||
if ncallable > 0:
|
||||
# commas outside strings and inside a callable are
|
||||
# used to mark argument separation - we use None
|
||||
# in the stack to indicate such a separation.
|
||||
stack.append(None)
|
||||
else:
|
||||
args.append(operation)
|
||||
elif gdict["start"]:
|
||||
funcname = _RE_STARTTOKEN.match(gdict["start"]).group(1)
|
||||
try:
|
||||
# try to fetch the matching inlinefunc from storage
|
||||
stack.append(_INLINE_FUNCS[funcname])
|
||||
except KeyError:
|
||||
stack.append(_INLINE_FUNCS["nomatch"])
|
||||
stack.append(funcname)
|
||||
ncallable += 1
|
||||
elif gdict["escaped"]:
|
||||
# escaped tokens
|
||||
token = gdict["escaped"].lstrip("\\")
|
||||
stack.append(token)
|
||||
elif gdict["comma"]:
|
||||
if ncallable > 0:
|
||||
# commas outside strings and inside a callable are
|
||||
# used to mark argument separation - we use None
|
||||
# in the stack to indicate such a separation.
|
||||
stack.append(None)
|
||||
# no callable active - just a string
|
||||
stack.append(",")
|
||||
else:
|
||||
# no callable active - just a string
|
||||
stack.append(",")
|
||||
# the rest
|
||||
stack.append(gdict["rest"])
|
||||
|
||||
if ncallable > 0:
|
||||
# this means not all inlinefuncs were complete
|
||||
return string
|
||||
|
||||
if _STACK_MAXSIZE > 0 and _STACK_MAXSIZE < len(stack):
|
||||
# if stack is larger than limit, throw away parsing
|
||||
return string + gdict["stackfull"](*args, **kwargs)
|
||||
else:
|
||||
# the rest
|
||||
stack.append(gdict["rest"])
|
||||
|
||||
if ncallable > 0:
|
||||
# this means not all inlinefuncs were complete
|
||||
return string
|
||||
|
||||
if _STACK_MAXSIZE > 0 and _STACK_MAXSIZE < len(stack):
|
||||
# if stack is larger than limit, throw away parsing
|
||||
return string + gdict["stackfull"](*args, **kwargs)
|
||||
else:
|
||||
# cache the stack
|
||||
_PARSING_CACHE[string] = stack
|
||||
# cache the stack
|
||||
_PARSING_CACHE[string] = stack
|
||||
|
||||
# run the stack recursively
|
||||
def _run_stack(item, depth=0):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue