mirror of
https://github.com/evennia/evennia.git
synced 2026-03-27 18:26:32 +01:00
667 lines
No EOL
68 KiB
HTML
667 lines
No EOL
68 KiB
HTML
|
|
<!DOCTYPE html>
|
|
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<title>evennia.utils.evform — 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> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="../../evennia.html" accesskey="U">evennia</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">evennia.utils.evform</a></li>
|
|
</ul>
|
|
<div class="develop">develop branch</div>
|
|
</div>
|
|
|
|
<div class="document">
|
|
|
|
<div class="documentwrapper">
|
|
<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="evform.html">1.0-dev (develop branch)</a></li>
|
|
<ul>
|
|
<li><a href="../0.9.5/index.html">0.9.5 (v0.9.5 branch)</a></li>
|
|
|
|
</ul>
|
|
|
|
</div>
|
|
</div>
|
|
<div class="bodywrapper">
|
|
<div class="body" role="main">
|
|
|
|
<h1>Source code for evennia.utils.evform</h1><div class="highlight"><pre>
|
|
<span></span><span class="c1"># coding=utf-8</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd">EvForm - a way to create advanced ASCII forms</span>
|
|
|
|
<span class="sd">This is intended for creating advanced ASCII game forms, such as a large pretty character sheet or</span>
|
|
<span class="sd">info document.</span>
|
|
|
|
<span class="sd">The system works on the basis of a readin template that is given in a separate Python file imported</span>
|
|
<span class="sd">into the handler. This file contains some optional settings and a string mapping out the form. The</span>
|
|
<span class="sd">template has markers in it to denounce fields to fill. The markers map the absolute size of the</span>
|
|
<span class="sd">field and will be filled with an `evtable.EvCell` object when displaying the form.</span>
|
|
|
|
<span class="sd">Example of input file `testform.py`:</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">FORMCHAR = "x"</span>
|
|
<span class="sd">TABLECHAR = "c"</span>
|
|
|
|
<span class="sd">FORM = '''</span>
|
|
<span class="sd">.------------------------------------------------.</span>
|
|
<span class="sd">| |</span>
|
|
<span class="sd">| Name: xxxxx1xxxxx Player: xxxxxxx2xxxxxxx |</span>
|
|
<span class="sd">| xxxxxxxxxxx |</span>
|
|
<span class="sd">| |</span>
|
|
<span class="sd"> >----------------------------------------------<</span>
|
|
<span class="sd">| |</span>
|
|
<span class="sd">| Desc: xxxxxxxxxxx STR: x4x DEX: x5x |</span>
|
|
<span class="sd">| xxxxx3xxxxx INT: x6x STA: x7x |</span>
|
|
<span class="sd">| xxxxxxxxxxx LUC: x8x MAG: x9x |</span>
|
|
<span class="sd">| |</span>
|
|
<span class="sd"> >----------------------------------------------<</span>
|
|
<span class="sd">| | |</span>
|
|
<span class="sd">| cccccccc | ccccccccccccccccccccccccccccccccccc |</span>
|
|
<span class="sd">| cccccccc | ccccccccccccccccccccccccccccccccccc |</span>
|
|
<span class="sd">| cccAcccc | ccccccccccccccccccccccccccccccccccc |</span>
|
|
<span class="sd">| cccccccc | ccccccccccccccccccccccccccccccccccc |</span>
|
|
<span class="sd">| cccccccc | cccccccccccccccccBccccccccccccccccc |</span>
|
|
<span class="sd">| | |</span>
|
|
<span class="sd">| v& |</span>
|
|
<span class="sd">-------------------------------------------------</span>
|
|
<span class="sd">'''</span>
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">The first line of the `FORM` string is ignored if empty. The forms and table markers must mark out</span>
|
|
<span class="sd">complete, unbroken rectangles, each containing one embedded single-character identifier (so the</span>
|
|
<span class="sd">smallest element possible is a 3-character wide form). The identifier can be any character except</span>
|
|
<span class="sd">for the `FORM_CHAR` and `TABLE_CHAR` and some of the common ASCII-art elements, like space, `_` `|`</span>
|
|
<span class="sd">`*` etc (see `INVALID_FORMCHARS` in this module). Form Rectangles can have any size, but must be</span>
|
|
<span class="sd">separated from each other by at least one other character's width.</span>
|
|
|
|
<span class="sd">The form can also replace literal markers not abiding by these rules. For example, the `v&` in the</span>
|
|
<span class="sd">bottom right corner could be such literal marker. If a literal-mapping for 'v&' is provided, all</span>
|
|
<span class="sd">occurrences of this marker will be replaced. This will happen *before* any other parsing, so in</span>
|
|
<span class="sd">principle this could be used to inject new fields/tables into the form dynamically. This literal</span>
|
|
<span class="sd">mapping does not consider width, but it will affect to total width of the form, so make sure what</span>
|
|
<span class="sd">you inject does not break things. Using literal markers is the only way to inject 1 or 2-character</span>
|
|
<span class="sd">replacements.</span>
|
|
|
|
<span class="sd">Usage</span>
|
|
|
|
<span class="sd">```python</span>
|
|
<span class="sd">from evennia import EvForm, EvTable</span>
|
|
|
|
<span class="sd"># create a new form from the template</span>
|
|
<span class="sd">form = EvForm("path/to/testform.py")</span>
|
|
|
|
<span class="sd"># alteratively, you can supply the template as a dict:</span>
|
|
|
|
<span class="sd">form = EvForm({"FORM": "....", "TABLECHAR": "c", "FORMCHAR": "x"})</span>
|
|
|
|
<span class="sd"># EvForm can also take a dictionary instead of a filepath, as long</span>
|
|
<span class="sd"># as the dict contains the keys FORMCHAR, TABLECHAR and FORM</span>
|
|
<span class="sd"># form = EvForm(form=form_dict)</span>
|
|
|
|
<span class="sd"># add data to each tagged form cell</span>
|
|
<span class="sd">form.map(cells={1: "Tom the Bouncer",</span>
|
|
<span class="sd"> 2: "Griatch",</span>
|
|
<span class="sd"> 3: "A sturdy fellow",</span>
|
|
<span class="sd"> 4: 12,</span>
|
|
<span class="sd"> 5: 10,</span>
|
|
<span class="sd"> 6: 5,</span>
|
|
<span class="sd"> 7: 18,</span>
|
|
<span class="sd"> 8: 10,</span>
|
|
<span class="sd"> 9: 3})</span>
|
|
<span class="sd"># create the EvTables</span>
|
|
<span class="sd">tableA = EvTable("HP","MV","MP",</span>
|
|
<span class="sd"> table=[["**"], ["*****"], ["***"]],</span>
|
|
<span class="sd"> border="incols")</span>
|
|
<span class="sd">tableB = EvTable("Skill", "Value", "Exp",</span>
|
|
<span class="sd"> table=[["Shooting", "Herbalism", "Smithing"],</span>
|
|
<span class="sd"> [12,14,9],["550/1200", "990/1400", "205/900"]],</span>
|
|
<span class="sd"> border="incols")</span>
|
|
<span class="sd"># map 'literal' replacents (here, a version string)</span>
|
|
<span class="sd">custom_mapping = {"v&", "v2"}</span>
|
|
|
|
<span class="sd"># add the tables to the proper ids in the form</span>
|
|
<span class="sd">form.map(tables={"A": tableA,</span>
|
|
<span class="sd"> "B": tableB})</span>
|
|
|
|
<span class="sd">print(form)</span>
|
|
<span class="sd">```</span>
|
|
|
|
<span class="sd">This produces the following result:</span>
|
|
|
|
<span class="sd">::</span>
|
|
|
|
<span class="sd"> .------------------------------------------------.</span>
|
|
<span class="sd"> | |</span>
|
|
<span class="sd"> | Name: Tom the Player: Griatch |</span>
|
|
<span class="sd"> | Bouncer |</span>
|
|
<span class="sd"> | |</span>
|
|
<span class="sd"> >----------------------------------------------<</span>
|
|
<span class="sd"> | |</span>
|
|
<span class="sd"> | Desc: A sturdy STR: 12 DEX: 10 |</span>
|
|
<span class="sd"> | fellow INT: 5 STA: 18 |</span>
|
|
<span class="sd"> | LUC: 10 MAG: 3 |</span>
|
|
<span class="sd"> | |</span>
|
|
<span class="sd"> >----------------------------------------------<</span>
|
|
<span class="sd"> | | |</span>
|
|
<span class="sd"> | HP|MV|MP | Skill |Value |Exp |</span>
|
|
<span class="sd"> | ~~+~~+~~ | ~~~~~~~~~~~+~~~~~~~~~~~+~~~~~~~~~~~ |</span>
|
|
<span class="sd"> | **|**|** | Shooting |12 |550/1200 |</span>
|
|
<span class="sd"> | |**|* | Herbalism |14 |990/1400 |</span>
|
|
<span class="sd"> | |* | | Smithing |9 |205/900 |</span>
|
|
<span class="sd"> | | |</span>
|
|
<span class="sd"> | v2 |</span>
|
|
<span class="sd"> ------------------------------------------------</span>
|
|
|
|
<span class="sd">The marked forms have been replaced with EvCells of text and with EvTables. The literal marker `v&`</span>
|
|
<span class="sd">was replaced with `v2`.</span>
|
|
|
|
<span class="sd">If you change the form layout on disk, you can use `form.reload()` to re-read it from disk without</span>
|
|
<span class="sd">creating a new form.</span>
|
|
|
|
<span class="sd">If you want to update the data of an existing form, you can use `form.map()` with the changes - the</span>
|
|
<span class="sd">mappings will be updated, keeping the things you want. You can also update the template itself this</span>
|
|
<span class="sd">way, by supplying it as a dict.</span>
|
|
|
|
<span class="sd">Each component (except literal mappings) is restrained to the width and height specified by the</span>
|
|
<span class="sd">template, so it will resize to fit (or crop text if the area is too small for it). If you try to fit</span>
|
|
<span class="sd">a table into an area it cannot fit into (when including its borders and at least one line of text),</span>
|
|
<span class="sd">the form will raise an error.</span>
|
|
|
|
<span class="sd">----</span>
|
|
|
|
<span class="sd">"""</span>
|
|
|
|
<span class="kn">import</span> <span class="nn">re</span>
|
|
<span class="kn">from</span> <span class="nn">copy</span> <span class="kn">import</span> <span class="n">copy</span>
|
|
|
|
<span class="kn">from</span> <span class="nn">evennia.utils.ansi</span> <span class="kn">import</span> <span class="n">ANSIString</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils.ansi</span> <span class="kn">import</span> <span class="n">raw</span> <span class="k">as</span> <span class="n">ansi_raw</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils.evtable</span> <span class="kn">import</span> <span class="n">EvCell</span><span class="p">,</span> <span class="n">EvTable</span>
|
|
<span class="kn">from</span> <span class="nn">evennia.utils.utils</span> <span class="kn">import</span> <span class="n">all_from_module</span><span class="p">,</span> <span class="n">is_iter</span><span class="p">,</span> <span class="n">to_str</span>
|
|
|
|
<span class="c1"># non-valid form-identifying characters (which can thus be</span>
|
|
<span class="c1"># used as separators between forms without being detected</span>
|
|
<span class="c1"># as an identifier). These should be listed in regex form.</span>
|
|
<span class="n">INVALID_FORMCHARS</span> <span class="o">=</span> <span class="sa">r</span><span class="s2">"\s\/\|</span><span class="se">\\</span><span class="s2">\*\_\-\#\<\>\~\^\:\;\.\,"</span>
|
|
<span class="c1"># if there is an ansi-escape (||) we have to replace this with ||| to make sure</span>
|
|
<span class="c1"># to properly escape down the line</span>
|
|
<span class="n">_ANSI_ESCAPE</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">"\|\|"</span><span class="p">)</span>
|
|
|
|
|
|
<div class="viewcode-block" id="EvForm"><a class="viewcode-back" href="../../../api/evennia.utils.evform.html#evennia.utils.evform.EvForm">[docs]</a><span class="k">class</span> <span class="nc">EvForm</span><span class="p">:</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> This object is instantiated with a text file and parses</span>
|
|
<span class="sd"> it for rectangular form fields. It can then be fed a</span>
|
|
<span class="sd"> mapping so as to populate the fields with fixed-width</span>
|
|
<span class="sd"> EvCell or Tables.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
|
|
<span class="c1"># cell option defaults</span>
|
|
<span class="n">cell_options</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"pad_left"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"pad_right"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"pad_top"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"pad_bottom"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"align"</span><span class="p">:</span> <span class="s2">"l"</span><span class="p">,</span>
|
|
<span class="s2">"valign"</span><span class="p">:</span> <span class="s2">"t"</span><span class="p">,</span>
|
|
<span class="s2">"enforce_size"</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
|
|
<span class="c1"># table option defaults</span>
|
|
<span class="n">table_options</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"pad_left"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"pad_right"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"pad_top"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"pad_bottom"</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
|
|
<span class="s2">"align"</span><span class="p">:</span> <span class="s2">"l"</span><span class="p">,</span>
|
|
<span class="s2">"valign"</span><span class="p">:</span> <span class="s2">"t"</span><span class="p">,</span>
|
|
<span class="s2">"enforce_size"</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>
|
|
<span class="p">}</span>
|
|
|
|
<div class="viewcode-block" id="EvForm.__init__"><a class="viewcode-back" href="../../../api/evennia.utils.evform.html#evennia.utils.evform.EvForm.__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">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">cells</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tables</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">literals</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">"""</span>
|
|
<span class="sd"> Initiate the form</span>
|
|
|
|
<span class="sd"> Keyword Args:</span>
|
|
<span class="sd"> data (str or dict): Path to template file or a dict with</span>
|
|
<span class="sd"> "formchar", "tablechar" and "form" keys (not case sensitive, so FORM etc</span>
|
|
<span class="sd"> also works, to stay compatible with the in-file names). While "form/FORM"</span>
|
|
<span class="sd"> is required, if FORMCHAR/TABLECHAR are not given, they will default to</span>
|
|
<span class="sd"> 'x' and 'c' respectively.</span>
|
|
<span class="sd"> cells (dict): A dictionary mapping `{id: str}`</span>
|
|
<span class="sd"> tables (dict): A dictionary mapping `{id: EvTable}`.</span>
|
|
<span class="sd"> literals (dict): A dictionary mapping `{id: str}`. Will be replaced</span>
|
|
<span class="sd"> after width of form is calculated, but before cells/tables are mapped.</span>
|
|
<span class="sd"> All occurrences of the identifier on the form will be replaced. Note</span>
|
|
<span class="sd"> that there is no length-restriction on the remap, you are responsible</span>
|
|
<span class="sd"> for not breaking the form.</span>
|
|
|
|
<span class="sd"> Notes:</span>
|
|
<span class="sd"> Other kwargs are fed as options to the EvCells and EvTables</span>
|
|
<span class="sd"> (see `evtable.EvCell` and `evtable.EvTable` for more info).</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indata</span> <span class="o">=</span> <span class="n">data</span> <span class="c1"># storing here so we can reload later in case of a filename</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">options</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_inkwargs</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">cells_mapping</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="nb">dict</span><span class="p">((</span><span class="n">to_str</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">value</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">cells</span><span class="o">.</span><span class="n">items</span><span class="p">())</span> <span class="k">if</span> <span class="n">cells</span> <span class="k">else</span> <span class="p">{}</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">tables_mapping</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="nb">dict</span><span class="p">((</span><span class="n">to_str</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">value</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">tables</span><span class="o">.</span><span class="n">items</span><span class="p">())</span> <span class="k">if</span> <span class="n">tables</span> <span class="k">else</span> <span class="p">{}</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">literals_mapping</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="nb">dict</span><span class="p">((</span><span class="n">to_str</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">to_str</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">literals</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
|
<span class="k">if</span> <span class="n">literals</span>
|
|
<span class="k">else</span> <span class="p">{}</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># work arrays</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">literal_form</span> <span class="o">=</span> <span class="s2">""</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">mapping</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">matrix</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">form</span> <span class="o">=</span> <span class="p">[]</span>
|
|
|
|
<span class="c1"># will parse and build the form</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">reload</span><span class="p">()</span></div>
|
|
|
|
<span class="k">def</span> <span class="nf">_parse_indata</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Parse and validate the `self.indata` property. We do this in order to be able to</span>
|
|
<span class="sd"> re-load the evform module if indata is a filename and catch any on-file changes.</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> dict: The data dict parsed/generated from the in-data.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">indata</span>
|
|
|
|
<span class="n">default_formchar</span> <span class="o">=</span> <span class="s2">"x"</span>
|
|
<span class="n">default_tablechar</span> <span class="o">=</span> <span class="s2">"c"</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="c1"># a module path - read all variables from it</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="n">all_from_module</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
|
|
<span class="s2">"form"</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"form"</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"FORM"</span><span class="p">,</span> <span class="kc">None</span><span class="p">))),</span>
|
|
<span class="s2">"formchar"</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"formchar"</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"FORMCHAR"</span><span class="p">,</span> <span class="n">default_formchar</span><span class="p">))),</span>
|
|
<span class="s2">"tablechar"</span><span class="p">:</span> <span class="nb">str</span><span class="p">(</span><span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"tablechar"</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"TABLECHAR"</span><span class="p">,</span> <span class="n">default_tablechar</span><span class="p">))),</span>
|
|
<span class="p">}</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"EvForm invalid input: </span><span class="si">{</span><span class="n">data</span><span class="si">}</span><span class="s2">."</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="ow">not</span> <span class="n">data</span> <span class="ow">or</span> <span class="n">data</span><span class="p">[</span><span class="s2">"form"</span><span class="p">]</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Evform data must specify a valid 'form' or 'FORM'."</span><span class="p">)</span>
|
|
|
|
<span class="c1"># handle empty or multi-character form/tablechars (not supported)</span>
|
|
<span class="n">data</span><span class="p">[</span><span class="s2">"formchar"</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"formchar"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s2">"formchar"</span><span class="p">]</span> <span class="k">else</span> <span class="n">default_formchar</span>
|
|
<span class="n">data</span><span class="p">[</span><span class="s2">"tablechar"</span><span class="p">]</span> <span class="o">=</span> <span class="n">data</span><span class="p">[</span><span class="s2">"tablechar"</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="k">if</span> <span class="n">data</span><span class="p">[</span><span class="s2">"tablechar"</span><span class="p">]</span> <span class="k">else</span> <span class="n">default_tablechar</span>
|
|
<span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">rf</span><span class="s2">"[</span><span class="si">{</span><span class="n">INVALID_FORMCHARS</span><span class="si">}</span><span class="s2">]"</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="s2">"formchar"</span><span class="p">]):</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Invalid formchar: </span><span class="si">{</span><span class="n">data</span><span class="p">[</span><span class="s1">'formchar'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="sa">rf</span><span class="s2">"[</span><span class="si">{</span><span class="n">INVALID_FORMCHARS</span><span class="si">}</span><span class="s2">]"</span><span class="p">,</span> <span class="n">data</span><span class="p">[</span><span class="s2">"tablechar"</span><span class="p">]):</span>
|
|
<span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Invalid tablechar: </span><span class="si">{</span><span class="n">data</span><span class="p">[</span><span class="s1">'tablechar'</span><span class="p">]</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">data</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_parse_inkwargs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Validate incoming kwargs that will be passed on to become cell/table options.</span>
|
|
|
|
<span class="sd"> Keyword Args:</span>
|
|
<span class="sd"> any: Kwargs to process.</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> dict: A validated/cleaned kwarg to use for options.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="s2">"filename"</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">DeprecationWarning</span><span class="p">(</span>
|
|
<span class="s2">"EvForm's 'filename' kwarg was renamed to 'data' and can now accept both "</span>
|
|
<span class="s2">"a python path and a dict with 'FORMCHAR', 'TABLECHAR' and 'FORM' keys."</span>
|
|
<span class="p">)</span>
|
|
<span class="k">if</span> <span class="s2">"form"</span> <span class="ow">in</span> <span class="n">kwargs</span><span class="p">:</span>
|
|
<span class="k">raise</span> <span class="ne">DeprecationWarning</span><span class="p">(</span>
|
|
<span class="s2">"EvForms's 'form' kwarg was renamed to 'data' and can now accept both "</span>
|
|
<span class="s2">"a python path and a dict detailing the form."</span>
|
|
<span class="p">)</span>
|
|
|
|
<span class="c1"># clean cell kwarg options (these cannot be overridden on the cell but must be controlled</span>
|
|
<span class="c1"># by the evform itself)</span>
|
|
<span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">"enforce_size"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">"width"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
<span class="n">kwargs</span><span class="o">.</span><span class="n">pop</span><span class="p">(</span><span class="s2">"height"</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">kwargs</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_do_literal_mapping</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Do literal replacement in the EvForm.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">literal_form</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"form"</span><span class="p">])</span>
|
|
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">repl</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">literals_mapping</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="n">literal_form</span> <span class="o">=</span> <span class="n">literal_form</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">repl</span><span class="p">)</span>
|
|
<span class="k">return</span> <span class="n">literal_form</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_parse_to_matrix</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Forces all lines to be as long as the longest line, filling with whitespace.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> lines (list): list of `ANSIString`s</span>
|
|
|
|
<span class="sd"> Returns:</span>
|
|
<span class="sd"> (list): list of `ANSIString`s of</span>
|
|
<span class="sd"> same length as the longest input line</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">matrix</span> <span class="o">=</span> <span class="n">EvForm</span><span class="o">.</span><span class="n">_to_ansi</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">literal_form</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">))</span>
|
|
|
|
<span class="n">maxl</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">matrix</span><span class="p">)</span>
|
|
<span class="n">matrix</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span> <span class="o">+</span> <span class="s2">" "</span> <span class="o">*</span> <span class="p">(</span><span class="n">maxl</span> <span class="o">-</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">))</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">matrix</span><span class="p">]</span>
|
|
<span class="k">if</span> <span class="n">matrix</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">matrix</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">():</span>
|
|
<span class="c1"># the first line is normally empty, we strip it.</span>
|
|
<span class="n">matrix</span> <span class="o">=</span> <span class="n">matrix</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
|
|
<span class="k">return</span> <span class="n">matrix</span>
|
|
|
|
<span class="nd">@staticmethod</span>
|
|
<span class="k">def</span> <span class="nf">_to_ansi</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">regexable</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
|
|
<span class="s2">"convert anything to ANSIString"</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">ANSIString</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="n">obj</span>
|
|
<span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
|
|
<span class="c1"># since ansi will be parsed twice (here and in the normal ansi send), we have to</span>
|
|
<span class="c1"># escape ansi twice.</span>
|
|
<span class="n">obj</span> <span class="o">=</span> <span class="n">ansi_raw</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="nb">dict</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="nb">dict</span><span class="p">(</span>
|
|
<span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">EvForm</span><span class="o">.</span><span class="n">_to_ansi</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">regexable</span><span class="o">=</span><span class="n">regexable</span><span class="p">))</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">obj</span><span class="o">.</span><span class="n">items</span><span class="p">()</span>
|
|
<span class="p">)</span>
|
|
<span class="c1"># regular _to_ansi (from EvTable)</span>
|
|
<span class="k">elif</span> <span class="n">is_iter</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
|
|
<span class="k">return</span> <span class="p">[</span><span class="n">EvForm</span><span class="o">.</span><span class="n">_to_ansi</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="k">for</span> <span class="n">o</span> <span class="ow">in</span> <span class="n">obj</span><span class="p">]</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">return</span> <span class="n">ANSIString</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">regexable</span><span class="o">=</span><span class="n">regexable</span><span class="p">)</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_rectangles_to_mapping</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Parse a form for rectangular formfields identified by formchar/tablechar enclosing an</span>
|
|
<span class="sd"> identifier.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">formchar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"formchar"</span><span class="p">]</span>
|
|
<span class="n">tablechar</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">[</span><span class="s2">"tablechar"</span><span class="p">]</span>
|
|
<span class="n">matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">matrix</span>
|
|
|
|
<span class="n">cell_options</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cell_options</span><span class="p">)</span>
|
|
<span class="n">cell_options</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="p">)</span>
|
|
|
|
<span class="n">table_options</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">table_options</span><span class="p">)</span>
|
|
<span class="n">table_options</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="p">)</span>
|
|
|
|
<span class="n">nmatrix</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">matrix</span><span class="p">)</span>
|
|
|
|
<span class="n">mapping</span> <span class="o">=</span> <span class="p">{}</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_get_rectangles</span><span class="p">(</span><span class="n">char</span><span class="p">):</span>
|
|
<span class="sd">"""Find all identified rectangles marked with given char"""</span>
|
|
<span class="n">rects</span> <span class="o">=</span> <span class="p">[]</span>
|
|
<span class="n">coords</span> <span class="o">=</span> <span class="p">{}</span>
|
|
<span class="n">regex</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">rf</span><span class="s2">"</span><span class="si">{</span><span class="n">char</span><span class="si">}</span><span class="s2">+([^</span><span class="si">{</span><span class="n">INVALID_FORMCHARS</span><span class="si">}{</span><span class="n">char</span><span class="si">}</span><span class="s2">]+)</span><span class="si">{</span><span class="n">char</span><span class="si">}</span><span class="s2">+"</span><span class="p">)</span>
|
|
|
|
<span class="c1"># find the start/width of rectangles for each line</span>
|
|
<span class="k">for</span> <span class="n">iy</span><span class="p">,</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">EvForm</span><span class="o">.</span><span class="n">_to_ansi</span><span class="p">(</span><span class="n">matrix</span><span class="p">,</span> <span class="n">regexable</span><span class="o">=</span><span class="kc">True</span><span class="p">)):</span>
|
|
<span class="n">ix0</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
|
|
<span class="n">match</span> <span class="o">=</span> <span class="n">regex</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="n">ix0</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="n">match</span><span class="p">:</span>
|
|
<span class="c1"># get the width of the rectangle directly from the match</span>
|
|
<span class="n">coords</span><span class="p">[</span><span class="n">match</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">)]</span> <span class="o">=</span> <span class="p">[</span><span class="n">iy</span><span class="p">,</span> <span class="n">match</span><span class="o">.</span><span class="n">start</span><span class="p">(),</span> <span class="n">match</span><span class="o">.</span><span class="n">end</span><span class="p">()]</span>
|
|
<span class="n">ix0</span> <span class="o">=</span> <span class="n">match</span><span class="o">.</span><span class="n">end</span><span class="p">()</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="p">(</span><span class="n">iy</span><span class="p">,</span> <span class="n">leftix</span><span class="p">,</span> <span class="n">rightix</span><span class="p">)</span> <span class="ow">in</span> <span class="n">coords</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
<span class="c1"># scan up to find top of rectangle</span>
|
|
<span class="n">dy_up</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">if</span> <span class="n">iy</span> <span class="o">></span> <span class="mi">0</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">iy</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">all</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="n">iy</span> <span class="o">-</span> <span class="n">i</span><span class="p">][</span><span class="n">ix</span><span class="p">]</span> <span class="o">==</span> <span class="n">char</span> <span class="k">for</span> <span class="n">ix</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">leftix</span><span class="p">,</span> <span class="n">rightix</span><span class="p">)):</span>
|
|
<span class="n">dy_up</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
<span class="c1"># find bottom edge of rectangle</span>
|
|
<span class="n">dy_down</span> <span class="o">=</span> <span class="mi">0</span>
|
|
<span class="k">if</span> <span class="n">iy</span> <span class="o"><</span> <span class="n">nmatrix</span> <span class="o">-</span> <span class="mi">1</span><span class="p">:</span>
|
|
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">nmatrix</span> <span class="o">-</span> <span class="n">iy</span> <span class="o">-</span> <span class="mi">1</span><span class="p">):</span>
|
|
<span class="k">if</span> <span class="nb">all</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="n">iy</span> <span class="o">+</span> <span class="n">i</span><span class="p">][</span><span class="n">ix</span><span class="p">]</span> <span class="o">==</span> <span class="n">char</span> <span class="k">for</span> <span class="n">ix</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">leftix</span><span class="p">,</span> <span class="n">rightix</span><span class="p">)):</span>
|
|
<span class="n">dy_down</span> <span class="o">+=</span> <span class="mi">1</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="k">break</span>
|
|
|
|
<span class="c1"># we have our rectangle. Calculate size</span>
|
|
<span class="n">iyup</span> <span class="o">=</span> <span class="n">iy</span> <span class="o">-</span> <span class="n">dy_up</span>
|
|
<span class="n">iydown</span> <span class="o">=</span> <span class="n">iy</span> <span class="o">+</span> <span class="n">dy_down</span>
|
|
<span class="n">width</span> <span class="o">=</span> <span class="n">rightix</span> <span class="o">-</span> <span class="n">leftix</span>
|
|
<span class="n">height</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</span><span class="n">iyup</span> <span class="o">-</span> <span class="n">iydown</span><span class="p">)</span> <span class="o">+</span> <span class="mi">1</span>
|
|
|
|
<span class="c1"># store (key, y, x, width, height) of triangle</span>
|
|
<span class="n">rects</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">key</span><span class="p">,</span> <span class="n">iyup</span><span class="p">,</span> <span class="n">leftix</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">))</span>
|
|
|
|
<span class="k">return</span> <span class="n">rects</span>
|
|
|
|
<span class="c1"># Map EvCells into form rectangles</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">)</span> <span class="ow">in</span> <span class="n">_get_rectangles</span><span class="p">(</span><span class="n">formchar</span><span class="p">):</span>
|
|
|
|
<span class="c1"># get data to populate cell</span>
|
|
<span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cells_mapping</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span>
|
|
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">EvCell</span><span class="p">):</span>
|
|
<span class="c1"># mapping already provides the cell. We need to override some</span>
|
|
<span class="c1"># of the cell's options to make it work in the evform rectangle.</span>
|
|
<span class="c1"># We retain the align/valign since this may be interesting to</span>
|
|
<span class="c1"># play with within the rectangle.</span>
|
|
<span class="n">cell</span> <span class="o">=</span> <span class="n">data</span>
|
|
<span class="n">custom_align</span> <span class="o">=</span> <span class="n">cell</span><span class="o">.</span><span class="n">align</span>
|
|
<span class="n">custom_valign</span> <span class="o">=</span> <span class="n">cell</span><span class="o">.</span><span class="n">valign</span>
|
|
<span class="n">cell</span><span class="o">.</span><span class="n">reformat</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">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span>
|
|
<span class="o">**</span><span class="p">{</span><span class="o">**</span><span class="n">cell_options</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="s2">"align"</span><span class="p">:</span> <span class="n">custom_align</span><span class="p">,</span> <span class="s2">"valign"</span><span class="p">:</span> <span class="n">custom_valign</span><span class="p">}},</span>
|
|
<span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="c1"># generating cell on the fly</span>
|
|
<span class="n">cell</span> <span class="o">=</span> <span class="n">EvCell</span><span class="p">(</span><span class="n">data</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">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span> <span class="o">**</span><span class="n">cell_options</span><span class="p">)</span>
|
|
|
|
<span class="n">mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="n">cell</span><span class="p">)</span>
|
|
|
|
<span class="c1"># Map EvTables into form rectangles</span>
|
|
<span class="k">for</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">)</span> <span class="ow">in</span> <span class="n">_get_rectangles</span><span class="p">(</span><span class="n">tablechar</span><span class="p">):</span>
|
|
|
|
<span class="c1"># get EvTable from mapping</span>
|
|
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">tables_mapping</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
|
|
|
|
<span class="k">if</span> <span class="n">table</span><span class="p">:</span>
|
|
<span class="n">table</span><span class="o">.</span><span class="n">reformat</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">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span> <span class="o">**</span><span class="n">table_options</span><span class="p">)</span>
|
|
<span class="k">else</span><span class="p">:</span>
|
|
<span class="n">table</span> <span class="o">=</span> <span class="n">EvTable</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">height</span><span class="o">=</span><span class="n">height</span><span class="p">,</span> <span class="o">**</span><span class="n">table_options</span><span class="p">)</span>
|
|
|
|
<span class="n">mapping</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="n">table</span><span class="p">)</span>
|
|
|
|
<span class="k">return</span> <span class="n">mapping</span>
|
|
|
|
<span class="k">def</span> <span class="nf">_build_form</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Insert cell/table contents into form at given locations to create</span>
|
|
<span class="sd"> the final result.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="n">form</span> <span class="o">=</span> <span class="n">copy</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">matrix</span><span class="p">)</span>
|
|
<span class="n">mapping</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">mapping</span>
|
|
|
|
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">width</span><span class="p">,</span> <span class="n">height</span><span class="p">,</span> <span class="n">cell_or_table</span><span class="p">)</span> <span class="ow">in</span> <span class="n">mapping</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
|
|
|
|
<span class="c1"># rect is a list of <height> lines, each <width> wide</span>
|
|
<span class="n">rect</span> <span class="o">=</span> <span class="n">cell_or_table</span><span class="o">.</span><span class="n">get</span><span class="p">()</span>
|
|
<span class="k">for</span> <span class="n">il</span><span class="p">,</span> <span class="n">rectline</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">rect</span><span class="p">):</span>
|
|
<span class="n">formline</span> <span class="o">=</span> <span class="n">form</span><span class="p">[</span><span class="n">y</span> <span class="o">+</span> <span class="n">il</span><span class="p">]</span>
|
|
<span class="c1"># insert new content, replacing old</span>
|
|
<span class="n">form</span><span class="p">[</span><span class="n">y</span> <span class="o">+</span> <span class="n">il</span><span class="p">]</span> <span class="o">=</span> <span class="n">formline</span><span class="p">[:</span><span class="n">x</span><span class="p">]</span> <span class="o">+</span> <span class="n">rectline</span> <span class="o">+</span> <span class="n">formline</span><span class="p">[</span><span class="n">x</span> <span class="o">+</span> <span class="n">width</span> <span class="p">:]</span>
|
|
|
|
<span class="k">return</span> <span class="n">form</span>
|
|
|
|
<div class="viewcode-block" id="EvForm.reload"><a class="viewcode-back" href="../../../api/evennia.utils.evform.html#evennia.utils.evform.EvForm.reload">[docs]</a> <span class="k">def</span> <span class="nf">reload</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
|
|
<span class="sd">"""</span>
|
|
<span class="sd"> Creates the form from a filename or data structure.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> data (str or dict): Can be used to update an existing form using</span>
|
|
<span class="sd"> the same cells/tables provided on initialization or using `.map()`.</span>
|
|
|
|
<span class="sd"> Notes:</span>
|
|
<span class="sd"> Kwargs are passed through to Cel creation.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_indata</span><span class="p">()</span>
|
|
|
|
<span class="c1"># Map any literals into the string</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">literal_form</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_do_literal_mapping</span><span class="p">()</span>
|
|
<span class="c1"># Create raw form matrix, indexable with (y, x) coords</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">matrix</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_to_matrix</span><span class="p">()</span>
|
|
<span class="c1"># parse and identify all rectangles in the form</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">mapping</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_rectangles_to_mapping</span><span class="p">()</span>
|
|
<span class="c1"># combine mapping with form template into a final result</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">form</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_build_form</span><span class="p">()</span></div>
|
|
|
|
<div class="viewcode-block" id="EvForm.map"><a class="viewcode-back" href="../../../api/evennia.utils.evform.html#evennia.utils.evform.EvForm.map">[docs]</a> <span class="k">def</span> <span class="nf">map</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cells</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">tables</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="n">literals</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">"""</span>
|
|
<span class="sd"> Add mapping for form. This allows for updating an existing</span>
|
|
<span class="sd"> evform.</span>
|
|
|
|
<span class="sd"> Args:</span>
|
|
<span class="sd"> cells (dict): A dictionary of {identifier:celltext}. These</span>
|
|
<span class="sd"> will be appended to the existing mappings.</span>
|
|
<span class="sd"> tables (dict): A dictionary of {identifier:table}. Will</span>
|
|
<span class="sd"> be appended to the existing mapping.</span>
|
|
<span class="sd"> data (str or dict): A path to a evform module or a dict with</span>
|
|
<span class="sd"> the needed "FORM", "TABLE/FORMCHAR" keys. Will replace</span>
|
|
<span class="sd"> the originally initialized form.</span>
|
|
<span class="sd"> literals</span>
|
|
|
|
<span class="sd"> Keyword Args:</span>
|
|
<span class="sd"> These will be appended to the existing cell/table options.</span>
|
|
|
|
<span class="sd"> Notes:</span>
|
|
<span class="sd"> kwargs will be forwarded to tables/cells. See</span>
|
|
<span class="sd"> `evtable.EvCell` and `evtable.EvTable` for info.</span>
|
|
|
|
<span class="sd"> """</span>
|
|
<span class="k">if</span> <span class="n">data</span><span class="p">:</span>
|
|
<span class="c1"># storing so ._parse_indata will find it during reload</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">indata</span> <span class="o">=</span> <span class="n">data</span>
|
|
|
|
<span class="n">new_cells</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">((</span><span class="n">to_str</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">value</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">cells</span><span class="o">.</span><span class="n">items</span><span class="p">())</span> <span class="k">if</span> <span class="n">cells</span> <span class="k">else</span> <span class="p">{}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">cells_mapping</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">new_cells</span><span class="p">)</span>
|
|
<span class="n">new_tables</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">((</span><span class="n">to_str</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">value</span><span class="p">)</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">tables</span><span class="o">.</span><span class="n">items</span><span class="p">())</span> <span class="k">if</span> <span class="n">tables</span> <span class="k">else</span> <span class="p">{}</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">tables_mapping</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">new_tables</span><span class="p">)</span>
|
|
<span class="n">new_literals</span> <span class="o">=</span> <span class="p">(</span>
|
|
<span class="nb">dict</span><span class="p">((</span><span class="n">to_str</span><span class="p">(</span><span class="n">key</span><span class="p">),</span> <span class="n">to_str</span><span class="p">(</span><span class="n">value</span><span class="p">))</span> <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">literals</span><span class="o">.</span><span class="n">items</span><span class="p">())</span>
|
|
<span class="k">if</span> <span class="n">literals</span>
|
|
<span class="k">else</span> <span class="p">{}</span>
|
|
<span class="p">)</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">literals_mapping</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">new_literals</span><span class="p">)</span>
|
|
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">options</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_parse_inkwargs</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">))</span>
|
|
|
|
<span class="c1"># parse and build the form</span>
|
|
<span class="bp">self</span><span class="o">.</span><span class="n">reload</span><span class="p">()</span></div>
|
|
|
|
<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="s2">"Prints the form"</span>
|
|
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="n">ANSIString</span><span class="p">(</span><span class="s2">"</span><span class="se">\n</span><span class="s2">"</span><span class="p">)</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">line</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">form</span><span class="p">]))</span></div>
|
|
</pre></div>
|
|
|
|
</div>
|
|
</div>
|
|
</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> »</li>
|
|
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> »</li>
|
|
<li class="nav-item nav-item-2"><a href="../../evennia.html" >evennia</a> »</li>
|
|
<li class="nav-item nav-item-this"><a href="">evennia.utils.evform</a></li>
|
|
</ul>
|
|
<div class="develop">develop branch</div>
|
|
</div>
|
|
<div class="footer" role="contentinfo">
|
|
© Copyright 2022, The Evennia developer community.
|
|
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
|
|
</div>
|
|
</body>
|
|
</html> |