mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
Merge pull request #3514 from InspectorCaracal/funcparser-pron-targets
Adds support for mapping keys, pronoun-verb agreement to actor stance callables
This commit is contained in:
commit
01783bd376
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
|
||||
depending on who sees it, and also to reference other people in the same way.
|
||||
- `$You([key])` - same as `$you` but always capitalized.
|
||||
- `$conj(verb)` ([code](evennia.utils.funcparser.funcparser_callable_conjugate)) - conjugates a verb
|
||||
between 2nd person presens to 3rd person presence depending on who
|
||||
- `$conj(verb [,key])` ([code](evennia.utils.funcparser.funcparser_callable_conjugate)) - conjugates a verb
|
||||
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
|
||||
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.
|
||||
- `$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.
|
||||
- `$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`
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
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.
|
||||
|
|
@ -1337,13 +1340,10 @@ def funcparser_callable_conjugate(*args, caller=None, receiver=None, **kwargs):
|
|||
ParsingError: If `you` and `recipient` were not both supplied.
|
||||
|
||||
Notes:
|
||||
Note that the verb will not be capitalized. It also
|
||||
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.
|
||||
|
||||
Note that the verb will not be capitalized.
|
||||
|
||||
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)`
|
||||
|
||||
|
|
@ -1356,14 +1356,76 @@ def funcparser_callable_conjugate(*args, caller=None, receiver=None, **kwargs):
|
|||
if not (caller and receiver):
|
||||
raise ParsingError("No caller/receiver supplied to $conj callable")
|
||||
|
||||
second_person_str, third_person_str = verb_actor_stance_components(args[0])
|
||||
return second_person_str if caller == receiver else third_person_str
|
||||
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)
|
||||
|
||||
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
|
||||
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`
|
||||
- `2nd person`/`2nd`/`2`
|
||||
- `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:
|
||||
|
||||
|
|
@ -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
|
||||
`caller` or not helps determine 2nd vs 3rd-person forms. This is
|
||||
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
|
||||
always capitalized.
|
||||
|
||||
|
|
@ -1457,8 +1525,17 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
|||
"""
|
||||
if not args:
|
||||
return ""
|
||||
# by default, we use the caller as the object being referred to
|
||||
obj = caller
|
||||
|
||||
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
|
||||
if len(options) == 1:
|
||||
options = options[0]
|
||||
|
|
@ -1468,11 +1545,11 @@ def funcparser_callable_pronoun(*args, caller=None, receiver=None, capitalize=Fa
|
|||
default_gender = "neutral"
|
||||
default_viewpoint = "2nd person"
|
||||
|
||||
if hasattr(caller, "gender"):
|
||||
if callable(caller.gender):
|
||||
default_gender = caller.gender()
|
||||
if hasattr(obj, "gender"):
|
||||
if callable(obj.gender):
|
||||
default_gender = obj.gender()
|
||||
else:
|
||||
default_gender = caller.gender
|
||||
default_gender = obj.gender
|
||||
|
||||
if "viewpoint" in kwargs:
|
||||
# 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_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(
|
||||
|
|
@ -1557,6 +1634,7 @@ ACTOR_STANCE_CALLABLES = {
|
|||
"obj": funcparser_callable_you,
|
||||
"Obj": funcparser_callable_you_capitalize,
|
||||
"conj": funcparser_callable_conjugate,
|
||||
"pconj": funcparser_callable_conjugate_for_pronouns,
|
||||
"pron": funcparser_callable_pronoun,
|
||||
"Pron": funcparser_callable_pronoun_capitalize,
|
||||
**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 $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) while $You(char2) $conj(waves, char2).", "You smile while Char2 waves.", "Char1 smiles while You wave."),
|
||||
(
|
||||
"$You(char2) $conj(smile) at $you(char1).",
|
||||
"Char2 smile at you.",
|
||||
|
|
@ -512,6 +513,15 @@ class TestDefaultCallables(TestCase):
|
|||
ret = self.parser.parse(string, caller=self.obj1, raise_errors=True)
|
||||
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):
|
||||
string = "Char1 smiles at $pron(I)"
|
||||
|
||||
|
|
|
|||
|
|
@ -365,25 +365,28 @@ def verb_is_past_participle(verb):
|
|||
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.
|
||||
|
||||
Args:
|
||||
verb (str): The verb to analyze
|
||||
plural (bool): Whether to force 3rd person to plural form
|
||||
|
||||
Returns:
|
||||
tuple: The 2nd person (you) and 3rd person forms of the verb,
|
||||
in the same tense as the ingoing verb.
|
||||
|
||||
"""
|
||||
tense = verb_tense(verb)
|
||||
them = "*" if plural else "3"
|
||||
them_suff = "" if plural else "s"
|
||||
|
||||
if "participle" in tense or "plural" in tense:
|
||||
return (verb, verb)
|
||||
if tense == "infinitive" or "present" in tense:
|
||||
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:
|
||||
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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue