mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
add mapping support, pronoun conjugation to actor stance callables
This commit is contained in:
parent
7f41e5a649
commit
f755f052d3
4 changed files with 119 additions and 24 deletions
|
|
@ -337,13 +337,17 @@ Here the `caller` is the one sending the message and `receiver` the one to see i
|
||||||
result of `you_obj.get_display_name(looker=receiver)`. This allows for a single string to echo differently
|
result of `you_obj.get_display_name(looker=receiver)`. This allows for a single string to echo differently
|
||||||
depending on who sees it, and also to reference other people in the same way.
|
depending on who sees it, and also to reference other people in the same way.
|
||||||
- `$You([key])` - same as `$you` but always capitalized.
|
- `$You([key])` - same as `$you` but always capitalized.
|
||||||
- `$conj(verb)` ([code](evennia.utils.funcparser.funcparser_callable_conjugate)) - conjugates a verb
|
- `$conj(verb [,key])` ([code](evennia.utils.funcparser.funcparser_callable_conjugate)) - conjugates a verb
|
||||||
between 2nd person presens to 3rd person presence depending on who
|
between 2nd person presence to 3rd person presence depending on who
|
||||||
sees the string. For example `"$You() $conj(smiles)".` will show as "You smile." and "Tom smiles." depending
|
sees the string. For example `"$You() $conj(smiles)".` will show as "You smile." and "Tom smiles." depending
|
||||||
on who sees it. This makes use of the tools in [evennia.utils.verb_conjugation](evennia.utils.verb_conjugation)
|
on who sees it. This makes use of the tools in [evennia.utils.verb_conjugation](evennia.utils.verb_conjugation)
|
||||||
to do this, and only works for English verbs.
|
to do this, and only works for English verbs.
|
||||||
- `$pron(pronoun [,options])` ([code](evennia.utils.funcparser.funcparser_callable_pronoun)) - Dynamically
|
- `$pron(pronoun [,options] [,key])` ([code](evennia.utils.funcparser.funcparser_callable_pronoun)) - Dynamically
|
||||||
map pronouns (like his, herself, you, its etc) between 1st/2nd person to 3rd person.
|
map pronouns (like his, herself, you, its etc) between 1st/2nd person to 3rd person.
|
||||||
|
- `$pconj(verb, [,key])` ([code](evennia.utils.funcparser.funcparser_callable_conjugate_for_pronouns)) - conjugates
|
||||||
|
a verb between 2nd and 3rd person, like `$conj`, but for pronouns instead of nouns to account for plural
|
||||||
|
gendering. For example `"$Pron(you) $pconj(smiles)"` will show to others as "He smiles" for a gender of "male", or
|
||||||
|
"They smile" for a gender of "plural".
|
||||||
|
|
||||||
|
|
||||||
### `evennia.prototypes.protfuncs`
|
### `evennia.prototypes.protfuncs`
|
||||||
|
|
|
||||||
|
|
@ -1320,15 +1320,18 @@ def funcparser_callable_your_capitalize(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def funcparser_callable_conjugate(*args, caller=None, receiver=None, **kwargs):
|
def funcparser_callable_conjugate(*args, caller=None, receiver=None, mapping=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage: $conj(word, [options])
|
Usage: $conj(word, [key])
|
||||||
|
|
||||||
Conjugate a verb according to if it should be 2nd or third person.
|
Conjugate a verb according to if it should be 2nd or third person.
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
caller (Object): The object who represents 'you' in the string.
|
caller (Object): The object who represents 'you' in the string.
|
||||||
receiver (Object): The recipient of the string.
|
receiver (Object): The recipient of the string.
|
||||||
|
mapping (dict, optional): This is a mapping `{key:Object, ...}` and is
|
||||||
|
used to find which object the optional `key` argument refers to. If not given,
|
||||||
|
the `caller` kwarg is used.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
str: The parsed string.
|
str: The parsed string.
|
||||||
|
|
@ -1337,13 +1340,10 @@ def funcparser_callable_conjugate(*args, caller=None, receiver=None, **kwargs):
|
||||||
ParsingError: If `you` and `recipient` were not both supplied.
|
ParsingError: If `you` and `recipient` were not both supplied.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
Note that the verb will not be capitalized. It also
|
Note that the verb will not be capitalized.
|
||||||
assumes that the active party (You) is the one performing the verb.
|
|
||||||
This automatic conjugation will fail if the active part is another person
|
|
||||||
than 'you'. The caller/receiver must be passed to the parser directly.
|
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
This is often used in combination with the $you/You( callables.
|
This is often used in combination with the $you/You callables.
|
||||||
|
|
||||||
- `With a grin, $you() $conj(jump)`
|
- `With a grin, $you() $conj(jump)`
|
||||||
|
|
||||||
|
|
@ -1356,14 +1356,76 @@ def funcparser_callable_conjugate(*args, caller=None, receiver=None, **kwargs):
|
||||||
if not (caller and receiver):
|
if not (caller and receiver):
|
||||||
raise ParsingError("No caller/receiver supplied to $conj callable")
|
raise ParsingError("No caller/receiver supplied to $conj callable")
|
||||||
|
|
||||||
second_person_str, third_person_str = verb_actor_stance_components(args[0])
|
verb, *options = args
|
||||||
return second_person_str if caller == receiver else third_person_str
|
obj = caller
|
||||||
|
if mapping and options:
|
||||||
|
# get the correct referenced object from the mapping, or fall back to caller
|
||||||
|
obj = mapping.get(options[0], caller)
|
||||||
|
|
||||||
|
second_person_str, third_person_str = verb_actor_stance_components(verb)
|
||||||
|
return second_person_str if obj == receiver else third_person_str
|
||||||
|
|
||||||
|
|
||||||
def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=False, **kwargs):
|
def funcparser_callable_conjugate_for_pronouns(*args, caller=None, receiver=None, mapping=None, **kwargs):
|
||||||
|
"""
|
||||||
|
Usage: $pconj(word, [key])
|
||||||
|
|
||||||
|
Conjugate a verb according to if it should be 2nd or third person, respecting the
|
||||||
|
singular/plural gendering for third person.
|
||||||
|
|
||||||
|
Keyword Args:
|
||||||
|
caller (Object): The object who represents 'you' in the string.
|
||||||
|
receiver (Object): The recipient of the string.
|
||||||
|
mapping (dict, optional): This is a mapping `{key:Object, ...}` and is
|
||||||
|
used to find which object the optional `key` argument refers to. If not given,
|
||||||
|
the `caller` kwarg is used.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: The parsed string.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ParsingError: If `you` and `recipient` were not both supplied.
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
Note that the verb will not be capitalized.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
This is often used in combination with the $pron/Pron callables.
|
||||||
|
|
||||||
|
- `With a grin, $pron(you) $pconj(jump)`
|
||||||
|
|
||||||
|
You will see "With a grin, you jump."
|
||||||
|
With your gender as "male", others will see "With a grin, he jumps."
|
||||||
|
With your gender as "plural", others will see "With a grin, they jump."
|
||||||
|
|
||||||
|
"""
|
||||||
|
if not args:
|
||||||
|
return ""
|
||||||
|
if not (caller and receiver):
|
||||||
|
raise ParsingError("No caller/receiver supplied to $conj callable")
|
||||||
|
|
||||||
|
verb, *options = args
|
||||||
|
obj = caller
|
||||||
|
if mapping and options:
|
||||||
|
# get the correct referenced object from the mapping, or fall back to caller
|
||||||
|
obj = mapping.get(options[0], caller)
|
||||||
|
|
||||||
|
# identify whether the 3rd person form should be singular or plural
|
||||||
|
plural = False
|
||||||
|
if hasattr(obj, "gender"):
|
||||||
|
if callable(obj.gender):
|
||||||
|
plural = (obj.gender() == "plural")
|
||||||
|
else:
|
||||||
|
plural = (obj.gender == "plural")
|
||||||
|
|
||||||
|
second_person_str, third_person_str = verb_actor_stance_components(verb, plural=plural)
|
||||||
|
return second_person_str if obj == receiver else third_person_str
|
||||||
|
|
||||||
|
|
||||||
|
def funcparser_callable_pronoun(*args, caller=None, receiver=None, mapping=None, capitalize=False, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
Usage: $pron(word, [options])
|
Usage: $pron(word, [options], [key])
|
||||||
|
|
||||||
Adjust pronouns to the expected form. Pronouns are words you use instead of a
|
Adjust pronouns to the expected form. Pronouns are words you use instead of a
|
||||||
proper name, such as 'him', 'herself', 'theirs' etc. These look different
|
proper name, such as 'him', 'herself', 'theirs' etc. These look different
|
||||||
|
|
@ -1424,6 +1486,9 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
||||||
- `1st person`/`1st`/`1`
|
- `1st person`/`1st`/`1`
|
||||||
- `2nd person`/`2nd`/`2`
|
- `2nd person`/`2nd`/`2`
|
||||||
- `3rd person`/`3rd`/`3`
|
- `3rd person`/`3rd`/`3`
|
||||||
|
key (str, optional): If a mapping is provided, a string defining which object to
|
||||||
|
reference when finding the correct pronoun. If not provided, it defaults
|
||||||
|
to `caller`
|
||||||
|
|
||||||
Keyword Args:
|
Keyword Args:
|
||||||
|
|
||||||
|
|
@ -1435,6 +1500,9 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
||||||
receiver (Object): The recipient of the string. This being the same as
|
receiver (Object): The recipient of the string. This being the same as
|
||||||
`caller` or not helps determine 2nd vs 3rd-person forms. This is
|
`caller` or not helps determine 2nd vs 3rd-person forms. This is
|
||||||
provided automatically by the funcparser.
|
provided automatically by the funcparser.
|
||||||
|
mapping (dict, optional): This is a mapping `{key:Object, ...}` and is
|
||||||
|
used to find which object the optional `key` argument refers to. If not given,
|
||||||
|
the `caller` kwarg is used.
|
||||||
capitalize (bool): The input retains its capitalization. If this is set the output is
|
capitalize (bool): The input retains its capitalization. If this is set the output is
|
||||||
always capitalized.
|
always capitalized.
|
||||||
|
|
||||||
|
|
@ -1457,8 +1525,17 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
||||||
"""
|
"""
|
||||||
if not args:
|
if not args:
|
||||||
return ""
|
return ""
|
||||||
|
# by default, we use the caller as the object being referred to
|
||||||
|
obj = caller
|
||||||
|
|
||||||
pronoun, *options = args
|
pronoun, *options = args
|
||||||
|
if options and mapping:
|
||||||
|
# check if the last argument is a valid mapping key
|
||||||
|
if options[-1] in mapping:
|
||||||
|
# get the object and remove the key from options
|
||||||
|
obj = mapping[options[-1]]
|
||||||
|
options = options[:-1]
|
||||||
|
|
||||||
# options is either multiple args or a space-separated string
|
# options is either multiple args or a space-separated string
|
||||||
if len(options) == 1:
|
if len(options) == 1:
|
||||||
options = options[0]
|
options = options[0]
|
||||||
|
|
@ -1468,11 +1545,11 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
||||||
default_gender = "neutral"
|
default_gender = "neutral"
|
||||||
default_viewpoint = "2nd person"
|
default_viewpoint = "2nd person"
|
||||||
|
|
||||||
if hasattr(caller, "gender"):
|
if hasattr(obj, "gender"):
|
||||||
if callable(caller.gender):
|
if callable(obj.gender):
|
||||||
default_gender = caller.gender()
|
default_gender = obj.gender()
|
||||||
else:
|
else:
|
||||||
default_gender = caller.gender
|
default_gender = obj.gender
|
||||||
|
|
||||||
if "viewpoint" in kwargs:
|
if "viewpoint" in kwargs:
|
||||||
# passed into FuncParser initialization
|
# passed into FuncParser initialization
|
||||||
|
|
@ -1490,7 +1567,7 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
||||||
pronoun_1st_or_2nd_person = pronoun_1st_or_2nd_person.capitalize()
|
pronoun_1st_or_2nd_person = pronoun_1st_or_2nd_person.capitalize()
|
||||||
pronoun_3rd_person = pronoun_3rd_person.capitalize()
|
pronoun_3rd_person = pronoun_3rd_person.capitalize()
|
||||||
|
|
||||||
return pronoun_1st_or_2nd_person if caller == receiver else pronoun_3rd_person
|
return pronoun_1st_or_2nd_person if obj == receiver else pronoun_3rd_person
|
||||||
|
|
||||||
|
|
||||||
def funcparser_callable_pronoun_capitalize(
|
def funcparser_callable_pronoun_capitalize(
|
||||||
|
|
@ -1557,6 +1634,7 @@ ACTOR_STANCE_CALLABLES = {
|
||||||
"obj": funcparser_callable_you,
|
"obj": funcparser_callable_you,
|
||||||
"Obj": funcparser_callable_you_capitalize,
|
"Obj": funcparser_callable_you_capitalize,
|
||||||
"conj": funcparser_callable_conjugate,
|
"conj": funcparser_callable_conjugate,
|
||||||
|
"pconj": funcparser_callable_conjugate_for_pronouns,
|
||||||
"pron": funcparser_callable_pronoun,
|
"pron": funcparser_callable_pronoun,
|
||||||
"Pron": funcparser_callable_pronoun_capitalize,
|
"Pron": funcparser_callable_pronoun_capitalize,
|
||||||
**FUNCPARSER_CALLABLES,
|
**FUNCPARSER_CALLABLES,
|
||||||
|
|
|
||||||
|
|
@ -435,6 +435,7 @@ class TestDefaultCallables(TestCase):
|
||||||
("$You() $conj(smile) at him.", "You smile at him.", "Char1 smiles at him."),
|
("$You() $conj(smile) at him.", "You smile at him.", "Char1 smiles at him."),
|
||||||
("$You() $conj(smile) at $You(char1).", "You smile at You.", "Char1 smiles at Char1."),
|
("$You() $conj(smile) at $You(char1).", "You smile at You.", "Char1 smiles at Char1."),
|
||||||
("$You() $conj(smile) at $You(char2).", "You smile at Char2.", "Char1 smiles at You."),
|
("$You() $conj(smile) at $You(char2).", "You smile at Char2.", "Char1 smiles at You."),
|
||||||
|
("$You() $conj(smile) while $You(char2) $conj(waves, char2).", "You smile while Char2 waves.", "Char1 smiles while You wave."),
|
||||||
(
|
(
|
||||||
"$You(char2) $conj(smile) at $you(char1).",
|
"$You(char2) $conj(smile) at $you(char1).",
|
||||||
"Char2 smile at you.",
|
"Char2 smile at you.",
|
||||||
|
|
@ -512,6 +513,15 @@ class TestDefaultCallables(TestCase):
|
||||||
ret = self.parser.parse(string, caller=self.obj1, raise_errors=True)
|
ret = self.parser.parse(string, caller=self.obj1, raise_errors=True)
|
||||||
self.assertEqual(expected, ret)
|
self.assertEqual(expected, ret)
|
||||||
|
|
||||||
|
def test_pronoun_mapping(self):
|
||||||
|
self.obj1.gender = "female"
|
||||||
|
self.obj2.gender = "male"
|
||||||
|
|
||||||
|
string = "Char1 raises $pron(your, char1) fist as Char2 raises $pron(yours, char2)"
|
||||||
|
expected = "Char1 raises her fist as Char2 raises his"
|
||||||
|
ret = self.parser.parse(string, caller=self.obj1, mapping={'char1': self.obj1, 'char2': self.obj2}, raise_errors=True)
|
||||||
|
self.assertEqual(expected, ret)
|
||||||
|
|
||||||
def test_pronoun_viewpoint(self):
|
def test_pronoun_viewpoint(self):
|
||||||
string = "Char1 smiles at $pron(I)"
|
string = "Char1 smiles at $pron(I)"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -365,25 +365,28 @@ def verb_is_past_participle(verb):
|
||||||
return tense == "past participle"
|
return tense == "past participle"
|
||||||
|
|
||||||
|
|
||||||
def verb_actor_stance_components(verb):
|
def verb_actor_stance_components(verb, plural=False):
|
||||||
"""
|
"""
|
||||||
Figure out actor stance components of a verb.
|
Figure out actor stance components of a verb.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
verb (str): The verb to analyze
|
verb (str): The verb to analyze
|
||||||
|
plural (bool): Whether to force 3rd person to plural form
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
tuple: The 2nd person (you) and 3rd person forms of the verb,
|
tuple: The 2nd person (you) and 3rd person forms of the verb,
|
||||||
in the same tense as the ingoing verb.
|
in the same tense as the ingoing verb.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
tense = verb_tense(verb)
|
tense = verb_tense(verb)
|
||||||
|
them = "*" if plural else "3"
|
||||||
|
them_suff = "" if plural else "s"
|
||||||
|
|
||||||
if "participle" in tense or "plural" in tense:
|
if "participle" in tense or "plural" in tense:
|
||||||
return (verb, verb)
|
return (verb, verb)
|
||||||
if tense == "infinitive" or "present" in tense:
|
if tense == "infinitive" or "present" in tense:
|
||||||
you_str = verb_present(verb, person="2") or verb
|
you_str = verb_present(verb, person="2") or verb
|
||||||
them_str = verb_present(verb, person="3") or verb + "s"
|
them_str = verb_present(verb, person=them) or verb + them_suff
|
||||||
else:
|
else:
|
||||||
you_str = verb_past(verb, person="2") or verb
|
you_str = verb_past(verb, person="2") or verb
|
||||||
them_str = verb_past(verb, person="3") or verb + "s"
|
them_str = verb_past(verb, person=them) or verb + them_suff
|
||||||
return (you_str, them_str)
|
return (you_str, them_str)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue