evennia/docs/1.0-dev/_modules/evennia/utils/funcparser.html
Evennia docbuilder action 70b4caedb6 Updated HTML docs
2022-06-22 06:30:53 +00:00

1509 lines
No EOL
151 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.utils.funcparser &#8212; Evennia 1.0-dev documentation</title>
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/jquery.js"></script>
<script src="../../../_static/underscore.js"></script>
<script src="../../../_static/doctools.js"></script>
<script src="../../../_static/language_data.js"></script>
<link rel="shortcut icon" href="../../../_static/favicon.ico"/>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../evennia.html" accesskey="U">evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.utils.funcparser</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.utils.funcparser</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Generic function parser for functions embedded in a string, on the form</span>
<span class="sd">`$funcname(*args, **kwargs)`, for example:</span>
<span class="sd">```</span>
<span class="sd">&quot;A string $foo() with $bar(a, b, c, $moo(), d=23) etc.&quot;</span>
<span class="sd">```</span>
<span class="sd">Each arg/kwarg can also be another nested function. These will be executed</span>
<span class="sd">inside-out and their return will used as arguments for the enclosing function</span>
<span class="sd">(so the same as for regular Python function execution).</span>
<span class="sd">This is the base for all forms of embedded func-parsing, like inlinefuncs and</span>
<span class="sd">protfuncs. Each function available to use must be registered as a &#39;safe&#39;</span>
<span class="sd">function for the parser to accept it. This is usually done in a module with</span>
<span class="sd">regular Python functions on the form:</span>
<span class="sd">```python</span>
<span class="sd"># in a module whose path is passed to the parser</span>
<span class="sd">def _helper(x):</span>
<span class="sd"> # use underscore to NOT make the function available as a callable</span>
<span class="sd">def funcname(*args, **kwargs):</span>
<span class="sd"> # this can be accessed as $funcname(*args, **kwargs)</span>
<span class="sd"> # it must always accept *args and **kwargs.</span>
<span class="sd"> ...</span>
<span class="sd"> return something</span>
<span class="sd">```</span>
<span class="sd">Usage:</span>
<span class="sd">```python</span>
<span class="sd">from evennia.utils.funcparser import FuncParser</span>
<span class="sd">parser = FuncParser(&quot;path.to.module_with_callables&quot;)</span>
<span class="sd">result = parser.parse(&quot;String with $funcname() in it&quot;)</span>
<span class="sd">```</span>
<span class="sd">The `FuncParser` also accepts a direct dict mapping of `{&#39;name&#39;: callable, ...}`.</span>
<span class="sd">---</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">dataclasses</span>
<span class="kn">import</span> <span class="nn">inspect</span>
<span class="kn">import</span> <span class="nn">random</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</span>
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="p">(</span>
<span class="n">make_iter</span><span class="p">,</span>
<span class="n">callables_from_module</span><span class="p">,</span>
<span class="n">variable_from_module</span><span class="p">,</span>
<span class="n">pad</span><span class="p">,</span>
<span class="n">crop</span><span class="p">,</span>
<span class="n">justify</span><span class="p">,</span>
<span class="n">safe_convert_to_types</span><span class="p">,</span>
<span class="p">)</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">search</span>
<span class="kn">from</span> <span class="nn">evennia.utils.verb_conjugation.conjugate</span> <span class="kn">import</span> <span class="n">verb_actor_stance_components</span>
<span class="kn">from</span> <span class="nn">evennia.utils.verb_conjugation.pronouns</span> <span class="kn">import</span> <span class="n">pronoun_to_viewpoints</span>
<span class="c1"># setup</span>
<span class="n">_CLIENT_DEFAULT_WIDTH</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CLIENT_DEFAULT_WIDTH</span>
<span class="n">_MAX_NESTING</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">FUNCPARSER_MAX_NESTING</span>
<span class="n">_START_CHAR</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">FUNCPARSER_START_CHAR</span>
<span class="n">_ESCAPE_CHAR</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">FUNCPARSER_ESCAPE_CHAR</span>
<span class="nd">@dataclasses</span><span class="o">.</span><span class="n">dataclass</span>
<span class="k">class</span> <span class="nc">_ParsedFunc</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Represents a function parsed from the string</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">prefix</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">_START_CHAR</span>
<span class="n">funcname</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">args</span><span class="p">:</span> <span class="nb">list</span> <span class="o">=</span> <span class="n">dataclasses</span><span class="o">.</span><span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">list</span><span class="p">)</span>
<span class="n">kwargs</span><span class="p">:</span> <span class="nb">dict</span> <span class="o">=</span> <span class="n">dataclasses</span><span class="o">.</span><span class="n">field</span><span class="p">(</span><span class="n">default_factory</span><span class="o">=</span><span class="nb">dict</span><span class="p">)</span>
<span class="c1"># state storage</span>
<span class="n">fullstr</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">infuncstr</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">single_quoted</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">double_quoted</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">current_kwarg</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">open_lparens</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">open_lsquate</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">open_lcurly</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">funcname</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">args</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">kwargs</span>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fullstr</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">infuncstr</span>
<div class="viewcode-block" id="ParsingError"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.ParsingError">[docs]</a><span class="k">class</span> <span class="nc">ParsingError</span><span class="p">(</span><span class="ne">RuntimeError</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Failed to parse for some reason.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<div class="viewcode-block" id="FuncParser"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser">[docs]</a><span class="k">class</span> <span class="nc">FuncParser</span><span class="p">:</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Sets up a parser for strings containing `$funcname(*args, **kwargs)`</span>
<span class="sd"> substrings.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="FuncParser.__init__"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">callables</span><span class="p">,</span>
<span class="n">start_char</span><span class="o">=</span><span class="n">_START_CHAR</span><span class="p">,</span>
<span class="n">escape_char</span><span class="o">=</span><span class="n">_ESCAPE_CHAR</span><span class="p">,</span>
<span class="n">max_nesting</span><span class="o">=</span><span class="n">_MAX_NESTING</span><span class="p">,</span>
<span class="o">**</span><span class="n">default_kwargs</span><span class="p">,</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Initialize the parser.</span>
<span class="sd"> Args:</span>
<span class="sd"> callables (str, module, list or dict): Where to find</span>
<span class="sd"> &#39;safe&#39; functions to make available in the parser. If a `dict`,</span>
<span class="sd"> it should be a direct mapping `{&quot;funcname&quot;: callable, ...}`. If</span>
<span class="sd"> one or mode modules or module-paths, the module(s) are first checked</span>
<span class="sd"> for a dict `FUNCPARSER_CALLABLES = {&quot;funcname&quot;, callable, ...}`. If</span>
<span class="sd"> no such variable exists, all callables in the module (whose name does</span>
<span class="sd"> not start with an underscore) will be made available to the parser.</span>
<span class="sd"> start_char (str, optional): A character used to identify the beginning</span>
<span class="sd"> of a parseable function. Default is `$`.</span>
<span class="sd"> escape_char (str, optional): Prepend characters with this to have</span>
<span class="sd"> them not count as a function. Default is the backtick, `\\\\`.</span>
<span class="sd"> max_nesting (int, optional): How many levels of nested function calls</span>
<span class="sd"> are allowed, to avoid exploitation. Default is 20.</span>
<span class="sd"> **default_kwargs: These kwargs will be passed into all callables. These</span>
<span class="sd"> kwargs can be overridden both by kwargs passed direcetly to `.parse` *and*</span>
<span class="sd"> by kwargs given directly in the string `$funcname` call. They are</span>
<span class="sd"> suitable for global defaults that is intended to be changed by the</span>
<span class="sd"> user. To guarantee a call always gets a particular kwarg, pass it</span>
<span class="sd"> into `.parse` as `**reserved_kwargs` instead.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">callables</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
<span class="n">loaded_callables</span> <span class="o">=</span> <span class="p">{</span><span class="o">**</span><span class="n">callables</span><span class="p">}</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># load all modules/paths in sequence. Later-added will override</span>
<span class="c1"># earlier same-named callables (allows for overriding evennia defaults)</span>
<span class="n">loaded_callables</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">module_or_path</span> <span class="ow">in</span> <span class="n">make_iter</span><span class="p">(</span><span class="n">callables</span><span class="p">):</span>
<span class="n">callables_mapping</span> <span class="o">=</span> <span class="n">variable_from_module</span><span class="p">(</span>
<span class="n">module_or_path</span><span class="p">,</span> <span class="n">variable</span><span class="o">=</span><span class="s2">&quot;FUNCPARSER_CALLABLES&quot;</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">callables_mapping</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># mapping supplied in variable</span>
<span class="n">loaded_callables</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">callables_mapping</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Failure to parse - </span><span class="si">{</span><span class="n">module_or_path</span><span class="si">}</span><span class="s2">.FUNCPARSER_CALLABLES &quot;</span>
<span class="s2">&quot;(must be a dict {&#39;funcname&#39;: callable, ...})&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># use all top-level variables</span>
<span class="c1"># (handles both paths and module instances</span>
<span class="n">loaded_callables</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">callables_from_module</span><span class="p">(</span><span class="n">module_or_path</span><span class="p">))</span>
<span class="bp">self</span><span class="o">.</span><span class="n">validate_callables</span><span class="p">(</span><span class="n">loaded_callables</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">callables</span> <span class="o">=</span> <span class="n">loaded_callables</span>
<span class="bp">self</span><span class="o">.</span><span class="n">escape_char</span> <span class="o">=</span> <span class="n">escape_char</span>
<span class="bp">self</span><span class="o">.</span><span class="n">start_char</span> <span class="o">=</span> <span class="n">start_char</span>
<span class="bp">self</span><span class="o">.</span><span class="n">default_kwargs</span> <span class="o">=</span> <span class="n">default_kwargs</span></div>
<div class="viewcode-block" id="FuncParser.validate_callables"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser.validate_callables">[docs]</a> <span class="k">def</span> <span class="nf">validate_callables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">callables</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate the loaded callables. Each callable must support at least</span>
<span class="sd"> `funcname(*args, **kwargs)`.</span>
<span class="sd"> property.</span>
<span class="sd"> Args:</span>
<span class="sd"> callables (dict): A mapping `{&quot;funcname&quot;: callable, ...}` to validate</span>
<span class="sd"> Raise:</span>
<span class="sd"> AssertionError: If invalid callable was found.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This is also a good method to override for individual parsers</span>
<span class="sd"> needing to run any particular pre-checks.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">for</span> <span class="n">funcname</span><span class="p">,</span> <span class="n">clble</span> <span class="ow">in</span> <span class="n">callables</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">mapping</span> <span class="o">=</span> <span class="n">inspect</span><span class="o">.</span><span class="n">getfullargspec</span><span class="p">(</span><span class="n">clble</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Could not run getfullargspec on </span><span class="si">{</span><span class="n">funcname</span><span class="si">}</span><span class="s2">: </span><span class="si">{</span><span class="n">clble</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">assert</span> <span class="n">mapping</span><span class="o">.</span><span class="n">varargs</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Parse-func callable &#39;</span><span class="si">{</span><span class="n">funcname</span><span class="si">}</span><span class="s2">&#39; does not support *args.&quot;</span>
<span class="k">assert</span> <span class="n">mapping</span><span class="o">.</span><span class="n">varkw</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&quot;Parse-func callable &#39;</span><span class="si">{</span><span class="n">funcname</span><span class="si">}</span><span class="s2">&#39; does not support **kwargs.&quot;</span></div>
<div class="viewcode-block" id="FuncParser.execute"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser.execute">[docs]</a> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">parsedfunc</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">reserved_kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Execute a parsed function</span>
<span class="sd"> Args:</span>
<span class="sd"> parsedfunc (_ParsedFunc): This dataclass holds the parsed details</span>
<span class="sd"> of the function.</span>
<span class="sd"> raise_errors (bool, optional): Raise errors. Otherwise return the</span>
<span class="sd"> string with the function unparsed.</span>
<span class="sd"> **reserved_kwargs: These kwargs are _guaranteed_ to always be passed into</span>
<span class="sd"> the callable on every call. It will override any default kwargs</span>
<span class="sd"> _and_ also a same-named kwarg given manually in the $funcname</span>
<span class="sd"> call. This is often used by Evennia to pass required data into</span>
<span class="sd"> the callable, for example the current Session for inlinefuncs.</span>
<span class="sd"> Returns:</span>
<span class="sd"> any: The result of the execution. If this is a nested function, it</span>
<span class="sd"> can be anything, otherwise it will be converted to a string later.</span>
<span class="sd"> Always a string on un-raised error (the unparsed function string).</span>
<span class="sd"> Raises:</span>
<span class="sd"> ParsingError, any: A `ParsingError` if the function could not be</span>
<span class="sd"> found, otherwise error from function definition. Only raised if</span>
<span class="sd"> `raise_errors` is `True`</span>
<span class="sd"> Notes:</span>
<span class="sd"> The kwargs passed into the callable will be a mixture of the</span>
<span class="sd"> `default_kwargs` passed into `FuncParser.__init__`, kwargs given</span>
<span class="sd"> directly in the `$funcdef` string, and the `reserved_kwargs` this</span>
<span class="sd"> function gets from `.parse()`. For colliding keys, funcdef-defined</span>
<span class="sd"> kwargs will override default kwargs while reserved kwargs will always</span>
<span class="sd"> override the other two.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">funcname</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">parsedfunc</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
<span class="n">func</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">callables</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">funcname</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">func</span><span class="p">:</span>
<span class="k">if</span> <span class="n">raise_errors</span><span class="p">:</span>
<span class="n">available</span> <span class="o">=</span> <span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;&#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39;&quot;</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">callables</span><span class="p">)</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;Unknown parsed function &#39;</span><span class="si">{</span><span class="nb">str</span><span class="p">(</span><span class="n">parsedfunc</span><span class="p">)</span><span class="si">}</span><span class="s2">&#39; &quot;</span> <span class="sa">f</span><span class="s2">&quot;(available: </span><span class="si">{</span><span class="n">available</span><span class="si">}</span><span class="s2">)&quot;</span>
<span class="p">)</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">parsedfunc</span><span class="p">)</span>
<span class="c1"># build kwargs in the proper priority order</span>
<span class="n">kwargs</span> <span class="o">=</span> <span class="p">{</span>
<span class="o">**</span><span class="bp">self</span><span class="o">.</span><span class="n">default_kwargs</span><span class="p">,</span>
<span class="o">**</span><span class="n">kwargs</span><span class="p">,</span>
<span class="o">**</span><span class="n">reserved_kwargs</span><span class="p">,</span>
<span class="o">**</span><span class="p">{</span><span class="s2">&quot;funcparser&quot;</span><span class="p">:</span> <span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;raise_errors&quot;</span><span class="p">:</span> <span class="n">raise_errors</span><span class="p">},</span>
<span class="p">}</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">ret</span> <span class="o">=</span> <span class="n">func</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">return</span> <span class="n">ret</span>
<span class="k">except</span> <span class="n">ParsingError</span><span class="p">:</span>
<span class="k">if</span> <span class="n">raise_errors</span><span class="p">:</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">parsedfunc</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">if</span> <span class="n">raise_errors</span><span class="p">:</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">parsedfunc</span><span class="p">)</span></div>
<div class="viewcode-block" id="FuncParser.parse"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">string</span><span class="p">,</span>
<span class="n">raise_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">escape</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">strip</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">return_str</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
<span class="o">**</span><span class="n">reserved_kwargs</span><span class="p">,</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Use parser to parse a string that may or may not have</span>
<span class="sd"> `$funcname(*args, **kwargs)` - style tokens in it. Only the callables</span>
<span class="sd"> used to initiate the parser will be eligible for parsing.</span>
<span class="sd"> Args:</span>
<span class="sd"> string (str): The string to parse.</span>
<span class="sd"> raise_errors (bool, optional): By default, a failing parse just</span>
<span class="sd"> means not parsing the string but leaving it as-is. If this is</span>
<span class="sd"> `True`, errors (like not closing brackets) will lead to an</span>
<span class="sd"> ParsingError.</span>
<span class="sd"> escape (bool, optional): If set, escape all found functions so they</span>
<span class="sd"> are not executed by later parsing.</span>
<span class="sd"> strip (bool, optional): If set, strip any inline funcs from string</span>
<span class="sd"> as if they were not there.</span>
<span class="sd"> return_str (bool, optional): If set (default), always convert the</span>
<span class="sd"> parse result to a string, otherwise return the result of the</span>
<span class="sd"> latest called inlinefunc (if called separately).</span>
<span class="sd"> **reserved_kwargs: If given, these are guaranteed to _always_ pass</span>
<span class="sd"> as part of each parsed callable&#39;s **kwargs. These override</span>
<span class="sd"> same-named default options given in `__init__` as well as any</span>
<span class="sd"> same-named kwarg given in the string function. This is because</span>
<span class="sd"> it is often used by Evennia to pass necessary kwargs into each</span>
<span class="sd"> callable (like the current Session object for inlinefuncs).</span>
<span class="sd"> Returns:</span>
<span class="sd"> str or any: The parsed string, or the same string on error (if</span>
<span class="sd"> `raise_errors` is `False`). This is always a string</span>
<span class="sd"> Raises:</span>
<span class="sd"> ParsingError: If a problem is encountered and `raise_errors` is True.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">start_char</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">start_char</span>
<span class="n">escape_char</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">escape_char</span>
<span class="c1"># replace e.g. $$ with \$ so we only need to handle one escape method</span>
<span class="n">string</span> <span class="o">=</span> <span class="n">string</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">start_char</span> <span class="o">+</span> <span class="n">start_char</span><span class="p">,</span> <span class="n">escape_char</span> <span class="o">+</span> <span class="n">start_char</span><span class="p">)</span>
<span class="c1"># parsing state</span>
<span class="n">callstack</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">single_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">double_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">open_lparens</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># open (</span>
<span class="n">open_lsquare</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># open [</span>
<span class="n">open_lcurly</span> <span class="o">=</span> <span class="mi">0</span> <span class="c1"># open {</span>
<span class="n">escaped</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">current_kwarg</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">curr_func</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">fullstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> <span class="c1"># final string</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span> <span class="c1"># string parts inside the current level of $funcdef (including $)</span>
<span class="n">literal_infuncstr</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">string</span><span class="p">:</span>
<span class="k">if</span> <span class="n">escaped</span><span class="p">:</span>
<span class="c1"># always store escaped characters verbatim</span>
<span class="k">if</span> <span class="n">curr_func</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">fullstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="n">escaped</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="n">escape_char</span><span class="p">:</span>
<span class="c1"># don&#39;t store the escape-char itself</span>
<span class="n">escaped</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="n">start_char</span><span class="p">:</span>
<span class="c1"># start a new function definition (not escaped as $$)</span>
<span class="k">if</span> <span class="n">curr_func</span><span class="p">:</span>
<span class="c1"># we are starting a nested funcdef</span>
<span class="n">return_str</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">callstack</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">_MAX_NESTING</span><span class="p">:</span>
<span class="c1"># stack full - ignore this function</span>
<span class="k">if</span> <span class="n">raise_errors</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span>
<span class="s2">&quot;Only allows for parsing nesting function defs &quot;</span>
<span class="sa">f</span><span class="s2">&quot;to a max depth of </span><span class="si">{</span><span class="n">_MAX_NESTING</span><span class="si">}</span><span class="s2">.&quot;</span>
<span class="p">)</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="k">continue</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># store state for the current func and stack it</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">current_kwarg</span> <span class="o">=</span> <span class="n">current_kwarg</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">infuncstr</span> <span class="o">=</span> <span class="n">infuncstr</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">single_quoted</span> <span class="o">=</span> <span class="n">single_quoted</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">double_quoted</span> <span class="o">=</span> <span class="n">double_quoted</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">open_lparens</span> <span class="o">=</span> <span class="n">open_lparens</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">open_lsquare</span> <span class="o">=</span> <span class="n">open_lsquare</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">open_lcurly</span> <span class="o">=</span> <span class="n">open_lcurly</span>
<span class="n">current_kwarg</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">single_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">double_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="n">open_lparens</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">open_lsquare</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">open_lcurly</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">literal_infuncstr</span> <span class="o">=</span> <span class="kc">False</span>
<span class="n">callstack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">curr_func</span><span class="p">)</span>
<span class="c1"># start a new func</span>
<span class="n">curr_func</span> <span class="o">=</span> <span class="n">_ParsedFunc</span><span class="p">(</span><span class="n">prefix</span><span class="o">=</span><span class="n">char</span><span class="p">,</span> <span class="n">fullstr</span><span class="o">=</span><span class="n">char</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">curr_func</span><span class="p">:</span>
<span class="c1"># a normal piece of string</span>
<span class="n">fullstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="c1"># this must always be a string</span>
<span class="n">return_str</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">continue</span>
<span class="c1"># in a function def (can be nested)</span>
<span class="k">if</span> <span class="n">exec_return</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span> <span class="ow">and</span> <span class="n">char</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;,=)&quot;</span><span class="p">):</span>
<span class="c1"># if exec_return is followed by any other character</span>
<span class="c1"># than one demarking an arg,kwarg or function-end</span>
<span class="c1"># it must immediately merge as a string</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">exec_return</span><span class="p">)</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;&#39;&quot;</span> <span class="ow">and</span> <span class="n">double_quoted</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span> <span class="c1"># note that this is the same as &quot;\&#39;&quot;</span>
<span class="c1"># a single quote - flip status</span>
<span class="k">if</span> <span class="n">single_quoted</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">single_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">elif</span> <span class="n">single_quoted</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">single_quoted</span><span class="p">]</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">prefix</span> <span class="o">+</span> <span class="n">infuncstr</span><span class="p">[</span><span class="n">single_quoted</span> <span class="o">+</span> <span class="mi">1</span> <span class="p">:]</span>
<span class="n">single_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">single_quoted</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">infuncstr</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">literal_infuncstr</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s1">&#39;&quot;&#39;</span> <span class="ow">and</span> <span class="n">single_quoted</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span> <span class="c1"># note that this is the same as &#39;\&quot;&#39;</span>
<span class="c1"># a double quote = flip status</span>
<span class="k">if</span> <span class="n">double_quoted</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">double_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">elif</span> <span class="n">double_quoted</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="n">prefix</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="n">double_quoted</span><span class="p">]</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">prefix</span> <span class="o">+</span> <span class="n">infuncstr</span><span class="p">[</span><span class="n">double_quoted</span> <span class="o">+</span> <span class="mi">1</span> <span class="p">:]</span>
<span class="n">double_quoted</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">double_quoted</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">infuncstr</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<span class="n">literal_infuncstr</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">double_quoted</span> <span class="o">&gt;=</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">single_quoted</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># inside a string definition - this escapes everything else</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="k">continue</span>
<span class="c1"># special characters detected inside function def</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;(&quot;</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">funcname</span><span class="p">:</span>
<span class="c1"># end of a funcdef name</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">funcname</span> <span class="o">=</span> <span class="n">infuncstr</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">fullstr</span> <span class="o">+=</span> <span class="n">infuncstr</span> <span class="o">+</span> <span class="n">char</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># just a random left-parenthesis</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="c1"># track the open left-parenthesis</span>
<span class="n">open_lparens</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="ow">in</span> <span class="s2">&quot;[]&quot;</span><span class="p">:</span>
<span class="c1"># a square bracket - start/end of a list?</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="n">open_lsquare</span> <span class="o">+=</span> <span class="o">-</span><span class="mi">1</span> <span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;]&quot;</span> <span class="k">else</span> <span class="mi">1</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="ow">in</span> <span class="s2">&quot;</span><span class="si">{}</span><span class="s2">&quot;</span><span class="p">:</span>
<span class="c1"># a curly bracket - start/end of dict/set?</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="n">open_lcurly</span> <span class="o">+=</span> <span class="o">-</span><span class="mi">1</span> <span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;}&quot;</span> <span class="k">else</span> <span class="mi">1</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;=&quot;</span><span class="p">:</span>
<span class="c1"># beginning of a keyword argument</span>
<span class="k">if</span> <span class="n">exec_return</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">exec_return</span>
<span class="n">current_kwarg</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">kwargs</span><span class="p">[</span><span class="n">current_kwarg</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">fullstr</span> <span class="o">+=</span> <span class="n">infuncstr</span> <span class="o">+</span> <span class="n">char</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">char</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;,)&quot;</span><span class="p">):</span>
<span class="c1"># commas and right-parens may indicate arguments ending</span>
<span class="k">if</span> <span class="n">open_lparens</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># one open left-parens is ok (beginning of arglist), more</span>
<span class="c1"># indicate we are inside an unclosed, nested (, so</span>
<span class="c1"># we need to not count this as a new arg or end of funcdef.</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="n">open_lparens</span> <span class="o">-=</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;)&quot;</span> <span class="k">else</span> <span class="mi">0</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">open_lcurly</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">open_lsquare</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<span class="c1"># also escape inside an open [... or {... structure</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">exec_return</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
<span class="c1"># store the execution return as-received</span>
<span class="k">if</span> <span class="n">current_kwarg</span><span class="p">:</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">kwargs</span><span class="p">[</span><span class="n">current_kwarg</span><span class="p">]</span> <span class="o">=</span> <span class="n">exec_return</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">exec_return</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">literal_infuncstr</span><span class="p">:</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">infuncstr</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="c1"># store a string instead</span>
<span class="k">if</span> <span class="n">current_kwarg</span><span class="p">:</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">kwargs</span><span class="p">[</span><span class="n">current_kwarg</span><span class="p">]</span> <span class="o">=</span> <span class="n">infuncstr</span>
<span class="k">elif</span> <span class="n">literal_infuncstr</span> <span class="ow">or</span> <span class="n">infuncstr</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span>
<span class="c1"># don&#39;t store the empty string</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">args</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">infuncstr</span><span class="p">)</span>
<span class="c1"># note that at this point either exec_return or infuncstr will</span>
<span class="c1"># be empty. We need to store the full string so we can print</span>
<span class="c1"># it &#39;raw&#39; in case this funcdef turns out to e.g. lack an</span>
<span class="c1"># ending paranthesis</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">fullstr</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">exec_return</span><span class="p">)</span> <span class="o">+</span> <span class="n">infuncstr</span> <span class="o">+</span> <span class="n">char</span>
<span class="n">current_kwarg</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">literal_infuncstr</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">char</span> <span class="o">==</span> <span class="s2">&quot;)&quot;</span><span class="p">:</span>
<span class="c1"># closing the function list - this means we have a</span>
<span class="c1"># ready function-def to run.</span>
<span class="n">open_lparens</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">if</span> <span class="n">strip</span><span class="p">:</span>
<span class="c1"># remove function as if it returned empty</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">elif</span> <span class="n">escape</span><span class="p">:</span>
<span class="c1"># get function and set it as escaped</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="n">escape_char</span> <span class="o">+</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">fullstr</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># execute the function - the result may be a string or</span>
<span class="c1"># something else</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
<span class="n">curr_func</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="n">raise_errors</span><span class="p">,</span> <span class="o">**</span><span class="n">reserved_kwargs</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">callstack</span><span class="p">:</span>
<span class="c1"># unnest the higher-level funcdef from stack</span>
<span class="c1"># and continue where we were</span>
<span class="n">curr_func</span> <span class="o">=</span> <span class="n">callstack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">current_kwarg</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">current_kwarg</span>
<span class="k">if</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">infuncstr</span><span class="p">:</span>
<span class="c1"># if we have an ongoing string, we must merge the</span>
<span class="c1"># exec into this as a part of that string</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">infuncstr</span> <span class="o">+</span> <span class="nb">str</span><span class="p">(</span><span class="n">exec_return</span><span class="p">)</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">curr_func</span><span class="o">.</span><span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">single_quoted</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">single_quoted</span>
<span class="n">double_quoted</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">double_quoted</span>
<span class="n">open_lparens</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">open_lparens</span>
<span class="n">open_lsquare</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">open_lsquare</span>
<span class="n">open_lcurly</span> <span class="o">=</span> <span class="n">curr_func</span><span class="o">.</span><span class="n">open_lcurly</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># back to the top-level string - this means the</span>
<span class="c1"># exec_return should always be converted to a string.</span>
<span class="n">curr_func</span> <span class="o">=</span> <span class="kc">None</span>
<span class="n">fullstr</span> <span class="o">+=</span> <span class="nb">str</span><span class="p">(</span><span class="n">exec_return</span><span class="p">)</span>
<span class="k">if</span> <span class="n">return_str</span><span class="p">:</span>
<span class="n">exec_return</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="n">literal_infuncstr</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">continue</span>
<span class="n">infuncstr</span> <span class="o">+=</span> <span class="n">char</span>
<span class="k">if</span> <span class="n">curr_func</span><span class="p">:</span>
<span class="c1"># if there is a still open funcdef or defs remaining in callstack,</span>
<span class="c1"># these are malformed (no closing bracket) and we should get their</span>
<span class="c1"># strings as-is.</span>
<span class="n">callstack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">curr_func</span><span class="p">)</span>
<span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">callstack</span><span class="p">)):</span>
<span class="n">infuncstr</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">callstack</span><span class="o">.</span><span class="n">pop</span><span class="p">())</span> <span class="o">+</span> <span class="n">infuncstr</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">return_str</span> <span class="ow">and</span> <span class="n">exec_return</span> <span class="o">!=</span> <span class="s2">&quot;&quot;</span><span class="p">:</span>
<span class="c1"># return explicit return</span>
<span class="k">return</span> <span class="n">exec_return</span>
<span class="c1"># add the last bit to the finished string</span>
<span class="n">fullstr</span> <span class="o">+=</span> <span class="n">infuncstr</span>
<span class="k">return</span> <span class="n">fullstr</span></div>
<div class="viewcode-block" id="FuncParser.parse_to_any"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser.parse_to_any">[docs]</a> <span class="k">def</span> <span class="nf">parse_to_any</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">string</span><span class="p">,</span> <span class="n">raise_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">reserved_kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This parses a string and if the string only contains a &quot;$func(...)&quot;,</span>
<span class="sd"> the return will be the return value of that function, even if it&#39;s not</span>
<span class="sd"> a string. If mixed in with other strings, the result will still always</span>
<span class="sd"> be a string.</span>
<span class="sd"> Args:</span>
<span class="sd"> string (str): The string to parse.</span>
<span class="sd"> raise_errors (bool, optional): If unset, leave a failing (or</span>
<span class="sd"> unrecognized) inline function as unparsed in the string. If set,</span>
<span class="sd"> raise an ParsingError.</span>
<span class="sd"> **reserved_kwargs: If given, these are guaranteed to _always_ pass</span>
<span class="sd"> as part of each parsed callable&#39;s **kwargs. These override</span>
<span class="sd"> same-named default options given in `__init__` as well as any</span>
<span class="sd"> same-named kwarg given in the string function. This is because</span>
<span class="sd"> it is often used by Evennia to pass necessary kwargs into each</span>
<span class="sd"> callable (like the current Session object for inlinefuncs).</span>
<span class="sd"> Returns:</span>
<span class="sd"> any: The return from the callable. Or string if the callable is not</span>
<span class="sd"> given alone in the string.</span>
<span class="sd"> Raises:</span>
<span class="sd"> ParsingError: If a problem is encountered and `raise_errors` is True.</span>
<span class="sd"> Notes:</span>
<span class="sd"> This is a convenience wrapper for `self.parse(..., return_str=False)` which</span>
<span class="sd"> accomplishes the same thing.</span>
<span class="sd"> Examples:</span>
<span class="sd"> ::</span>
<span class="sd"> from ast import literal_eval</span>
<span class="sd"> from evennia.utils.funcparser import FuncParser</span>
<span class="sd"> def ret1(*args, **kwargs):</span>
<span class="sd"> return 1</span>
<span class="sd"> parser = FuncParser({&quot;lit&quot;: lit})</span>
<span class="sd"> assert parser.parse_to_any(&quot;$ret1()&quot; == 1</span>
<span class="sd"> assert parser.parse_to_any(&quot;$ret1() and text&quot; == &#39;1 and text&#39;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">parse</span><span class="p">(</span>
<span class="n">string</span><span class="p">,</span>
<span class="n">raise_errors</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">escape</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">strip</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="n">return_str</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span>
<span class="o">**</span><span class="n">reserved_kwargs</span><span class="p">,</span>
<span class="p">)</span></div></div>
<span class="c1">#</span>
<span class="c1"># Default funcparser callables. These are made available from this module&#39;s</span>
<span class="c1"># FUNCPARSER_CALLABLES.</span>
<span class="c1">#</span>
<div class="viewcode-block" id="funcparser_callable_eval"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_eval">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_eval</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Funcparser callable. This will combine safe evaluations to try to parse the</span>
<span class="sd"> incoming string into a python object. If it fails, the return will be same</span>
<span class="sd"> as the input.</span>
<span class="sd"> Args:</span>
<span class="sd"> string (str): The string to parse. Only simple literals or operators are allowed.</span>
<span class="sd"> Returns:</span>
<span class="sd"> any: The string parsed into its Python form, or the same as input.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - `$py(1) -&gt; 1`</span>
<span class="sd"> - `$py([1,2,3,4] -&gt; [1, 2, 3]`</span>
<span class="sd"> - `$py(3 + 4) -&gt; 7`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">safe_convert_to_types</span><span class="p">((</span><span class="s2">&quot;py&quot;</span><span class="p">,</span> <span class="p">{}),</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">return</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">args</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="funcparser_callable_toint"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_toint">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_toint</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Usage: toint(43.0) -&gt; 43&quot;&quot;&quot;</span>
<span class="n">inp</span> <span class="o">=</span> <span class="n">funcparser_callable_eval</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">inp</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="k">return</span> <span class="n">inp</span></div>
<span class="k">def</span> <span class="nf">_apply_operation_two_elements</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">operator</span><span class="o">=</span><span class="s2">&quot;+&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper operating on two arguments</span>
<span class="sd"> Args:</span>
<span class="sd"> val1 (any): First value to operate on.</span>
<span class="sd"> val2 (any): Second value to operate on.</span>
<span class="sd"> Return:</span>
<span class="sd"> any: The result of val1 + val2. Values must be</span>
<span class="sd"> valid simple Python structures possible to add,</span>
<span class="sd"> such as numbers, lists etc. The $eval is usually</span>
<span class="sd"> better for non-list arithmetic.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">safe_convert_to_types</span><span class="p">(((</span><span class="s2">&quot;py&quot;</span><span class="p">,</span> <span class="s2">&quot;py&quot;</span><span class="p">),</span> <span class="p">{}),</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">val1</span><span class="p">,</span> <span class="n">val2</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">args</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">operator</span> <span class="o">==</span> <span class="s2">&quot;+&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">val1</span> <span class="o">+</span> <span class="n">val2</span>
<span class="k">elif</span> <span class="n">operator</span> <span class="o">==</span> <span class="s2">&quot;-&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">val1</span> <span class="o">-</span> <span class="n">val2</span>
<span class="k">elif</span> <span class="n">operator</span> <span class="o">==</span> <span class="s2">&quot;*&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">val1</span> <span class="o">*</span> <span class="n">val2</span>
<span class="k">elif</span> <span class="n">operator</span> <span class="o">==</span> <span class="s2">&quot;/&quot;</span><span class="p">:</span>
<span class="k">return</span> <span class="n">val1</span> <span class="o">/</span> <span class="n">val2</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;raise_errors&quot;</span><span class="p">):</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<div class="viewcode-block" id="funcparser_callable_add"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_add">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_add</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Usage: `$add(val1, val2) -&gt; val1 + val2`&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">_apply_operation_two_elements</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">operator</span><span class="o">=</span><span class="s2">&quot;+&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_sub"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_sub">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_sub</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Usage: ``$sub(val1, val2) -&gt; val1 - val2`&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">_apply_operation_two_elements</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">operator</span><span class="o">=</span><span class="s2">&quot;-&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_mult"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_mult">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_mult</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Usage: `$mult(val1, val2) -&gt; val1 * val2`&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">_apply_operation_two_elements</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">operator</span><span class="o">=</span><span class="s2">&quot;*&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_div"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_div">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_div</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Usage: `$mult(val1, val2) -&gt; val1 / val2`&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">_apply_operation_two_elements</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">operator</span><span class="o">=</span><span class="s2">&quot;/&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_round"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_round">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_round</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Funcparser callable. Rounds an incoming float to a</span>
<span class="sd"> certain number of significant digits.</span>
<span class="sd"> Args:</span>
<span class="sd"> inp (str or number): If a string, it will attempt</span>
<span class="sd"> to be converted to a number first.</span>
<span class="sd"> significant (int): The number of significant digits. Default is None -</span>
<span class="sd"> this will turn the result into an int.</span>
<span class="sd"> Returns:</span>
<span class="sd"> any: The rounded value or inp if inp was not a number.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - `$round(3.5434343, 3) -&gt; 3.543`</span>
<span class="sd"> - `$round($random(), 2)` - rounds random result, e.g `0.22`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">safe_convert_to_types</span><span class="p">(((</span><span class="nb">float</span><span class="p">,</span> <span class="nb">int</span><span class="p">),</span> <span class="p">{}),</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">num</span><span class="p">,</span> <span class="o">*</span><span class="n">significant</span> <span class="o">=</span> <span class="n">args</span>
<span class="n">significant</span> <span class="o">=</span> <span class="n">significant</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">significant</span> <span class="k">else</span> <span class="mi">0</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">round</span><span class="p">(</span><span class="n">num</span><span class="p">,</span> <span class="n">significant</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;raise_errors&quot;</span><span class="p">):</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="funcparser_callable_random"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_random">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_random</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Funcparser callable. Returns a random number between 0 and 1, from 0 to a</span>
<span class="sd"> maximum value, or within a given range (inclusive).</span>
<span class="sd"> Args:</span>
<span class="sd"> minval (str, optional): Minimum value. If not given, assumed 0.</span>
<span class="sd"> maxval (str, optional): Maximum value.</span>
<span class="sd"> Notes:</span>
<span class="sd"> If either of the min/maxvalue has a &#39;.&#39; in it, a floating-point random</span>
<span class="sd"> value will be returned. Otherwise it will be an</span>
<span class="sd"> integer value in the given range.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - `$random()` - random value [0 .. 1) (float).</span>
<span class="sd"> - `$random(5)` - random value [0..5] (int)</span>
<span class="sd"> - `$random(5.0)` - random value [0..5] (float)</span>
<span class="sd"> - `$random(5, 10)` - random value [5..10] (int)</span>
<span class="sd"> - `$random(5, 10.0)` - random value [5..10] (float)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">safe_convert_to_types</span><span class="p">(((</span><span class="s2">&quot;py&quot;</span><span class="p">,</span> <span class="s2">&quot;py&quot;</span><span class="p">),</span> <span class="p">{}),</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="n">nargs</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span>
<span class="k">if</span> <span class="n">nargs</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># only maxval given</span>
<span class="n">minval</span><span class="p">,</span> <span class="n">maxval</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">elif</span> <span class="n">nargs</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">minval</span><span class="p">,</span> <span class="n">maxval</span> <span class="o">=</span> <span class="n">args</span><span class="p">[:</span><span class="mi">2</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">minval</span><span class="p">,</span> <span class="n">maxval</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">minval</span><span class="p">,</span> <span class="nb">float</span><span class="p">)</span> <span class="ow">or</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">maxval</span><span class="p">,</span> <span class="nb">float</span><span class="p">):</span>
<span class="k">return</span> <span class="n">minval</span> <span class="o">+</span> <span class="p">((</span><span class="n">maxval</span> <span class="o">-</span> <span class="n">minval</span><span class="p">)</span> <span class="o">*</span> <span class="n">random</span><span class="o">.</span><span class="n">random</span><span class="p">())</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="n">minval</span><span class="p">,</span> <span class="n">maxval</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;raise_errors&quot;</span><span class="p">):</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="funcparser_callable_randint"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_randint">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_randint</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $randint(start, end):</span>
<span class="sd"> Legacy alias - always returns integers.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">funcparser_callable_random</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">))</span></div>
<div class="viewcode-block" id="funcparser_callable_choice"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_choice">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_choice</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> FuncParser callable. Picks a random choice from a list.</span>
<span class="sd"> Args:</span>
<span class="sd"> listing (list): A list of items to randomly choose between.</span>
<span class="sd"> This will be converted from a string to a real list.</span>
<span class="sd"> Returns:</span>
<span class="sd"> any: The randomly chosen element.</span>
<span class="sd"> Example:</span>
<span class="sd"> - `$choice([key, flower, house])`</span>
<span class="sd"> - `$choice([1, 2, 3, 4])`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="n">safe_convert_to_types</span><span class="p">((</span><span class="s2">&quot;py&quot;</span><span class="p">,</span> <span class="p">{}),</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="n">random</span><span class="o">.</span><span class="n">choice</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="k">if</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;raise_errors&quot;</span><span class="p">):</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span></div>
<div class="viewcode-block" id="funcparser_callable_pad"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_pad">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_pad</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> FuncParser callable. Pads text to given width, optionally with fill-characters</span>
<span class="sd"> Args:</span>
<span class="sd"> text (str): Text to pad.</span>
<span class="sd"> width (int): Width of padding.</span>
<span class="sd"> align (str, optional): Alignment of padding; one of &#39;c&#39;, &#39;l&#39; or &#39;r&#39;.</span>
<span class="sd"> fillchar (str, optional): Character used for padding. Defaults to a space.</span>
<span class="sd"> Example:</span>
<span class="sd"> - `$pad(text, 12, r, &#39; &#39;) -&gt; &quot; text&quot;`</span>
<span class="sd"> - `$pad(text, width=12, align=c, fillchar=-) -&gt; &quot;----text----&quot;`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span> <span class="o">=</span> <span class="n">safe_convert_to_types</span><span class="p">(</span>
<span class="p">((</span><span class="nb">str</span><span class="p">,</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">),</span> <span class="p">{</span><span class="s2">&quot;width&quot;</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="s2">&quot;align&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="s2">&quot;fillchar&quot;</span><span class="p">:</span> <span class="nb">str</span><span class="p">}),</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span>
<span class="n">text</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span> <span class="o">=</span> <span class="n">args</span>
<span class="n">nrest</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;width&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">nrest</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">_CLIENT_DEFAULT_WIDTH</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="n">_CLIENT_DEFAULT_WIDTH</span>
<span class="n">align</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;align&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">nrest</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">&quot;c&quot;</span><span class="p">)</span>
<span class="n">fillchar</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;fillchar&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="n">nrest</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">else</span> <span class="s2">&quot; &quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">align</span> <span class="ow">not</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;c&quot;</span><span class="p">,</span> <span class="s2">&quot;l&quot;</span><span class="p">,</span> <span class="s2">&quot;r&quot;</span><span class="p">):</span>
<span class="n">align</span> <span class="o">=</span> <span class="s2">&quot;c&quot;</span>
<span class="k">return</span> <span class="n">pad</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">),</span> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="n">align</span><span class="p">,</span> <span class="n">fillchar</span><span class="o">=</span><span class="n">fillchar</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_crop"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_crop">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_crop</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> FuncParser callable. Crops ingoing text to given widths.</span>
<span class="sd"> Args:</span>
<span class="sd"> text (str, optional): Text to crop.</span>
<span class="sd"> width (str, optional): Will be converted to an integer. Width of</span>
<span class="sd"> crop in characters.</span>
<span class="sd"> suffix (str, optional): End string to mark the fact that a part</span>
<span class="sd"> of the string was cropped. Defaults to `[...]`.</span>
<span class="sd"> Example:</span>
<span class="sd"> - `$crop(A long text, 10, [...]) -&gt; &quot;A lon[...]&quot;`</span>
<span class="sd"> - `$crop(text, width=11, suffix=&#39;[...]) -&gt; &quot;A long[...]&quot;`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">text</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span> <span class="o">=</span> <span class="n">args</span>
<span class="n">nrest</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;width&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">nrest</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">_CLIENT_DEFAULT_WIDTH</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="n">_CLIENT_DEFAULT_WIDTH</span>
<span class="n">suffix</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;suffix&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">nrest</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">&quot;[...]&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">crop</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">),</span> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span> <span class="n">suffix</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">suffix</span><span class="p">))</span></div>
<div class="viewcode-block" id="funcparser_callable_space"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_space">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_space</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwarg</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $space(43)</span>
<span class="sd"> Insert a length of space.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">return</span> <span class="s2">&quot; &quot;</span> <span class="o">*</span> <span class="n">width</span></div>
<div class="viewcode-block" id="funcparser_callable_justify"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_justify">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Justify text across a width, default across screen width.</span>
<span class="sd"> Args:</span>
<span class="sd"> text (str): Text to justify.</span>
<span class="sd"> width (int, optional): Defaults to default screen width.</span>
<span class="sd"> align (str, optional): One of &#39;l&#39;, &#39;c&#39;, &#39;r&#39; or &#39;f&#39; for &#39;full&#39;.</span>
<span class="sd"> indent (int, optional): Intendation of text block, if any.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The justified text.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - `$just(text, width=40)`</span>
<span class="sd"> - `$just(text, align=r, indent=2)`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">text</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span> <span class="o">=</span> <span class="n">args</span>
<span class="n">lrest</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;width&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">lrest</span> <span class="o">&gt;</span> <span class="mi">0</span> <span class="k">else</span> <span class="n">_CLIENT_DEFAULT_WIDTH</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">width</span> <span class="o">=</span> <span class="n">_CLIENT_DEFAULT_WIDTH</span>
<span class="n">align</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;align&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="k">if</span> <span class="n">lrest</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">&quot;f&quot;</span><span class="p">))</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">indent</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;indent&quot;</span><span class="p">,</span> <span class="n">rest</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">if</span> <span class="n">lrest</span> <span class="o">&gt;</span> <span class="mi">2</span> <span class="k">else</span> <span class="mi">0</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">TypeError</span><span class="p">:</span>
<span class="n">indent</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">return</span> <span class="n">justify</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">text</span><span class="p">),</span> <span class="n">width</span><span class="o">=</span><span class="n">width</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="n">align</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="n">indent</span><span class="p">)</span></div>
<span class="c1"># legacy for backwards compatibility</span>
<div class="viewcode-block" id="funcparser_callable_left_justify"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_left_justify">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_left_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="s2">&quot;Usage: $ljust(text)&quot;</span>
<span class="k">return</span> <span class="n">funcparser_callable_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;l&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_right_justify"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_right_justify">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_right_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="s2">&quot;Usage: $rjust(text)&quot;</span>
<span class="k">return</span> <span class="n">funcparser_callable_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;r&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_center_justify"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_center_justify">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_center_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="s2">&quot;Usage: $cjust(text)&quot;</span>
<span class="k">return</span> <span class="n">funcparser_callable_justify</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">align</span><span class="o">=</span><span class="s2">&quot;c&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_clr"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_clr">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_clr</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> FuncParser callable. Colorizes nested text.</span>
<span class="sd"> Args:</span>
<span class="sd"> startclr (str, optional): An ANSI color abbreviation without the</span>
<span class="sd"> prefix `|`, such as `r` (red foreground) or `[r` (red background).</span>
<span class="sd"> text (str, optional): Text</span>
<span class="sd"> endclr (str, optional): The color to use at the end of the string. Defaults</span>
<span class="sd"> to `|n` (reset-color).</span>
<span class="sd"> Kwargs:</span>
<span class="sd"> color (str, optional): If given,</span>
<span class="sd"> Example:</span>
<span class="sd"> - `$clr(r, text, n) -&gt; &quot;|rtext|n&quot;`</span>
<span class="sd"> - `$clr(r, text) -&gt; &quot;|rtext|n`</span>
<span class="sd"> - `$clr(text, start=r, end=n) -&gt; &quot;|rtext|n&quot;`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">startclr</span><span class="p">,</span> <span class="n">text</span><span class="p">,</span> <span class="n">endclr</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
<span class="c1"># $clr(pre, text, post))</span>
<span class="n">startclr</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span> <span class="o">=</span> <span class="n">args</span>
<span class="k">if</span> <span class="n">rest</span><span class="p">:</span>
<span class="n">text</span><span class="p">,</span> <span class="o">*</span><span class="n">endclr</span> <span class="o">=</span> <span class="n">rest</span>
<span class="k">if</span> <span class="n">endclr</span><span class="p">:</span>
<span class="n">endclr</span> <span class="o">=</span> <span class="n">endclr</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># $clr(text, start=pre, end=post)</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">startclr</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;start&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">endclr</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;end&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="n">startclr</span> <span class="o">=</span> <span class="s2">&quot;|&quot;</span> <span class="o">+</span> <span class="n">startclr</span> <span class="k">if</span> <span class="n">startclr</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span>
<span class="n">endclr</span> <span class="o">=</span> <span class="s2">&quot;|&quot;</span> <span class="o">+</span> <span class="n">endclr</span> <span class="k">if</span> <span class="n">endclr</span> <span class="k">else</span> <span class="p">(</span><span class="s2">&quot;|n&quot;</span> <span class="k">if</span> <span class="n">startclr</span> <span class="k">else</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">startclr</span><span class="si">}{</span><span class="n">text</span><span class="si">}{</span><span class="n">endclr</span><span class="si">}</span><span class="s2">&quot;</span></div>
<div class="viewcode-block" id="funcparser_callable_search"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_search">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_search</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">access</span><span class="o">=</span><span class="s2">&quot;control&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> FuncParser callable. Finds an object based on name or #dbref. Note that</span>
<span class="sd"> this requries the parser be called with the caller&#39;s Session for proper</span>
<span class="sd"> security. If called without session, the call is aborted.</span>
<span class="sd"> Args:</span>
<span class="sd"> query (str): The key or dbref to search for.</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> return_list (bool): If set, return a list of objects with</span>
<span class="sd"> 0, 1 or more matches to `query`. Defaults to False.</span>
<span class="sd"> type (str): One of &#39;obj&#39;, &#39;account&#39;, &#39;script&#39;</span>
<span class="sd"> caller (Entity): Supplied to Parser. This is required and will</span>
<span class="sd"> be passed into the access check for the entity being searched for.</span>
<span class="sd"> The &#39;control&#39; permission is required.</span>
<span class="sd"> access (str): Which locktype access to check. Unset to disable the</span>
<span class="sd"> security check.</span>
<span class="sd"> Returns:</span>
<span class="sd"> any: An entity match or None if no match or a list if `return_list` is set.</span>
<span class="sd"> Raise:</span>
<span class="sd"> ParsingError: If zero/multimatch and `return_list` is False, or caller was not</span>
<span class="sd"> passed into parser.</span>
<span class="sd"> Examples:</span>
<span class="sd"> - &quot;$search(#233)&quot;</span>
<span class="sd"> - &quot;$search(Tom, type=account)&quot;</span>
<span class="sd"> - &quot;$search(meadow, return_list=True)&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">return_list</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;return_list&quot;</span><span class="p">,</span> <span class="s2">&quot;false&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="o">==</span> <span class="s2">&quot;true&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span> <span class="k">if</span> <span class="n">return_list</span> <span class="k">else</span> <span class="kc">None</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">caller</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span><span class="s2">&quot;$search requires a `caller` passed to the parser.&quot;</span><span class="p">)</span>
<span class="n">query</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="n">typ</span> <span class="o">=</span> <span class="n">kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;type&quot;</span><span class="p">,</span> <span class="s2">&quot;obj&quot;</span><span class="p">)</span>
<span class="n">targets</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;obj&quot;</span><span class="p">:</span>
<span class="n">targets</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">search_object</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;account&quot;</span><span class="p">:</span>
<span class="n">targets</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">search_account</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="k">elif</span> <span class="n">typ</span> <span class="o">==</span> <span class="s2">&quot;script&quot;</span><span class="p">:</span>
<span class="n">targets</span> <span class="o">=</span> <span class="n">search</span><span class="o">.</span><span class="n">search_script</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">targets</span><span class="p">:</span>
<span class="k">if</span> <span class="n">return_list</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[]</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;$search: Query &#39;</span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">&#39; gave no matches.&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">targets</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">return_list</span><span class="p">:</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span>
<span class="s2">&quot;$search: Query &#39;</span><span class="si">{query}</span><span class="s2">&#39; found </span><span class="si">{num}</span><span class="s2"> matches. &quot;</span>
<span class="s2">&quot;Set return_list=True to accept a list&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">query</span><span class="o">=</span><span class="n">query</span><span class="p">,</span> <span class="n">num</span><span class="o">=</span><span class="nb">len</span><span class="p">(</span><span class="n">targets</span><span class="p">))</span>
<span class="p">)</span>
<span class="k">for</span> <span class="n">target</span> <span class="ow">in</span> <span class="n">targets</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">target</span><span class="o">.</span><span class="n">access</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="n">target</span><span class="p">,</span> <span class="n">access</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span><span class="s2">&quot;$search Cannot add found entity - access failure.&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">list</span><span class="p">(</span><span class="n">targets</span><span class="p">)</span> <span class="k">if</span> <span class="n">return_list</span> <span class="k">else</span> <span class="n">targets</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span></div>
<div class="viewcode-block" id="funcparser_callable_search_list"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_search_list">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_search_list</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">access</span><span class="o">=</span><span class="s2">&quot;control&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $objlist(#123)</span>
<span class="sd"> Legacy alias for search with a return_list=True kwarg preset.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">funcparser_callable_search</span><span class="p">(</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">access</span><span class="o">=</span><span class="n">access</span><span class="p">,</span> <span class="n">return_list</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_you"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_you">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_you</span><span class="p">(</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mapping</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">capitalize</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $you() or $you(key)</span>
<span class="sd"> Replaces with you for the caller of the string, with the display_name</span>
<span class="sd"> of the caller for others.</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> caller (Object): The &#39;you&#39; in the string. This is used unless another</span>
<span class="sd"> you-key is passed to the callable in combination with `mapping`.</span>
<span class="sd"> receiver (Object): The recipient of the string.</span>
<span class="sd"> mapping (dict, optional): This is a mapping `{key:Object, ...}` and is</span>
<span class="sd"> used to find which object `$you(key)` refers to. If not given, the</span>
<span class="sd"> `caller` kwarg is used.</span>
<span class="sd"> capitalize (bool): Passed by the You helper, to capitalize you.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The parsed string.</span>
<span class="sd"> Raises:</span>
<span class="sd"> ParsingError: If `caller` and `receiver` were not supplied.</span>
<span class="sd"> Notes:</span>
<span class="sd"> The kwargs should be passed the to parser directly.</span>
<span class="sd"> Examples:</span>
<span class="sd"> This can be used by the say or emote hooks to pass actor stance</span>
<span class="sd"> strings. This should usually be combined with the $conj() callable.</span>
<span class="sd"> - `With a grin, $you() $conj(jump) at $you(tommy).`</span>
<span class="sd"> The caller-object will see &quot;With a grin, you jump at Tommy.&quot;</span>
<span class="sd"> Tommy will see &quot;With a grin, CharName jumps at you.&quot;</span>
<span class="sd"> Others will see &quot;With a grin, CharName jumps at Tommy.&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">args</span> <span class="ow">and</span> <span class="n">mapping</span><span class="p">:</span>
<span class="c1"># this would mean a $you(key) form</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">caller</span> <span class="o">=</span> <span class="n">mapping</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">caller</span> <span class="ow">and</span> <span class="n">receiver</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span><span class="s2">&quot;No caller or receiver supplied to $you callable.&quot;</span><span class="p">)</span>
<span class="n">capitalize</span> <span class="o">=</span> <span class="nb">bool</span><span class="p">(</span><span class="n">capitalize</span><span class="p">)</span>
<span class="k">if</span> <span class="n">caller</span> <span class="o">==</span> <span class="n">receiver</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;You&quot;</span> <span class="k">if</span> <span class="n">capitalize</span> <span class="k">else</span> <span class="s2">&quot;you&quot;</span>
<span class="k">return</span> <span class="p">(</span>
<span class="n">caller</span><span class="o">.</span><span class="n">get_display_name</span><span class="p">(</span><span class="n">looker</span><span class="o">=</span><span class="n">receiver</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;get_display_name&quot;</span><span class="p">)</span>
<span class="k">else</span> <span class="nb">str</span><span class="p">(</span><span class="n">caller</span><span class="p">)</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_you_capitalize"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_you_capitalize">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_you_capitalize</span><span class="p">(</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">you</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">mapping</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">capitalize</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $You() - capitalizes the &#39;you&#39; output.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">funcparser_callable_you</span><span class="p">(</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">you</span><span class="o">=</span><span class="n">you</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="n">receiver</span><span class="p">,</span> <span class="n">mapping</span><span class="o">=</span><span class="n">mapping</span><span class="p">,</span> <span class="n">capitalize</span><span class="o">=</span><span class="n">capitalize</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span></div>
<div class="viewcode-block" id="funcparser_callable_conjugate"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_conjugate">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_conjugate</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $conj(word, [options])</span>
<span class="sd"> Conjugate a verb according to if it should be 2nd or third person.</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> caller (Object): The object who represents &#39;you&#39; in the string.</span>
<span class="sd"> receiver (Object): The recipient of the string.</span>
<span class="sd"> Returns:</span>
<span class="sd"> str: The parsed string.</span>
<span class="sd"> Raises:</span>
<span class="sd"> ParsingError: If `you` and `recipient` were not both supplied.</span>
<span class="sd"> Notes:</span>
<span class="sd"> Note that the verb will not be capitalized. It also</span>
<span class="sd"> assumes that the active party (You) is the one performing the verb.</span>
<span class="sd"> This automatic conjugation will fail if the active part is another person</span>
<span class="sd"> than &#39;you&#39;. The caller/receiver must be passed to the parser directly.</span>
<span class="sd"> Examples:</span>
<span class="sd"> This is often used in combination with the $you/You( callables.</span>
<span class="sd"> - `With a grin, $you() $conj(jump)`</span>
<span class="sd"> You will see &quot;With a grin, you jump.&quot;</span>
<span class="sd"> Others will see &quot;With a grin, CharName jumps.&quot;</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="p">(</span><span class="n">caller</span> <span class="ow">and</span> <span class="n">receiver</span><span class="p">):</span>
<span class="k">raise</span> <span class="n">ParsingError</span><span class="p">(</span><span class="s2">&quot;No caller/receiver supplied to $conj callable&quot;</span><span class="p">)</span>
<span class="n">second_person_str</span><span class="p">,</span> <span class="n">third_person_str</span> <span class="o">=</span> <span class="n">verb_actor_stance_components</span><span class="p">(</span><span class="n">args</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
<span class="k">return</span> <span class="n">second_person_str</span> <span class="k">if</span> <span class="n">caller</span> <span class="o">==</span> <span class="n">receiver</span> <span class="k">else</span> <span class="n">third_person_str</span></div>
<div class="viewcode-block" id="funcparser_callable_pronoun"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_pronoun">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_pronoun</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">capitalize</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $pron(word, [options])</span>
<span class="sd"> Adjust pronouns to the expected form. Pronouns are words you use instead of a</span>
<span class="sd"> proper name, such as &#39;him&#39;, &#39;herself&#39;, &#39;theirs&#39; etc. These look different</span>
<span class="sd"> depending on who sees the outgoing string.</span>
<span class="sd"> The parser maps between this table ...</span>
<span class="sd"> ==================== ======= ======= ========== ========== ===========</span>
<span class="sd"> 1st/2nd person Subject Object Possessive Possessive Reflexive</span>
<span class="sd"> Pronoun Pronoun Adjective Pronoun Pronoun</span>
<span class="sd"> ==================== ======= ======= ========== ========== ===========</span>
<span class="sd"> 1st person I me my mine myself</span>
<span class="sd"> 1st person plural we us our ours ourselves</span>
<span class="sd"> 2nd person you you your yours yourself</span>
<span class="sd"> 2nd person plural you you your yours yourselves</span>
<span class="sd"> ==================== ======= ======= ========== ========== ===========</span>
<span class="sd"> ... and this table (and vice versa).</span>
<span class="sd"> ==================== ======= ======= ========== ========== ===========</span>
<span class="sd"> 3rd person Subject Object Possessive Possessive Reflexive</span>
<span class="sd"> Pronoun Pronoun Adjective Pronoun Pronoun</span>
<span class="sd"> ==================== ======= ======= ========== ========== ===========</span>
<span class="sd"> 3rd person male he him his his himself</span>
<span class="sd"> 3rd person female she her her hers herself</span>
<span class="sd"> 3rd person neutral it it its itself</span>
<span class="sd"> 3rd person plural they them their theirs themselves</span>
<span class="sd"> ==================== ======= ======= ========== ========== ===========</span>
<span class="sd"> This system will examine `caller` for either a property or a callable `.gender` to</span>
<span class="sd"> get a default gender fallback (if not specified in the call). If a callable,</span>
<span class="sd"> `.gender` will be called without arguments and should return a string</span>
<span class="sd"> `male`/`female`/`neutral`/`plural` (plural is considered a gender for this purpose).</span>
<span class="sd"> If no `gender` property/callable is found, `neutral` is used as a fallback.</span>
<span class="sd"> The pronoun-type default (if not specified in call) is `subject pronoun`.</span>
<span class="sd"> Args:</span>
<span class="sd"> pronoun (str): Input argument to parsed call. This can be any of the pronouns</span>
<span class="sd"> in the table above. If given in 1st/second form, they will be mappped to</span>
<span class="sd"> 3rd-person form for others viewing the message (but will need extra input</span>
<span class="sd"> via the `gender`, see below). If given on 3rd person form, this will be</span>
<span class="sd"> mapped to 2nd person form for `caller` unless `viewpoint` is specified</span>
<span class="sd"> in options.</span>
<span class="sd"> options (str, optional): A space- or comma-separated string detailing `pronoun_type`,</span>
<span class="sd"> `gender`/`plural` and/or `viewpoint` to help the mapper differentiate between</span>
<span class="sd"> non-unique cases (such as if `you` should become `him` or `they`).</span>
<span class="sd"> Allowed values are:</span>
<span class="sd"> - `subject pronoun`/`subject`/`sp` (I, you, he, they)</span>
<span class="sd"> - `object pronoun`/`object/`/`op` (me, you, him, them)</span>
<span class="sd"> - `possessive adjective`/`adjective`/`pa` (my, your, his, their)</span>
<span class="sd"> - `possessive pronoun`/`pronoun`/`pp` (mine, yours, his, theirs)</span>
<span class="sd"> - `male`/`m`</span>
<span class="sd"> - `female`/`f`</span>
<span class="sd"> - `neutral`/`n`</span>
<span class="sd"> - `plural`/`p`</span>
<span class="sd"> - `1st person`/`1st`/`1`</span>
<span class="sd"> - `2nd person`/`2nd`/`2`</span>
<span class="sd"> - `3rd person`/`3rd`/`3`</span>
<span class="sd"> Keyword Args:</span>
<span class="sd"> caller (Object): The object creating the string. If this has a property &#39;gender&#39;,</span>
<span class="sd"> it will be checked for a string &#39;male/female/neutral&#39; to determine</span>
<span class="sd"> the 3rd person gender (but if `pronoun_type` contains a gender</span>
<span class="sd"> component, that takes precedence). Provided automatically to the</span>
<span class="sd"> funcparser.</span>
<span class="sd"> receiver (Object): The recipient of the string. This being the same as</span>
<span class="sd"> `caller` or not helps determine 2nd vs 3rd-person forms. This is</span>
<span class="sd"> provided automatically by the funcparser.</span>
<span class="sd"> capitalize (bool): The input retains its capitalization. If this is set the output is</span>
<span class="sd"> always capitalized.</span>
<span class="sd"> Examples:</span>
<span class="sd"> ====================== ============= ===========</span>
<span class="sd"> Input caller sees others see</span>
<span class="sd"> ====================== ============= ===========</span>
<span class="sd"> $pron(I, m) I he</span>
<span class="sd"> $pron(you,fo) you her</span>
<span class="sd"> $pron(yourself) yourself itself</span>
<span class="sd"> $pron(its) your its</span>
<span class="sd"> $pron(you,op,p) you them</span>
<span class="sd"> ====================== ============= ===========</span>
<span class="sd"> Notes:</span>
<span class="sd"> There is no option to specify reflexive pronouns since they are all unique</span>
<span class="sd"> and the mapping can always be auto-detected.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">args</span><span class="p">:</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span>
<span class="n">pronoun</span><span class="p">,</span> <span class="o">*</span><span class="n">options</span> <span class="o">=</span> <span class="n">args</span>
<span class="c1"># options is either multiple args or a space-separated string</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">options</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
<span class="n">options</span> <span class="o">=</span> <span class="n">options</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="c1"># default differentiators</span>
<span class="n">default_pronoun_type</span> <span class="o">=</span> <span class="s2">&quot;subject pronoun&quot;</span>
<span class="n">default_gender</span> <span class="o">=</span> <span class="s2">&quot;neutral&quot;</span>
<span class="n">default_viewpoint</span> <span class="o">=</span> <span class="s2">&quot;2nd person&quot;</span>
<span class="k">if</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">caller</span><span class="p">,</span> <span class="s2">&quot;gender&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="n">callable</span><span class="p">(</span><span class="n">caller</span><span class="o">.</span><span class="n">gender</span><span class="p">):</span>
<span class="n">default_gender</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">gender</span><span class="p">()</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">default_gender</span> <span class="o">=</span> <span class="n">caller</span><span class="o">.</span><span class="n">gender</span>
<span class="k">if</span> <span class="s2">&quot;viewpoint&quot;</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
<span class="c1"># passed into FuncParser initialization</span>
<span class="n">default_viewpoint</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s2">&quot;viewpoint&quot;</span><span class="p">]</span>
<span class="n">pronoun_1st_or_2nd_person</span><span class="p">,</span> <span class="n">pronoun_3rd_person</span> <span class="o">=</span> <span class="n">pronoun_to_viewpoints</span><span class="p">(</span>
<span class="n">pronoun</span><span class="p">,</span>
<span class="n">options</span><span class="p">,</span>
<span class="n">pronoun_type</span><span class="o">=</span><span class="n">default_pronoun_type</span><span class="p">,</span>
<span class="n">gender</span><span class="o">=</span><span class="n">default_gender</span><span class="p">,</span>
<span class="n">viewpoint</span><span class="o">=</span><span class="n">default_viewpoint</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">capitalize</span><span class="p">:</span>
<span class="n">pronoun_1st_or_2nd_person</span> <span class="o">=</span> <span class="n">pronoun_1st_or_2nd_person</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span>
<span class="n">pronoun_3rd_person</span> <span class="o">=</span> <span class="n">pronoun_3rd_person</span><span class="o">.</span><span class="n">capitalize</span><span class="p">()</span>
<span class="k">return</span> <span class="n">pronoun_1st_or_2nd_person</span> <span class="k">if</span> <span class="n">caller</span> <span class="o">==</span> <span class="n">receiver</span> <span class="k">else</span> <span class="n">pronoun_3rd_person</span></div>
<div class="viewcode-block" id="funcparser_callable_pronoun_capitalize"><a class="viewcode-back" href="../../../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_pronoun_capitalize">[docs]</a><span class="k">def</span> <span class="nf">funcparser_callable_pronoun_capitalize</span><span class="p">(</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">capitalize</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Usage: $Pron(word, [options]) - always maps to a capitalized word.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">funcparser_callable_pronoun</span><span class="p">(</span>
<span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="n">caller</span><span class="o">=</span><span class="n">caller</span><span class="p">,</span> <span class="n">receiver</span><span class="o">=</span><span class="n">receiver</span><span class="p">,</span> <span class="n">capitalize</span><span class="o">=</span><span class="n">capitalize</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span>
<span class="p">)</span></div>
<span class="c1"># these are made available as callables by adding &#39;evennia.utils.funcparser&#39; as</span>
<span class="c1"># a callable-path when initializing the FuncParser.</span>
<span class="n">FUNCPARSER_CALLABLES</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1"># &#39;standard&#39; callables</span>
<span class="c1"># eval and arithmetic</span>
<span class="s2">&quot;eval&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_eval</span><span class="p">,</span>
<span class="s2">&quot;add&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_add</span><span class="p">,</span>
<span class="s2">&quot;sub&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_sub</span><span class="p">,</span>
<span class="s2">&quot;mult&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_mult</span><span class="p">,</span>
<span class="s2">&quot;div&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_div</span><span class="p">,</span>
<span class="s2">&quot;round&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_round</span><span class="p">,</span>
<span class="s2">&quot;toint&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_toint</span><span class="p">,</span>
<span class="c1"># randomizers</span>
<span class="s2">&quot;random&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_random</span><span class="p">,</span>
<span class="s2">&quot;randint&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_randint</span><span class="p">,</span>
<span class="s2">&quot;choice&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_choice</span><span class="p">,</span>
<span class="c1"># string manip</span>
<span class="s2">&quot;pad&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_pad</span><span class="p">,</span>
<span class="s2">&quot;crop&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_crop</span><span class="p">,</span>
<span class="s2">&quot;just&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_justify</span><span class="p">,</span>
<span class="s2">&quot;ljust&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_left_justify</span><span class="p">,</span>
<span class="s2">&quot;rjust&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_right_justify</span><span class="p">,</span>
<span class="s2">&quot;cjust&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_center_justify</span><span class="p">,</span>
<span class="s2">&quot;justify&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_justify</span><span class="p">,</span> <span class="c1"># aliases for backwards compat</span>
<span class="s2">&quot;justify_left&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_left_justify</span><span class="p">,</span>
<span class="s2">&quot;justify_right&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_right_justify</span><span class="p">,</span>
<span class="s2">&quot;justify_center&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_center_justify</span><span class="p">,</span>
<span class="s2">&quot;space&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_space</span><span class="p">,</span>
<span class="s2">&quot;clr&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_clr</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">SEARCHING_CALLABLES</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1"># requires `caller` and optionally `access` to be passed into parser</span>
<span class="s2">&quot;search&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_search</span><span class="p">,</span>
<span class="s2">&quot;obj&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_search</span><span class="p">,</span> <span class="c1"># aliases for backwards compat</span>
<span class="s2">&quot;objlist&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_search_list</span><span class="p">,</span>
<span class="s2">&quot;dbref&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_search</span><span class="p">,</span>
<span class="p">}</span>
<span class="n">ACTOR_STANCE_CALLABLES</span> <span class="o">=</span> <span class="p">{</span>
<span class="c1"># requires `you`, `receiver` and `mapping` to be passed into parser</span>
<span class="s2">&quot;you&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_you</span><span class="p">,</span>
<span class="s2">&quot;You&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_you_capitalize</span><span class="p">,</span>
<span class="s2">&quot;obj&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_you</span><span class="p">,</span>
<span class="s2">&quot;Obj&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_you_capitalize</span><span class="p">,</span>
<span class="s2">&quot;conj&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_conjugate</span><span class="p">,</span>
<span class="s2">&quot;pron&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_pronoun</span><span class="p">,</span>
<span class="s2">&quot;Pron&quot;</span><span class="p">:</span> <span class="n">funcparser_callable_pronoun_capitalize</span><span class="p">,</span>
<span class="p">}</span>
</pre></div>
<div class="clearer"></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../../index.html">
<img class="logo" src="../../../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com">Home page</a> </li>
<li><a href="https://github.com/evennia/evennia">Evennia Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Versions</h3>
<ul>
<li><a href="funcparser.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia 1.0-dev</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../evennia.html" >evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.utils.funcparser</a></li>
</ul>
<div class="develop">develop branch</div>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2020, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>