<p>The <aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser"title="evennia.utils.funcparser.FuncParser"><spanclass="xref myst py py-class">FuncParser</span></a> extracts and executes ‘inline functions’ embedded in a string on the form <codeclass="docutils literal notranslate"><spanclass="pre">$funcname(args,</span><spanclass="pre">kwargs)</span></code>, executes the matching ‘inline function’ and replaces the call with the return from the call.</p>
<p>To test it, let’s tell Evennia to apply the Funcparser on every outgoing message. This is disabled by default (not everyone needs this functionality). To activate, add to your settings file:</p>
<p>To escape the inlinefunc (e.g. to explain to someone how it works, use <codeclass="docutils literal notranslate"><spanclass="pre">$$</span></code>)</p>
<p>While <codeclass="docutils literal notranslate"><spanclass="pre">randint</span></code> may look and work just like <codeclass="docutils literal notranslate"><spanclass="pre">random.randint</span></code> from the standard Python library, it is <em>not</em>. Instead it’s a <codeclass="docutils literal notranslate"><spanclass="pre">inlinefunc</span></code> named <codeclass="docutils literal notranslate"><spanclass="pre">randint</span></code> made available to Evennia (which in turn uses the standard library function). For security reasons, only functions explicitly assigned to be used as inlinefuncs are viable.</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">FuncParser</span></code> tool is initialized with the inlinefuncs it’s supposed to recognize. Below is an example of a parser only only understanding a single <codeclass="docutils literal notranslate"><spanclass="pre">$pow</span></code> inlinefunc:</p>
<p>Next, just pass a string into the parser, containing <codeclass="docutils literal notranslate"><spanclass="pre">$func(...)</span></code> markers:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="n">parser</span><spanclass="o">.</span><spanclass="n">parse</span><spanclass="p">(</span><spanclass="s2">"We have that 4 x 4 x 4 is $pow(4, power=3)."</span><spanclass="p">)</span>
<spanclass="s2">"We have that 4 x 4 x 4 is 64."</span>
</pre></div>
</div>
<p>Normally the return is always converted to a string but you can also get the actual data type from the call:</p>
<h2>Working with FuncParser<aclass="headerlink"href="#working-with-funcparser"title="Permalink to this headline">¶</a></h2>
<p>The FuncParser can be applied to any string. Out of the box it’s applied in a few situations:</p>
<ulclass="simple">
<li><p><em>Outgoing messages</em>. All messages sent from the server is processed through FuncParser and every callable is provided the <aclass="reference internal"href="Sessions.html"><spanclass="doc std std-doc">Session</span></a> of the object receiving the message. This potentially allows a message to be modified on the fly to look different for different recipients.</p></li>
<li><p><em>Prototype values</em>. A <aclass="reference internal"href="Prototypes.html"><spanclass="doc std std-doc">Prototype</span></a> dict’s values are run through the parser such that every callable gets a reference to the rest of the prototype. In the Prototype ORM, this would allow builders to safely call functions to set non-string values to prototype values, get random values, reference
other fields of the prototype, and more.</p></li>
<li><p><em>Actor-stance in messages to others</em>. In the <aclass="reference internal"href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject.msg_contents"title="evennia.objects.objects.DefaultObject.msg_contents"><spanclass="xref myst py py-meth">Object.msg_contents</span></a> method, the outgoing string is parsed for special <codeclass="docutils literal notranslate"><spanclass="pre">$You()</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">$conj()</span></code> callables to decide if a given recipient
should see “You” or the character’s name.</p></li>
</ul>
<divclass="admonition important">
<pclass="admonition-title">Important</p>
<p>The inline-function parser is not intended as a ‘softcode’ programming language. It does not have things like loops and conditionals, for example. While you could in principle extend it to do very advanced things and allow builders a lot of power, all-out coding is something Evennia expects you to do in a proper text editor, outside of the game, not from inside it.</p>
</div>
<p>You can apply inline function parsing to any string. The
<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.FuncParser"title="evennia.utils.funcparser.FuncParser"><spanclass="xref myst py py-class">FuncParser</span></a> is imported as <codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.funcparser</span></code>.</p>
<p>Here, <codeclass="docutils literal notranslate"><spanclass="pre">callables</span></code> points to a collection of normal Python functions (see next section) for you to make
available to the parser as you parse strings with it. It can either be</p>
<ulclass="simple">
<li><p>A <codeclass="docutils literal notranslate"><spanclass="pre">dict</span></code> of <codeclass="docutils literal notranslate"><spanclass="pre">{"functionname":</span><spanclass="pre">callable,</span><spanclass="pre">...}</span></code>. This allows you do pick and choose exactly which callables
to include and how they should be named. Do you want a callable to be available under more than one name?
Just add it multiple times to the dict, with a different key.</p></li>
<li><p>A <codeclass="docutils literal notranslate"><spanclass="pre">module</span></code> or (more commonly) a <codeclass="docutils literal notranslate"><spanclass="pre">python-path</span></code> to a module. This module can define a dict
<codeclass="docutils literal notranslate"><spanclass="pre">FUNCPARSER_CALLABLES</span><spanclass="pre">=</span><spanclass="pre">{"funcname":</span><spanclass="pre">callable,</span><spanclass="pre">...}</span></code> - this will be imported and used like the <codeclass="docutils literal notranslate"><spanclass="pre">dict</span></code> above.
If no such variable is defined, <em>every</em> top-level function in the module (whose name doesn’t start with
an underscore <codeclass="docutils literal notranslate"><spanclass="pre">_</span></code>) will be considered a suitable callable. The name of the function will be the <codeclass="docutils literal notranslate"><spanclass="pre">$funcname</span></code>
by which it can be called.</p></li>
<li><p>A <codeclass="docutils literal notranslate"><spanclass="pre">list</span></code> of modules/paths. This allows you to pull in modules from many sources for your parsing.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">**default</span></code> kwargs are optional kwargs that will be passed to <em>all</em>
callables every time this parser is used - unless the user overrides it explicitly in
their call. This is great for providing sensible standards that the user can
tweak as needed.</p></li>
</ul>
<p><codeclass="docutils literal notranslate"><spanclass="pre">FuncParser.parse</span></code> takes further arguments, and can vary for every string parsed.</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">raise_errors</span></code> - By default, any errors from a callable will be quietly ignored and the result
will be that the failing function call will show verbatim. If <codeclass="docutils literal notranslate"><spanclass="pre">raise_errors</span></code> is set,
then parsing will stop and whatever exception happened will be raised. It’d be up to you to handle
this properly.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">escape</span></code> - Returns a string where every <codeclass="docutils literal notranslate"><spanclass="pre">$func(...)</span></code> has been escaped as <codeclass="docutils literal notranslate"><spanclass="pre">\$func()</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">strip</span></code> - Remove all <codeclass="docutils literal notranslate"><spanclass="pre">$func(...)</span></code> calls from string (as if each returned <codeclass="docutils literal notranslate"><spanclass="pre">''</span></code>).</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">return_str</span></code> - When <codeclass="docutils literal notranslate"><spanclass="pre">True</span></code> (default), <codeclass="docutils literal notranslate"><spanclass="pre">parser</span></code> always returns a string. If <codeclass="docutils literal notranslate"><spanclass="pre">False</span></code>, it may return
the return value of a single function call in the string. This is the same as using the <codeclass="docutils literal notranslate"><spanclass="pre">.parse_to_any</span></code>
method.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">**reserved_keywords</span></code> are <em>always</em> passed to every callable in the string.
They override any <codeclass="docutils literal notranslate"><spanclass="pre">**defaults</span></code> given when instantiating the parser and cannot
be overridden by the user - if they enter the same kwarg it will be ignored.
This is great for providing the current session, settings etc.</p></li>
<li><p>The <codeclass="docutils literal notranslate"><spanclass="pre">funcparser</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">raise_errors</span></code>
are always added as reserved keywords - the first is a
back-reference to the <codeclass="docutils literal notranslate"><spanclass="pre">FuncParser</span></code> instance and the second
is the <codeclass="docutils literal notranslate"><spanclass="pre">raise_errors</span></code> boolean given to <codeclass="docutils literal notranslate"><spanclass="pre">FuncParser.parse</span></code>.</p></li>
</ul>
<p>Here’s an example of using the default/reserved keywords:</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">mydefault=2</span></code> kwarg could be overwritten if we made the call as <codeclass="docutils literal notranslate"><spanclass="pre">$test(mydefault=...)</span></code> but <codeclass="docutils literal notranslate"><spanclass="pre">myreserved=[1,</span><spanclass="pre">2,</span><spanclass="pre">3]</span></code> will <em>always</em> be sent as-is and will override a call <codeclass="docutils literal notranslate"><spanclass="pre">$test(myreserved=...)</span></code>.
The <codeclass="docutils literal notranslate"><spanclass="pre">funcparser</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">raise_errors</span></code> kwargs are also always included as reserved kwargs.</p>
</section>
<sectionid="defining-custom-callables">
<h2>Defining custom callables<aclass="headerlink"href="#defining-custom-callables"title="Permalink to this headline">¶</a></h2>
<p>All callables made available to the parser must have the following signature:</p>
<div><p>The <codeclass="docutils literal notranslate"><spanclass="pre">*args</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">**kwargs</span></code> must always be included. If you are unsure how <codeclass="docutils literal notranslate"><spanclass="pre">*args</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">**kwargs</span></code> work in Python, <aclass="reference external"href="https://www.digitalocean.com/community/tutorials/how-to-use-args-and-kwargs-in-python-3">read about them here</a>.</p>
</div></blockquote>
<p>The input from the innermost <codeclass="docutils literal notranslate"><spanclass="pre">$funcname(...)</span></code> call in your callable will always be a <codeclass="docutils literal notranslate"><spanclass="pre">str</span></code>. Here’s
an example of an <codeclass="docutils literal notranslate"><spanclass="pre">$toint</span></code> function; it converts numbers to integers.</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>"There's a $toint(22.0)% chance of survival."
</pre></div>
</div>
<p>What will enter the <codeclass="docutils literal notranslate"><spanclass="pre">$toint</span></code> callable (as <codeclass="docutils literal notranslate"><spanclass="pre">args[0]</span></code>) is the <em>string</em><codeclass="docutils literal notranslate"><spanclass="pre">"22.0"</span></code>. The function is responsible for converting this to a number so that we can convert it to an integer. We must also properly handle invalid inputs (like non-numbers).</p>
<p>If you want to mark an error, raise <codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.funcparser.ParsingError</span></code>. This stops the entire parsing of the string and may or may not raise the exception depending on what you set <codeclass="docutils literal notranslate"><spanclass="pre">raise_errors</span></code> to when you created the parser.</p>
<p>However, if you <em>nest</em> functions, the return of the innermost function may be something other than
a string. Let’s introduce the <codeclass="docutils literal notranslate"><spanclass="pre">$eval</span></code> function, which evaluates simple expressions using
Python’s <codeclass="docutils literal notranslate"><spanclass="pre">literal_eval</span></code> and/or <codeclass="docutils literal notranslate"><spanclass="pre">simple_eval</span></code>. It returns whatever data type it
evaluates to.</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>"There's a $toint($eval(10 * 2.2))% chance of survival."
</pre></div>
</div>
<p>Since the <codeclass="docutils literal notranslate"><spanclass="pre">$eval</span></code> is the innermost call, it will get a string as input - the string <codeclass="docutils literal notranslate"><spanclass="pre">"10</span><spanclass="pre">*</span><spanclass="pre">2.2"</span></code>.
It evaluates this and returns the <codeclass="docutils literal notranslate"><spanclass="pre">float</span></code><codeclass="docutils literal notranslate"><spanclass="pre">22.0</span></code>. This time the outermost <codeclass="docutils literal notranslate"><spanclass="pre">$toint</span></code> will be called with
this <codeclass="docutils literal notranslate"><spanclass="pre">float</span></code> instead of with a string.</p>
<blockquote>
<div><p>It’s important to safely validate your inputs since users may end up nesting your callables in any order. See the next section for useful tools to help with this.</p>
</div></blockquote>
<p>In these examples, the result will be embedded in the larger string, so the result of the entire parsing will be a string:</p>
<spanclass="s2">"There's a 22</span><spanclass="si">% c</span><spanclass="s2">hance of survival."</span>
</pre></div>
</div>
<p>However, if you use the <codeclass="docutils literal notranslate"><spanclass="pre">parse_to_any</span></code> (or <codeclass="docutils literal notranslate"><spanclass="pre">parse(...,</span><spanclass="pre">return_str=False)</span></code>) and <em>don’t add any extra string around the outermost function call</em>, you’ll get the return type of the outermost callable back:</p>
<spanclass="n">parser</span><spanclass="o">.</span><spanclass="n">parse_to_any</span><spanclass="p">(</span><spanclass="s2">"the number $toint($eval(10 * 2.2)."</span><spanclass="p">)</span>
<h3>Escaping special character<aclass="headerlink"href="#escaping-special-character"title="Permalink to this headline">¶</a></h3>
<p>When entering funcparser callables in strings, it looks like a regular
function call inside a string:</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="s2">"This is a $myfunc(arg1, arg2, kwarg=foo)."</span>
</pre></div>
</div>
<p>Commas (<codeclass="docutils literal notranslate"><spanclass="pre">,</span></code>) and equal-signs (<codeclass="docutils literal notranslate"><spanclass="pre">=</span></code>) are considered to separate the arguments and
kwargs. In the same way, the right parenthesis (<codeclass="docutils literal notranslate"><spanclass="pre">)</span></code>) closes the argument list.
Sometimes you want to include commas in the argument without it breaking the
argument list.</p>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="s2">"The $format(forest's smallest meadow, with dandelions) is to the west."</span>
</pre></div>
</div>
<p>You can escape in various ways.</p>
<ulclass="simple">
<li><p>Prepending special characters like <codeclass="docutils literal notranslate"><spanclass="pre">,</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">=</span></code> with the escape character <codeclass="docutils literal notranslate"><spanclass="pre">\</span></code></p></li>
</ul>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="s2">"The $format(forest's smallest meadow\, with dandelions) is to the west."</span>
</pre></div>
</div>
<ulclass="simple">
<li><p>Wrapping your strings in double quotes. Unlike in raw Python, you
can’t escape with single quotes <codeclass="docutils literal notranslate"><spanclass="pre">'</span></code> since these could also be apostrophes (like
<codeclass="docutils literal notranslate"><spanclass="pre">forest's</span></code> above). The result will be a verbatim string that contains
everything but the outermost double quotes.</p></li>
</ul>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="s1">'The $format("forest'</span><spanclass="n">s</span><spanclass="n">smallest</span><spanclass="n">meadow</span><spanclass="p">,</span><spanclass="k">with</span><spanclass="n">dandelions</span><spanclass="s2">") is to the west.'</span>
</pre></div>
</div>
<ulclass="simple">
<li><p>If you want verbatim double-quotes to appear in your string, you can escape
them with <codeclass="docutils literal notranslate"><spanclass="pre">\"</span></code> in turn.</p></li>
</ul>
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="s1">'The $format("forest'</span><spanclass="n">s</span><spanclass="n">smallest</span><spanclass="n">meadow</span><spanclass="p">,</span><spanclass="k">with</span> \<spanclass="s2">"dandelions</span><spanclass="se">\"</span><spanclass="s2">') is to the west.'</span>
</pre></div>
</div>
</section>
<sectionid="safe-convertion-of-inputs">
<h3>Safe convertion of inputs<aclass="headerlink"href="#safe-convertion-of-inputs"title="Permalink to this headline">¶</a></h3>
<p>Since you don’t know in which order users may use your callables, they should
always check the types of its inputs and convert to the type the callable needs.
Note also that when converting from strings, there are limits what inputs you
can support. This is because FunctionParser strings can be used by
non-developer players/builders and some things (such as complex
classes/callables etc) are just not safe/possible to convert from string
representation.</p>
<p>In <codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.utils</span></code> is a helper called <aclass="reference internal"href="../api/evennia.utils.utils.html#evennia.utils.utils.safe_convert_to_types"title="evennia.utils.utils.safe_convert_to_types"><spanclass="xref myst py py-func">safe_convert_to_types</span></a>. This function automates the conversion of simple data types in a safe way:</p>
<spanclass="c1"># args/kwargs should be correct types now</span>
</pre></div>
</div>
<p>In other words, in the callable <codeclass="docutils literal notranslate"><spanclass="pre">$process(expression,</span><spanclass="pre">local,</span><spanclass="pre">extra1=..,</span><spanclass="pre">extra2=...)</span></code>, the first argument will be handled by the ‘py’ converter (described below), the second will passed through regular Python <codeclass="docutils literal notranslate"><spanclass="pre">str</span></code>, kwargs will be handled by <codeclass="docutils literal notranslate"><spanclass="pre">int</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">str</span></code> respectively. You can supply your own converter function as long as it takes one argument and returns the converted result.</p>
<p>The special converter <codeclass="docutils literal notranslate"><spanclass="pre">"py"</span></code> will try to convert a string argument to a Python structure with the help of the following tools (which you may also find useful to experiment with on your own):</p>
<ulclass="simple">
<li><p><aclass="reference external"href="https://docs.python.org/3.8/library/ast.html#ast.literal_eval">ast.literal_eval</a> is an in-built Python function. It <em>only</em> supports strings, bytes, numbers, tuples, lists, dicts, sets, booleans and <codeclass="docutils literal notranslate"><spanclass="pre">None</span></code>. That’s it - no arithmetic or modifications of data is allowed. This is good for converting individual values and lists/dicts from the input line to real Python objects.</p></li>
<li><p><aclass="reference external"href="https://pypi.org/project/simpleeval/">simpleeval</a> is a third-party tool included with Evennia. This allows for evaluation of simple (and thus safe) expressions. One can operate on numbers and strings with <codeclass="docutils literal notranslate"><spanclass="pre">+-/*</span></code> as well as do simple comparisons like <codeclass="docutils literal notranslate"><spanclass="pre">4</span><spanclass="pre">></span><spanclass="pre">3</span></code> and more. It does <em>not</em> accept more complex containers like lists/dicts etc, so this and <codeclass="docutils literal notranslate"><spanclass="pre">literal_eval</span></code> are complementary to each other.</p></li>
</ul>
<divclass="admonition warning">
<pclass="admonition-title">Warning</p>
<p>It may be tempting to run use Python’s in-built <codeclass="docutils literal notranslate"><spanclass="pre">eval()</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">exec()</span></code> functions as converters since these are able to convert any valid Python source code to Python. NEVER DO THIS unless you really, really know that ONLY developers will ever modify the string going into the callable. The parser is intended for untrusted users (if you were trusted you’d have access to Python already). Letting untrusted users pass strings to <codeclass="docutils literal notranslate"><spanclass="pre">eval</span></code>/<codeclass="docutils literal notranslate"><spanclass="pre">exec</span></code> is a MAJOR security risk. It allows the caller to run arbitrary Python code on your server. This is the path to maliciously deleted hard drives. Just don’t do it and sleep better at night.</p>
</div>
</section>
</section>
<sectionid="default-funcparser-callables">
<h2>Default funcparser callables<aclass="headerlink"href="#default-funcparser-callables"title="Permalink to this headline">¶</a></h2>
<p>These are some example callables you can import and add your parser. They are divided into global-level dicts in <codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.funcparser</span></code>. Just import the dict(s) and merge/add one or more to them when you create your <codeclass="docutils literal notranslate"><spanclass="pre">FuncParser</span></code> instance to have those callables be available.</p>
<h3><codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.funcparser.FUNCPARSER_CALLABLES</span></code><aclass="headerlink"href="#evennia-utils-funcparser-funcparser-callables"title="Permalink to this headline">¶</a></h3>
<p>These are the ‘base’ callables.</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$eval(expression)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_eval"title="evennia.utils.funcparser.funcparser_callable_eval"><spanclass="xref myst py py-func">code</span></a>) - this uses <codeclass="docutils literal notranslate"><spanclass="pre">literal_eval</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">simple_eval</span></code> (see previous section) attemt to convert a string expression to a python object. This handles e.g. lists of literals <codeclass="docutils literal notranslate"><spanclass="pre">[1,</span><spanclass="pre">2,</span><spanclass="pre">3]</span></code> and simple expressions like <codeclass="docutils literal notranslate"><spanclass="pre">"1</span><spanclass="pre">+</span><spanclass="pre">2"</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$toint(number)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_toint"title="evennia.utils.funcparser.funcparser_callable_toint"><spanclass="xref myst py py-func">code</span></a>) - always converts an output to an integer, if possible.</p></li>
this adds/subtracts/multiplies and divides to elements together. While simple addition could be done with <codeclass="docutils literal notranslate"><spanclass="pre">$eval</span></code>, this could for example be used also to add two lists together, which is not possible with <codeclass="docutils literal notranslate"><spanclass="pre">eval</span></code>; for example <codeclass="docutils literal notranslate"><spanclass="pre">$add($eval([1,2,3]),</span><spanclass="pre">$eval([4,5,6]))</span><spanclass="pre">-></span><spanclass="pre">[1,</span><spanclass="pre">2,</span><spanclass="pre">3,</span><spanclass="pre">4,</span><spanclass="pre">5,</span><spanclass="pre">6]</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$round(float,</span><spanclass="pre">significant)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_round"title="evennia.utils.funcparser.funcparser_callable_round"><spanclass="xref myst py py-func">code</span></a>) - rounds an input float into the number of provided significant digits. For example <codeclass="docutils literal notranslate"><spanclass="pre">$round(3.54343,</span><spanclass="pre">3)</span><spanclass="pre">-></span><spanclass="pre">3.543</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$random([start,</span><spanclass="pre">[end]])</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_random"title="evennia.utils.funcparser.funcparser_callable_random"><spanclass="xref myst py py-func">code</span></a>) - this works like the Python <codeclass="docutils literal notranslate"><spanclass="pre">random()</span></code> function, but will randomize to an integer value if both start/end are
integers. Without argument, will return a float between 0 and 1.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$randint([start,</span><spanclass="pre">[end]])</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_randint"title="evennia.utils.funcparser.funcparser_callable_randint"><spanclass="xref myst py py-func">code</span></a>) - works like the <codeclass="docutils literal notranslate"><spanclass="pre">randint()</span></code> python function and always returns an integer.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$choice(list)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_choice"title="evennia.utils.funcparser.funcparser_callable_choice"><spanclass="xref myst py py-func">code</span></a>) - the input will automatically be parsed the same way as <codeclass="docutils literal notranslate"><spanclass="pre">$eval</span></code> and is expected to be an iterable. A random element of this list will be returned.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$pad(text[,</span><spanclass="pre">width,</span><spanclass="pre">align,</span><spanclass="pre">fillchar])</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_pad"title="evennia.utils.funcparser.funcparser_callable_pad"><spanclass="xref myst py py-func">code</span></a>) - this will pad content. <codeclass="docutils literal notranslate"><spanclass="pre">$pad("Hello",</span><spanclass="pre">30,</span><spanclass="pre">c,</span><spanclass="pre">-)</span></code> will lead to a text centered in a 30-wide block surrounded by <codeclass="docutils literal notranslate"><spanclass="pre">-</span></code> characters.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$crop(text,</span><spanclass="pre">width=78,</span><spanclass="pre">suffix='[...]')</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_crop"title="evennia.utils.funcparser.funcparser_callable_crop"><spanclass="xref myst py py-func">code</span></a>) - this will crop a text longer than the width, by default ending it with a <codeclass="docutils literal notranslate"><spanclass="pre">[...]</span></code>-suffix that also fits within the width. If no width is given, the client width or <codeclass="docutils literal notranslate"><spanclass="pre">settings.DEFAULT_CLIENT_WIDTH</span></code> will be used.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$space(num)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_space"title="evennia.utils.funcparser.funcparser_callable_space"><spanclass="xref myst py py-func">code</span></a>) - this will insert <codeclass="docutils literal notranslate"><spanclass="pre">num</span></code> spaces.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$just(string,</span><spanclass="pre">width=40,</span><spanclass="pre">align=c,</span><spanclass="pre">indent=2)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_justify"title="evennia.utils.funcparser.funcparser_callable_justify"><spanclass="xref myst py py-func">code</span></a>) - justifies the text to a given width, aligning it left/right/center or ‘f’ for full (spread text across width).</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$ljust</span></code> - shortcut to justify-left. Takes all other kwarg of <codeclass="docutils literal notranslate"><spanclass="pre">$just</span></code>.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$rjust</span></code> - shortcut to right justify.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$cjust</span></code> - shortcut to center justify.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$clr(startcolor,</span><spanclass="pre">text[,</span><spanclass="pre">endcolor])</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_clr"title="evennia.utils.funcparser.funcparser_callable_clr"><spanclass="xref myst py py-func">code</span></a>) - color text. The color is given with one or two characters without the preceeding <codeclass="docutils literal notranslate"><spanclass="pre">|</span></code>. If no endcolor is given, the string will go back to neutral, so <codeclass="docutils literal notranslate"><spanclass="pre">$clr(r,</span><spanclass="pre">Hello)</span></code> is equivalent to <codeclass="docutils literal notranslate"><spanclass="pre">|rHello|n</span></code>.</p></li>
<h3><codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.funcparser.SEARCHING_CALLABLES</span></code><aclass="headerlink"href="#evennia-utils-funcparser-searching-callables"title="Permalink to this headline">¶</a></h3>
<p>These are callables that requires access-checks in order to search for objects. So they require some extra reserved kwargs to be passed when running the parser:</p>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code> is required, it’s the the object to do the access-check for. The <codeclass="docutils literal notranslate"><spanclass="pre">access</span></code> kwarg is the
<aclass="reference internal"href="Locks.html"><spanclass="doc std std-doc">lock type</span></a> to check, default being <codeclass="docutils literal notranslate"><spanclass="pre">"control"</span></code>.</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$search(query,type=account|script,return_list=False)</span></code> (<aclass="reference internal"href="../api/evennia.utils.funcparser.html#evennia.utils.funcparser.funcparser_callable_search"title="evennia.utils.funcparser.funcparser_callable_search"><spanclass="xref myst py py-func">code</span></a>) - this will look up and try to match an object by key or alias. Use the <codeclass="docutils literal notranslate"><spanclass="pre">type</span></code> kwarg to search for <codeclass="docutils literal notranslate"><spanclass="pre">account</span></code> or <codeclass="docutils literal notranslate"><spanclass="pre">script</span></code> instead. By default this will return nothing if there are more than one match; if <codeclass="docutils literal notranslate"><spanclass="pre">return_list</span></code> is <codeclass="docutils literal notranslate"><spanclass="pre">True</span></code> a list of 0, 1 or more matches will be returned instead.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$objlist(query)</span></code> - legacy alias for <codeclass="docutils literal notranslate"><spanclass="pre">$search</span></code>, always returning a list.</p></li>
<h3><codeclass="docutils literal notranslate"><spanclass="pre">evennia.utils.funcparser.ACTOR_STANCE_CALLABLES</span></code><aclass="headerlink"href="#evennia-utils-funcparser-actor-stance-callables"title="Permalink to this headline">¶</a></h3>
<p>These are used to implement actor-stance emoting. They are used by the <aclass="reference internal"href="../api/evennia.objects.objects.html#evennia.objects.objects.DefaultObject.msg_contents"title="evennia.objects.objects.DefaultObject.msg_contents"><spanclass="xref myst py py-meth">DefaultObject.msg_contents</span></a> method by default. You can read a lot more about this on the page
<aclass="reference internal"href="../Concepts/Change-Message-Per-Receiver.html"><spanclass="doc std std-doc">Change messages per receiver</span></a>.</p>
<p>On the parser side, all these inline functions require extra kwargs be passed into the parser (done by <codeclass="docutils literal notranslate"><spanclass="pre">msg_contents</span></code> by default):</p>
<p>Here the <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code> is the one sending the message and <codeclass="docutils literal notranslate"><spanclass="pre">receiver</span></code> the one to see it. The <codeclass="docutils literal notranslate"><spanclass="pre">mapping</span></code> contains references to other objects accessible via these callables.</p>
if no <codeclass="docutils literal notranslate"><spanclass="pre">key</span></code> is given, this represents the <codeclass="docutils literal notranslate"><spanclass="pre">caller</span></code>, otherwise an object from <codeclass="docutils literal notranslate"><spanclass="pre">mapping</span></code>
will be used. As this message is sent to different recipients, the <codeclass="docutils literal notranslate"><spanclass="pre">receiver</span></code> will change and this will
be replaced either with the string <codeclass="docutils literal notranslate"><spanclass="pre">you</span></code> (if you and the receiver is the same entity) or with the
result of <codeclass="docutils literal notranslate"><spanclass="pre">you_obj.get_display_name(looker=receiver)</span></code>. This allows for a single string to echo differently
depending on who sees it, and also to reference other people in the same way.</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$You([key])</span></code> - same as <codeclass="docutils literal notranslate"><spanclass="pre">$you</span></code> but always capitalized.</p></li>
between 2nd person presens to 3rd person presence depending on who
sees the string. For example <codeclass="docutils literal notranslate"><spanclass="pre">"$You()</span><spanclass="pre">$conj(smiles)".</span></code> will show as “You smile.” and “Tom smiles.” depending
on who sees it. This makes use of the tools in <aclass="reference internal"href="../api/evennia.utils.verb_conjugation.html#evennia-utils-verb-conjugation"><spanclass="std std-ref">evennia.utils.verb_conjugation</span></a>
to do this, and only works for English verbs.</p></li>
<h3><codeclass="docutils literal notranslate"><spanclass="pre">evennia.prototypes.protfuncs</span></code><aclass="headerlink"href="#evennia-prototypes-protfuncs"title="Permalink to this headline">¶</a></h3>
<p>This is used by the <aclass="reference internal"href="Prototypes.html"><spanclass="doc std std-doc">Prototype system</span></a> and allows for adding references inside the prototype. The funcparsing will happen before the spawn.</p>
<p>Available inlinefuncs to prototypes:</p>
<ulclass="simple">
<li><p>All <codeclass="docutils literal notranslate"><spanclass="pre">FUNCPARSER_CALLABLES</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">SEARCHING_CALLABLES</span></code></p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">$protkey(key)</span></code> - returns the value of another key within the same prototype. Note that the system will try to convert this to a ‘real’ value (like turning the string “3” into the integer 3), for security reasons, not all embedded values can be converted this way. Note however that you can do nested calls with inlinefuncs, including adding your own converters.</p></li>
<p>Above we define two callables <codeclass="docutils literal notranslate"><spanclass="pre">_dashline</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">_uptime</span></code> and map them to names <codeclass="docutils literal notranslate"><spanclass="pre">"dashline"</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">"uptime"</span></code>,
which is what we then can call as <codeclass="docutils literal notranslate"><spanclass="pre">$header</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">$uptime</span></code> in the string. We also have access to
all the defaults (like <codeclass="docutils literal notranslate"><spanclass="pre">$toint()</span></code>).</p>
<p>The parsed result of the above would be something like this:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>This is the current uptime: