diff options
author | Thijs Schreijer <thijs@thijsschreijer.nl> | 2018-11-22 18:41:22 +0300 |
---|---|---|
committer | Thijs Schreijer <thijs@thijsschreijer.nl> | 2018-11-23 23:08:28 +0300 |
commit | d70ac91eede03936db36b3fc31b62500242ed2e7 (patch) | |
tree | 20971375fd99be2b663b0379b58b9c2484debcda | |
parent | 2615db2914b46376a08e6045776e2206da390589 (diff) |
Release 1.6.01.6.0
Moved docs to ./docs for easy github publishing
Also added and fixed some additional links in the readme.
83 files changed, 31278 insertions, 26 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d3db742..161a7a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## 1.6.0 (not released yet) +## 1.6.0 (2018-11-23) ### New features @@ -10,6 +10,7 @@ - `utils.unpack` is now documented and respects `.n` field of its argument. - `tablex.deepcopy` and `tablex.deepcompare` are now cycle aware (#262) + - Installing through LuaRocks will now include the full rendered documentation ### Fixes @@ -29,7 +30,7 @@ ### Fixes - - Fixed `compat.execute` behaving differently on Lua 5.1 and 5,1+. + - Fixed `compat.execute` behaving differently on Lua 5.1 and 5.1+. - Fixed `lapp.process_options_string` setting global `success` variable. ## 1.5.3 (2017-07-16) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 90ea9e4..0ec775d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,7 +34,7 @@ you're doing, such as _"added-klingon-cloacking-device"_ - from `master` branch. If you wanna be a rockstar; -1. Update the [CHANGES.md](https://github.com/stevedonovan/Penlight/blob/master/CHANGES.md) file +1. Update the [CHANGELOG.md](https://github.com/stevedonovan/Penlight/blob/master/CHANGELOG.md) file 2. [Add tests](https://github.com/stevedonovan/Penlight/tree/master/tests) that show the defect your fix repairs, or that tests your new feature Please note - if you want to change multiple things that don't depend on each @@ -57,6 +57,10 @@ Python standard libraries. * `utils`: `utils.string_lambda` converts short strings like '|x| x^2' into functions * `comprehension`: list comprehensions: `C'x for x=1,4'()=={1,2,3,4}` +## License + +Penlight is distributed under the [MIT license](https://github.com/stevedonovan/Penlight/blob/master/LICENSE.md) + ## Installation Using [LuaRocks](https://luarocks.org): simply run `luarocks install penlight`. @@ -75,12 +79,17 @@ in Lua for Windows. ## Building the Documentation Requires [ldoc](https://github.com/stevedonovan/LDoc), which is available -through LuaRocks. Then it's a simple matter of running `ldoc` in the docs folder. +through LuaRocks. Then it's a simple matter of running `ldoc .` from the repo. + +## Contributing -``` -Penlight/docs$ ldoc . -``` +Contributions are most welcome, please check the [contribution guidelines](https://github.com/stevedonovan/Penlight/blob/master/CONTRIBUTING.md). ## Running tests Execute `lua run.lua tests` to run the tests. Execute `lua run.lua examples` to run examples. + +## History + +For a complete history of the development of Penlight, please check the +[changelog](https://github.com/stevedonovan/Penlight/blob/master/CHANGELOG.md). diff --git a/doc/config.ld b/config.ld index da115cb..e56ed2d 100644 --- a/doc/config.ld +++ b/config.ld @@ -1,20 +1,17 @@ project = 'Penlight' -description = 'Penlight Lua Libraries 1.5.4' +description = 'Penlight Lua Libraries 1.6.0' full_description = 'The documentation is available @{01-introduction.md|here}.' title = 'Penlight Documentation' -dir = 'api' +dir = 'docs' style = '!fixed' use_markdown_titles = true -topics = 'manual' -examples = {'../examples','../tests/test-data.lua'} +topics = 'docs_topics' +examples = {'./examples','./tests/test-data.lua'} package = 'pl' format = 'discount' sort_modules=true -file = '../lua/pl' +file = './lua/pl' kind_names={topic='Manual',module='Libraries'} tparam_alias('array','array') tparam_alias('array2d','array') alias('ret',{'return',modifiers={type="$1"}}) - - - diff --git a/docs/classes/pl.Date.html b/docs/classes/pl.Date.html new file mode 100644 index 0000000..2f35b94 --- /dev/null +++ b/docs/classes/pl.Date.html @@ -0,0 +1,1041 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#Methods">Methods</a></li> +</ul> + + +<h2>Classes</h2> +<ul class="nowrap"> + <li><strong>pl.Date</strong></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Class <code>pl.Date</code></h1> +<p>Date and Date Format classes.</p> +<p> See <a href="../manual/05-dates.md.html#">the Guide</a>.</p> + +<p> Dependencies: <a href="../libraries/pl.class.html#">pl.class</a>, <a href="../libraries/pl.stringx.html#">pl.stringx</a>, <a href="../libraries/pl.utils.html#">pl.utils</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#Date:set">Date:set (t)</a></td> + <td class="summary">set the current time of this Date object.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.tzone">Date.tzone (ts)</a></td> + <td class="summary">get the time zone offset from UTC.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:toUTC">Date:toUTC ()</a></td> + <td class="summary">convert this date to UTC.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:toLocal">Date:toLocal ()</a></td> + <td class="summary">convert this UTC date to local.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:year">Date:year (y)</a></td> + <td class="summary">set the year.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:month">Date:month (m)</a></td> + <td class="summary">set the month.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:day">Date:day (d)</a></td> + <td class="summary">set the day.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:hour">Date:hour (h)</a></td> + <td class="summary">set the hour.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:min">Date:min (min)</a></td> + <td class="summary">set the minutes.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:sec">Date:sec (sec)</a></td> + <td class="summary">set the seconds.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:yday">Date:yday (yday)</a></td> + <td class="summary">set the day of year.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:year">Date:year (y)</a></td> + <td class="summary">get the year.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:month">Date:month ()</a></td> + <td class="summary">get the month.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:day">Date:day ()</a></td> + <td class="summary">get the day.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:hour">Date:hour ()</a></td> + <td class="summary">get the hour.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:min">Date:min ()</a></td> + <td class="summary">get the minutes.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:sec">Date:sec ()</a></td> + <td class="summary">get the seconds.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:yday">Date:yday ()</a></td> + <td class="summary">get the day of year.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:weekday_name">Date:weekday_name (full)</a></td> + <td class="summary">name of day of week.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:month_name">Date:month_name (full)</a></td> + <td class="summary">name of month.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:is_weekend">Date:is_weekend ()</a></td> + <td class="summary">is this day on a weekend?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:add">Date:add (t)</a></td> + <td class="summary">add to a date object.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:last_day">Date:last_day ()</a></td> + <td class="summary">last day of the month.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:diff">Date:diff (other)</a></td> + <td class="summary">difference between two Date objects.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:__tostring">Date:__tostring ()</a></td> + <td class="summary">long numerical ISO data format version of this date.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:__eq">Date:__eq (other)</a></td> + <td class="summary">equality between Date objects.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:__lt">Date:__lt (other)</a></td> + <td class="summary">ordering between Date objects.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:__sub">Date:__sub ()</a></td> + <td class="summary">difference between Date objects.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date:__add">Date:__add (other)</a></td> + <td class="summary">add a date and an interval.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.Interval">Date.Interval (t)</a></td> + <td class="summary">Date.Interval constructor</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.Interval:__tostring">Date.Interval:__tostring ()</a></td> + <td class="summary">If it’s an interval then the format is ‘2 hours 29 sec’ etc.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.Format">Date.Format (fmt.)</a></td> + <td class="summary">Date.Format constructor.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.Format:parse">Date.Format:parse (str)</a></td> + <td class="summary">parse a string into a Date object.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.Format:tostring">Date.Format:tostring (d)</a></td> + <td class="summary">convert a Date object into a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Date.Format:US_order">Date.Format:US_order (yesno)</a></td> + <td class="summary">force US order in dates like 9/11/2001</td> + </tr> +</table> +<h2><a href="#Methods">Methods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.Date:Date">pl.Date:Date (t, ...)</a></td> + <td class="summary">Date constructor.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "Date:set"></a> + <strong>Date:set (t)</strong> + </dt> + <dd> + set the current time of this Date object. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">int</span></span> + seconds since epoch + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date.tzone"></a> + <strong>Date.tzone (ts)</strong> + </dt> + <dd> + get the time zone offset from UTC. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">ts</span> + <span class="types"><span class="type">int</span></span> + seconds ahead of UTC + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:toUTC"></a> + <strong>Date:toUTC ()</strong> + </dt> + <dd> + convert this date to UTC. + + + + + + + +</dd> + <dt> + <a name = "Date:toLocal"></a> + <strong>Date:toLocal ()</strong> + </dt> + <dd> + convert this UTC date to local. + + + + + + + +</dd> + <dt> + <a name = "Date:year"></a> + <strong>Date:year (y)</strong> + </dt> + <dd> + set the year. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">y</span> + <span class="types"><span class="type">int</span></span> + Four-digit year + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:month"></a> + <strong>Date:month (m)</strong> + </dt> + <dd> + set the month. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">m</span> + <span class="types"><span class="type">int</span></span> + month + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:day"></a> + <strong>Date:day (d)</strong> + </dt> + <dd> + set the day. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">d</span> + <span class="types"><span class="type">int</span></span> + day + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:hour"></a> + <strong>Date:hour (h)</strong> + </dt> + <dd> + set the hour. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">h</span> + <span class="types"><span class="type">int</span></span> + hour + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:min"></a> + <strong>Date:min (min)</strong> + </dt> + <dd> + set the minutes. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">min</span> + <span class="types"><span class="type">int</span></span> + minutes + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:sec"></a> + <strong>Date:sec (sec)</strong> + </dt> + <dd> + set the seconds. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">sec</span> + <span class="types"><span class="type">int</span></span> + seconds + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:yday"></a> + <strong>Date:yday (yday)</strong> + </dt> + <dd> + set the day of year. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">yday</span> + <span class="types"><span class="type">int</span></span> + day of year + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:year"></a> + <strong>Date:year (y)</strong> + </dt> + <dd> + get the year. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">y</span> + <span class="types"><span class="type">int</span></span> + Four-digit year + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:month"></a> + <strong>Date:month ()</strong> + </dt> + <dd> + get the month. + + + + + + + +</dd> + <dt> + <a name = "Date:day"></a> + <strong>Date:day ()</strong> + </dt> + <dd> + get the day. + + + + + + + +</dd> + <dt> + <a name = "Date:hour"></a> + <strong>Date:hour ()</strong> + </dt> + <dd> + get the hour. + + + + + + + +</dd> + <dt> + <a name = "Date:min"></a> + <strong>Date:min ()</strong> + </dt> + <dd> + get the minutes. + + + + + + + +</dd> + <dt> + <a name = "Date:sec"></a> + <strong>Date:sec ()</strong> + </dt> + <dd> + get the seconds. + + + + + + + +</dd> + <dt> + <a name = "Date:yday"></a> + <strong>Date:yday ()</strong> + </dt> + <dd> + get the day of year. + + + + + + + +</dd> + <dt> + <a name = "Date:weekday_name"></a> + <strong>Date:weekday_name (full)</strong> + </dt> + <dd> + name of day of week. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">full</span> + <span class="types"><span class="type">bool</span></span> + abbreviated if true, full otherwise. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + name + </ol> + + + + +</dd> + <dt> + <a name = "Date:month_name"></a> + <strong>Date:month_name (full)</strong> + </dt> + <dd> + name of month. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">full</span> + <span class="types"><span class="type">int</span></span> + abbreviated if true, full otherwise. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + name + </ol> + + + + +</dd> + <dt> + <a name = "Date:is_weekend"></a> + <strong>Date:is_weekend ()</strong> + </dt> + <dd> + is this day on a weekend?. + + + + + + + +</dd> + <dt> + <a name = "Date:add"></a> + <strong>Date:add (t)</strong> + </dt> + <dd> + add to a date object. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + a table containing one of the following keys and a value: + one of <a href="../classes/pl.Date.html#Date:year">year</a>,<a href="../classes/pl.Date.html#Date:month">month</a>,<a href="../classes/pl.Date.html#Date:day">day</a>,<a href="../classes/pl.Date.html#Date:hour">hour</a>,<a href="../classes/pl.Date.html#Date:min">min</a>,<a href="../classes/pl.Date.html#Date:sec">sec</a> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + this date + </ol> + + + + +</dd> + <dt> + <a name = "Date:last_day"></a> + <strong>Date:last_day ()</strong> + </dt> + <dd> + last day of the month. + + + + <h3>Returns:</h3> + <ol> + + int day + </ol> + + + + +</dd> + <dt> + <a name = "Date:diff"></a> + <strong>Date:diff (other)</strong> + </dt> + <dd> + difference between two Date objects. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">other</span> + <span class="types"><a class="type" href="../classes/pl.Date.html">Date</a></span> + Date object + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="../classes/pl.Date.html#Date.Interval">Date.Interval</a></span> + object + </ol> + + + + +</dd> + <dt> + <a name = "Date:__tostring"></a> + <strong>Date:__tostring ()</strong> + </dt> + <dd> + long numerical ISO data format version of this date. + + + + + + + +</dd> + <dt> + <a name = "Date:__eq"></a> + <strong>Date:__eq (other)</strong> + </dt> + <dd> + equality between Date objects. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">other</span> + + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:__lt"></a> + <strong>Date:__lt (other)</strong> + </dt> + <dd> + ordering between Date objects. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">other</span> + + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date:__sub"></a> + <strong>Date:__sub ()</strong> + </dt> + <dd> + difference between Date objects. + + + + + + + +</dd> + <dt> + <a name = "Date:__add"></a> + <strong>Date:__add (other)</strong> + </dt> + <dd> + add a date and an interval. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">other</span> + either a <a href="../classes/pl.Date.html#Date.Interval">Date.Interval</a> object or a table such as + passed to <a href="../classes/pl.Date.html#Date:add">Date:add</a> + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date.Interval"></a> + <strong>Date.Interval (t)</strong> + </dt> + <dd> + Date.Interval constructor + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">int</span></span> + an interval in seconds + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Date.Interval:__tostring"></a> + <strong>Date.Interval:__tostring ()</strong> + </dt> + <dd> + If it’s an interval then the format is ‘2 hours 29 sec’ etc. + + + + + + + +</dd> + <dt> + <a name = "Date.Format"></a> + <strong>Date.Format (fmt.)</strong> + </dt> + <dd> + Date.Format constructor. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fmt.</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A string where the following fields are significant:</p> + +<ul> +<li> d day (either d or dd)</li> +<li> y year (either yy or yyy)</li> +<li> m month (either m or mm)</li> +<li> H hour (either H or HH)</li> +<li> M minute (either M or MM)</li> +<li> S second (either S or SS)</li> +</ul> + + +<p> Alternatively, if fmt is nil then this returns a flexible date parser + that tries various date/time schemes in turn:</p> + +<ul> +<li><a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>, like <code>2010-05-10 12:35:23Z</code> or <code>2008-10-03T14:30+02</code></li> +<li>times like 15:30 or 8.05pm (assumed to be today’s date)</li> +<li>dates like 28/10/02 (European order!) or 5 Feb 2012</li> +<li>month name like march or Mar (case-insensitive, first 3 letters); here the +day will be 1 and the year this current year</li> +</ul> + + +<p> A date in format 3 can be optionally followed by a time in format 2. + Please see test-date.lua in the tests folder for more examples. + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">df = Date.Format(<span class="string">"yyyy-mm-dd HH:MM:SS"</span>)</pre> + </ul> + +</dd> + <dt> + <a name = "Date.Format:parse"></a> + <strong>Date.Format:parse (str)</strong> + </dt> + <dd> + parse a string into a Date object. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">str</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a date string + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + date object + </ol> + + + + +</dd> + <dt> + <a name = "Date.Format:tostring"></a> + <strong>Date.Format:tostring (d)</strong> + </dt> + <dd> + convert a Date object into a string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">d</span> + a date object, or a time value as returned by <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.time">os.time</a> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + string + </ol> + + + + +</dd> + <dt> + <a name = "Date.Format:US_order"></a> + <strong>Date.Format:US_order (yesno)</strong> + </dt> + <dd> + force US order in dates like 9/11/2001 + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">yesno</span> + + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Methods"></a>Methods</h2> + + <dl class="function"> + <dt> + <a name = "pl.Date:Date"></a> + <strong>pl.Date:Date (t, ...)</strong> + </dt> + <dd> + Date constructor. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <p> this can be either</p> + +<ul> +<li> <code>nil</code> or empty - use current date and time</li> +<li> number - seconds since epoch (as returned by <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.time">os.time</a>). Resulting time is UTC</li> +<li> <a href="../classes/pl.Date.html">Date</a> - make a copy of this date</li> +<li> table - table containing year, month, etc as for <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.time">os.time</a>. You may leave out year, month or day, +in which case current values will be used.</li> +<li> year (will be followed by month, day etc)</li> +</ul> + + </li> + <li><span class="parameter">...</span> + true if Universal Coordinated Time, or two to five numbers: month,day,hour,min,sec + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/classes/pl.List.html b/docs/classes/pl.List.html new file mode 100644 index 0000000..acc8e54 --- /dev/null +++ b/docs/classes/pl.List.html @@ -0,0 +1,1444 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#metamethods">metamethods</a></li> +</ul> + + +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><strong>pl.List</strong></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Class <code>pl.List</code></h1> +<p>Python-style list class.</p> +<p> <strong>Please Note</strong>: methods that change the list will return the list. + This is to allow for method chaining, but please note that <code>ls = ls:sort()</code> + does not mean that a new copy of the list is made. In-place (mutable) methods + are marked as returning ‘the list’ in this documentation.</p> + +<p> See the Guide for further <a href="../manual/02-arrays.md.html#Python_style_Lists">discussion</a></p> + +<p> See <a href="http://www.python.org/doc/current/tut/tut.html">http://www.python.org/doc/current/tut/tut.html</a>, section 5.1</p> + +<p> <strong>Note</strong>: The comments before some of the functions are from the Python docs + and contain Python code.</p> + +<p> Written for Lua version Nick Trout 4.0; Redone for Lua 5.1, Steve Donovan.</p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a>, <a href="../libraries/pl.class.html#">pl.class</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#List.new">List.new ([t])</a></td> + <td class="summary">Create a new list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:clone">List:clone ()</a></td> + <td class="summary">Make a copy of an existing list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:append">List:append (i)</a></td> + <td class="summary">Add an item to the end of the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:extend">List:extend (L)</a></td> + <td class="summary">Extend the list by appending all the items in the given list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:insert">List:insert (i, x)</a></td> + <td class="summary">Insert an item at a given position.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:put">List:put (x)</a></td> + <td class="summary">Insert an item at the begining of the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:remove">List:remove (i)</a></td> + <td class="summary">Remove an element given its index.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:remove_value">List:remove_value (x)</a></td> + <td class="summary">Remove the first item from the list whose value is given.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:pop">List:pop ([i])</a></td> + <td class="summary">Remove the item at the given position in the list, and return it.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:index">List:index (x[, idx=1])</a></td> + <td class="summary">Return the index in the list of the first item whose value is given.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:contains">List:contains (x)</a></td> + <td class="summary">Does this list contain the value?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:count">List:count (x)</a></td> + <td class="summary">Return the number of times value appears in the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:sort">List:sort ([cmp='<'])</a></td> + <td class="summary">Sort the items of the list, in place.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:sorted">List:sorted ([cmp='<'])</a></td> + <td class="summary">Return a sorted copy of this list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:reverse">List:reverse ()</a></td> + <td class="summary">Reverse the elements of the list, in place.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:minmax">List:minmax ()</a></td> + <td class="summary">Return the minimum and the maximum value of the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:slice">List:slice (first, last)</a></td> + <td class="summary">Emulate list slicing.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:clear">List:clear ()</a></td> + <td class="summary">Empty the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List.range">List.range (start[, finish[, incr=1]])</a></td> + <td class="summary">Emulate Python’s range(x) function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:len">List:len ()</a></td> + <td class="summary">list:len() is the same as #list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:chop">List:chop (i1, i2)</a></td> + <td class="summary">Remove a subrange of elements.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:splice">List:splice (idx, list)</a></td> + <td class="summary">Insert a sublist into a list + equivalent to ’s[idx:idx] = list' in Python</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:slice_assign">List:slice_assign (i1, i2, seq)</a></td> + <td class="summary">General slice assignment s[i1:i2] = seq.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:join">List:join ([delim=''])</a></td> + <td class="summary">Join the elements of a list using a delimiter.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:concat">List:concat ([delim=''])</a></td> + <td class="summary">Join a list of strings.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:foreach">List:foreach (fun, ...)</a></td> + <td class="summary">Call the function on each element of the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:foreachm">List:foreachm (name, ...)</a></td> + <td class="summary">Call the named method on each element of the list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:filter">List:filter (fun[, arg])</a></td> + <td class="summary">Create a list of all elements which match a function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List.split">List.split (s[, delim])</a></td> + <td class="summary">Split a string using a delimiter.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:map">List:map (fun, ...)</a></td> + <td class="summary">Apply a function to all elements.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:transform">List:transform (fun, ...)</a></td> + <td class="summary">Apply a function to all elements, in-place.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:map2">List:map2 (fun, ls, ...)</a></td> + <td class="summary">Apply a function to elements of two lists.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:mapm">List:mapm (name, ...)</a></td> + <td class="summary">apply a named method to all elements.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:reduce">List:reduce (fun)</a></td> + <td class="summary">‘reduce’ a list using a binary function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:partition">List:partition (fun, ...)</a></td> + <td class="summary">Partition a list using a classifier function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:iter">List:iter ()</a></td> + <td class="summary">return an iterator over all values.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List.iterate">List.iterate (seq)</a></td> + <td class="summary">Create an iterator over a seqence.</td> + </tr> +</table> +<h2><a href="#metamethods">metamethods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#List:__concat">List:__concat (L)</a></td> + <td class="summary">Concatenation operator.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:__eq">List:__eq (L)</a></td> + <td class="summary">Equality operator ==.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#List:__tostring">List:__tostring ()</a></td> + <td class="summary">How our list should be rendered as a string.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "List.new"></a> + <strong>List.new ([t])</strong> + </dt> + <dd> + Create a new list. Can optionally pass a table; + passing another instance of List will cause a copy to be created; + this will return a plain table with an appropriate metatable. + we pass anything which isn’t a simple table to iterate() to work out + an appropriate iterator + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + An optional list-like table + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new List + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../classes/pl.List.html#List.iterate">List.iterate</a> + </ul> + + <h3>Usage:</h3> + <ul> + <pre class="example">ls = List(); ls = List {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "List:clone"></a> + <strong>List:clone ()</strong> + </dt> + <dd> + Make a copy of an existing list. + The difference from a plain ‘copy constructor’ is that this returns + the actual List subtype. + + + + + + + +</dd> + <dt> + <a name = "List:append"></a> + <strong>List:append (i)</strong> + </dt> + <dd> + Add an item to the end of the list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">i</span> + An item + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:extend"></a> + <strong>List:extend (L)</strong> + </dt> + <dd> + Extend the list by appending all the items in the given list. + equivalent to ‘a[len(a):] = L’. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">L</span> + <span class="types"><a class="type" href="../classes/pl.List.html">List</a></span> + Another List + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:insert"></a> + <strong>List:insert (i, x)</strong> + </dt> + <dd> + Insert an item at a given position. i is the index of the + element before which to insert. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">i</span> + <span class="types"><span class="type">int</span></span> + index of element before whichh to insert + </li> + <li><span class="parameter">x</span> + A data item + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:put"></a> + <strong>List:put (x)</strong> + </dt> + <dd> + Insert an item at the begining of the list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + a data item + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:remove"></a> + <strong>List:remove (i)</strong> + </dt> + <dd> + Remove an element given its index. + (equivalent of Python’s del s[i]) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">i</span> + <span class="types"><span class="type">int</span></span> + the index + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:remove_value"></a> + <strong>List:remove_value (x)</strong> + </dt> + <dd> + Remove the first item from the list whose value is given. + (This is called ‘remove’ in Python; renamed to avoid confusion + with table.remove) + Return nil if there is no such item. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + A data value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:pop"></a> + <strong>List:pop ([i])</strong> + </dt> + <dd> + Remove the item at the given position in the list, and return it. + If no index is specified, a:pop() returns the last item in the list. + The item is also removed from the list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">i</span> + <span class="types"><span class="type">int</span></span> + An index + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the item + </ol> + + + + +</dd> + <dt> + <a name = "List:index"></a> + <strong>List:index (x[, idx=1])</strong> + </dt> + <dd> + Return the index in the list of the first item whose value is given. + Return nil if there is no such item. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + A data value + </li> + <li><span class="parameter">idx</span> + <span class="types"><span class="type">int</span></span> + where to start search + (<em>default</em> 1) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the index, or nil if not found. + </ol> + + + + +</dd> + <dt> + <a name = "List:contains"></a> + <strong>List:contains (x)</strong> + </dt> + <dd> + Does this list contain the value? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + A data value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "List:count"></a> + <strong>List:count (x)</strong> + </dt> + <dd> + Return the number of times value appears in the list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + A data value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + number of times x appears + </ol> + + + + +</dd> + <dt> + <a name = "List:sort"></a> + <strong>List:sort ([cmp='<'])</strong> + </dt> + <dd> + Sort the items of the list, in place. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cmp</span> + <span class="types"><span class="type">func</span></span> + an optional comparison function + (<em>default</em> '<') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:sorted"></a> + <strong>List:sorted ([cmp='<'])</strong> + </dt> + <dd> + Return a sorted copy of this list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cmp</span> + <span class="types"><span class="type">func</span></span> + an optional comparison function + (<em>default</em> '<') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new list + </ol> + + + + +</dd> + <dt> + <a name = "List:reverse"></a> + <strong>List:reverse ()</strong> + </dt> + <dd> + Reverse the elements of the list, in place. + + + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:minmax"></a> + <strong>List:minmax ()</strong> + </dt> + <dd> + Return the minimum and the maximum value of the list. + + + + <h3>Returns:</h3> + <ol> + <li> + minimum value</li> + <li> + maximum value</li> + </ol> + + + + +</dd> + <dt> + <a name = "List:slice"></a> + <strong>List:slice (first, last)</strong> + </dt> + <dd> + Emulate list slicing. like ‘list[first:last]’ in Python. + If first or last are negative then they are relative to the end of the list + eg. slice(-2) gives last 2 entries in a list, and + slice(-4,-2) gives from -4th to -2nd + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">first</span> + An index + </li> + <li><span class="parameter">last</span> + An index + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new List + </ol> + + + + +</dd> + <dt> + <a name = "List:clear"></a> + <strong>List:clear ()</strong> + </dt> + <dd> + Empty the list. + + + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List.range"></a> + <strong>List.range (start[, finish[, incr=1]])</strong> + </dt> + <dd> + Emulate Python’s range(x) function. + Include it in List table for tidiness + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">start</span> + <span class="types"><span class="type">int</span></span> + A number + </li> + <li><span class="parameter">finish</span> + <span class="types"><span class="type">int</span></span> + A number greater than start; if absent, + then start is 1 and finish is start + (<em>optional</em>) + </li> + <li><span class="parameter">incr</span> + <span class="types"><span class="type">int</span></span> + an increment (may be less than 1) + (<em>default</em> 1) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a List from start .. finish + </ol> + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">List.range(<span class="number">0</span>,<span class="number">3</span>) == List{<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}</pre></li> + <li><pre class="example">List.range(<span class="number">4</span>) = List{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}</pre></li> + <li><pre class="example">List.range(<span class="number">5</span>,<span class="number">1</span>,-<span class="number">1</span>) == List{<span class="number">5</span>,<span class="number">4</span>,<span class="number">3</span>,<span class="number">2</span>,<span class="number">1</span>}</pre></li> + </ul> + +</dd> + <dt> + <a name = "List:len"></a> + <strong>List:len ()</strong> + </dt> + <dd> + list:len() is the same as #list. + + + + + + + +</dd> + <dt> + <a name = "List:chop"></a> + <strong>List:chop (i1, i2)</strong> + </dt> + <dd> + Remove a subrange of elements. + equivalent to ‘del s[i1:i2]’ in Python. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start of range + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end of range + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:splice"></a> + <strong>List:splice (idx, list)</strong> + </dt> + <dd> + Insert a sublist into a list + equivalent to ’s[idx:idx] = list' in Python + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">idx</span> + <span class="types"><span class="type">int</span></span> + index + </li> + <li><span class="parameter">list</span> + <span class="types"><a class="type" href="../classes/pl.List.html">List</a></span> + list to insert + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">l = List{<span class="number">10</span>,<span class="number">20</span>}; l:splice(<span class="number">2</span>,{<span class="number">21</span>,<span class="number">22</span>}); <span class="global">assert</span>(l == List{<span class="number">10</span>,<span class="number">21</span>,<span class="number">22</span>,<span class="number">20</span>})</pre> + </ul> + +</dd> + <dt> + <a name = "List:slice_assign"></a> + <strong>List:slice_assign (i1, i2, seq)</strong> + </dt> + <dd> + General slice assignment s[i1:i2] = seq. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start index + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end index + </li> + <li><span class="parameter">seq</span> + <span class="types"><a class="type" href="../classes/pl.List.html">List</a></span> + a list + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list + </ol> + + + + +</dd> + <dt> + <a name = "List:join"></a> + <strong>List:join ([delim=''])</strong> + </dt> + <dd> + Join the elements of a list using a delimiter. + This method uses tostring on all elements. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a delimiter string, can be empty. + (<em>default</em> '') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string + </ol> + + + + +</dd> + <dt> + <a name = "List:concat"></a> + <strong>List:concat ([delim=''])</strong> + </dt> + <dd> + Join a list of strings. <br> + Uses <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.concat">table.concat</a> directly. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a delimiter + (<em>default</em> '') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string + </ol> + + + + +</dd> + <dt> + <a name = "List:foreach"></a> + <strong>List:foreach (fun, ...)</strong> + </dt> + <dd> + Call the function on each element of the list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function or callable object + </li> + <li><span class="parameter">...</span> + optional values to pass to function + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "List:foreachm"></a> + <strong>List:foreachm (name, ...)</strong> + </dt> + <dd> + Call the named method on each element of the list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">name</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the method name + </li> + <li><span class="parameter">...</span> + optional values to pass to function + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "List:filter"></a> + <strong>List:filter (fun[, arg])</strong> + </dt> + <dd> + Create a list of all elements which match a function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a boolean function + </li> + <li><span class="parameter">arg</span> + optional argument to be passed as second argument of the predicate + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new filtered list. + </ol> + + + + +</dd> + <dt> + <a name = "List.split"></a> + <strong>List.split (s[, delim])</strong> + </dt> + <dd> + Split a string using a delimiter. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the delimiter (default spaces) + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a List of strings + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.utils.html#split">pl.utils.split</a> + </ul> + + +</dd> + <dt> + <a name = "List:map"></a> + <strong>List:map (fun, ...)</strong> + </dt> + <dd> + Apply a function to all elements. + Any extra arguments will be passed to the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of at least one argument + </li> + <li><span class="parameter">...</span> + arbitrary extra arguments. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new list: {f(x) for x in self} + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#imap">pl.tablex.imap</a> + </ul> + + <h3>Usage:</h3> + <ul> + <pre class="example">List{<span class="string">'one'</span>,<span class="string">'two'</span>}:map(<span class="global">string</span>.upper) == {<span class="string">'ONE'</span>,<span class="string">'TWO'</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "List:transform"></a> + <strong>List:transform (fun, ...)</strong> + </dt> + <dd> + Apply a function to all elements, in-place. + Any extra arguments are passed to the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + A function that takes at least one argument + </li> + <li><span class="parameter">...</span> + arbitrary extra arguments. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the list. + </ol> + + + + +</dd> + <dt> + <a name = "List:map2"></a> + <strong>List:map2 (fun, ls, ...)</strong> + </dt> + <dd> + Apply a function to elements of two lists. + Any extra arguments will be passed to the function + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of at least two arguments + </li> + <li><span class="parameter">ls</span> + <span class="types"><a class="type" href="../classes/pl.List.html">List</a></span> + another list + </li> + <li><span class="parameter">...</span> + arbitrary extra arguments. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new list: {f(x,y) for x in self, for x in arg1} + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#imap2">pl.tablex.imap2</a> + </ul> + + +</dd> + <dt> + <a name = "List:mapm"></a> + <strong>List:mapm (name, ...)</strong> + </dt> + <dd> + apply a named method to all elements. + Any extra arguments will be passed to the method. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">name</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + name of method + </li> + <li><span class="parameter">...</span> + extra arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new list of the results + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.seq.html#mapmethod">pl.seq.mapmethod</a> + </ul> + + +</dd> + <dt> + <a name = "List:reduce"></a> + <strong>List:reduce (fun)</strong> + </dt> + <dd> + ‘reduce’ a list using a binary function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of two arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + result of the function + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#reduce">pl.tablex.reduce</a> + </ul> + + +</dd> + <dt> + <a name = "List:partition"></a> + <strong>List:partition (fun, ...)</strong> + </dt> + <dd> + Partition a list using a classifier function. + The function may return nil, but this will be converted to the string key ‘<nil>’. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of at least one argument + </li> + <li><span class="parameter">...</span> + will also be passed to the function + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="../classes/pl.MultiMap.html">MultiMap</a></span> + a table where the keys are the returned values, and the values are Lists + of values where the function returned that key. + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../classes/pl.MultiMap.html#">pl.MultiMap</a> + </ul> + + +</dd> + <dt> + <a name = "List:iter"></a> + <strong>List:iter ()</strong> + </dt> + <dd> + return an iterator over all values. + + + + + + + +</dd> + <dt> + <a name = "List.iterate"></a> + <strong>List.iterate (seq)</strong> + </dt> + <dd> + Create an iterator over a seqence. + This captures the Python concept of ‘sequence’. + For tables, iterates over all values with integer indices. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">seq</span> + a sequence; a string (over characters), a table, a file object (over lines) or an iterator function + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example"><span class="keyword">for</span> x <span class="keyword">in</span> iterate {<span class="number">1</span>,<span class="number">10</span>,<span class="number">22</span>,<span class="number">55</span>} <span class="keyword">do</span> <span class="global">io</span>.write(x,<span class="string">','</span>) <span class="keyword">end</span> ==> <span class="number">1</span>,<span class="number">10</span>,<span class="number">22</span>,<span class="number">55</span></pre></li> + <li><pre class="example"><span class="keyword">for</span> ch <span class="keyword">in</span> iterate <span class="string">'help'</span> <span class="keyword">do</span> <span class="keyword">do</span> <span class="global">io</span>.write(ch,<span class="string">' '</span>) <span class="keyword">end</span> ==> h e l p</pre></li> + </ul> + +</dd> +</dl> + <h2 class="section-header "><a name="metamethods"></a>metamethods</h2> + + <dl class="function"> + <dt> + <a name = "List:__concat"></a> + <strong>List:__concat (L)</strong> + </dt> + <dd> + Concatenation operator. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">L</span> + <span class="types"><a class="type" href="../classes/pl.List.html">List</a></span> + another List + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new list consisting of the list with the elements of the new list appended + </ol> + + + + +</dd> + <dt> + <a name = "List:__eq"></a> + <strong>List:__eq (L)</strong> + </dt> + <dd> + Equality operator ==. True iff all elements of two lists are equal. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">L</span> + <span class="types"><a class="type" href="../classes/pl.List.html">List</a></span> + another List + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "List:__tostring"></a> + <strong>List:__tostring ()</strong> + </dt> + <dd> + How our list should be rendered as a string. Uses join(). + + + + + + <h3>See also:</h3> + <ul> + <a href="../classes/pl.List.html#List:join">List:join</a> + </ul> + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/classes/pl.Map.html b/docs/classes/pl.Map.html new file mode 100644 index 0000000..98becae --- /dev/null +++ b/docs/classes/pl.Map.html @@ -0,0 +1,419 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Fields">Fields</a></li> +<li><a href="#Methods">Methods</a></li> +<li><a href="#Metamethods">Metamethods</a></li> +</ul> + + +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><strong>pl.Map</strong></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Class <code>pl.Map</code></h1> +<p>A Map class.</p> +<p> + +<pre> +> Map = <span class="global">require</span> <span class="string">'pl.Map'</span> +> m = Map{one=<span class="number">1</span>,two=<span class="number">2</span>} +> m:update {three=<span class="number">3</span>,four=<span class="number">4</span>,two=<span class="number">20</span>} +> = m == M{one=<span class="number">1</span>,two=<span class="number">20</span>,three=<span class="number">3</span>,four=<span class="number">4</span>} +<span class="keyword">true</span> +</pre> + + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.class.html#">pl.class</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a>, <a href="../libraries/pl.pretty.html#">pl.pretty</a></p></p> + + +<h2><a href="#Fields">Fields</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.Map.keys">pl.Map.keys</a></td> + <td class="summary">list of keys.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map.values">pl.Map.values</a></td> + <td class="summary">list of values.</td> + </tr> +</table> +<h2><a href="#Methods">Methods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.Map:iter">pl.Map:iter ()</a></td> + <td class="summary">return an iterator over all key-value pairs.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:items">pl.Map:items ()</a></td> + <td class="summary">return a List of all key-value pairs, sorted by the keys.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:len">pl.Map:len ()</a></td> + <td class="summary">size of map.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:set">pl.Map:set (key, val)</a></td> + <td class="summary">put a value into the map.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:get">pl.Map:get (key)</a></td> + <td class="summary">get a value from the map.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:getvalues">pl.Map:getvalues (keys)</a></td> + <td class="summary">get a list of values indexed by a list of keys.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:update">pl.Map:update (table)</a></td> + <td class="summary">update the map using key/value pairs from another table.</td> + </tr> +</table> +<h2><a href="#Metamethods">Metamethods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.Map:__eq">pl.Map:__eq (m)</a></td> + <td class="summary">equality between maps.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.Map:__tostring">pl.Map:__tostring ()</a></td> + <td class="summary">string representation of a map.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Fields"></a>Fields</h2> + + <dl class="function"> + <dt> + <a name = "pl.Map.keys"></a> + <strong>pl.Map.keys</strong> + </dt> + <dd> + list of keys. + + + + + + + +</dd> + <dt> + <a name = "pl.Map.values"></a> + <strong>pl.Map.values</strong> + </dt> + <dd> + list of values. + + + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Methods"></a>Methods</h2> + + <dl class="function"> + <dt> + <a name = "pl.Map:iter"></a> + <strong>pl.Map:iter ()</strong> + </dt> + <dd> + return an iterator over all key-value pairs. + + + + + + + +</dd> + <dt> + <a name = "pl.Map:items"></a> + <strong>pl.Map:items ()</strong> + </dt> + <dd> + return a List of all key-value pairs, sorted by the keys. + + + + + + + +</dd> + <dt> + <a name = "pl.Map:len"></a> + <strong>pl.Map:len ()</strong> + </dt> + <dd> + size of map. + note: this is a relatively expensive operation! + + + + + + + +</dd> + <dt> + <a name = "pl.Map:set"></a> + <strong>pl.Map:set (key, val)</strong> + </dt> + <dd> + put a value into the map. + This will remove the key if the value is <code>nil</code> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">key</span> + the key + </li> + <li><span class="parameter">val</span> + the value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "pl.Map:get"></a> + <strong>pl.Map:get (key)</strong> + </dt> + <dd> + get a value from the map. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">key</span> + the key + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the value, or nil if not found. + </ol> + + + + +</dd> + <dt> + <a name = "pl.Map:getvalues"></a> + <strong>pl.Map:getvalues (keys)</strong> + </dt> + <dd> + get a list of values indexed by a list of keys. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">keys</span> + a list-like table of keys + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new list + </ol> + + + + +</dd> + <dt> + <a name = "pl.Map:update"></a> + <strong>pl.Map:update (table)</strong> + </dt> + <dd> + update the map using key/value pairs from another table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">table</span> + <span class="types"><span class="type">tab</span></span> + + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Metamethods"></a>Metamethods</h2> + + <dl class="function"> + <dt> + <a name = "pl.Map:__eq"></a> + <strong>pl.Map:__eq (m)</strong> + </dt> + <dd> + equality between maps. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">m</span> + <span class="types"><a class="type" href="../classes/pl.Map.html">Map</a></span> + another map. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "pl.Map:__tostring"></a> + <strong>pl.Map:__tostring ()</strong> + </dt> + <dd> + string representation of a map. + + + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/classes/pl.MultiMap.html b/docs/classes/pl.MultiMap.html new file mode 100644 index 0000000..21835cf --- /dev/null +++ b/docs/classes/pl.MultiMap.html @@ -0,0 +1,208 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Methods">Methods</a></li> +</ul> + + +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><strong>pl.MultiMap</strong></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Class <code>pl.MultiMap</code></h1> +<p>MultiMap, a Map which has multiple values per key.</p> +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.class.html#">pl.class</a>, <a href="../classes/pl.List.html#">pl.List</a>, <a href="../classes/pl.Map.html#">pl.Map</a></p> + + +<h2><a href="#Methods">Methods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.MultiMap:update">pl.MultiMap:update (t)</a></td> + <td class="summary">update a MultiMap using a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.MultiMap:set">pl.MultiMap:set (key, val)</a></td> + <td class="summary">add a new value to a key.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Methods"></a>Methods</h2> + + <dl class="function"> + <dt> + <a name = "pl.MultiMap:update"></a> + <strong>pl.MultiMap:update (t)</strong> + </dt> + <dd> + update a MultiMap using a table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + either a Multimap or a map-like table. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the map + </ol> + + + + +</dd> + <dt> + <a name = "pl.MultiMap:set"></a> + <strong>pl.MultiMap:set (key, val)</strong> + </dt> + <dd> + add a new value to a key. Setting a nil value removes the key. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">key</span> + the key + </li> + <li><span class="parameter">val</span> + the value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the map + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/classes/pl.OrderedMap.html b/docs/classes/pl.OrderedMap.html new file mode 100644 index 0000000..6f26905 --- /dev/null +++ b/docs/classes/pl.OrderedMap.html @@ -0,0 +1,418 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Methods">Methods</a></li> +<li><a href="#Metamethods">Metamethods</a></li> +</ul> + + +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><strong>pl.OrderedMap</strong></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Class <code>pl.OrderedMap</code></h1> +<p>OrderedMap, a map which preserves ordering.</p> +<p> Derived from <a href="../classes/pl.Map.html#">pl.Map</a>.</p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a>, <a href="../libraries/pl.class.html#">pl.class</a>, <a href="../classes/pl.List.html#">pl.List</a>, <a href="../classes/pl.Map.html#">pl.Map</a></p> + + +<h2><a href="#Methods">Methods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:_init">pl.OrderedMap:_init (t)</a></td> + <td class="summary">construct an OrderedMap.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:update">pl.OrderedMap:update (t)</a></td> + <td class="summary">update an OrderedMap using a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:set">pl.OrderedMap:set (key, val)</a></td> + <td class="summary">set the key’s value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:insert">pl.OrderedMap:insert (pos, key, val)</a></td> + <td class="summary">insert a key/value pair before a given position.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:keys">pl.OrderedMap:keys ()</a></td> + <td class="summary">return the keys in order.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:values">pl.OrderedMap:values ()</a></td> + <td class="summary">return the values in order.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:sort">pl.OrderedMap:sort (cmp)</a></td> + <td class="summary">sort the keys.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:iter">pl.OrderedMap:iter ()</a></td> + <td class="summary">iterate over key-value pairs in order.</td> + </tr> +</table> +<h2><a href="#Metamethods">Metamethods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:__pairs">pl.OrderedMap:__pairs ()</a></td> + <td class="summary">iterate over an ordered map (5.2).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pl.OrderedMap:__tostring">pl.OrderedMap:__tostring ()</a></td> + <td class="summary">string representation of an ordered map.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Methods"></a>Methods</h2> + + <dl class="function"> + <dt> + <a name = "pl.OrderedMap:_init"></a> + <strong>pl.OrderedMap:_init (t)</strong> + </dt> + <dd> + construct an OrderedMap. + Will throw an error if the argument is bad. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + optional initialization table, same as for <a href="../classes/pl.OrderedMap.html#pl.OrderedMap:update">OrderedMap:update</a> + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:update"></a> + <strong>pl.OrderedMap:update (t)</strong> + </dt> + <dd> + update an OrderedMap using a table. + If the table is itself an OrderedMap, then its entries will be appended. + if it s a table of the form <code>{{key1=val1},{key2=val2},…}</code> these will be appended.</p> + +<p> Otherwise, it is assumed to be a map-like table, and order of extra entries is arbitrary. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + a table. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + the map, or nil in case of error</li> + <li> + the error message</li> + </ol> + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:set"></a> + <strong>pl.OrderedMap:set (key, val)</strong> + </dt> + <dd> + set the key’s value. This key will be appended at the end of the map.</p> + +<p> If the value is nil, then the key is removed. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">key</span> + the key + </li> + <li><span class="parameter">val</span> + the value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the map + </ol> + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:insert"></a> + <strong>pl.OrderedMap:insert (pos, key, val)</strong> + </dt> + <dd> + insert a key/value pair before a given position. + Note: if the map already contains the key, then this effectively + moves the item to the new position by first removing at the old position. + Has no effect if the key does not exist and val is nil + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">pos</span> + <span class="types"><span class="type">int</span></span> + a position starting at 1 + </li> + <li><span class="parameter">key</span> + the key + </li> + <li><span class="parameter">val</span> + the value; if nil use the old value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:keys"></a> + <strong>pl.OrderedMap:keys ()</strong> + </dt> + <dd> + return the keys in order. + (Not a copy!) + + + + <h3>Returns:</h3> + <ol> + + List + </ol> + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:values"></a> + <strong>pl.OrderedMap:values ()</strong> + </dt> + <dd> + return the values in order. + this is relatively expensive. + + + + <h3>Returns:</h3> + <ol> + + List + </ol> + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:sort"></a> + <strong>pl.OrderedMap:sort (cmp)</strong> + </dt> + <dd> + sort the keys. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cmp</span> + <span class="types"><span class="type">func</span></span> + a comparison function as for <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.sort">table.sort</a> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the map + </ol> + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:iter"></a> + <strong>pl.OrderedMap:iter ()</strong> + </dt> + <dd> + iterate over key-value pairs in order. + + + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Metamethods"></a>Metamethods</h2> + + <dl class="function"> + <dt> + <a name = "pl.OrderedMap:__pairs"></a> + <strong>pl.OrderedMap:__pairs ()</strong> + </dt> + <dd> + iterate over an ordered map (5.2). + + + + + + + +</dd> + <dt> + <a name = "pl.OrderedMap:__tostring"></a> + <strong>pl.OrderedMap:__tostring ()</strong> + </dt> + <dd> + string representation of an ordered map. + + + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/seesubst.lua.html b/docs/examples/seesubst.lua.html new file mode 100644 index 0000000..3ff98aa --- /dev/null +++ b/docs/examples/seesubst.lua.html @@ -0,0 +1,175 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><strong>seesubst.lua</strong></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>seesubst.lua</h2> +<pre> +<span class="comment">-- shows how replacing '@see module' in the Markdown documentation +</span><span class="comment">-- can be done more elegantly using PL. +</span><span class="comment">-- We either have something like 'pl.config' (a module reference) +</span><span class="comment">-- or 'pl.seq.map' (a function reference); these cases must be distinguished +</span><span class="comment">-- and a Markdown link generated pointing to the LuaDoc file. +</span> +<span class="keyword">local</span> sip = <span class="global">require</span> <span class="string">'pl.sip'</span> +<span class="keyword">local</span> stringx = <span class="global">require</span> <span class="string">'pl.stringx'</span> + +<span class="keyword">local</span> res = {} +<span class="keyword">local</span> s = <span class="string">[[ +(@see pl.bonzo.dog) +remember about @see pl.bonzo + +]]</span> + +<span class="keyword">local</span> _gsub_patterns = {} + +<span class="keyword">local</span> <span class="keyword">function</span> gsub (s,pat,subst,start) + <span class="keyword">local</span> fpat = _gsub_patterns[pat] + <span class="keyword">if</span> <span class="keyword">not</span> fpat <span class="keyword">then</span> + <span class="comment">-- use SIP to generate a proper string pattern. +</span> <span class="comment">-- the _whole thing_ is a capture, to get the whole match +</span> <span class="comment">-- and the unnamed capture. +</span> fpat = <span class="string">'('</span>..sip.create_pattern(pat)..<span class="string">')'</span> + _gsub_patterns[pat] = fpat + <span class="keyword">end</span> + <span class="keyword">return</span> s:gsub(fpat,subst,start) +<span class="keyword">end</span> + + +<span class="keyword">local</span> mod = sip.compile <span class="string">'$v.$v'</span> +<span class="keyword">local</span> fun = sip.compile <span class="string">'$v.$v.$v'</span> + +<span class="keyword">for</span> line <span class="keyword">in</span> stringx.lines(s) <span class="keyword">do</span> + line = gsub(line,<span class="string">'@see $p'</span>,<span class="keyword">function</span>(see,path) + <span class="keyword">if</span> fun(path,res) <span class="keyword">or</span> mod(path,res) <span class="keyword">then</span> + <span class="keyword">local</span> ret = (<span class="string">'[see %s](%s.%s.html'</span>):format(path,res[<span class="number">1</span>],res[<span class="number">2</span>]) + <span class="keyword">if</span> res[<span class="number">3</span>] <span class="keyword">then</span> + <span class="keyword">return</span> ret..<span class="string">'#'</span>..res[<span class="number">3</span>]..<span class="string">')'</span> + <span class="keyword">else</span> + <span class="keyword">return</span> ret..<span class="string">')'</span> + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">end</span>) + <span class="global">print</span>(line) +<span class="keyword">end</span></pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/sipscan.lua.html b/docs/examples/sipscan.lua.html new file mode 100644 index 0000000..55c7279 --- /dev/null +++ b/docs/examples/sipscan.lua.html @@ -0,0 +1,162 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><strong>sipscan.lua</strong></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>sipscan.lua</h2> +<pre> +<span class="comment">-- another SIP example, shows how an awkward log file format +</span><span class="comment">-- can be parsed. It also prints out the actual Lua string +</span><span class="comment">-- pattern generated: +</span><span class="comment">-- SYNC%s*%[([+%-%d]%d*)%]%s*([+%-%d]%d*)%s*([+%-%d]%d*) +</span> +<span class="keyword">local</span> sip = <span class="global">require</span> <span class="string">'pl.sip'</span> +<span class="keyword">local</span> stringx = <span class="global">require</span> <span class="string">'pl.stringx'</span> + +<span class="keyword">local</span> s = <span class="string">[[ +SYNC [1] 0 547 (14679 sec) +SYNC [2] 0 555 (14679 sec) +SYNC [3] 0 563 (14679 sec) +SYNC [4] 0 571 (14679 sec) +SYNC [5] -1 580 (14679 sec) +SYNC [6] 0 587 (14679 sec) +]]</span> + + +<span class="keyword">local</span> first = <span class="keyword">true</span> +<span class="keyword">local</span> expected +<span class="keyword">local</span> res = {} +<span class="keyword">local</span> pat = <span class="string">'SYNC [$i{seq}] $i{diff} $i{val}'</span> +<span class="global">print</span>(sip.create_pattern(pat)) +<span class="keyword">local</span> match = sip.compile(pat) +<span class="keyword">for</span> line <span class="keyword">in</span> stringx.lines(s) <span class="keyword">do</span> + <span class="keyword">if</span> match(line,res) <span class="keyword">then</span> + <span class="keyword">if</span> first <span class="keyword">then</span> + expected = res.val + first = <span class="keyword">false</span> + <span class="keyword">end</span> + <span class="global">print</span>(res.val,expected - res.val) + expected = expected + <span class="number">8</span> + <span class="keyword">end</span> +<span class="keyword">end</span></pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/symbols.lua.html b/docs/examples/symbols.lua.html new file mode 100644 index 0000000..aa6b7b3 --- /dev/null +++ b/docs/examples/symbols.lua.html @@ -0,0 +1,348 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><strong>symbols.lua</strong></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>symbols.lua</h2> +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +utils.import <span class="string">'pl.func'</span> +<span class="keyword">local</span> ops = <span class="global">require</span> <span class="string">'pl.operator'</span> +<span class="keyword">local</span> List = <span class="global">require</span> <span class="string">'pl.List'</span> +<span class="keyword">local</span> append,concat = <span class="global">table</span>.insert,<span class="global">table</span>.concat +<span class="keyword">local</span> compare,find_if,compare_no_order,imap,reduce,count_map = tablex.compare,tablex.find_if,tablex.compare_no_order,tablex.imap,tablex.reduce,tablex.count_map +<span class="keyword">local</span> <span class="global">unpack</span> = <span class="global">table</span>.<span class="global">unpack</span> + +<span class="keyword">function</span> bindval (self,val) + <span class="global">rawset</span>(self,<span class="string">'value'</span>,val) +<span class="keyword">end</span> + +<span class="keyword">local</span> optable = ops.optable + +<span class="keyword">function</span> sexpr (e) + <span class="keyword">if</span> isPE(e) <span class="keyword">then</span> + <span class="keyword">if</span> e.op ~= <span class="string">'X'</span> <span class="keyword">then</span> + <span class="keyword">local</span> args = tablex.imap(sexpr,e) + <span class="keyword">return</span> <span class="string">'('</span>..e.op..<span class="string">' '</span>..<span class="global">table</span>.concat(args,<span class="string">' '</span>)..<span class="string">')'</span> + <span class="keyword">else</span> + <span class="keyword">return</span> e.repr + <span class="keyword">end</span> + <span class="keyword">else</span> + <span class="keyword">return</span> <span class="global">tostring</span>(e) + <span class="keyword">end</span> +<span class="keyword">end</span> + + +psexpr = compose(<span class="global">print</span>,sexpr) + + + +<span class="keyword">function</span> equals (e1,e2) + <span class="keyword">local</span> p1,p2 = isPE(e1),isPE(e2) + <span class="keyword">if</span> p1 ~= p2 <span class="keyword">then</span> <span class="keyword">return</span> <span class="keyword">false</span> <span class="keyword">end</span> <span class="comment">-- different kinds of animals! +</span> <span class="keyword">if</span> p1 <span class="keyword">and</span> p2 <span class="keyword">then</span> <span class="comment">-- both PEs +</span> <span class="comment">-- operators must be the same +</span> <span class="keyword">if</span> e1.op ~= e2.op <span class="keyword">then</span> <span class="keyword">return</span> <span class="keyword">false</span> <span class="keyword">end</span> + <span class="comment">-- PHs are equal if their representations are equal +</span> <span class="keyword">if</span> e1.op == <span class="string">'X'</span> <span class="keyword">then</span> <span class="keyword">return</span> e1.repr == e2.repr + <span class="comment">-- commutative operators +</span> <span class="keyword">elseif</span> e1.op == <span class="string">'+'</span> <span class="keyword">or</span> e1.op == <span class="string">'*'</span> <span class="keyword">then</span> + <span class="keyword">return</span> compare_no_order(e1,e2,equals) + <span class="keyword">else</span> + <span class="comment">-- arguments must be the same +</span> <span class="keyword">return</span> compare(e1,e2,equals) + <span class="keyword">end</span> + <span class="keyword">else</span> <span class="comment">-- fall back on simple equality for non PEs +</span> <span class="keyword">return</span> e1 == e2 + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="comment">-- run down an unbalanced operator chain (like a+b+c) and return the arguments {a,b,c} +</span><span class="keyword">function</span> tcollect (op,e,ls) + <span class="keyword">if</span> isPE(e) <span class="keyword">and</span> e.op == op <span class="keyword">then</span> + <span class="keyword">for</span> i = <span class="number">1</span>,#e <span class="keyword">do</span> + tcollect(op,e[i],ls) + <span class="keyword">end</span> + <span class="keyword">else</span> + ls:append(e) + <span class="keyword">return</span> + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">function</span> rcollect (e) + <span class="keyword">local</span> res = List() + tcollect(e.op,e,res) + <span class="keyword">return</span> res +<span class="keyword">end</span> + + +<span class="comment">-- balance ensures that +/* chains are collected together, operates in-place. +</span><span class="comment">-- thus (+(+ a b) c) or (+ a (+ b c)) becomes (+ a b c), order immaterial +</span><span class="keyword">function</span> balance (e) + <span class="keyword">if</span> isPE(e) <span class="keyword">and</span> e.op ~= <span class="string">'X'</span> <span class="keyword">then</span> + <span class="keyword">local</span> op,args = e.op + <span class="keyword">if</span> op == <span class="string">'+'</span> <span class="keyword">or</span> op == <span class="string">'*'</span> <span class="keyword">then</span> + args = rcollect(e) + <span class="keyword">else</span> + args = imap(balance,e) + <span class="keyword">end</span> + <span class="keyword">for</span> i = <span class="number">1</span>,#args <span class="keyword">do</span> + e[i] = args[i] + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">return</span> e +<span class="keyword">end</span> + +<span class="comment">-- fold constants in an expression +</span><span class="keyword">function</span> fold (e) + <span class="keyword">if</span> isPE(e) <span class="keyword">then</span> + <span class="keyword">if</span> e.op == <span class="string">'X'</span> <span class="keyword">then</span> + <span class="comment">-- there could be _bound values_! +</span> <span class="keyword">local</span> val = <span class="global">rawget</span>(e,<span class="string">'value'</span>) + <span class="keyword">return</span> val <span class="keyword">and</span> val <span class="keyword">or</span> e + <span class="keyword">else</span> + <span class="keyword">local</span> op = e.op + <span class="keyword">local</span> addmul = op == <span class="string">'*'</span> <span class="keyword">or</span> op == <span class="string">'+'</span> + <span class="comment">-- first fold all arguments +</span> <span class="keyword">local</span> args = imap(fold,e) + <span class="keyword">if</span> <span class="keyword">not</span> addmul <span class="keyword">and</span> <span class="keyword">not</span> find_if(args,isPE) <span class="keyword">then</span> + <span class="comment">-- no placeholders in these args, we can fold the expression. +</span> <span class="keyword">local</span> opfn = optable[op] + <span class="keyword">if</span> opfn <span class="keyword">then</span> + <span class="keyword">return</span> opfn(<span class="global">unpack</span>(args)) + <span class="keyword">else</span> + <span class="keyword">return</span> <span class="string">'?'</span> + <span class="keyword">end</span> + <span class="keyword">elseif</span> addmul <span class="keyword">then</span> + <span class="comment">-- enforce a few rules for + and * +</span> <span class="comment">-- split the args into two classes, PE args and non-PE args. +</span> <span class="keyword">local</span> classes = List.partition(args,isPE) + <span class="keyword">local</span> pe,npe = classes[<span class="keyword">true</span>],classes[<span class="keyword">false</span>] + <span class="keyword">if</span> npe <span class="keyword">then</span> <span class="comment">-- there's at least one non PE argument +</span> <span class="comment">-- so fold them +</span> <span class="keyword">if</span> #npe == <span class="number">1</span> <span class="keyword">then</span> npe = npe[<span class="number">1</span>] + <span class="keyword">else</span> npe = npe:reduce(optable[op]) + <span class="keyword">end</span> + <span class="comment">-- if the result is a constant, return it +</span> <span class="keyword">if</span> <span class="keyword">not</span> pe <span class="keyword">then</span> <span class="keyword">return</span> npe <span class="keyword">end</span> + + <span class="comment">-- either (* 1 x) => x or (* 1 x y ...) => (* x y ...) +</span> <span class="keyword">if</span> op == <span class="string">'*'</span> <span class="keyword">then</span> + <span class="keyword">if</span> npe == <span class="number">0</span> <span class="keyword">then</span> <span class="keyword">return</span> <span class="number">0</span> + <span class="keyword">elseif</span> npe == <span class="number">1</span> <span class="keyword">then</span> <span class="comment">-- identity +</span> <span class="keyword">if</span> #pe == <span class="number">1</span> <span class="keyword">then</span> <span class="keyword">return</span> pe[<span class="number">1</span>] <span class="keyword">else</span> npe = <span class="keyword">nil</span> <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">else</span> <span class="comment">-- special cases for + +</span> <span class="keyword">if</span> npe == <span class="number">0</span> <span class="keyword">then</span> <span class="comment">-- identity +</span> <span class="keyword">if</span> #pe == <span class="number">1</span> <span class="keyword">then</span> <span class="keyword">return</span> pe[<span class="number">1</span>] <span class="keyword">else</span> npe = <span class="keyword">nil</span> <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="comment">-- build up the final arguments +</span> <span class="keyword">local</span> res = {} + <span class="keyword">if</span> npe <span class="keyword">then</span> append(res,npe) <span class="keyword">end</span> + <span class="keyword">for</span> val,count <span class="keyword">in</span> <span class="global">pairs</span>(count_map(pe,equals)) <span class="keyword">do</span> + <span class="keyword">if</span> count > <span class="number">1</span> <span class="keyword">then</span> + <span class="keyword">if</span> op == <span class="string">'*'</span> <span class="keyword">then</span> val = val ^ count + <span class="keyword">else</span> val = val * count + <span class="keyword">end</span> + <span class="keyword">end</span> + append(res,val) + <span class="keyword">end</span> + <span class="keyword">if</span> #res == <span class="number">1</span> <span class="keyword">then</span> <span class="keyword">return</span> res[<span class="number">1</span>] <span class="keyword">end</span> + <span class="keyword">return</span> PE{op=op,<span class="global">unpack</span>(res)} + <span class="keyword">elseif</span> op == <span class="string">'^'</span> <span class="keyword">then</span> + <span class="keyword">if</span> args[<span class="number">2</span>] == <span class="number">1</span> <span class="keyword">then</span> <span class="keyword">return</span> args[<span class="number">1</span>] <span class="keyword">end</span> <span class="comment">-- identity +</span> <span class="keyword">if</span> args[<span class="number">2</span>] == <span class="number">0</span> <span class="keyword">then</span> <span class="keyword">return</span> <span class="number">1</span> <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">return</span> PE{op=op,<span class="global">unpack</span>(args)} + <span class="keyword">end</span> + <span class="keyword">else</span> + <span class="keyword">return</span> e + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">function</span> expand (e) + <span class="keyword">if</span> isPE(e) <span class="keyword">and</span> e.op == <span class="string">'*'</span> <span class="keyword">and</span> isPE(e[<span class="number">2</span>]) <span class="keyword">and</span> e[<span class="number">2</span>].op == <span class="string">'+'</span> <span class="keyword">then</span> + <span class="keyword">local</span> a,b = e[<span class="number">1</span>],e[<span class="number">2</span>] + <span class="keyword">return</span> expand(b[<span class="number">1</span>]*a) + expand(b[<span class="number">2</span>]*a) + <span class="keyword">else</span> + <span class="keyword">return</span> e + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">function</span> isnumber (x) + <span class="keyword">return</span> <span class="global">type</span>(x) == <span class="string">'number'</span> +<span class="keyword">end</span> + +<span class="comment">-- does this PE contain a reference to x? +</span><span class="keyword">function</span> references (e,x) + <span class="keyword">if</span> isPE(e) <span class="keyword">then</span> + <span class="keyword">if</span> e.op == <span class="string">'X'</span> <span class="keyword">then</span> <span class="keyword">return</span> x.repr == e.repr + <span class="keyword">else</span> + <span class="keyword">return</span> find_if(e,references,x) + <span class="keyword">end</span> + <span class="keyword">else</span> + <span class="keyword">return</span> <span class="keyword">false</span> + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">local</span> <span class="keyword">function</span> muli (args) + <span class="keyword">return</span> PE{op=<span class="string">'*'</span>,<span class="global">unpack</span>(args)} +<span class="keyword">end</span> + +<span class="keyword">local</span> <span class="keyword">function</span> addi (args) + <span class="keyword">return</span> PE{op=<span class="string">'+'</span>,<span class="global">unpack</span>(args)} +<span class="keyword">end</span> + +<span class="keyword">function</span> diff (e,x) + <span class="keyword">if</span> isPE(e) <span class="keyword">and</span> references(e,x) <span class="keyword">then</span> + <span class="keyword">local</span> op = e.op + <span class="keyword">if</span> op == <span class="string">'X'</span> <span class="keyword">then</span> + <span class="keyword">return</span> <span class="number">1</span> + <span class="keyword">else</span> + <span class="keyword">local</span> a,b = e[<span class="number">1</span>],e[<span class="number">2</span>] + <span class="keyword">if</span> op == <span class="string">'+'</span> <span class="keyword">then</span> <span class="comment">-- differentiation is linear +</span> <span class="keyword">local</span> args = imap(diff,e,x) + <span class="keyword">return</span> balance(addi(args)) + <span class="keyword">elseif</span> op == <span class="string">'*'</span> <span class="keyword">then</span> <span class="comment">-- product rule +</span> <span class="keyword">local</span> res,d,ee = {} + <span class="keyword">for</span> i = <span class="number">1</span>,#e <span class="keyword">do</span> + d = fold(diff(e[i],x)) + <span class="keyword">if</span> d ~= <span class="number">0</span> <span class="keyword">then</span> + ee = {<span class="global">unpack</span>(e)} + ee[i] = d + append(res,balance(muli(ee))) + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">if</span> #res > <span class="number">1</span> <span class="keyword">then</span> <span class="keyword">return</span> addi(res) + <span class="keyword">else</span> <span class="keyword">return</span> res[<span class="number">1</span>] <span class="keyword">end</span> + <span class="keyword">elseif</span> op == <span class="string">'^'</span> <span class="keyword">and</span> isnumber(b) <span class="keyword">then</span> <span class="comment">-- power rule +</span> <span class="keyword">return</span> b*x^(b-<span class="number">1</span>) + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="keyword">else</span> + <span class="keyword">return</span> <span class="number">0</span> + <span class="keyword">end</span> +<span class="keyword">end</span></pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/test-cmp.lua.html b/docs/examples/test-cmp.lua.html new file mode 100644 index 0000000..59da691 --- /dev/null +++ b/docs/examples/test-cmp.lua.html @@ -0,0 +1,131 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><strong>test-cmp.lua</strong></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>test-cmp.lua</h2> +<pre> +<span class="keyword">local</span> A = <span class="global">require</span> <span class="string">'pl.tablex'</span> +<span class="global">print</span>(A.compare_no_order({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>})) +<span class="global">print</span>(A.compare_no_order({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>},<span class="string">'=='</span>))</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/test-data.lua.html b/docs/examples/test-data.lua.html new file mode 100644 index 0000000..031dd79 --- /dev/null +++ b/docs/examples/test-data.lua.html @@ -0,0 +1,373 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><strong>test-data.lua</strong></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>test-data.lua</h2> +<pre> +<span class="keyword">local</span> data = <span class="global">require</span> <span class="string">'pl.data'</span> +<span class="keyword">local</span> List = <span class="global">require</span> <span class="string">'pl.List'</span> +<span class="keyword">local</span> array = <span class="global">require</span> <span class="string">'pl.array2d'</span> +<span class="keyword">local</span> func = <span class="global">require</span> <span class="string">'pl.func'</span> +<span class="keyword">local</span> seq = <span class="global">require</span> <span class="string">'pl.seq'</span> +<span class="keyword">local</span> stringio = <span class="global">require</span> <span class="string">'pl.stringio'</span> +<span class="keyword">local</span> open = stringio. open +<span class="keyword">local</span> asserteq = <span class="global">require</span> <span class="string">'pl.test'</span> . asserteq +<span class="keyword">local</span> T = <span class="global">require</span> <span class="string">'pl.test'</span>. tuple + +<span class="comment">--[=[ +dat,err = data.read(open [[ +1.0 0.1 +0.2 1.3 +]]) + +if err then print(err) end + +require 'pl.pretty'.dump(dat) +os.exit(0) +--]=]</span> + +<span class="comment">-- tab-separated data, explicit column names +</span><span class="keyword">local</span> t1f = open <span class="string">[[ +EventID Magnitude LocationX LocationY LocationZ LocationError EventDate DataFile +981124001 2.0 18988.4 10047.1 4149.7 33.8 24/11/1998 11:18:05 981124DF.AAB +981125001 0.8 19104.0 9970.4 5088.7 3.0 25/11/1998 05:44:54 981125DF.AAB +981127003 0.5 19012.5 9946.9 3831.2 46.0 27/11/1998 17:15:17 981127DF.AAD +981127005 0.6 18676.4 10606.2 3761.9 4.4 27/11/1998 17:46:36 981127DF.AAF +981127006 0.2 19109.9 9716.5 3612.0 11.8 27/11/1998 19:29:51 981127DF.AAG +]]</span> + +<span class="keyword">local</span> t1 = data.read (t1f) +<span class="comment">-- column_by_name returns a List +</span>asserteq(t1:column_by_name <span class="string">'Magnitude'</span>,List{<span class="number">2</span>,<span class="number">0.8</span>,<span class="number">0.5</span>,<span class="number">0.6</span>,<span class="number">0.2</span>}) +<span class="comment">-- can use array.column as well +</span>asserteq(array.column(t1,<span class="number">2</span>),{<span class="number">2</span>,<span class="number">0.8</span>,<span class="number">0.5</span>,<span class="number">0.6</span>,<span class="number">0.2</span>}) + +<span class="comment">-- only numerical columns (deduced from first data row) are converted by default +</span><span class="comment">-- can look up indices in the list fieldnames. +</span><span class="keyword">local</span> EDI = t1.fieldnames:index <span class="string">'EventDate'</span> +<span class="global">assert</span>(<span class="global">type</span>(t1[<span class="number">1</span>][EDI]) == <span class="string">'string'</span>) + +<span class="comment">-- select method returns a sequence, in this case single-valued. +</span><span class="comment">-- (Note that seq.copy returns a List) +</span>asserteq(seq(t1:<span class="global">select</span> <span class="string">'LocationX where Magnitude > 0.5'</span>):copy(),List{<span class="number">18988.4</span>,<span class="number">19104</span>,<span class="number">18676.4</span>}) + +<span class="comment">--[[ +--a common select usage pattern: +for event,mag in t1:select 'EventID,Magnitude sort by Magnitude desc' do + print(event,mag) +end +--]]</span> + +<span class="comment">-- space-separated, but with last field containing spaces. +</span><span class="keyword">local</span> t2f = open <span class="string">[[ +USER PID %MEM %CPU COMMAND +sdonovan 2333 0.3 0.1 background --n=2 +root 2332 0.4 0.2 fred --start=yes +root 2338 0.2 0.1 backyard-process +]]</span> + +<span class="keyword">local</span> t2,err = data.read(t2f,{last_field_collect=<span class="keyword">true</span>}) +<span class="keyword">if</span> <span class="keyword">not</span> t2 <span class="keyword">then</span> <span class="keyword">return</span> <span class="global">print</span> (err) <span class="keyword">end</span> + +<span class="comment">-- the last_field_collect option is useful with space-delimited data where the last +</span><span class="comment">-- field may contain spaces. Otherwise, a record count mismatch should be an error! +</span><span class="keyword">local</span> lt2 = List(t2[<span class="number">2</span>]) +asserteq(lt2:join <span class="string">','</span>,<span class="string">'root,2332,0.4,0.2,fred --start=yes'</span>) + +<span class="comment">-- fieldnames are converted into valid identifiers by substituting _ +</span><span class="comment">-- (we do this to make select queries parseable by Lua) +</span>asserteq(t2.fieldnames,List{<span class="string">'USER'</span>,<span class="string">'PID'</span>,<span class="string">'_MEM'</span>,<span class="string">'_CPU'</span>,<span class="string">'COMMAND'</span>}) + +<span class="comment">-- select queries are NOT SQL so remember to use == ! (and no 'between' operator, sorry) +</span><span class="comment">--s,err = t2:select('_MEM where USER="root"') +</span><span class="comment">--assert(err == [[[string "tmp"]:9: unexpected symbol near '=']]) +</span> +<span class="keyword">local</span> s = t2:<span class="global">select</span>(<span class="string">'_MEM where USER=="root"'</span>) +<span class="global">assert</span>(s() == <span class="number">0.4</span>) +<span class="global">assert</span>(s() == <span class="number">0.2</span>) +<span class="global">assert</span>(s() == <span class="keyword">nil</span>) + +<span class="comment">-- CSV, Excel style. Double-quoted fields are allowed, and they may contain commas! +</span><span class="keyword">local</span> t3f = open <span class="string">[[ +"Department Name","Employee ID",Project,"Hours Booked" +sales,1231,overhead,4 +sales,1255,overhead,3 +engineering,1501,development,5 +engineering,1501,maintenance,3 +engineering,1433,maintenance,10 +]]</span> + +<span class="keyword">local</span> t3 = data.read(t3f,{csv=<span class="keyword">true</span>}) + +<span class="comment">-- although fieldnames are turned in valid Lua identifiers, there is always <code>original_fieldnames</code> +</span>asserteq(t3.fieldnames,List{<span class="string">'Department_Name'</span>,<span class="string">'Employee_ID'</span>,<span class="string">'Project'</span>,<span class="string">'Hours_Booked'</span>}) +asserteq(t3.original_fieldnames,List{<span class="string">'Department Name'</span>,<span class="string">'Employee ID'</span>,<span class="string">'Project'</span>,<span class="string">'Hours Booked'</span>}) + +<span class="comment">-- a common operation is to select using a given list of columns, and each row +</span><span class="comment">-- on some explicit condition. The select() method can take a table with these +</span><span class="comment">-- parameters +</span><span class="keyword">local</span> keepcols = {<span class="string">'Employee_ID'</span>,<span class="string">'Hours_Booked'</span>} + +<span class="keyword">local</span> q = t3:<span class="global">select</span> { fields = keepcols, + where = <span class="keyword">function</span>(row) <span class="keyword">return</span> row[<span class="number">1</span>]==<span class="string">'engineering'</span> <span class="keyword">end</span> + } + +asserteq(seq.copy2(q),{{<span class="number">1501</span>,<span class="number">5</span>},{<span class="number">1501</span>,<span class="number">3</span>},{<span class="number">1433</span>,<span class="number">10</span>}}) + +<span class="comment">-- another pattern is doing a select to restrict rows & columns, process some +</span><span class="comment">-- fields and write out the modified rows. +</span> +<span class="keyword">local</span> outf = stringio.create() + +<span class="keyword">local</span> names = {[<span class="number">1501</span>]=<span class="string">'don'</span>,[<span class="number">1433</span>]=<span class="string">'dilbert'</span>} + +t3:write_row (outf,{<span class="string">'Employee'</span>,<span class="string">'Hours_Booked'</span>}) +q = t3:select_row {fields=keepcols,where=func.Eq(func._1[<span class="number">1</span>],<span class="string">'engineering'</span>)} +<span class="keyword">for</span> row <span class="keyword">in</span> q <span class="keyword">do</span> + row[<span class="number">1</span>] = names[row[<span class="number">1</span>]] + t3:write_row(outf,row) +<span class="keyword">end</span> + +asserteq(outf:value(), +<span class="string">[[ +Employee,Hours_Booked +don,5 +don,3 +dilbert,10 +]]</span>) + +<span class="comment">-- data may not always have column headers. When creating a data object +</span><span class="comment">-- from a two-dimensional array, may specify the fieldnames, as a list or a string. +</span><span class="comment">-- The delimiter is deduced from the fieldname string, so a string just containing +</span><span class="comment">-- the delimiter will set it, and the fieldnames will be empty. +</span><span class="keyword">local</span> dat = List() +<span class="keyword">local</span> row = List.range(<span class="number">1</span>,<span class="number">10</span>) +<span class="keyword">for</span> i = <span class="number">1</span>,<span class="number">10</span> <span class="keyword">do</span> + dat:append(row:map(<span class="string">'*'</span>,i)) +<span class="keyword">end</span> +dat = data.new(dat,<span class="string">','</span>) +<span class="keyword">local</span> out = stringio.create() +dat:write(out,<span class="string">','</span>) +asserteq(out:value(), <span class="string">[[ +1,2,3,4,5,6,7,8,9,10 +2,4,6,8,10,12,14,16,18,20 +3,6,9,12,15,18,21,24,27,30 +4,8,12,16,20,24,28,32,36,40 +5,10,15,20,25,30,35,40,45,50 +6,12,18,24,30,36,42,48,54,60 +7,14,21,28,35,42,49,56,63,70 +8,16,24,32,40,48,56,64,72,80 +9,18,27,36,45,54,63,72,81,90 +10,20,30,40,50,60,70,80,90,100 +]]</span>) + +<span class="comment">-- you can always use numerical field indices, AWK-style; +</span><span class="comment">-- note how the copy_select method gives you a data object instead of an +</span><span class="comment">-- iterator over the fields +</span><span class="keyword">local</span> res = dat:copy_select <span class="string">'$1,$3 where $1 > 5'</span> +<span class="keyword">local</span> L = List +asserteq(L(res),L{ + L{<span class="number">6</span>, <span class="number">18</span>}, + L{<span class="number">7</span>,<span class="number">21</span>}, + L{<span class="number">8</span>,<span class="number">24</span>}, + L{<span class="number">9</span>,<span class="number">27</span>}, + L{<span class="number">10</span>,<span class="number">30</span>}, +}) + +<span class="comment">-- the column_by_name method may take a fieldname or an index +</span>asserteq(dat:column_by_name(<span class="number">2</span>), L{<span class="number">2</span>,<span class="number">4</span>,<span class="number">6</span>,<span class="number">8</span>,<span class="number">10</span>,<span class="number">12</span>,<span class="number">14</span>,<span class="number">16</span>,<span class="number">18</span>,<span class="number">20</span>}) + +<span class="comment">-- the field list may contain expressions or even constants +</span><span class="keyword">local</span> q = dat:<span class="global">select</span> <span class="string">'$3,2*$4 where $1 == 8'</span> +asserteq(T(q()),T(<span class="number">24</span>,<span class="number">64</span>)) + +dat,err = data.read(open <span class="string">[[ +1.0 0.1 +0.2 1.3 +]]</span>) + +<span class="keyword">if</span> err <span class="keyword">then</span> <span class="global">print</span>(err) <span class="keyword">end</span> + +<span class="comment">-- if a method cannot be found, then we look up in array2d +</span><span class="comment">-- array2d.flatten(t) makes a 1D list out of a 2D array, +</span><span class="comment">-- and then List.minmax() gets the extrema. +</span> +asserteq(T(dat:flatten():minmax()),T(<span class="number">0.1</span>,<span class="number">1.3</span>)) + +<span class="keyword">local</span> f = open <span class="string">[[ +Time Message +1266840760 +# EE7C0600006F0D00C00F06010302054000000308010A00002B00407B00 +1266840760 closure data 0.000000 1972 1972 0 +1266840760 ++ 1266840760 EE 1 +1266840760 +# EE7C0600006F0D00C00F06010302054000000408020A00002B00407B00 +1266840764 closure data 0.000000 1972 1972 0 +1266840764 ++ 1266840764 EE 1 +1266840764 +# EE7C0600006F0D00C00F06010302054000000508030A00002B00407B00 +1266840768 duplicate? +1266840768 +# EE7C0600006F0D00C00F06010302054000000508030A00002B00407B00 +1266840768 closure data 0.000000 1972 1972 0 +]]</span> + +<span class="comment">-- the <code>convert</code> option provides custom converters for each specified column. +</span><span class="comment">-- Here we convert the timestamps into Date objects and collect everything +</span><span class="comment">-- else into one field +</span><span class="keyword">local</span> Date = <span class="global">require</span> <span class="string">'pl.Date'</span> + +<span class="keyword">local</span> <span class="keyword">function</span> date_convert (ds) + <span class="keyword">return</span> Date(<span class="global">tonumber</span>(ds)) +<span class="keyword">end</span> + +<span class="keyword">local</span> d = data.read(f,{convert={[<span class="number">1</span>]=date_convert},last_field_collect=<span class="keyword">true</span>}) + +asserteq(#d[<span class="number">1</span>],<span class="number">2</span>) +asserteq(d[<span class="number">2</span>][<span class="number">1</span>]:year(),<span class="number">2010</span>) + +d = {{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}} +out = stringio.create() +data.write(d,out,{<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>},<span class="string">','</span>) +asserteq(out:value(), +<span class="string">[[ +A,B,C +1,2,3 +10,20,30 +]]</span>) + +out = stringio.create() +d.fieldnames = {<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>} +data.write(d,out) + +asserteq(out:value(), +<span class="string">[[ +A B C +1 2 3 +10 20 30 +]]</span>) + + +d = data.read(stringio.open <span class="string">'One,Two\n1,\n,20\n'</span>,{csv=<span class="keyword">true</span>}) +asserteq(d,{ + {<span class="number">1</span>,<span class="number">0</span>},{<span class="number">0</span>,<span class="number">20</span>}, + original_fieldnames={<span class="string">"One"</span>,<span class="string">"Two"</span>},fieldnames={<span class="string">"One"</span>,<span class="string">"Two"</span>},delim=<span class="string">","</span> +})</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/test-listcallbacks.lua.html b/docs/examples/test-listcallbacks.lua.html new file mode 100644 index 0000000..1e9e8b0 --- /dev/null +++ b/docs/examples/test-listcallbacks.lua.html @@ -0,0 +1,139 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><strong>test-listcallbacks.lua</strong></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>test-listcallbacks.lua</h2> +<pre> +<span class="comment">-- demonstrates how to use a list of callbacks +</span><span class="keyword">local</span> List = <span class="global">require</span> <span class="string">'pl.List'</span> +<span class="keyword">local</span> utils = <span class="global">require</span> <span class="string">'pl.utils'</span> +<span class="keyword">local</span> actions = List() +<span class="keyword">local</span> L = utils.string_lambda + +actions:append(<span class="keyword">function</span>() <span class="global">print</span> <span class="string">'hello'</span> <span class="keyword">end</span>) +actions:append(L <span class="string">'|| print "yay"'</span>) + +<span class="comment">-- '()' is a shortcut for operator.call or function(x) return x() end +</span>actions:foreach <span class="string">'()'</span></pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/test-pretty.lua.html b/docs/examples/test-pretty.lua.html new file mode 100644 index 0000000..fe555ac --- /dev/null +++ b/docs/examples/test-pretty.lua.html @@ -0,0 +1,141 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><strong>test-pretty.lua</strong></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>test-pretty.lua</h2> +<pre> +<span class="keyword">local</span> pretty = <span class="global">require</span> <span class="string">'pl.pretty'</span> + +<span class="keyword">local</span> tb = { + <span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}, + alpha=<span class="number">1</span>,beta=<span class="number">2</span>,gamma=<span class="number">3</span>,[<span class="string">'&'</span>]=<span class="keyword">true</span>,[<span class="number">0</span>]=<span class="keyword">false</span>, + _fred = {<span class="keyword">true</span>,<span class="keyword">true</span>}, + s = <span class="string">[[ +hello dolly +you're so fine +]]</span> +} + +<span class="global">print</span>(pretty.write(tb))</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/test-symbols.lua.html b/docs/examples/test-symbols.lua.html new file mode 100644 index 0000000..8f0be26 --- /dev/null +++ b/docs/examples/test-symbols.lua.html @@ -0,0 +1,210 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><strong>test-symbols.lua</strong></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>test-symbols.lua</h2> +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +<span class="comment">-- force us to look in the script's directory when requiring... +</span>app.require_here() +<span class="global">require</span> <span class="string">'symbols'</span> + +<span class="keyword">local</span> MT = <span class="global">getmetatable</span>(_1) + +add = MT.__add +mul = MT.__mul +pow = MT.__pow + + +<span class="keyword">function</span> testeq (e1,e2) + <span class="keyword">if</span> <span class="keyword">not</span> equals(e1,e2) <span class="keyword">then</span> + <span class="global">print</span> (<span class="string">'Not equal'</span>,repr(e1),repr(e2)) + <span class="keyword">end</span> +<span class="keyword">end</span> + +sin = register(<span class="global">math</span>.sin,<span class="string">'sin'</span>) + +f = register(<span class="keyword">function</span>(x,y,z) <span class="keyword">end</span>) + +<span class="comment">--[[ +testeq (_1,_1) +testeq (_1+_2,_1+_2) +testeq (_1 + 3*_2,_1 + 3*_2) +testeq (_2+_1,_1+_2) +testeq (sin(_1),sin(_1)) +testeq (1+f(10,20,'ok'),f(10,20,'ok')+1) +--]]</span> + + +<span class="keyword">function</span> testexpand (e) + <span class="global">print</span>(repr(fold(expand(e)))) <span class="comment">--fold +</span><span class="keyword">end</span> + +<span class="comment">--[[ +testexpand (a*(a+1)) + +testexpand ((x+2)*(b+1)) +]]</span><span class="comment">-- +</span> +<span class="keyword">function</span> testfold (e) + <span class="global">print</span>(repr(fold(e))) +<span class="keyword">end</span> + +a,b,c,x,y = Var <span class="string">'a,b,c,x,y'</span> + +<span class="comment">--~ testfold(_1 + _2) +</span><span class="comment">--~ testfold(add(10,20)) +</span><span class="comment">--~ testfold(add(mul(2,_1),mul(3,_2))) +</span><span class="comment">--[[ +testfold(sin(a)) +e = a^(b+2) +testfold(e) +bindval(b,1) +testfold(e) +bindval(a,2) +testfold(e) + +bindval(a) +bindval(b) +]]</span> + + + +<span class="keyword">function</span> testdiff (e) + balance(e) + e = diff(e,x) + balance(e) + <span class="global">print</span>(<span class="string">'+ '</span>,e) + e = fold(e) + <span class="global">print</span>(<span class="string">'- '</span>,e) +<span class="keyword">end</span> + + +testdiff(x^<span class="number">2</span>+<span class="number">1</span>) +testdiff(<span class="number">3</span>*x^<span class="number">2</span>) +testdiff(x^<span class="number">2</span> + <span class="number">2</span>*x^<span class="number">3</span>) +testdiff(x^<span class="number">2</span> + <span class="number">2</span>*a*x^<span class="number">3</span> + x^<span class="number">4</span>) +testdiff(<span class="number">2</span>*a*x^<span class="number">3</span>) +testdiff(x*x*x)</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testapp.lua.html b/docs/examples/testapp.lua.html new file mode 100644 index 0000000..56ae5a3 --- /dev/null +++ b/docs/examples/testapp.lua.html @@ -0,0 +1,133 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><strong>testapp.lua</strong></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testapp.lua</h2> +<pre> +<span class="comment">-- shows how a script can get a private file path +</span><span class="comment">-- the output on my Windows machine is: +</span><span class="comment">-- C:\Documents and Settings\steve\.testapp\test.txt +</span><span class="keyword">local</span> app = <span class="global">require</span> <span class="string">'pl.app'</span> +<span class="global">print</span>(app.appfile <span class="string">'test.txt'</span>)</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testclone.lua.html b/docs/examples/testclone.lua.html new file mode 100644 index 0000000..aa6de87 --- /dev/null +++ b/docs/examples/testclone.lua.html @@ -0,0 +1,166 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><strong>testclone.lua</strong></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testclone.lua</h2> +<pre> +<span class="comment">--cloning a directory tree. +</span><span class="keyword">local</span> lfs = <span class="global">require</span> <span class="string">'lfs'</span> +<span class="keyword">local</span> path = <span class="global">require</span> <span class="string">'pl.path'</span> +<span class="keyword">local</span> dir = <span class="global">require</span> <span class="string">'pl.dir'</span> + +<span class="keyword">local</span> p1 = <span class="string">[[examples]]</span> +<span class="keyword">local</span> p2 = <span class="string">[[copy/of/examples]]</span> + +<span class="keyword">if</span> <span class="keyword">not</span> path.isfile <span class="string">'examples/testclone.lua'</span> <span class="keyword">then</span> + <span class="keyword">return</span> <span class="global">print</span> <span class="string">'please run this in the penlight folder (below examples)'</span> +<span class="keyword">end</span> + +<span class="comment">-- make a copy of the examples folder +</span>dir.clonetree(p1,p2,dir.copyfile) + +<span class="global">assert</span>(path.isdir <span class="string">'copy'</span>) + +<span class="global">print</span> <span class="string">'---'</span> +<span class="keyword">local</span> t = <span class="global">os</span>.time() +<span class="global">print</span>(lfs.touch(<span class="string">'examples/testclone.lua'</span>,t,t+<span class="number">10</span>)) + +<span class="comment">-- this should only update this file +</span>dir.clonetree(p1,p2, +<span class="keyword">function</span>(f1,f2) + <span class="keyword">local</span> t1 = path.getmtime(f1) + <span class="keyword">local</span> t2 = path.getmtime(f2) + <span class="comment">--print(f1,t1,f2,t2) +</span> <span class="keyword">if</span> t1 > t2 <span class="keyword">then</span> + dir.copyfile(f1,f2) + <span class="global">print</span>(f1,f2,t1,t2) + <span class="keyword">end</span> + <span class="keyword">return</span> <span class="keyword">true</span> +<span class="keyword">end</span>) + +<span class="comment">-- and get rid of the whole copy directory, with subdirs +</span>dir.rmtree <span class="string">'copy'</span> + +<span class="global">assert</span>(<span class="keyword">not</span> path.exists <span class="string">'copy'</span>)</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testconfig.lua.html b/docs/examples/testconfig.lua.html new file mode 100644 index 0000000..39e32e3 --- /dev/null +++ b/docs/examples/testconfig.lua.html @@ -0,0 +1,177 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><strong>testconfig.lua</strong></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testconfig.lua</h2> +<pre> +<span class="keyword">local</span> stringio = <span class="global">require</span> <span class="string">'pl.stringio'</span> +<span class="keyword">local</span> config = <span class="global">require</span> <span class="string">'pl.config'</span> + +<span class="keyword">local</span> <span class="keyword">function</span> dump(t,indent) + <span class="keyword">if</span> <span class="global">type</span>(t) == <span class="string">'table'</span> <span class="keyword">then</span> + <span class="global">io</span>.write(indent,<span class="string">'{\n'</span>) + <span class="keyword">local</span> newindent = indent..<span class="string">' '</span> + <span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="global">pairs</span>(t) <span class="keyword">do</span> + <span class="global">io</span>.write(newindent,k,<span class="string">'='</span>) + dump(v,indent) + <span class="global">io</span>.write(<span class="string">'\n'</span>) + <span class="keyword">end</span> + <span class="global">io</span>.write(newindent,<span class="string">'},\n'</span>) + <span class="keyword">else</span> + <span class="global">io</span>.write(indent,t,<span class="string">'('</span>,<span class="global">type</span>(t),<span class="string">')'</span>) + <span class="keyword">end</span> +<span class="keyword">end</span> + + +<span class="keyword">local</span> <span class="keyword">function</span> testconfig(test) + <span class="keyword">local</span> f = stringio.open(test) + <span class="keyword">local</span> c = config.read(f) + f:close() + dump(c,<span class="string">' '</span>) + <span class="global">print</span> <span class="string">'-----'</span> +<span class="keyword">end</span> + +testconfig <span class="string">[[ + ; comment 2 (an ini file) +[section!] +bonzo.dog=20,30 +config_parm=here we go again +depth = 2 +[another] +felix="cat" +]]</span> + +testconfig <span class="string">[[ +# this is a more Unix-y config file +fred = 1 +alice = 2 +home = /bonzo/dog/etc +]]</span> + +testconfig <span class="string">[[ +# this is just a set of comma-separated values +1000,444,222 +44,555,224 +]]</span></pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testglobal.lua.html b/docs/examples/testglobal.lua.html new file mode 100644 index 0000000..5618f98 --- /dev/null +++ b/docs/examples/testglobal.lua.html @@ -0,0 +1,154 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><strong>testglobal.lua</strong></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testglobal.lua</h2> +<pre> +<span class="comment">-- very simple lexer program which looks at all identifiers in a Lua +</span><span class="comment">-- file and checks whether they're in the global namespace. +</span><span class="comment">-- At the end, we dump out the result of count_map, which will give us +</span><span class="comment">-- unique identifiers with their usage count. +</span><span class="comment">-- (an example of a program which itself needs to be careful about what +</span><span class="comment">-- goes into the global namespace) +</span> +<span class="keyword">local</span> utils = <span class="global">require</span> <span class="string">'pl.utils'</span> +<span class="keyword">local</span> file = <span class="global">require</span> <span class="string">'pl.file'</span> +<span class="keyword">local</span> lexer = <span class="global">require</span> <span class="string">'pl.lexer'</span> +<span class="keyword">local</span> List = <span class="global">require</span> <span class="string">'pl.List'</span> +<span class="keyword">local</span> pretty = <span class="global">require</span> <span class="string">'pl.pretty'</span> +<span class="keyword">local</span> seq = <span class="global">require</span> <span class="string">'pl.seq'</span> +<span class="keyword">local</span> path = <span class="global">require</span> <span class="string">'pl.path'</span> + +utils.on_error <span class="string">'quit'</span> + +<span class="keyword">local</span> txt = file.read(arg[<span class="number">1</span>] <span class="keyword">or</span> path.normpath(<span class="string">'examples/testglobal.lua'</span>)) +<span class="keyword">local</span> globals = List() +<span class="keyword">for</span> t,v <span class="keyword">in</span> lexer.lua(txt) <span class="keyword">do</span> + <span class="keyword">if</span> t == <span class="string">'iden'</span> <span class="keyword">and</span> <span class="global">rawget</span>(_G,v) <span class="keyword">then</span> + globals:append(v) + <span class="keyword">end</span> +<span class="keyword">end</span> + +pretty.dump(seq.count_map(globals))</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testinputfields.lua.html b/docs/examples/testinputfields.lua.html new file mode 100644 index 0000000..fad1770 --- /dev/null +++ b/docs/examples/testinputfields.lua.html @@ -0,0 +1,141 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><strong>testinputfields.lua</strong></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testinputfields.lua</h2> +<pre> +<span class="keyword">local</span> input = <span class="global">require</span> <span class="string">'pl.input'</span> +<span class="keyword">local</span> sum = <span class="number">0.0</span> +<span class="keyword">local</span> count = <span class="number">0</span> +<span class="keyword">local</span> text = <span class="string">[[ + 981124001 2.0 18988.4 10047.1 4149.7 + 981125001 0.8 19104.0 9970.4 5088.7 + 981127003 0.5 19012.5 9946.9 3831.2 +]]</span> +<span class="keyword">for</span> id,magn,x <span class="keyword">in</span> input.fields(<span class="number">3</span>,<span class="string">' '</span>,text) <span class="keyword">do</span> + sum = sum + x + count = count + <span class="number">1</span> +<span class="keyword">end</span> +<span class="global">print</span>(<span class="string">'average x coord is '</span>,sum/count)</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testinputfields2.lua.html b/docs/examples/testinputfields2.lua.html new file mode 100644 index 0000000..9081ae1 --- /dev/null +++ b/docs/examples/testinputfields2.lua.html @@ -0,0 +1,137 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><strong>testinputfields2.lua</strong></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testinputfields2.lua</h2> +<pre> +<span class="keyword">local</span> input = <span class="global">require</span> <span class="string">'pl.input'</span> +<span class="keyword">local</span> seq = <span class="global">require</span> <span class="string">'pl.seq'</span> +<span class="keyword">local</span> text = <span class="string">[[ + 981124001 2.0 18988.4 10047.1 4149.7 + 981125001 0.8 19104.0 9970.4 5088.7 + 981127003 0.5 19012.5 9946.9 3831.2 +]]</span> +<span class="keyword">local</span> sum,count = seq.sum(input.fields ({<span class="number">3</span>},<span class="string">' '</span>,text)) +<span class="global">print</span>(sum/count)</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/testxml.lua.html b/docs/examples/testxml.lua.html new file mode 100644 index 0000000..d07dfa4 --- /dev/null +++ b/docs/examples/testxml.lua.html @@ -0,0 +1,210 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><strong>testxml.lua</strong></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>testxml.lua</h2> +<pre> +<span class="comment">-- an example showing 'pl.lexer' doing some serious work. +</span><span class="comment">-- The resulting Lua table is in the same LOM format used by luaexpat. +</span><span class="comment">-- This is (clearly) not a professional XML parser, so don't use it +</span><span class="comment">-- on your homework! +</span> +<span class="keyword">local</span> lexer = <span class="global">require</span> <span class="string">'pl.lexer'</span> +<span class="keyword">local</span> pretty = <span class="global">require</span> <span class="string">'pl.pretty'</span> + +<span class="keyword">local</span> append = <span class="global">table</span>.insert +<span class="keyword">local</span> skipws,expecting = lexer.skipws,lexer.expecting + +<span class="keyword">local</span> <span class="keyword">function</span> parse_element (tok,tag) + <span class="keyword">local</span> tbl,t,v,attrib + tbl = {} + tbl.tag = tag <span class="comment">-- LOM 'tag' is the element tag +</span> t,v = skipws(tok) + <span class="keyword">while</span> v ~= <span class="string">'/'</span> <span class="keyword">and</span> v ~= <span class="string">'>'</span> <span class="keyword">do</span> + <span class="keyword">if</span> t ~= <span class="string">'iden'</span> <span class="keyword">then</span> <span class="global">error</span>(<span class="string">'expecting attribute identifier'</span>) <span class="keyword">end</span> + attrib = v + expecting(tok,<span class="string">'='</span>) + v = expecting(tok,<span class="string">'string'</span>) + <span class="comment">-- LOM: 'attr' subtable contains attrib/value pairs and an ordered list of attribs +</span> <span class="keyword">if</span> <span class="keyword">not</span> tbl.attr <span class="keyword">then</span> tbl.attr = {} <span class="keyword">end</span> + tbl.attr[attrib] = v + append(tbl.attr,attrib) + t,v = skipws(tok) + <span class="keyword">end</span> + <span class="keyword">if</span> v == <span class="string">'/'</span> <span class="keyword">then</span> + expecting(tok,<span class="string">'>'</span>) + <span class="keyword">return</span> tbl + <span class="keyword">end</span> + <span class="comment">-- pick up element data +</span> t,v = tok() + <span class="keyword">while</span> <span class="keyword">true</span> <span class="keyword">do</span> + <span class="keyword">if</span> t == <span class="string">'<'</span> <span class="keyword">then</span> + t,v = skipws(tok) + <span class="keyword">if</span> t == <span class="string">'/'</span> <span class="keyword">then</span> <span class="comment">-- element end tag +</span> t,v = tok() + <span class="keyword">if</span> t == <span class="string">'>'</span> <span class="keyword">then</span> <span class="keyword">return</span> tbl <span class="keyword">end</span> + <span class="keyword">if</span> t == <span class="string">'iden'</span> <span class="keyword">and</span> v == tag <span class="keyword">then</span> + <span class="keyword">if</span> tok() == <span class="string">'>'</span> <span class="keyword">then</span> <span class="keyword">return</span> tbl <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="global">error</span>(<span class="string">'expecting end tag '</span>..tag) + <span class="keyword">else</span> + append(tbl,parse_element(tok,v)) <span class="comment">-- LOM: child elements added to table +</span> t,v = skipws(tok) + <span class="keyword">end</span> + <span class="keyword">else</span> + append(tbl,v) <span class="comment">-- LOM: text added to table +</span> t,v = skipws(tok) + <span class="keyword">end</span> + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">local</span> <span class="keyword">function</span> parse_xml (tok) + <span class="keyword">local</span> t = skipws(tok) + <span class="keyword">local</span> v + <span class="keyword">while</span> t == <span class="string">'<'</span> <span class="keyword">do</span> + t,v = tok() + <span class="keyword">if</span> t == <span class="string">'?'</span> <span class="keyword">or</span> t == <span class="string">'!'</span> <span class="keyword">then</span> + <span class="comment">-- skip meta stuff and commentary +</span> <span class="keyword">repeat</span> t = tok() <span class="keyword">until</span> t == <span class="string">'>'</span> + t = expecting(tok,<span class="string">'<'</span>) + <span class="keyword">else</span> + <span class="keyword">return</span> parse_element(tok,v) + <span class="keyword">end</span> + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">local</span> s = <span class="string">[[ +<?xml version="1.0" encoding="UTF-8"?> +<sensor name="closure-meter-2" id="7D7D0600006F0D00" loc="100,100,0" device="closure-meter" init="true"> +<detector name="closure-meter" phenomenon="closure" units="mm" id="1" + vmin="0" vmax="5000" device="closure-meter" calib="0,0;5000,5000" + sampling_interval="25000" measurement_interval="600000" +/> +</sensor> +]]</span> + +<span class="keyword">local</span> tok = lexer.scan(s,<span class="keyword">nil</span>,{space=<span class="keyword">false</span>},{<span class="global">string</span>=<span class="keyword">true</span>}) +<span class="keyword">local</span> res = parse_xml(tok) +<span class="global">print</span>(pretty.write(res))</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/examples/which.lua.html b/docs/examples/which.lua.html new file mode 100644 index 0000000..2b4b848 --- /dev/null +++ b/docs/examples/which.lua.html @@ -0,0 +1,156 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><strong>which.lua</strong></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>which.lua</h2> +<pre> +<span class="comment">-- a simple implementation of the which command. This looks for +</span><span class="comment">-- the given file on the path. On windows, it will assume an extension +</span><span class="comment">-- of .exe if no extension is given. +</span><span class="keyword">local</span> List = <span class="global">require</span> <span class="string">'pl.List'</span> +<span class="keyword">local</span> path = <span class="global">require</span> <span class="string">'pl.path'</span> +<span class="keyword">local</span> app = <span class="global">require</span> <span class="string">'pl.app'</span> + +<span class="keyword">local</span> pathl = List.split(<span class="global">os</span>.getenv <span class="string">'PATH'</span>,path.dirsep) + +<span class="keyword">local</span> <span class="keyword">function</span> which (file) + <span class="keyword">local</span> res = pathl:map(path.join,file) + res = res:filter(path.exists) + <span class="keyword">if</span> res <span class="keyword">then</span> <span class="keyword">return</span> res[<span class="number">1</span>] <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="keyword">local</span> _,lua = app.lua() +<span class="keyword">local</span> file = arg[<span class="number">1</span>] <span class="keyword">or</span> lua <span class="comment">-- i.e. location of lua executable +</span><span class="keyword">local</span> try + +<span class="keyword">if</span> <span class="keyword">not</span> file <span class="keyword">then</span> <span class="keyword">return</span> <span class="global">print</span> <span class="string">'must provide a filename'</span> <span class="keyword">end</span> + +<span class="keyword">if</span> path.extension(file) == <span class="string">''</span> <span class="keyword">and</span> path.is_windows <span class="keyword">then</span> + try = which(file..<span class="string">'.exe'</span>) +<span class="keyword">else</span> + try = which(file) +<span class="keyword">end</span> + +<span class="keyword">if</span> try <span class="keyword">then</span> <span class="global">print</span>(try) <span class="keyword">else</span> <span class="global">print</span> <span class="string">'cannot find on path'</span> <span class="keyword">end</span></pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..d241189 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,394 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + + + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="libraries/pl.html">pl</a></li> + <li><a href="libraries/pl.Set.html">pl.Set</a></li> + <li><a href="libraries/pl.app.html">pl.app</a></li> + <li><a href="libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="libraries/pl.class.html">pl.class</a></li> + <li><a href="libraries/pl.compat.html">pl.compat</a></li> + <li><a href="libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="libraries/pl.config.html">pl.config</a></li> + <li><a href="libraries/pl.data.html">pl.data</a></li> + <li><a href="libraries/pl.dir.html">pl.dir</a></li> + <li><a href="libraries/pl.file.html">pl.file</a></li> + <li><a href="libraries/pl.func.html">pl.func</a></li> + <li><a href="libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="libraries/pl.input.html">pl.input</a></li> + <li><a href="libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="libraries/pl.operator.html">pl.operator</a></li> + <li><a href="libraries/pl.path.html">pl.path</a></li> + <li><a href="libraries/pl.permute.html">pl.permute</a></li> + <li><a href="libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="libraries/pl.seq.html">pl.seq</a></li> + <li><a href="libraries/pl.sip.html">pl.sip</a></li> + <li><a href="libraries/pl.strict.html">pl.strict</a></li> + <li><a href="libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="libraries/pl.template.html">pl.template</a></li> + <li><a href="libraries/pl.test.html">pl.test</a></li> + <li><a href="libraries/pl.text.html">pl.text</a></li> + <li><a href="libraries/pl.types.html">pl.types</a></li> + <li><a href="libraries/pl.url.html">pl.url</a></li> + <li><a href="libraries/pl.utils.html">pl.utils</a></li> + <li><a href="libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="classes/pl.Date.html">pl.Date</a></li> + <li><a href="classes/pl.List.html">pl.List</a></li> + <li><a href="classes/pl.Map.html">pl.Map</a></li> + <li><a href="classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="manual/01-introduction.md.html">Introduction</a></li> + <li><a href="manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="manual/05-dates.md.html">Date and Time</a></li> + <li><a href="manual/06-data.md.html">Data</a></li> + <li><a href="manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + + <h2>Penlight Lua Libraries 1.6.0</h2> + <p>The documentation is available <a href="manual/01-introduction.md.html#">here</a>.</p> + +<h2>Libraries</h2> +<table class="module_list"> + <tr> + <td class="name" nowrap><a href="libraries/pl.html">pl</a></td> + <td class="summary">Entry point for loading all PL libraries only on demand, into the global space.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.Set.html">pl.Set</a></td> + <td class="summary">A Set class.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.app.html">pl.app</a></td> + <td class="summary">Application support functions.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.array2d.html">pl.array2d</a></td> + <td class="summary">Operations on two-dimensional arrays.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.class.html">pl.class</a></td> + <td class="summary">Provides a reuseable and convenient framework for creating classes in Lua.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.compat.html">pl.compat</a></td> + <td class="summary">Lua 5.1/5.2/5.3 compatibility.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.comprehension.html">pl.comprehension</a></td> + <td class="summary">List comprehensions implemented in Lua.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.config.html">pl.config</a></td> + <td class="summary">Reads configuration files into a Lua table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.data.html">pl.data</a></td> + <td class="summary">Reading and querying simple tabular data.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.dir.html">pl.dir</a></td> + <td class="summary">Listing files in directories and creating/removing directory paths.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.file.html">pl.file</a></td> + <td class="summary">File manipulation functions: reading, writing, moving and copying.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.func.html">pl.func</a></td> + <td class="summary">Functional helpers like composition, binding and placeholder expressions.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.import_into.html">pl.import_into</a></td> + <td class="summary">PL loader, for loading all PL libraries, only on demand.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.input.html">pl.input</a></td> + <td class="summary">Iterators for extracting words or numbers from an input source.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.lapp.html">pl.lapp</a></td> + <td class="summary">Simple command-line parsing using human-readable specification.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.lexer.html">pl.lexer</a></td> + <td class="summary">Lexical scanner for creating a sequence of tokens from text.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.luabalanced.html">pl.luabalanced</a></td> + <td class="summary">Extract delimited Lua sequences from strings.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.operator.html">pl.operator</a></td> + <td class="summary">Lua operators available as functions.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.path.html">pl.path</a></td> + <td class="summary">Path manipulation and file queries.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.permute.html">pl.permute</a></td> + <td class="summary">Permutation operations.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.pretty.html">pl.pretty</a></td> + <td class="summary">Pretty-printing Lua tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.seq.html">pl.seq</a></td> + <td class="summary">Manipulating iterators as sequences.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.sip.html">pl.sip</a></td> + <td class="summary">Simple Input Patterns (SIP).</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.strict.html">pl.strict</a></td> + <td class="summary">Checks uses of undeclared global variables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.stringio.html">pl.stringio</a></td> + <td class="summary">Reading and writing strings using file-like objects.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.stringx.html">pl.stringx</a></td> + <td class="summary">Python-style extended string library.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.tablex.html">pl.tablex</a></td> + <td class="summary">Extended operations on Lua tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.template.html">pl.template</a></td> + <td class="summary">A template preprocessor.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.test.html">pl.test</a></td> + <td class="summary">Useful test utilities.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.text.html">pl.text</a></td> + <td class="summary">Text processing utilities.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.types.html">pl.types</a></td> + <td class="summary">Dealing with Detailed Type Information</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.url.html">pl.url</a></td> + <td class="summary">Python-style URL quoting library.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.utils.html">pl.utils</a></td> + <td class="summary">Generally useful routines.</td> + </tr> + <tr> + <td class="name" nowrap><a href="libraries/pl.xml.html">pl.xml</a></td> + <td class="summary">XML LOM Utilities.</td> + </tr> +</table> +<h2>Classes</h2> +<table class="module_list"> + <tr> + <td class="name" nowrap><a href="classes/pl.Date.html">pl.Date</a></td> + <td class="summary">Date and Date Format classes.</td> + </tr> + <tr> + <td class="name" nowrap><a href="classes/pl.List.html">pl.List</a></td> + <td class="summary">Python-style list class.</td> + </tr> + <tr> + <td class="name" nowrap><a href="classes/pl.Map.html">pl.Map</a></td> + <td class="summary">A Map class.</td> + </tr> + <tr> + <td class="name" nowrap><a href="classes/pl.MultiMap.html">pl.MultiMap</a></td> + <td class="summary">MultiMap, a Map which has multiple values per key.</td> + </tr> + <tr> + <td class="name" nowrap><a href="classes/pl.OrderedMap.html">pl.OrderedMap</a></td> + <td class="summary">OrderedMap, a map which preserves ordering.</td> + </tr> +</table> +<h2>Manual</h2> +<table class="module_list"> + <tr> + <td class="name" nowrap><a href="manual/01-introduction.md.html">01-introduction.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/02-arrays.md.html">02-arrays.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/03-strings.md.html">03-strings.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/04-paths.md.html">04-paths.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/05-dates.md.html">05-dates.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/06-data.md.html">06-data.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/07-functional.md.html">07-functional.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/08-additional.md.html">08-additional.md</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="manual/09-discussion.md.html">09-discussion.md</a></td> + <td class="summary"></td> + </tr> +</table> +<h2>Examples</h2> +<table class="module_list"> + <tr> + <td class="name" nowrap><a href="examples/seesubst.lua.html">seesubst.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/sipscan.lua.html">sipscan.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/symbols.lua.html">symbols.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/test-cmp.lua.html">test-cmp.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/test-data.lua.html">test-data.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/test-pretty.lua.html">test-pretty.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/test-symbols.lua.html">test-symbols.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testapp.lua.html">testapp.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testclone.lua.html">testclone.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testconfig.lua.html">testconfig.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testglobal.lua.html">testglobal.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testinputfields.lua.html">testinputfields.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testinputfields2.lua.html">testinputfields2.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/testxml.lua.html">testxml.lua</a></td> + <td class="summary"></td> + </tr> + <tr> + <td class="name" nowrap><a href="examples/which.lua.html">which.lua</a></td> + <td class="summary"></td> + </tr> +</table> + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/ldoc_fixed.css b/docs/ldoc_fixed.css new file mode 100644 index 0000000..9b0fc00 --- /dev/null +++ b/docs/ldoc_fixed.css @@ -0,0 +1,311 @@ +/* BEGIN RESET + +Copyright (c) 2010, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.com/yui/license.html +version: 2.8.2r1 +*/ +html { + color: #000; + background: #FFF; +} +body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { + margin: 0; + padding: 0; +} +table { + border-collapse: collapse; + border-spacing: 0; +} +fieldset,img { + border: 0; +} +address,caption,cite,code,dfn,em,strong,th,var,optgroup { + font-style: inherit; + font-weight: inherit; +} +del,ins { + text-decoration: none; +} +li { + margin-left: 20px; +} +caption,th { + text-align: left; +} +h1,h2,h3,h4,h5,h6 { + font-size: 100%; + font-weight: bold; +} +q:before,q:after { + content: ''; +} +abbr,acronym { + border: 0; + font-variant: normal; +} +sup { + vertical-align: baseline; +} +sub { + vertical-align: baseline; +} +legend { + color: #000; +} +input,button,textarea,select,optgroup,option { + font-family: inherit; + font-size: inherit; + font-style: inherit; + font-weight: inherit; +} +input,button,textarea,select {*font-size:100%; +} +/* END RESET */ + +body { + margin-left: 1em; + margin-right: 1em; + font-family: arial, helvetica, geneva, sans-serif; + background-color: #ffffff; margin: 0px; +} + +code, tt { font-family: monospace; font-size: 1.1em; } +span.parameter { font-family:monospace; } +span.parameter:after { content:":"; } +span.types:before { content:"("; } +span.types:after { content:")"; } +.type { font-weight: bold; font-style:italic } + +body, p, td, th { font-size: .95em; line-height: 1.2em;} + +p, ul { margin: 10px 0 0 0px;} + +strong { font-weight: bold;} + +em { font-style: italic;} + +h1 { + font-size: 1.5em; + margin: 0 0 20px 0; +} +h2, h3, h4 { margin: 15px 0 10px 0; } +h2 { font-size: 1.25em; } +h3 { font-size: 1.15em; } +h4 { font-size: 1.06em; } + +a:link { font-weight: bold; color: #004080; text-decoration: none; } +a:visited { font-weight: bold; color: #006699; text-decoration: none; } +a:link:hover { text-decoration: underline; } + +hr { + color:#cccccc; + background: #00007f; + height: 1px; +} + +blockquote { margin-left: 3em; } + +ul { list-style-type: disc; } + +p.name { + font-family: "Andale Mono", monospace; + padding-top: 1em; +} + +pre { + background-color: rgb(245, 245, 245); + border: 1px solid #C0C0C0; /* silver */ + padding: 10px; + margin: 10px 0 10px 0; + overflow: auto; + font-family: "Andale Mono", monospace; +} + +pre.example { + font-size: .85em; +} + +table.index { border: 1px #00007f; } +table.index td { text-align: left; vertical-align: top; } + +#container { + margin-left: 1em; + margin-right: 1em; + background-color: #ffffff; +} + +#product { + text-align: center; + border-bottom: 1px solid #cccccc; + background-color: #ffffff; +} + +#product big { + font-size: 2em; +} + +#main { + background-color:#FFFFFF; // #f0f0f0; + border-left: 1px solid #cccccc; +} + +#navigation { + position: fixed; + top: 0; + left: 0; + float: left; + width: 14em; + vertical-align: top; + background-color:#FFFFFF; // #f0f0f0; + border-right: 2px solid #cccccc; + overflow: visible; + overflow-y: scroll; + height: 100%; + padding-left: 1em; +} + +#navigation h2 { + background-color:#FFFFFF;//:#e7e7e7; + font-size:1.1em; + color:#000000; + text-align: left; + padding:0.2em; + border-bottom:1px solid #dddddd; +} + +#navigation ul +{ + font-size:1em; + list-style-type: none; + margin: 1px 1px 10px 1px; +} + +#navigation li { + text-indent: -1em; + display: block; + margin: 3px 0px 0px 22px; +} + +#navigation li li a { + margin: 0px 3px 0px -1em; +} + +#content { + margin-left: 14em; + padding: 1em; + padding-left: 2em; + width: 700px; + border-left: 2px solid #cccccc; + // border-right: 2px solid #cccccc; + background-color: #ffffff; +} + +#about { + clear: both; + padding-left: 1em; + margin-left: 14em; // avoid the damn sidebar! + border-top: 2px solid #cccccc; + border-left: 2px solid #cccccc; + background-color: #ffffff; +} + +@media print { + body { + font: 12pt "Times New Roman", "TimeNR", Times, serif; + } + a { font-weight: bold; color: #004080; text-decoration: underline; } + + #main { + background-color: #ffffff; + border-left: 0px; + } + + #container { + margin-left: 2%; + margin-right: 2%; + background-color: #ffffff; + } + + #content { + padding: 1em; + background-color: #ffffff; + } + + #navigation { + display: none; + } + pre.example { + font-family: "Andale Mono", monospace; + font-size: 10pt; + page-break-inside: avoid; + } +} + +table.module_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.module_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.module_list td.name { background-color: #f0f0f0; ; min-width: 200px; } +table.module_list td.summary { width: 100%; } + +table.function_list { + border-width: 1px; + border-style: solid; + border-color: #cccccc; + border-collapse: collapse; +} +table.function_list td { + border-width: 1px; + padding: 3px; + border-style: solid; + border-color: #cccccc; +} +table.function_list td.name { background-color: #f6f6ff; ; min-width: 200px; } +table.function_list td.summary { width: 100%; } + +dl.table dt, dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;} +dl.table dd, dl.function dd {padding-bottom: 1em; margin: 10px 0 0 20px;} +dl.table h3, dl.function h3 {font-size: .95em;} + +ul.nowrap { + overflow:auto; + whitespace:nowrap; +} + +/* stop sublists from having initial vertical space */ +ul ul { margin-top: 0px; } +ol ul { margin-top: 0px; } +ol ol { margin-top: 0px; } +ul ol { margin-top: 0px; } + +/* make the target distinct; helps when we're navigating to a function */ +a:target + * { + background-color: #FF9; +} + + +/* styles for prettification of source */ +pre .comment { color: #558817; } +pre .constant { color: #a8660d; } +pre .escape { color: #844631; } +pre .keyword { color: #aa5050; font-weight: bold; } +pre .library { color: #0e7c6b; } +pre .marker { color: #512b1e; background: #fedc56; font-weight: bold; } +pre .string { color: #8080ff; } +pre .number { color: #f8660d; } +pre .operator { color: #2239a8; font-weight: bold; } +pre .preprocessor, pre .prepro { color: #a33243; } +pre .global { color: #800080; } +pre .user-keyword { color: #800080; } +pre .prompt { color: #558817; } +pre .url { color: #272fc2; text-decoration: underline; } + diff --git a/docs/libraries/pl.Set.html b/docs/libraries/pl.Set.html new file mode 100644 index 0000000..8eda41e --- /dev/null +++ b/docs/libraries/pl.Set.html @@ -0,0 +1,650 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#metamethods">metamethods</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><strong>pl.Set</strong></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.Set</code></h1> +<p>A Set class.</p> +<p> + +<pre> +> Set = <span class="global">require</span> <span class="string">'pl.Set'</span> +> = Set{<span class="string">'one'</span>,<span class="string">'two'</span>} == Set{<span class="string">'two'</span>,<span class="string">'one'</span>} +<span class="keyword">true</span> +> fruit = Set{<span class="string">'apple'</span>,<span class="string">'banana'</span>,<span class="string">'orange'</span>} +> = fruit[<span class="string">'banana'</span>] +<span class="keyword">true</span> +> = fruit[<span class="string">'hazelnut'</span>] +<span class="keyword">nil</span> +> colours = Set{<span class="string">'red'</span>,<span class="string">'orange'</span>,<span class="string">'green'</span>,<span class="string">'blue'</span>} +> = fruit,colours +[apple,orange,banana] [blue,green,orange,red] +> = fruit+colours +[blue,green,apple,red,orange,banana] +[orange] +> more_fruits = fruit + <span class="string">'apricot'</span> +> = fruit*colours + = more_fruits, fruit +banana,apricot,apple,orange] [banana,apple,orange] +</pre> + + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a>, <a href="../libraries/pl.class.html#">pl.class</a>, <a href="../classes/pl.Map.html#">pl.Map</a>, (<a href="../classes/pl.List.html#">pl.List</a> if __tostring is used)</p></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#Set">Set (t)</a></td> + <td class="summary">create a set.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#values">values (self)</a></td> + <td class="summary">get a list of the values in a set.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#map">map (self, fn, ...)</a></td> + <td class="summary">map a function over the values of a set.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#union">union (self, set)</a></td> + <td class="summary">union of two sets (also +).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#intersection">intersection (self, set)</a></td> + <td class="summary">intersection of two sets (also *).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#difference">difference (self, set)</a></td> + <td class="summary">new set with elements in the set that are not in the other (also -).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#issubset">issubset (self, set)</a></td> + <td class="summary">is the first set a subset of the second (also <)?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isempty">isempty (self)</a></td> + <td class="summary">is the set empty?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isdisjoint">isdisjoint (s1, s2)</a></td> + <td class="summary">are the sets disjoint?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#len">len (s)</a></td> + <td class="summary">size of this set (also # for 5.2).</td> + </tr> +</table> +<h2><a href="#metamethods">metamethods</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#__tostring">__tostring ()</a></td> + <td class="summary">string representation of a set.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__add">__add ()</a></td> + <td class="summary">union of sets.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__mul">__mul ()</a></td> + <td class="summary">intersection of sets.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__sub">__sub ()</a></td> + <td class="summary">difference of sets.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__pow">__pow ()</a></td> + <td class="summary">symmetric difference of sets.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__lt">__lt ()</a></td> + <td class="summary">first set subset of second?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__len">__len ()</a></td> + <td class="summary">cardinality of set (5.2).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#__eq">__eq (s1, s2)</a></td> + <td class="summary">equality between sets.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "Set"></a> + <strong>Set (t)</strong> + </dt> + <dd> + create a set. <br> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + may be a Set, Map or list-like table. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "values"></a> + <strong>values (self)</strong> + </dt> + <dd> + get a list of the values in a set. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list + </ol> + + + + +</dd> + <dt> + <a name = "map"></a> + <strong>map (self, fn, ...)</strong> + </dt> + <dd> + map a function over the values of a set. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + <li><span class="parameter">fn</span> + a function + </li> + <li><span class="parameter">...</span> + extra arguments to pass to the function. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new set + </ol> + + + + +</dd> + <dt> + <a name = "union"></a> + <strong>union (self, set)</strong> + </dt> + <dd> + union of two sets (also +). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + <li><span class="parameter">set</span> + another set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new set + </ol> + + + + +</dd> + <dt> + <a name = "intersection"></a> + <strong>intersection (self, set)</strong> + </dt> + <dd> + intersection of two sets (also *). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + <li><span class="parameter">set</span> + another set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new set + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">> s = Set{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +> t = Set{<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} +> = t +[<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>] +> = Set.intersection(s,t) +[<span class="number">30</span>,<span class="number">20</span>] +> = s*t +[<span class="number">30</span>,<span class="number">20</span>]</pre> + </ul> + +</dd> + <dt> + <a name = "difference"></a> + <strong>difference (self, set)</strong> + </dt> + <dd> + new set with elements in the set that are not in the other (also -). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + <li><span class="parameter">set</span> + another set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new set + </ol> + + + + +</dd> + <dt> + <a name = "issubset"></a> + <strong>issubset (self, set)</strong> + </dt> + <dd> + is the first set a subset of the second (also <)?. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + <li><span class="parameter">set</span> + another set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "isempty"></a> + <strong>isempty (self)</strong> + </dt> + <dd> + is the set empty?. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">self</span> + a Set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "isdisjoint"></a> + <strong>isdisjoint (s1, s2)</strong> + </dt> + <dd> + are the sets disjoint? (no elements in common). + Uses naive definition, i.e. that intersection is empty + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s1</span> + a Set + </li> + <li><span class="parameter">s2</span> + another set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "len"></a> + <strong>len (s)</strong> + </dt> + <dd> + size of this set (also # for 5.2). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + a Set + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + size + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="metamethods"></a>metamethods</h2> + + <dl class="function"> + <dt> + <a name = "__tostring"></a> + <strong>__tostring ()</strong> + </dt> + <dd> + string representation of a set. + + + + + + + +</dd> + <dt> + <a name = "__add"></a> + <strong>__add ()</strong> + </dt> + <dd> + union of sets. + + + + + + + +</dd> + <dt> + <a name = "__mul"></a> + <strong>__mul ()</strong> + </dt> + <dd> + intersection of sets. + + + + + + + +</dd> + <dt> + <a name = "__sub"></a> + <strong>__sub ()</strong> + </dt> + <dd> + difference of sets. + + + + + + + +</dd> + <dt> + <a name = "__pow"></a> + <strong>__pow ()</strong> + </dt> + <dd> + symmetric difference of sets. + + + + + + + +</dd> + <dt> + <a name = "__lt"></a> + <strong>__lt ()</strong> + </dt> + <dd> + first set subset of second? + + + + + + + +</dd> + <dt> + <a name = "__len"></a> + <strong>__len ()</strong> + </dt> + <dd> + cardinality of set (5.2). + + + + + + + +</dd> + <dt> + <a name = "__eq"></a> + <strong>__eq (s1, s2)</strong> + </dt> + <dd> + equality between sets. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s1</span> + + </li> + <li><span class="parameter">s2</span> + + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.app.html b/docs/libraries/pl.app.html new file mode 100644 index 0000000..fd69387 --- /dev/null +++ b/docs/libraries/pl.app.html @@ -0,0 +1,310 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><strong>pl.app</strong></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.app</code></h1> +<p>Application support functions.</p> +<p> See <a href="../manual/01-introduction.md.html#Application_Support">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.path.html#">pl.path</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#require_here">require_here (base)</a></td> + <td class="summary">add the current script’s path to the Lua module path.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#appfile">appfile (file)</a></td> + <td class="summary">return a suitable path for files private to this application.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#platform">platform ()</a></td> + <td class="summary">return string indicating operating system.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#lua">lua ()</a></td> + <td class="summary">return the full command-line used to invoke this script.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#parse_args">parse_args (args, flags_with_values)</a></td> + <td class="summary">parse command-line arguments into flags and parameters.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "require_here"></a> + <strong>require_here (base)</strong> + </dt> + <dd> + add the current script’s path to the Lua module path. + Applies to both the source and the binary module paths. It makes it easy for + the main file of a multi-file program to access its modules in the same directory. + <code>base</code> allows these modules to be put in a specified subdirectory, to allow for + cleaner deployment and resolve potential conflicts between a script name and its + library directory. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">base</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + optional base directory. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the current script’s path with a trailing slash + </ol> + + + + +</dd> + <dt> + <a name = "appfile"></a> + <strong>appfile (file)</strong> + </dt> + <dd> + return a suitable path for files private to this application. + These will look like ‘~/.SNAME/file’, with ‘~’ as with expanduser and + SNAME is the name of the script without .lua extension. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">file</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a filename (w/out path) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + a full pathname, or nil</li> + <li> + ‘cannot create’ error</li> + </ol> + + + + +</dd> + <dt> + <a name = "platform"></a> + <strong>platform ()</strong> + </dt> + <dd> + return string indicating operating system. + + + + <h3>Returns:</h3> + <ol> + + ‘Windows’,‘OSX’ or whatever uname returns (e.g. ‘Linux’) + </ol> + + + + +</dd> + <dt> + <a name = "lua"></a> + <strong>lua ()</strong> + </dt> + <dd> + return the full command-line used to invoke this script. + Any extra flags occupy slots, so that <code>lua -lpl</code> gives us <code>{[-2]='lua',[-1]='-lpl'}</code> + + + + <h3>Returns:</h3> + <ol> + <li> + command-line</li> + <li> + name of Lua program used</li> + </ol> + + + + +</dd> + <dt> + <a name = "parse_args"></a> + <strong>parse_args (args, flags_with_values)</strong> + </dt> + <dd> + parse command-line arguments into flags and parameters. + Understands GNU-style command-line flags; short (<code>-f</code>) and long (<code>–flag</code>). + These may be given a value with either ‘=’ or ‘:’ (<code>-k:2</code>,<code>–alpha=3.2</code>,<code>-n2</code>); + note that a number value can be given without a space. + Multiple short args can be combined like so: ( <code>-abcd</code>). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">args</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">{string}</a></span> + an array of strings (default is the global <code>arg</code>) + </li> + <li><span class="parameter">flags_with_values</span> + <span class="types"><span class="type">tab</span></span> + any flags that take values, e.g. <code>{out=true}</code> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + a table of flags (flag=value pairs)</li> + <li> + an array of parameters</li> + </ol> + + <h3>Raises:</h3> + if args is nil, then the global <code>args</code> must be available! + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.array2d.html b/docs/libraries/pl.array2d.html new file mode 100644 index 0000000..a15b347 --- /dev/null +++ b/docs/libraries/pl.array2d.html @@ -0,0 +1,1151 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><strong>pl.array2d</strong></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.array2d</code></h1> +<p>Operations on two-dimensional arrays.</p> +<p> See <a href="../manual/02-arrays.md.html#Operations_on_two_dimensional_tables">The Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a>, <a href="../libraries/pl.types.html#">pl.types</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#size">size (t)</a></td> + <td class="summary">return the row and column size.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#column">column (a, key)</a></td> + <td class="summary">extract a column from the 2D array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#map">map (f, a, arg)</a></td> + <td class="summary">map a function over a 2D array</td> + </tr> + <tr> + <td class="name" nowrap><a href="#reduce_rows">reduce_rows (f, a)</a></td> + <td class="summary">reduce the rows using a function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#reduce_cols">reduce_cols (f, a)</a></td> + <td class="summary">reduce the columns using a function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#reduce2">reduce2 (opc, opr, a)</a></td> + <td class="summary">reduce a 2D array into a scalar, using two operations.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#map2">map2 (f, ad, bd, a, b, arg)</a></td> + <td class="summary">map a function over two arrays.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#product">product (f, t1, t2)</a></td> + <td class="summary">cartesian product of two 1d arrays.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#flatten">flatten (t)</a></td> + <td class="summary">flatten a 2D array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#reshape">reshape (t, nrows, co)</a></td> + <td class="summary">reshape a 2D array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#swap_rows">swap_rows (t, i1, i2)</a></td> + <td class="summary">swap two rows of an array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#swap_cols">swap_cols (t, j1, j2)</a></td> + <td class="summary">swap two columns of an array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#extract_rows">extract_rows (t, ridx)</a></td> + <td class="summary">extract the specified rows.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#extract_cols">extract_cols (t, cidx)</a></td> + <td class="summary">extract the specified columns.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#remove_row">remove_row (t, i)</a></td> + <td class="summary">remove a row from an array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#remove_col">remove_col (t, j)</a></td> + <td class="summary">remove a column from an array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#parse_range">parse_range (s)</a></td> + <td class="summary">parse a spreadsheet range.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#range">range (t, rstr)</a></td> + <td class="summary">get a slice of a 2D array using spreadsheet range notation.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#slice">slice (t, i1, j1, i2, j2)</a></td> + <td class="summary">get a slice of a 2D array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#set">set (t, value, i1, j1, i2, j2)</a></td> + <td class="summary">set a specified range of an array to a value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#write">write (t, f, fmt, i1, j1, i2, j2)</a></td> + <td class="summary">write a 2D array to a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#forall">forall (t, row_op, end_row_op, i1, j1, i2, j2)</a></td> + <td class="summary">perform an operation for all values in a 2D array.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#move">move (dest, di, dj, src, i1, j1, i2, j2)</a></td> + <td class="summary">move a block from the destination to the source.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#iter">iter (a, indices, i1, j1, i2, j2)</a></td> + <td class="summary">iterate over all elements in a 2D array, with optional indices.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#columns">columns (a)</a></td> + <td class="summary">iterate over all columns.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#new">new (rows, cols, val)</a></td> + <td class="summary">new array of specified dimensions</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "size"></a> + <strong>size (t)</strong> + </dt> + <dd> + return the row and column size. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2d array + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + <span class="types"><span class="type">int</span></span> + number of rows</li> + <li> + <span class="types"><span class="type">int</span></span> + number of cols</li> + </ol> + + + + +</dd> + <dt> + <a name = "column"></a> + <strong>column (a, key)</strong> + </dt> + <dd> + extract a column from the 2D array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + <li><span class="parameter">key</span> + an index or key + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + 1d array + </ol> + + + + +</dd> + <dt> + <a name = "map"></a> + <strong>map (f, a, arg)</strong> + </dt> + <dd> + map a function over a 2D array + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + a function of at least one argument + </li> + <li><span class="parameter">a</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + <li><span class="parameter">arg</span> + an optional extra argument to be passed to the function. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + 2d array + </ol> + + + + +</dd> + <dt> + <a name = "reduce_rows"></a> + <strong>reduce_rows (f, a)</strong> + </dt> + <dd> + reduce the rows using a function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + a binary function + </li> + <li><span class="parameter">a</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + 1d array + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#reduce">pl.tablex.reduce</a> + </ul> + + +</dd> + <dt> + <a name = "reduce_cols"></a> + <strong>reduce_cols (f, a)</strong> + </dt> + <dd> + reduce the columns using a function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + a binary function + </li> + <li><span class="parameter">a</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + 1d array + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#reduce">pl.tablex.reduce</a> + </ul> + + +</dd> + <dt> + <a name = "reduce2"></a> + <strong>reduce2 (opc, opr, a)</strong> + </dt> + <dd> + reduce a 2D array into a scalar, using two operations. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">opc</span> + <span class="types"><span class="type">func</span></span> + operation to reduce the final result + </li> + <li><span class="parameter">opr</span> + <span class="types"><span class="type">func</span></span> + operation to reduce the rows + </li> + <li><span class="parameter">a</span> + 2D array + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "map2"></a> + <strong>map2 (f, ad, bd, a, b, arg)</strong> + </dt> + <dd> + map a function over two arrays. + They can be both or either 2D arrays + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + function of at least two arguments + </li> + <li><span class="parameter">ad</span> + <span class="types"><span class="type">int</span></span> + order of first array (1 or 2) + </li> + <li><span class="parameter">bd</span> + <span class="types"><span class="type">int</span></span> + order of second array (1 or 2) + </li> + <li><span class="parameter">a</span> + <span class="types"><span class="type">tab</span></span> + 1d or 2d array + </li> + <li><span class="parameter">b</span> + <span class="types"><span class="type">tab</span></span> + 1d or 2d array + </li> + <li><span class="parameter">arg</span> + optional extra argument to pass to function + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + 2D array, unless both arrays are 1D + </ol> + + + + +</dd> + <dt> + <a name = "product"></a> + <strong>product (f, t1, t2)</strong> + </dt> + <dd> + cartesian product of two 1d arrays. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + a function of 2 arguments + </li> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">array</span></span> + a 1d table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">array</span></span> + a 1d table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + 2d table + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">product(<span class="string">'..'</span>,{<span class="number">1</span>,<span class="number">2</span>},{<span class="string">'a'</span>,<span class="string">'b'</span>}) == {{<span class="string">'1a'</span>,<span class="string">'2a'</span>},{<span class="string">'1b'</span>,<span class="string">'2b'</span>}}</pre> + </ul> + +</dd> + <dt> + <a name = "flatten"></a> + <strong>flatten (t)</strong> + </dt> + <dd> + flatten a 2D array. + (this goes over columns first.) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + 2d table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a 1d table + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">flatten {{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">3</span>,<span class="number">4</span>},{<span class="number">5</span>,<span class="number">6</span>}} == {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "reshape"></a> + <strong>reshape (t, nrows, co)</strong> + </dt> + <dd> + reshape a 2D array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + <li><span class="parameter">nrows</span> + <span class="types"><span class="type">int</span></span> + new number of rows + </li> + <li><span class="parameter">co</span> + <span class="types"><span class="type">bool</span></span> + column-order (Fortran-style) (default false) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new 2d array + </ol> + + + + +</dd> + <dt> + <a name = "swap_rows"></a> + <strong>swap_rows (t, i1, i2)</strong> + </dt> + <dd> + swap two rows of an array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2d array + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + a row index + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + a row index + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "swap_cols"></a> + <strong>swap_cols (t, j1, j2)</strong> + </dt> + <dd> + swap two columns of an array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2d array + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + a column index + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + a column index + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "extract_rows"></a> + <strong>extract_rows (t, ridx)</strong> + </dt> + <dd> + extract the specified rows. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + <li><span class="parameter">ridx</span> + <span class="types"><span class="type">{int}</span></span> + a table of row indices + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "extract_cols"></a> + <strong>extract_cols (t, cidx)</strong> + </dt> + <dd> + extract the specified columns. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + 2d array + </li> + <li><span class="parameter">cidx</span> + <span class="types"><span class="type">{int}</span></span> + a table of column indices + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "remove_row"></a> + <strong>remove_row (t, i)</strong> + </dt> + <dd> + remove a row from an array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2d array + </li> + <li><span class="parameter">i</span> + <span class="types"><span class="type">int</span></span> + a row index + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "remove_col"></a> + <strong>remove_col (t, j)</strong> + </dt> + <dd> + remove a column from an array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2d array + </li> + <li><span class="parameter">j</span> + <span class="types"><span class="type">int</span></span> + a column index + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "parse_range"></a> + <strong>parse_range (s)</strong> + </dt> + <dd> + parse a spreadsheet range. + The range can be specified either as ‘A1:B2’ or ‘R1C1:R2C2’; + a special case is a single element (e.g ‘A1’ or ‘R1C1’) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a range. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + <span class="types"><span class="type">int</span></span> + start col</li> + <li> + <span class="types"><span class="type">int</span></span> + start row</li> + <li> + <span class="types"><span class="type">int</span></span> + end col</li> + <li> + <span class="types"><span class="type">int</span></span> + end row</li> + </ol> + + + + +</dd> + <dt> + <a name = "range"></a> + <strong>range (t, rstr)</strong> + </dt> + <dd> + get a slice of a 2D array using spreadsheet range notation. @see parse_range + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + <li><span class="parameter">rstr</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + range expression + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a slice + </ol> + + + <h3>See also:</h3> + <ul> + <li><a href="../libraries/pl.array2d.html#parse_range">array2d.parse_range</a></li> + <li><a href="../libraries/pl.array2d.html#slice">array2d.slice</a></li> + </ul> + + +</dd> + <dt> + <a name = "slice"></a> + <strong>slice (t, i1, j1, i2, j2)</strong> + </dt> + <dd> + get a slice of a 2D array. Note that if the specified range has + a 1D result, the rank of the result will be 1. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start row (default 1) + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + start col (default 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end row (default N) + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + end col (default M) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an array, 2D in general but 1D in special cases. + </ol> + + + + +</dd> + <dt> + <a name = "set"></a> + <strong>set (t, value, i1, j1, i2, j2)</strong> + </dt> + <dd> + set a specified range of an array to a value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + <li><span class="parameter">value</span> + the value (may be a function) + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start row (default 1) + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + start col (default 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end row (default N) + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + end col (default M) + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#set">tablex.set</a> + </ul> + + +</dd> + <dt> + <a name = "write"></a> + <strong>write (t, f, fmt, i1, j1, i2, j2)</strong> + </dt> + <dd> + write a 2D array to a file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + <li><span class="parameter">f</span> + a file object (default stdout) + </li> + <li><span class="parameter">fmt</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a format string (default is just to use tostring) + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start row (default 1) + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + start col (default 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end row (default N) + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + end col (default M) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "forall"></a> + <strong>forall (t, row_op, end_row_op, i1, j1, i2, j2)</strong> + </dt> + <dd> + perform an operation for all values in a 2D array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + 2D array + </li> + <li><span class="parameter">row_op</span> + <span class="types"><span class="type">func</span></span> + function to call on each value + </li> + <li><span class="parameter">end_row_op</span> + <span class="types"><span class="type">func</span></span> + function to call at end of each row + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start row (default 1) + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + start col (default 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end row (default N) + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + end col (default M) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "move"></a> + <strong>move (dest, di, dj, src, i1, j1, i2, j2)</strong> + </dt> + <dd> + move a block from the destination to the source. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">dest</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + <li><span class="parameter">di</span> + <span class="types"><span class="type">int</span></span> + start row in dest + </li> + <li><span class="parameter">dj</span> + <span class="types"><span class="type">int</span></span> + start col in dest + </li> + <li><span class="parameter">src</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start row (default 1) + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + start col (default 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end row (default N) + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + end col (default M) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "iter"></a> + <strong>iter (a, indices, i1, j1, i2, j2)</strong> + </dt> + <dd> + iterate over all elements in a 2D array, with optional indices. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + <span class="types"><span class="type">array</span></span> + 2D array + </li> + <li><span class="parameter">indices</span> + <span class="types"><span class="type">{int}</span></span> + with indices (default false) + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start row (default 1) + </li> + <li><span class="parameter">j1</span> + <span class="types"><span class="type">int</span></span> + start col (default 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end row (default N) + </li> + <li><span class="parameter">j2</span> + <span class="types"><span class="type">int</span></span> + end col (default M) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + either value or i,j,value depending on indices + </ol> + + + + +</dd> + <dt> + <a name = "columns"></a> + <strong>columns (a)</strong> + </dt> + <dd> + iterate over all columns. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + <span class="types"><span class="type">array</span></span> + a 2D array + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + each column in turn + </ol> + + + + +</dd> + <dt> + <a name = "new"></a> + <strong>new (rows, cols, val)</strong> + </dt> + <dd> + new array of specified dimensions + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">rows</span> + <span class="types"><span class="type">int</span></span> + number of rows + </li> + <li><span class="parameter">cols</span> + <span class="types"><span class="type">int</span></span> + number of cols + </li> + <li><span class="parameter">val</span> + initial value; if it’s a function then use <code>val(i,j)</code> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + new 2d array + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.class.html b/docs/libraries/pl.class.html new file mode 100644 index 0000000..ff594f3 --- /dev/null +++ b/docs/libraries/pl.class.html @@ -0,0 +1,333 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><strong>pl.class</strong></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.class</code></h1> +<p>Provides a reuseable and convenient framework for creating classes in Lua.</p> +<p> Two possible notations:</p> + +<pre> +B = class(A) +class.B(A) +</pre> + + +<p> The latter form creates a named class within the current environment. Note + that this implicitly brings in <a href="../libraries/pl.utils.html#">pl.utils</a> as a dependency.</p> + +<p> See the Guide for further <a href="../manual/01-introduction.md.html#Simplifying_Object_Oriented_Programming_in_Lua">discussion</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#_init">_init (...)</a></td> + <td class="summary">initializes an <strong>instance</strong> upon creation.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#instance:is_a">instance:is_a (some_class)</a></td> + <td class="summary">checks whether an <strong>instance</strong> is derived from some class.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#some_class:class_of">some_class:class_of (some_instance)</a></td> + <td class="summary">checks whether an <strong>instance</strong> is derived from some class.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#some_class:cast">some_class:cast (some_instance)</a></td> + <td class="summary">cast an object to another class.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#class">class (base, c_arg, c)</a></td> + <td class="summary">create a new class, derived from a given base class.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "_init"></a> + <strong>_init (...)</strong> + </dt> + <dd> + initializes an <strong>instance</strong> upon creation. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + parameters passed to the constructor + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">local</span> Cat = class() +<span class="keyword">function</span> Cat:_init(name) + <span class="comment">--self:super(name) -- call the ancestor initializer if needed +</span> self.name = name +<span class="keyword">end</span> + +<span class="keyword">local</span> pussycat = Cat(<span class="string">"pussycat"</span>) +<span class="global">print</span>(pussycat.name) <span class="comment">--> pussycat</span></pre> + </ul> + +</dd> + <dt> + <a name = "instance:is_a"></a> + <strong>instance:is_a (some_class)</strong> + </dt> + <dd> + checks whether an <strong>instance</strong> is derived from some class. + Works the other way around as <a href="../libraries/pl.class.html#some_class:class_of">class_of</a>. It has two ways of using; + 1) call with a class to check against, 2) call without params. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">some_class</span> + class to check against, or <code>nil</code> to return the class + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <code>true</code> if <code>instance</code> is derived from <code>some_class</code>, or if <code>some_class == nil</code> then + it returns the class table of the instance + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">local</span> pussycat = Lion() <span class="comment">-- assuming Lion derives from Cat +</span><span class="keyword">if</span> pussycat:is_a(Cat) <span class="keyword">then</span> + <span class="comment">-- it's true, it is a Lion, but also a Cat +</span><span class="keyword">end</span> + +<span class="keyword">if</span> pussycat:is_a() == Lion <span class="keyword">then</span> + <span class="comment">-- It's true +</span><span class="keyword">end</span></pre> + </ul> + +</dd> + <dt> + <a name = "some_class:class_of"></a> + <strong>some_class:class_of (some_instance)</strong> + </dt> + <dd> + checks whether an <strong>instance</strong> is derived from some class. + Works the other way around as <a href="../libraries/pl.class.html#instance:is_a">is_a</a>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">some_instance</span> + instance to check against + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <code>true</code> if <code>some_instance</code> is derived from <code>some_class</code> + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">local</span> pussycat = Lion() <span class="comment">-- assuming Lion derives from Cat +</span><span class="keyword">if</span> Cat:class_of(pussycat) <span class="keyword">then</span> + <span class="comment">-- it's true +</span><span class="keyword">end</span></pre> + </ul> + +</dd> + <dt> + <a name = "some_class:cast"></a> + <strong>some_class:cast (some_instance)</strong> + </dt> + <dd> + cast an object to another class. + It is not clever (or safe!) so use carefully. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">some_instance</span> + the object to be changed + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "class"></a> + <strong>class (base, c_arg, c)</strong> + </dt> + <dd> + create a new class, derived from a given base class. + Supporting two class creation syntaxes: + either <code>Name = class(base)</code> or <code>class.Name(base)</code>. + The first form returns the class directly and does not set its <code>_name</code>. + The second form creates a variable <code>Name</code> in the current environment set + to the class, and also sets <code>_name</code>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">base</span> + optional base class + </li> + <li><span class="parameter">c_arg</span> + optional parameter to class constructor + </li> + <li><span class="parameter">c</span> + optional table to be used as class + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.compat.html b/docs/libraries/pl.compat.html new file mode 100644 index 0000000..cc9bd0c --- /dev/null +++ b/docs/libraries/pl.compat.html @@ -0,0 +1,372 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#Lua_5_2_Functions_Available_for_5_1">Lua 5.2 Functions Available for 5.1 </a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><strong>pl.compat</strong></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.compat</code></h1> +<p>Lua 5.1/5.2/5.3 compatibility.</p> +<p> Ensures that <a href="../libraries/pl.compat.html#table.pack">table.pack</a> and <a href="../libraries/pl.compat.html#package.searchpath">package.searchpath</a> are available + for Lua 5.1 and LuaJIT. + The exported function <a href="../libraries/pl.compat.html#load">load</a> is Lua 5.2 compatible. + <a href="../libraries/pl.compat.html#setfenv">compat.setfenv</a> and <a href="../libraries/pl.compat.html#getfenv">compat.getfenv</a> are available for Lua 5.2, although + they are not always guaranteed to work.</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#execute">execute (cmd)</a></td> + <td class="summary">execute a shell command.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#load">load (ld[, source[, mode[, env]]])</a></td> + <td class="summary">Load Lua code as a text or binary chunk.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getfenv">getfenv (f)</a></td> + <td class="summary">Get environment of a function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#setfenv">setfenv (f, env)</a></td> + <td class="summary">Set environment of a function</td> + </tr> +</table> +<h2><a href="#Lua_5_2_Functions_Available_for_5_1">Lua 5.2 Functions Available for 5.1 </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#table.pack">table.pack (...)</a></td> + <td class="summary">pack an argument list into a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#t">t</a></td> + <td class="summary">unpack a table and return the elements.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#package.searchpath">package.searchpath (mod, path)</a></td> + <td class="summary">return the full path where a Lua module name would be matched.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "execute"></a> + <strong>execute (cmd)</strong> + </dt> + <dd> + execute a shell command. + This is a compatibility function that returns the same for Lua 5.1 and Lua 5.2 + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cmd</span> + a shell command + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + true if successful</li> + <li> + actual return code</li> + </ol> + + + + +</dd> + <dt> + <a name = "load"></a> + <strong>load (ld[, source[, mode[, env]]])</strong> + </dt> + <dd> + Load Lua code as a text or binary chunk. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">ld</span> + code string or loader + </li> + <li><span class="parameter">source</span> + name of chunk for errors + (<em>optional</em>) + </li> + <li><span class="parameter">mode</span> + ‘b’, ’t' or ‘bt’ + (<em>optional</em>) + </li> + <li><span class="parameter">env</span> + environment to load the chunk in + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "getfenv"></a> + <strong>getfenv (f)</strong> + </dt> + <dd> + Get environment of a function. + With Lua 5.2, may return nil for a function with no global references! + Based on code by <a href="http://lua-users.org/lists/lua-l/2010-06/msg00313.html">Sergey Rozhenko</a> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + a function or a call stack reference + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "setfenv"></a> + <strong>setfenv (f, env)</strong> + </dt> + <dd> + Set environment of a function + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + a function or a call stack reference + </li> + <li><span class="parameter">env</span> + a table that becomes the new environment of <code>f</code> + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Lua_5_2_Functions_Available_for_5_1"></a>Lua 5.2 Functions Available for 5.1 </h2> + + <dl class="function"> + <dt> + <a name = "table.pack"></a> + <strong>table.pack (...)</strong> + </dt> + <dd> + pack an argument list into a table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + any arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table with field n set to the length + </ol> + + + + +</dd> + <dt> + <a name = "t"></a> + <strong>t</strong> + </dt> + <dd> + unpack a table and return the elements. + + + <ul> + <li><span class="parameter">t</span> + index of the last element to unpack, defaults to #t + (<em>optional</em>) + </li> + <li><span class="parameter">i</span> + index from which to start unpacking, defaults to 1 + (<em>optional</em>) + </li> + <li><span class="parameter">t</span> + index of the last element to unpack, defaults to #t + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "package.searchpath"></a> + <strong>package.searchpath (mod, path)</strong> + </dt> + <dd> + return the full path where a Lua module name would be matched. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">mod</span> + module name, possibly dotted + </li> + <li><span class="parameter">path</span> + a path in the same form as package.path or package.cpath + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.path.html#package_path">path.package_path</a> + </ul> + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.comprehension.html b/docs/libraries/pl.comprehension.html new file mode 100644 index 0000000..b552ee7 --- /dev/null +++ b/docs/libraries/pl.comprehension.html @@ -0,0 +1,166 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><strong>pl.comprehension</strong></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.comprehension</code></h1> +<p>List comprehensions implemented in Lua.</p> +<p> See the <a href="http://lua-users.org/wiki/ListComprehensions">wiki page</a></p> + +<pre> +<span class="keyword">local</span> C= <span class="global">require</span> <span class="string">'pl.comprehension'</span> . new() + +C (<span class="string">'x for x=1,10'</span>) () +==> {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>} +C <span class="string">'x^2 for x=1,4'</span> () +==> {<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">16</span>} +C <span class="string">'{x,x^2} for x=1,4'</span> () +==> {{<span class="number">1</span>,<span class="number">1</span>},{<span class="number">2</span>,<span class="number">4</span>},{<span class="number">3</span>,<span class="number">9</span>},{<span class="number">4</span>,<span class="number">16</span>}} +C <span class="string">'2*x for x'</span> {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +==> {<span class="number">2</span>,<span class="number">4</span>,<span class="number">6</span>} +dbl = C <span class="string">'2*x for x'</span> +dbl {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +==> {<span class="number">20</span>,<span class="number">40</span>,<span class="number">60</span>} +C <span class="string">'x for x if x % 2 == 0'</span> {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>} +==> {<span class="number">2</span>,<span class="number">4</span>} +C <span class="string">'{x,y} for x = 1,2 for y = 1,2'</span> () +==> {{<span class="number">1</span>,<span class="number">1</span>},{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">2</span>,<span class="number">1</span>},{<span class="number">2</span>,<span class="number">2</span>}} +C <span class="string">'{x,y} for x for y'</span> ({<span class="number">1</span>,<span class="number">2</span>},{<span class="number">10</span>,<span class="number">20</span>}) +==> {{<span class="number">1</span>,<span class="number">10</span>},{<span class="number">1</span>,<span class="number">20</span>},{<span class="number">2</span>,<span class="number">10</span>},{<span class="number">2</span>,<span class="number">20</span>}} +<span class="global">assert</span>(C <span class="string">'sum(x^2 for x)'</span> {<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>} == <span class="number">2</span>^<span class="number">2</span>+<span class="number">3</span>^<span class="number">2</span>+<span class="number">4</span>^<span class="number">2</span>) +</pre> + + +<p> © 2008 David Manura. Licensed under the same terms as Lua (MIT license).</p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.luabalanced.html#">pl.luabalanced</a></p> + +<p> See <a href="../manual/07-functional.md.html#List_Comprehensions">the Guide</a></p> + + + +<br/> +<br/> + + + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.config.html b/docs/libraries/pl.config.html new file mode 100644 index 0000000..e1331a6 --- /dev/null +++ b/docs/libraries/pl.config.html @@ -0,0 +1,254 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><strong>pl.config</strong></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.config</code></h1> +<p>Reads configuration files into a Lua table.</p> +<p><p> Understands INI files, classic Unix config files, and simple + delimited columns of values. See <a href="../manual/06-data.md.html#Reading_Configuration_Files">the Guide</a></p> + +<pre> +# test.config +# Read timeout <span class="keyword">in</span> seconds +read.timeout=<span class="number">10</span> +# Write timeout <span class="keyword">in</span> seconds +write.timeout=<span class="number">5</span> +#acceptable ports +ports = <span class="number">1002</span>,<span class="number">1003</span>,<span class="number">1004</span> + +<span class="comment">-- readconfig.lua +</span><span class="keyword">local</span> config = <span class="global">require</span> <span class="string">'config'</span> +<span class="keyword">local</span> t = config.read <span class="string">'test.config'</span> +<span class="global">print</span>(pretty.write(t)) + +### output ##### +{ + ports = { + <span class="number">1002</span>, + <span class="number">1003</span>, + <span class="number">1004</span> + }, + write_timeout = <span class="number">5</span>, + read_timeout = <span class="number">10</span> +} +</pre> +</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#lines">lines (file)</a></td> + <td class="summary">like io.lines(), but allows for lines to be continued with ‘\’.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#read">read (file[, cnfg])</a></td> + <td class="summary">read a configuration file into a table</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "lines"></a> + <strong>lines (file)</strong> + </dt> + <dd> + like io.lines(), but allows for lines to be continued with ‘\’. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">file</span> + a file-like object (anything where read() returns the next line) or a filename. + Defaults to stardard input. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + an iterator over the lines, or nil</li> + <li> + error ‘not a file-like object’ or ‘file is nil’</li> + </ol> + + + + +</dd> + <dt> + <a name = "read"></a> + <strong>read (file[, cnfg])</strong> + </dt> + <dd> + read a configuration file into a table + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">file</span> + either a file-like object or a string, which must be a filename + </li> + <li><span class="parameter">cnfg</span> + <span class="types"><span class="type">tab</span></span> + <p> a configuration table that may contain these fields:</p> + +<ul> +<li><code>smart</code> try to deduce what kind of config file we have (default false)</li> +<li><code>variablilize</code> make names into valid Lua identifiers (default true)</li> +<li><code>convert_numbers</code> try to convert values into numbers (default true)</li> +<li><code>trim_space</code> ensure that there is no starting or trailing whitespace with values (default true)</li> +<li><code>trim_quotes</code> remove quotes from strings (default false)</li> +<li><code>list_delim</code> delimiter to use when separating columns (default ‘,’)</li> +<li><code>keysep</code> separator between key and value pairs (default ‘=’)</li> +</ul> + + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + a table containing items, or <code>nil</code></li> + <li> + error message (same as <a href="../libraries/pl.config.html#lines">config.lines</a></li> + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.data.html b/docs/libraries/pl.data.html new file mode 100644 index 0000000..0d6dddb --- /dev/null +++ b/docs/libraries/pl.data.html @@ -0,0 +1,570 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><strong>pl.data</strong></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.data</code></h1> +<p>Reading and querying simple tabular data.</p> +<p> + +<pre> +data.read <span class="string">'test.txt'</span> +==> {{<span class="number">10</span>,<span class="number">20</span>},{<span class="number">2</span>,<span class="number">5</span>},{<span class="number">40</span>,<span class="number">50</span>},fieldnames={<span class="string">'x'</span>,<span class="string">'y'</span>},delim=<span class="string">','</span>} +</pre> + + +<p> Provides a way of creating basic SQL-like queries.</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +<span class="keyword">local</span> d = data.read(<span class="string">'xyz.txt'</span>) +<span class="keyword">local</span> q = d:<span class="global">select</span>(<span class="string">'x,y,z where x > 3 and z < 2 sort by y'</span>) +<span class="keyword">for</span> x,y,z <span class="keyword">in</span> q <span class="keyword">do</span> + <span class="global">print</span>(x,y,z) +<span class="keyword">end</span> +</pre> + + +<p> See <a href="../manual/06-data.md.html#Reading_Columnar_Data">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.array2d.html#">pl.array2d</a> (fallback methods)</p></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#Data.column_by_name">Data.column_by_name (name)</a></td> + <td class="summary">return a particular column as a list of values (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Data.select">Data.select (condn)</a></td> + <td class="summary">return a query iterator on this data (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Data.select_row">Data.select_row (condn)</a></td> + <td class="summary">return a row iterator on this data (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Data.copy_select">Data.copy_select (condn)</a></td> + <td class="summary">return a new data object based on this query (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Data.column_names">Data.column_names ()</a></td> + <td class="summary">return the field names of this data object (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Data.write_row">Data.write_row (f)</a></td> + <td class="summary">write out a row (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Data.write">Data.write (f)</a></td> + <td class="summary">write data out to file (method).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#read">read (file, cnfg)</a></td> + <td class="summary">read a delimited file in a Lua table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#write">write (data, file[, fieldnames[, delim='\t']])</a></td> + <td class="summary">write 2D data to a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#new">new (d[, fieldnames])</a></td> + <td class="summary">create a new dataset from a table of rows.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#query">query (data, condn, context, return_row)</a></td> + <td class="summary">create a query iterator from a select string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#filter">filter (Q, infile, outfile, dont_fail)</a></td> + <td class="summary">Filter input using a query.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "Data.column_by_name"></a> + <strong>Data.column_by_name (name)</strong> + </dt> + <dd> + return a particular column as a list of values (method). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">name</span> + either name of column, or numerical index. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Data.select"></a> + <strong>Data.select (condn)</strong> + </dt> + <dd> + return a query iterator on this data (method). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">condn</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the query expression + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.data.html#query">data.query</a> + </ul> + + +</dd> + <dt> + <a name = "Data.select_row"></a> + <strong>Data.select_row (condn)</strong> + </dt> + <dd> + return a row iterator on this data (method). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">condn</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the query expression + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Data.copy_select"></a> + <strong>Data.copy_select (condn)</strong> + </dt> + <dd> + return a new data object based on this query (method). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">condn</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the query expression + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Data.column_names"></a> + <strong>Data.column_names ()</strong> + </dt> + <dd> + return the field names of this data object (method). + + + + + + + +</dd> + <dt> + <a name = "Data.write_row"></a> + <strong>Data.write_row (f)</strong> + </dt> + <dd> + write out a row (method). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + file-like object + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Data.write"></a> + <strong>Data.write (f)</strong> + </dt> + <dd> + write data out to file (method). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + file-like object + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "read"></a> + <strong>read (file, cnfg)</strong> + </dt> + <dd> + read a delimited file in a Lua table. + By default, attempts to treat first line as separated list of fieldnames. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">file</span> + a filename or a file-like object + </li> + <li><span class="parameter">cnfg</span> parsing options + <ul> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string pattern to split fields + </li> + <li><span class="parameter">fieldnames</span> + <span class="types"><span class="type">array</span></span> + (i.e. don’t read from first line) + </li> + <li><span class="parameter">no_convert</span> + <span class="types"><span class="type">bool</span></span> + (default is to try conversion on first data line) + </li> + <li><span class="parameter">convert</span> + <span class="types"><span class="type">tab</span></span> + table of custom conversion functions with column keys + </li> + <li><span class="parameter">numfields</span> + <span class="types"><span class="type">int</span></span> + indices of columns known to be numbers + </li> + <li><span class="parameter">last_field_collect</span> + <span class="types"><span class="type">bool</span></span> + only split as many fields as fieldnames. + </li> + <li><span class="parameter">thousands_dot</span> + <span class="types"><span class="type">int</span></span> + thousands separator in Excel CSV is ‘.’ + </li> + <li><span class="parameter">csv</span> + <span class="types"><span class="type">bool</span></span> + fields may be double-quoted and contain commas; + Also, empty fields are considered to be equivalent to zero. + </li> + </li></ul> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + <a href="../libraries/pl.data.html">data</a> object, or <code>nil</code></li> + <li> + error message. May be a file error, ‘not a file-like object’ + or a conversion error</li> + </ol> + + + + +</dd> + <dt> + <a name = "write"></a> + <strong>write (data, file[, fieldnames[, delim='\t']])</strong> + </dt> + <dd> + write 2D data to a file. + Does not assume that the data has actually been + generated with <a href="../libraries/pl.data.html#new">new</a> or <a href="../libraries/pl.data.html#read">read</a>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">data</span> + 2D array + </li> + <li><span class="parameter">file</span> + filename or file-like object + </li> + <li><span class="parameter">fieldnames</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">{string}</a></span> + list of fields (optional) + (<em>optional</em>) + </li> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + delimiter (default tab) + (<em>default</em> '\t') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or nil, error + </ol> + + + + +</dd> + <dt> + <a name = "new"></a> + <strong>new (d[, fieldnames])</strong> + </dt> + <dd> + create a new dataset from a table of rows. + Can specify the fieldnames, else the table must have a field called + ‘fieldnames’, which is either a string of delimiter-separated names, + or a table of names. <br> + If the table does not have a field called ‘delim’, then an attempt will be + made to guess it from the fieldnames string, defaults otherwise to tab. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">d</span> + the table. + </li> + <li><span class="parameter">fieldnames</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">{string}</a></span> + optional fieldnames + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the table. + </ol> + + + + +</dd> + <dt> + <a name = "query"></a> + <strong>query (data, condn, context, return_row)</strong> + </dt> + <dd> + create a query iterator from a select string. + Select string has this format: <br> + FIELDLIST [ where LUA-CONDN [ sort by FIELD] ]<br> + FIELDLIST is a comma-separated list of valid fields, or ‘*’. <br> <br> + The condition can also be a table, with fields ‘fields’ (comma-sep string or + table), ‘sort_by’ (string) and ‘where’ (Lua expression string or function) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">data</span> + table produced by read + </li> + <li><span class="parameter">condn</span> + select string or table + </li> + <li><span class="parameter">context</span> + a list of tables to be searched when resolving functions + </li> + <li><span class="parameter">return_row</span> + if true, wrap the results in a row table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + an iterator over the specified fields, or nil</li> + <li> + an error message</li> + </ol> + + + + +</dd> + <dt> + <a name = "filter"></a> + <strong>filter (Q, infile, outfile, dont_fail)</strong> + </dt> + <dd> + Filter input using a query. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">Q</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a query string + </li> + <li><span class="parameter">infile</span> + filename or file-like object + </li> + <li><span class="parameter">outfile</span> + filename or file-like object + </li> + <li><span class="parameter">dont_fail</span> + <span class="types"><span class="type">bool</span></span> + true if you want to return an error, not just fail + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.dir.html b/docs/libraries/pl.dir.html new file mode 100644 index 0000000..ffe71f6 --- /dev/null +++ b/docs/libraries/pl.dir.html @@ -0,0 +1,613 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><strong>pl.dir</strong></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.dir</code></h1> +<p>Listing files in directories and creating/removing directory paths.</p> +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.path.html#">pl.path</a></p> + +<p> Soft Dependencies: <code>alien</code>, <code>ffi</code> (either are used on Windows for copying/moving files)</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#fnmatch">fnmatch (filename, pattern)</a></td> + <td class="summary">Test whether a file name matches a shell pattern.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#filter">filter (filenames, pattern)</a></td> + <td class="summary">Return a list of all file names within an array which match a pattern.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getfiles">getfiles (dir, mask)</a></td> + <td class="summary">return a list of all files in a directory which match the a shell pattern.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getdirectories">getdirectories (dir)</a></td> + <td class="summary">return a list of all subdirectories of the directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#copyfile">copyfile (src, dest, flag)</a></td> + <td class="summary">copy a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#movefile">movefile (src, dest)</a></td> + <td class="summary">move a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#walk">walk (root, bottom_up, follow_links)</a></td> + <td class="summary">return an iterator which walks through a directory tree starting at root.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rmtree">rmtree (fullpath)</a></td> + <td class="summary">remove a whole directory tree.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#makepath">makepath (p)</a></td> + <td class="summary">create a directory path.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#clonetree">clonetree (path1, path2, file_fun, verbose)</a></td> + <td class="summary">clone a directory tree.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#dirtree">dirtree (d)</a></td> + <td class="summary">return an iterator over all entries in a directory tree</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getallfiles">getallfiles (start_path, shell_pattern)</a></td> + <td class="summary">Recursively returns all the file starting at <em>path</em>.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "fnmatch"></a> + <strong>fnmatch (filename, pattern)</strong> + </dt> + <dd> + Test whether a file name matches a shell pattern. + Both parameters are case-normalized if operating system is + case-insensitive. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filename</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file name. + </li> + <li><span class="parameter">pattern</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A shell pattern. The only special characters are + <code>'<em>'</code> and <code>'?'</code>: <code>'</em>'</code> matches any sequence of characters and + <code>'?'</code> matches any single character. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><span class="type">bool</span></span> + + </ol> + + <h3>Raises:</h3> + dir and mask must be strings + + + +</dd> + <dt> + <a name = "filter"></a> + <strong>filter (filenames, pattern)</strong> + </dt> + <dd> + Return a list of all file names within an array which match a pattern. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filenames</span> + <span class="types"><span class="type">tab</span></span> + An array containing file names. + </li> + <li><span class="parameter">pattern</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A shell pattern. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="../classes/pl.List.html">List(string)</a></span> + List of matching file names. + </ol> + + <h3>Raises:</h3> + dir and mask must be strings + + + +</dd> + <dt> + <a name = "getfiles"></a> + <strong>getfiles (dir, mask)</strong> + </dt> + <dd> + return a list of all files in a directory which match the a shell pattern. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">dir</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A directory. If not given, all files in current directory are returned. + </li> + <li><span class="parameter">mask</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A shell pattern. If not given, all files are returned. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">{string}</a></span> + list of files + </ol> + + <h3>Raises:</h3> + dir and mask must be strings + + + +</dd> + <dt> + <a name = "getdirectories"></a> + <strong>getdirectories (dir)</strong> + </dt> + <dd> + return a list of all subdirectories of the directory. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">dir</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A directory + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">{string}</a></span> + a list of directories + </ol> + + <h3>Raises:</h3> + dir must be a a valid directory + + + +</dd> + <dt> + <a name = "copyfile"></a> + <strong>copyfile (src, dest, flag)</strong> + </dt> + <dd> + copy a file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">src</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + source file + </li> + <li><span class="parameter">dest</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + destination file or directory + </li> + <li><span class="parameter">flag</span> + <span class="types"><span class="type">bool</span></span> + true if you want to force the copy (default) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><span class="type">bool</span></span> + operation succeeded + </ol> + + <h3>Raises:</h3> + src and dest must be strings + + + +</dd> + <dt> + <a name = "movefile"></a> + <strong>movefile (src, dest)</strong> + </dt> + <dd> + move a file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">src</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + source file + </li> + <li><span class="parameter">dest</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + destination file or directory + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><span class="type">bool</span></span> + operation succeeded + </ol> + + <h3>Raises:</h3> + src and dest must be strings + + + +</dd> + <dt> + <a name = "walk"></a> + <strong>walk (root, bottom_up, follow_links)</strong> + </dt> + <dd> + return an iterator which walks through a directory tree starting at root. + The iterator returns (root,dirs,files) + Note that dirs and files are lists of names (i.e. you must say path.join(root,d) + to get the actual full path) + If bottom_up is false (or not present), then the entries at the current level are returned + before we go deeper. This means that you can modify the returned list of directories before + continuing. + This is a clone of os.walk from the Python libraries. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">root</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A starting directory + </li> + <li><span class="parameter">bottom_up</span> + <span class="types"><span class="type">bool</span></span> + False if we start listing entries immediately. + </li> + <li><span class="parameter">follow_links</span> + <span class="types"><span class="type">bool</span></span> + follow symbolic links + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator returning root,dirs,files + </ol> + + <h3>Raises:</h3> + root must be a directory + + + +</dd> + <dt> + <a name = "rmtree"></a> + <strong>rmtree (fullpath)</strong> + </dt> + <dd> + remove a whole directory tree. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fullpath</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A directory path + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + true or nil</li> + <li> + error if failed</li> + </ol> + + <h3>Raises:</h3> + fullpath must be a string + + + +</dd> + <dt> + <a name = "makepath"></a> + <strong>makepath (p)</strong> + </dt> + <dd> + create a directory path. + This will create subdirectories as necessary! + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">p</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A directory path + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true on success, nil + errormsg on failure + </ol> + + <h3>Raises:</h3> + failure to create + + + +</dd> + <dt> + <a name = "clonetree"></a> + <strong>clonetree (path1, path2, file_fun, verbose)</strong> + </dt> + <dd> + clone a directory tree. Will always try to create a new directory structure + if necessary. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">path1</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the base path of the source tree + </li> + <li><span class="parameter">path2</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the new base path for the destination + </li> + <li><span class="parameter">file_fun</span> + <span class="types"><span class="type">func</span></span> + an optional function to apply on all files + </li> + <li><span class="parameter">verbose</span> + <span class="types"><span class="type">bool</span></span> + an optional boolean to control the verbosity of the output. + It can also be a logging function that behaves like print() + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + true, or nil</li> + <li> + error message, or list of failed directory creations</li> + <li> + list of failed file operations</li> + </ol> + + <h3>Raises:</h3> + path1 and path2 must be strings + + + <h3>Usage:</h3> + <ul> + <pre class="example">clonetree(<span class="string">'.'</span>,<span class="string">'../backup'</span>,copyfile)</pre> + </ul> + +</dd> + <dt> + <a name = "dirtree"></a> + <strong>dirtree (d)</strong> + </dt> + <dd> + return an iterator over all entries in a directory tree + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">d</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a directory + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator giving pathname and mode (true for dir, false otherwise) + </ol> + + <h3>Raises:</h3> + d must be a non-empty string + + + +</dd> + <dt> + <a name = "getallfiles"></a> + <strong>getallfiles (start_path, shell_pattern)</strong> + </dt> + <dd> + Recursively returns all the file starting at <em>path</em>. It can optionally take a shell pattern and + only returns files that match <em>shell_pattern</em>. If a pattern is given it will do a case insensitive search. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">start_path</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A directory. If not given, all files in current directory are returned. + </li> + <li><span class="parameter">shell_pattern</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A shell pattern. If not given, all files are returned. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><a class="type" href="../classes/pl.List.html">List(string)</a></span> + containing all the files found recursively starting at <em>path</em> and filtered by <em>shell_pattern</em>. + </ol> + + <h3>Raises:</h3> + start_path must be a directory + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.file.html b/docs/libraries/pl.file.html new file mode 100644 index 0000000..54221fd --- /dev/null +++ b/docs/libraries/pl.file.html @@ -0,0 +1,378 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><strong>pl.file</strong></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.file</code></h1> +<p>File manipulation functions: reading, writing, moving and copying.</p> +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.dir.html#">pl.dir</a>, <a href="../libraries/pl.path.html#">pl.path</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#read">read (filename)</a></td> + <td class="summary">return the contents of a file as a string</td> + </tr> + <tr> + <td class="name" nowrap><a href="#write">write (filename, str)</a></td> + <td class="summary">write a string to a file</td> + </tr> + <tr> + <td class="name" nowrap><a href="#copy">copy (src, dest, flag)</a></td> + <td class="summary">copy a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#move">move (src, dest)</a></td> + <td class="summary">move a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#access_time">access_time (path)</a></td> + <td class="summary">Return the time of last access as the number of seconds since the epoch.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#creation_time">creation_time (path)</a></td> + <td class="summary">Return when the file was created.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#modified_time">modified_time (path)</a></td> + <td class="summary">Return the time of last modification</td> + </tr> + <tr> + <td class="name" nowrap><a href="#delete">delete (path)</a></td> + <td class="summary">Delete a file</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "read"></a> + <strong>read (filename)</strong> + </dt> + <dd> + return the contents of a file as a string + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filename</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + The file path + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + file contents + </ol> + + + + +</dd> + <dt> + <a name = "write"></a> + <strong>write (filename, str)</strong> + </dt> + <dd> + write a string to a file + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filename</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + The file path + </li> + <li><span class="parameter">str</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + The string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "copy"></a> + <strong>copy (src, dest, flag)</strong> + </dt> + <dd> + copy a file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">src</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + source file + </li> + <li><span class="parameter">dest</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + destination file + </li> + <li><span class="parameter">flag</span> + <span class="types"><span class="type">bool</span></span> + true if you want to force the copy (default) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true if operation succeeded + </ol> + + + + +</dd> + <dt> + <a name = "move"></a> + <strong>move (src, dest)</strong> + </dt> + <dd> + move a file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">src</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + source file + </li> + <li><span class="parameter">dest</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + destination file + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true if operation succeeded, else false and the reason for the error. + </ol> + + + + +</dd> + <dt> + <a name = "access_time"></a> + <strong>access_time (path)</strong> + </dt> + <dd> + Return the time of last access as the number of seconds since the epoch. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">path</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "creation_time"></a> + <strong>creation_time (path)</strong> + </dt> + <dd> + Return when the file was created. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">path</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "modified_time"></a> + <strong>modified_time (path)</strong> + </dt> + <dd> + Return the time of last modification + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">path</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "delete"></a> + <strong>delete (path)</strong> + </dt> + <dd> + Delete a file + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">path</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.func.html b/docs/libraries/pl.func.html new file mode 100644 index 0000000..b4c2e2c --- /dev/null +++ b/docs/libraries/pl.func.html @@ -0,0 +1,461 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><strong>pl.func</strong></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.func</code></h1> +<p>Functional helpers like composition, binding and placeholder expressions.</p> +<p> Placeholder expressions are useful for short anonymous functions, and were + inspired by the Boost Lambda library.</p> + +<pre> +> utils.import <span class="string">'pl.func'</span> +> ls = List{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +> = ls:map(_1+<span class="number">1</span>) +{<span class="number">11</span>,<span class="number">21</span>,<span class="number">31</span>} +</pre> + + +<p> They can also be used to <em>bind</em> particular arguments of a function.</p> + +<pre> +> p = bind(<span class="global">print</span>,<span class="string">'start>'</span>,_0) +> p(<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>) +> start> <span class="number">10</span> <span class="number">20</span> <span class="number">30</span> +</pre> + + +<p> See <a href="../manual/07-functional.md.html#Creating_Functions_from_Functions">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#import">import (tname, context)</a></td> + <td class="summary">wrap a table of functions.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#register">register (fun[, name])</a></td> + <td class="summary">register a function for use in placeholder expressions.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#tail">tail (ls)</a></td> + <td class="summary">all elements of a table except the first.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#repr">repr (e, lastpred)</a></td> + <td class="summary">create a string representation of a placeholder expression.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#instantiate">instantiate (e)</a></td> + <td class="summary">instantiate a PE into an actual function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#I">I (e)</a></td> + <td class="summary">instantiate a PE unless it has already been done.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#bind1">bind1 (fn, p)</a></td> + <td class="summary">bind the first parameter of the function to a value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#compose">compose (f, g)</a></td> + <td class="summary">create a function which chains two functions.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#bind">bind (fn, ...)</a></td> + <td class="summary">bind the arguments of a function to given values.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "import"></a> + <strong>import (tname, context)</strong> + </dt> + <dd> + wrap a table of functions. This makes them available for use in + placeholder expressions. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tname</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a table name + </li> + <li><span class="parameter">context</span> + <span class="types"><span class="type">tab</span></span> + context to put results, defaults to environment of caller + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "register"></a> + <strong>register (fun[, name])</strong> + </dt> + <dd> + register a function for use in placeholder expressions. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function + </li> + <li><span class="parameter">name</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + an optional name + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a placeholder functiond + </ol> + + + + +</dd> + <dt> + <a name = "tail"></a> + <strong>tail (ls)</strong> + </dt> + <dd> + all elements of a table except the first. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">ls</span> + <span class="types"><span class="type">tab</span></span> + a list-like table. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "repr"></a> + <strong>repr (e, lastpred)</strong> + </dt> + <dd> + create a string representation of a placeholder expression. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">e</span> + a placeholder expression + </li> + <li><span class="parameter">lastpred</span> + not used + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "instantiate"></a> + <strong>instantiate (e)</strong> + </dt> + <dd> + instantiate a PE into an actual function. First we find the largest placeholder used, + e.g. _2; from this a list of the formal parameters can be build. Then we collect and replace + any non-PE values from the PE, and build up a constant binding list. + Finally, the expression can be compiled, and e.__PE_function is set. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">e</span> + a placeholder expression + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function + </ol> + + + + +</dd> + <dt> + <a name = "I"></a> + <strong>I (e)</strong> + </dt> + <dd> + instantiate a PE unless it has already been done. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">e</span> + a placeholder expression + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the function + </ol> + + + + +</dd> + <dt> + <a name = "bind1"></a> + <strong>bind1 (fn, p)</strong> + </dt> + <dd> + bind the first parameter of the function to a value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + <span class="types"><span class="type">func</span></span> + a function of one or more arguments + </li> + <li><span class="parameter">p</span> + a value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function of one less argument + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">(bind1(<span class="global">math</span>.max,<span class="number">10</span>))(<span class="number">20</span>) == <span class="global">math</span>.max(<span class="number">10</span>,<span class="number">20</span>)</pre> + </ul> + +</dd> + <dt> + <a name = "compose"></a> + <strong>compose (f, g)</strong> + </dt> + <dd> + create a function which chains two functions. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + a function of at least one argument + </li> + <li><span class="parameter">g</span> + <span class="types"><span class="type">func</span></span> + a function of at least one argument + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">printf = compose(<span class="global">io</span>.write,<span class="global">string</span>.format)</pre> + </ul> + +</dd> + <dt> + <a name = "bind"></a> + <strong>bind (fn, ...)</strong> + </dt> + <dd> + bind the arguments of a function to given values. + <code>bind(fn,v,_2)</code> is equivalent to <code>bind1(fn,v)</code>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + <span class="types"><span class="type">func</span></span> + a function of at least one argument + </li> + <li><span class="parameter">...</span> + values or placeholder variables + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function + </ol> + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">(bind(f,_1,a))(b) == f(a,b)</pre></li> + <li><pre class="example">(bind(f,_2,_1))(a,b) == f(b,a)</pre></li> + </ul> + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.html b/docs/libraries/pl.html new file mode 100644 index 0000000..d1d449d --- /dev/null +++ b/docs/libraries/pl.html @@ -0,0 +1,140 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><strong>pl</strong></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl</code></h1> +<p>Entry point for loading all PL libraries only on demand, into the global space.</p> +<p> Requiring ‘pl’ means that whenever a module is implicitly accesssed + (e.g. <a href="../libraries/pl.utils.html#split">utils.split</a>) + then that module is dynamically loaded. The submodules are all brought into + the global space. +Updated to use <a href="../libraries/pl.import_into.html#">pl.import_into</a></p> + + + +<br/> +<br/> + + + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.import_into.html b/docs/libraries/pl.import_into.html new file mode 100644 index 0000000..74ea5c6 --- /dev/null +++ b/docs/libraries/pl.import_into.html @@ -0,0 +1,143 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><strong>pl.import_into</strong></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.import_into</code></h1> +<p>PL loader, for loading all PL libraries, only on demand.</p> +<p> Whenever a module is implicitly accesssed, the table will have the module automatically injected. + (e.g. <code>_ENV.tablex</code>) + then that module is dynamically loaded. The submodules are all brought into + the table that is provided as the argument, or returned in a new table. + If a table is provided, that table’s metatable is clobbered, but the values are not. + This module returns a single function, which is passed the environment. + If this is <code>true</code>, then return a ‘shadow table’ as the module + See <a href="../manual/01-introduction.md.html#To_Inject_or_not_to_Inject_">the Guide</a></p> + + + +<br/> +<br/> + + + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.input.html b/docs/libraries/pl.input.html new file mode 100644 index 0000000..cbdb255 --- /dev/null +++ b/docs/libraries/pl.input.html @@ -0,0 +1,333 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><strong>pl.input</strong></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.input</code></h1> +<p>Iterators for extracting words or numbers from an input source.</p> +<p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +<span class="keyword">local</span> total,n = seq.sum(input.numbers()) +<span class="global">print</span>(<span class="string">'average'</span>,total/n) +</pre> + + +<p> <em>source</em> is defined as a string or a file-like object (i.e. has a read() method which returns the next line)</p> + +<p> See <a href="../manual/06-data.md.html#Reading_Unstructured_Text_Data">here</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a></p></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#alltokens">alltokens (getter, pattern[, fn])</a></td> + <td class="summary">create an iterator over all tokens.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#create_getter">create_getter (f)</a></td> + <td class="summary">create a function which grabs the next value from a source.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#numbers">numbers (f)</a></td> + <td class="summary">generate a sequence of numbers from a source.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#words">words (f)</a></td> + <td class="summary">generate a sequence of words from a source.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#fields">fields (ids, delim, f, opts)</a></td> + <td class="summary">parse an input source into fields.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "alltokens"></a> + <strong>alltokens (getter, pattern[, fn])</strong> + </dt> + <dd> + create an iterator over all tokens. + based on allwords from PiL, 7.1 + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">getter</span> + <span class="types"><span class="type">func</span></span> + any function that returns a line of text + </li> + <li><span class="parameter">pattern</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + + </li> + <li><span class="parameter">fn</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + Optionally can pass a function to process each token as it’s found. + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator + </ol> + + + + +</dd> + <dt> + <a name = "create_getter"></a> + <strong>create_getter (f)</strong> + </dt> + <dd> + create a function which grabs the next value from a source. If the source is a string, then the getter + will return the string and thereafter return nil. If not specified then the source is assumed to be stdin. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + a string or a file-like object (i.e. has a read() method which returns the next line) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a getter function + </ol> + + + + +</dd> + <dt> + <a name = "numbers"></a> + <strong>numbers (f)</strong> + </dt> + <dd> + generate a sequence of numbers from a source. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + A source + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + An iterator + </ol> + + + + +</dd> + <dt> + <a name = "words"></a> + <strong>words (f)</strong> + </dt> + <dd> + generate a sequence of words from a source. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + A source + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + An iterator + </ol> + + + + +</dd> + <dt> + <a name = "fields"></a> + <strong>fields (ids, delim, f, opts)</strong> + </dt> + <dd> + parse an input source into fields. + By default, will fail if it cannot convert a field to a number. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">ids</span> + a list of field indices, or a maximum field index + </li> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + delimiter to parse fields (default space) + </li> + <li><span class="parameter">f</span> + a source @see create_getter + </li> + <li><span class="parameter">opts</span> + <span class="types"><span class="type">tab</span></span> + option table, <code>{no_fail=true}</code> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator with the field values + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">for</span> x,y <span class="keyword">in</span> fields {<span class="number">2</span>,<span class="number">3</span>} <span class="keyword">do</span> <span class="global">print</span>(x,y) <span class="keyword">end</span> <span class="comment">-- 2nd and 3rd fields from stdin</span></pre> + </ul> + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.lapp.html b/docs/libraries/pl.lapp.html new file mode 100644 index 0000000..4f15198 --- /dev/null +++ b/docs/libraries/pl.lapp.html @@ -0,0 +1,383 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#Fields">Fields</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><strong>pl.lapp</strong></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.lapp</code></h1> +<p>Simple command-line parsing using human-readable specification.</p> +<p> Supports GNU-style parameters.</p> + +<pre> +lapp = <span class="global">require</span> <span class="string">'pl.lapp'</span> +<span class="keyword">local</span> args = lapp <span class="string">[[ +Does some calculations + -o,--offset (default 0.0) Offset to add to scaled number + -s,--scale (number) Scaling factor + <number> (number) Number to be scaled +]]</span> + +<span class="global">print</span>(args.offset + args.scale * args.number) +</pre> + + +<p> Lines beginning with <code>'-'</code> are flags; there may be a short and a long name; + lines beginning with <code>'<var>'</code> are arguments. Anything in parens after + the flag/argument is either a default, a type name or a range constraint.</p> + +<p> See <a href="../manual/08-additional.md.html#Command_line_Programs_with_Lapp">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.sip.html#">pl.sip</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#quit">quit (msg, no_usage)</a></td> + <td class="summary">quit this script immediately.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#error">error (msg, no_usage)</a></td> + <td class="summary">print an error to stderr and quit.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#open">open (file[, opt])</a></td> + <td class="summary">open a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#assert">assert (condn, msg)</a></td> + <td class="summary">quit if the condition is false.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#add_type">add_type (name, converter[, constraint])</a></td> + <td class="summary">add a new type to Lapp.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#process_options_string">process_options_string (str, args)</a></td> + <td class="summary">process a Lapp options string.</td> + </tr> +</table> +<h2><a href="#Fields">Fields</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#show_usage_error">show_usage_error</a></td> + <td class="summary">controls whether to dump usage on error.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "quit"></a> + <strong>quit (msg, no_usage)</strong> + </dt> + <dd> + quit this script immediately. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">msg</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + optional message + </li> + <li><span class="parameter">no_usage</span> + <span class="types"><span class="type">bool</span></span> + suppress ‘usage’ display + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "error"></a> + <strong>error (msg, no_usage)</strong> + </dt> + <dd> + print an error to stderr and quit. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">msg</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a message + </li> + <li><span class="parameter">no_usage</span> + <span class="types"><span class="type">bool</span></span> + suppress ‘usage’ display + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "open"></a> + <strong>open (file[, opt])</strong> + </dt> + <dd> + open a file. + This will quit on error, and keep a list of file objects for later cleanup. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">file</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + filename + </li> + <li><span class="parameter">opt</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + same as second parameter of <a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.open">io.open</a> + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "assert"></a> + <strong>assert (condn, msg)</strong> + </dt> + <dd> + quit if the condition is false. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">condn</span> + <span class="types"><span class="type">bool</span></span> + a condition + </li> + <li><span class="parameter">msg</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + message text + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "add_type"></a> + <strong>add_type (name, converter[, constraint])</strong> + </dt> + <dd> + add a new type to Lapp. These appear in parens after the value like + a range constraint, e.g. ‘<ival> (integer) Process PID’ + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">name</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + name of type + </li> + <li><span class="parameter">converter</span> + either a function to convert values, or a Lua type name. + </li> + <li><span class="parameter">constraint</span> + <span class="types"><span class="type">func</span></span> + optional function to verify values, should use lapp.error + if failed. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "process_options_string"></a> + <strong>process_options_string (str, args)</strong> + </dt> + <dd> + process a Lapp options string. + Usually called as <code>lapp()</code>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">str</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the options text + </li> + <li><span class="parameter">args</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">{string}</a></span> + a table of arguments (default is <code>_G.arg</code>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table with parameter-value pairs + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Fields"></a>Fields</h2> + + <dl class="function"> + <dt> + <a name = "show_usage_error"></a> + <strong>show_usage_error</strong> + </dt> + <dd> + controls whether to dump usage on error. + Defaults to true + + + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.lexer.html b/docs/libraries/pl.lexer.html new file mode 100644 index 0000000..0760855 --- /dev/null +++ b/docs/libraries/pl.lexer.html @@ -0,0 +1,525 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><strong>pl.lexer</strong></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.lexer</code></h1> +<p>Lexical scanner for creating a sequence of tokens from text.</p> +<p> <code>lexer.scan(s)</code> returns an iterator over all tokens found in the + string <code>s</code>. This iterator returns two values, a token type string + (such as ‘string’ for quoted string, ‘iden’ for identifier) and the value of the + token.</p> + +<p> Versions specialized for Lua and C are available; these also handle block comments + and classify keywords as ‘keyword’ tokens. For example:</p> + +<pre> +> s = <span class="string">'for i=1,n do'</span> +> <span class="keyword">for</span> t,v <span class="keyword">in</span> lexer.lua(s) <span class="keyword">do</span> <span class="global">print</span>(t,v) <span class="keyword">end</span> +keyword <span class="keyword">for</span> +iden i += = +number <span class="number">1</span> +, , +iden n +keyword <span class="keyword">do</span> +</pre> + + +<p> See the Guide for further <a href="../manual/06-data.md.html#Lexical_Scanning">discussion</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#scan">scan (s, matches[, filter[, options]])</a></td> + <td class="summary">create a plain token iterator from a string or file-like object.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#insert">insert (tok, a1, a2)</a></td> + <td class="summary">insert tokens into a stream.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getline">getline (tok)</a></td> + <td class="summary">get everything in a stream upto a newline.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#lineno">lineno (tok)</a></td> + <td class="summary">get current line number.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getrest">getrest (tok)</a></td> + <td class="summary">get the rest of the stream.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#get_keywords">get_keywords ()</a></td> + <td class="summary">get the Lua keywords as a set-like table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#lua">lua (s[, filter[, options]])</a></td> + <td class="summary">create a Lua token iterator from a string or file-like object.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#cpp">cpp (s[, filter[, options]])</a></td> + <td class="summary">create a C/C++ token iterator from a string or file-like object.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#get_separated_list">get_separated_list (tok[, endtoken=')'[, delim=']])</a></td> + <td class="summary">get a list of parameters separated by a delimiter from a stream.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#skipws">skipws (tok)</a></td> + <td class="summary">get the next non-space token from the stream.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#expecting">expecting (tok, expected_type, no_skip_ws)</a></td> + <td class="summary">get the next token, which must be of the expected type.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "scan"></a> + <strong>scan (s, matches[, filter[, options]])</strong> + </dt> + <dd> + create a plain token iterator from a string or file-like object. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> or <span class="type">file</span></span> + a string or a file-like object with <code>:read()</code> method returning lines. + </li> + <li><span class="parameter">matches</span> + <span class="types"><span class="type">tab</span></span> + an optional match table - array of token descriptions. + A token is described by a <code>{pattern, action}</code> pair, where <code>pattern</code> should match + token body and <code>action</code> is a function called when a token of described type is found. + </li> + <li><span class="parameter">filter</span> + <span class="types"><span class="type">tab</span></span> + a table of token types to exclude, by default <code>{space=true}</code> + (<em>optional</em>) + </li> + <li><span class="parameter">options</span> + <span class="types"><span class="type">tab</span></span> + a table of options; by default, <code>{number=true,string=true}</code>, + which means convert numbers and strip string quotes. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "insert"></a> + <strong>insert (tok, a1, a2)</strong> + </dt> + <dd> + insert tokens into a stream. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + a token stream + </li> + <li><span class="parameter">a1</span> + a string is the type, a table is a token list and + a function is assumed to be a token-like iterator (returns type & value) + </li> + <li><span class="parameter">a2</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string is the value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "getline"></a> + <strong>getline (tok)</strong> + </dt> + <dd> + get everything in a stream upto a newline. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + a token stream + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string + </ol> + + + + +</dd> + <dt> + <a name = "lineno"></a> + <strong>lineno (tok)</strong> + </dt> + <dd> + get current line number. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + a token stream + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the line number. + if the input source is a file-like object, + also return the column. + </ol> + + + + +</dd> + <dt> + <a name = "getrest"></a> + <strong>getrest (tok)</strong> + </dt> + <dd> + get the rest of the stream. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + a token stream + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string + </ol> + + + + +</dd> + <dt> + <a name = "get_keywords"></a> + <strong>get_keywords ()</strong> + </dt> + <dd> + get the Lua keywords as a set-like table. + So <code>res["and"]</code> etc would be <code>true</code>. + + + + <h3>Returns:</h3> + <ol> + + a table + </ol> + + + + +</dd> + <dt> + <a name = "lua"></a> + <strong>lua (s[, filter[, options]])</strong> + </dt> + <dd> + create a Lua token iterator from a string or file-like object. + Will return the token type and value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">filter</span> + <span class="types"><span class="type">tab</span></span> + a table of token types to exclude, by default <code>{space=true,comments=true}</code> + (<em>optional</em>) + </li> + <li><span class="parameter">options</span> + <span class="types"><span class="type">tab</span></span> + a table of options; by default, <code>{number=true,string=true}</code>, + which means convert numbers and strip string quotes. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "cpp"></a> + <strong>cpp (s[, filter[, options]])</strong> + </dt> + <dd> + create a C/C++ token iterator from a string or file-like object. + Will return the token type type and value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">filter</span> + <span class="types"><span class="type">tab</span></span> + a table of token types to exclude, by default <code>{space=true,comments=true}</code> + (<em>optional</em>) + </li> + <li><span class="parameter">options</span> + <span class="types"><span class="type">tab</span></span> + a table of options; by default, <code>{number=true,string=true}</code>, + which means convert numbers and strip string quotes. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "get_separated_list"></a> + <strong>get_separated_list (tok[, endtoken=')'[, delim=']])</strong> + </dt> + <dd> + get a list of parameters separated by a delimiter from a stream. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + the token stream + </li> + <li><span class="parameter">endtoken</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + end of list. Can be ‘\n’ + (<em>default</em> ')') + </li> + <li><span class="parameter">delim</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + separator + (<em>default</em> ') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list of token lists. + </ol> + + + + +</dd> + <dt> + <a name = "skipws"></a> + <strong>skipws (tok)</strong> + </dt> + <dd> + get the next non-space token from the stream. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + the token stream. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "expecting"></a> + <strong>expecting (tok, expected_type, no_skip_ws)</strong> + </dt> + <dd> + get the next token, which must be of the expected type. + Throws an error if this type does not match! + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tok</span> + the token stream + </li> + <li><span class="parameter">expected_type</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the token type + </li> + <li><span class="parameter">no_skip_ws</span> + <span class="types"><span class="type">bool</span></span> + whether we should skip whitespace + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.luabalanced.html b/docs/libraries/pl.luabalanced.html new file mode 100644 index 0000000..53dd851 --- /dev/null +++ b/docs/libraries/pl.luabalanced.html @@ -0,0 +1,150 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><strong>pl.luabalanced</strong></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.luabalanced</code></h1> +<p>Extract delimited Lua sequences from strings.</p> +<p> Inspired by Damian Conway’s Text::Balanced in Perl. <br/> + <ul> + <li>[1] <a href="http://lua-users.org/wiki/LuaBalanced">Lua Wiki Page</a></li> + <li>[2] http://search.cpan.org/dist/Text-Balanced/lib/Text/Balanced.pm</li> + </ul> <br/> + <pre class=example> + local lb = require “pl.luabalanced” + –Extract Lua expression starting at position 4. + print(lb.match_expression(“if x<sup>2</sup> + x > 5 then print(x) end”, 4)) + –> x<sup>2</sup> + x > 5 16 + –Extract Lua string starting at (default) position 1. + print(lb.match_string([[“test\"123” .. “more”]])) + –> “test\"123” 12 + </pre> + © 2008, David Manura, Licensed under the same terms as Lua (MIT license).</p> + + + +<br/> +<br/> + + + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.operator.html b/docs/libraries/pl.operator.html new file mode 100644 index 0000000..b47f344 --- /dev/null +++ b/docs/libraries/pl.operator.html @@ -0,0 +1,812 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#Tables">Tables</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><strong>pl.operator</strong></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.operator</code></h1> +<p>Lua operators available as functions.</p> +<p> (similar to the Python module of the same name)</p> + +<p> There is a module field <a href="../libraries/pl.operator.html#optable">optable</a> which maps the operator strings + onto these functions, e.g. <code>operator.optable['()']==operator.call</code></p> + +<p> Operator strings like ‘>’ and ‘{}’ can be passed to most Penlight functions + expecting a function argument.</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#call">call (fn, ...)</a></td> + <td class="summary">apply function to some arguments <strong>()</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#index">index (t, k)</a></td> + <td class="summary">get the indexed value from a table <strong>[]</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#eq">eq (a, b)</a></td> + <td class="summary">returns true if arguments are equal <strong>==</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#neq">neq (a, b)</a></td> + <td class="summary">returns true if arguments are not equal <strong>~=</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#lt">lt (a, b)</a></td> + <td class="summary">returns true if a is less than b <strong><</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#le">le (a, b)</a></td> + <td class="summary">returns true if a is less or equal to b <strong><=</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#gt">gt (a, b)</a></td> + <td class="summary">returns true if a is greater than b <strong>></strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#ge">ge (a, b)</a></td> + <td class="summary">returns true if a is greater or equal to b <strong>>=</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#len">len (a)</a></td> + <td class="summary">returns length of string or table <strong>#</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#add">add (a, b)</a></td> + <td class="summary">add two values <strong>+</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#sub">sub (a, b)</a></td> + <td class="summary">subtract b from a <strong>-</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#mul">mul (a, b)</a></td> + <td class="summary">multiply two values <strong>*</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#div">div (a, b)</a></td> + <td class="summary">divide first value by second <strong>/</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#pow">pow (a, b)</a></td> + <td class="summary">raise first to the power of second <strong>^</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#mod">mod (a, b)</a></td> + <td class="summary">modulo; remainder of a divided by b <strong>%</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#concat">concat (a, b)</a></td> + <td class="summary">concatenate two values (either strings or <code>__concat</code> defined) <strong>..</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#unm">unm (a)</a></td> + <td class="summary">return the negative of a value <strong>-</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#lnot">lnot (a)</a></td> + <td class="summary">false if value evaluates as true <strong>not</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#land">land (a, b)</a></td> + <td class="summary">true if both values evaluate as true <strong>and</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#lor">lor (a, b)</a></td> + <td class="summary">true if either value evaluate as true <strong>or</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#table">table (...)</a></td> + <td class="summary">make a table from the arguments <strong>{}</strong></td> + </tr> + <tr> + <td class="name" nowrap><a href="#match">match (a, b)</a></td> + <td class="summary">match two strings <strong>~</strong>.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#nop">nop (...)</a></td> + <td class="summary">the null operation.</td> + </tr> +</table> +<h2><a href="#Tables">Tables</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#optable">optable</a></td> + <td class="summary">Map from operator symbol to function.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "call"></a> + <strong>call (fn, ...)</strong> + </dt> + <dd> + apply function to some arguments <strong>()</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + a function or callable object + </li> + <li><span class="parameter">...</span> + arguments + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "index"></a> + <strong>index (t, k)</strong> + </dt> + <dd> + get the indexed value from a table <strong>[]</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + a table or any indexable object + </li> + <li><span class="parameter">k</span> + the key + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "eq"></a> + <strong>eq (a, b)</strong> + </dt> + <dd> + returns true if arguments are equal <strong>==</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "neq"></a> + <strong>neq (a, b)</strong> + </dt> + <dd> + returns true if arguments are not equal <strong>~=</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "lt"></a> + <strong>lt (a, b)</strong> + </dt> + <dd> + returns true if a is less than b <strong><</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "le"></a> + <strong>le (a, b)</strong> + </dt> + <dd> + returns true if a is less or equal to b <strong><=</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "gt"></a> + <strong>gt (a, b)</strong> + </dt> + <dd> + returns true if a is greater than b <strong>></strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "ge"></a> + <strong>ge (a, b)</strong> + </dt> + <dd> + returns true if a is greater or equal to b <strong>>=</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "len"></a> + <strong>len (a)</strong> + </dt> + <dd> + returns length of string or table <strong>#</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + a string or a table + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "add"></a> + <strong>add (a, b)</strong> + </dt> + <dd> + add two values <strong>+</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "sub"></a> + <strong>sub (a, b)</strong> + </dt> + <dd> + subtract b from a <strong>-</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "mul"></a> + <strong>mul (a, b)</strong> + </dt> + <dd> + multiply two values <strong>*</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "div"></a> + <strong>div (a, b)</strong> + </dt> + <dd> + divide first value by second <strong>/</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "pow"></a> + <strong>pow (a, b)</strong> + </dt> + <dd> + raise first to the power of second <strong>^</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "mod"></a> + <strong>mod (a, b)</strong> + </dt> + <dd> + modulo; remainder of a divided by b <strong>%</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "concat"></a> + <strong>concat (a, b)</strong> + </dt> + <dd> + concatenate two values (either strings or <code>__concat</code> defined) <strong>..</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "unm"></a> + <strong>unm (a)</strong> + </dt> + <dd> + return the negative of a value <strong>-</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "lnot"></a> + <strong>lnot (a)</strong> + </dt> + <dd> + false if value evaluates as true <strong>not</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "land"></a> + <strong>land (a, b)</strong> + </dt> + <dd> + true if both values evaluate as true <strong>and</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "lor"></a> + <strong>lor (a, b)</strong> + </dt> + <dd> + true if either value evaluate as true <strong>or</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + value + </li> + <li><span class="parameter">b</span> + value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "table"></a> + <strong>table (...)</strong> + </dt> + <dd> + make a table from the arguments <strong>{}</strong> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + non-nil arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table + </ol> + + + + +</dd> + <dt> + <a name = "match"></a> + <strong>match (a, b)</strong> + </dt> + <dd> + match two strings <strong>~</strong>. + uses <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.find">string.find</a> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + + </li> + <li><span class="parameter">b</span> + + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "nop"></a> + <strong>nop (...)</strong> + </dt> + <dd> + the null operation. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the arguments + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Tables"></a>Tables</h2> + + <dl class="function"> + <dt> + <a name = "optable"></a> + <strong>optable</strong> + </dt> + <dd> + <p>Map from operator symbol to function. + Most of these map directly from operators; + But note these extras</p> + +<ul> +<li><strong>‘()’</strong> <a href="../libraries/pl.operator.html#call">call</a></li> +<li><strong>‘[]’</strong> <a href="../libraries/pl.operator.html#index">index</a></li> +<li><strong>‘{}’</strong> <a href="../libraries/pl.operator.html#table">table</a></li> +<li><strong>‘~’</strong> <a href="../libraries/pl.operator.html#match">match</a></li> +</ul> + + + + <h3>Fields:</h3> + <ul> + <li><span class="parameter">operator</span> + + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.path.html b/docs/libraries/pl.path.html new file mode 100644 index 0000000..ab52a07 --- /dev/null +++ b/docs/libraries/pl.path.html @@ -0,0 +1,900 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#Fields">Fields</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><strong>pl.path</strong></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.path</code></h1> +<p>Path manipulation and file queries.</p> +<p> This is modelled after Python’s os.path library (10.1); see <a href="../manual/04-paths.md.html#">the Guide</a>.</p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="http://stevedonovan.github.io/lua-stdlibs/modules/lfs.html">lfs</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#isdir">isdir (P)</a></td> + <td class="summary">is this a directory?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isfile">isfile (P)</a></td> + <td class="summary">is this a file?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getsize">getsize (P)</a></td> + <td class="summary">return size of a file.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#exists">exists (P)</a></td> + <td class="summary">does a path exist?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getatime">getatime (P)</a></td> + <td class="summary">Return the time of last access as the number of seconds since the epoch.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getmtime">getmtime (P)</a></td> + <td class="summary">Return the time of last modification</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getctime">getctime (P)</a></td> + <td class="summary">Return the system’s ctime.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#splitpath">splitpath (P)</a></td> + <td class="summary">given a path, return the directory part and a file part.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#abspath">abspath (P[, pwd])</a></td> + <td class="summary">return an absolute path.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#splitext">splitext (P)</a></td> + <td class="summary">given a path, return the root part and the extension part.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#dirname">dirname (P)</a></td> + <td class="summary">return the directory part of a path</td> + </tr> + <tr> + <td class="name" nowrap><a href="#basename">basename (P)</a></td> + <td class="summary">return the file part of a path</td> + </tr> + <tr> + <td class="name" nowrap><a href="#extension">extension (P)</a></td> + <td class="summary">get the extension part of a path.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isabs">isabs (P)</a></td> + <td class="summary">is this an absolute path?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#join">join (p1, p2, ...)</a></td> + <td class="summary">return the path resulting from combining the individual paths.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#normcase">normcase (P)</a></td> + <td class="summary">normalize the case of a pathname.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#normpath">normpath (P)</a></td> + <td class="summary">normalize a path name.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#relpath">relpath (P[, start])</a></td> + <td class="summary">relative path from current directory or optional start point</td> + </tr> + <tr> + <td class="name" nowrap><a href="#expanduser">expanduser (P)</a></td> + <td class="summary">Replace a starting ‘~’ with the user’s home directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#tmpname">tmpname ()</a></td> + <td class="summary">Return a suitable full path to a new temporary file name.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#common_prefix">common_prefix (path1, path2)</a></td> + <td class="summary">return the largest common prefix path of two paths.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#package_path">package_path (mod)</a></td> + <td class="summary">return the full path where a particular Lua module would be found.</td> + </tr> +</table> +<h2><a href="#Fields">Fields</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#dir">dir</a></td> + <td class="summary">Lua iterator over the entries of a given directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#mkdir">mkdir</a></td> + <td class="summary">Creates a directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rmdir">rmdir</a></td> + <td class="summary">Removes a directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#currentdir">currentdir</a></td> + <td class="summary">Get the working directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#chdir">chdir</a></td> + <td class="summary">Changes the working directory.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_windows">is_windows</a></td> + <td class="summary">are we running Windows?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sep">sep</a></td> + <td class="summary">path separator for this platform.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#dirsep">dirsep</a></td> + <td class="summary">separator for PATH for this platform</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "isdir"></a> + <strong>isdir (P)</strong> + </dt> + <dd> + is this a directory? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "isfile"></a> + <strong>isfile (P)</strong> + </dt> + <dd> + is this a file?. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "getsize"></a> + <strong>getsize (P)</strong> + </dt> + <dd> + return size of a file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "exists"></a> + <strong>exists (P)</strong> + </dt> + <dd> + does a path exist?. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the file path if it exists, nil otherwise + </ol> + + + + +</dd> + <dt> + <a name = "getatime"></a> + <strong>getatime (P)</strong> + </dt> + <dd> + Return the time of last access as the number of seconds since the epoch. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "getmtime"></a> + <strong>getmtime (P)</strong> + </dt> + <dd> + Return the time of last modification + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "getctime"></a> + <strong>getctime (P)</strong> + </dt> + <dd> + Return the system’s ctime. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "splitpath"></a> + <strong>splitpath (P)</strong> + </dt> + <dd> + given a path, return the directory part and a file part. + if there’s no directory part, the first value will be empty + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "abspath"></a> + <strong>abspath (P[, pwd])</strong> + </dt> + <dd> + return an absolute path. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + <li><span class="parameter">pwd</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + optional start path to use (default is current dir) + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "splitext"></a> + <strong>splitext (P)</strong> + </dt> + <dd> + given a path, return the root part and the extension part. + if there’s no extension part, the second value will be empty + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + root part</li> + <li> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + extension part (maybe empty)</li> + </ol> + + + + +</dd> + <dt> + <a name = "dirname"></a> + <strong>dirname (P)</strong> + </dt> + <dd> + return the directory part of a path + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "basename"></a> + <strong>basename (P)</strong> + </dt> + <dd> + return the file part of a path + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "extension"></a> + <strong>extension (P)</strong> + </dt> + <dd> + get the extension part of a path. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "isabs"></a> + <strong>isabs (P)</strong> + </dt> + <dd> + is this an absolute path?. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "join"></a> + <strong>join (p1, p2, ...)</strong> + </dt> + <dd> + return the path resulting from combining the individual paths. + if the second (or later) path is absolute, we return the last absolute path (joined with any non-absolute paths following). + empty elements (except the last) will be ignored. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">p1</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + <li><span class="parameter">p2</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + <li><span class="parameter">...</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + more file paths + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "normcase"></a> + <strong>normcase (P)</strong> + </dt> + <dd> + normalize the case of a pathname. On Unix, this returns the path unchanged; + for Windows, it converts the path to lowercase, and it also converts forward slashes + to backward slashes. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "normpath"></a> + <strong>normpath (P)</strong> + </dt> + <dd> + normalize a path name. + A//B, A/./B and A/foo/../B all become A/B. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "relpath"></a> + <strong>relpath (P[, start])</strong> + </dt> + <dd> + relative path from current directory or optional start point + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a path + </li> + <li><span class="parameter">start</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + optional start point (default current directory) + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "expanduser"></a> + <strong>expanduser (P)</strong> + </dt> + <dd> + Replace a starting ‘~’ with the user’s home directory. + In windows, if HOME isn’t set, then USERPROFILE is used in preference to + HOMEDRIVE HOMEPATH. This is guaranteed to be writeable on all versions of Windows. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">P</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + A file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "tmpname"></a> + <strong>tmpname ()</strong> + </dt> + <dd> + Return a suitable full path to a new temporary file name. + unlike os.tmpnam(), it always gives you a writeable path (uses TEMP environment variable on Windows) + + + + + + + +</dd> + <dt> + <a name = "common_prefix"></a> + <strong>common_prefix (path1, path2)</strong> + </dt> + <dd> + return the largest common prefix path of two paths. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">path1</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a file path + </li> + <li><span class="parameter">path2</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a file path + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "package_path"></a> + <strong>package_path (mod)</strong> + </dt> + <dd> + return the full path where a particular Lua module would be found. + Both package.path and package.cpath is searched, so the result may + either be a Lua file or a shared library. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">mod</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + name of the module + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + on success: path of module, lua or binary</li> + <li> + on error: nil,error string</li> + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Fields"></a>Fields</h2> + + <dl class="function"> + <dt> + <a name = "dir"></a> + <strong>dir</strong> + </dt> + <dd> + Lua iterator over the entries of a given directory. + Behaves like <a href="http://stevedonovan.github.io/lua-stdlibs/modules/lfs.html#dir">lfs.dir</a> + + + + + + + +</dd> + <dt> + <a name = "mkdir"></a> + <strong>mkdir</strong> + </dt> + <dd> + Creates a directory. + + + + + + + +</dd> + <dt> + <a name = "rmdir"></a> + <strong>rmdir</strong> + </dt> + <dd> + Removes a directory. + + + + + + + +</dd> + <dt> + <a name = "currentdir"></a> + <strong>currentdir</strong> + </dt> + <dd> + Get the working directory. + + + + + + + +</dd> + <dt> + <a name = "chdir"></a> + <strong>chdir</strong> + </dt> + <dd> + Changes the working directory. + + + + + + + +</dd> + <dt> + <a name = "is_windows"></a> + <strong>is_windows</strong> + </dt> + <dd> + are we running Windows? + + + + + + + +</dd> + <dt> + <a name = "sep"></a> + <strong>sep</strong> + </dt> + <dd> + path separator for this platform. + + + + + + + +</dd> + <dt> + <a name = "dirsep"></a> + <strong>dirsep</strong> + </dt> + <dd> + separator for PATH for this platform + + + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.permute.html b/docs/libraries/pl.permute.html new file mode 100644 index 0000000..b239a8b --- /dev/null +++ b/docs/libraries/pl.permute.html @@ -0,0 +1,210 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><strong>pl.permute</strong></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.permute</code></h1> +<p>Permutation operations.</p> +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#iter">iter (a)</a></td> + <td class="summary">an iterator over all permutations of the elements of a list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#table">table (a)</a></td> + <td class="summary">construct a table containing all the permutations of a list.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "iter"></a> + <strong>iter (a)</strong> + </dt> + <dd> + an iterator over all permutations of the elements of a list. + Please note that the same list is returned each time, so do not keep references! + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + list-like table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator which provides the next permutation as a list + </ol> + + + + +</dd> + <dt> + <a name = "table"></a> + <strong>table (a)</strong> + </dt> + <dd> + construct a table containing all the permutations of a list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + list-like table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table of tables + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">permute.<span class="global">table</span> {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} <span class="comment">--> {{2,3,1},{3,2,1},{3,1,2},{1,3,2},{2,1,3},{1,2,3}}</span></pre> + </ul> + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.pretty.html b/docs/libraries/pl.pretty.html new file mode 100644 index 0000000..78a25a6 --- /dev/null +++ b/docs/libraries/pl.pretty.html @@ -0,0 +1,345 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><strong>pl.pretty</strong></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.pretty</code></h1> +<p>Pretty-printing Lua tables.</p> +<p> Also provides a sandboxed Lua table reader and + a function to present large numbers in human-friendly format.</p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.lexer.html#">pl.lexer</a>, <a href="../libraries/pl.stringx.html#">pl.stringx</a>, <a href="https://www.lua.org/manual/5.1/manual.html#5.9">debug</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#read">read (s)</a></td> + <td class="summary">Read a string representation of a Lua table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#load">load (s[, env[, paranoid]])</a></td> + <td class="summary">Read a Lua chunk.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#write">write (tbl[, space[, not_clever]])</a></td> + <td class="summary">Create a string representation of a Lua table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#dump">dump (t[, filename])</a></td> + <td class="summary">Dump a Lua table out to a file or stdout.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#number">number (num[, kind[, prec]])</a></td> + <td class="summary">Format large numbers nicely for human consumption.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "read"></a> + <strong>read (s)</strong> + </dt> + <dd> + Read a string representation of a Lua table. + This function loads and runs the string as Lua code, but bails out + if it contains a function definition. + Loaded string is executed in an empty environment. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + string to read in <code>{…}</code> format, possibly with some whitespace + before or after the curly braces. A single line comment may be present + at the beginning. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table in case of success. + If loading the string failed, return <code>nil</code> and error message. + If executing loaded string failed, return <code>nil</code> and the error it raised. + </ol> + + + + +</dd> + <dt> + <a name = "load"></a> + <strong>load (s[, env[, paranoid]])</strong> + </dt> + <dd> + Read a Lua chunk. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + Lua code. + </li> + <li><span class="parameter">env</span> + <span class="types"><span class="type">tab</span></span> + environment used to run the code, empty by default. + (<em>optional</em>) + </li> + <li><span class="parameter">paranoid</span> + <span class="types"><span class="type">bool</span></span> + abort loading if any looping constructs a found in the code + and disable string methods. + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the environment in case of success or <code>nil</code> and syntax or runtime error + if something went wrong. + </ol> + + + + +</dd> + <dt> + <a name = "write"></a> + <strong>write (tbl[, space[, not_clever]])</strong> + </dt> + <dd> + Create a string representation of a Lua table. + This function never fails, but may complain by returning an + extra value. Normally puts out one item per line, using + the provided indent; set the second parameter to an empty string + if you want output on one line. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tbl</span> + <span class="types"><span class="type">tab</span></span> + Table to serialize to a string. + </li> + <li><span class="parameter">space</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + The indent to use. + Defaults to two spaces; pass an empty string for no indentation. + (<em>optional</em>) + </li> + <li><span class="parameter">not_clever</span> + <span class="types"><span class="type">bool</span></span> + Pass <code>true</code> for plain output, e.g <code>{['key']=1}</code>. + Defaults to <code>false</code>. + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + a string</li> + <li> + an optional error message</li> + </ol> + + + + +</dd> + <dt> + <a name = "dump"></a> + <strong>dump (t[, filename])</strong> + </dt> + <dd> + Dump a Lua table out to a file or stdout. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + The table to write to a file or stdout. + </li> + <li><span class="parameter">filename</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + File name to write too. Defaults to writing + to stdout. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "number"></a> + <strong>number (num[, kind[, prec]])</strong> + </dt> + <dd> + Format large numbers nicely for human consumption. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">num</span> + <span class="types"><a class="type" href="../libraries/pl.pretty.html#number">number</a></span> + a number. + </li> + <li><span class="parameter">kind</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + one of <code>'M'</code> (memory in <code>KiB</code>, <code>MiB</code>, etc.), + <code>'N'</code> (postfixes are <code>'K'</code>, <code>'M'</code> and <code>'B'</code>), + or <code>'T'</code> (use commas as thousands separator), <code>'N'</code> by default. + (<em>optional</em>) + </li> + <li><span class="parameter">prec</span> + <span class="types"><span class="type">int</span></span> + number of digits to use for <code>'M'</code> and <code>'N'</code>, <code>1</code> by default. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.seq.html b/docs/libraries/pl.seq.html new file mode 100644 index 0000000..ee99af4 --- /dev/null +++ b/docs/libraries/pl.seq.html @@ -0,0 +1,889 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><strong>pl.seq</strong></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.seq</code></h1> +<p>Manipulating iterators as sequences.</p> +<p> See <a href="../manual/07-functional.md.html#Sequences">The Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.types.html#">pl.types</a>, <a href="https://www.lua.org/manual/5.1/manual.html#5.9">debug</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#matching">matching (s)</a></td> + <td class="summary">given a string, return a function(y) which matches y against the string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#list">list (t)</a></td> + <td class="summary">sequence adaptor for a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#keys">keys (t)</a></td> + <td class="summary">return the keys of the table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#range">range (start, finish)</a></td> + <td class="summary">create an iterator over a numerical range.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#minmax">minmax (iter)</a></td> + <td class="summary">return the minimum and the maximum value of the sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sum">sum (iter, fn)</a></td> + <td class="summary">return the sum and element count of the sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#copy">copy (iter)</a></td> + <td class="summary">create a table from the sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#copy2">copy2 (iter, i1, i2)</a></td> + <td class="summary">create a table of pairs from the double-valued sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#copy_tuples">copy_tuples (iter)</a></td> + <td class="summary">create a table of ‘tuples’ from a multi-valued sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#random">random (n, l, u)</a></td> + <td class="summary">return an iterator of random numbers.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sort">sort (iter, comp)</a></td> + <td class="summary">return an iterator to the sorted elements of a sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#zip">zip (iter1, iter2)</a></td> + <td class="summary">return an iterator which returns elements of two sequences.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#count_map">count_map (iter)</a></td> + <td class="summary">Makes a table where the key/values are the values and value counts of the sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#printall">printall (iter, sep, nfields, fmt)</a></td> + <td class="summary">print out a sequence iter with a separator.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#map">map (fn, iter, arg)</a></td> + <td class="summary">return a sequence where every element of a sequence has been transformed + by a function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#filter">filter (iter, pred, arg)</a></td> + <td class="summary">filter a sequence using a predicate function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#reduce">reduce (fn, iter, initval)</a></td> + <td class="summary">‘reduce’ a sequence using a binary function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#take">take (iter, n)</a></td> + <td class="summary">take the first n values from the sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#skip">skip (iter, n)</a></td> + <td class="summary">skip the first n values of a sequence</td> + </tr> + <tr> + <td class="name" nowrap><a href="#enum">enum (iter)</a></td> + <td class="summary">a sequence with a sequence count and the original value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#mapmethod">mapmethod (iter, name, arg1, arg2)</a></td> + <td class="summary">map using a named method over a sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#last">last (iter)</a></td> + <td class="summary">a sequence of (last,current) values from another sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#foreach">foreach (iter, fn)</a></td> + <td class="summary">call the function on each element of the sequence.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#lines">lines (f, ...)</a></td> + <td class="summary">create a wrapped iterator over all lines in the file.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "matching"></a> + <strong>matching (s)</strong> + </dt> + <dd> + given a string, return a function(y) which matches y against the string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "list"></a> + <strong>list (t)</strong> + </dt> + <dd> + sequence adaptor for a table. Note that if any generic function is + passed a table, it will automatically use seq.list() + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + a list-like table + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">sum(list(t)) is the sum of all elements of t</pre></li> + <li><pre class="example"><span class="keyword">for</span> x <span class="keyword">in</span> list(t) <span class="keyword">do</span>...<span class="keyword">end</span></pre></li> + </ul> + +</dd> + <dt> + <a name = "keys"></a> + <strong>keys (t)</strong> + </dt> + <dd> + return the keys of the table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + an arbitrary table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + iterator over keys + </ol> + + + + +</dd> + <dt> + <a name = "range"></a> + <strong>range (start, finish)</strong> + </dt> + <dd> + create an iterator over a numerical range. Like the standard Python function xrange. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">start</span> + a number + </li> + <li><span class="parameter">finish</span> + a number greater than start + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "minmax"></a> + <strong>minmax (iter)</strong> + </dt> + <dd> + return the minimum and the maximum value of the sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + minimum value</li> + <li> + maximum value</li> + </ol> + + + + +</dd> + <dt> + <a name = "sum"></a> + <strong>sum (iter, fn)</strong> + </dt> + <dd> + return the sum and element count of the sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + <li><span class="parameter">fn</span> + an optional function to apply to the values + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "copy"></a> + <strong>copy (iter)</strong> + </dt> + <dd> + create a table from the sequence. (This will make the result a List.) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a List + </ol> + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">copy(list(ls)) is equal to ls</pre></li> + <li><pre class="example">copy(list {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}) == List{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}</pre></li> + </ul> + +</dd> + <dt> + <a name = "copy2"></a> + <strong>copy2 (iter, i1, i2)</strong> + </dt> + <dd> + create a table of pairs from the double-valued sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a double-valued sequence + </li> + <li><span class="parameter">i1</span> + used to capture extra iterator values + </li> + <li><span class="parameter">i2</span> + as with pairs & ipairs + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list-like table + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">copy2(<span class="global">ipairs</span>{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}) == {{<span class="number">1</span>,<span class="number">10</span>},{<span class="number">2</span>,<span class="number">20</span>},{<span class="number">3</span>,<span class="number">30</span>}}</pre> + </ul> + +</dd> + <dt> + <a name = "copy_tuples"></a> + <strong>copy_tuples (iter)</strong> + </dt> + <dd> + create a table of ‘tuples’ from a multi-valued sequence. + A generalization of copy2 above + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a multiple-valued sequence + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list-like table + </ol> + + + + +</dd> + <dt> + <a name = "random"></a> + <strong>random (n, l, u)</strong> + </dt> + <dd> + return an iterator of random numbers. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">n</span> + the length of the sequence + </li> + <li><span class="parameter">l</span> + same as the first optional argument to math.random + </li> + <li><span class="parameter">u</span> + same as the second optional argument to math.random + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a sequence + </ol> + + + + +</dd> + <dt> + <a name = "sort"></a> + <strong>sort (iter, comp)</strong> + </dt> + <dd> + return an iterator to the sorted elements of a sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + <li><span class="parameter">comp</span> + an optional comparison function (comp(x,y) is true if x < y) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "zip"></a> + <strong>zip (iter1, iter2)</strong> + </dt> + <dd> + return an iterator which returns elements of two sequences. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter1</span> + a sequence + </li> + <li><span class="parameter">iter2</span> + a sequence + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">for</span> x,y <span class="keyword">in</span> seq.zip(ls1,ls2) <span class="keyword">do</span>....<span class="keyword">end</span></pre> + </ul> + +</dd> + <dt> + <a name = "count_map"></a> + <strong>count_map (iter)</strong> + </dt> + <dd> + Makes a table where the key/values are the values and value counts of the sequence. + This version works with ‘hashable’ values like strings and numbers. + <a href="../libraries/pl.tablex.html#count_map">pl.tablex.count_map</a> is more general. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + a map-like table</li> + <li> + a table</li> + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#count_map">pl.tablex.count_map</a> + </ul> + + +</dd> + <dt> + <a name = "printall"></a> + <strong>printall (iter, sep, nfields, fmt)</strong> + </dt> + <dd> + print out a sequence iter with a separator. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + <li><span class="parameter">sep</span> + the separator (default space) + </li> + <li><span class="parameter">nfields</span> + maximum number of values per line (default 7) + </li> + <li><span class="parameter">fmt</span> + optional format function for each value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "map"></a> + <strong>map (fn, iter, arg)</strong> + </dt> + <dd> + return a sequence where every element of a sequence has been transformed + by a function. If you don’t supply an argument, then the function will + receive both values of a double-valued sequence, otherwise behaves rather like + tablex.map. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + a function to apply to elements; may take two arguments + </li> + <li><span class="parameter">iter</span> + a sequence of one or two values + </li> + <li><span class="parameter">arg</span> + optional argument to pass to function. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "filter"></a> + <strong>filter (iter, pred, arg)</strong> + </dt> + <dd> + filter a sequence using a predicate function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence of one or two values + </li> + <li><span class="parameter">pred</span> + a boolean function; may take two arguments + </li> + <li><span class="parameter">arg</span> + optional argument to pass to function. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "reduce"></a> + <strong>reduce (fn, iter, initval)</strong> + </dt> + <dd> + ‘reduce’ a sequence using a binary function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + <span class="types"><span class="type">func</span></span> + a function of two arguments + </li> + <li><span class="parameter">iter</span> + a sequence + </li> + <li><span class="parameter">initval</span> + optional initial value + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">seq.reduce(operator.add,seq.list{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) == <span class="number">10</span></pre></li> + <li><pre class="example">seq.reduce(<span class="string">'-'</span>,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>}) == -<span class="number">13</span></pre></li> + </ul> + +</dd> + <dt> + <a name = "take"></a> + <strong>take (iter, n)</strong> + </dt> + <dd> + take the first n values from the sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence of one or two values + </li> + <li><span class="parameter">n</span> + number of items to take + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a sequence of at most n items + </ol> + + + + +</dd> + <dt> + <a name = "skip"></a> + <strong>skip (iter, n)</strong> + </dt> + <dd> + skip the first n values of a sequence + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence of one or more values + </li> + <li><span class="parameter">n</span> + number of items to skip + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "enum"></a> + <strong>enum (iter)</strong> + </dt> + <dd> + a sequence with a sequence count and the original value. + enum(copy(ls)) is a roundabout way of saying ipairs(ls). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a single or double valued sequence + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + sequence of (i,v), i = 1..n and v is from iter. + </ol> + + + + +</dd> + <dt> + <a name = "mapmethod"></a> + <strong>mapmethod (iter, name, arg1, arg2)</strong> + </dt> + <dd> + map using a named method over a sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + <li><span class="parameter">name</span> + the method name + </li> + <li><span class="parameter">arg1</span> + optional first extra argument + </li> + <li><span class="parameter">arg2</span> + optional second extra argument + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "last"></a> + <strong>last (iter)</strong> + </dt> + <dd> + a sequence of (last,current) values from another sequence. + This will return S(i-1),S(i) if given S(i) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "foreach"></a> + <strong>foreach (iter, fn)</strong> + </dt> + <dd> + call the function on each element of the sequence. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">iter</span> + a sequence with up to 3 values + </li> + <li><span class="parameter">fn</span> + a function + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "lines"></a> + <strong>lines (f, ...)</strong> + </dt> + <dd> + create a wrapped iterator over all lines in the file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + either a filename, file-like object, or ‘STDIN’ (for standard input) + </li> + <li><span class="parameter">...</span> + for Lua 5.2 only, optional format specifiers, as in <a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.read">io.read</a>. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a sequence wrapper + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.sip.html b/docs/libraries/pl.sip.html new file mode 100644 index 0000000..9a5d913 --- /dev/null +++ b/docs/libraries/pl.sip.html @@ -0,0 +1,400 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><strong>pl.sip</strong></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.sip</code></h1> +<p>Simple Input Patterns (SIP).</p> +<p> SIP patterns start with ‘$’, then a + one-letter type, and then an optional variable in curly braces.</p> + +<pre> +sip.match(<span class="string">'$v=$q'</span>,<span class="string">'name="dolly"'</span>,res) +==> res=={<span class="string">'name'</span>,<span class="string">'dolly'</span>} +sip.match(<span class="string">'($q{first},$q{second})'</span>,<span class="string">'("john","smith")'</span>,res) +==> res=={second=<span class="string">'smith'</span>,first=<span class="string">'john'</span>} +</pre> + + +<p> Type names:</p> + +<pre> +v identifier +i integer +f floating-point +q quoted <span class="global">string</span> +([{< match up to closing bracket +</pre> + + +<p> See <a href="../manual/08-additional.md.html#Simple_Input_Patterns">the Guide</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#create_pattern">create_pattern (spec, options)</a></td> + <td class="summary">convert a SIP pattern into the equivalent Lua string pattern.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#compile">compile (spec, options)</a></td> + <td class="summary">convert a SIP pattern into a matching function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#match">match (spec, line, res, options)</a></td> + <td class="summary">match a SIP pattern against a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#match_at_start">match_at_start (spec, line, res)</a></td> + <td class="summary">match a SIP pattern against the start of a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#fields">fields (spec, f)</a></td> + <td class="summary">given a pattern and a file object, return an iterator over the results</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pattern">pattern (spec, fun)</a></td> + <td class="summary">register a match which will be used in the read function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#read">read (f, matches)</a></td> + <td class="summary">enter a loop which applies all registered matches to the input file.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "create_pattern"></a> + <strong>create_pattern (spec, options)</strong> + </dt> + <dd> + convert a SIP pattern into the equivalent Lua string pattern. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">spec</span> + a SIP pattern + </li> + <li><span class="parameter">options</span> + a table; only the <code>at_start</code> field is + currently meaningful and ensures that the pattern is anchored + at the start of the string. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a Lua string pattern. + </ol> + + + + +</dd> + <dt> + <a name = "compile"></a> + <strong>compile (spec, options)</strong> + </dt> + <dd> + convert a SIP pattern into a matching function. + The returned function takes two arguments, the line and an empty table. + If the line matched the pattern, then this function returns true + and the table is filled with field-value pairs. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">spec</span> + a SIP pattern + </li> + <li><span class="parameter">options</span> + optional table; {at_start=true} ensures that the pattern + is anchored at the start of the string. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function if successful, or nil,error + </ol> + + + + +</dd> + <dt> + <a name = "match"></a> + <strong>match (spec, line, res, options)</strong> + </dt> + <dd> + match a SIP pattern against a string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">spec</span> + a SIP pattern + </li> + <li><span class="parameter">line</span> + a string + </li> + <li><span class="parameter">res</span> + a table to receive values + </li> + <li><span class="parameter">options</span> + (optional) option table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "match_at_start"></a> + <strong>match_at_start (spec, line, res)</strong> + </dt> + <dd> + match a SIP pattern against the start of a string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">spec</span> + a SIP pattern + </li> + <li><span class="parameter">line</span> + a string + </li> + <li><span class="parameter">res</span> + a table to receive values + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "fields"></a> + <strong>fields (spec, f)</strong> + </dt> + <dd> + given a pattern and a file object, return an iterator over the results + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">spec</span> + a SIP pattern + </li> + <li><span class="parameter">f</span> + a file-like object. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "pattern"></a> + <strong>pattern (spec, fun)</strong> + </dt> + <dd> + register a match which will be used in the read function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">spec</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a SIP pattern + </li> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function to be called with the results of the match + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.sip.html#read">read</a> + </ul> + + +</dd> + <dt> + <a name = "read"></a> + <strong>read (f, matches)</strong> + </dt> + <dd> + enter a loop which applies all registered matches to the input file. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + a file-like object + </li> + <li><span class="parameter">matches</span> + <span class="types"><span class="type">array</span></span> + optional list of <code>{spec,fun}</code> pairs, as for <a href="../libraries/pl.sip.html#pattern">pattern</a> above. + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.strict.html b/docs/libraries/pl.strict.html new file mode 100644 index 0000000..79f9b34 --- /dev/null +++ b/docs/libraries/pl.strict.html @@ -0,0 +1,254 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><strong>pl.strict</strong></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.strict</code></h1> +<p>Checks uses of undeclared global variables.</p> +<p> All global variables must be ‘declared’ through a regular assignment + (even assigning <code>nil</code> will do) in a main chunk before being used + anywhere or assigned to inside a function. Existing metatables <code>__newindex</code> and <code>__index</code> + metamethods are respected.</p> + +<p> You can set any table to have strict behaviour using <a href="../libraries/pl.strict.html#module">strict.module</a>. Creating a new + module with <a href="../libraries/pl.strict.html#closed_module">strict.closed_module</a> makes the module immune to monkey-patching, if + you don’t wish to encourage monkey business.</p> + +<p> If the global <code>PENLIGHT_NO_GLOBAL_STRICT</code> is defined, then this module won’t make the + global environment strict - if you just want to explicitly set table strictness.</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#module">module (name[, mod[, predeclared]])</a></td> + <td class="summary">make an existing table strict.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#make_all_strict">make_all_strict (T)</a></td> + <td class="summary">make all tables in a table strict.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#closed_module">closed_module (mod, name)</a></td> + <td class="summary">make a new module table which is closed to further changes.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "module"></a> + <strong>module (name[, mod[, predeclared]])</strong> + </dt> + <dd> + make an existing table strict. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">name</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + name of table (optional) + </li> + <li><span class="parameter">mod</span> + <span class="types"><span class="type">tab</span></span> + table - if <code>nil</code> then we’ll return a new table + (<em>optional</em>) + </li> + <li><span class="parameter">predeclared</span> + <span class="types"><span class="type">tab</span></span> + <ul> +<li>table of variables that are to be considered predeclared.</li> +</ul> + + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the given table, or a new table + </ol> + + + + +</dd> + <dt> + <a name = "make_all_strict"></a> + <strong>make_all_strict (T)</strong> + </dt> + <dd> + make all tables in a table strict. + So <code>strict.make_all_strict(_G)</code> prevents monkey-patching + of any global table + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">T</span> + <span class="types"><span class="type">tab</span></span> + + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "closed_module"></a> + <strong>closed_module (mod, name)</strong> + </dt> + <dd> + make a new module table which is closed to further changes. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">mod</span> + + </li> + <li><span class="parameter">name</span> + + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.stringio.html b/docs/libraries/pl.stringio.html new file mode 100644 index 0000000..ca903fa --- /dev/null +++ b/docs/libraries/pl.stringio.html @@ -0,0 +1,216 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><strong>pl.stringio</strong></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.stringio</code></h1> +<p>Reading and writing strings using file-like objects.</p> +<p> <br></p> + +<pre> +f = stringio.open(text) +l1 = f:read() <span class="comment">-- read first line +</span>n,m = f:read (<span class="string">'*n'</span>,<span class="string">'*n'</span>) <span class="comment">-- read two numbers +</span><span class="keyword">for</span> line <span class="keyword">in</span> f:lines() <span class="keyword">do</span> <span class="global">print</span>(line) <span class="keyword">end</span> <span class="comment">-- iterate over all lines +</span>f = stringio.create() +f:write(<span class="string">'hello'</span>) +f:write(<span class="string">'dolly'</span>) +<span class="global">assert</span>(f:value(),<span class="string">'hellodolly'</span>) +</pre> + + +<p> See <a href="../manual/03-strings.md.html#File_style_I_O_on_Strings">the Guide</a>.</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#create">create ()</a></td> + <td class="summary">create a file-like object which can be used to construct a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#open">open (s)</a></td> + <td class="summary">create a file-like object for reading from a given string.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "create"></a> + <strong>create ()</strong> + </dt> + <dd> + create a file-like object which can be used to construct a string. + The resulting object has an extra <code>value()</code> method for + retrieving the string value. Implements <a href="../libraries/pl.file.html#write">file:write</a>, <code>file:seek</code>, <code>file:lines</code>, + plus an extra <code>writef</code> method which works like <a href="../libraries/pl.utils.html#printf">utils.printf</a>. + + + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">f = create(); f:write(<span class="string">'hello, dolly\n'</span>); <span class="global">print</span>(f:value())</pre> + </ul> + +</dd> + <dt> + <a name = "open"></a> + <strong>open (s)</strong> + </dt> + <dd> + create a file-like object for reading from a given string. + Implements <a href="../libraries/pl.file.html#read">file:read</a>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + The input string. + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">fs = open <span class="string">'20 10'</span>; x,y = f:read (<span class="string">'*n'</span>,<span class="string">'*n'</span>); <span class="global">assert</span>(x == <span class="number">20</span> <span class="keyword">and</span> y == <span class="number">10</span>)</pre> + </ul> + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.stringx.html b/docs/libraries/pl.stringx.html new file mode 100644 index 0000000..666a958 --- /dev/null +++ b/docs/libraries/pl.stringx.html @@ -0,0 +1,1162 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#String_Predicates">String Predicates </a></li> +<li><a href="#Strings_and_Lists">Strings and Lists </a></li> +<li><a href="#Finding_and_Replacing">Finding and Replacing </a></li> +<li><a href="#Stripping_and_Justifying">Stripping and Justifying </a></li> +<li><a href="#Partioning_Strings">Partioning Strings </a></li> +<li><a href="#Miscelaneous">Miscelaneous </a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><strong>pl.stringx</strong></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.stringx</code></h1> +<p>Python-style extended string library.</p> +<p> see 3.6.1 of the Python reference. + If you want to make these available as string methods, then say + <code>stringx.import()</code> to bring them into the standard <a href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> table.</p> + +<p> See <a href="../manual/03-strings.md.html#">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a></p> + + +<h2><a href="#String_Predicates">String Predicates </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#isalpha">isalpha (s)</a></td> + <td class="summary">does s only contain alphabetic characters?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isdigit">isdigit (s)</a></td> + <td class="summary">does s only contain digits?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isalnum">isalnum (s)</a></td> + <td class="summary">does s only contain alphanumeric characters?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isspace">isspace (s)</a></td> + <td class="summary">does s only contain spaces?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#islower">islower (s)</a></td> + <td class="summary">does s only contain lower case characters?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#isupper">isupper (s)</a></td> + <td class="summary">does s only contain upper case characters?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#startswith">startswith (s, prefix)</a></td> + <td class="summary">does s start with prefix or one of prefixes?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#endswith">endswith (s, suffix)</a></td> + <td class="summary">does s end with suffix or one of suffixes?</td> + </tr> +</table> +<h2><a href="#Strings_and_Lists">Strings and Lists </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#join">join (s, seq)</a></td> + <td class="summary">concatenate the strings using this string as a delimiter.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#splitlines">splitlines (s[, keep_ends])</a></td> + <td class="summary">Split a string into a list of lines.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#split">split (s[, re[, n]])</a></td> + <td class="summary">split a string into a list of strings using a delimiter.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#expandtabs">expandtabs (s, tabsize)</a></td> + <td class="summary">replace all tabs in s with tabsize spaces.</td> + </tr> +</table> +<h2><a href="#Finding_and_Replacing">Finding and Replacing </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#lfind">lfind (s, sub[, first[, last]])</a></td> + <td class="summary">find index of first instance of sub in s from the left.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rfind">rfind (s, sub[, first[, last]])</a></td> + <td class="summary">find index of first instance of sub in s from the right.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#replace">replace (s, old, new[, n])</a></td> + <td class="summary">replace up to n instances of old by new in the string s.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#count">count (s, sub)</a></td> + <td class="summary">count all instances of substring in string.</td> + </tr> +</table> +<h2><a href="#Stripping_and_Justifying">Stripping and Justifying </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#ljust">ljust (s, w[, ch=' '])</a></td> + <td class="summary">left-justify s with width w.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rjust">rjust (s, w[, ch=' '])</a></td> + <td class="summary">right-justify s with width w.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#center">center (s, w[, ch=' '])</a></td> + <td class="summary">center-justify s with width w.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#lstrip">lstrip (s[, chrs='%s'])</a></td> + <td class="summary">trim any whitespace on the left of s.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rstrip">rstrip (s[, chrs='%s'])</a></td> + <td class="summary">trim any whitespace on the right of s.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#strip">strip (s[, chrs='%s'])</a></td> + <td class="summary">trim any whitespace on both left and right of s.</td> + </tr> +</table> +<h2><a href="#Partioning_Strings">Partioning Strings </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#splitv">splitv (s[, re='%s'])</a></td> + <td class="summary">split a string using a pattern.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#partition">partition (s, ch)</a></td> + <td class="summary">partition the string using first occurance of a delimiter</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rpartition">rpartition (s, ch)</a></td> + <td class="summary">partition the string p using last occurance of a delimiter</td> + </tr> + <tr> + <td class="name" nowrap><a href="#at">at (s, idx)</a></td> + <td class="summary">return the ‘character’ at the index.</td> + </tr> +</table> +<h2><a href="#Miscelaneous">Miscelaneous </a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#lines">lines (s)</a></td> + <td class="summary">return an iterator over all lines in a string</td> + </tr> + <tr> + <td class="name" nowrap><a href="#title">title (s)</a></td> + <td class="summary">iniital word letters uppercase (‘title case’).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#shorten">shorten (s, w, tail)</a></td> + <td class="summary">Return a shortened version of a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#quote_string">quote_string (s)</a></td> + <td class="summary">Quote the given string and preserve any control or escape characters, such that reloading the string in Lua returns the same result.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="String_Predicates"></a>String Predicates </h2> + + <dl class="function"> + <dt> + <a name = "isalpha"></a> + <strong>isalpha (s)</strong> + </dt> + <dd> + does s only contain alphabetic characters? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "isdigit"></a> + <strong>isdigit (s)</strong> + </dt> + <dd> + does s only contain digits? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "isalnum"></a> + <strong>isalnum (s)</strong> + </dt> + <dd> + does s only contain alphanumeric characters? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "isspace"></a> + <strong>isspace (s)</strong> + </dt> + <dd> + does s only contain spaces? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "islower"></a> + <strong>islower (s)</strong> + </dt> + <dd> + does s only contain lower case characters? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "isupper"></a> + <strong>isupper (s)</strong> + </dt> + <dd> + does s only contain upper case characters? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "startswith"></a> + <strong>startswith (s, prefix)</strong> + </dt> + <dd> + does s start with prefix or one of prefixes? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + <li><span class="parameter">prefix</span> + a string or an array of strings + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "endswith"></a> + <strong>endswith (s, suffix)</strong> + </dt> + <dd> + does s end with suffix or one of suffixes? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a string + </li> + <li><span class="parameter">suffix</span> + a string or an array of strings + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Strings_and_Lists"></a>Strings and Lists </h2> + + <dl class="function"> + <dt> + <a name = "join"></a> + <strong>join (s, seq)</strong> + </dt> + <dd> + concatenate the strings using this string as a delimiter. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">seq</span> + a table of strings or numbers + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">(<span class="string">' '</span>):join {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} == <span class="string">'1 2 3'</span></pre> + </ul> + +</dd> + <dt> + <a name = "splitlines"></a> + <strong>splitlines (s[, keep_ends])</strong> + </dt> + <dd> + Split a string into a list of lines. + <code>"\r"</code>, <code>"\n"</code>, and <code>"\r\n"</code> are considered line ends. + They are not included in the lines unless <code>keepends</code> is passed. + Terminal line end does not produce an extra line. + Splitting an empty string results in an empty list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string. + </li> + <li><span class="parameter">keep_ends</span> + <span class="types"><span class="type">bool</span></span> + include line ends. + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "split"></a> + <strong>split (s[, re[, n]])</strong> + </dt> + <dd> + split a string into a list of strings using a delimiter. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">re</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a delimiter (defaults to whitespace) + (<em>optional</em>) + </li> + <li><span class="parameter">n</span> + <span class="types"><span class="type">int</span></span> + maximum number of results + (<em>optional</em>) + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">#((<span class="string">'one two'</span>):split()) == <span class="number">2</span></pre></li> + <li><pre class="example">(<span class="string">'one,two,three'</span>):split(<span class="string">','</span>) == List{<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>}</pre></li> + <li><pre class="example">(<span class="string">'one,two,three'</span>):split(<span class="string">','</span>,<span class="number">2</span>) == List{<span class="string">'one'</span>,<span class="string">'two,three'</span>}</pre></li> + </ul> + +</dd> + <dt> + <a name = "expandtabs"></a> + <strong>expandtabs (s, tabsize)</strong> + </dt> + <dd> + replace all tabs in s with tabsize spaces. If not specified, tabsize defaults to 8. + with 0.9.5 this now correctly expands to the next tab stop (if you really + want to just replace tabs, use :gsub(‘\t’,‘ ’) etc) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">tabsize</span> + <span class="types"><span class="type">int</span></span> + [opt=8] number of spaces to expand each tab + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Finding_and_Replacing"></a>Finding and Replacing </h2> + + <dl class="function"> + <dt> + <a name = "lfind"></a> + <strong>lfind (s, sub[, first[, last]])</strong> + </dt> + <dd> + find index of first instance of sub in s from the left. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">sub</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + substring + </li> + <li><span class="parameter">first</span> + <span class="types"><span class="type">int</span></span> + first index + (<em>optional</em>) + </li> + <li><span class="parameter">last</span> + <span class="types"><span class="type">int</span></span> + last index + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "rfind"></a> + <strong>rfind (s, sub[, first[, last]])</strong> + </dt> + <dd> + find index of first instance of sub in s from the right. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">sub</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + substring + </li> + <li><span class="parameter">first</span> + <span class="types"><span class="type">int</span></span> + first index + (<em>optional</em>) + </li> + <li><span class="parameter">last</span> + <span class="types"><span class="type">int</span></span> + last index + (<em>optional</em>) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "replace"></a> + <strong>replace (s, old, new[, n])</strong> + </dt> + <dd> + replace up to n instances of old by new in the string s. + if n is not present, replace all instances. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">old</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the target substring + </li> + <li><span class="parameter">new</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the substitution + </li> + <li><span class="parameter">n</span> + <span class="types"><span class="type">int</span></span> + optional maximum number of substitutions + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + result string + </ol> + + + + +</dd> + <dt> + <a name = "count"></a> + <strong>count (s, sub)</strong> + </dt> + <dd> + count all instances of substring in string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">sub</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + substring + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Stripping_and_Justifying"></a>Stripping and Justifying </h2> + + <dl class="function"> + <dt> + <a name = "ljust"></a> + <strong>ljust (s, w[, ch=' '])</strong> + </dt> + <dd> + left-justify s with width w. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">w</span> + <span class="types"><span class="type">int</span></span> + width of justification + </li> + <li><span class="parameter">ch</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + padding character + (<em>default</em> ' ') + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "rjust"></a> + <strong>rjust (s, w[, ch=' '])</strong> + </dt> + <dd> + right-justify s with width w. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">w</span> + <span class="types"><span class="type">int</span></span> + width of justification + </li> + <li><span class="parameter">ch</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + padding character + (<em>default</em> ' ') + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "center"></a> + <strong>center (s, w[, ch=' '])</strong> + </dt> + <dd> + center-justify s with width w. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">w</span> + <span class="types"><span class="type">int</span></span> + width of justification + </li> + <li><span class="parameter">ch</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + padding character + (<em>default</em> ' ') + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "lstrip"></a> + <strong>lstrip (s[, chrs='%s'])</strong> + </dt> + <dd> + trim any whitespace on the left of s. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">chrs</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + default any whitespace character, + but can be a string of characters to be trimmed + (<em>default</em> '%s') + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "rstrip"></a> + <strong>rstrip (s[, chrs='%s'])</strong> + </dt> + <dd> + trim any whitespace on the right of s. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">chrs</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + default any whitespace character, + but can be a string of characters to be trimmed + (<em>default</em> '%s') + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "strip"></a> + <strong>strip (s[, chrs='%s'])</strong> + </dt> + <dd> + trim any whitespace on both left and right of s. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">chrs</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + default any whitespace character, + but can be a string of characters to be trimmed + (<em>default</em> '%s') + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Partioning_Strings"></a>Partioning Strings </h2> + + <dl class="function"> + <dt> + <a name = "splitv"></a> + <strong>splitv (s[, re='%s'])</strong> + </dt> + <dd> + split a string using a pattern. Note that at least one value will be returned! + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">re</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a Lua string pattern (defaults to whitespace) + (<em>default</em> '%s') + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the parts of the string + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">a,b = line:splitv(<span class="string">'='</span>)</pre> + </ul> + +</dd> + <dt> + <a name = "partition"></a> + <strong>partition (s, ch)</strong> + </dt> + <dd> + partition the string using first occurance of a delimiter + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">ch</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + delimiter + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + part before ch</li> + <li> + ch</li> + <li> + part after ch</li> + </ol> + + + + +</dd> + <dt> + <a name = "rpartition"></a> + <strong>rpartition (s, ch)</strong> + </dt> + <dd> + partition the string p using last occurance of a delimiter + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">ch</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + delimiter + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + part before ch</li> + <li> + ch</li> + <li> + part after ch</li> + </ol> + + + + +</dd> + <dt> + <a name = "at"></a> + <strong>at (s, idx)</strong> + </dt> + <dd> + return the ‘character’ at the index. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">idx</span> + <span class="types"><span class="type">int</span></span> + an index (can be negative) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a substring of length 1 if successful, empty string otherwise. + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Miscelaneous"></a>Miscelaneous </h2> + + <dl class="function"> + <dt> + <a name = "lines"></a> + <strong>lines (s)</strong> + </dt> + <dd> + return an iterator over all lines in a string + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator + </ol> + + + + +</dd> + <dt> + <a name = "title"></a> + <strong>title (s)</strong> + </dt> + <dd> + iniital word letters uppercase (‘title case’). + Here ‘words’ mean chunks of non-space characters. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string with each word’s first letter uppercase + </ol> + + + + +</dd> + <dt> + <a name = "shorten"></a> + <strong>shorten (s, w, tail)</strong> + </dt> + <dd> + Return a shortened version of a string. + Fits string within w characters. Removed characters are marked with ellipsis. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">w</span> + <span class="types"><span class="type">int</span></span> + the maxinum size allowed + </li> + <li><span class="parameter">tail</span> + <span class="types"><span class="type">bool</span></span> + true if we want to show the end of the string (head otherwise) + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">(<span class="string">'1234567890'</span>):shorten(<span class="number">8</span>) == <span class="string">'12345...'</span></pre></li> + <li><pre class="example">(<span class="string">'1234567890'</span>):shorten(<span class="number">8</span>, <span class="keyword">true</span>) == <span class="string">'...67890'</span></pre></li> + <li><pre class="example">(<span class="string">'1234567890'</span>):shorten(<span class="number">20</span>) == <span class="string">'1234567890'</span></pre></li> + </ul> + +</dd> + <dt> + <a name = "quote_string"></a> + <strong>quote_string (s)</strong> + </dt> + <dd> + Quote the given string and preserve any control or escape characters, such that reloading the string in Lua returns the same result. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + The string to be quoted. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + The quoted string. + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.tablex.html b/docs/libraries/pl.tablex.html new file mode 100644 index 0000000..ded9185 --- /dev/null +++ b/docs/libraries/pl.tablex.html @@ -0,0 +1,1895 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +<li><a href="#Copying">Copying</a></li> +<li><a href="#Comparing">Comparing</a></li> +<li><a href="#Finding">Finding</a></li> +<li><a href="#MappingAndFiltering">MappingAndFiltering</a></li> +<li><a href="#Iterating">Iterating</a></li> +<li><a href="#Extraction">Extraction</a></li> +<li><a href="#Merging">Merging</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><strong>pl.tablex</strong></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.tablex</code></h1> +<p>Extended operations on Lua tables.</p> +<p> See <a href="../manual/02-arrays.md.html#Useful_Operations_on_Tables">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.types.html#">pl.types</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#size">size (t)</a></td> + <td class="summary">total number of elements in this table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#index_by">index_by (tbl, idx)</a></td> + <td class="summary">return a list of all values in a table indexed by another list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#transform">transform (fun, t, ...)</a></td> + <td class="summary">apply a function to all values of a table, in-place.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#range">range (start, finish[, step=1])</a></td> + <td class="summary">generate a table of all numbers in a range.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#reduce">reduce (fun, t, memo)</a></td> + <td class="summary">‘reduce’ a list using a binary function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#index_map">index_map (t)</a></td> + <td class="summary">create an index map from a list-like table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#makeset">makeset (t)</a></td> + <td class="summary">create a set from a list-like table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#union">union (t1, t2)</a></td> + <td class="summary">the union of two map-like tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#intersection">intersection (t1, t2)</a></td> + <td class="summary">the intersection of two map-like tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#count_map">count_map (t, cmp)</a></td> + <td class="summary">A table where the key/values are the values and value counts of the table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#set">set (t, val[, i1=1[, i2=#t]])</a></td> + <td class="summary">set an array range to a value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#new">new (n, val)</a></td> + <td class="summary">create a new array of specified size with initial value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#clear">clear (t, istart)</a></td> + <td class="summary">clear out the contents of a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#removevalues">removevalues (t, i1, i2)</a></td> + <td class="summary">remove a range of values from a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#readonly">readonly (t)</a></td> + <td class="summary">modifies a table to be read only.</td> + </tr> +</table> +<h2><a href="#Copying">Copying</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#update">update (t1, t2)</a></td> + <td class="summary">copy a table into another, in-place.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#copy">copy (t)</a></td> + <td class="summary">make a shallow copy of a table</td> + </tr> + <tr> + <td class="name" nowrap><a href="#deepcopy">deepcopy (t)</a></td> + <td class="summary">make a deep copy of a table, recursively copying all the keys and fields.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#icopy">icopy (dest, src[, idest=1[, isrc=1[, nsrc=#src]]])</a></td> + <td class="summary">copy an array into another one, clearing <code>dest</code> after <code>idest+nsrc</code>, if necessary.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#move">move (dest, src[, idest=1[, isrc=1[, nsrc=#src]]])</a></td> + <td class="summary">copy an array into another one.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#insertvalues">insertvalues (t[, position], values)</a></td> + <td class="summary">insert values into a table.</td> + </tr> +</table> +<h2><a href="#Comparing">Comparing</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#deepcompare">deepcompare (t1, t2[, ignore_mt[, eps]])</a></td> + <td class="summary">compare two values.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#compare">compare (t1, t2, cmp)</a></td> + <td class="summary">compare two arrays using a predicate.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#compare_no_order">compare_no_order (t1, t2, cmp)</a></td> + <td class="summary">compare two list-like tables using an optional predicate, without regard for element order.</td> + </tr> +</table> +<h2><a href="#Finding">Finding</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#find">find (t, val, idx)</a></td> + <td class="summary">return the index of a value in a list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#rfind">rfind (t, val, idx)</a></td> + <td class="summary">return the index of a value in a list, searching from the end.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#find_if">find_if (t, cmp, arg)</a></td> + <td class="summary">return the index (or key) of a value in a table using a comparison function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#search">search (t, value[, exclude])</a></td> + <td class="summary">find a value in a table by recursive search.</td> + </tr> +</table> +<h2><a href="#MappingAndFiltering">MappingAndFiltering</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#map">map (fun, t, ...)</a></td> + <td class="summary">apply a function to all values of a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#imap">imap (fun, t, ...)</a></td> + <td class="summary">apply a function to all values of a list.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#map_named_method">map_named_method (name, t, ...)</a></td> + <td class="summary">apply a named method to values from a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#map2">map2 (fun, t1, t2, ...)</a></td> + <td class="summary">apply a function to values from two tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#imap2">imap2 (fun, t1, t2, ...)</a></td> + <td class="summary">apply a function to values from two arrays.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#mapn">mapn (fun, ..., fun)</a></td> + <td class="summary">Apply a function to a number of tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#pairmap">pairmap (fun, t, ...)</a></td> + <td class="summary">call the function with the key and value pairs from a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#filter">filter (t, pred, arg)</a></td> + <td class="summary">filter an array’s values using a predicate function</td> + </tr> +</table> +<h2><a href="#Iterating">Iterating</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#foreach">foreach (t, fun, ...)</a></td> + <td class="summary">apply a function to all elements of a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#foreachi">foreachi (t, fun, ...)</a></td> + <td class="summary">apply a function to all elements of a list-like table in order.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sort">sort (t, f)</a></td> + <td class="summary">return an iterator to a table sorted by its keys</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sortv">sortv (t, f)</a></td> + <td class="summary">return an iterator to a table sorted by its values</td> + </tr> +</table> +<h2><a href="#Extraction">Extraction</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#keys">keys (t)</a></td> + <td class="summary">return all the keys of a table in arbitrary order.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#values">values (t)</a></td> + <td class="summary">return all the values of the table in arbitrary order</td> + </tr> + <tr> + <td class="name" nowrap><a href="#sub">sub (t, first, last)</a></td> + <td class="summary">Extract a range from a table, like ‘string.sub’.</td> + </tr> +</table> +<h2><a href="#Merging">Merging</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#merge">merge (t1, t2, dup)</a></td> + <td class="summary">combine two tables, either as union or intersection.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#difference">difference (s1, s2, symm)</a></td> + <td class="summary">a new table which is the difference of two tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#zip">zip (...)</a></td> + <td class="summary">return a table where each element is a table of the ith values of an arbitrary + number of tables.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "size"></a> + <strong>size (t)</strong> + </dt> + <dd> + total number of elements in this table. + Note that this is distinct from <code>#t</code>, which is the number + of values in the array part; this value will always + be greater or equal. The difference gives the size of + the hash part, for practical purposes. Works for any + object with a __pairs metamethod. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the size + </ol> + + + + +</dd> + <dt> + <a name = "index_by"></a> + <strong>index_by (tbl, idx)</strong> + </dt> + <dd> + return a list of all values in a table indexed by another list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tbl</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">idx</span> + <span class="types"><span class="type">array</span></span> + an index table (a list of keys) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list-like table + </ol> + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">index_by({<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>},{<span class="number">2</span>,<span class="number">4</span>}) == {<span class="number">20</span>,<span class="number">40</span>}</pre></li> + <li><pre class="example">index_by({one=<span class="number">1</span>,two=<span class="number">2</span>,three=<span class="number">3</span>},{<span class="string">'one'</span>,<span class="string">'three'</span>}) == {<span class="number">1</span>,<span class="number">3</span>}</pre></li> + </ul> + +</dd> + <dt> + <a name = "transform"></a> + <strong>transform (fun, t, ...)</strong> + </dt> + <dd> + apply a function to all values of a table, in-place. + Any extra arguments are passed to the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + A function that takes at least one argument + </li> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">...</span> + extra arguments + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "range"></a> + <strong>range (start, finish[, step=1])</strong> + </dt> + <dd> + generate a table of all numbers in a range. + This is consistent with a numerical for loop. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">start</span> + <span class="types"><span class="type">int</span></span> + number + </li> + <li><span class="parameter">finish</span> + <span class="types"><span class="type">int</span></span> + number + </li> + <li><span class="parameter">step</span> + <span class="types"><span class="type">int</span></span> + make this negative for start < finish + (<em>default</em> 1) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "reduce"></a> + <strong>reduce (fun, t, memo)</strong> + </dt> + <dd> + ‘reduce’ a list using a binary function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of two arguments + </li> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">memo</span> + <span class="types"><span class="type">array</span></span> + optional initial memo value. Defaults to first value in table. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the result of the function + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">reduce(<span class="string">'+'</span>,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) == <span class="number">10</span></pre> + </ul> + +</dd> + <dt> + <a name = "index_map"></a> + <strong>index_map (t)</strong> + </dt> + <dd> + create an index map from a list-like table. The original values become keys, + and the associated values are the indices into the original list. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a map-like table + </ol> + + + + +</dd> + <dt> + <a name = "makeset"></a> + <strong>makeset (t)</strong> + </dt> + <dd> + create a set from a list-like table. A set is a table where the original values + become keys, and the associated values are all true. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a set (a map-like table) + </ol> + + + + +</dd> + <dt> + <a name = "union"></a> + <strong>union (t1, t2)</strong> + </dt> + <dd> + the union of two map-like tables. + If there are duplicate keys, the second table wins. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><span class="type">tab</span></span> + + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#merge">tablex.merge</a> + </ul> + + +</dd> + <dt> + <a name = "intersection"></a> + <strong>intersection (t1, t2)</strong> + </dt> + <dd> + the intersection of two map-like tables. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <span class="types"><span class="type">tab</span></span> + + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#merge">tablex.merge</a> + </ul> + + +</dd> + <dt> + <a name = "count_map"></a> + <strong>count_map (t, cmp)</strong> + </dt> + <dd> + A table where the key/values are the values and value counts of the table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">cmp</span> + <span class="types"><span class="type">func</span></span> + a function that defines equality (otherwise uses ==) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a map-like table + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.seq.html#count_map">seq.count_map</a> + </ul> + + +</dd> + <dt> + <a name = "set"></a> + <strong>set (t, val[, i1=1[, i2=#t]])</strong> + </dt> + <dd> + set an array range to a value. If it’s a function we use the result + of applying it to the indices. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">val</span> + a value + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start range + (<em>default</em> 1) + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end range + (<em>default</em> #t) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "new"></a> + <strong>new (n, val)</strong> + </dt> + <dd> + create a new array of specified size with initial value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">n</span> + <span class="types"><span class="type">int</span></span> + size + </li> + <li><span class="parameter">val</span> + initial value (can be <code>nil</code>, but don’t expect <code>#</code> to work!) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the table + </ol> + + + + +</dd> + <dt> + <a name = "clear"></a> + <strong>clear (t, istart)</strong> + </dt> + <dd> + clear out the contents of a table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list + </li> + <li><span class="parameter">istart</span> + optional start position + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "removevalues"></a> + <strong>removevalues (t, i1, i2)</strong> + </dt> + <dd> + remove a range of values from a table. + End of range may be negative. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">i1</span> + <span class="types"><span class="type">int</span></span> + start index + </li> + <li><span class="parameter">i2</span> + <span class="types"><span class="type">int</span></span> + end index + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the table + </ol> + + + + +</dd> + <dt> + <a name = "readonly"></a> + <strong>readonly (t)</strong> + </dt> + <dd> + modifies a table to be read only. + This only offers weak protection. Tables can still be modified with + <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.insert">table.insert</a> and <a href="https://www.lua.org/manual/5.1/manual.html#pdf-rawset">rawset</a>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + the table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the table read only. + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Copying"></a>Copying</h2> + + <dl class="function"> + <dt> + <a name = "update"></a> + <strong>update (t1, t2)</strong> + </dt> + <dd> + copy a table into another, in-place. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">tab</span></span> + destination table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">tab</span></span> + source (actually any iterable object) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + first table + </ol> + + + + +</dd> + <dt> + <a name = "copy"></a> + <strong>copy (t)</strong> + </dt> + <dd> + make a shallow copy of a table + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + an iterable source + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + new table + </ol> + + + + +</dd> + <dt> + <a name = "deepcopy"></a> + <strong>deepcopy (t)</strong> + </dt> + <dd> + make a deep copy of a table, recursively copying all the keys and fields. + This supports cycles in tables; cycles will be reproduced in the copy. + This will also set the copied table’s metatable to that of the original. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + A table + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + new table + </ol> + + + + +</dd> + <dt> + <a name = "icopy"></a> + <strong>icopy (dest, src[, idest=1[, isrc=1[, nsrc=#src]]])</strong> + </dt> + <dd> + copy an array into another one, clearing <code>dest</code> after <code>idest+nsrc</code>, if necessary. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">dest</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">src</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">idest</span> + <span class="types"><span class="type">int</span></span> + where to start copying values into destination + (<em>default</em> 1) + </li> + <li><span class="parameter">isrc</span> + <span class="types"><span class="type">int</span></span> + where to start copying values from source + (<em>default</em> 1) + </li> + <li><span class="parameter">nsrc</span> + <span class="types"><span class="type">int</span></span> + number of elements to copy from source + (<em>default</em> #src) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "move"></a> + <strong>move (dest, src[, idest=1[, isrc=1[, nsrc=#src]]])</strong> + </dt> + <dd> + copy an array into another one. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">dest</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">src</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">idest</span> + <span class="types"><span class="type">int</span></span> + where to start copying values into destination + (<em>default</em> 1) + </li> + <li><span class="parameter">isrc</span> + <span class="types"><span class="type">int</span></span> + where to start copying values from source + (<em>default</em> 1) + </li> + <li><span class="parameter">nsrc</span> + <span class="types"><span class="type">int</span></span> + number of elements to copy from source + (<em>default</em> #src) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "insertvalues"></a> + <strong>insertvalues (t[, position], values)</strong> + </dt> + <dd> + insert values into a table. + similar to <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.insert">table.insert</a> but inserts values from given table <a href="../libraries/pl.tablex.html#values">values</a>, + not the object itself, into table <code>t</code> at position <code>pos</code>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + the list + </li> + <li><span class="parameter">position</span> + <span class="types"><span class="type">int</span></span> + (default is at end) + (<em>optional</em>) + </li> + <li><span class="parameter">values</span> + <span class="types"><span class="type">array</span></span> + + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Comparing"></a>Comparing</h2> + + <dl class="function"> + <dt> + <a name = "deepcompare"></a> + <strong>deepcompare (t1, t2[, ignore_mt[, eps]])</strong> + </dt> + <dd> + compare two values. + if they are tables, then compare their keys and fields recursively. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + A value + </li> + <li><span class="parameter">t2</span> + A value + </li> + <li><span class="parameter">ignore_mt</span> + <span class="types"><span class="type">bool</span></span> + if true, ignore __eq metamethod (default false) + (<em>optional</em>) + </li> + <li><span class="parameter">eps</span> + <span class="types"><span class="type">number</span></span> + if defined, then used for any number comparisons + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true or false + </ol> + + + + +</dd> + <dt> + <a name = "compare"></a> + <strong>compare (t1, t2, cmp)</strong> + </dt> + <dd> + compare two arrays using a predicate. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">array</span></span> + an array + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">array</span></span> + an array + </li> + <li><span class="parameter">cmp</span> + <span class="types"><span class="type">func</span></span> + A comparison function + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "compare_no_order"></a> + <strong>compare_no_order (t1, t2, cmp)</strong> + </dt> + <dd> + compare two list-like tables using an optional predicate, without regard for element order. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">cmp</span> + A comparison function (may be nil) + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Finding"></a>Finding</h2> + + <dl class="function"> + <dt> + <a name = "find"></a> + <strong>find (t, val, idx)</strong> + </dt> + <dd> + return the index of a value in a list. + Like string.find, there is an optional index to start searching, + which can be negative. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + A list-like table + </li> + <li><span class="parameter">val</span> + A value + </li> + <li><span class="parameter">idx</span> + <span class="types"><span class="type">int</span></span> + index to start; -1 means last element,etc (default 1) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + index of value or nil if not found + </ol> + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">find({<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>},<span class="number">20</span>) == <span class="number">2</span></pre></li> + <li><pre class="example">find({<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'a'</span>,<span class="string">'c'</span>},<span class="string">'a'</span>,<span class="number">2</span>) == <span class="number">3</span></pre></li> + </ul> + +</dd> + <dt> + <a name = "rfind"></a> + <strong>rfind (t, val, idx)</strong> + </dt> + <dd> + return the index of a value in a list, searching from the end. + Like string.find, there is an optional index to start searching, + which can be negative. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + A list-like table + </li> + <li><span class="parameter">val</span> + A value + </li> + <li><span class="parameter">idx</span> + index to start; -1 means last element,etc (default 1) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + index of value or nil if not found + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">rfind({<span class="number">10</span>,<span class="number">10</span>,<span class="number">10</span>},<span class="number">10</span>) == <span class="number">3</span></pre> + </ul> + +</dd> + <dt> + <a name = "find_if"></a> + <strong>find_if (t, cmp, arg)</strong> + </dt> + <dd> + return the index (or key) of a value in a table using a comparison function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + A table + </li> + <li><span class="parameter">cmp</span> + <span class="types"><span class="type">func</span></span> + A comparison function + </li> + <li><span class="parameter">arg</span> + an optional second argument to the function + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + index of value, or nil if not found</li> + <li> + value returned by comparison function</li> + </ol> + + + + +</dd> + <dt> + <a name = "search"></a> + <strong>search (t, value[, exclude])</strong> + </dt> + <dd> + find a value in a table by recursive search. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + the table + </li> + <li><span class="parameter">value</span> + the value + </li> + <li><span class="parameter">exclude</span> + <span class="types"><span class="type">array</span></span> + any tables to avoid searching + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a fieldspec, e.g. ‘a.b’ or ‘math.sin’ + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">search(_G,<span class="global">math</span>.sin,{<span class="global">package</span>.path}) == <span class="string">'math.sin'</span></pre> + </ul> + +</dd> +</dl> + <h2 class="section-header "><a name="MappingAndFiltering"></a>MappingAndFiltering</h2> + + <dl class="function"> + <dt> + <a name = "map"></a> + <strong>map (fun, t, ...)</strong> + </dt> + <dd> + apply a function to all values of a table. + This returns a table of the results. + Any extra arguments are passed to the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + A function that takes at least one argument + </li> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + A table + </li> + <li><span class="parameter">...</span> + optional arguments + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">map(<span class="keyword">function</span>(v) <span class="keyword">return</span> v*v <span class="keyword">end</span>, {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,fred=<span class="number">2</span>}) is {<span class="number">100</span>,<span class="number">400</span>,<span class="number">900</span>,fred=<span class="number">4</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "imap"></a> + <strong>imap (fun, t, ...)</strong> + </dt> + <dd> + apply a function to all values of a list. + This returns a table of the results. + Any extra arguments are passed to the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + A function that takes at least one argument + </li> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a table (applies to array part) + </li> + <li><span class="parameter">...</span> + optional arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list-like table + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">imap(<span class="keyword">function</span>(v) <span class="keyword">return</span> v*v <span class="keyword">end</span>, {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,fred=<span class="number">2</span>}) is {<span class="number">100</span>,<span class="number">400</span>,<span class="number">900</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "map_named_method"></a> + <strong>map_named_method (name, t, ...)</strong> + </dt> + <dd> + apply a named method to values from a table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">name</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the method name + </li> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">...</span> + any extra arguments to the method + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "map2"></a> + <strong>map2 (fun, t1, t2, ...)</strong> + </dt> + <dd> + apply a function to values from two tables. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of at least two arguments + </li> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">...</span> + extra arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example">map2(<span class="string">'+'</span>,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,m=<span class="number">4</span>},{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,m=<span class="number">40</span>}) is {<span class="number">11</span>,<span class="number">22</span>,<span class="number">23</span>,m=<span class="number">44</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "imap2"></a> + <strong>imap2 (fun, t1, t2, ...)</strong> + </dt> + <dd> + apply a function to values from two arrays. + The result will be the length of the shortest array. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function of at least two arguments + </li> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">...</span> + extra arguments + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">imap2(<span class="string">'+'</span>,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,m=<span class="number">4</span>},{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,m=<span class="number">40</span>}) is {<span class="number">11</span>,<span class="number">22</span>,<span class="number">23</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "mapn"></a> + <strong>mapn (fun, ..., fun)</strong> + </dt> + <dd> + Apply a function to a number of tables. + A more general version of map + The result is a table containing the result of applying that function to the + ith value of each table. Length of output list is the minimum length of all the lists + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + A function that takes as many arguments as there are tables + </li> + <li><span class="parameter">...</span> + <span class="types"><span class="type">tab</span></span> + n tables + </li> + <li><span class="parameter">fun</span> + A function that takes as many arguments as there are tables + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">mapn(<span class="keyword">function</span>(x,y,z) <span class="keyword">return</span> x+y+z <span class="keyword">end</span>, {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>},{<span class="number">100</span>,<span class="number">200</span>,<span class="number">300</span>}) is {<span class="number">111</span>,<span class="number">222</span>,<span class="number">333</span>}</pre></li> + <li><pre class="example">mapn(<span class="global">math</span>.max, {<span class="number">1</span>,<span class="number">20</span>,<span class="number">300</span>},{<span class="number">10</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">100</span>,<span class="number">200</span>,<span class="number">100</span>}) is {<span class="number">100</span>,<span class="number">200</span>,<span class="number">300</span>}</pre></li> + </ul> + +</dd> + <dt> + <a name = "pairmap"></a> + <strong>pairmap (fun, t, ...)</strong> + </dt> + <dd> + call the function with the key and value pairs from a table. + The function can return a value and a key (note the order!). If both + are not nil, then this pair is inserted into the result: if the key already exists, we convert the value for that + key into a table and append into it. If only value is not nil, then it is appended to the result. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + A function which will be passed each key and value as arguments, plus any extra arguments to pairmap. + </li> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + A table + </li> + <li><span class="parameter">...</span> + optional arguments + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">pairmap(<span class="keyword">function</span>(k,v) <span class="keyword">return</span> v <span class="keyword">end</span>,{fred=<span class="number">10</span>,bonzo=<span class="number">20</span>}) is {<span class="number">10</span>,<span class="number">20</span>} _or_ {<span class="number">20</span>,<span class="number">10</span>}</pre></li> + <li><pre class="example">pairmap(<span class="keyword">function</span>(k,v) <span class="keyword">return</span> {k,v},k <span class="keyword">end</span>,{one=<span class="number">1</span>,two=<span class="number">2</span>}) is {one={<span class="string">'one'</span>,<span class="number">1</span>},two={<span class="string">'two'</span>,<span class="number">2</span>}}</pre></li> + </ul> + +</dd> + <dt> + <a name = "filter"></a> + <strong>filter (t, pred, arg)</strong> + </dt> + <dd> + filter an array’s values using a predicate function + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">pred</span> + <span class="types"><span class="type">func</span></span> + a boolean function + </li> + <li><span class="parameter">arg</span> + optional argument to be passed as second argument of the predicate + </li> + </ul> + + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Iterating"></a>Iterating</h2> + + <dl class="function"> + <dt> + <a name = "foreach"></a> + <strong>foreach (t, fun, ...)</strong> + </dt> + <dd> + apply a function to all elements of a table. + The arguments to the function will be the value, + the key and <em>finally</em> any extra arguments passed to this function. + Note that the Lua 5.0 function table.foreach passed the <em>key</em> first. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function with at least one argument + </li> + <li><span class="parameter">...</span> + extra arguments + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "foreachi"></a> + <strong>foreachi (t, fun, ...)</strong> + </dt> + <dd> + apply a function to all elements of a list-like table in order. + The arguments to the function will be the value, + the index and <em>finally</em> any extra arguments passed to this function + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a table + </li> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a function with at least one argument + </li> + <li><span class="parameter">...</span> + optional arguments + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "sort"></a> + <strong>sort (t, f)</strong> + </dt> + <dd> + return an iterator to a table sorted by its keys + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + the table + </li> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + an optional comparison function (f(x,y) is true if x < y) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator to traverse elements sorted by the keys + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">for</span> k,v <span class="keyword">in</span> tablex.sort(t) <span class="keyword">do</span> <span class="global">print</span>(k,v) <span class="keyword">end</span></pre> + </ul> + +</dd> + <dt> + <a name = "sortv"></a> + <strong>sortv (t, f)</strong> + </dt> + <dd> + return an iterator to a table sorted by its values + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + the table + </li> + <li><span class="parameter">f</span> + <span class="types"><span class="type">func</span></span> + an optional comparison function (f(x,y) is true if x < y) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an iterator to traverse elements sorted by the values + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">for</span> k,v <span class="keyword">in</span> tablex.sortv(t) <span class="keyword">do</span> <span class="global">print</span>(k,v) <span class="keyword">end</span></pre> + </ul> + +</dd> +</dl> + <h2 class="section-header "><a name="Extraction"></a>Extraction</h2> + + <dl class="function"> + <dt> + <a name = "keys"></a> + <strong>keys (t)</strong> + </dt> + <dd> + return all the keys of a table in arbitrary order. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + A table + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "values"></a> + <strong>values (t)</strong> + </dt> + <dd> + return all the values of the table in arbitrary order + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">tab</span></span> + A table + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "sub"></a> + <strong>sub (t, first, last)</strong> + </dt> + <dd> + Extract a range from a table, like ‘string.sub’. + If first or last are negative then they are relative to the end of the list + eg. sub(t,-2) gives last 2 entries in a list, and + sub(t,-4,-2) gives from -4th to -2nd + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + <span class="types"><span class="type">array</span></span> + a list-like table + </li> + <li><span class="parameter">first</span> + <span class="types"><span class="type">int</span></span> + An index + </li> + <li><span class="parameter">last</span> + <span class="types"><span class="type">int</span></span> + An index + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a new List + </ol> + + + + +</dd> +</dl> + <h2 class="section-header "><a name="Merging"></a>Merging</h2> + + <dl class="function"> + <dt> + <a name = "merge"></a> + <strong>merge (t1, t2, dup)</strong> + </dt> + <dd> + combine two tables, either as union or intersection. Corresponds to + set operations for sets () but more general. Not particularly + useful for list-like tables. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">t2</span> + <span class="types"><span class="type">tab</span></span> + a table + </li> + <li><span class="parameter">dup</span> + <span class="types"><span class="type">bool</span></span> + true for a union, false for an intersection. + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.tablex.html#index_map">tablex.index_map</a> + </ul> + + <h3>Usage:</h3> + <ul> + <li><pre class="example">merge({alice=<span class="number">23</span>,fred=<span class="number">34</span>},{bob=<span class="number">25</span>,fred=<span class="number">34</span>}) is {fred=<span class="number">34</span>}</pre></li> + <li><pre class="example">merge({alice=<span class="number">23</span>,fred=<span class="number">34</span>},{bob=<span class="number">25</span>,fred=<span class="number">34</span>},<span class="keyword">true</span>) is {bob=<span class="number">25</span>,fred=<span class="number">34</span>,alice=<span class="number">23</span>}</pre></li> + </ul> + +</dd> + <dt> + <a name = "difference"></a> + <strong>difference (s1, s2, symm)</strong> + </dt> + <dd> + a new table which is the difference of two tables. + With sets (where the values are all true) this is set difference and + symmetric difference depending on the third parameter. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s1</span> + <span class="types"><span class="type">tab</span></span> + a map-like table or set + </li> + <li><span class="parameter">s2</span> + <span class="types"><span class="type">tab</span></span> + a map-like table or set + </li> + <li><span class="parameter">symm</span> + <span class="types"><span class="type">bool</span></span> + symmetric difference (default false) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a map-like table or set + </ol> + + + + +</dd> + <dt> + <a name = "zip"></a> + <strong>zip (...)</strong> + </dt> + <dd> + return a table where each element is a table of the ith values of an arbitrary + number of tables. It is equivalent to a matrix transpose. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + <span class="types"><span class="type">array</span></span> + arrays to be zipped + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">zip({<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>},{<span class="number">100</span>,<span class="number">200</span>,<span class="number">300</span>}) is {{<span class="number">10</span>,<span class="number">100</span>},{<span class="number">20</span>,<span class="number">200</span>},{<span class="number">30</span>,<span class="number">300</span>}}</pre> + </ul> + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.template.html b/docs/libraries/pl.template.html new file mode 100644 index 0000000..0dcb1da --- /dev/null +++ b/docs/libraries/pl.template.html @@ -0,0 +1,334 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><strong>pl.template</strong></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.template</code></h1> +<p>A template preprocessor.</p> +<p> Originally by <a href="http://lua-users.org/wiki/SlightlyLessSimpleLuaPreprocessor">Ricki Lake</a></p> + +<p> There are two rules:</p> + +<ul> +<li>lines starting with # are Lua</li> +<li>otherwise, <code>$(expr)</code> is the result of evaluating <code>expr</code></li> +</ul> + + +<p> Example:</p> + +<pre> +# <span class="keyword">for</span> i = <span class="number">1</span>,<span class="number">3</span> <span class="keyword">do</span> + $(i) Hello, Word! +# <span class="keyword">end</span> +===> +<span class="number">1</span> Hello, Word! +<span class="number">2</span> Hello, Word! +<span class="number">3</span> Hello, Word! +</pre> + + +<p> Other escape characters can be used, when the defaults conflict + with the output language.</p> + +<pre> +> <span class="keyword">for</span> _,n <span class="keyword">in</span> <span class="global">pairs</span>{<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>} <span class="keyword">do</span> +static int l_${n} (luaState *state); +> <span class="keyword">end</span> +</pre> + + +<p> See <a href="../manual/03-strings.md.html#Another_Style_of_Template">the Guide</a>.</p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#substitute">substitute (str[, env])</a></td> + <td class="summary">expand the template using the specified environment.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#ct:render">ct:render ([env[, parent[, db]]])</a></td> + <td class="summary">executes the previously compiled template and renders it.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#compile">compile (str[, opts])</a></td> + <td class="summary">compiles the template.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "substitute"></a> + <strong>substitute (str[, env])</strong> + </dt> + <dd> + <p>expand the template using the specified environment. + This function will compile and render the template. For more performant + recurring usage use the two step approach by using <a href="../libraries/pl.template.html#compile">compile</a> and <a href="../libraries/pl.template.html#ct:render">ct:render</a>. + There are six special fields in the environment table <code>env</code></p> + +<ul> +<li> <code>_parent</code>: continue looking up in this table (e.g. <code>_parent=_G</code>).</li> +<li> <code>_brackets</code>: bracket pair that wraps inline Lua expressions, default is ‘()’.</li> +<li> <code>_escape</code>: character marking Lua lines, default is ‘#’</li> +<li> <code>_inline_escape</code>: character marking inline Lua expression, default is ‘$’.</li> +<li> <code>_chunk_name</code>: chunk name for loaded templates, used if there + is an error in Lua code. Default is ‘TMP’.</li> +<li> <code>_debug</code>: if truthy, the generated code will be printed upon a render error</li> +</ul> + + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">str</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the template string + </li> + <li><span class="parameter">env</span> + <span class="types"><span class="type">tab</span></span> + the environment + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <code>rendered template + nil + source_code</code>, or <code>nil + error + source_code</code>. The last + return value (<code>source_code</code>) is only returned if the debug option is used. + </ol> + + + + +</dd> + <dt> + <a name = "ct:render"></a> + <strong>ct:render ([env[, parent[, db]]])</strong> + </dt> + <dd> + executes the previously compiled template and renders it. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">env</span> + <span class="types"><span class="type">tab</span></span> + the environment. + (<em>optional</em>) + </li> + <li><span class="parameter">parent</span> + <span class="types"><span class="type">tab</span></span> + continue looking up in this table (e.g. <code>parent=_G</code>). + (<em>optional</em>) + </li> + <li><span class="parameter">db</span> + <span class="types"><span class="type">bool</span></span> + if thruthy, it will print the code upon a render error + (provided the template was compiled with the debug option). + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + <code>rendered template + nil + source_code</code>, or <code>nil + error + source_code</code>. The last return value + (<code>source_code</code>) is only returned if the template was compiled with the debug option. + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">local</span> ct, err = template.compile(my_template) +<span class="keyword">local</span> rendered , err = ct:render(my_env, parent)</pre> + </ul> + +</dd> + <dt> + <a name = "compile"></a> + <strong>compile (str[, opts])</strong> + </dt> + <dd> + <p>compiles the template. + Returns an object that can repeatedly be rendered without parsing/compiling + the template again. + The options passed in the <code>opts</code> table support the following options:</p> + +<ul> +<li> <code>chunk_name</code>: chunk name for loaded templates, used if there + is an error in Lua code. Default is ‘TMP’.</li> +<li> <code>escape</code>: character marking Lua lines, default is ‘#’</li> +<li> <code>inline_escape</code>: character marking inline Lua expression, default is ‘$’.</li> +<li> <code>inline_brackets</code>: bracket pair that wraps inline Lua expressions, default is ‘()’.</li> +<li> <code>newline</code>: string to replace newline characters, default is <code>nil</code> (not replacing newlines).</li> +<li> <a href="https://www.lua.org/manual/5.1/manual.html#5.9">debug</a>: if truthy, the generated source code will be retained within the compiled template object, default is <code>nil</code>.</li> +</ul> + + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">str</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the template string + </li> + <li><span class="parameter">opts</span> + <span class="types"><span class="type">tab</span></span> + the compilation options to use + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + template object, or <code>nil + error + source_code</code> + </ol> + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">local</span> ct, err = template.compile(my_template) +<span class="keyword">local</span> rendered , err = ct:render(my_env, parent)</pre> + </ul> + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.test.html b/docs/libraries/pl.test.html new file mode 100644 index 0000000..3719fd8 --- /dev/null +++ b/docs/libraries/pl.test.html @@ -0,0 +1,432 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><strong>pl.test</strong></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.test</code></h1> +<p>Useful test utilities.</p> +<p> + +<pre> +test.asserteq({<span class="number">1</span>,<span class="number">2</span>},{<span class="number">1</span>,<span class="number">2</span>}) <span class="comment">-- can compare tables +</span>test.asserteq(<span class="number">1.2</span>,<span class="number">1.19</span>,<span class="number">0.02</span>) <span class="comment">-- compare FP numbers within precision +</span>T = test.tuple <span class="comment">-- used for comparing multiple results +</span>test.asserteq(T(<span class="global">string</span>.find(<span class="string">" me"</span>,<span class="string">"me"</span>)),T(<span class="number">2</span>,<span class="number">3</span>)) +</pre> + + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.tablex.html#">pl.tablex</a>, <a href="../libraries/pl.pretty.html#">pl.pretty</a>, <a href="../libraries/pl.path.html#">pl.path</a>, <a href="https://www.lua.org/manual/5.1/manual.html#5.9">debug</a></p></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#error_handler">error_handler (file, line, got_text, needed_text, msg)</a></td> + <td class="summary">error handling for test results.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#complain">complain (x, y, msg, where)</a></td> + <td class="summary">general test complain message.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#asserteq">asserteq (x, y, eps, where)</a></td> + <td class="summary">like assert, except takes two arguments that must be equal and can be tables.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#assertmatch">assertmatch (s1, s2, where)</a></td> + <td class="summary">assert that the first string matches the second.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#assertraise">assertraise (fn, e, where)</a></td> + <td class="summary">assert that the function raises a particular error.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#asserteq2">asserteq2 (x1, x2, y1, y2, where)</a></td> + <td class="summary">a version of asserteq that takes two pairs of values.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#tuple">tuple (...)</a></td> + <td class="summary">encode an arbitrary argument list as a tuple.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#timer">timer (msg, n, fun, ...)</a></td> + <td class="summary">Time a function.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "error_handler"></a> + <strong>error_handler (file, line, got_text, needed_text, msg)</strong> + </dt> + <dd> + error handling for test results. + By default, this writes to stderr and exits the program. + Re-define this function to raise an error and/or redirect output + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">file</span> + + </li> + <li><span class="parameter">line</span> + + </li> + <li><span class="parameter">got_text</span> + + </li> + <li><span class="parameter">needed_text</span> + + </li> + <li><span class="parameter">msg</span> + + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "complain"></a> + <strong>complain (x, y, msg, where)</strong> + </dt> + <dd> + general test complain message. + Useful for composing new test functions (see tests/tablex.lua for an example) + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + a value + </li> + <li><span class="parameter">y</span> + value to compare first value against + </li> + <li><span class="parameter">msg</span> + message + </li> + <li><span class="parameter">where</span> + extra level offset for errors + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "asserteq"></a> + <strong>asserteq (x, y, eps, where)</strong> + </dt> + <dd> + like assert, except takes two arguments that must be equal and can be tables. + If they are plain tables, it will use tablex.deepcompare. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + any value + </li> + <li><span class="parameter">y</span> + a value equal to x + </li> + <li><span class="parameter">eps</span> + an optional tolerance for numerical comparisons + </li> + <li><span class="parameter">where</span> + extra level offset + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "assertmatch"></a> + <strong>assertmatch (s1, s2, where)</strong> + </dt> + <dd> + assert that the first string matches the second. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s1</span> + a string + </li> + <li><span class="parameter">s2</span> + a string + </li> + <li><span class="parameter">where</span> + extra level offset + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "assertraise"></a> + <strong>assertraise (fn, e, where)</strong> + </dt> + <dd> + assert that the function raises a particular error. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + a function or a table of the form {function,arg1,…} + </li> + <li><span class="parameter">e</span> + a string to match the error against + </li> + <li><span class="parameter">where</span> + extra level offset + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "asserteq2"></a> + <strong>asserteq2 (x1, x2, y1, y2, where)</strong> + </dt> + <dd> + a version of asserteq that takes two pairs of values. + <code>x1==y1 and x2==y2</code> must be true. Useful for functions that naturally + return two values. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x1</span> + any value + </li> + <li><span class="parameter">x2</span> + any value + </li> + <li><span class="parameter">y1</span> + any value + </li> + <li><span class="parameter">y2</span> + any value + </li> + <li><span class="parameter">where</span> + extra level offset + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "tuple"></a> + <strong>tuple (...)</strong> + </dt> + <dd> + encode an arbitrary argument list as a tuple. + This can be used to compare to other argument lists, which is + very useful for testing functions which return a number of values. + Unlike regular array-like tables (‘sequences’) they may contain nils. + Tuples understand equality and know how to print themselves out. + The # operator is defined to be the size, irrespecive of any nils, + and there is an <a href="https://www.lua.org/manual/5.1/manual.html#pdf-unpack">unpack</a> method. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example">asserteq(tuple( (<span class="string">'ab'</span>):find <span class="string">'a'</span>), tuple(<span class="number">1</span>,<span class="number">1</span>))</pre> + </ul> + +</dd> + <dt> + <a name = "timer"></a> + <strong>timer (msg, n, fun, ...)</strong> + </dt> + <dd> + Time a function. Call the function a given number of times, and report the number of seconds taken, + together with a message. Any extra arguments will be passed to the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">msg</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + a descriptive message + </li> + <li><span class="parameter">n</span> + <span class="types"><span class="type">int</span></span> + number of times to call the function + </li> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + the function + </li> + <li><span class="parameter">...</span> + optional arguments to fun + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.text.html b/docs/libraries/pl.text.html new file mode 100644 index 0000000..360f7a9 --- /dev/null +++ b/docs/libraries/pl.text.html @@ -0,0 +1,378 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><strong>pl.text</strong></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.text</code></h1> +<p>Text processing utilities.</p> +<p> This provides a Template class (modeled after the same from the Python + libraries, see string.Template). It also provides similar functions to those + found in the textwrap module.</p> + +<p> See <a href="../manual/03-strings.md.html#String_Templates">the Guide</a>.</p> + +<p> Calling <code>text.format_operator()</code> overloads the % operator for strings to give Python/Ruby style formated output. + This is extended to also do template-like substitution for map-like data.</p> + +<pre> +> <span class="global">require</span> <span class="string">'pl.text'</span>.format_operator() +> = <span class="string">'%s = %5.3f'</span> % {<span class="string">'PI'</span>,<span class="global">math</span>.pi} +PI = <span class="number">3.142</span> +> = <span class="string">'$name = $value'</span> % {name=<span class="string">'dog'</span>,value=<span class="string">'Pluto'</span>} +dog = Pluto +</pre> + + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a>, <a href="../libraries/pl.types.html#">pl.types</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#indent">indent (s, n, ch)</a></td> + <td class="summary">indent a multiline string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#dedent">dedent (s)</a></td> + <td class="summary">dedent a multiline string by removing any initial indent.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#wrap">wrap (s, width)</a></td> + <td class="summary">format a paragraph into lines so that they fit into a line width.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#fill">fill (s, width)</a></td> + <td class="summary">format a paragraph so that it fits into a line width.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Template:substitute">Template:substitute (tbl)</a></td> + <td class="summary">substitute values into a template, throwing an error.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Template:safe_substitute">Template:safe_substitute (tbl)</a></td> + <td class="summary">substitute values into a template.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Template:indent_substitute">Template:indent_substitute (tbl)</a></td> + <td class="summary">substitute values into a template, preserving indentation.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "indent"></a> + <strong>indent (s, n, ch)</strong> + </dt> + <dd> + indent a multiline string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the string + </li> + <li><span class="parameter">n</span> + the size of the indent + </li> + <li><span class="parameter">ch</span> + the character to use when indenting (default ‘ ’) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + indented string + </ol> + + + + +</dd> + <dt> + <a name = "dedent"></a> + <strong>dedent (s)</strong> + </dt> + <dd> + dedent a multiline string by removing any initial indent. + useful when working with [[..]] strings. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the string + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string with initial indent zero. + </ol> + + + + +</dd> + <dt> + <a name = "wrap"></a> + <strong>wrap (s, width)</strong> + </dt> + <dd> + format a paragraph into lines so that they fit into a line width. + It will not break long words, so lines can be over the length + to that extent. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the string + </li> + <li><span class="parameter">width</span> + the margin width, default 70 + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list of lines + </ol> + + + + +</dd> + <dt> + <a name = "fill"></a> + <strong>fill (s, width)</strong> + </dt> + <dd> + format a paragraph so that it fits into a line width. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the string + </li> + <li><span class="parameter">width</span> + the margin width, default 70 + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.text.html#wrap">wrap</a> + </ul> + + +</dd> + <dt> + <a name = "Template:substitute"></a> + <strong>Template:substitute (tbl)</strong> + </dt> + <dd> + substitute values into a template, throwing an error. + This will throw an error if no name is found. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tbl</span> + a table of name-value pairs. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Template:safe_substitute"></a> + <strong>Template:safe_substitute (tbl)</strong> + </dt> + <dd> + substitute values into a template. + This version just passes unknown names through. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tbl</span> + a table of name-value pairs. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Template:indent_substitute"></a> + <strong>Template:indent_substitute (tbl)</strong> + </dt> + <dd> + substitute values into a template, preserving indentation. <br> + If the value is a multiline string <em>or</em> a template, it will insert + the lines at the correct indentation. <br> + Furthermore, if a template, then that template will be subsituted + using the same table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tbl</span> + a table of name-value pairs. + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.types.html b/docs/libraries/pl.types.html new file mode 100644 index 0000000..e4d0b9f --- /dev/null +++ b/docs/libraries/pl.types.html @@ -0,0 +1,412 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><strong>pl.types</strong></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.types</code></h1> +<p>Dealing with Detailed Type Information</p> +<p></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#is_callable">is_callable (obj)</a></td> + <td class="summary">is the object either a function or a callable object?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_type">is_type (obj, tp)</a></td> + <td class="summary">is the object of the specified type?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#type">type (obj)</a></td> + <td class="summary">a string representation of a type.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_integer">is_integer (x)</a></td> + <td class="summary">is this number an integer?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_empty">is_empty (o, ignore_spaces)</a></td> + <td class="summary">Check if the object is “empty”.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_indexable">is_indexable (val)</a></td> + <td class="summary">is an object ‘array-like’?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_iterable">is_iterable (val)</a></td> + <td class="summary">can an object be iterated over with <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pairs">pairs</a>?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_writeable">is_writeable (val)</a></td> + <td class="summary">can an object accept new key/pair values?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#to_bool">to_bool (o[, true_strs[, check_objs]])</a></td> + <td class="summary">Convert to a boolean value.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "is_callable"></a> + <strong>is_callable (obj)</strong> + </dt> + <dd> + is the object either a function or a callable object?. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">obj</span> + Object to check. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "is_type"></a> + <strong>is_type (obj, tp)</strong> + </dt> + <dd> + is the object of the specified type?. + If the type is a string, then use type, otherwise compare with metatable + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">obj</span> + An object to check + </li> + <li><span class="parameter">tp</span> + String of what type it should be + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "type"></a> + <strong>type (obj)</strong> + </dt> + <dd> + a string representation of a type. + For tables with metatables, we assume that the metatable has a <code>_name</code> + field. Knows about Lua file objects. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">obj</span> + an object + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string like ‘number’, ‘table’ or ‘List’ + </ol> + + + + +</dd> + <dt> + <a name = "is_integer"></a> + <strong>is_integer (x)</strong> + </dt> + <dd> + is this number an integer? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">x</span> + a number + </li> + </ul> + + + <h3>Raises:</h3> + error if x is not a number + + + +</dd> + <dt> + <a name = "is_empty"></a> + <strong>is_empty (o, ignore_spaces)</strong> + </dt> + <dd> + Check if the object is “empty”. + An object is considered empty if it is nil, a table with out any items (key, + value pairs or indexes), or a string with no content (“”). + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">o</span> + The object to check if it is empty. + </li> + <li><span class="parameter">ignore_spaces</span> + If the object is a string and this is true the string is + considered empty is it only contains spaces. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true if the object is empty, otherwise false. + </ol> + + + + +</dd> + <dt> + <a name = "is_indexable"></a> + <strong>is_indexable (val)</strong> + </dt> + <dd> + is an object ‘array-like’? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">val</span> + any value. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "is_iterable"></a> + <strong>is_iterable (val)</strong> + </dt> + <dd> + can an object be iterated over with <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pairs">pairs</a>? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">val</span> + any value. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "is_writeable"></a> + <strong>is_writeable (val)</strong> + </dt> + <dd> + can an object accept new key/pair values? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">val</span> + any value. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "to_bool"></a> + <strong>to_bool (o[, true_strs[, check_objs]])</strong> + </dt> + <dd> + <p>Convert to a boolean value. + True values are:</p> + +<ul> +<li>boolean: true.</li> +<li>string: ‘yes’, ‘y’, ‘true’, ’t', ‘1’ or additional strings specified by <code>true_strs</code>.</li> +<li>number: Any non-zero value.</li> +<li>table: Is not empty and <code>check_objs</code> is true.</li> +<li>object: Is not <code>nil</code> and <code>check_objs</code> is true.</li> +</ul> + + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">o</span> + The object to evaluate. + </li> + <li><span class="parameter">true_strs</span> + optional Additional strings that when matched should evaluate to true. Comparison is case insensitive. + This should be a List of strings. E.g. “ja” to support German. + (<em>optional</em>) + </li> + <li><span class="parameter">check_objs</span> + True if objects should be evaluated. Default is to evaluate objects as true if not nil + or if it is a table and it is not empty. + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + true if the input evaluates to true, otherwise false. + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.url.html b/docs/libraries/pl.url.html new file mode 100644 index 0000000..e95df60 --- /dev/null +++ b/docs/libraries/pl.url.html @@ -0,0 +1,201 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><strong>pl.url</strong></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.url</code></h1> +<p>Python-style URL quoting library.</p> +<p></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#quote">quote (s, quote_plus)</a></td> + <td class="summary">Quote the url, replacing special characters using the ‘%xx’ escape.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#unquote">unquote (s)</a></td> + <td class="summary">Unquote the url, replacing ‘%xx’ escapes and plus signs.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "quote"></a> + <strong>quote (s, quote_plus)</strong> + </dt> + <dd> + Quote the url, replacing special characters using the ‘%xx’ escape. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + <li><span class="parameter">quote_plus</span> + <span class="types"><span class="type">bool</span></span> + Also escape slashes and replace spaces by plus signs. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "unquote"></a> + <strong>unquote (s)</strong> + </dt> + <dd> + Unquote the url, replacing ‘%xx’ escapes and plus signs. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the string + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.utils.html b/docs/libraries/pl.utils.html new file mode 100644 index 0000000..28d0ed1 --- /dev/null +++ b/docs/libraries/pl.utils.html @@ -0,0 +1,1179 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><strong>pl.utils</strong></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.utils</code></h1> +<p>Generally useful routines.</p> +<p> See <a href="../manual/01-introduction.md.html#Generally_useful_functions_">the Guide</a>.</p> + +<p> Dependencies: <a href="../libraries/pl.compat.html#">pl.compat</a></p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#pack">pack (...)</a></td> + <td class="summary">pack an argument list into a table.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#unpack">unpack (t[, i[, t]])</a></td> + <td class="summary">unpack a table and return its contents.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#quit">quit (code, ...)</a></td> + <td class="summary">end this program gracefully.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#printf">printf (fmt, ...)</a></td> + <td class="summary">print an arbitrary number of arguments using a format.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#fprintf">fprintf (f, fmt, ...)</a></td> + <td class="summary">write an arbitrary number of arguments to a file using a format.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#import">import (t, T)</a></td> + <td class="summary">take a table and ‘inject’ it into the local namespace.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#escape">escape (s)</a></td> + <td class="summary">escape any ‘magic’ characters in a string</td> + </tr> + <tr> + <td class="name" nowrap><a href="#choose">choose (cond, value1, value2)</a></td> + <td class="summary">return either of two values, depending on a condition.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#readfile">readfile (filename, is_bin)</a></td> + <td class="summary">return the contents of a file as a string</td> + </tr> + <tr> + <td class="name" nowrap><a href="#writefile">writefile (filename, str, is_bin)</a></td> + <td class="summary">write a string to a file</td> + </tr> + <tr> + <td class="name" nowrap><a href="#readlines">readlines (filename)</a></td> + <td class="summary">return the contents of a file as a list of lines</td> + </tr> + <tr> + <td class="name" nowrap><a href="#split">split (s, re, plain, n)</a></td> + <td class="summary">split a string into a list of strings separated by a delimiter.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#splitv">splitv (s, re)</a></td> + <td class="summary">split a string into a number of values.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#array_tostring">array_tostring (t, temp, tostr)</a></td> + <td class="summary">convert an array of values to strings.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#quote_arg">quote_arg (argument)</a></td> + <td class="summary">Quote an argument of a command.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#executeex">executeex (cmd, bin)</a></td> + <td class="summary">execute a shell command and return the output.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#memoize">memoize (func)</a></td> + <td class="summary">‘memoize’ a function (cache returned value for next call).</td> + </tr> + <tr> + <td class="name" nowrap><a href="#add_function_factory">add_function_factory (mt, fun)</a></td> + <td class="summary">associate a function factory with a type.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#string_lambda">string_lambda (lf)</a></td> + <td class="summary">an anonymous function as a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#function_arg">function_arg (idx, f, msg)</a></td> + <td class="summary">process a function argument.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#bind1">bind1 (fn, p)</a></td> + <td class="summary">bind the first argument of the function to a value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#bind2">bind2 (fn, p)</a></td> + <td class="summary">bind the second argument of the function to a value.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#assert_arg">assert_arg (n, val, tp, verify, msg, lev)</a></td> + <td class="summary">assert that the given argument is in fact of the correct type.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#assert_string">assert_string (n, val)</a></td> + <td class="summary">assert the common case that the argument is a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#on_error">on_error (mode)</a></td> + <td class="summary">control the error strategy used by Penlight.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#raise">raise (err)</a></td> + <td class="summary">used by Penlight functions to return errors.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_type">is_type (obj, tp)</a></td> + <td class="summary">is the object of the specified type?.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#load">load (code, name, mode, env)</a></td> + <td class="summary">load a code string or bytecode chunk.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#getfenv">getfenv (f)</a></td> + <td class="summary">Get environment of a function.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#setfenv">setfenv (f, env)</a></td> + <td class="summary">Set environment of a function</td> + </tr> + <tr> + <td class="name" nowrap><a href="#execute">execute (cmd)</a></td> + <td class="summary">execute a shell command.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "pack"></a> + <strong>pack (...)</strong> + </dt> + <dd> + pack an argument list into a table. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">...</span> + any arguments + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a table with field n set to the length + </ol> + + + + +</dd> + <dt> + <a name = "unpack"></a> + <strong>unpack (t[, i[, t]])</strong> + </dt> + <dd> + unpack a table and return its contents. + NOTE: this implementation differs from the Lua implementation in the way + that this one DOES honor the n field in the table t, such that it is ‘nil-safe’. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + index of the last element to unpack, defaults to <code>t.n</code> or #t + (<em>optional</em>) + </li> + <li><span class="parameter">i</span> + index from which to start unpacking, defaults to 1 + (<em>optional</em>) + </li> + <li><span class="parameter">t</span> + index of the last element to unpack, defaults to <code>t.n</code> or #t + (<em>optional</em>) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + multiple returns values from the table + </ol> + + + + +</dd> + <dt> + <a name = "quit"></a> + <strong>quit (code, ...)</strong> + </dt> + <dd> + end this program gracefully. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">code</span> + The exit code or a message to be printed + </li> + <li><span class="parameter">...</span> + extra arguments for message’s format' + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.utils.html#fprintf">utils.fprintf</a> + </ul> + + +</dd> + <dt> + <a name = "printf"></a> + <strong>printf (fmt, ...)</strong> + </dt> + <dd> + print an arbitrary number of arguments using a format. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fmt</span> + The format (see string.format) + </li> + <li><span class="parameter">...</span> + Extra arguments for format + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "fprintf"></a> + <strong>fprintf (f, fmt, ...)</strong> + </dt> + <dd> + write an arbitrary number of arguments to a file using a format. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + File handle to write to. + </li> + <li><span class="parameter">fmt</span> + The format (see string.format). + </li> + <li><span class="parameter">...</span> + Extra arguments for format + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "import"></a> + <strong>import (t, T)</strong> + </dt> + <dd> + take a table and ‘inject’ it into the local namespace. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + The Table + </li> + <li><span class="parameter">T</span> + An optional destination table (defaults to callers environment) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "escape"></a> + <strong>escape (s)</strong> + </dt> + <dd> + escape any ‘magic’ characters in a string + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + The input string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "choose"></a> + <strong>choose (cond, value1, value2)</strong> + </dt> + <dd> + return either of two values, depending on a condition. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cond</span> + A condition + </li> + <li><span class="parameter">value1</span> + Value returned if cond is true + </li> + <li><span class="parameter">value2</span> + Value returned if cond is false (can be optional) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "readfile"></a> + <strong>readfile (filename, is_bin)</strong> + </dt> + <dd> + return the contents of a file as a string + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filename</span> + The file path + </li> + <li><span class="parameter">is_bin</span> + open in binary mode + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + file contents + </ol> + + + + +</dd> + <dt> + <a name = "writefile"></a> + <strong>writefile (filename, str, is_bin)</strong> + </dt> + <dd> + write a string to a file + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filename</span> + The file path + </li> + <li><span class="parameter">str</span> + The string + </li> + <li><span class="parameter">is_bin</span> + open in binary mode + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + true or nil</li> + <li> + error message</li> + </ol> + + <h3>Raises:</h3> + error if filename or str aren’t strings + + + +</dd> + <dt> + <a name = "readlines"></a> + <strong>readlines (filename)</strong> + </dt> + <dd> + return the contents of a file as a list of lines + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">filename</span> + The file path + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + file contents as a table + </ol> + + <h3>Raises:</h3> + errror if filename is not a string + + + +</dd> + <dt> + <a name = "split"></a> + <strong>split (s, re, plain, n)</strong> + </dt> + <dd> + split a string into a list of strings separated by a delimiter. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + The input string + </li> + <li><span class="parameter">re</span> + A Lua string pattern; defaults to ‘%s+’ + </li> + <li><span class="parameter">plain</span> + don’t use Lua patterns + </li> + <li><span class="parameter">n</span> + optional maximum number of splits + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list-like table + </ol> + + <h3>Raises:</h3> + error if s is not a string + + + +</dd> + <dt> + <a name = "splitv"></a> + <strong>splitv (s, re)</strong> + </dt> + <dd> + split a string into a number of values. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the string + </li> + <li><span class="parameter">re</span> + the delimiter, default space + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + n values + </ol> + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.utils.html#split">split</a> + </ul> + + <h3>Usage:</h3> + <ul> + <pre class="example">first,<span class="global">next</span> = splitv(<span class="string">'jane:doe'</span>,<span class="string">':'</span>)</pre> + </ul> + +</dd> + <dt> + <a name = "array_tostring"></a> + <strong>array_tostring (t, temp, tostr)</strong> + </dt> + <dd> + convert an array of values to strings. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + a list-like table + </li> + <li><span class="parameter">temp</span> + buffer to use, otherwise allocate + </li> + <li><span class="parameter">tostr</span> + custom tostring function, called with (value,index). + Otherwise use <a href="https://www.lua.org/manual/5.1/manual.html#pdf-tostring">tostring</a> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + the converted buffer + </ol> + + + + +</dd> + <dt> + <a name = "quote_arg"></a> + <strong>quote_arg (argument)</strong> + </dt> + <dd> + Quote an argument of a command. + Quotes a single argument of a command to be passed + to <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.execute">os.execute</a>, <a href="../libraries/pl.utils.html#execute">pl.utils.execute</a> or <a href="../libraries/pl.utils.html#executeex">pl.utils.executeex</a>. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">argument</span> + <span class="types"><a class="type" href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a></span> + the argument. + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + quoted argument. + </ol> + + + + +</dd> + <dt> + <a name = "executeex"></a> + <strong>executeex (cmd, bin)</strong> + </dt> + <dd> + execute a shell command and return the output. + This function redirects the output to tempfiles and returns the content of those files. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cmd</span> + a shell command + </li> + <li><span class="parameter">bin</span> + boolean, if true, read output as binary file + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + true if successful</li> + <li> + actual return code</li> + <li> + stdout output (string)</li> + <li> + errout output (string)</li> + </ol> + + + + +</dd> + <dt> + <a name = "memoize"></a> + <strong>memoize (func)</strong> + </dt> + <dd> + ‘memoize’ a function (cache returned value for next call). + This is useful if you have a function which is relatively expensive, + but you don’t know in advance what values will be required, so + building a table upfront is wasteful/impossible. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">func</span> + a function of at least one argument + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function with at least one argument, which is used as the key. + </ol> + + + + +</dd> + <dt> + <a name = "add_function_factory"></a> + <strong>add_function_factory (mt, fun)</strong> + </dt> + <dd> + associate a function factory with a type. + A function factory takes an object of the given type and + returns a function for evaluating it + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">mt</span> + <span class="types"><span class="type">tab</span></span> + metatable + </li> + <li><span class="parameter">fun</span> + <span class="types"><span class="type">func</span></span> + a callable that returns a function + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "string_lambda"></a> + <strong>string_lambda (lf)</strong> + </dt> + <dd> + an anonymous function as a string. This string is either of the form + ‘|args| expression’ or is a function of one argument, ‘_’ + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">lf</span> + function as a string + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function + </ol> + + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">string_lambda <span class="string">'|x|x+1'</span> (<span class="number">2</span>) == <span class="number">3</span></pre></li> + <li><pre class="example">string_lambda <span class="string">'_+1'</span> (<span class="number">2</span>) == <span class="number">3</span></pre></li> + </ul> + +</dd> + <dt> + <a name = "function_arg"></a> + <strong>function_arg (idx, f, msg)</strong> + </dt> + <dd> + process a function argument. + This is used throughout Penlight and defines what is meant by a function: + Something that is callable, or an operator string as defined by <code>pl.operator</code>, + such as ‘>’ or ‘#’. If a function factory has been registered for the type, it will + be called to get the function. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">idx</span> + argument index + </li> + <li><span class="parameter">f</span> + a function, operator string, or callable object + </li> + <li><span class="parameter">msg</span> + optional error message + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a callable + </ol> + + <h3>Raises:</h3> + if idx is not a number or if f is not callable + + + +</dd> + <dt> + <a name = "bind1"></a> + <strong>bind1 (fn, p)</strong> + </dt> + <dd> + bind the first argument of the function to a value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + a function of at least two values (may be an operator string) + </li> + <li><span class="parameter">p</span> + a value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function such that f(x) is fn(p,x) + </ol> + + <h3>Raises:</h3> + same as <a href="../libraries/pl.utils.html#function_arg">function_arg</a> + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.func.html#bind1">func.bind1</a> + </ul> + + +</dd> + <dt> + <a name = "bind2"></a> + <strong>bind2 (fn, p)</strong> + </dt> + <dd> + bind the second argument of the function to a value. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">fn</span> + a function of at least two values (may be an operator string) + </li> + <li><span class="parameter">p</span> + a value + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a function such that f(x) is fn(x,p) + </ol> + + <h3>Raises:</h3> + same as <a href="../libraries/pl.utils.html#function_arg">function_arg</a> + + + +</dd> + <dt> + <a name = "assert_arg"></a> + <strong>assert_arg (n, val, tp, verify, msg, lev)</strong> + </dt> + <dd> + assert that the given argument is in fact of the correct type. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">n</span> + argument index + </li> + <li><span class="parameter">val</span> + the value + </li> + <li><span class="parameter">tp</span> + the type + </li> + <li><span class="parameter">verify</span> + an optional verification function + </li> + <li><span class="parameter">msg</span> + an optional custom message + </li> + <li><span class="parameter">lev</span> + optional stack position for trace, default 2 + </li> + </ul> + + + <h3>Raises:</h3> + if the argument n is not the correct type + + + <h3>Usage:</h3> + <ul> + <li><pre class="example">assert_arg(<span class="number">1</span>,t,<span class="string">'table'</span>)</pre></li> + <li><pre class="example">assert_arg(n,val,<span class="string">'string'</span>,path.isdir,<span class="string">'not a directory'</span>)</pre></li> + </ul> + +</dd> + <dt> + <a name = "assert_string"></a> + <strong>assert_string (n, val)</strong> + </dt> + <dd> + assert the common case that the argument is a string. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">n</span> + argument index + </li> + <li><span class="parameter">val</span> + a value that must be a string + </li> + </ul> + + + <h3>Raises:</h3> + val must be a string + + + +</dd> + <dt> + <a name = "on_error"></a> + <strong>on_error (mode)</strong> + </dt> + <dd> + control the error strategy used by Penlight. + Controls how <code>utils.raise</code> works; the default is for it + to return nil and the error string, but if the mode is ‘error’ then + it will throw an error. If mode is ‘quit’ it will immediately terminate + the program. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">mode</span> + <ul> +<li>either ‘default’, ‘quit’ or ‘error’</li> +</ul> + + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.utils.html#raise">utils.raise</a> + </ul> + + +</dd> + <dt> + <a name = "raise"></a> + <strong>raise (err)</strong> + </dt> + <dd> + used by Penlight functions to return errors. Its global behaviour is controlled + by <code>utils.on_error</code> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">err</span> + the error string. + </li> + </ul> + + + + <h3>See also:</h3> + <ul> + <a href="../libraries/pl.utils.html#on_error">utils.on_error</a> + </ul> + + +</dd> + <dt> + <a name = "is_type"></a> + <strong>is_type (obj, tp)</strong> + </dt> + <dd> + is the object of the specified type?. + If the type is a string, then use type, otherwise compare with metatable + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">obj</span> + An object to check + </li> + <li><span class="parameter">tp</span> + String of what type it should be + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "load"></a> + <strong>load (code, name, mode, env)</strong> + </dt> + <dd> + load a code string or bytecode chunk. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">code</span> + Lua code as a string or bytecode + </li> + <li><span class="parameter">name</span> + for source errors + </li> + <li><span class="parameter">mode</span> + kind of chunk, ’t' for text, ‘b’ for bytecode, ‘bt’ for all (default) + </li> + <li><span class="parameter">env</span> + the environment for the new chunk (default nil) + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + compiled chunk</li> + <li> + error message (chunk is nil)</li> + </ol> + + + + +</dd> + <dt> + <a name = "getfenv"></a> + <strong>getfenv (f)</strong> + </dt> + <dd> + Get environment of a function. + With Lua 5.2, may return nil for a function with no global references! + Based on code by <a href="http://lua-users.org/lists/lua-l/2010-06/msg00313.html">Sergey Rozhenko</a> + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + a function or a call stack reference + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "setfenv"></a> + <strong>setfenv (f, env)</strong> + </dt> + <dd> + Set environment of a function + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">f</span> + a function or a call stack reference + </li> + <li><span class="parameter">env</span> + a table that becomes the new environment of <code>f</code> + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "execute"></a> + <strong>execute (cmd)</strong> + </dt> + <dd> + execute a shell command. + This is a compatibility function that returns the same for Lua 5.1 and Lua 5.2 + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">cmd</span> + a shell command + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + true if successful</li> + <li> + actual return code</li> + </ol> + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/libraries/pl.xml.html b/docs/libraries/pl.xml.html new file mode 100644 index 0000000..f1ac5d9 --- /dev/null +++ b/docs/libraries/pl.xml.html @@ -0,0 +1,836 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Functions">Functions</a></li> +</ul> + + +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><strong>pl.xml</strong></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + +<h1>Module <code>pl.xml</code></h1> +<p>XML LOM Utilities.</p> +<p> This implements some useful things on <a href="http://matthewwild.co.uk/projects/luaexpat/lom.html">LOM</a> documents, such as returned by <code>lxp.lom.parse</code>. + In particular, it can convert LOM back into XML text, with optional pretty-printing control. + It is s based on stanza.lua from <a href="http://hg.prosody.im/trunk/file/4621c92d2368/util/stanza.lua">Prosody</a></p> + +<pre> +> d = xml.parse <span class="string">"<nodes><node id='1'>alice</node></nodes>"</span> +> = d +<nodes><node id=<span class="string">'1'</span>>alice</node></nodes> +> = xml.<span class="global">tostring</span>(d,<span class="string">''</span>,<span class="string">' '</span>) +<nodes> + <node id=<span class="string">'1'</span>>alice</node> +</nodes> +</pre> + + +<p> Can be used as a lightweight one-stop-shop for simple XML processing; a simple XML parser is included + but the default is to use <code>lxp.lom</code> if it can be found. + <pre> + Prosody IM + Copyright © 2008-2010 Matthew Wild + Copyright © 2008-2010 Waqas Hussain– + classic Lua XML parser by Roberto Ierusalimschy. + modified to output LOM format. + http://lua-users.org/wiki/LuaXml + </pre> + See <a href="../manual/06-data.md.html#XML">the Guide</a></p> + +<p> Dependencies: <a href="../libraries/pl.utils.html#">pl.utils</a></p> + +<p> Soft Dependencies: <code>lxp.lom</code> (fallback is to use basic Lua parser)</p> + + +<h2><a href="#Functions">Functions</a></h2> +<table class="function_list"> + <tr> + <td class="name" nowrap><a href="#new">new (tag, attr)</a></td> + <td class="summary">create a new document node.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#parse">parse (text_or_file, is_file, use_basic)</a></td> + <td class="summary">parse an XML document.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:addtag">Doc:addtag (tag, attrs)</a></td> + <td class="summary">convenient function to add a document node, This updates the last inserted position.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:text">Doc:text (text)</a></td> + <td class="summary">convenient function to add a text node.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:up">Doc:up ()</a></td> + <td class="summary">go up one level in a document</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:add_direct_child">Doc:add_direct_child (child)</a></td> + <td class="summary">append a child to a document directly.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:add_child">Doc:add_child (child)</a></td> + <td class="summary">append a child to a document at the last element added</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:set_attribs">Doc:set_attribs (t)</a></td> + <td class="summary">set attributes of a document node.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:set_attrib">Doc:set_attrib (a, v)</a></td> + <td class="summary">set a single attribute of a document node.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:get_attribs">Doc:get_attribs ()</a></td> + <td class="summary">access the attributes of a document node.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#elem">elem (tag, items)</a></td> + <td class="summary">function to create an element with a given tag name and a set of children.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#tags">tags (list)</a></td> + <td class="summary">given a list of names, return a number of element constructors.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc.subst">Doc.subst (templ, data)</a></td> + <td class="summary">create a substituted copy of a document,</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:child_with_name">Doc:child_with_name (tag)</a></td> + <td class="summary">get the first child with a given tag name.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:get_elements_with_name">Doc:get_elements_with_name (tag, dont_recurse)</a></td> + <td class="summary">get all elements in a document that have a given tag.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:childtags">Doc:childtags ()</a></td> + <td class="summary">iterate over all child elements of a document node.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:maptags">Doc:maptags (callback)</a></td> + <td class="summary">visit child element of a node and call a function, possibility modifying the document.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#tostring">tostring (t, idn, indent, attr_indent, xml)</a></td> + <td class="summary">pretty-print an XML document</td> + </tr> + <tr> + <td class="name" nowrap><a href="#Doc:get_text">Doc:get_text ()</a></td> + <td class="summary">get the full text value of an element</td> + </tr> + <tr> + <td class="name" nowrap><a href="#clone">clone (doc, strsubst)</a></td> + <td class="summary">make a copy of a document</td> + </tr> + <tr> + <td class="name" nowrap><a href="#compare">compare (t1, t2)</a></td> + <td class="summary">compare two documents.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#is_tag">is_tag (d)</a></td> + <td class="summary">is this value a document element?</td> + </tr> + <tr> + <td class="name" nowrap><a href="#walk">walk (doc, depth_first, operation)</a></td> + <td class="summary">call the desired function recursively over the document.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#parsehtml">parsehtml (s)</a></td> + <td class="summary">Parse a well-formed HTML file as a string.</td> + </tr> + <tr> + <td class="name" nowrap><a href="#basic_parse">basic_parse (s, all_text, html)</a></td> + <td class="summary">Parse a simple XML document using a pure Lua parser based on Robero Ierusalimschy’s original version.</td> + </tr> +</table> + +<br/> +<br/> + + + <h2 class="section-header "><a name="Functions"></a>Functions</h2> + + <dl class="function"> + <dt> + <a name = "new"></a> + <strong>new (tag, attr)</strong> + </dt> + <dd> + create a new document node. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tag</span> + the tag name + </li> + <li><span class="parameter">attr</span> + optional attributes (table of name-value pairs) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "parse"></a> + <strong>parse (text_or_file, is_file, use_basic)</strong> + </dt> + <dd> + parse an XML document. By default, this uses lxp.lom.parse, but + falls back to basic_parse, or if use_basic is true + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">text_or_file</span> + file or string representation + </li> + <li><span class="parameter">is_file</span> + whether text_or_file is a file name or not + </li> + <li><span class="parameter">use_basic</span> + do a basic parse + </li> + </ul> + + <h3>Returns:</h3> + <ol> + <li> + a parsed LOM document with the document metatatables set</li> + <li> + nil, error the error can either be a file error or a parse error</li> + </ol> + + + + +</dd> + <dt> + <a name = "Doc:addtag"></a> + <strong>Doc:addtag (tag, attrs)</strong> + </dt> + <dd> + convenient function to add a document node, This updates the last inserted position. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tag</span> + a tag name + </li> + <li><span class="parameter">attrs</span> + optional set of attributes (name-string pairs) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:text"></a> + <strong>Doc:text (text)</strong> + </dt> + <dd> + convenient function to add a text node. This updates the last inserted position. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">text</span> + a string + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:up"></a> + <strong>Doc:up ()</strong> + </dt> + <dd> + go up one level in a document + + + + + + + +</dd> + <dt> + <a name = "Doc:add_direct_child"></a> + <strong>Doc:add_direct_child (child)</strong> + </dt> + <dd> + append a child to a document directly. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">child</span> + a child node (either text or a document) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:add_child"></a> + <strong>Doc:add_child (child)</strong> + </dt> + <dd> + append a child to a document at the last element added + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">child</span> + a child node (either text or a document) + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:set_attribs"></a> + <strong>Doc:set_attribs (t)</strong> + </dt> + <dd> + set attributes of a document node. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + a table containing attribute/value pairs + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:set_attrib"></a> + <strong>Doc:set_attrib (a, v)</strong> + </dt> + <dd> + set a single attribute of a document node. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">a</span> + attribute + </li> + <li><span class="parameter">v</span> + its value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:get_attribs"></a> + <strong>Doc:get_attribs ()</strong> + </dt> + <dd> + access the attributes of a document node. + + + + + + + +</dd> + <dt> + <a name = "elem"></a> + <strong>elem (tag, items)</strong> + </dt> + <dd> + function to create an element with a given tag name and a set of children. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tag</span> + a tag name + </li> + <li><span class="parameter">items</span> + either text or a table where the hash part is the attributes and the list part is the children. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "tags"></a> + <strong>tags (list)</strong> + </dt> + <dd> + given a list of names, return a number of element constructors. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">list</span> + a list of names, or a comma-separated string. + </li> + </ul> + + + + + <h3>Usage:</h3> + <ul> + <pre class="example"><span class="keyword">local</span> parent,children = doc.tags <span class="string">'parent,children'</span> <br> + doc = parent {child <span class="string">'one'</span>, child <span class="string">'two'</span>}</pre> + </ul> + +</dd> + <dt> + <a name = "Doc.subst"></a> + <strong>Doc.subst (templ, data)</strong> + </dt> + <dd> + create a substituted copy of a document, + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">templ</span> + may be a document or a string representation which will be parsed and cached + </li> + <li><span class="parameter">data</span> + a table of name-value pairs or a list of such tables + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + an XML document + </ol> + + + + +</dd> + <dt> + <a name = "Doc:child_with_name"></a> + <strong>Doc:child_with_name (tag)</strong> + </dt> + <dd> + get the first child with a given tag name. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tag</span> + the tag name + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "Doc:get_elements_with_name"></a> + <strong>Doc:get_elements_with_name (tag, dont_recurse)</strong> + </dt> + <dd> + get all elements in a document that have a given tag. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">tag</span> + a tag name + </li> + <li><span class="parameter">dont_recurse</span> + optionally only return the immediate children with this tag name + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a list of elements + </ol> + + + + +</dd> + <dt> + <a name = "Doc:childtags"></a> + <strong>Doc:childtags ()</strong> + </dt> + <dd> + iterate over all child elements of a document node. + + + + + + + +</dd> + <dt> + <a name = "Doc:maptags"></a> + <strong>Doc:maptags (callback)</strong> + </dt> + <dd> + visit child element of a node and call a function, possibility modifying the document. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">callback</span> + a function passed the node (text or element). If it returns nil, that node will be removed. + If it returns a value, that will replace the current node. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "tostring"></a> + <strong>tostring (t, idn, indent, attr_indent, xml)</strong> + </dt> + <dd> + pretty-print an XML document + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t</span> + an XML document + </li> + <li><span class="parameter">idn</span> + an initial indent (indents are all strings) + </li> + <li><span class="parameter">indent</span> + an indent for each level + </li> + <li><span class="parameter">attr_indent</span> + if given, indent each attribute pair and put on a separate line + </li> + <li><span class="parameter">xml</span> + force prefacing with default or custom <?xml…> + </li> + </ul> + + <h3>Returns:</h3> + <ol> + + a string representation + </ol> + + + + +</dd> + <dt> + <a name = "Doc:get_text"></a> + <strong>Doc:get_text ()</strong> + </dt> + <dd> + get the full text value of an element + + + + + + + +</dd> + <dt> + <a name = "clone"></a> + <strong>clone (doc, strsubst)</strong> + </dt> + <dd> + make a copy of a document + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">doc</span> + the original document + </li> + <li><span class="parameter">strsubst</span> + an optional function for handling string copying which could do substitution, etc. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "compare"></a> + <strong>compare (t1, t2)</strong> + </dt> + <dd> + compare two documents. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">t1</span> + any value + </li> + <li><span class="parameter">t2</span> + any value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "is_tag"></a> + <strong>is_tag (d)</strong> + </dt> + <dd> + is this value a document element? + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">d</span> + any value + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "walk"></a> + <strong>walk (doc, depth_first, operation)</strong> + </dt> + <dd> + call the desired function recursively over the document. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">doc</span> + the document + </li> + <li><span class="parameter">depth_first</span> + visit child notes first, then the current node + </li> + <li><span class="parameter">operation</span> + a function which will receive the current tag name and current node. + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "parsehtml"></a> + <strong>parsehtml (s)</strong> + </dt> + <dd> + Parse a well-formed HTML file as a string. + Tags are case-insenstive, DOCTYPE is ignored, and empty elements can be .. empty. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the HTML + </li> + </ul> + + + + + +</dd> + <dt> + <a name = "basic_parse"></a> + <strong>basic_parse (s, all_text, html)</strong> + </dt> + <dd> + Parse a simple XML document using a pure Lua parser based on Robero Ierusalimschy’s original version. + + + <h3>Parameters:</h3> + <ul> + <li><span class="parameter">s</span> + the XML document to be parsed. + </li> + <li><span class="parameter">all_text</span> + if true, preserves all whitespace. Otherwise only text containing non-whitespace is included. + </li> + <li><span class="parameter">html</span> + if true, uses relaxed HTML rules for parsing + </li> + </ul> + + + + + +</dd> +</dl> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/01-introduction.md.html b/docs/manual/01-introduction.md.html new file mode 100644 index 0000000..dbd2d62 --- /dev/null +++ b/docs/manual/01-introduction.md.html @@ -0,0 +1,845 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Purpose">Purpose </a></li> +<li><a href="#To_Inject_or_not_to_Inject_">To Inject or not to Inject? </a></li> +<li><a href="#What_are_function_arguments_in_Penlight_">What are function arguments in Penlight? </a></li> +<li><a href="#Pros_and_Cons_of_Loopless_Programming">Pros and Cons of Loopless Programming </a></li> +<li><a href="#Generally_useful_functions">Generally useful functions </a></li> +<li><a href="#Application_Support">Application Support </a></li> +<li><a href="#Simplifying_Object_Oriented_Programming_in_Lua">Simplifying Object-Oriented Programming in Lua </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><strong>Introduction</strong></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Introduction</h2> + +<p><a name="Purpose"></a></p> + +<h3>Purpose</h3> + +<p>It is often said of Lua that it does not include batteries. That is because the +goal of Lua is to produce a lean expressive language that will be used on all +sorts of machines, (some of which don’t even have hierarchical filesystems). The +Lua language is the equivalent of an operating system kernel; the creators of Lua +do not see it as their responsibility to create a full software ecosystem around +the language. That is the role of the community.</p> + +<p>A principle of software design is to recognize common patterns and reuse them. If +you find yourself writing things like <code>io.write(string.format('the answer is %d +',42))</code> more than a number of times then it becomes useful just to define a +function <code>printf</code>. This is good, not just because repeated code is harder to +maintain, but because such code is easier to read, once people understand your +libraries.</p> + +<p>Penlight captures many such code patterns, so that the intent of your code +becomes clearer. For instance, a Lua idiom to copy a table is <code>{unpack(t)}</code>, but +this will only work for ‘small’ tables (for a given value of ‘small’) so it is +not very robust. Also, the intent is not clear. So <a href="../libraries/pl.tablex.html#deepcopy">tablex.deepcopy</a> is provided, +which will also copy nested tables and and associated metatables, so it can be +used to clone complex objects.</p> + +<p>The default error handling policy follows that of the Lua standard libraries: if +a argument is the wrong type, then an error will be thrown, but otherwise we +return <code>nil,message</code> if there is a problem. There are some exceptions; functions +like <a href="../libraries/pl.input.html#fields">input.fields</a> default to shutting down the program immediately with a +useful message. This is more appropriate behaviour for a <em>script</em> than providing +a stack trace. (However, this default can be changed.) The lexer functions always +throw errors, to simplify coding, and so should be wrapped in <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pcall">pcall</a>.</p> + +<p>If you are used to Python conventions, please note that all indices consistently +start at 1.</p> + +<p>The Lua function <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.foreach">table.foreach</a> has been deprecated in favour of the <code>for in</code> +statement, but such an operation becomes particularly useful with the +higher-order function support in Penlight. Note that <a href="../libraries/pl.tablex.html#foreach">tablex.foreach</a> reverses +the order, so that the function is passed the value and then the key. Although +perverse, this matches the intended use better.</p> + +<p>The only important external dependence of Penlight is +<a href="http://keplerproject.github.com/luafilesystem/manual.html">LuaFileSystem</a> +(<a href="http://stevedonovan.github.io/lua-stdlibs/modules/lfs.html">lfs</a>), and if you want <a href="../libraries/pl.dir.html#copyfile">dir.copyfile</a> to work cleanly on Windows, you will need +either <a href="http://alien.luaforge.net/">alien</a> or be using +<a href="http://luajit.org">LuaJIT</a> as well. (The fallback is to call the equivalent +shell commands.)</p> + +<p><a name="To_Inject_or_not_to_Inject_"></a></p> + +<h3>To Inject or not to Inject?</h3> + +<p>It was realized a long time ago that large programs needed a way to keep names +distinct by putting them into tables (Lua), namespaces (C++) or modules +(Python). It is obviously impossible to run a company where everyone is called +‘Bruce’, except in Monty Python skits. These ‘namespace clashes’ are more of a +problem in a simple language like Lua than in C++, because C++ does more +complicated lookup over ‘injected namespaces’. However, in a small group of +friends, ‘Bruce’ is usually unique, so in particular situations it’s useful to +drop the formality and not use last names. It depends entirely on what kind of +program you are writing, whether it is a ten line script or a ten thousand line +program.</p> + +<p>So the Penlight library provides the formal way and the informal way, without +imposing any preference. You can do it formally like:</p> + +<pre> +<span class="keyword">local</span> utils = <span class="global">require</span> <span class="string">'pl.utils'</span> +utils.printf(<span class="string">"%s\n"</span>,<span class="string">"hello, world!"</span>) +</pre> + + +<p>or informally like:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +utils.printf(<span class="string">"%s\n"</span>,<span class="string">"That feels better"</span>) +</pre> + + +<p><code>require 'pl'</code> makes all the separate Penlight modules available, without needing +to require them each individually.</p> + +<p>Generally, the formal way is better when writing modules, since then there are no +global side-effects and the dependencies of your module are made explicit.</p> + +<p>Andrew Starks has contributed another way, which balances nicely between the +formal need to keep the global table uncluttered and the informal need for +convenience. <code>require'pl.import_into'</code> returns a function, which accepts a table +for injecting Penlight into, or if no table is given, it passes back a new one.</p> + +<pre> +<span class="keyword">local</span> pl = <span class="global">require</span><span class="string">'pl.import_into'</span>() +</pre> + + +<p>The table <a href="../libraries/pl.html#">pl</a> is a ‘lazy table’ which loads modules as needed, so we can then +use <a href="../libraries/pl.utils.html#printf">pl.utils.printf</a> and so forth, without an explicit `require' or harming any +globals.</p> + +<p>If you are using <code>_ENV</code> with Lua 5.2 to define modules, then here is a way to +make Penlight available within a module:</p> + +<pre> +<span class="keyword">local</span> _ENV,M = <span class="global">require</span> <span class="string">'pl.import_into'</span> () + +<span class="keyword">function</span> answer () + <span class="comment">-- all the Penlight modules are available! +</span> <span class="keyword">return</span> pretty.write(utils.split <span class="string">'10 20 30'</span>, <span class="string">''</span>) +<span class="keyword">end</span> + +<span class="keyword">return</span> M +</pre> + + +<p>The default is to put Penlight into <code>\<em>ENV</code>, which has the unintended effect of +making it available from the module (much as <code>module(…,package.seeall)</code> does). +To satisfy both convenience and safety, you may pass <code>true</code> to this function, and +then the </em>module<em> <code>M</code> is not the same as <code>\</em>ENV</code>, but only contains the exported +functions.</p> + +<p>Otherwise, Penlight will <em>not</em> bring in functions into the global table, or +clobber standard tables like ‘io’. require(‘pl’) will bring tables like +‘utils’,‘tablex’,etc into the global table <em>if they are used</em>. This +‘load-on-demand’ strategy ensures that the whole kitchen sink is not loaded up +front, so this method is as efficient as explicitly loading required modules.</p> + +<p>You have an option to bring the <a href="../libraries/pl.stringx.html#">pl.stringx</a> methods into the standard string +table. All strings have a metatable that allows for automatic lookup in <a href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a>, +so we can say <code>s:upper()</code>. Importing <a href="../libraries/pl.stringx.html#">stringx</a> allows for its functions to also +be called as methods: <code>s:strip()</code>,etc:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +stringx.import() +</pre> + + +<p>or, more explicitly:</p> + +<pre> +<span class="global">require</span>(<span class="string">'pl.stringx'</span>).import() +</pre> + + +<p>A more delicate operation is importing tables into the local environment. This is +convenient when the context makes the meaning of a name very clear:</p> + +<pre> +> <span class="global">require</span> <span class="string">'pl'</span> +> utils.import(<span class="global">math</span>) +> = sin(<span class="number">1.2</span>) +<span class="number">0.93203908596723</span> +</pre> + + +<p><a href="../libraries/pl.utils.html#import">utils.import</a> can also be passed a module name as a string, which is first +required and then imported. If used in a module, <code>import</code> will bring the symbols +into the module context.</p> + +<p>Keeping the global scope simple is very necessary with dynamic languages. Using +global variables in a big program is always asking for trouble, especially since +you do not have the spell-checking provided by a compiler. The <a href="../libraries/pl.strict.html#">pl.strict</a> +module enforces a simple rule: globals must be ‘declared’. This means that they +must be assigned before use; assigning to <code>nil</code> is sufficient.</p> + +<pre> +> <span class="global">require</span> <span class="string">'pl.strict'</span> +> <span class="global">print</span>(x) +stdin:<span class="number">1</span>: variable <span class="string">'x'</span> is <span class="keyword">not</span> declared +> x = <span class="keyword">nil</span> +> <span class="global">print</span>(x) +<span class="keyword">nil</span> +</pre> + + +<p>The <a href="../libraries/pl.strict.html#">strict</a> module provided by Penlight is compatible with the ‘load-on-demand’ +scheme used by <code>require 'pl</code>.</p> + +<p><a href="../libraries/pl.strict.html#">strict</a> also disallows assignment to global variables, except in the main +program. Generally, modules have no business messing with global scope; if you +must do it, then use a call to <a href="https://www.lua.org/manual/5.1/manual.html#pdf-rawset">rawset</a>. Similarly, if you have to check for the +existence of a global, use <a href="https://www.lua.org/manual/5.1/manual.html#pdf-rawget">rawget</a>.</p> + +<p>If you wish to enforce strictness globally, then just add <code>require 'pl.strict'</code> +at the end of <code>pl/init.lua</code>, otherwise call it from your main program.</p> + +<p>As from 1.1.0, this module provides a <a href="../libraries/pl.strict.html#module">strict.module</a> function which creates (or +modifies) modules so that accessing an unknown function or field causes an error.</p> + +<p>For example,</p> + +<pre> +<span class="comment">-- mymod.lua +</span><span class="keyword">local</span> strict = <span class="global">require</span> <span class="string">'pl.strict'</span> +<span class="keyword">local</span> M = strict.<span class="global">module</span> (...) + +<span class="keyword">function</span> M.answer () + <span class="keyword">return</span> <span class="number">42</span> +<span class="keyword">end</span> + +<span class="keyword">return</span> M +</pre> + + +<p>If you were to accidently type <code>mymod.Answer()</code>, then you would get a runtime +error: “variable ‘Answer’ is not declared in ‘mymod’”.</p> + +<p>This can be applied to existing modules. You may desire to have the same level +of checking for the Lua standard libraries:</p> + +<pre> +strict.make_all_strict(_G) +</pre> + + +<p>Thereafter a typo such as <code>math.cosine</code> will give you an explicit error, rather +than merely returning a <code>nil</code> that will cause problems later.</p> + +<p><a name="What_are_function_arguments_in_Penlight_"></a></p> + +<h3>What are function arguments in Penlight?</h3> + +<p>Many functions in Penlight themselves take function arguments, like <code>map</code> which +applies a function to a list, element by element. You can use existing +functions, like <a href="https://www.lua.org/manual/5.1/manual.html#pdf-math.max">math.max</a>, anonymous functions (like <code>function(x,y) return x > y +end<code> ), or operations by name (e.g &apos;*&apos; or &apos;..&apos;). The module </code>pl.operator</code> exports +all the standard Lua operations, like the Python module of the same name. +Penlight allows these to be referred to by name, so <a href="../libraries/pl.operator.html#gt">operator.gt</a> can be more +concisely expressed as ‘>’.</p> + +<p>Note that the <code>map</code> functions pass any extra arguments to the function, so we can +have <code>ls:filter('>',0)</code>, which is a shortcut for +<code>ls:filter(function(x) return x > 0 end)</code>.</p> + +<p>Finally, <a href="../libraries/pl.func.html#">pl.func</a> supports <em>placeholder expressions</em> in the Boost lambda style, +so that an anonymous function to multiply the two arguments can be expressed as +<code>\<em>1*\</em>2</code>.</p> + +<p>To use them directly, note that <em>all</em> function arguments in Penlight go through +<a href="../libraries/pl.utils.html#function_arg">utils.function_arg</a>. <a href="../libraries/pl.func.html#">pl.func</a> registers itself with this function, so that you +can directly use placeholder expressions with standard methods:</p> + +<pre> +> _1 = func._1 +> = List{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}:map(_1+<span class="number">1</span>) +{<span class="number">11</span>,<span class="number">21</span>,<span class="number">31</span>} +</pre> + + +<p>Another option for short anonymous functions is provided by +<a href="../libraries/pl.utils.html#string_lambda">utils.string_lambda</a>; this is invoked automatically:</p> + +<pre> +> = List{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}:map <span class="string">'|x| x + 1'</span> +{<span class="number">11</span>,<span class="number">21</span>,<span class="number">31</span>} +</pre> + + +<p><a name="Pros_and_Cons_of_Loopless_Programming"></a></p> + +<h3>Pros and Cons of Loopless Programming</h3> + +<p>The standard loops-and-ifs ‘imperative’ style of programming is dominant, and +often seems to be the ‘natural’ way of telling a machine what to do. It is in +fact very much how the machine does things, but we need to take a step back and +find ways of expressing solutions in a higher-level way. For instance, applying +a function to all elements of a list is a common operation:</p> + +<pre> +<span class="keyword">local</span> res = {} +<span class="keyword">for</span> i = <span class="number">1</span>,#ls <span class="keyword">do</span> + res[i] = fun(ls[i]) +<span class="keyword">end</span> +</pre> + + +<p>This can be efficiently and succintly expressed as <code>ls:map(fun)</code>. Not only is +there less typing but the intention of the code is clearer. If readers of your +code spend too much time trying to guess your intention by analyzing your loops, +then you have failed to express yourself clearly. Similarly, <code>ls:filter('>',0)</code> +will give you all the values in a list greater than zero. (Of course, if you +don’t feel like using <a href="../classes/pl.List.html#">List</a>, or have non-list-like tables, then <a href="../libraries/pl.tablex.html#">pl.tablex</a> +offers the same facilities. In fact, the <a href="../classes/pl.List.html#">List</a> methods are implemented using +<a href="../libraries/pl.tablex.html#">tablex</a> functions.)</p> + +<p>A common observation is that loopless programming is less efficient, particularly +in the way it uses memory. <code>ls1:map2('*',ls2):reduce '+'</code> will give you the dot +product of two lists, but an unnecessary temporary list is created. But +efficiency is relative to the actual situation, it may turn out to be <em>fast +enough</em>, or may not appear in any crucial inner loops, etc.</p> + +<p>Writing loops is ‘error-prone and tedious’, as Stroustrup says. But any +half-decent editor can be taught to do much of that typing for you. The question +should actually be: is it tedious to <em>read</em> loops? As with natural language, +programmers tend to read chunks at a time. A for-loop causes no surprise, and +probably little brain activity. One argument for loopless programming is the +loops that you <em>do</em> write stand out more, and signal ‘something different +happening here’. It should not be an all-or-nothing thing, since most programs +require a mixture of idioms that suit the problem. Some languages (like APL) do +nearly everything with map and reduce operations on arrays, and so solutions can +sometimes seem forced. Wisdom is knowing when a particular idiom makes a +particular problem easy to <em>solve</em> and the solution easy to <em>explain</em> afterwards.</p> + +<p><a name="Generally_useful_functions_"></a></p> + +<h3>Generally useful functions.</h3> + +<p>The function <code>printf</code> discussed earlier is included in <a href="../libraries/pl.utils.html#">pl.utils</a> because it +makes properly formatted output easier. (There is an equivalent <code>fprintf</code> which +also takes a file object parameter, just like the C function.)</p> + +<p>Splitting a string using a delimiter is a fairly common operation, hence <code>split</code>.</p> + +<p>Utility functions like <code>is_type</code> help with identifying what +kind of animal you are dealing with. +The Lua <a href="https://www.lua.org/manual/5.1/manual.html#pdf-type">type</a> function handles the basic types, but can’t distinguish between +different kinds of objects, which are all tables. So <code>is_type</code> handles both +cases, like <code>is_type(s,"string")</code> and <code>is_type(ls,List)</code>.</p> + +<p>A common pattern when working with Lua varargs is capturing all the arguments in +a table:</p> + +<pre> +<span class="keyword">function</span> t(...) + <span class="keyword">local</span> args = {...} + ... +<span class="keyword">end</span> +</pre> + + +<p>But this will bite you someday when <code>nil</code> is one of the arguments, since this +will put a ‘hole’ in your table. In particular, <code>#ls</code> will only give you the size +upto the <code>nil</code> value. Hence the need for <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.pack">table.pack</a> - this is a new Lua 5.2 +function which Penlight defines also for Lua 5.1.</p> + +<pre> +<span class="keyword">function</span> t(...) + <span class="keyword">local</span> args,n = <span class="global">table</span>.pack(...) + <span class="keyword">for</span> i = <span class="number">1</span>,n <span class="keyword">do</span> + ... + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>The ‘memoize’ pattern occurs when you have a function which is expensive to call, +but will always return the same value subsequently. <a href="../libraries/pl.utils.html#memoize">utils.memoize</a> is given a +function, and returns another function. This calls the function the first time, +saves the value for that argument, and thereafter for that argument returns the +saved value. This is a more flexible alternative to building a table of values +upfront, since in general you won’t know what values are needed.</p> + +<pre> +sum = utils.memoize(<span class="keyword">function</span>(n) + <span class="keyword">local</span> sum = <span class="number">0</span> + <span class="keyword">for</span> i = <span class="number">1</span>,n <span class="keyword">do</span> sum = sum + i <span class="keyword">end</span> + <span class="keyword">return</span> sum +<span class="keyword">end</span>) +... +s = sum(<span class="number">1e8</span>) <span class="comment">--takes time! +</span>... +s = sum(<span class="number">1e8</span>) <span class="comment">--returned saved value!</span> +</pre> + + +<p>Penlight is fully compatible with Lua 5.1, 5.2 and LuaJIT 2. To ensure this, +<a href="../libraries/pl.utils.html#">utils</a> also defines the global Lua 5.2 +<a href="http://www.lua.org/work/doc/manual.html#pdf-load">load</a> function as <a href="../libraries/pl.utils.html#load">utils.load</a></p> + +<ul> +<li>the input (either a string or a function)</li> +<li>the source name used in debug information</li> +<li>the mode is a string that can have either or both of ‘b’ or ’t', depending on +whether the source is a binary chunk or text code (default is ‘bt’)</li> +<li>the environment for the compiled chunk</li> +</ul> + + +<p>Using <a href="../libraries/pl.utils.html#load">utils.load</a> should reduce the need to call the deprecated function <a href="https://www.lua.org/manual/5.1/manual.html#pdf-setfenv">setfenv</a>, +and make your Lua 5.1 code 5.2-friendly.</p> + +<p>The <a href="../libraries/pl.utils.html#">utils</a> module exports <a href="https://www.lua.org/manual/5.1/manual.html#pdf-getfenv">getfenv</a> and <a href="https://www.lua.org/manual/5.1/manual.html#pdf-setfenv">setfenv</a> for +Lua 5.2 as well, based on code by Sergey Rozhenko. Note that these functions can fail +for functions which don’t access any globals.</p> + +<p><a name="Application_Support"></a></p> + +<h3>Application Support</h3> + +<p><a href="../libraries/pl.app.html#parse_args">app.parse_args</a> is a simple command-line argument parser. If called without any +arguments, it tries to use the global <code>arg</code> array. It returns the <em>flags</em> +(options begining with ‘-’) as a table of name/value pairs, and the <em>arguments</em> +as an array. It knows about long GNU-style flag names, e.g. <code>–value</code>, and +groups of short flags are understood, so that <code>-ab</code> is short for <code>-a -b</code>. The +flags result would then look like <code>{value=true,a=true,b=true}</code>.</p> + +<p>Flags may take values. The command-line <code>–value=open -n10</code> would result in +<code>{value='open',n='10'}</code>; generally you can use ‘=’ or ‘:’ to separate the flag +from its value, except in the special case where a short flag is followed by an +integer. Or you may specify upfront that some flags have associated values, and +then the values will follow the flag.</p> + +<pre> +> <span class="global">require</span> <span class="string">'pl'</span> +> flags,args = app.parse_args({<span class="string">'-o'</span>,<span class="string">'fred'</span>,<span class="string">'-n10'</span>,<span class="string">'fred.txt'</span>},{o=<span class="keyword">true</span>}) +> pretty.dump(flags) +{o=<span class="string">'fred'</span>,n=<span class="string">'10'</span>} +</pre> + + +<p><code>parse_args</code> is not intelligent or psychic; it will not convert any flag values +or arguments for you, or raise errors. For that, have a look at +<a href="../manual/08-additional.md.html#Command_line_Programs_with_Lapp">Lapp</a>.</p> + +<p>An application which consists of several files usually cannot use <a href="https://www.lua.org/manual/5.1/manual.html#pdf-require">require</a> to +load files in the same directory as the main script. <code>app.require_here()</code> +ensures that the Lua module path is modified so that files found locally are +found first. In the <code>examples</code> directory, <a href="../examples/test-symbols.lua.html#">test-symbols.lua</a> uses this function +to ensure that it can find <a href="../examples/symbols.lua.html#">symbols.lua</a> even if it is not run from this directory.</p> + +<p><a href="../libraries/pl.app.html#appfile">app.appfile</a> will create a filename that your application can use to store its +private data, based on the script name. For example, <code>app.appfile "test.txt"</code> +from a script called <a href="../examples/testapp.lua.html#">testapp.lua</a> produces the following file on my Windows +machine:</p> + +<pre><code>C:\Documents and Settings\SJDonova\.testapp\test.txt +</code></pre> + +<p>and the equivalent on my Linux machine:</p> + +<pre><code>/home/sdonovan/.testapp/test.txt +</code></pre> + +<p>If <code>.testapp</code> does not exist, it will be created.</p> + +<p>Penlight makes it convenient to save application data in Lua format. You can use +<code>pretty.dump(t,file)</code> to write a Lua table in a human-readable form to a file, +and <code>pretty.read(file.read(file))</code> to generate the table again, using the +<a href="../libraries/pl.pretty.html#">pretty</a> module.</p> + +<p><a name="Simplifying_Object_Oriented_Programming_in_Lua"></a></p> + +<h3>Simplifying Object-Oriented Programming in Lua</h3> + +<p>Lua is similar to JavaScript in that the concept of class is not directly +supported by the language. In fact, Lua has a very general mechanism for +extending the behaviour of tables which makes it straightforward to implement +classes. A table’s behaviour is controlled by its metatable. If that metatable +has a <code>\<em>\</em>index</code> function or table, this will handle looking up anything which is +not found in the original table. A class is just a table with an <code>__index</code> key +pointing to itself. Creating an object involves making a table and setting its +metatable to the class; then when handling <code>obj.fun</code>, Lua first looks up <code>fun</code> in +the table <code>obj</code>, and if not found it looks it up in the class. <code>obj:fun(a)</code> is +just short for <code>obj.fun(obj,a)</code>. So with the metatable mechanism and this bit of +syntactic sugar, it is straightforward to implement classic object orientation.</p> + +<pre> +<span class="comment">-- animal.lua +</span> +class = <span class="global">require</span> <span class="string">'pl.class'</span> + +class.Animal() + +<span class="keyword">function</span> Animal:_init(name) + self.name = name +<span class="keyword">end</span> + +<span class="keyword">function</span> Animal:__tostring() + <span class="keyword">return</span> self.name..<span class="string">': '</span>..self:speak() +<span class="keyword">end</span> + +class.Dog(Animal) + +<span class="keyword">function</span> Dog:speak() + <span class="keyword">return</span> <span class="string">'bark'</span> +<span class="keyword">end</span> + +class.Cat(Animal) + +<span class="keyword">function</span> Cat:_init(name,breed) + self:super(name) <span class="comment">-- must init base! +</span> self.breed = breed +<span class="keyword">end</span> + +<span class="keyword">function</span> Cat:speak() + <span class="keyword">return</span> <span class="string">'meow'</span> +<span class="keyword">end</span> + +class.Lion(Cat) + +<span class="keyword">function</span> Lion:speak() + <span class="keyword">return</span> <span class="string">'roar'</span> +<span class="keyword">end</span> + +fido = Dog(<span class="string">'Fido'</span>) +felix = Cat(<span class="string">'Felix'</span>,<span class="string">'Tabby'</span>) +leo = Lion(<span class="string">'Leo'</span>,<span class="string">'African'</span>) + +$ lua -i animal.lua +> = fido,felix,leo +Fido: bark Felix: meow Leo: roar +> = leo:is_a(Animal) +<span class="keyword">true</span> +> = leo:is_a(Dog) +<span class="keyword">false</span> +> = leo:is_a(Cat) +<span class="keyword">true</span> +</pre> + + +<p>All Animal does is define <code>\<em>\</em>tostring</code>, which Lua will use whenever a string +representation is needed of the object. In turn, this relies on <code>speak</code>, which is +not defined. So it’s what C++ people would call an abstract base class; the +specific derived classes like Dog define <code>speak</code>. Please note that <em>if</em> derived +classes have their own constructors, they must explicitly call the base +constructor for their base class; this is conveniently available as the <code>super</code> +method.</p> + +<p>Note that (as always) there are multiple ways to implement OOP in Lua; this method +uses the classic ‘a class is the __index of its objects’ but does ‘fat inheritance’; +methods from the base class are copied into the new class. The advantage of this is +that you are not penalized for long inheritance chains, for the price of larger classes, +but generally objects outnumber classes! (If not, something odd is going on with your design.)</p> + +<p>All such objects will have a <code>is_a</code> method, which looks up the inheritance chain +to find a match. Another form is <code>class_of</code>, which can be safely called on all +objects, so instead of <code>leo:is_a(Animal)</code> one can say <code>Animal:class_of(leo)</code>.</p> + +<p>There are two ways to define a class, either <code>class.Name()</code> or <code>Name = class()</code>; +both work identically, except that the first form will always put the class in +the current environment (whether global or module); the second form provides more +flexibility about where to store the class. The first form does <em>name</em> the class +by setting the <code>_name</code> field, which can be useful in identifying the objects of +this type later. This session illustrates the usefulness of having named classes, +if no <code>__tostring</code> method is explicitly defined.</p> + +<pre> +> class.Fred() +> a = Fred() +> = a +Fred: <span class="number">00459330</span> +> Alice = class() +> b = Alice() +> = b +<span class="global">table</span>: <span class="number">00459</span>AE8 +> Alice._name = <span class="string">'Alice'</span> +> = b +Alice: <span class="number">00459</span>AE8 +</pre> + + +<p>So <code>Alice = class(); Alice._name = 'Alice'</code> is exactly the same as <code>class.Alice()</code>.</p> + +<p>This useful notation is borrowed from Hugo Etchegoyen’s +<a href="http://lua-users.org/wiki/MultipleInheritanceClasses">classlib</a> which further +extends this concept to allow for multiple inheritance. Notice that the +more convenient form puts the class name in the <em>current environment</em>! That is, +you may use it safely within modules using the old-fashioned <code>module()</code> +or the new <code>_ENV</code> mechanism.</p> + +<p>There is always more than one way of doing things in Lua; some may prefer this +style for creating classes:</p> + +<pre> +<span class="keyword">local</span> class = <span class="global">require</span> <span class="string">'pl.class'</span> + +class.Named { + _init = <span class="keyword">function</span>(self,name) + self.name = name + <span class="keyword">end</span>; + + __tostring = <span class="keyword">function</span>(self) + <span class="keyword">return</span> <span class="string">'boo '</span>..self.name + <span class="keyword">end</span>; +} + +b = Named <span class="string">'dog'</span> +<span class="global">print</span>(b) +<span class="comment">--> boo dog</span> +</pre> + + +<p>Note that you have to explicitly declare <code>self</code> and end each function definition +with a semi-colon or comma, since this is a Lua table. To inherit from a base class, +set the special field <code>_base</code> to the class in this table.</p> + +<p>Penlight provides a number of useful classes; there is <a href="../classes/pl.List.html#">List</a>, which is a Lua +clone of the standard Python list object, and <a href="../libraries/pl.Set.html#">Set</a> which represents sets. There +are three kinds of <em>map</em> defined: <a href="../classes/pl.Map.html#">Map</a>, <a href="../classes/pl.MultiMap.html#">MultiMap</a> (where a key may have +multiple values) and <a href="../classes/pl.OrderedMap.html#">OrderedMap</a> (where the order of insertion is remembered.). +There is nothing special about these classes and you may inherit from them.</p> + +<p>A powerful thing about dynamic languages is that you can redefine existing classes +and functions, which is often called ‘monkey patching’ It’s entertaining and convenient, +but ultimately anti-social; you may modify <a href="../classes/pl.List.html#">List</a> but then any other modules using +this <em>shared</em> resource can no longer be sure about its behaviour. (This is why you +must say <code>stringx.import()</code> explicitly if you want the extended string methods - it +would be a bad default.) Lua is particularly open to modification but the +community is not as tolerant of monkey-patching as the Ruby community, say. You may +wish to add some new methods to <a href="../classes/pl.List.html#">List</a>? Cool, but that’s what subclassing is for.</p> + +<pre> +class.Strings(List) + +<span class="keyword">function</span> Strings:my_method() +... +<span class="keyword">end</span> +</pre> + + +<p>It’s definitely more useful to define exactly how your objects behave +in <em>unknown</em> conditions. All classes have a <code>catch</code> method you can use to set +a handler for unknown lookups; the function you pass looks exactly like the +<code>__index</code> metamethod.</p> + +<pre> +Strings:catch(<span class="keyword">function</span>(self,name) + <span class="keyword">return</span> <span class="keyword">function</span>() <span class="global">error</span>(<span class="string">"no such method "</span>..name,<span class="number">2</span>) <span class="keyword">end</span> +<span class="keyword">end</span>) +</pre> + + +<p>In this case we’re just customizing the error message, but +creative things can be done. Consider this code from <code>test-vector.lua</code>:</p> + +<pre> +Strings:catch(List.default_map_with(<span class="global">string</span>)) + +ls = Strings{<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>} +asserteq(ls:upper(),{<span class="string">'ONE'</span>,<span class="string">'TWO'</span>,<span class="string">'THREE'</span>}) +asserteq(ls:sub(<span class="number">1</span>,<span class="number">2</span>),{<span class="string">'on'</span>,<span class="string">'tw'</span>,<span class="string">'th'</span>}) +</pre> + + +<p>So we’ve converted a unknown method invocation into a map using the function of +that name found in <a href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a>. So for a <code>Vector</code> (which is a specialization of <a href="../classes/pl.List.html#">List</a> +for numbers) it makes sense to make <a href="https://www.lua.org/manual/5.1/manual.html#5.6">math</a> the default map so that <code>v:sin()</code> makes +sense.</p> + +<p>Note that <code>map</code> operations return a object of the same type - this is often called +<em>covariance</em>. So <code>ls:upper()</code> itself returns a <code>Strings</code> object.</p> + +<p>This is not <em>always</em> what you want, but objects can always be cast to the desired type. +(<code>cast</code> doesn’t create a new object, but returns the object passed.)</p> + +<pre> +<span class="keyword">local</span> sizes = ls:map <span class="string">'#'</span> +asserteq(sizes, {<span class="number">3</span>,<span class="number">3</span>,<span class="number">5</span>}) +asserteq(utils.<span class="global">type</span>(sizes),<span class="string">'Strings'</span>) +asserteq(sizes:is_a(Strings),<span class="keyword">true</span>) +sizes = Vector:cast(sizes) +asserteq(utils.<span class="global">type</span>(sizes),<span class="string">'Vector'</span>) +asserteq(sizes+<span class="number">1</span>,{<span class="number">4</span>,<span class="number">4</span>,<span class="number">6</span>}) +</pre> + + +<p>About <code>utils.type</code>: it can only return a string for a class type if that class does +in fact have a <code>_name</code> field.</p> + +<p><em>Properties</em> are a useful object-oriented pattern. We wish to control access to a +field, but don’t wish to force the user of the class to say <code>obj:get_field()</code> +etc. This excerpt from <code>tests/test-class.lua</code> shows how it is done:</p> + +<pre> +<span class="keyword">local</span> MyProps = class(class.properties) +<span class="keyword">local</span> setted_a, got_b + +<span class="keyword">function</span> MyProps:_init () + self._a = <span class="number">1</span> + self._b = <span class="number">2</span> +<span class="keyword">end</span> + +<span class="keyword">function</span> MyProps:set_a (v) + setted_a = <span class="keyword">true</span> + self._a = v +<span class="keyword">end</span> + +<span class="keyword">function</span> MyProps:get_b () + got_b = <span class="keyword">true</span> + <span class="keyword">return</span> self._b +<span class="keyword">end</span> + +<span class="keyword">local</span> mp = MyProps() + +mp.a = <span class="number">10</span> + +asserteq(mp.a,<span class="number">10</span>) +asserteq(mp.b,<span class="number">2</span>) +asserteq(setted_a <span class="keyword">and</span> got_b, <span class="keyword">true</span>) +</pre> + + +<p>The convention is that the internal field name is prefixed with an underscore; +when reading <code>mp.a</code>, first a check for an explicit <em>getter</em> <code>get_a</code> and then only +look for <code>_a</code>. Simularly, writing <code>mp.a</code> causes the <em>setter</em> <code>set_a</code> to be used.</p> + +<p>This is cool behaviour, but like much Lua metaprogramming, it is not free. Method +lookup on such objects goes through <code>\<em>\</em>index</code> as before, but now <code>\<em>\</em>index</code> is a +function which has to explicitly look up methods in the class, before doing any +property indexing, which is not going to be as fast as field lookup. If however, +your accessors actually do non-trivial things, then the extra overhead could be +worth it.</p> + +<p>This is not really intended for <em>access control</em> because external code can write +to <code>mp._a</code> directly. It is possible to have this kind of control in Lua, but it +again comes with run-time costs.</p> + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/02-arrays.md.html b/docs/manual/02-arrays.md.html new file mode 100644 index 0000000..9b548ae --- /dev/null +++ b/docs/manual/02-arrays.md.html @@ -0,0 +1,911 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Python_style_Lists">Python-style Lists </a></li> +<li><a href="#Map_and_Set_classes">Map and Set classes </a></li> +<li><a href="#Useful_Operations_on_Tables">Useful Operations on Tables </a></li> +<li><a href="#Operations_on_two_dimensional_tables">Operations on two-dimensional tables </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><strong>Tables and Arrays</strong></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Tables and Arrays</h2> + +<p><a id="list"/></p> + +<p><a name="Python_style_Lists"></a></p> + +<h3>Python-style Lists</h3> + +<p>One of the elegant things about Lua is that tables do the job of both lists and +dicts (as called in Python) or vectors and maps, (as called in C++), and they do +it efficiently. However, if we are dealing with ‘tables with numerical indices’ +we may as well call them lists and look for operations which particularly make +sense for lists. The Penlight <a href="../classes/pl.List.html#">List</a> class was originally written by Nick Trout +for Lua 5.0, and translated to 5.1 and extended by myself. It seemed that +borrowing from Python was a good idea, and this eventually grew into Penlight.</p> + +<p>Here is an example showing <a href="../classes/pl.List.html#">List</a> in action; it redefines <code>__tostring</code>, so that +it can print itself out more sensibly:</p> + +<pre> +> List = <span class="global">require</span> <span class="string">'pl.List'</span> <span class="comment">--> automatic with require 'pl' <--- +</span>> l = List() +> l:append(<span class="number">10</span>) +> l:append(<span class="number">20</span>) +> = l +{<span class="number">10</span>,<span class="number">20</span>} +> l:extend {<span class="number">30</span>,<span class="number">40</span>} +{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} +> l:insert(<span class="number">1</span>,<span class="number">5</span>) +{<span class="number">5</span>,<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} +> = l:pop() +<span class="number">40</span> +> = l +{<span class="number">5</span>,<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +> = l:index(<span class="number">30</span>) +<span class="number">4</span> +> = l:contains(<span class="number">30</span>) +<span class="keyword">true</span> +> = l:reverse() <span class="comment">---> note: doesn't make a copy! +</span>{<span class="number">30</span>,<span class="number">20</span>,<span class="number">10</span>,<span class="number">5</span>} +</pre> + + +<p>Although methods like <code>sort</code> and <code>reverse</code> operate in-place and change the list, +they do return the original list. This makes it possible to do <em>method chaining</em>, +like <code>ls = ls:append(10):append(20):reverse():append(1)</code>. But (and this is an +important but) no extra copy is made, so <code>ls</code> does not change identity. <a href="../classes/pl.List.html#">List</a> +objects (like tables) are <em>mutable</em>, unlike strings. If you want a copy of a +list, then <code>List(ls)</code> will do the job, i.e. it acts like a copy constructor. +However, if passed any other table, <a href="../classes/pl.List.html#">List</a> will just set the metatable of the +table and <em>not</em> make a copy.</p> + +<p>A particular feature of Python lists is <em>slicing</em>. This is fully supported in +this version of <a href="../classes/pl.List.html#">List</a>, except we use 1-based indexing. So <a href="../classes/pl.List.html#List:slice">List.slice</a> works +rather like <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.sub">string.sub</a>:</p> + +<pre> +> l = List {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} +> = l:slice(<span class="number">1</span>,<span class="number">1</span>) <span class="comment">---> note: creates a new list! +</span>{<span class="number">10</span>} +> = l:slice(<span class="number">2</span>,<span class="number">2</span>) +{<span class="number">20</span>} +> = l:slice(<span class="number">2</span>,<span class="number">3</span>) +{<span class="number">20</span>,<span class="number">30</span>} +> = l:slice(<span class="number">2</span>,-<span class="number">2</span>) +{<span class="number">20</span>,<span class="number">30</span>} +> = l:slice_assign(<span class="number">2</span>,<span class="number">2</span>,{<span class="number">21</span>,<span class="number">22</span>,<span class="number">23</span>}) +{<span class="number">10</span>,<span class="number">21</span>,<span class="number">22</span>,<span class="number">23</span>,<span class="number">30</span>,<span class="number">40</span>} +> = l:chop(<span class="number">1</span>,<span class="number">1</span>) +{<span class="number">21</span>,<span class="number">22</span>,<span class="number">23</span>,<span class="number">30</span>,<span class="number">40</span>} +</pre> + + +<p>Functions like <code>slice_assign</code> and <code>chop</code> modify the list; the first is equivalent +to Python<code>l[i1:i2] = seq</code> and the second to <code>del l[i1:i2]</code>.</p> + +<p>List objects are ultimately just Lua ‘list-like’ tables, but they have extra +operations defined on them, such as equality and concatention. For regular +tables, equality is only true if the two tables are <em>identical objects</em>, whereas +two lists are equal if they have the same contents, i.e. that <code>l1[i]==l2[i]</code> for +all elements.</p> + +<pre> +> l1 = List {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +> l2 = List {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +> = l1 == l2 +<span class="keyword">true</span> +> = l1..l2 +{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +</pre> + + +<p>The <a href="../classes/pl.List.html#">List</a> constructor can be passed a function. If so, it’s assumed that this is +an iterator function that can be repeatedly called to generate a sequence. One +such function is <a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.lines">io.lines</a>; the following short, intense little script counts +the number of lines in standard input:</p> + +<pre> +<span class="comment">-- linecount.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +ls = List(<span class="global">io</span>.lines()) +<span class="global">print</span>(#ls) +</pre> + + +<p><a href="../classes/pl.List.html#List.iterate">List.iterate</a> captures what <a href="../classes/pl.List.html#">List</a> considers a sequence. In particular, it can +also iterate over all ‘characters’ in a string:</p> + +<pre> +> <span class="keyword">for</span> ch <span class="keyword">in</span> List.iterate <span class="string">'help'</span> <span class="keyword">do</span> <span class="global">io</span>.write(ch,<span class="string">' '</span>) <span class="keyword">end</span> +h e l p > +</pre> + + +<p>Since the function <code>iterate</code> is used internally by the <a href="../classes/pl.List.html#">List</a> constructor, +strings can be made into lists of character strings very easily.</p> + +<p>There are a number of operations that go beyond the standard Python methods. For +instance, you can <em>partition</em> a list into a table of sublists using a function. +In the simplest form, you use a predicate (a function returning a boolean value) +to partition the list into two lists, one of elements matching and another of +elements not matching. But you can use any function; if we use <a href="https://www.lua.org/manual/5.1/manual.html#pdf-type">type</a> then the +keys will be the standard Lua type names.</p> + +<pre> +> ls = List{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>} +> ops = <span class="global">require</span> <span class="string">'pl.operator'</span> +> ls:partition(<span class="keyword">function</span>(x) <span class="keyword">return</span> x > <span class="number">2</span> <span class="keyword">end</span>) +{<span class="keyword">false</span>={<span class="number">1</span>,<span class="number">2</span>},<span class="keyword">true</span>={<span class="number">3</span>,<span class="number">4</span>}} +> ls = List{<span class="string">'one'</span>,<span class="global">math</span>.sin,List{<span class="number">1</span>},<span class="number">10</span>,<span class="number">20</span>,List{<span class="number">1</span>,<span class="number">2</span>}} +> ls:partition(<span class="global">type</span>) +{<span class="keyword">function</span>={<span class="keyword">function</span>: <span class="number">00369110</span>},<span class="global">string</span>={one},number={<span class="number">10</span>,<span class="number">20</span>},<span class="global">table</span>={{<span class="number">1</span>},{<span class="number">1</span>,<span class="number">2</span>}}} +</pre> + + +<p>This is one <a href="../classes/pl.List.html#">List</a> method which returns a table which is not a <a href="../classes/pl.List.html#">List</a>. Bear in +mind that you can always call a <a href="../classes/pl.List.html#">List</a> method on a plain table argument, so +<code>List.partition(t,type)</code> works as expected. But these functions will only operate +on the array part of the table.</p> + +<p>The ‘nominal’ type of the returned table is <code>pl.Multimap</code>, which describes a mapping +between keys and multiple values. This does not mean that <code>pl.Multimap</code> is automatically +loaded whenever you use <code>partition</code> (or <a href="../classes/pl.List.html#">List</a> for that matter); this is one of the +standard metatables which are only filled out when the appropriate module is loaded. +This allows tables to be tagged appropriately without causing excessive coupling.</p> + +<p>Stacks occur everywhere in computing. <a href="../classes/pl.List.html#">List</a> supports stack-like operations; +there is already <code>pop</code> (remove and return last value) and <code>append</code> acts like +<code>push</code> (add a value to the end). <code>push</code> is provided as an alias for <code>append</code>, and +the other stack operation (size) is simply the size operator <code>#</code>. Queues can +also be implemented; you use <code>pop</code> to take values out of the queue, and <code>put</code> to +insert a value at the begining.</p> + +<p>You may derive classes from <a href="../classes/pl.List.html#">List</a>, and since the list-returning methods +are covariant, the result of <code>slice</code> etc will return lists of the derived type, +not <a href="../classes/pl.List.html#">List</a>. For instance, consider the specialization of a <a href="../classes/pl.List.html#">List</a> type that contains +numbers in <code>tests/test-list.lua</code>:</p> + +<pre> +n1 = NA{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +n2 = NA{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +ns = n1 + <span class="number">2</span>*n2 +asserteq(ns,{<span class="number">12</span>,<span class="number">24</span>,<span class="number">36</span>}) +min,max = ns:slice(<span class="number">1</span>,<span class="number">2</span>):minmax() +asserteq(T(min,max),T(<span class="number">12</span>,<span class="number">24</span>)) +asserteq(n1:normalize():sum(),<span class="number">1</span>,<span class="number">1e-8</span>) +</pre> + + +<p><a name="Map_and_Set_classes"></a></p> + +<h3>Map and Set classes</h3> + +<p>The <a href="../classes/pl.Map.html#">Map</a> class exposes what Python would call a ‘dict’ interface, and accesses +the hash part of the table. The name ‘Map’ is used to emphasize the interface, +not the implementation; it is an object which maps keys onto values; <code>m['alice']</code> +or the equivalent <code>m.alice</code> is the access operation. This class also provides +explicit <code>set</code> and <code>get</code> methods, which are trivial for regular maps but get +interesting when <a href="../classes/pl.Map.html#">Map</a> is subclassed. The other operation is <code>update</code>, which +extends a map by copying the keys and values from another table, perhaps +overwriting existing keys:</p> + +<pre> +> Map = <span class="global">require</span> <span class="string">'pl.Map'</span> +> m = Map{one=<span class="number">1</span>,two=<span class="number">2</span>} +> m:update {three=<span class="number">3</span>,four=<span class="number">4</span>,two=<span class="number">20</span>} +> = m == M{one=<span class="number">1</span>,two=<span class="number">20</span>,three=<span class="number">3</span>,four=<span class="number">4</span>} +<span class="keyword">true</span> +</pre> + + +<p>The method <code>values</code> returns a list of the values, and <code>keys</code> returns a list of +the keys; there is no guarantee of order. <code>getvalues</code> is given a list of keys and +returns a list of values associated with these keys:</p> + +<pre> +> m = Map{one=<span class="number">1</span>,two=<span class="number">2</span>,three=<span class="number">3</span>} +> = m:getvalues {<span class="string">'one'</span>,<span class="string">'three'</span>} +{<span class="number">1</span>,<span class="number">3</span>} +> = m:getvalues(m:keys()) == m:values() +<span class="keyword">true</span> +</pre> + + +<p>When querying the value of a <a href="../classes/pl.Map.html#">Map</a>, it is best to use the <code>get</code> method:</p> + +<pre> +> <span class="global">print</span>(m:get <span class="string">'one'</span>, m:get <span class="string">'two'</span>) +<span class="number">1</span> <span class="number">2</span> +</pre> + + +<p>The reason is that <code>m[key]</code> can be ambiguous; due to the current implementation, +<code>m["get"]</code> will always succeed, because if a value is not present in the map, it +will be looked up in the <a href="../classes/pl.Map.html#">Map</a> metatable, which contains a method <code>get</code>. There is +currently no simple solution to this annoying restriction.</p> + +<p>There are some useful classes which inherit from <a href="../classes/pl.Map.html#">Map</a>. An <a href="../classes/pl.OrderedMap.html#">OrderedMap</a> behaves +like a <a href="../classes/pl.Map.html#">Map</a> but keeps its keys in order if you use its <code>set</code> method to add keys +and values. Like all the ‘container’ classes in Penlight, it defines an <code>iter</code> +method for iterating over its values; this will return the keys and values in the +order of insertion; the <code>keys</code> and <code>values</code> methods likewise.</p> + +<p>A <a href="../classes/pl.MultiMap.html#">MultiMap</a> allows multiple values to be associated with a given key. So <code>set</code> +(as before) takes a key and a value, but calling it with the same key and a +different value does not overwrite but adds a new value. <code>get</code> (or using <code>[]</code>) +will return a list of values.</p> + +<p>A <a href="../libraries/pl.Set.html#">Set</a> can be seen as a special kind of <a href="../classes/pl.Map.html#">Map</a>, where all the values are <code>true</code>, +the keys are the values, and the order is not important. So in this case +<a href="../libraries/pl.Set.html#values">Set.values</a> is defined to return a list of the keys. Sets can display +themselves, and the basic operations like <code>union</code> (<code>+</code>) and <code>intersection</code> (<code>*</code>) +are defined.</p> + +<pre> +> Set = <span class="global">require</span> <span class="string">'pl.Set'</span> +> = Set{<span class="string">'one'</span>,<span class="string">'two'</span>} == Set{<span class="string">'two'</span>,<span class="string">'one'</span>} +<span class="keyword">true</span> +> fruit = Set{<span class="string">'apple'</span>,<span class="string">'banana'</span>,<span class="string">'orange'</span>} +> = fruit[<span class="string">'banana'</span>] +<span class="keyword">true</span> +> = fruit[<span class="string">'hazelnut'</span>] +<span class="keyword">nil</span> +> = fruit:values() +{apple,orange,banana} +> colours = Set{<span class="string">'red'</span>,<span class="string">'orange'</span>,<span class="string">'green'</span>,<span class="string">'blue'</span>} +> = fruit,colours +[apple,orange,banana] [blue,green,orange,red] +> = fruit+colours +[blue,green,apple,red,orange,banana] +> = fruit*colours +[orange] +</pre> + + +<p>There are also the functions <a href="../libraries/pl.Set.html#difference">Set.difference</a> and <code>Set.symmetric_difference</code>. The +first answers the question ‘what fruits are not colours?’ and the second ‘what +are fruits and colours but not both?’</p> + +<pre> +> = fruit - colours +[apple,banana] +> = fruit ^ colours +[blue,green,apple,red,banana] +</pre> + + +<p>Adding elements to a set is simply <code>fruit['peach'] = true</code> and removing is +<code>fruit['apple'] = nil</code> . To make this simplicity work properly, the <a href="../libraries/pl.Set.html#">Set</a> class has no +methods - either you use the operator forms or explicitly use <code>Set.intersect</code> +etc. In this way we avoid the ambiguity that plagues <a href="../classes/pl.Map.html#">Map</a>.</p> + +<p>(See <a href="../classes/pl.Map.html#">pl.Map</a> and <a href="../libraries/pl.Set.html#">pl.Set</a>)</p> + +<p><a name="Useful_Operations_on_Tables"></a></p> + +<h3>Useful Operations on Tables</h3> + +<p>Some notes on terminology: Lua tables are usually <em>list-like</em> (like an array) or +<em>map-like</em> (like an associative array or dict); they can of course have a +list-like and a map-like part. Some of the table operations only make sense for +list-like tables, and some only for map-like tables. (The usual Lua terminology +is the array part and the hash part of the table, which reflects the actual +implementation used; it is more accurate to say that a Lua table is an +associative map which happens to be particularly efficient at acting like an +array.)</p> + +<p>The functions provided in <a href="https://www.lua.org/manual/5.1/manual.html#5.5">table</a> provide all the basic manipulations on Lua +tables, but as we saw with the <a href="../classes/pl.List.html#">List</a> class, it is useful to build higher-level +operations on top of those functions. For instance, to copy a table involves this +kind of loop:</p> + +<pre> +<span class="keyword">local</span> res = {} +<span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="global">pairs</span>(T) <span class="keyword">do</span> + res[k] = v +<span class="keyword">end</span> +<span class="keyword">return</span> res +</pre> + + +<p>The <a href="../libraries/pl.tablex.html#">tablex</a> module provides this as <a href="../libraries/pl.tablex.html#copy">copy</a>, which does a <em>shallow</em> copy of a +table. There is also <a href="../libraries/pl.tablex.html#deepcopy">deepcopy</a> which goes further than a simple loop in two +ways; first, it also gives the copy the same metatable as the original (so it can +copy objects like <a href="../classes/pl.List.html#">List</a> above) and any nested tables will also be copied, to +arbitrary depth. There is also <a href="../libraries/pl.tablex.html#icopy">icopy</a> which operates on list-like tables, where +you can set optionally set the start index of the source and destination as well. +It ensures that any left-over elements will be deleted:</p> + +<pre> +asserteq(icopy({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">20</span>,<span class="number">30</span>}),{<span class="number">20</span>,<span class="number">30</span>}) <span class="comment">-- start at 1 +</span>asserteq(icopy({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">20</span>,<span class="number">30</span>},<span class="number">2</span>),{<span class="number">1</span>,<span class="number">20</span>,<span class="number">30</span>}) <span class="comment">-- start at 2 +</span>asserteq(icopy({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">20</span>,<span class="number">30</span>},<span class="number">2</span>,<span class="number">2</span>),{<span class="number">1</span>,<span class="number">30</span>}) <span class="comment">-- start at 2, copy from 2</span> +</pre> + + +<p>(This code from the <a href="../libraries/pl.tablex.html#">tablex</a> test module shows the use of <a href="../libraries/pl.test.html#asserteq">pl.test.asserteq</a>)</p> + +<p>Whereas, <a href="../libraries/pl.tablex.html#move">move</a> overwrites but does not delete the rest of the destination:</p> + +<pre> +asserteq(move({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">20</span>,<span class="number">30</span>}),{<span class="number">20</span>,<span class="number">30</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>}) +asserteq(move({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">20</span>,<span class="number">30</span>},<span class="number">2</span>),{<span class="number">1</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>}) +asserteq(move({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">20</span>,<span class="number">30</span>},<span class="number">2</span>,<span class="number">2</span>),{<span class="number">1</span>,<span class="number">30</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>}) +</pre> + + +<p>(The difference is somewhat like that between C’s <code>strcpy</code> and <code>memmove</code>.)</p> + +<p>To summarize, use <a href="../libraries/pl.tablex.html#copy">copy</a> or <a href="../libraries/pl.tablex.html#deepcopy">deepcopy</a> to make a copy of an arbitrary table. To +copy into a map-like table, use <a href="../libraries/pl.tablex.html#update">update</a>; to copy into a list-like table use +<a href="../libraries/pl.tablex.html#icopy">icopy</a>, and <a href="../libraries/pl.tablex.html#move">move</a> if you are updating a range in the destination.</p> + +<p>To complete this set of operations, there is <a href="../libraries/pl.tablex.html#insertvalues">insertvalues</a> which works like +<a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.insert">table.insert</a> except that one provides a table of values to be inserted, and +<a href="../libraries/pl.tablex.html#removevalues">removevalues</a> which removes a range of values.</p> + +<pre> +asserteq(insertvalues({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>},<span class="number">2</span>,{<span class="number">20</span>,<span class="number">30</span>}),{<span class="number">1</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +asserteq(insertvalues({<span class="number">1</span>,<span class="number">2</span>},{<span class="number">3</span>,<span class="number">4</span>}),{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +</pre> + + +<p>Another example:</p> + +<pre> +> T = <span class="global">require</span> <span class="string">'pl.tablex'</span> +> t = {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} +> = T.removevalues(t,<span class="number">2</span>,<span class="number">3</span>) +{<span class="number">10</span>,<span class="number">40</span>} +> = T.insertvalues(t,<span class="number">2</span>,{<span class="number">20</span>,<span class="number">30</span>}) +{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} +</pre> + + +<p>In a similar spirit to <a href="../libraries/pl.tablex.html#deepcopy">deepcopy</a>, <a href="../libraries/pl.tablex.html#deepcompare">deepcompare</a> will take two tables and return +true only if they have exactly the same values and structure.</p> + +<pre> +> t1 = {<span class="number">1</span>,{<span class="number">2</span>,<span class="number">3</span>},<span class="number">4</span>} +> t2 = deepcopy(t1) +> = t1 == t2 +<span class="keyword">false</span> +> = deepcompare(t1,t2) +<span class="keyword">true</span> +</pre> + + +<p><a href="../libraries/pl.tablex.html#find">find</a> will return the index of a given value in a list-like table. Note that +like <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.find">string.find</a> you can specify an index to start searching, so that all +instances can be found. There is an optional fourth argument, which makes the +search start at the end and go backwards, so we could define <a href="../libraries/pl.tablex.html#rfind">rfind</a> like so:</p> + +<pre> +<span class="keyword">function</span> rfind(t,val,istart) + <span class="keyword">return</span> tablex.find(t,val,istart,<span class="keyword">true</span>) +<span class="keyword">end</span> +</pre> + + +<p><a href="../libraries/pl.tablex.html#find">find</a> does a linear search, so it can slow down code that depends on it. If +efficiency is required for large tables, consider using an <em>index map</em>. +<a href="../libraries/pl.tablex.html#index_map">index_map</a> will return a table where the keys are the original values of the +list, and the associated values are the indices. (It is almost exactly the +representation needed for a <em>set</em>.)</p> + +<pre> +> t = {<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>} +> = tablex.find(t,<span class="string">'two'</span>) +<span class="number">2</span> +> = tablex.find(t,<span class="string">'four'</span>) +<span class="keyword">nil</span> +> il = tablex.index_map(t) +> = il[<span class="string">'two'</span>] +<span class="number">2</span> +> = il.two +<span class="number">2</span> +</pre> + + +<p>A version of <a href="../libraries/pl.tablex.html#index_map">index_map</a> called <a href="../libraries/pl.tablex.html#makeset">makeset</a> is also provided, where the values are +just <code>true</code>. This is useful because two such sets can be compared for equality +using <a href="../libraries/pl.tablex.html#deepcompare">deepcompare</a>:</p> + +<pre> +> = deepcompare(makeset {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},makeset {<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>}) +<span class="keyword">true</span> +</pre> + + +<p>Consider the problem of determining the new employees that have joined in a +period. Assume we have two files of employee names:</p> + +<pre> +(last-month.txt) +smith,john +brady,maureen +mongale,thabo + +(this-month.txt) +smith,john +smit,johan +brady,maureen +mogale,thabo +van der Merwe,Piet +</pre> + + +<p>To find out differences, just make the employee lists into sets, like so:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> + +<span class="keyword">function</span> read_employees(file) + <span class="keyword">local</span> ls = List(<span class="global">io</span>.lines(file)) <span class="comment">-- a list of employees +</span> <span class="keyword">return</span> tablex.makeset(ls) +<span class="keyword">end</span> + +last = read_employees <span class="string">'last-month.txt'</span> +this = read_employees <span class="string">'this-month.txt'</span> + +<span class="comment">-- who is in this but not in last? +</span>diff = tablex.difference(this,last) + +<span class="comment">-- in a set, the keys are the values... +</span><span class="keyword">for</span> e <span class="keyword">in</span> <span class="global">pairs</span>(diff) <span class="keyword">do</span> <span class="global">print</span>(e) <span class="keyword">end</span> + +<span class="comment">-- *output* +</span><span class="comment">-- van der Merwe,Piet +</span><span class="comment">-- smit,johan</span> +</pre> + + +<p>The <a href="../libraries/pl.tablex.html#difference">difference</a> operation is easy to write and read:</p> + +<pre> +<span class="keyword">for</span> e <span class="keyword">in</span> <span class="global">pairs</span>(this) <span class="keyword">do</span> + <span class="keyword">if</span> <span class="keyword">not</span> last[e] <span class="keyword">then</span> + <span class="global">print</span>(e) + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>Using <a href="../libraries/pl.tablex.html#difference">difference</a> here is not that it is a tricky thing to code, it is that you +are stating your intentions clearly to other readers of your code. (And naturally +to your future self, in six months time.)</p> + +<p><a href="../libraries/pl.tablex.html#find_if">find_if</a> will search a table using a function. The optional third argument is a +value which will be passed as a second argument to the function. <a href="../libraries/pl.operator.html#">pl.operator</a> +provides the Lua operators conveniently wrapped as functions, so the basic +comparison functions are available:</p> + +<pre> +> ops = <span class="global">require</span> <span class="string">'pl.operator'</span> +> = tablex.find_if({<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>},ops.gt,<span class="number">20</span>) +<span class="number">3</span> <span class="keyword">true</span> +</pre> + + +<p>Note that <a href="../libraries/pl.tablex.html#find_if">find_if</a> will also return the <em>actual value</em> returned by the function, +which of course is usually just <code>true</code> for a boolean function, but any value +which is not <code>nil</code> and not <code>false</code> can be usefully passed back.</p> + +<p><a href="../libraries/pl.tablex.html#deepcompare">deepcompare</a> does a thorough recursive comparison, but otherwise using the +default equality operator. <a href="../libraries/pl.tablex.html#compare">compare</a> allows you to specify exactly what function +to use when comparing two list-like tables, and <a href="../libraries/pl.tablex.html#compare_no_order">compare_no_order</a> is true if +they contain exactly the same elements. Do note that the latter does not need an +explicit comparison function - in this case the implementation is actually to +compare the two sets, as above:</p> + +<pre> +> = compare_no_order({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>}) +<span class="keyword">true</span> +> = compare_no_order({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">2</span>,<span class="number">1</span>,<span class="number">3</span>},<span class="string">'=='</span>) +<span class="keyword">true</span> +</pre> + + +<p>(Note the special string ‘==’ above; instead of saying <code>ops.gt</code> or <code>ops.eq</code> we +can use the strings ‘>’ or ‘==’ respectively.)</p> + +<p><a href="../libraries/pl.tablex.html#sort">sort</a> and <a href="../libraries/pl.tablex.html#sortv">sortv</a> return iterators that will iterate through the +sorted elements of a table. <a href="../libraries/pl.tablex.html#sort">sort</a> iterates by sorted key order, and +<a href="../libraries/pl.tablex.html#sortv">sortv</a> iterates by sorted value order. For example, given a table +with names and ages, it is trivial to iterate over the elements:</p> + +<pre> +> t = {john=<span class="number">27</span>,jane=<span class="number">31</span>,mary=<span class="number">24</span>} +> <span class="keyword">for</span> name,age <span class="keyword">in</span> tablex.sort(t) <span class="keyword">do</span> <span class="global">print</span>(name,age) <span class="keyword">end</span> +jane <span class="number">31</span> +john <span class="number">27</span> +mary <span class="number">24</span> +> <span class="keyword">for</span> name,age <span class="keyword">in</span> tablex.sortv(t) <span class="keyword">do</span> <span class="global">print</span>(name,age) <span class="keyword">end</span> +mary <span class="number">24</span> +john <span class="number">27</span> +jane <span class="number">31</span> +</pre> + + +<p>There are several ways to merge tables in PL. If they are list-like, then see the +operations defined by <a href="../classes/pl.List.html#">pl.List</a>, like concatenation. If they are map-like, then +<a href="../libraries/pl.tablex.html#merge">merge</a> provides two basic operations. If the third arg is false, then the result +only contains the keys that are in common between the two tables, and if true, +then the result contains all the keys of both tables. These are in fact +generalized set union and intersection operations:</p> + +<pre> +> S1 = {john=<span class="number">27</span>,jane=<span class="number">31</span>,mary=<span class="number">24</span>} +> S2 = {jane=<span class="number">31</span>,jones=<span class="number">50</span>} +> = tablex.merge(S1, S2, <span class="keyword">false</span>) +{jane=<span class="number">31</span>} +> = tablex.merge(S1, S2, <span class="keyword">true</span>) +{mary=<span class="number">24</span>,jane=<span class="number">31</span>,john=<span class="number">27</span>,jones=<span class="number">50</span>} +</pre> + + +<p>When working with tables, you will often find yourself writing loops like in the +first example. Loops are second nature to programmers, but they are often not the +most elegant and self-describing way of expressing an operation. Consider the +<a href="../libraries/pl.tablex.html#map">map</a> function, which creates a new table by applying a function to each element +of the original:</p> + +<pre> +> = map(<span class="global">math</span>.sin, {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{ <span class="number">0.84</span>, <span class="number">0.91</span>, <span class="number">0.14</span>, -<span class="number">0.76</span>} +> = map(<span class="keyword">function</span>(x) <span class="keyword">return</span> x*x <span class="keyword">end</span>, {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">16</span>} +</pre> + + +<p><a href="../libraries/pl.tablex.html#map">map</a> saves you from writing a loop, and the resulting code is often clearer, as +well as being shorter. This is not to say that ‘loops are bad’ (although you will +hear that from some extremists), just that it’s good to capture standard +patterns. Then the loops you do write will stand out and acquire more significance.</p> + +<p><a href="../libraries/pl.tablex.html#pairmap">pairmap</a> is interesting, because the function works with both the key and the +value.</p> + +<pre> +> t = {fred=<span class="number">10</span>,bonzo=<span class="number">20</span>,alice=<span class="number">4</span>} +> = pairmap(<span class="keyword">function</span>(k,v) <span class="keyword">return</span> v <span class="keyword">end</span>, t) +{<span class="number">4</span>,<span class="number">10</span>,<span class="number">20</span>} +> = pairmap(<span class="keyword">function</span>(k,v) <span class="keyword">return</span> k <span class="keyword">end</span>, t) +{<span class="string">'alice'</span>,<span class="string">'fred'</span>,<span class="string">'bonzo'</span>} +</pre> + + +<p>(These are common enough operations that the first is defined as <a href="../libraries/pl.tablex.html#values">values</a> and the +second as <a href="../libraries/pl.tablex.html#keys">keys</a>.) If the function returns two values, then the <em>second</em> value is +considered to be the new key:</p> + +<pre> +> = pairmap(t,<span class="keyword">function</span>(k,v) <span class="keyword">return</span> v+<span class="number">10</span>, k:upper() <span class="keyword">end</span>) +{BONZO=<span class="number">30</span>,FRED=<span class="number">20</span>,ALICE=<span class="number">14</span>} +</pre> + + +<p><a href="../libraries/pl.tablex.html#map2">map2</a> applies a function to two tables:</p> + +<pre> +> map2(ops.add,{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">10</span>,<span class="number">20</span>}) +{<span class="number">11</span>,<span class="number">22</span>} +> map2(<span class="string">'*'</span>,{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">10</span>,<span class="number">20</span>}) +{<span class="number">10</span>,<span class="number">40</span>} +</pre> + + +<p>The various map operations generate tables; <a href="../libraries/pl.tablex.html#reduce">reduce</a> applies a function of two +arguments over a table and returns the result as a scalar:</p> + +<pre> +> reduce (<span class="string">'+'</span>, {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}) +<span class="number">6</span> +> reduce (<span class="string">'..'</span>, {<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>}) +<span class="string">'onetwothree'</span> +</pre> + + +<p>Finally, <a href="../libraries/pl.tablex.html#zip">zip</a> sews different tables together:</p> + +<pre> +> = zip({<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}) +{{<span class="number">1</span>,<span class="number">10</span>},{<span class="number">2</span>,<span class="number">20</span>},{<span class="number">3</span>,<span class="number">30</span>}} +</pre> + + +<p>Browsing through the documentation, you will find that <a href="../libraries/pl.tablex.html#">tablex</a> and <a href="../classes/pl.List.html#">List</a> share +methods. For instance, <a href="../libraries/pl.tablex.html#imap">tablex.imap</a> and <a href="../classes/pl.List.html#List:map">List.map</a> are basically the same +function; they both operate over the array-part of the table and generate another +table. This can also be expressed as a <em>list comprehension</em> <code>C 'f(x) for x' (t)</code> +which makes the operation more explicit. So why are there different ways to do +the same thing? The main reason is that not all tables are Lists: the expression +<code>ls:map('#')</code> will return a <em>list</em> of the lengths of any elements of <code>ls</code>. A list +is a thin wrapper around a table, provided by the metatable <a href="../classes/pl.List.html#">List</a>. Sometimes you +may wish to work with ordinary Lua tables; the <a href="../classes/pl.List.html#">List</a> interface is not a +compulsory way to use Penlight table operations.</p> + +<p><a name="Operations_on_two_dimensional_tables"></a></p> + +<h3>Operations on two-dimensional tables</h3> + +<p>Two-dimensional tables are of course easy to represent in Lua, for instance +<code>{{1,2},{3,4}}</code> where we store rows as subtables and index like so <code>A[col][row]</code>. +This is the common representation used by matrix libraries like +<a href="http://lua-users.org/wiki/LuaMatrix">LuaMatrix</a>. <a href="../libraries/pl.array2d.html#">pl.array2d</a> does not provide +matrix operations, since that is the job for a specialized library, but rather +provides generalizations of the higher-level operations provided by <a href="../libraries/pl.tablex.html#">pl.tablex</a> +for one-dimensional arrays.</p> + +<p><a href="../libraries/pl.array2d.html#iter">iter</a> is a useful generalization of <a href="https://www.lua.org/manual/5.1/manual.html#pdf-ipairs">ipairs</a>. (The extra parameter determines +whether you want the indices as well.)</p> + +<pre> +> a = {{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">3</span>,<span class="number">4</span>}} +> <span class="keyword">for</span> i,j,v <span class="keyword">in</span> array2d.iter(a,<span class="keyword">true</span>) <span class="keyword">do</span> <span class="global">print</span>(i,j,v) <span class="keyword">end</span> +<span class="number">1</span> <span class="number">1</span> <span class="number">1</span> +<span class="number">1</span> <span class="number">2</span> <span class="number">2</span> +<span class="number">2</span> <span class="number">1</span> <span class="number">3</span> +<span class="number">2</span> <span class="number">2</span> <span class="number">4</span> +</pre> + + +<p>Note that you can always convert an arbitrary 2D array into a ‘list of lists’ +with <code>List(tablex.map(List,a))</code></p> + +<p><a href="../libraries/pl.array2d.html#map">map</a> will apply a function over all elements (notice that extra arguments can be +provided, so this operation is in effect <code>function(x) return x-1 end</code>)</p> + +<pre> +> array2d.map(<span class="string">'-'</span>,a,<span class="number">1</span>) +{{<span class="number">0</span>,<span class="number">1</span>},{<span class="number">2</span>,<span class="number">3</span>}} +</pre> + + +<p>2D arrays are stored as an array of rows, but columns can be extracted:</p> + +<pre> +> array2d.column(a,<span class="number">1</span>) +{<span class="number">1</span>,<span class="number">3</span>} +</pre> + + +<p>There are three equivalents to <a href="../libraries/pl.tablex.html#reduce">tablex.reduce</a>. You can either reduce along the +rows (which is the most efficient) or reduce along the columns. Either one will +give you a 1D array. And <a href="../libraries/pl.array2d.html#reduce2">reduce2</a> will apply two operations: the first one +reduces the rows, and the second reduces the result.</p> + +<pre> +> array2d.reduce_rows(<span class="string">'+'</span>,a) +{<span class="number">3</span>,<span class="number">7</span>} +> array2d.reduce_cols(<span class="string">'+'</span>,a) +{<span class="number">4</span>,<span class="number">6</span>} +> <span class="comment">-- same as tablex.reduce('*',array.reduce_rows('+',a)) +</span>> array2d.reduce2(<span class="string">'*'</span>,<span class="string">'+'</span>,a) +<span class="number">21</span> ` +</pre> + + +<p><a href="../libraries/pl.tablex.html#map2">tablex.map2</a> applies an operation to two tables, giving another table. +<a href="../libraries/pl.array2d.html#map2">array2d.map2</a> does this for 2D arrays. Note that you have to provide the <em>rank</em> +of the arrays involved, since it’s hard to always correctly deduce this from the +data:</p> + +<pre> +> b = {{<span class="number">10</span>,<span class="number">20</span>},{<span class="number">30</span>,<span class="number">40</span>}} +> a = {{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">3</span>,<span class="number">4</span>}} +> = array2d.map2(<span class="string">'+'</span>,<span class="number">2</span>,<span class="number">2</span>,a,b) <span class="comment">-- two 2D arrays +</span>{{<span class="number">11</span>,<span class="number">22</span>},{<span class="number">33</span>,<span class="number">44</span>}} +> = array2d.map2(<span class="string">'+'</span>,<span class="number">1</span>,<span class="number">2</span>,{<span class="number">10</span>,<span class="number">100</span>},a) <span class="comment">-- 1D, 2D +</span>{{<span class="number">11</span>,<span class="number">102</span>},{<span class="number">13</span>,<span class="number">104</span>}} +> = array2d.map2(<span class="string">'*'</span>,<span class="number">2</span>,<span class="number">1</span>,a,{<span class="number">1</span>,-<span class="number">1</span>}) <span class="comment">-- 2D, 1D +</span>{{<span class="number">1</span>,-<span class="number">2</span>},{<span class="number">3</span>,-<span class="number">4</span>}} +</pre> + + +<p>Of course, you are not limited to simple arithmetic. Say we have a 2D array of +strings, and wish to print it out with proper right justification. The first step +is to create all the string lengths by mapping <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.len">string.len</a> over the array, the +second is to reduce this along the columns using <a href="https://www.lua.org/manual/5.1/manual.html#pdf-math.max">math.max</a> to get maximum column +widths, and last, apply <a href="../libraries/pl.stringx.html#rjust">stringx.rjust</a> with these widths.</p> + +<pre> +maxlens = reduce_cols(<span class="global">math</span>.max,map(<span class="string">'#'</span>,lines)) +lines = map2(stringx.rjust,<span class="number">2</span>,<span class="number">1</span>,lines,maxlens) +</pre> + + +<p>There is <a href="../libraries/pl.array2d.html#product">product</a> which returns the <em>Cartesian product</em> of two 1D arrays. The +result is a 2D array formed from applying the function to all possible pairs from +the two arrays.</p> + +<pre> +> array2d.product(<span class="string">'{}'</span>,{<span class="number">1</span>,<span class="number">2</span>},{<span class="string">'a'</span>,<span class="string">'b'</span>}) +{{{<span class="number">1</span>,<span class="string">'b'</span>},{<span class="number">2</span>,<span class="string">'a'</span>}},{{<span class="number">1</span>,<span class="string">'a'</span>},{<span class="number">2</span>,<span class="string">'b'</span>}}} +</pre> + + +<p>There is a set of operations which work in-place on 2D arrays. You can +<a href="../libraries/pl.array2d.html#swap_rows">swap_rows</a> and <a href="../libraries/pl.array2d.html#swap_cols">swap_cols</a>; the first really is a simple one-liner, but the idea +here is to give the operation a name. <a href="../libraries/pl.array2d.html#remove_row">remove_row</a> and <a href="../libraries/pl.array2d.html#remove_col">remove_col</a> are +generalizations of <a href="https://www.lua.org/manual/5.1/manual.html#pdf-table.remove">table.remove</a>. Likewise, <a href="../libraries/pl.array2d.html#extract_rows">extract_rows</a> and <a href="../libraries/pl.array2d.html#extract_cols">extract_cols</a> +are given arrays of indices and discard anything else. So, for instance, +<code>extract_cols(A,{2,4})</code> will leave just columns 2 and 4 in the array.</p> + +<p><a href="../classes/pl.List.html#List:slice">List.slice</a> is often useful on 1D arrays; <a href="../libraries/pl.array2d.html#slice">slice</a> does the same thing, but is +generally given a start (row,column) and a end (row,column).</p> + +<pre> +> A = {{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>},{<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>},{<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>}} +> B = slice(A,<span class="number">1</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">2</span>) +> write(B) + <span class="number">1</span> <span class="number">2</span> + <span class="number">4</span> <span class="number">5</span> +> B = slice(A,<span class="number">2</span>,<span class="number">2</span>) +> write(B,<span class="keyword">nil</span>,<span class="string">'%4.1f'</span>) + <span class="number">5.0</span> <span class="number">6.0</span> + <span class="number">8.0</span> <span class="number">9.0</span> +</pre> + + +<p>Here <a href="../libraries/pl.array2d.html#write">write</a> is used to print out an array nicely; the second parameter is <code>nil</code>, +which is the default (stdout) but can be any file object and the third parameter +is an optional format (as used in <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.format">string.format</a>).</p> + +<p><a href="../libraries/pl.array2d.html#parse_range">parse_range</a> will take a spreadsheet range like ‘A1:B2’ or ‘R1C1:R2C2’ and +return the range as four numbers, which can be passed to <a href="../libraries/pl.array2d.html#slice">slice</a>. The rule is +that <a href="../libraries/pl.array2d.html#slice">slice</a> will return an array of the appropriate shape depending on the +range; if a range represents a row or a column, the result is 1D, otherwise 2D.</p> + +<p>This applies to <a href="../libraries/pl.array2d.html#iter">iter</a> as well, which can also optionally be given a range:</p> + +<pre> +> <span class="keyword">for</span> i,j,v <span class="keyword">in</span> iter(A,<span class="keyword">true</span>,<span class="number">2</span>,<span class="number">2</span>) <span class="keyword">do</span> <span class="global">print</span>(i,j,v) <span class="keyword">end</span> +<span class="number">2</span> <span class="number">2</span> <span class="number">5</span> +<span class="number">2</span> <span class="number">3</span> <span class="number">6</span> +<span class="number">3</span> <span class="number">2</span> <span class="number">8</span> +<span class="number">3</span> <span class="number">3</span> <span class="number">9</span> +</pre> + + +<p><a href="../libraries/pl.array2d.html#new">new</a> will construct a new 2D array with the given dimensions. You provide an +initial value for the elements, which is interpreted as a function if it’s +callable. With <code>L</code> being <a href="../libraries/pl.utils.html#string_lambda">utils.string_lambda</a> we then have the following way to +make an <em>identity matrix</em>:</p> + +<pre> +asserteq( + array.new(<span class="number">3</span>,<span class="number">3</span>,L<span class="string">'|i,j| i==j and 1 or 0'</span>), + {{<span class="number">1</span>,<span class="number">0</span>,<span class="number">0</span>},{<span class="number">0</span>,<span class="number">1</span>,<span class="number">0</span>},{<span class="number">0</span>,<span class="number">0</span>,<span class="number">1</span>}} +) +</pre> + + +<p>Please note that most functions in <a href="../libraries/pl.array2d.html#">array2d</a> are <em>covariant</em>, that is, they +return an array of the same type as they receive. In particular, any objects +created with <a href="../libraries/pl.data.html#new">data.new</a> or <code>matrix.new</code> will remain data or matrix objects when +reshaped or sliced, etc. Data objects have the <a href="../libraries/pl.array2d.html#">array2d</a> functions available as +methods.</p> + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/03-strings.md.html b/docs/manual/03-strings.md.html new file mode 100644 index 0000000..987a49d --- /dev/null +++ b/docs/manual/03-strings.md.html @@ -0,0 +1,397 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Extra_String_Methods">Extra String Methods </a></li> +<li><a href="#String_Templates">String Templates </a></li> +<li><a href="#Another_Style_of_Template">Another Style of Template </a></li> +<li><a href="#File_style_I_O_on_Strings">File-style I/O on Strings </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><strong>Strings. Higher-level operations on strings.</strong></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Strings. Higher-level operations on strings.</h2> + +<p><a name="Extra_String_Methods"></a></p> + +<h3>Extra String Methods</h3> + +<p>These are convenient borrowings from Python, as described in 3.6.1 of the Python +reference, but note that indices in Lua always begin at one. <a href="../libraries/pl.stringx.html#">stringx</a> defines +functions like <a href="../libraries/pl.stringx.html#isalpha">isalpha</a> and <a href="../libraries/pl.stringx.html#isdigit">isdigit</a>, which return <code>true</code> if s is only composed +of letters or digits respectively. <a href="../libraries/pl.stringx.html#startswith">startswith</a> and <a href="../libraries/pl.stringx.html#endswith">endswith</a> are convenient +ways to find substrings. (<a href="../libraries/pl.stringx.html#endswith">endswith</a> works as in Python 2.5, so that <code>f:endswith +{'.bat','.exe','.cmd'}</code> will be true for any filename which ends with these +extensions.) There are justify methods and whitespace trimming functions like +<a href="../libraries/pl.stringx.html#strip">strip</a>.</p> + +<pre> +> stringx.import() +> (<span class="string">'bonzo.dog'</span>):endswith {<span class="string">'.dog'</span>,<span class="string">'.cat'</span>} +<span class="keyword">true</span> +> (<span class="string">'bonzo.txt'</span>):endswith {<span class="string">'.dog'</span>,<span class="string">'.cat'</span>} +<span class="keyword">false</span> +> (<span class="string">'bonzo.cat'</span>):endswith {<span class="string">'.dog'</span>,<span class="string">'.cat'</span>} +<span class="keyword">true</span> +> (<span class="string">' stuff'</span>):ljust(<span class="number">20</span>,<span class="string">'+'</span>) +<span class="string">'++++++++++++++ stuff'</span> +> (<span class="string">' stuff '</span>):lstrip() +<span class="string">'stuff '</span> +> (<span class="string">' stuff '</span>):rstrip() +<span class="string">' stuff'</span> +> (<span class="string">' stuff '</span>):strip() +<span class="string">'stuff'</span> +> <span class="keyword">for</span> s <span class="keyword">in</span> (<span class="string">'one\ntwo\nthree\n'</span>):lines() <span class="keyword">do</span> <span class="global">print</span>(s) <span class="keyword">end</span> +one +two +three +</pre> + + +<p>Most of these can be fairly easily implemented using the Lua string library, +which is more general and powerful. But they are convenient operations to have +easily at hand. Note that can be injected into the <a href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> table if you use +<code>stringx.import</code>, but a simple alias like <code>local stringx = require 'pl.stringx'</code> +is preferrable. This is the recommended practice when writing modules for +consumption by other people, since it is bad manners to change the global state +of the rest of the system. Magic may be used for convenience, but there is always +a price.</p> + +<p><a name="String_Templates"></a></p> + +<h3>String Templates</h3> + +<p>Another borrowing from Python, string templates allow you to substitute values +looked up in a table:</p> + +<pre> +<span class="keyword">local</span> Template = <span class="global">require</span> (<span class="string">'pl.text'</span>).Template +t = Template(<span class="string">'${here} is the $answer'</span>) +<span class="global">print</span>(t:substitute {here = <span class="string">'Lua'</span>, answer = <span class="string">'best'</span>}) +==> +Lua is the best +</pre> + + +<p>‘$ variables’ can optionally have curly braces; this form is useful if you are +glueing text together to make variables, e.g <code>${prefix}_name_${postfix}</code>. The +<a href="../libraries/pl.text.html#Template:substitute">substitute</a> method will throw an error if a $ variable is not found in the +table, and the <a href="../libraries/pl.text.html#Template:safe_substitute">safe_substitute</a> method will not.</p> + +<p>The Lua implementation has an extra method, <a href="../libraries/pl.text.html#Template:indent_substitute">indent_substitute</a> which is very +useful for inserting blocks of text, because it adjusts indentation. Consider +this example:</p> + +<pre> +<span class="comment">-- testtemplate.lua +</span><span class="keyword">local</span> Template = <span class="global">require</span> (<span class="string">'pl.text'</span>).Template + +t = Template <span class="string">[[ + for i = 1,#$t do + $body + end +]]</span> + +body = Template <span class="string">[[ +local row = $t[i] +for j = 1,#row do + fun(row[j]) +end +]]</span> + +<span class="global">print</span>(t:indent_substitute {body=body,t=<span class="string">'tbl'</span>}) +</pre> + + +<p>And the output is:</p> + +<pre> +<span class="keyword">for</span> i = <span class="number">1</span>,#tbl <span class="keyword">do</span> + <span class="keyword">local</span> row = tbl[i] + <span class="keyword">for</span> j = <span class="number">1</span>,#row <span class="keyword">do</span> + fun(row[j]) + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p><a href="../libraries/pl.text.html#Template:indent_substitute">indent_substitute</a> can substitute templates, and in which case they themselves +will be substituted using the given table. So in this case, <code>$t</code> was substituted +twice.</p> + +<p><a href="../libraries/pl.text.html#">pl.text</a> also has a number of useful functions like <a href="../libraries/pl.text.html#dedent">dedent</a>, which strips all +the initial indentation from a multiline string. As in Python, this is useful for +preprocessing multiline strings if you like indenting them with your code. The +function <a href="../libraries/pl.text.html#wrap">wrap</a> is passed a long string (a <em>paragraph</em>) and returns a list of +lines that fit into a desired line width. As an extension, there is also <a href="../libraries/pl.text.html#indent">indent</a> +for indenting multiline strings.</p> + +<p>New in Penlight with the 0.9 series is <code>text.format_operator</code>. Calling this +enables Python-style string formating using the modulo operator <code>%</code>:</p> + +<pre> +> text.format_operator() +> = <span class="string">'%s[%d]'</span> % {<span class="string">'dog'</span>,<span class="number">1</span>} +dog[<span class="number">1</span>] +</pre> + + +<p>So in its simplest form it saves the typing involved with <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.format">string.format</a>; it +will also expand <code>$</code> variables using named fields:</p> + +<pre> +> = <span class="string">'$animal[$num]'</span> % {animal=<span class="string">'dog'</span>,num=<span class="number">1</span>} +dog[<span class="number">1</span>] +</pre> + + +<p>As with <code>stringx.import</code> you have to do this explicitly, since all strings share the same +metatable. But in your own scripts you can feel free to do this.</p> + +<p><a name="Another_Style_of_Template"></a></p> + +<h3>Another Style of Template</h3> + +<p>A new module is <a href="../libraries/pl.template.html#">template</a>, which is a version of Rici Lake’s <a href="http://lua-users.org/wiki/SlightlyLessSimpleLuaPreprocessor">Lua +Preprocessor</a>. This +allows you to mix Lua code with your templates in a straightforward way. There +are only two rules:</p> + +<ul> +<li>Lines begining with <code>#</code> are Lua</li> +<li>Otherwise, anything inside <code>$()</code> is a Lua expression.</li> +</ul> + + +<p>So a template generating an HTML list would look like this:</p> + +<pre> +<ul> +# <span class="keyword">for</span> i,val <span class="keyword">in</span> <span class="global">ipairs</span>(T) <span class="keyword">do</span> +<li>$(i) = $(val:upper())</li> +# <span class="keyword">end</span> +</ul> +</pre> + + +<p>Assume the text is inside <code>tmpl</code>, then the template can be expanded using:</p> + +<pre> +<span class="keyword">local</span> template = <span class="global">require</span> <span class="string">'pl.template'</span> +<span class="keyword">local</span> my_env = { + <span class="global">ipairs</span> = <span class="global">ipairs</span>, + T = {<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'three'</span>} +} +res = template.substitute(tmpl, my_env) +</pre> + + +<p>and we get</p> + +<pre> +<ul> +<li><span class="number">1</span> = ONE</li> +<li><span class="number">2</span> = TWO</li> +<li><span class="number">3</span> = THREE</li> +</ul> +</pre> + + +<p>There is a single function, <a href="../libraries/pl.template.html#substitute">template.substitute</a> which is passed a template +string and an environment table. This table may contain some special fields, +like <code>\<em>parent</code> which can be set to a table representing a ‘fallback’ environment +in case a symbol was not found. <code>\</em>brackets</code> is usually ‘()’ and <code>\_escape</code> is +usually ‘#’ but it’s sometimes necessary to redefine these if the defaults +interfere with the target language - for instance, <code>$(V)</code> has another meaning in +Make, and <code>#</code> means a preprocessor line in C/C++.</p> + +<p>Finally, if something goes wrong, passing <code>_debug</code> will cause the intermediate +Lua code to be dumped if there’s a problem.</p> + +<p>Here is a C code generation example; something that could easily be extended to +be a minimal Lua extension skeleton generator.</p> + +<pre> +<span class="keyword">local</span> subst = <span class="global">require</span> <span class="string">'pl.template'</span>.substitute + +<span class="keyword">local</span> templ = <span class="string">[[ +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> + +> for _,f in ipairs(mod) do +static int l_$(f.name) (lua_State *L) { + +} +> end + +static const luaL_reg $(mod.name)[] = { +> for _,f in ipairs(mod) do + {"$(f.name)",l_$(f.name)}, +> end + {NULL,NULL} +}; + +int luaopen_$(mod.name) { + luaL_register (L, "$(mod.name)", $(mod.name)); + return 1; +} +]]</span> + +<span class="global">print</span>(subst(templ,{ + _escape = <span class="string">'>'</span>, + <span class="global">ipairs</span> = <span class="global">ipairs</span>, + mod = { + name = <span class="string">'baggins'</span>; + {name=<span class="string">'frodo'</span>}, + {name=<span class="string">'bilbo'</span>} + } +})) +</pre> + + +<p><a name="File_style_I_O_on_Strings"></a></p> + +<h3>File-style I/O on Strings</h3> + +<p><a href="../libraries/pl.stringio.html#">pl.stringio</a> provides just three functions; <a href="../libraries/pl.stringio.html#open">stringio.open</a> is passed a string, +and returns a file-like object for reading. It supports a <code>read</code> method, which +takes the same arguments as standard file objects:</p> + +<pre> +> f = stringio.open <span class="string">'first line\n10 20 30\n'</span> +> = f:read() +first line +> = f:read(<span class="string">'*n'</span>,<span class="string">'*n'</span>,<span class="string">'*n'</span>) +<span class="number">10</span> <span class="number">20</span> <span class="number">30</span> +</pre> + + +<p><code>lines</code> and <code>seek</code> are also supported.</p> + +<p><code>stringio.lines</code> is a useful short-cut for iterating over all the lines in a +string.</p> + +<p><a href="../libraries/pl.stringio.html#create">stringio.create</a> creates a writeable file-like object. You then use <code>write</code> to +this stream, and finally extract the builded string using <code>value</code>. This ‘string +builder’ pattern is useful for efficiently creating large strings.</p> + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/04-paths.md.html b/docs/manual/04-paths.md.html new file mode 100644 index 0000000..125b53c --- /dev/null +++ b/docs/manual/04-paths.md.html @@ -0,0 +1,330 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Working_with_Paths">Working with Paths </a></li> +<li><a href="#File_Operations">File Operations </a></li> +<li><a href="#Directory_Operations">Directory Operations </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><strong>Paths and Directories</strong></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Paths and Directories</h2> + +<p><a name="Working_with_Paths"></a></p> + +<h3>Working with Paths</h3> + +<p>Programs should not depend on quirks of your operating system. They will be +harder to read, and need to be ported for other systems. The worst of course is +hardcoding paths like ‘c:\’ in programs, and wondering why Vista complains so +much. But even something like <code>dir..'\'..file</code> is a problem, since Unix can’t +understand backslashes in this way. <code>dir..'/'..file</code> is <em>usually</em> portable, but +it’s best to put this all into a simple function, <a href="../libraries/pl.path.html#join">path.join</a>. If you +consistently use <a href="../libraries/pl.path.html#join">path.join</a>, then it’s much easier to write cross-platform code, +since it handles the directory separator for you.</p> + +<p><a href="../libraries/pl.path.html#">pl.path</a> provides the same functionality as Python’s <code>os.path</code> module (11.1).</p> + +<pre> +> p = <span class="string">'c:\\bonzo\\DOG.txt'</span> +> = path.normcase (p) <span class="comment">---> only makes sense on Windows +</span>c:\bonzo\dog.txt +> = path.splitext (p) +c:\bonzo\DOG .txt +> = path.extension (p) +.txt +> = path.basename (p) +DOG.txt +> = path.exists(p) +<span class="keyword">false</span> +> = path.join (<span class="string">'fred'</span>,<span class="string">'alice.txt'</span>) +fred\alice.txt +> = path.exists <span class="string">'pretty.lua'</span> +<span class="keyword">true</span> +> = path.getsize <span class="string">'pretty.lua'</span> +<span class="number">2125</span> +> = path.isfile <span class="string">'pretty.lua'</span> +<span class="keyword">true</span> +> = path.isdir <span class="string">'pretty.lua'</span> +<span class="keyword">false</span> +</pre> + + +<p>It is very important for all programmers, not just on Unix, to only write to +where they are allowed to write. <a href="../libraries/pl.path.html#expanduser">path.expanduser</a> will expand ‘~’ (tilde) into +the home directory. Depending on your OS, this will be a guaranteed place where +you can create files:</p> + +<pre> +> = path.expanduser <span class="string">'~/mydata.txt'</span> +<span class="string">'C:\Documents and Settings\SJDonova/mydata.txt'</span> + +> = path.expanduser <span class="string">'~/mydata.txt'</span> +/home/sdonovan/mydata.txt +</pre> + + +<p>Under Windows, <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.tmpname">os.tmpname</a> returns a path which leads to your drive root full of +temporary files. (And increasingly, you do not have access to this root folder.) +This is corrected by <a href="../libraries/pl.path.html#tmpname">path.tmpname</a>, which uses the environment variable TMP:</p> + +<pre> +> <span class="global">os</span>.tmpname() <span class="comment">-- not a good place to put temporary files! +</span><span class="string">'\s25g.'</span> +> path.tmpname() +<span class="string">'C:\DOCUME~1\SJDonova\LOCALS~1\Temp\s25g.1'</span> +</pre> + + +<p>A useful extra function is <a href="../libraries/pl.path.html#package_path">pl.path.package_path</a>, which will tell you the path +of a particular Lua module. So on my system, <code>package_path('pl.path')</code> returns +‘C:\Program Files\Lua\5.1\lualibs\pl\path.lua’, and <code>package_path('ifs')</code> returns +‘C:\Program Files\Lua\5.1\clibs\lfs.dll’. It is implemented in terms of +<a href="https://www.lua.org/manual/5.1/manual.html#pdf-package.searchpath">package.searchpath</a>, which is a new function in Lua 5.2 which has been +implemented for Lua 5.1 in Penlight.</p> + +<p><a name="File_Operations"></a></p> + +<h3>File Operations</h3> + +<p><a href="../libraries/pl.file.html#">pl.file</a> is a new module that provides more sensible names for common file +operations. For instance, <a href="https://www.lua.org/manual/5.1/manual.html#pdf-file:read">file.read</a> and <a href="https://www.lua.org/manual/5.1/manual.html#pdf-file:write">file.write</a> are aliases for +<a href="../libraries/pl.utils.html#readfile">utils.readfile</a> and <a href="../libraries/pl.utils.html#writefile">utils.writefile</a>.</p> + +<p>Smaller files can be efficiently read and written in one operation. <a href="https://www.lua.org/manual/5.1/manual.html#pdf-file:read">file.read</a> +is passed a filename and returns the contents as a string, if successful; if not, +then it returns <code>nil</code> and the actual error message. There is an optional boolean +parameter if you want the file to be read in binary mode (this makes no +difference on Unix but remains important with Windows.)</p> + +<p>In previous versions of Penlight, <a href="../libraries/pl.utils.html#readfile">utils.readfile</a> would read standard input if +the file was not specified, but this can lead to nasty bugs; use <code>io.read '*a'</code> +to grab all of standard input.</p> + +<p>Similarly, <a href="https://www.lua.org/manual/5.1/manual.html#pdf-file:write">file.write</a> takes a filename and a string which will be written to +that file.</p> + +<p>For example, this little script converts a file into upper case:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +<span class="global">assert</span>(#arg == <span class="number">2</span>, <span class="string">'supply two filenames'</span>) +text = <span class="global">assert</span>(file.read(arg[<span class="number">1</span>])) +<span class="global">assert</span>(file.write(arg[<span class="number">2</span>],text:upper())) +</pre> + + +<p>Copying files is suprisingly tricky. <a href="../libraries/pl.file.html#copy">file.copy</a> and <a href="../libraries/pl.file.html#move">file.move</a> attempt to use +the best implementation possible. On Windows, they link to the API functions +<code>CopyFile</code> and <code>MoveFile</code>, but only if the <code>alien</code> package is installed (this is +true for Lua for Windows.) Otherwise, the system copy command is used. This can +be ugly when writing Windows GUI applications, because of the dreaded flashing +black-box problem with launching processes.</p> + +<p><a name="Directory_Operations"></a></p> + +<h3>Directory Operations</h3> + +<p><a href="../libraries/pl.dir.html#">pl.dir</a> provides some useful functions for working with directories. <code>fnmatch</code> +will match a filename against a shell pattern, and <code>filter</code> will return any files +in the supplied list which match the given pattern, which correspond to the +functions in the Python <code>fnmatch</code> module. <code>getdirectories</code> will return all +directories contained in a directory, and <code>getfiles</code> will return all files in a +directory which match a shell pattern. These functions return the files as a +table, unlike <a href="http://stevedonovan.github.io/lua-stdlibs/modules/lfs.html#dir">lfs.dir</a> which returns an iterator.)</p> + +<p><a href="../libraries/pl.dir.html#makepath">dir.makepath</a> can create a full path, creating subdirectories as necessary; +<code>rmtree</code> is the Nuclear Option of file deleting functions, since it will +recursively clear out and delete all directories found begining at a path (there +is a similar function with this name in the Python <code>shutils</code> module.)</p> + +<pre> +> = dir.makepath <span class="string">'t\\temp\\bonzo'</span> +> = path.isdir <span class="string">'t\\temp\\bonzo'</span> +<span class="keyword">true</span> +> = dir.rmtree <span class="string">'t'</span> +</pre> + + +<p><a href="../libraries/pl.dir.html#rmtree">dir.rmtree</a> depends on <a href="../libraries/pl.dir.html#walk">dir.walk</a>, which is a powerful tool for scanning a whole +directory tree. Here is the implementation of <a href="../libraries/pl.dir.html#rmtree">dir.rmtree</a>:</p> + +<pre> +<span class="comment">--- remove a whole directory tree. +</span><span class="comment">-- @param path A directory path +</span><span class="keyword">function</span> dir.rmtree(fullpath) + <span class="keyword">for</span> root,dirs,files <span class="keyword">in</span> dir.walk(fullpath) <span class="keyword">do</span> + <span class="keyword">for</span> i,f <span class="keyword">in</span> <span class="global">ipairs</span>(files) <span class="keyword">do</span> + <span class="global">os</span>.remove(path.join(root,f)) + <span class="keyword">end</span> + lfs.rmdir(root) + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p><a href="../libraries/pl.dir.html#clonetree">dir.clonetree</a> clones directory trees. The first argument is a path that must +exist, and the second path is the path to be cloned. (Note that this path cannot +be <em>inside</em> the first path, since this leads to madness.) By default, it will +then just recreate the directory structure. You can in addition provide a +function, which will be applied for all files found.</p> + +<pre> +<span class="comment">-- make a copy of my libs folder +</span><span class="global">require</span> <span class="string">'pl'</span> +p1 = <span class="string">[[d:\dev\lua\libs]]</span> +p2 = <span class="string">[[D:\dev\lua\libs\..\tests]]</span> +dir.clonetree(p1,p2,dir.copyfile) +</pre> + + +<p>A more sophisticated version, which only copies files which have been modified:</p> + +<pre> +<span class="comment">-- p1 and p2 as before, or from arg[1] and arg[2] +</span>dir.clonetree(p1,p2,<span class="keyword">function</span>(f1,f2) + <span class="keyword">local</span> res + <span class="keyword">local</span> t1,t2 = path.getmtime(f1),path.getmtime(f2) + <span class="comment">-- f2 might not exist, so be careful about t2 +</span> <span class="keyword">if</span> <span class="keyword">not</span> t2 <span class="keyword">or</span> t1 > t2 <span class="keyword">then</span> + res = dir.copyfile(f1,f2) + <span class="keyword">end</span> + <span class="keyword">return</span> res <span class="comment">-- indicates successful operation +</span><span class="keyword">end</span>) +</pre> + + +<p><a href="../libraries/pl.dir.html#clonetree">dir.clonetree</a> uses <a href="../libraries/pl.path.html#common_prefix">path.common_prefix</a>. With <code>p1</code> and <code>p2</code> defined above, the +common path is ’d:\dev\lua'. So ’d:\dev\lua\libs\testfunc.lua' is copied to +’d:\dev\lua\test\testfunc.lua', etc.</p> + +<p>If you need to find the common path of list of files, then <a href="../libraries/pl.tablex.html#reduce">tablex.reduce</a> will +do the job:</p> + +<pre> +> p3 = <span class="string">[[d:\dev]]</span> +> = tablex.reduce(path.common_prefix,{p1,p2,p3}) +<span class="string">'d:\dev'</span> +</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/05-dates.md.html b/docs/manual/05-dates.md.html new file mode 100644 index 0000000..46b78c3 --- /dev/null +++ b/docs/manual/05-dates.md.html @@ -0,0 +1,266 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Creating_and_Displaying_Dates">Creating and Displaying Dates </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><strong>Date and Time</strong></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Date and Time</h2> + +<p><a id="date"></a></p> + +<p><a name="Creating_and_Displaying_Dates"></a></p> + +<h3>Creating and Displaying Dates</h3> + +<p>The <a href="../classes/pl.Date.html#">Date</a> class provides a simplified way to work with <a href="http://www.lua.org/pil/22.1.html">date and +time</a> in Lua; it leans heavily on the functions +<a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.date">os.date</a> and <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.time">os.time</a>.</p> + +<p>A <a href="../classes/pl.Date.html#">Date</a> object can be constructed from a table, just like with <a href="https://www.lua.org/manual/5.1/manual.html#pdf-os.time">os.time</a>. +Methods are provided to get and set the various parts of the date.</p> + +<pre> +> d = Date {year = <span class="number">2011</span>, month = <span class="number">3</span>, day = <span class="number">2</span> } +> = d +<span class="number">2011</span>-<span class="number">03</span>-<span class="number">02</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = d:month(),d:year(),d:day() +<span class="number">3</span> <span class="number">2011</span> <span class="number">2</span> +> d:month(<span class="number">4</span>) +> = d +<span class="number">2011</span>-<span class="number">04</span>-<span class="number">02</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> d:add {day=<span class="number">1</span>} +> = d +<span class="number">2011</span>-<span class="number">04</span>-<span class="number">03</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +</pre> + + +<p><code>add</code> takes a table containing one of the date table fields.</p> + +<pre> +> = d:weekday_name() +Sun +> = d:last_day() +<span class="number">2011</span>-<span class="number">04</span>-<span class="number">30</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = d:month_name(<span class="keyword">true</span>) +April +</pre> + + +<p>There is a default conversion to text for date objects, but <a href="../classes/pl.Date.html#Date.Format">Date.Format</a> gives +you full control of the format for both parsing and displaying dates:</p> + +<pre> +> iso = Date.Format <span class="string">'yyyy-mm-dd'</span> +> d = iso:parse <span class="string">'2010-04-10'</span> +> amer = Date.Format <span class="string">'mm/dd/yyyy'</span> +> = amer:<span class="global">tostring</span>(d) +<span class="number">04</span>/<span class="number">10</span>/<span class="number">2010</span> +</pre> + + +<p>With the 0.9.7 relase, the <a href="../classes/pl.Date.html#">Date</a> constructor has become more flexible. You may +omit any of the ‘year’, ‘month’ or ‘day’ fields:</p> + +<pre> +> = Date { year = <span class="number">2008</span> } +<span class="number">2008</span>-<span class="number">01</span>-<span class="number">01</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = Date { month = <span class="number">3</span> } +<span class="number">2011</span>-<span class="number">03</span>-<span class="number">01</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = Date { day = <span class="number">20</span> } +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">20</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = Date { hour = <span class="number">14</span>, min = <span class="number">30</span> } +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">13</span> <span class="number">14</span>:<span class="number">30</span>:<span class="number">00</span> +</pre> + + +<p>If ‘year’ is omitted, then the current year is assumed, and likewise for ‘month’.</p> + +<p>To set the time on such a partial date, you can use the fact that the ‘setter’ +methods return the date object and so you can ‘chain’ these methods.</p> + +<pre> +> d = Date { day = <span class="number">03</span> } +> = d:hour(<span class="number">18</span>):min(<span class="number">30</span>) +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">03</span> <span class="number">18</span>:<span class="number">30</span>:<span class="number">00</span> +</pre> + + +<p>Finally, <a href="../classes/pl.Date.html#">Date</a> also now accepts positional arguments:</p> + +<pre> +> = Date(<span class="number">2011</span>,<span class="number">10</span>,<span class="number">3</span>) +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">03</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = Date(<span class="number">2011</span>,<span class="number">10</span>,<span class="number">3</span>,<span class="number">18</span>,<span class="number">30</span>,<span class="number">23</span>) +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">03</span> <span class="number">18</span>:<span class="number">30</span>:<span class="number">23</span> +</pre> + + +<p><code>Date.format</code> has been extended. If you construct an instance without a pattern, +then it will try to match against a set of known formats. This is useful for +human-input dates since keeping to a strict format is not one of the strong +points of users. It assumes that there will be a date, and then a date.</p> + +<pre> +> df = Date.Format() +> = df:parse <span class="string">'5.30pm'</span> +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">13</span> <span class="number">17</span>:<span class="number">30</span>:<span class="number">00</span> +> = df:parse <span class="string">'1730'</span> +<span class="keyword">nil</span> day out of range: <span class="number">1730</span> is <span class="keyword">not</span> between <span class="number">1</span> <span class="keyword">and</span> <span class="number">31</span> +> = df:parse <span class="string">'17.30'</span> +<span class="number">2011</span>-<span class="number">10</span>-<span class="number">13</span> <span class="number">17</span>:<span class="number">30</span>:<span class="number">00</span> +> = df:parse <span class="string">'mar'</span> +<span class="number">2011</span>-<span class="number">03</span>-<span class="number">01</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = df:parse <span class="string">'3 March'</span> +<span class="number">2011</span>-<span class="number">03</span>-<span class="number">03</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = df:parse <span class="string">'15 March'</span> +<span class="number">2011</span>-<span class="number">03</span>-<span class="number">15</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = df:parse <span class="string">'15 March 2008'</span> +<span class="number">2008</span>-<span class="number">03</span>-<span class="number">15</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +> = df:parse <span class="string">'15 March 2008 1.30pm'</span> +<span class="number">2008</span>-<span class="number">03</span>-<span class="number">15</span> <span class="number">13</span>:<span class="number">30</span>:<span class="number">00</span> +> = df:parse <span class="string">'2008-10-03 15:30:23'</span> +<span class="number">2008</span>-<span class="number">10</span>-<span class="number">03</span> <span class="number">15</span>:<span class="number">30</span>:<span class="number">23</span> +</pre> + + +<p>ISO date format is of course a good idea if you need to deal with users from +different countries. Here is the default behaviour for ‘short’ dates:</p> + +<pre> +> = df:parse <span class="string">'24/02/12'</span> +<span class="number">2012</span>-<span class="number">02</span>-<span class="number">24</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +</pre> + + +<p>That’s not what Americans expect! It’s tricky to work out in a cross-platform way +exactly what the expected format is, so there is an explicit flag:</p> + +<pre> +> df:US_order(<span class="keyword">true</span>) +> = df:parse <span class="string">'9/11/01'</span> +<span class="number">2001</span>-<span class="number">11</span>-<span class="number">09</span> <span class="number">12</span>:<span class="number">00</span>:<span class="number">00</span> +</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/06-data.md.html b/docs/manual/06-data.md.html new file mode 100644 index 0000000..44bd4ed --- /dev/null +++ b/docs/manual/06-data.md.html @@ -0,0 +1,1638 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Reading_Data_Files">Reading Data Files </a></li> +<li><a href="#Reading_Unstructured_Text_Data">Reading Unstructured Text Data </a></li> +<li><a href="#Reading_Columnar_Data">Reading Columnar Data </a></li> +<li><a href="#Reading_Configuration_Files">Reading Configuration Files </a></li> +<li><a href="#Lexical_Scanning">Lexical Scanning </a></li> +<li><a href="#XML">XML </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><strong>Data</strong></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Data</h2> + +<p><a name="Reading_Data_Files"></a></p> + +<h3>Reading Data Files</h3> + +<p>The first thing to consider is this: do you actually need to write a custom file +reader? And if the answer is yes, the next question is: can you write the reader +in as clear a way as possible? Correctness, Robustness, and Speed; pick the first +two and the third can be sorted out later, <em>if necessary</em>.</p> + +<p>A common sort of data file is the configuration file format commonly used on Unix +systems. This format is often called a <em>property</em> file in the Java world.</p> + +<pre> +# Read timeout <span class="keyword">in</span> seconds +read.timeout=<span class="number">10</span> + +# Write timeout <span class="keyword">in</span> seconds +write.timeout=<span class="number">10</span> +</pre> + + +<p>Here is a simple Lua implementation:</p> + +<pre> +<span class="comment">-- property file parsing with Lua string patterns +</span>props = [] +<span class="keyword">for</span> line <span class="keyword">in</span> <span class="global">io</span>.lines() <span class="keyword">do</span> + <span class="keyword">if</span> line:find(<span class="string">'#'</span>,<span class="number">1</span>,<span class="keyword">true</span>) ~= <span class="number">1</span> <span class="keyword">and</span> <span class="keyword">not</span> line:find(<span class="string">'^%s*$'</span>) <span class="keyword">then</span> + <span class="keyword">local</span> var,value = line:match(<span class="string">'([^=]+)=(.*)'</span>) + props[var] = value + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>Very compact, but it suffers from a similar disease in equivalent Perl programs; +it uses odd string patterns which are ‘lexically noisy’. Noisy code like this +slows the casual reader down. (For an even more direct way of doing this, see the +next section, ‘Reading Configuration Files’)</p> + +<p>Another implementation, using the Penlight libraries:</p> + +<pre> +<span class="comment">-- property file parsing with extended string functions +</span><span class="global">require</span> <span class="string">'pl'</span> +stringx.import() +props = [] +<span class="keyword">for</span> line <span class="keyword">in</span> <span class="global">io</span>.lines() <span class="keyword">do</span> + <span class="keyword">if</span> <span class="keyword">not</span> line:startswith(<span class="string">'#'</span>) <span class="keyword">and</span> <span class="keyword">not</span> line:isspace() <span class="keyword">then</span> + <span class="keyword">local</span> var,value = line:splitv(<span class="string">'='</span>) + props[var] = value + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>This is more self-documenting; it is generally better to make the code express +the <em>intention</em>, rather than having to scatter comments everywhere - comments are +necessary, of course, but mostly to give the higher view of your intention that +cannot be expressed in code. It is slightly slower, true, but in practice the +speed of this script is determined by I/O, so further optimization is unnecessary.</p> + +<p><a name="Reading_Unstructured_Text_Data"></a></p> + +<h3>Reading Unstructured Text Data</h3> + +<p>Text data is sometimes unstructured, for example a file containing words. The +<a href="../libraries/pl.input.html#">pl.input</a> module has a number of functions which makes processing such files +easier. For example, a script to count the number of words in standard input +using <code>import.words</code>:</p> + +<pre> +<span class="comment">-- countwords.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +<span class="keyword">local</span> k = <span class="number">1</span> +<span class="keyword">for</span> w <span class="keyword">in</span> input.words(<span class="global">io</span>.stdin) <span class="keyword">do</span> + k = k + <span class="number">1</span> +<span class="keyword">end</span> +<span class="global">print</span>(<span class="string">'count'</span>,k) +</pre> + + +<p>Or this script to calculate the average of a set of numbers using <a href="../libraries/pl.input.html#numbers">input.numbers</a>:</p> + +<pre> +<span class="comment">-- average.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +<span class="keyword">local</span> k = <span class="number">1</span> +<span class="keyword">local</span> sum = <span class="number">0</span> +<span class="keyword">for</span> n <span class="keyword">in</span> input.numbers(<span class="global">io</span>.stdin) <span class="keyword">do</span> + sum = sum + n + k = k + <span class="number">1</span> +<span class="keyword">end</span> +<span class="global">print</span>(<span class="string">'average'</span>,sum/k) +</pre> + + +<p>These scripts can be improved further by <em>eliminating loops</em> In the last case, +there is a perfectly good function <a href="../libraries/pl.seq.html#sum">seq.sum</a> which can already take a sequence of +numbers and calculate these numbers for us:</p> + +<pre> +<span class="comment">-- average2.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +<span class="keyword">local</span> total,n = seq.sum(input.numbers()) +<span class="global">print</span>(<span class="string">'average'</span>,total/n) +</pre> + + +<p>A further simplification here is that if <code>numbers</code> or <code>words</code> are not passed an +argument, they will grab their input from standard input. The first script can +be rewritten:</p> + +<pre> +<span class="comment">-- countwords2.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +<span class="global">print</span>(<span class="string">'count'</span>,seq.count(input.words())) +</pre> + + +<p>A useful feature of a sequence generator like <code>numbers</code> is that it can read from +a string source. Here is a script to calculate the sums of the numbers on each +line in a file:</p> + +<pre> +<span class="comment">-- sums.lua +</span><span class="keyword">for</span> line <span class="keyword">in</span> <span class="global">io</span>.lines() <span class="keyword">do</span> + <span class="global">print</span>(seq.sum(input.numbers(line)) +<span class="keyword">end</span> +</pre> + + +<p><a name="Reading_Columnar_Data"></a></p> + +<h3>Reading Columnar Data</h3> + +<p>It is very common to find data in columnar form, either space or comma-separated, +perhaps with an initial set of column headers. Here is a typical example:</p> + +<pre> +EventID Magnitude LocationX LocationY LocationZ +<span class="number">981124001</span> <span class="number">2.0</span> <span class="number">18988.4</span> <span class="number">10047.1</span> <span class="number">4149.7</span> +<span class="number">981125001</span> <span class="number">0.8</span> <span class="number">19104.0</span> <span class="number">9970.4</span> <span class="number">5088.7</span> +<span class="number">981127003</span> <span class="number">0.5</span> <span class="number">19012.5</span> <span class="number">9946.9</span> <span class="number">3831.2</span> +... +</pre> + + +<p><a href="../libraries/pl.input.html#fields">input.fields</a> is designed to extract several columns, given some delimiter +(default to whitespace). Here is a script to calculate the average X location of +all the events:</p> + +<pre> +<span class="comment">-- avg-x.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +<span class="global">io</span>.read() <span class="comment">-- skip the header line +</span><span class="keyword">local</span> sum,count = seq.sum(input.fields {<span class="number">3</span>}) +<span class="global">print</span>(sum/count) +</pre> + + +<p><a href="../libraries/pl.input.html#fields">input.fields</a> is passed either a field count, or a list of column indices, +starting at one as usual. So in this case we’re only interested in column 3. If +you pass it a field count, then you get every field up to that count:</p> + +<pre> +<span class="keyword">for</span> id,mag,locX,locY,locZ <span class="keyword">in</span> input.fields (<span class="number">5</span>) <span class="keyword">do</span> +.... +<span class="keyword">end</span> +</pre> + + +<p><a href="../libraries/pl.input.html#fields">input.fields</a> by default tries to convert each field to a number. It will skip +lines which clearly don’t match the pattern, but will abort the script if there +are any fields which cannot be converted to numbers.</p> + +<p>The second parameter is a delimiter, by default spaces. ‘ ’ is understood to mean +‘any number of spaces’, i.e. ‘%s+’. Any Lua string pattern can be used.</p> + +<p>The third parameter is a <em>data source</em>, by default standard input (defined by +<a href="../libraries/pl.input.html#create_getter">input.create_getter</a>.) It assumes that the data source has a <code>read</code> method which +brings in the next line, i.e. it is a ‘file-like’ object. As a special case, a +string will be split into its lines:</p> + +<pre> +> <span class="keyword">for</span> x,y <span class="keyword">in</span> input.fields(<span class="number">2</span>,<span class="string">' '</span>,<span class="string">'10 20\n30 40\n'</span>) <span class="keyword">do</span> <span class="global">print</span>(x,y) <span class="keyword">end</span> +<span class="number">10</span> <span class="number">20</span> +<span class="number">30</span> <span class="number">40</span> +</pre> + + +<p>Note the default behaviour for bad fields, which is to show the offending line +number:</p> + +<pre> +> <span class="keyword">for</span> x,y <span class="keyword">in</span> input.fields(<span class="number">2</span>,<span class="string">' '</span>,<span class="string">'10 20\n30 40x\n'</span>) <span class="keyword">do</span> <span class="global">print</span>(x,y) <span class="keyword">end</span> +<span class="number">10</span> <span class="number">20</span> +line <span class="number">2</span>: cannot convert <span class="string">'40x'</span> to number +</pre> + + +<p>This behaviour of <a href="../libraries/pl.input.html#fields">input.fields</a> is appropriate for a script which you want to +fail immediately with an appropriate <em>user</em> error message if conversion fails. +The fourth optional parameter is an options table: <code>{no_fail=true}</code> means that +conversion is attempted but if it fails it just returns the string, rather as AWK +would operate. You are then responsible for checking the type of the returned +field. <code>{no_convert=true}</code> switches off conversion altogether and all fields are +returned as strings.</p> + +<p>Sometimes it is useful to bring a whole dataset into memory, for operations such +as extracting columns. Penlight provides a flexible reader specifically for +reading this kind of data, using the <a href="../libraries/pl.data.html#">data</a> module. Given a file looking like this:</p> + +<pre> +x,y +<span class="number">10</span>,<span class="number">20</span> +<span class="number">2</span>,<span class="number">5</span> +<span class="number">40</span>,<span class="number">50</span> +</pre> + + +<p>Then <a href="../libraries/pl.data.html#read">data.read</a> will create a table like this, with each row represented by a +sublist:</p> + +<pre> +> t = data.read <span class="string">'test.txt'</span> +> pretty.dump(t) +{{<span class="number">10</span>,<span class="number">20</span>},{<span class="number">2</span>,<span class="number">5</span>},{<span class="number">40</span>,<span class="number">50</span>},fieldnames={<span class="string">'x'</span>,<span class="string">'y'</span>},delim=<span class="string">','</span>} +</pre> + + +<p>You can now analyze this returned table using the supplied methods. For instance, +the method <a href="../libraries/pl.data.html#Data.column_by_name">column_by_name</a> returns a table of all the values of that column.</p> + +<pre> +<span class="comment">-- testdata.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +d = data.read(<span class="string">'fev.txt'</span>) +<span class="keyword">for</span> _,name <span class="keyword">in</span> <span class="global">ipairs</span>(d.fieldnames) <span class="keyword">do</span> + <span class="keyword">local</span> col = d:column_by_name(name) + <span class="keyword">if</span> <span class="global">type</span>(col[<span class="number">1</span>]) == <span class="string">'number'</span> <span class="keyword">then</span> + <span class="keyword">local</span> total,n = seq.sum(col) + utils.printf(<span class="string">"Average for %s is %f\n"</span>,name,total/n) + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p><a href="../libraries/pl.data.html#read">data.read</a> tries to be clever when given data; by default it expects a first +line of column names, unless any of them are numbers. It tries to deduce the +column delimiter by looking at the first line. Sometimes it guesses wrong; these +things can be specified explicitly. The second optional parameter is an options +table: can override <code>delim</code> (a string pattern), <code>fieldnames</code> (a list or +comma-separated string), specify <code>no_convert</code> (default is to convert), numfields +(indices of columns known to be numbers, as a list) and <code>thousands_dot</code> (when the +thousands separator in Excel CSV is ‘.’)</p> + +<p>A very powerful feature is a way to execute SQL-like queries on such data:</p> + +<pre> +<span class="comment">-- queries on tabular data +</span><span class="global">require</span> <span class="string">'pl'</span> +<span class="keyword">local</span> d = data.read(<span class="string">'xyz.txt'</span>) +<span class="keyword">local</span> q = d:<span class="global">select</span>(<span class="string">'x,y,z where x > 3 and z < 2 sort by y'</span>) +<span class="keyword">for</span> x,y,z <span class="keyword">in</span> q <span class="keyword">do</span> + <span class="global">print</span>(x,y,z) +<span class="keyword">end</span> +</pre> + + +<p>Please note that the format of queries is restricted to the following syntax:</p> + +<pre> +FIELDLIST [ <span class="string">'where'</span> CONDITION ] [ <span class="string">'sort by'</span> FIELD [asc|desc]] +</pre> + + +<p>Any valid Lua code can appear in <code>CONDITION</code>; remember it is <em>not</em> SQL and you +have to use <code>==</code> (this warning comes from experience.)</p> + +<p>For this to work, <em>field names must be Lua identifiers</em>. So <a href="../libraries/pl.data.html#read">read</a> will massage +fieldnames so that all non-alphanumeric chars are replaced with underscores. +However, the <code>original_fieldnames</code> field always contains the original un-massaged +fieldnames.</p> + +<p><a href="../libraries/pl.data.html#read">read</a> can handle standard CSV files fine, although doesn’t try to be a +full-blown CSV parser. With the <code>csv=true</code> option, it’s possible to have +double-quoted fields, which may contain commas; then trailing commas become +significant as well.</p> + +<p>Spreadsheet programs are not always the best tool to +process such data, strange as this might seem to some people. This is a toy CSV +file; to appreciate the problem, imagine thousands of rows and dozens of columns +like this:</p> + +<pre> +Department Name,Employee ID,Project,Hours Booked +sales,<span class="number">1231</span>,overhead,<span class="number">4</span> +sales,<span class="number">1255</span>,overhead,<span class="number">3</span> +engineering,<span class="number">1501</span>,development,<span class="number">5</span> +engineering,<span class="number">1501</span>,maintenance,<span class="number">3</span> +engineering,<span class="number">1433</span>,maintenance,<span class="number">10</span> +</pre> + + +<p>The task is to reduce the dataset to a relevant set of rows and columns, perhaps +do some processing on row data, and write the result out to a new CSV file. The +<a href="../libraries/pl.data.html#Data.write_row">write_row</a> method uses the delimiter to write the row to a file; +<code>Data.select_row</code> is like <code>Data.select</code>, except it iterates over <em>rows</em>, not +fields; this is necessary if we are dealing with a lot of columns!</p> + +<pre> +names = {[<span class="number">1501</span>]=<span class="string">'don'</span>,[<span class="number">1433</span>]=<span class="string">'dilbert'</span>} +keepcols = {<span class="string">'Employee_ID'</span>,<span class="string">'Hours_Booked'</span>} +t:write_row (outf,{<span class="string">'Employee'</span>,<span class="string">'Hours_Booked'</span>}) +q = t:select_row { + fields=keepcols, + where=<span class="keyword">function</span>(row) <span class="keyword">return</span> row[<span class="number">1</span>]==<span class="string">'engineering'</span> <span class="keyword">end</span> +} +<span class="keyword">for</span> row <span class="keyword">in</span> q <span class="keyword">do</span> + row[<span class="number">1</span>] = names[row[<span class="number">1</span>]] + t:write_row(outf,row) +<span class="keyword">end</span> +</pre> + + +<p><code>Data.select_row</code> and <code>Data.select</code> can be passed a table specifying the query; a +list of field names, a function defining the condition and an optional parameter +<code>sort_by</code>. It isn’t really necessary here, but if we had a more complicated row +condition (such as belonging to a specified set) then it is not generally +possible to express such a condition as a query string, without resorting to +hackery such as global variables.</p> + +<p>With 1.0.3, you can specify explicit conversion functions for selected columns. +For instance, this is a log file with a Unix date stamp:</p> + +<pre> +Time Message +<span class="number">1266840760</span> +# EE7C0600006F0D00C00F06010302054000000308010A00002B00407B00 +<span class="number">1266840760</span> closure data <span class="number">0.000000</span> <span class="number">1972</span> <span class="number">1972</span> <span class="number">0</span> +<span class="number">1266840760</span> ++ <span class="number">1266840760</span> EE <span class="number">1</span> +<span class="number">1266840760</span> +# EE7C0600006F0D00C00F06010302054000000408020A00002B00407B00 +<span class="number">1266840764</span> closure data <span class="number">0.000000</span> <span class="number">1972</span> <span class="number">1972</span> <span class="number">0</span> +</pre> + + +<p>We would like the first column as an actual date object, so the <code>convert</code> +field sets an explicit conversion for column 1. (Note that we have to explicitly +convert the string to a number first.)</p> + +<pre> +Date = <span class="global">require</span> <span class="string">'pl.Date'</span> + +<span class="keyword">function</span> date_convert (ds) + <span class="keyword">return</span> Date(<span class="global">tonumber</span>(ds)) +<span class="keyword">end</span> + +d = data.read(f,{convert={[<span class="number">1</span>]=date_convert},last_field_collect=<span class="keyword">true</span>}) +</pre> + + +<p>This gives us a two-column dataset, where the first column contains <a href="../classes/pl.Date.html#">Date</a> objects +and the second column contains the rest of the line. Queries can then easily +pick out events on a day of the week:</p> + +<pre> +q = d:<span class="global">select</span> <span class="string">"Time,Message where Time:weekday_name()=='Sun'"</span> +</pre> + + +<p>Data does not have to come from files, nor does it necessarily come from the lab +or the accounts department. On Linux, <code>ps aux</code> gives you a full listing of all +processes running on your machine. It is straightforward to feed the output of +this command into <a href="../libraries/pl.data.html#read">data.read</a> and perform useful queries on it. Notice that +non-identifier characters like ‘%’ get converted into underscores:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> +f = <span class="global">io</span>.popen <span class="string">'ps aux'</span> +s = data.read (f,{last_field_collect=<span class="keyword">true</span>}) +f:close() +<span class="global">print</span>(s.fieldnames) +<span class="global">print</span>(s:column_by_name <span class="string">'USER'</span>) +qs = <span class="string">'COMMAND,_MEM where _MEM > 5 and USER=="steve"'</span> +<span class="keyword">for</span> name,mem <span class="keyword">in</span> s:<span class="global">select</span>(qs) <span class="keyword">do</span> + <span class="global">print</span>(mem,name) +<span class="keyword">end</span> +</pre> + + +<p>I’ve always been an admirer of the AWK programming language; with <a href="../libraries/pl.data.html#filter">filter</a> you +can get Lua programs which are just as compact:</p> + +<pre> +<span class="comment">-- printxy.lua +</span><span class="global">require</span> <span class="string">'pl'</span> +data.filter <span class="string">'x,y where x > 3'</span> +</pre> + + +<p>It is common enough to have data files without headers of field names. +<a href="../libraries/pl.data.html#read">data.read</a> makes a special exception for such files if all fields are numeric. +Since there are no column names to use in query expressions, you can use AWK-like +column indexes, e.g. ‘$1,$2 where $1 > 3’. I have a little executable script on +my system called <code>lf</code> which looks like this:</p> + +<pre> +#!/usr/bin/env lua +<span class="global">require</span> <span class="string">'pl.data'</span>.filter(arg[<span class="number">1</span>]) +</pre> + + +<p>And it can be used generally as a filter command to extract columns from data. +(The column specifications may be expressions or even constants.)</p> + +<pre> +$ lf <span class="string">'$1,$5/10'</span> < test.dat +</pre> + + +<p>(As with AWK, please note the single-quotes used in this command; this prevents +the shell trying to expand the column indexes. If you are on Windows, then you +must quote the expression in double-quotes so +it is passed as one argument to your batch file.)</p> + +<p>As a tutorial resource, have a look at <a href="../examples/test-data.lua.html#">test-data.lua</a> in the PL tests directory +for other examples of use, plus comments.</p> + +<p>The data returned by <a href="../libraries/pl.data.html#read">read</a> or constructed by <code>Data.copy_select</code> from a query is +basically just an array of rows: <code>{{1,2},{3,4}}</code>. So you may use <a href="../libraries/pl.data.html#read">read</a> to pull +in any array-like dataset, and process with any function that expects such a +implementation. In particular, the functions in <a href="../libraries/pl.array2d.html#">array2d</a> will work fine with +this data. In fact, these functions are available as methods; e.g. +<a href="../libraries/pl.array2d.html#flatten">array2d.flatten</a> can be called directly like so to give us a one-dimensional list:</p> + +<pre> +v = data.read(<span class="string">'dat.txt'</span>):flatten() +</pre> + + +<p>The data is also in exactly the right shape to be treated as matrices by +<a href="http://lua-users.org/wiki/LuaMatrix">LuaMatrix</a>:</p> + +<pre> +> matrix = <span class="global">require</span> <span class="string">'matrix'</span> +> m = matrix(data.read <span class="string">'mat.txt'</span>) +> = m +<span class="number">1</span> <span class="number">0.2</span> <span class="number">0.3</span> +<span class="number">0.2</span> <span class="number">1</span> <span class="number">0.1</span> +<span class="number">0.1</span> <span class="number">0.2</span> <span class="number">1</span> +> = m^<span class="number">2</span> <span class="comment">-- same as m*m +</span><span class="number">1.07</span> <span class="number">0.46</span> <span class="number">0.62</span> +<span class="number">0.41</span> <span class="number">1.06</span> <span class="number">0.26</span> +<span class="number">0.24</span> <span class="number">0.42</span> <span class="number">1.05</span> +</pre> + + +<p><a href="../libraries/pl.data.html#write">write</a> will write matrices back to files for you.</p> + +<p>Finally, for the curious, the global variable <code>_DEBUG</code> can be used to print out +the actual iterator function which a query generates and dynamically compiles. By +using code generation, we can get pretty much optimal performance out of +arbitrary queries.</p> + +<pre> +> lua -lpl -e <span class="string">"_DEBUG=true"</span> -e <span class="string">"data.filter 'x,y where x > 4 sort by x'"</span> < test.txt +<span class="keyword">return</span> <span class="keyword">function</span> (t) + <span class="keyword">local</span> i = <span class="number">0</span> + <span class="keyword">local</span> v + <span class="keyword">local</span> ls = {} + <span class="keyword">for</span> i,v <span class="keyword">in</span> <span class="global">ipairs</span>(t) <span class="keyword">do</span> + <span class="keyword">if</span> v[<span class="number">1</span>] > <span class="number">4</span> <span class="keyword">then</span> + ls[#ls+<span class="number">1</span>] = v + <span class="keyword">end</span> + <span class="keyword">end</span> + <span class="global">table</span>.sort(ls,<span class="keyword">function</span>(v1,v2) + <span class="keyword">return</span> v1[<span class="number">1</span>] < v2[<span class="number">1</span>] + <span class="keyword">end</span>) + <span class="keyword">local</span> n = #ls + <span class="keyword">return</span> <span class="keyword">function</span>() + i = i + <span class="number">1</span> + v = ls[i] + <span class="keyword">if</span> i > n <span class="keyword">then</span> <span class="keyword">return</span> <span class="keyword">end</span> + <span class="keyword">return</span> v[<span class="number">1</span>],v[<span class="number">2</span>] + <span class="keyword">end</span> +<span class="keyword">end</span> + +<span class="number">10</span>,<span class="number">20</span> +<span class="number">40</span>,<span class="number">50</span> +</pre> + + +<p><a name="Reading_Configuration_Files"></a></p> + +<h3>Reading Configuration Files</h3> + +<p>The <a href="../libraries/pl.config.html#">config</a> module provides a simple way to convert several kinds of +configuration files into a Lua table. Consider the simple example:</p> + +<pre> +# test.config +# Read timeout <span class="keyword">in</span> seconds +read.timeout=<span class="number">10</span> + +# Write timeout <span class="keyword">in</span> seconds +write.timeout=<span class="number">5</span> + +#acceptable ports +ports = <span class="number">1002</span>,<span class="number">1003</span>,<span class="number">1004</span> +</pre> + + +<p>This can be easily brought in using <a href="../libraries/pl.config.html#read">config.read</a> and the result shown using +<a href="../libraries/pl.pretty.html#write">pretty.write</a>:</p> + +<pre> +<span class="comment">-- readconfig.lua +</span><span class="keyword">local</span> config = <span class="global">require</span> <span class="string">'pl.config'</span> +<span class="keyword">local</span> pretty= <span class="global">require</span> <span class="string">'pl.pretty'</span> + +<span class="keyword">local</span> t = config.read(arg[<span class="number">1</span>]) +<span class="global">print</span>(pretty.write(t)) +</pre> + + +<p>and the output of <code>lua readconfig.lua test.config</code> is:</p> + +<pre> +{ + ports = { + <span class="number">1002</span>, + <span class="number">1003</span>, + <span class="number">1004</span> + }, + write_timeout = <span class="number">5</span>, + read_timeout = <span class="number">10</span> +} +</pre> + + +<p>That is, <a href="../libraries/pl.config.html#read">config.read</a> will bring in all key/value pairs, ignore # comments, and +ensure that the key names are proper Lua identifiers by replacing non-identifier +characters with ‘_’. If the values are numbers, then they will be converted. (So +the value of <code>t.write_timeout</code> is the number 5). In addition, any values which +are separated by commas will be converted likewise into an array.</p> + +<p>Any line can be continued with a backslash. So this will all be considered one +line:</p> + +<pre> +names=one,two,three, \ +four,five,six,seven, \ +eight,nine,ten +</pre> + + +<p>Windows-style INI files are also supported. The section structure of INI files +translates naturally to nested tables in Lua:</p> + +<pre> +; test.ini +[timeouts] +read=<span class="number">10</span> ; Read timeout <span class="keyword">in</span> seconds +write=<span class="number">5</span> ; Write timeout <span class="keyword">in</span> seconds +[portinfo] +ports = <span class="number">1002</span>,<span class="number">1003</span>,<span class="number">1004</span> +</pre> + + +<p> The output is:</p> + +<pre> +{ + portinfo = { + ports = { + <span class="number">1002</span>, + <span class="number">1003</span>, + <span class="number">1004</span> + } + }, + timeouts = { + write = <span class="number">5</span>, + read = <span class="number">10</span> + } +} +</pre> + + +<p>You can now refer to the write timeout as <code>t.timeouts.write</code>.</p> + +<p>As a final example of the flexibility of <a href="../libraries/pl.config.html#read">config.read</a>, if passed this simple +comma-delimited file</p> + +<pre> +one,two,three +<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span> +<span class="number">40</span>,<span class="number">50</span>,<span class="number">60</span> +<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span> +</pre> + + +<p>it will produce the following table:</p> + +<pre> +{ + { <span class="string">"one"</span>, <span class="string">"two"</span>, <span class="string">"three"</span> }, + { <span class="number">10</span>, <span class="number">20</span>, <span class="number">30</span> }, + { <span class="number">40</span>, <span class="number">50</span>, <span class="number">60</span> }, + { <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span> } +} +</pre> + + +<p><a href="../libraries/pl.config.html#read">config.read</a> isn’t designed to read all CSV files in general, but intended to +support some Unix configuration files not structured as key-value pairs, such as +‘/etc/passwd’.</p> + +<p>This function is intended to be a Swiss Army Knife of configuration readers, but +it does have to make assumptions, and you may not like them. So there is an +optional extra parameter which allows some control, which is table that may have +the following fields:</p> + +<pre> +{ + variablilize = <span class="keyword">true</span>, + convert_numbers = <span class="global">tonumber</span>, + trim_space = <span class="keyword">true</span>, + list_delim = <span class="string">','</span>, + trim_quotes = <span class="keyword">true</span>, + ignore_assign = <span class="keyword">false</span>, + keysep = <span class="string">'='</span>, + smart = <span class="keyword">false</span>, +} +</pre> + + +<p><code>variablilize</code> is the option that converted <code>write.timeout</code> in the first example +to the valid Lua identifier <code>write_timeout</code>. If <code>convert_numbers</code> is true, then +an attempt is made to convert any string that starts like a number. You can +specify your own function (say one that will convert a string like ‘5224 kb’ into +a number.)</p> + +<p><code>trim_space</code> ensures that there is no starting or trailing whitespace with +values, and <code>list_delim</code> is the character that will be used to decide whether to +split a value up into a list (it may be a Lua string pattern such as ‘%s+’.)</p> + +<p>For instance, the password file in Unix is colon-delimited:</p> + +<pre> +t = config.read(<span class="string">'/etc/passwd'</span>,{list_delim=<span class="string">':'</span>}) +</pre> + + +<p>This produces the following output on my system (only last two lines shown):</p> + +<pre> +{ + ... + { + <span class="string">"user"</span>, + <span class="string">"x"</span>, + <span class="string">"1000"</span>, + <span class="string">"1000"</span>, + <span class="string">"user,,,"</span>, + <span class="string">"/home/user"</span>, + <span class="string">"/bin/bash"</span> + }, + { + <span class="string">"sdonovan"</span>, + <span class="string">"x"</span>, + <span class="string">"1001"</span>, + <span class="string">"1001"</span>, + <span class="string">"steve donovan,28,,"</span>, + <span class="string">"/home/sdonovan"</span>, + <span class="string">"/bin/bash"</span> + } +} +</pre> + + +<p>You can get this into a more sensible format, where the usernames are the keys, +with this (the <a href="../libraries/pl.tablex.html#pairmap">tablex.pairmap</a> function must return value, key!)</p> + +<pre> +t = tablex.pairmap(<span class="keyword">function</span>(k,v) <span class="keyword">return</span> v,v[<span class="number">1</span>] <span class="keyword">end</span>,t) +</pre> + + +<p>and you get:</p> + +<pre> +{ ... + sdonovan = { + <span class="string">"sdonovan"</span>, + <span class="string">"x"</span>, + <span class="string">"1001"</span>, + <span class="string">"1001"</span>, + <span class="string">"steve donovan,28,,"</span>, + <span class="string">"/home/sdonovan"</span>, + <span class="string">"/bin/bash"</span> + } +... +} +</pre> + + +<p>Many common Unix configuration files can be read by tweaking these parameters. +For <code>/etc/fstab</code>, the options <code>{list_delim='%s+',ignore_assign=true}</code> will +correctly separate the columns. It’s common to find ‘KEY VALUE’ assignments in +files such as <code>/etc/ssh/ssh_config</code>; the options <code>{keysep=' '}</code> make +<a href="../libraries/pl.config.html#read">config.read</a> return a table where each KEY has a value VALUE.</p> + +<p>Files in the Linux <code>procfs</code> usually use ‘:` as the field delimiter:</p> + +<pre> +> t = config.read(<span class="string">'/proc/meminfo'</span>,{keysep=<span class="string">':'</span>}) +> = t.MemFree +<span class="number">220140</span> kB +</pre> + + +<p>That result is a string, since <a href="https://www.lua.org/manual/5.1/manual.html#pdf-tonumber">tonumber</a> doesn’t like it, but defining the +<code>convert_numbers</code> option as <code>function(s) return tonumber((s:gsub(' kB$',''))) +end</code> will get the memory figures as actual numbers in the result. (The extra +parentheses are necessary so that <a href="https://www.lua.org/manual/5.1/manual.html#pdf-tonumber">tonumber</a> only gets the first result from +<code>gsub</code>). From `tests/test-config.lua':</p> + +<pre> +testconfig(<span class="string">[[ +MemTotal: 1024748 kB +MemFree: 220292 kB +]]</span>, +{ MemTotal = <span class="number">1024748</span>, MemFree = <span class="number">220292</span> }, +{ + keysep = <span class="string">':'</span>, + convert_numbers = <span class="keyword">function</span>(s) + s = s:gsub(<span class="string">' kB$'</span>,<span class="string">''</span>) + <span class="keyword">return</span> <span class="global">tonumber</span>(s) + <span class="keyword">end</span> + } +) +</pre> + + +<p>The <code>smart</code> option lets <a href="../libraries/pl.config.html#read">config.read</a> make a reasonable guess for you; there +are examples in <code>tests/test-config.lua</code>, but basically these common file +formats (and those following the same pattern) can be processed directly in +smart mode: ‘etc/fstab’, ‘/proc/XXXX/status’, ‘ssh_config’ and ‘pdatedb.conf’.</p> + +<p>Please note that <a href="../libraries/pl.config.html#read">config.read</a> can be passed a <em>file-like object</em>; if it’s not a +string and supports the <a href="../libraries/pl.data.html#read">read</a> method, then that will be used. For instance, to +read a configuration from a string, use <a href="../libraries/pl.stringio.html#open">stringio.open</a>.</p> + +<p><a id="lexer"/></p> + +<p><a name="Lexical_Scanning"></a></p> + +<h3>Lexical Scanning</h3> + +<p>Although Lua’s string pattern matching is very powerful, there are times when +something more powerful is needed. <a href="../libraries/pl.lexer.html#scan">pl.lexer.scan</a> provides lexical scanners +which <em>tokenize</em> a string, classifying tokens into numbers, strings, etc.</p> + +<pre> +> lua -lpl +Lua <span class="number">5.1</span>.<span class="number">4</span> Copyright (C) <span class="number">1994</span>-<span class="number">2008</span> Lua.org, PUC-Rio +> tok = lexer.scan <span class="string">'alpha = sin(1.5)'</span> +> = tok() +iden alpha +> = tok() += = +> = tok() +iden sin +> = tok() +( ( +> = tok() +number <span class="number">1.5</span> +> = tok() +) ) +> = tok() +(<span class="keyword">nil</span>) +</pre> + + +<p>The scanner is a function, which is repeatedly called and returns the <em>type</em> and +<em>value</em> of the token. Recognized basic types are ‘iden’,‘string’,‘number’, and +‘space’. and everything else is represented by itself. Note that by default the +scanner will skip any ‘space’ tokens.</p> + +<p>‘comment’ and ‘keyword’ aren’t applicable to the plain scanner, which is not +language-specific, but a scanner which understands Lua is available. It +recognizes the Lua keywords, and understands both short and long comments and +strings.</p> + +<pre> +> <span class="keyword">for</span> t,v <span class="keyword">in</span> lexer.lua <span class="string">'for i=1,n do'</span> <span class="keyword">do</span> <span class="global">print</span>(t,v) <span class="keyword">end</span> +keyword <span class="keyword">for</span> +iden i += = +number <span class="number">1</span> +, , +iden n +keyword <span class="keyword">do</span> +</pre> + + +<p>A lexical scanner is useful where you have highly-structured data which is not +nicely delimited by newlines. For example, here is a snippet of a in-house file +format which it was my task to maintain:</p> + +<pre> +points +</pre> + + +<p>(818344.1,-20389.7,-0.1),(818337.9,-20389.3,-0.1),(818332.5,-20387.8,-0.1)</p> + +<pre> +,(<span class="number">818327.4</span>,-<span class="number">20388</span>,-<span class="number">0.1</span>),(<span class="number">818322</span>,-<span class="number">20387.7</span>,-<span class="number">0.1</span>),(<span class="number">818316.3</span>,-<span class="number">20388.6</span>,-<span class="number">0.1</span>) +,(<span class="number">818309.7</span>,-<span class="number">20389.4</span>,-<span class="number">0.1</span>),(<span class="number">818303.5</span>,-<span class="number">20390.6</span>,-<span class="number">0.1</span>),(<span class="number">818295.8</span>,-<span class="number">20388.3</span>,-<span class="number">0.1</span>) +,(<span class="number">818290.5</span>,-<span class="number">20386.9</span>,-<span class="number">0.1</span>),(<span class="number">818285.2</span>,-<span class="number">20386.1</span>,-<span class="number">0.1</span>),(<span class="number">818279.3</span>,-<span class="number">20383.6</span>,-<span class="number">0.1</span>) +,(<span class="number">818274</span>,-<span class="number">20381.2</span>,-<span class="number">0.1</span>),(<span class="number">818274</span>,-<span class="number">20380.7</span>,-<span class="number">0.1</span>); +</pre> + + +<p>Here is code to extract the points using <a href="../libraries/pl.lexer.html#">pl.lexer</a>:</p> + +<pre> +<span class="comment">-- assume 's' contains the text above... +</span><span class="keyword">local</span> lexer = <span class="global">require</span> <span class="string">'pl.lexer'</span> +<span class="keyword">local</span> expecting = lexer.expecting +<span class="keyword">local</span> append = <span class="global">table</span>.insert + +<span class="keyword">local</span> tok = lexer.scan(s) + +<span class="keyword">local</span> points = {} +<span class="keyword">local</span> t,v = tok() <span class="comment">-- should be 'iden','points' +</span> +<span class="keyword">while</span> t ~= <span class="string">';'</span> <span class="keyword">do</span> + c = {} + expecting(tok,<span class="string">'('</span>) + c.x = expecting(tok,<span class="string">'number'</span>) + expecting(tok,<span class="string">','</span>) + c.y = expecting(tok,<span class="string">'number'</span>) + expecting(tok,<span class="string">','</span>) + c.z = expecting(tok,<span class="string">'number'</span>) + expecting(tok,<span class="string">')'</span>) + t,v = tok() <span class="comment">-- either ',' or ';' +</span> append(points,c) +<span class="keyword">end</span> +</pre> + + +<p>The <code>expecting</code> function grabs the next token and if the type doesn’t match, it +throws an error. (<a href="../libraries/pl.lexer.html#">pl.lexer</a>, unlike other PL libraries, raises errors if +something goes wrong, so you should wrap your code in <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pcall">pcall</a> to catch the error +gracefully.)</p> + +<p>The scanners all have a second optional argument, which is a table which controls +whether you want to exclude spaces and/or comments. The default for <a href="../libraries/pl.lexer.html#lua">lexer.lua</a> +is <code>{space=true,comments=true}</code>. There is a third optional argument which +determines how string and number tokens are to be processsed.</p> + +<p>The ultimate highly-structured data is of course, program source. Here is a +snippet from ‘text-lexer.lua’:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> + +lines = <span class="string">[[ +for k,v in pairs(t) do + if type(k) == 'number' then + print(v) -- array-like case + else + print(k,v) + end +end +]]</span> + +ls = List() +<span class="keyword">for</span> tp,val <span class="keyword">in</span> lexer.lua(lines,{space=<span class="keyword">true</span>,comments=<span class="keyword">true</span>}) <span class="keyword">do</span> + <span class="global">assert</span>(tp ~= <span class="string">'space'</span> <span class="keyword">and</span> tp ~= <span class="string">'comment'</span>) + <span class="keyword">if</span> tp == <span class="string">'keyword'</span> <span class="keyword">then</span> ls:append(val) <span class="keyword">end</span> +<span class="keyword">end</span> +test.asserteq(ls,List{<span class="string">'for'</span>,<span class="string">'in'</span>,<span class="string">'do'</span>,<span class="string">'if'</span>,<span class="string">'then'</span>,<span class="string">'else'</span>,<span class="string">'end'</span>,<span class="string">'end'</span>}) +</pre> + + +<p>Here is a useful little utility that identifies all common global variables found +in a lua module (ignoring those declared locally for the moment):</p> + +<pre> +<span class="comment">-- testglobal.lua +</span><span class="global">require</span> <span class="string">'pl'</span> + +<span class="keyword">local</span> txt,err = utils.readfile(arg[<span class="number">1</span>]) +<span class="keyword">if</span> <span class="keyword">not</span> txt <span class="keyword">then</span> <span class="keyword">return</span> <span class="global">print</span>(err) <span class="keyword">end</span> + +<span class="keyword">local</span> globals = List() +<span class="keyword">for</span> t,v <span class="keyword">in</span> lexer.lua(txt) <span class="keyword">do</span> + <span class="keyword">if</span> t == <span class="string">'iden'</span> <span class="keyword">and</span> _G[v] <span class="keyword">then</span> + globals:append(v) + <span class="keyword">end</span> +<span class="keyword">end</span> +pretty.dump(seq.count_map(globals)) +</pre> + + +<p>Rather then dumping the whole list, with its duplicates, we pass it through +<a href="../libraries/pl.seq.html#count_map">seq.count_map</a> which turns the list into a table where the keys are the values, +and the associated values are the number of times those values occur in the +sequence. Typical output looks like this:</p> + +<pre> +{ + <span class="global">type</span> = <span class="number">2</span>, + <span class="global">pairs</span> = <span class="number">2</span>, + <span class="global">table</span> = <span class="number">2</span>, + <span class="global">print</span> = <span class="number">3</span>, + <span class="global">tostring</span> = <span class="number">2</span>, + <span class="global">require</span> = <span class="number">1</span>, + <span class="global">ipairs</span> = <span class="number">4</span> +} +</pre> + + +<p>You could further pass this through <a href="../libraries/pl.tablex.html#keys">tablex.keys</a> to get a unique list of +symbols. This can be useful when writing ‘strict’ Lua modules, where all global +symbols must be defined as locals at the top of the file.</p> + +<p>For a more detailed use of <a href="../libraries/pl.lexer.html#scan">lexer.scan</a>, please look at <a href="../examples/testxml.lua.html#">testxml.lua</a> in the +examples directory.</p> + +<p><a name="XML"></a></p> + +<h3>XML</h3> + +<p>New in the 0.9.7 release is some support for XML. This is a large topic, and +Penlight does not provide a full XML stack, which is properly the task of a more +specialized library.</p> + +<h4>Parsing and Pretty-Printing</h4> + +<p>The semi-standard XML parser in the Lua universe is <a href="http://matthewwild.co.uk/projects/luaexpat/">lua-expat</a>. +In particular, +it has a function called <code>lxp.lom.parse</code> which will parse XML into the Lua Object +Model (LOM) format. However, it does not provide a way to convert this data back +into XML text. <a href="../libraries/pl.xml.html#parse">xml.parse</a> will use this function, <em>if</em> <code>lua-expat</code> is +available, and otherwise switches back to a pure Lua parser originally written by +Roberto Ierusalimschy.</p> + +<p>The resulting document object knows how to render itself as a string, which is +useful for debugging:</p> + +<pre> +> d = xml.parse <span class="string">"<nodes><node id='1'>alice</node></nodes>"</span> +> = d +<nodes><node id=<span class="string">'1'</span>>alice</node></nodes> +> pretty.dump (d) +{ + { + <span class="string">"alice"</span>, + attr = { + <span class="string">"id"</span>, + id = <span class="string">"1"</span> + }, + tag = <span class="string">"node"</span> + }, + attr = { + }, + tag = <span class="string">"nodes"</span> +} +</pre> + + +<p>Looking at the actual shape of the data reveals the structure of LOM:</p> + +<ul> +<li>every element has a <code>tag</code> field with its name</li> +<li>plus a <code>attr</code> field which is a table containing the attributes as fields, and +also as an array. It is always present.</li> +<li>the children of the element are the array part of the element, so <code>d[1]</code> is +the first child of <code>d</code>, etc.</li> +</ul> + + +<p>It could be argued that having attributes also as the array part of <code>attr</code> is not +essential (you cannot depend on attribute order in XML) but that’s how +it goes with this standard.</p> + +<p><code>lua-expat</code> is another <em>soft dependency</em> of Penlight; generally, the fallback +parser is good enough for straightforward XML as is commonly found in +configuration files, etc. <code>doc.basic_parse</code> is not intended to be a proper +conforming parser (it’s only sixty lines) but it handles simple kinds of +documents that do not have comments or DTD directives. It is intelligent enough +to ignore the <code><?xml</code> directive and that is about it.</p> + +<p>You can get pretty-printing by explicitly calling <a href="../libraries/pl.xml.html#tostring">xml.tostring</a> and passing it +the initial indent and the per-element indent:</p> + +<pre> +> = xml.<span class="global">tostring</span>(d,<span class="string">''</span>,<span class="string">' '</span>) + +<nodes> + <node id=<span class="string">'1'</span>>alice</node> +</nodes> +</pre> + + +<p>There is a fourth argument which is the <em>attribute indent</em>:</p> + +<pre> +> a = xml.parse <span class="string">"<frodo name='baggins' age='50' type='hobbit'/>"</span> +> = xml.<span class="global">tostring</span>(a,<span class="string">''</span>,<span class="string">' '</span>,<span class="string">' '</span>) + +<frodo + <span class="global">type</span>=<span class="string">'hobbit'</span> + name=<span class="string">'baggins'</span> + age=<span class="string">'50'</span> +/> +</pre> + + +<h4>Parsing and Working with Configuration Files</h4> + +<p>It’s common to find configurations expressed with XML these days. It’s +straightforward to ‘walk’ the <a href="http://matthewwild.co.uk/projects/luaexpat/lom.html">LOM</a> +data and extract the data in the form you want:</p> + +<pre> +<span class="global">require</span> <span class="string">'pl'</span> + +<span class="keyword">local</span> config = <span class="string">[[ +<config> + <alpha>1.3</alpha> + <beta>10</beta> + <name>bozo</name> +</config> +]]</span> +<span class="keyword">local</span> d,err = xml.parse(config) + +<span class="keyword">local</span> t = {} +<span class="keyword">for</span> item <span class="keyword">in</span> d:childtags() <span class="keyword">do</span> + t[item.tag] = item[<span class="number">1</span>] +<span class="keyword">end</span> + +pretty.dump(t) +<span class="comment">---> +</span>{ + beta = <span class="string">"10"</span>, + alpha = <span class="string">"1.3"</span>, + name = <span class="string">"bozo"</span> +} +</pre> + + +<p>The only gotcha is that here we must use the <code>Doc:childtags</code> method, which will +skip over any text elements.</p> + +<p>A more involved example is this excerpt from <code>serviceproviders.xml</code>, which is +usually found at <code>/usr/share/mobile-broadband-provider-info/serviceproviders.xml</code> +on Debian/Ubuntu Linux systems.</p> + +<pre> +d = xml.parse <span class="string">[[ +<serviceproviders format="2.0"> +... +<country code="za"> + <provider> + <name>Cell-c</name> + <gsm> + <network-id mcc="655" mnc="07"/> + <apn value="internet"> + <username>Cellcis</username> + <dns>196.7.0.138</dns> + <dns>196.7.142.132</dns> + </apn> + </gsm> + </provider> + <provider> + <name>MTN</name> + <gsm> + <network-id mcc="655" mnc="10"/> + <apn value="internet"> + <dns>196.11.240.241</dns> + <dns>209.212.97.1</dns> + </apn> + </gsm> + </provider> + <provider> + <name>Vodacom</name> + <gsm> + <network-id mcc="655" mnc="01"/> + <apn value="internet"> + <dns>196.207.40.165</dns> + <dns>196.43.46.190</dns> + </apn> + <apn value="unrestricted"> + <name>Unrestricted</name> + <dns>196.207.32.69</dns> + <dns>196.43.45.190</dns> + </apn> + </gsm> + </provider> + <provider> + <name>Virgin Mobile</name> + <gsm> + <apn value="vdata"> + <dns>196.7.0.138</dns> + <dns>196.7.142.132</dns> + </apn> + </gsm> + </provider> +</country> +.... +</serviceproviders> +]]</span> +</pre> + + +<p>Getting the names of the providers per-country is straightforward:</p> + +<pre> +<span class="keyword">local</span> t = {} +<span class="keyword">for</span> country <span class="keyword">in</span> d:childtags() <span class="keyword">do</span> + <span class="keyword">local</span> providers = {} + t[country.attr.code] = providers + <span class="keyword">for</span> provider <span class="keyword">in</span> country:childtags() <span class="keyword">do</span> + <span class="global">table</span>.insert(providers,provider:child_with_name(<span class="string">'name'</span>):get_text()) + <span class="keyword">end</span> +<span class="keyword">end</span> + +pretty.dump(t) +<span class="comment">--> +</span>{ + za = { + <span class="string">"Cell-c"</span>, + <span class="string">"MTN"</span>, + <span class="string">"Vodacom"</span>, + <span class="string">"Virgin Mobile"</span> + } + .... +} +</pre> + + +<h4>Generating XML with ‘xmlification’</h4> + +<p>This feature is inspired by the <code>htmlify</code> function used by +<a href="http://keplerproject.github.com/orbit/">Orbit</a> to simplify HTML generation, +except that no function environment magic is used; the <code>tags</code> function returns a +set of <em>constructors</em> for elements of the given tag names.</p> + +<pre> +> nodes, node = xml.tags <span class="string">'nodes, node'</span> +> = node <span class="string">'alice'</span> +<node>alice</node> +> = nodes { node {id=<span class="string">'1'</span>,<span class="string">'alice'</span>}} +<nodes><node id=<span class="string">'1'</span>>alice</node></nodes> +</pre> + + +<p>The flexibility of Lua tables is very useful here, since both the attributes and +the children of an element can be encoded naturally. The argument to these tag +constructors is either a single value (like a string) or a table where the +attributes are the named keys and the children are the array values.</p> + +<h4>Generating XML using Templates</h4> + +<p>A template is a little XML document which contains dollar-variables. The <code>subst</code> +method on a document is fed an array of tables containing values for these +variables. Note how the parent tag name is specified:</p> + +<pre> +> templ = xml.parse <span class="string">"<node id='$id'>$name</node>"</span> +> = templ:subst {tag=<span class="string">'nodes'</span>, {id=<span class="number">1</span>,name=<span class="string">'alice'</span>},{id=<span class="number">2</span>,name=<span class="string">'john'</span>}} +<nodes><node id=<span class="string">'1'</span>>alice</node><node id=<span class="string">'2'</span>>john</node></nodes> +</pre> + + +<p>Substitution is very related to <em>filtering</em> documents. One of the annoying things +about XML is that it is a document markup language first, and a data language +second. Standard parsers will assume you really care about all those extra +text elements. Consider this fragment, which has been changed by a five-year old:</p> + +<pre> +T = <span class="string">[[ + <weather> + boops! + <current_conditions> + <condition data='$condition'/> + <temp_c data='$temp'/> + <bo>whoops!</bo> + </current_conditions> + </weather> +]]</span> +</pre> + + +<p>Conformant parsers will give you text elements with the line feed after <code><current_conditions></code> +although it makes handling the data more irritating.</p> + +<pre> +<span class="keyword">local</span> <span class="keyword">function</span> parse (str) + <span class="keyword">return</span> xml.parse(str,<span class="keyword">false</span>,<span class="keyword">true</span>) +<span class="keyword">end</span> +</pre> + + +<p>Second argument means ‘string, not file’ and third argument means use the built-in +Lua parser (instead of LuaExpat if available) which <em>by default</em> is not interested in +keeping such strings.</p> + +<p>How to remove the string <code>boops!</code>? <code>clone</code> (also called <a href="../libraries/pl.data.html#filter">filter</a> when called as a +method) copies a LOM document. It can be passed a filter function, which is applied +to each string found. The powerful thing about this is that this function receives +structural information - the parent node, and whether this was a tag name, a text +element or a attribute name:</p> + +<pre> +d = parse (T) +c = d:filter(<span class="keyword">function</span>(s,kind,parent) + <span class="global">print</span>(stringx.strip(s),kind,parent <span class="keyword">and</span> parent.tag <span class="keyword">or</span> <span class="string">'?'</span>) + <span class="keyword">if</span> kind == <span class="string">'*TEXT'</span> <span class="keyword">and</span> #parent > <span class="number">1</span> <span class="keyword">then</span> <span class="keyword">return</span> <span class="keyword">nil</span> <span class="keyword">end</span> + <span class="keyword">return</span> s +<span class="keyword">end</span>) +<span class="comment">---> +</span>weather *TAG ? +boops! *TEXT weather +current_conditions *TAG weather +condition *TAG current_conditions +$condition data condition +temp_c *TAG current_conditions +$temp data temp_c +bo *TAG current_conditions +whoops! *TEXT bo +</pre> + + +<p>We can pull out ‘boops’ and not ‘whoops’ by discarding text elements which are not +the single child of an element.</p> + +<h4>Extracting Data using Templates</h4> + +<p>Matching goes in the opposite direction. We have a document, and would like to +extract values from it using a pattern.</p> + +<p>A common use of this is parsing the XML result of API queries. The +<a href="http://blog.programmableweb.com/2010/02/08/googles-secret-weather-api/">(undocumented and subsequently discontinued) Google Weather +API</a> is a +good example. Grabbing the result of +`http://www.google.com/ig/api?weather=Johannesburg,ZA" we get something like +this, after pretty-printing:</p> + +<pre> +<xml_api_reply version=<span class="string">'1'</span>> + <weather module_id=<span class="string">'0'</span> tab_id=<span class="string">'0'</span> mobile_zipped=<span class="string">'1'</span> section=<span class="string">'0'</span> row=<span class="string">'0'</span> +</pre> + + +<p>mobile_row=‘0’></p> + +<pre> +<forecast_information> + <city data=<span class="string">'Johannesburg, Gauteng'</span>/> + <postal_code data=<span class="string">'Johannesburg,ZA'</span>/> + <latitude_e6 data=<span class="string">''</span>/> + <longitude_e6 data=<span class="string">''</span>/> + <forecast_date data=<span class="string">'2010-10-02'</span>/> + <current_date_time data=<span class="string">'2010-10-02 18:30:00 +0000'</span>/> + <unit_system data=<span class="string">'US'</span>/> +</forecast_information> +<current_conditions> + <condition data=<span class="string">'Clear'</span>/> + <temp_f data=<span class="string">'75'</span>/> + <temp_c data=<span class="string">'24'</span>/> + <humidity data=<span class="string">'Humidity: 19%'</span>/> + <icon data=<span class="string">'/ig/images/weather/sunny.gif'</span>/> + <wind_condition data=<span class="string">'Wind: NW at 7 mph'</span>/> +</current_conditions> +<forecast_conditions> + <day_of_week data=<span class="string">'Sat'</span>/> + <low data=<span class="string">'60'</span>/> + <high data=<span class="string">'89'</span>/> + <icon data=<span class="string">'/ig/images/weather/sunny.gif'</span>/> + <condition data=<span class="string">'Clear'</span>/> +</forecast_conditions> +.... +/weather> +l_api_reply> +</pre> + + +<p>Assume that the above XML has been read into <code>google</code>. The idea is to write a +pattern looking like a template, and use it to extract some values of interest:</p> + +<pre> +t = <span class="string">[[ + <weather> + <current_conditions> + <condition data='$condition'/> + <temp_c data='$temp'/> + </current_conditions> + </weather> +]]</span> + +<span class="keyword">local</span> res, ret = google:match(t) +pretty.dump(res) +</pre> + + +<p>And the output is:</p> + +<pre> +{ + condition = <span class="string">"Clear"</span>, + temp = <span class="string">"24"</span> +} +</pre> + + +<p>The <code>match</code> method can be passed a LOM document or some text, which will be +parsed first.</p> + +<p>But what if we need to extract values from repeated elements? Match templates may +contain ‘array matches’ which are enclosed in ‘{{..}}’:</p> + +<pre> +<weather> + {{<forecast_conditions> + <day_of_week data=<span class="string">'$day'</span>/> + <low data=<span class="string">'$low'</span>/> + <high data=<span class="string">'$high'</span>/> + <condition data=<span class="string">'$condition'</span>/> + </forecast_conditions>}} +</weather> +</pre> + + +<p>And the match result is:</p> + +<pre> +{ + { + low = <span class="string">"60"</span>, + high = <span class="string">"89"</span>, + day = <span class="string">"Sat"</span>, + condition = <span class="string">"Clear"</span>, + }, + { + low = <span class="string">"53"</span>, + high = <span class="string">"86"</span>, + day = <span class="string">"Sun"</span>, + condition = <span class="string">"Clear"</span>, + }, + { + low = <span class="string">"57"</span>, + high = <span class="string">"87"</span>, + day = <span class="string">"Mon"</span>, + condition = <span class="string">"Clear"</span>, + }, + { + low = <span class="string">"60"</span>, + high = <span class="string">"84"</span>, + day = <span class="string">"Tue"</span>, + condition = <span class="string">"Clear"</span>, + } +} +</pre> + + +<p>With this array of tables, you can use <a href="../libraries/pl.tablex.html#">tablex</a> or <a href="../classes/pl.List.html#">List</a> +to reshape into the desired form, if you choose. Just as with reading a Unix password +file with <a href="../libraries/pl.config.html#">config</a>, you can make the array into a map of days to conditions using:</p> + +<pre> +<span class="backtick"><a href="../libraries/pl.tablex.html#pairmap">tablex.pairmap</a></span>(<span class="string">'|k,v| v,v.day'</span>,conditions) +</pre> + + +<p>(Here using the alternative string lambda option)</p> + +<p>However, xml matches can shape the structure of the output. By replacing the <code>day_of_week</code> +line of the template with <code><day_of_week data='$_'/></code> we get the same effect; <code>$_</code> is +a special symbol that means that this captured value (or simply <em>capture</em>) becomes the key.</p> + +<p>Note that <code>$NUMBER</code> means a numerical index, so +that <code>$1</code> is the first element of the resulting array, and so forth. You can mix +numbered and named captures, but it’s strongly advised to make the numbered captures +form a proper array sequence (everything from <code>1</code> to <code>n</code> inclusive). <code>$0</code> has a +special meaning; if it is the only capture (<code>{[0]='foo'}</code>) then the table is +collapsed into ‘foo’.</p> + +<pre> +<weather> + {{<forecast_conditions> + <day_of_week data=<span class="string">'$_'</span>/> + <low data=<span class="string">'$1'</span>/> + <high data=<span class="string">'$2'</span>/> + <condition data=<span class="string">'$3'</span>/> + </forecast_conditions>}} +</weather> +</pre> + + +<p>Now the result is:</p> + +<pre> +{ + Tue = { + <span class="string">"60"</span>, + <span class="string">"84"</span>, + <span class="string">"Clear"</span> + }, + Sun = { + <span class="string">"53"</span>, + <span class="string">"86"</span>, + <span class="string">"Clear"</span> + }, + Sat = { + <span class="string">"60"</span>, + <span class="string">"89"</span>, + <span class="string">"Clear"</span> + }, + Mon = { + <span class="string">"57"</span>, + <span class="string">"87"</span>, + <span class="string">"Clear"</span> + } +} +</pre> + + +<p>Applying matches to this config file poses another problem, because the actual +tags matched are themselves meaningful.</p> + +<pre> +<config> + <alpha><span class="number">1.3</span></alpha> + <beta><span class="number">10</span></beta> + <name>bozo</name> +</config> +</pre> + + +<p>So there are tag ‘wildcards’ which are element names ending with a hyphen.</p> + +<pre> +<config> + {{<key->$value</key->}} +</config> +</pre> + + +<p>You will then get <code>{{alpha='1.3'},…}</code>. The most convenient format would be +returned by this (note that <code>_-</code> behaves just like <code>$_</code>):</p> + +<pre> +<config> + {{<_->$<span class="number">0</span></_->}} +</config> +</pre> + + +<p>which would return <code>{alpha='1.3',beta='10',name='bozo'}</code>.</p> + +<p>We could play this game endlessly, and encode ways of converting captures, but +the scheme is complex enough, and it’s easy to do the conversion later</p> + +<pre> +<span class="keyword">local</span> numbers = {alpha=<span class="keyword">true</span>,beta=<span class="keyword">true</span>} +<span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="global">pairs</span>(res) <span class="keyword">do</span> + <span class="keyword">if</span> numbers[v] <span class="keyword">then</span> res[k] = <span class="global">tonumber</span>(v) <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<h4>HTML Parsing</h4> + +<p>HTML is an unusually degenerate form of XML, and Dennis Schridde has contributed +a feature which makes parsing it easier. For instance, from the tests:</p> + +<pre> +doc = xml.parsehtml <span class="string">[[ +<BODY> +Hello dolly<br> +HTML is <b>slack</b><br> +</BODY> +]]</span> + +asserteq(xml.<span class="global">tostring</span>(doc),<span class="string">[[ +<body> +Hello dolly<br/> +HTML is <b>slack</b><br/></body>]]</span>) +</pre> + + +<p>That is, all tags are converted to lowercase, and empty HTML elements like <code>br</code> +are properly closed; attributes do not need to be quoted.</p> + +<p>Also, DOCTYPE directives and comments are skipped. For truly badly formed HTML, +this is not the tool for you!</p> + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/07-functional.md.html b/docs/manual/07-functional.md.html new file mode 100644 index 0000000..c093eef --- /dev/null +++ b/docs/manual/07-functional.md.html @@ -0,0 +1,835 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Sequences">Sequences </a></li> +<li><a href="#Sequence_Wrappers">Sequence Wrappers </a></li> +<li><a href="#List_Comprehensions">List Comprehensions </a></li> +<li><a href="#Creating_Functions_from_Functions">Creating Functions from Functions </a></li> +<li><a href="#Placeholder_Expressions">Placeholder Expressions </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><strong>Functional Programming</strong></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Functional Programming</h2> + +<p><a name="Sequences"></a></p> + +<h3>Sequences</h3> + +<p>A Lua iterator (in its simplest form) is a function which can be repeatedly +called to return a set of one or more values. The <code>for in</code> statement understands +these iterators, and loops until the function returns <code>nil</code>. There are standard +sequence adapters for tables in Lua (<a href="https://www.lua.org/manual/5.1/manual.html#pdf-ipairs">ipairs</a> and <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pairs">pairs</a>), and <a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.lines">io.lines</a> +returns an iterator over all the lines in a file. In the Penlight libraries, such +iterators are also called <em>sequences</em>. A sequence of single values (say from +<a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.lines">io.lines</a>) is called <em>single-valued</em>, whereas the sequence defined by <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pairs">pairs</a> is +<em>double-valued</em>.</p> + +<p><a href="../libraries/pl.seq.html#">pl.seq</a> provides a number of useful iterators, and some functions which operate +on sequences. At first sight this example looks like an attempt to write Python +in Lua, (with the sequence being inclusive):</p> + +<pre> +> <span class="keyword">for</span> i <span class="keyword">in</span> seq.range(<span class="number">1</span>,<span class="number">4</span>) <span class="keyword">do</span> <span class="global">print</span>(i) <span class="keyword">end</span> +<span class="number">1</span> +<span class="number">2</span> +<span class="number">3</span> +<span class="number">4</span> +</pre> + + +<p>But <a href="../libraries/pl.seq.html#range">range</a> is actually equivalent to Python’s <code>xrange</code>, since it generates a +sequence, not a list. To get a list, use <code>seq.copy(seq.range(1,10))</code>, which +takes any single-value sequence and makes a table from the result. <a href="../libraries/pl.seq.html#list">seq.list</a> is +like <a href="https://www.lua.org/manual/5.1/manual.html#pdf-ipairs">ipairs</a> except that it does not give you the index, just the value.</p> + +<pre> +> <span class="keyword">for</span> x <span class="keyword">in</span> seq.list {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} <span class="keyword">do</span> <span class="global">print</span>(x) <span class="keyword">end</span> +<span class="number">1</span> +<span class="number">2</span> +<span class="number">3</span> +</pre> + + +<p><a href="../libraries/pl.seq.html#enum">enum</a> takes a sequence and turns it into a double-valued sequence consisting of +a sequence number and the value, so <code>enum(list(ls))</code> is actually equivalent to +<a href="https://www.lua.org/manual/5.1/manual.html#pdf-ipairs">ipairs</a>. A more interesting example prints out a file with line numbers:</p> + +<pre> +<span class="keyword">for</span> i,v <span class="keyword">in</span> seq.enum(<span class="global">io</span>.lines(fname)) <span class="keyword">do</span> <span class="global">print</span>(i..<span class="string">' '</span>..v) <span class="keyword">end</span> +</pre> + + +<p>Sequences can be <em>combined</em>, either by ‘zipping’ them or by concatenating them.</p> + +<pre> +> <span class="keyword">for</span> x,y <span class="keyword">in</span> seq.zip(l1,l2) <span class="keyword">do</span> <span class="global">print</span>(x,y) <span class="keyword">end</span> +<span class="number">10</span> <span class="number">1</span> +<span class="number">20</span> <span class="number">2</span> +<span class="number">30</span> <span class="number">3</span> +> <span class="keyword">for</span> x <span class="keyword">in</span> seq.splice(l1,l2) <span class="keyword">do</span> <span class="global">print</span>(x) <span class="keyword">end</span> +<span class="number">10</span> +<span class="number">20</span> +<span class="number">30</span> +<span class="number">1</span> +<span class="number">2</span> +<span class="number">3</span> +</pre> + + +<p><a href="../libraries/pl.seq.html#printall">seq.printall</a> is useful for printing out single-valued sequences, and provides +some finer control over formating, such as a delimiter, the number of fields per +line, and a format string to use (@see string.format)</p> + +<pre> +> seq.printall(seq.random(<span class="number">10</span>)) +<span class="number">0.0012512588885159</span> <span class="number">0.56358531449324</span> <span class="number">0.19330423902097</span> .... +> seq.printall(seq.random(<span class="number">10</span>), <span class="string">','</span>, <span class="number">4</span>, <span class="string">'%4.2f'</span>) +<span class="number">0.17</span>,<span class="number">0.86</span>,<span class="number">0.71</span>,<span class="number">0.51</span> +<span class="number">0.30</span>,<span class="number">0.01</span>,<span class="number">0.09</span>,<span class="number">0.36</span> +<span class="number">0.15</span>,<span class="number">0.17</span>, +</pre> + + +<p><a href="../libraries/pl.seq.html#map">map</a> will apply a function to a sequence.</p> + +<pre> +> seq.printall(seq.map(<span class="global">string</span>.upper, {<span class="string">'one'</span>,<span class="string">'two'</span>})) +ONE TWO +> seq.printall(seq.map(<span class="string">'+'</span>, {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}, <span class="number">1</span>)) +<span class="number">11</span> <span class="number">21</span> <span class="number">31</span> +</pre> + + +<p><a href="../libraries/pl.seq.html#filter">filter</a> will filter a sequence using a boolean function (often called a +<em>predicate</em>). For instance, this code only prints lines in a file which are +composed of digits:</p> + +<pre> +<span class="keyword">for</span> l <span class="keyword">in</span> seq.filter(<span class="global">io</span>.lines(file), stringx.isdigit) <span class="keyword">do</span> <span class="global">print</span>(l) <span class="keyword">end</span> +</pre> + + +<p>The following returns a table consisting of all the positive values in the +original table (equivalent to <code>tablex.filter(ls, '>', 0)</code>)</p> + +<pre> +ls = seq.copy(seq.filter(ls, <span class="string">'>'</span>, <span class="number">0</span>)) +</pre> + + +<p>We’re already encounted <a href="../libraries/pl.seq.html#sum">seq.sum</a> when discussing <a href="../libraries/pl.input.html#numbers">input.numbers</a>. This can also +be expressed with <a href="../libraries/pl.seq.html#reduce">seq.reduce</a>:</p> + +<pre> +> seq.reduce(<span class="keyword">function</span>(x,y) <span class="keyword">return</span> x + y <span class="keyword">end</span>, seq.list{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +<span class="number">10</span> +</pre> + + +<p><a href="../libraries/pl.seq.html#reduce">seq.reduce</a> applies a binary function in a recursive fashion, so that:</p> + +<pre> +reduce(op,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}) => op(<span class="number">1</span>,reduce(op,{<span class="number">2</span>,<span class="number">3</span>}) => op(<span class="number">1</span>,op(<span class="number">2</span>,<span class="number">3</span>)) +</pre> + + +<p>it’s now possible to easily generate other cumulative operations; the standard +operations declared in <a href="../libraries/pl.operator.html#">pl.operator</a> are useful here:</p> + +<pre> +> ops = <span class="global">require</span> <span class="string">'pl.operator'</span> +> <span class="comment">-- can also say '*' instead of ops.mul +</span>> = seq.reduce(ops.mul,input.numbers <span class="string">'1 2 3 4'</span>) +<span class="number">24</span> +</pre> + + +<p>There are functions to extract statistics from a sequence of numbers:</p> + +<pre> +> l1 = List {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +> l2 = List {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +> = seq.minmax(l1) +<span class="number">10</span> <span class="number">30</span> +> = seq.sum(l1) +<span class="number">60</span> <span class="number">3</span> +</pre> + + +<p>It is common to get sequences where values are repeated, say the words in a file. +<a href="../libraries/pl.seq.html#count_map">count_map</a> will take such a sequence and count the values, returning a table +where the <em>keys</em> are the unique values, and the value associated with each key is +the number of times they occurred:</p> + +<pre> +> t = seq.count_map {<span class="string">'one'</span>,<span class="string">'fred'</span>,<span class="string">'two'</span>,<span class="string">'one'</span>,<span class="string">'two'</span>,<span class="string">'two'</span>} +> = t +{one=<span class="number">2</span>,fred=<span class="number">1</span>,two=<span class="number">3</span>} +</pre> + + +<p>This will also work on numerical sequences, but you cannot expect the result to +be a proper list, i.e. having no ‘holes’. Instead, you always need to use <a href="https://www.lua.org/manual/5.1/manual.html#pdf-pairs">pairs</a> +to iterate over the result - note that there is a hole at index 5:</p> + +<pre> +> t = seq.count_map {<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">2</span>,<span class="number">6</span>} +> <span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="global">pairs</span>(t) <span class="keyword">do</span> <span class="global">print</span>(k,v) <span class="keyword">end</span> +<span class="number">1</span> <span class="number">1</span> +<span class="number">2</span> <span class="number">4</span> +<span class="number">3</span> <span class="number">1</span> +<span class="number">4</span> <span class="number">2</span> +<span class="number">6</span> <span class="number">1</span> +</pre> + + +<p><code>unique</code> uses <a href="../libraries/pl.seq.html#count_map">count_map</a> to return a list of the unique values, that is, just +the keys of the resulting table.</p> + +<p><a href="../libraries/pl.seq.html#last">last</a> turns a single-valued sequence into a double-valued sequence with the +current value and the last value:</p> + +<pre> +> <span class="keyword">for</span> current,last <span class="keyword">in</span> seq.last {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>,<span class="number">40</span>} <span class="keyword">do</span> <span class="global">print</span> (current,last) <span class="keyword">end</span> +<span class="number">20</span> <span class="number">10</span> +<span class="number">30</span> <span class="number">20</span> +<span class="number">40</span> <span class="number">30</span> +</pre> + + +<p>This makes it easy to do things like identify repeated lines in a file, or +construct differences between values. <a href="../libraries/pl.seq.html#filter">filter</a> can handle double-valued sequences +as well, so one could filter such a sequence to only return cases where the +current value is less than the last value by using <a href="../libraries/pl.operator.html#lt">operator.lt</a> or just ‘<’. +This code then copies the resulting code into a table.</p> + +<pre> +> ls = {<span class="number">10</span>,<span class="number">9</span>,<span class="number">10</span>,<span class="number">3</span>} +> = seq.copy(seq.filter(seq.last(s),<span class="string">'<'</span>)) +{<span class="number">9</span>,<span class="number">3</span>} +</pre> + + +<p><a name="Sequence_Wrappers"></a></p> + +<h3>Sequence Wrappers</h3> + +<p>The functions in <a href="../libraries/pl.seq.html#">pl.seq</a> cover the common patterns when dealing with sequences, +but chaining these functions together can lead to ugly code. Consider the last +example of the previous section; <a href="../libraries/pl.seq.html#">seq</a> is repeated three times and the resulting +expression has to be read right-to-left. The first issue can be helped by local +aliases, so that the expression becomes <code>copy(filter(last(s),'<'))</code> but the +second issue refers to the somewhat unnatural order of functional application. +We tend to prefer reading operations from left to right, which is one reason why +object-oriented notation has become popular. Sequence adapters allow this +expression to be written like so:</p> + +<pre> +seq(s):last():filter(<span class="string">'<'</span>):copy() +</pre> + + +<p>With this notation, the operation becomes a chain of method calls running from +left to right.</p> + +<p>‘Sequence’ is not a basic Lua type, they are generally functions or callable +objects. The expression <code>seq(s)</code> wraps a sequence in a <em>sequence wrapper</em>, which +is an object which understands all the functions in <a href="../libraries/pl.seq.html#">pl.seq</a> as methods. This +object then explicitly represents sequences.</p> + +<p>As a special case, the constructor (which is when you call the table <a href="../libraries/pl.seq.html#">seq</a>) will +make a wrapper for a plain list-like table. Here we apply the length operator to +a sequence of strings, and print them out.</p> + +<pre> +> seq{<span class="string">'one'</span>,<span class="string">'tw'</span>,<span class="string">'t'</span>} :map <span class="string">'#'</span> :printall() +<span class="number">3</span> <span class="number">2</span> <span class="number">1</span> +</pre> + + +<p>As a convenience, there is a function <a href="../libraries/pl.seq.html#lines">seq.lines</a> which behaves just like +<a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.lines">io.lines</a> except it wraps the result as an explicit sequence type. This takes +the first 10 lines from standard input, makes it uppercase, turns it into a +sequence with a count and the value, glues these together with the concatenation +operator, and finally prints out the sequence delimited by a newline.</p> + +<pre> +seq.lines():take(<span class="number">10</span>):upper():enum():map(<span class="string">'..'</span>):printall <span class="string">'\n'</span> +</pre> + + +<p>Note the method <code>upper</code>, which is not a <a href="../libraries/pl.seq.html#">seq</a> function. if an unknown method is +called, sequence wrappers apply that method to all the values in the sequence +(this is implicit use of <a href="../libraries/pl.seq.html#mapmethod">mapmethod</a>)</p> + +<p>It is straightforward to create custom sequences that can be used in this way. On +Unix, <code>/dev/random</code> gives you an <em>endless</em> sequence of random bytes, so we use +<a href="../libraries/pl.seq.html#take">take</a> to limit the sequence, and then <a href="../libraries/pl.seq.html#map">map</a> to scale the result into the desired +range. The key step is to use <a href="../libraries/pl.seq.html#">seq</a> to wrap the iterator function:</p> + +<pre> +<span class="comment">-- random.lua +</span><span class="keyword">local</span> seq = <span class="global">require</span> <span class="string">'pl.seq'</span> + +<span class="keyword">function</span> dev_random() + <span class="keyword">local</span> f = <span class="global">io</span>.open(<span class="string">'/dev/random'</span>) + <span class="keyword">local</span> byte = <span class="global">string</span>.byte + <span class="keyword">return</span> seq(<span class="keyword">function</span>() + <span class="comment">-- read two bytes into a string and convert into a 16-bit number +</span> <span class="keyword">local</span> s = f:read(<span class="number">2</span>) + <span class="keyword">return</span> byte(s,<span class="number">1</span>) + <span class="number">256</span>*byte(s,<span class="number">2</span>) + <span class="keyword">end</span>) +<span class="keyword">end</span> + +<span class="comment">-- print 10 random numbers from 0 to 1 ! +</span>dev_random():take(<span class="number">10</span>):map(<span class="string">'%'</span>,<span class="number">100</span>):map(<span class="string">'/'</span>,<span class="number">100</span>):printall <span class="string">','</span> +</pre> + + +<p>Another Linux one-liner depends on the <code>/proc</code> filesystem and makes a list of all +the currently running processes:</p> + +<pre> +pids = seq(lfs.dir <span class="string">'/proc'</span>):filter(stringx.isdigit):map(<span class="global">tonumber</span>):copy() +</pre> + + +<p>This version of Penlight has an experimental feature which relies on the fact +that <em>all</em> Lua types can have metatables, including functions. This makes +<em>implicit sequence wrapping</em> possible:</p> + +<pre> +> seq.import() +> seq.random(<span class="number">5</span>):printall(<span class="string">','</span>,<span class="number">5</span>,<span class="string">'%4.1f'</span>) + <span class="number">0.0</span>, <span class="number">0.1</span>, <span class="number">0.4</span>, <span class="number">0.1</span>, <span class="number">0.2</span> +</pre> + + +<p>This avoids the awkward <code>seq(seq.random(5))</code> construction. Or the iterator can +come from somewhere else completely:</p> + +<pre> +> (<span class="string">'one two three'</span>):gfind(<span class="string">'%a+'</span>):printall(<span class="string">','</span>) +one,two,three, +</pre> + + +<p>After <code>seq.import</code>, it is no longer necessary to explicitly wrap sequence +functions.</p> + +<p>But there is a price to pay for this convenience. <em>Every</em> function is affected, +so that any function can be used, appropriate or not:</p> + +<pre> +> <span class="global">math</span>.sin:printall() +..seq.lua:<span class="number">287</span>: bad argument #<span class="number">1</span> to <span class="string">'(for generator)'</span> (number expected, got <span class="keyword">nil</span>) +> a = <span class="global">tostring</span> +> = a:find(<span class="string">' '</span>) +<span class="keyword">function</span>: <span class="number">0042</span>C920 +</pre> + + +<p>What function is returned? It’s almost certain to be something that makes no +sense in the current context. So implicit sequences may make certain kinds of +programming mistakes harder to catch - they are best used for interactive +exploration and small scripts.</p> + +<p><a id="comprehensions"/></p> + +<p><a name="List_Comprehensions"></a></p> + +<h3>List Comprehensions</h3> + +<p>List comprehensions are a compact way to create tables by specifying their +elements. In Python, you can say this:</p> + +<pre> +ls = [x <span class="keyword">for</span> x <span class="keyword">in</span> range(<span class="number">5</span>)] # == [<span class="number">0</span>,<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>] +</pre> + + +<p>In Lua, using <a href="../libraries/pl.comprehension.html#">pl.comprehension</a>:</p> + +<pre> +> C = <span class="global">require</span>(<span class="string">'pl.comprehension'</span>).new() +> = C (<span class="string">'x for x=1,10'</span>) () +{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>,<span class="number">10</span>} +</pre> + + +<p><code>C</code> is a function which compiles a list comprehension <em>string</em> into a <em>function</em>. +In this case, the function has no arguments. The parentheses are redundant for a +function taking a string argument, so this works as well:</p> + +<pre> +> = C <span class="string">'x^2 for x=1,4'</span> () +{<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">16</span>} +> = C <span class="string">'{x,x^2} for x=1,4'</span> () +{{<span class="number">1</span>,<span class="number">1</span>},{<span class="number">2</span>,<span class="number">4</span>},{<span class="number">3</span>,<span class="number">9</span>},{<span class="number">4</span>,<span class="number">16</span>}} +</pre> + + +<p>Note that the expression can be <em>any</em> function of the variable <code>x</code>!</p> + +<p>The basic syntax so far is <code><expr> for <set></code>, where <code><set></code> can be anything that +the Lua <code>for</code> statement understands. <code><set></code> can also just be the variable, in +which case the values will come from the <em>argument</em> of the comprehension. Here +I’m emphasizing that a comprehension is a function which can take a list argument:</p> + +<pre> +> = C <span class="string">'2*x for x'</span> {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>} +{<span class="number">2</span>,<span class="number">4</span>,<span class="number">6</span>} +> dbl = C <span class="string">'2*x for x'</span> +> = dbl {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +{<span class="number">20</span>,<span class="number">40</span>,<span class="number">60</span>} +</pre> + + +<p>Here is a somewhat more explicit way of saying the same thing; <code>_1</code> is a +<em>placeholder</em> refering to the <em>first</em> argument passed to the comprehension.</p> + +<pre> +> = C <span class="string">'2*x for _,x in pairs(_1)'</span> {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>} +{<span class="number">20</span>,<span class="number">40</span>,<span class="number">60</span>} +> = C <span class="string">'_1(x) for x'</span>(<span class="global">tostring</span>,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,<span class="string">'4'</span>} +</pre> + + +<p>This extended syntax is useful when you wish to collect the result of some +iterator, such as <a href="https://www.lua.org/manual/5.1/manual.html#pdf-io.lines">io.lines</a>. This comprehension creates a function which creates +a table of all the lines in a file:</p> + +<pre> +> f = <span class="global">io</span>.open(<span class="string">'array.lua'</span>) +> lines = C <span class="string">'line for line in _1:lines()'</span> (f) +> = #lines +<span class="number">118</span> +</pre> + + +<p>There are a number of functions that may be applied to the result of a +comprehension:</p> + +<pre> +> = C <span class="string">'min(x for x)'</span> {<span class="number">1</span>,<span class="number">44</span>,<span class="number">0</span>} +<span class="number">0</span> +> = C <span class="string">'max(x for x)'</span> {<span class="number">1</span>,<span class="number">44</span>,<span class="number">0</span>} +<span class="number">44</span> +> = C <span class="string">'sum(x for x)'</span> {<span class="number">1</span>,<span class="number">44</span>,<span class="number">0</span>} +<span class="number">45</span> +</pre> + + +<p>(These are equivalent to a reduce operation on a list.)</p> + +<p>After the <code>for</code> part, there may be a condition, which filters the output. This +comprehension collects the even numbers from a list:</p> + +<pre> +> = C <span class="string">'x for x if x % 2 == 0'</span> {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>} +{<span class="number">2</span>,<span class="number">4</span>} +</pre> + + +<p>There may be a number of <code>for</code> parts:</p> + +<pre> +> = C <span class="string">'{x,y} for x = 1,2 for y = 1,2'</span> () +{{<span class="number">1</span>,<span class="number">1</span>},{<span class="number">1</span>,<span class="number">2</span>},{<span class="number">2</span>,<span class="number">1</span>},{<span class="number">2</span>,<span class="number">2</span>}} +> = C <span class="string">'{x,y} for x for y'</span> ({<span class="number">1</span>,<span class="number">2</span>},{<span class="number">10</span>,<span class="number">20</span>}) +{{<span class="number">1</span>,<span class="number">10</span>},{<span class="number">1</span>,<span class="number">20</span>},{<span class="number">2</span>,<span class="number">10</span>},{<span class="number">2</span>,<span class="number">20</span>}} +</pre> + + +<p>These comprehensions are useful when dealing with functions of more than one +variable, and are not so easily achieved with the other Penlight functional forms.</p> + +<p><a id="func"/></p> + +<p><a name="Creating_Functions_from_Functions"></a></p> + +<h3>Creating Functions from Functions</h3> + +<p>Lua functions may be treated like any other value, although of course you cannot +multiply or add them. One operation that makes sense is <em>function composition</em>, +which chains function calls (so <code>(f * g)(x)</code> is <code>f(g(x))</code>.)</p> + +<pre> +> func = <span class="global">require</span> <span class="string">'pl.func'</span> +> printf = func.compose(<span class="global">io</span>.write,<span class="global">string</span>.format) +> printf(<span class="string">"hello %s\n"</span>,<span class="string">'world'</span>) +hello world +<span class="keyword">true</span> +</pre> + + +<p>Many functions require you to pass a function as an argument, say to apply to all +values of a sequence or as a callback. Often useful functions have the wrong +number of arguments. So there is a need to construct a function of one argument +from one of two arguments, <em>binding</em> the extra argument to a given value.</p> + +<p><em>partial application</em> takes a function of n arguments and returns a function of n-1 +arguments where the first argument is bound to some value:</p> + +<pre> +> p2 = func.bind1(<span class="global">print</span>,<span class="string">'start>'</span>) +> p2(<span class="string">'hello'</span>,<span class="number">2</span>) +start> hello <span class="number">2</span> +> ops = <span class="global">require</span> <span class="string">'pl.operator'</span> +> = tablex.filter({<span class="number">1</span>,-<span class="number">2</span>,<span class="number">10</span>,-<span class="number">1</span>,<span class="number">2</span>},bind1(ops.gt,<span class="number">0</span>)) +{-<span class="number">2</span>,-<span class="number">1</span>} +> tablex.filter({<span class="number">1</span>,-<span class="number">2</span>,<span class="number">10</span>,-<span class="number">1</span>,<span class="number">2</span>},bind1(ops.le,<span class="number">0</span>)) +{<span class="number">1</span>,<span class="number">10</span>,<span class="number">2</span>} +</pre> + + +<p>The last example unfortunately reads backwards, because <a href="../libraries/pl.func.html#bind1">bind1</a> alway binds the +first argument! Also unfortunately, in my youth I confused ‘currying’ with +‘partial application’, so the old name for <a href="../libraries/pl.func.html#bind1">bind1</a> is <code>curry</code> - this alias still exists.</p> + +<p>This is a specialized form of function argument binding. Here is another way +to say the <a href="https://www.lua.org/manual/5.1/manual.html#pdf-print">print</a> example:</p> + +<pre> +> p2 = func.bind(<span class="global">print</span>,<span class="string">'start>'</span>,func._1,func._2) +> p2(<span class="string">'hello'</span>,<span class="number">2</span>) +start> hello <span class="number">2</span> +</pre> + + +<p>where <code>_1</code> and <code>_2</code> are <em>placeholder variables</em>, corresponding to the first and +second argument respectively.</p> + +<p>Having <a href="../libraries/pl.func.html#">func</a> all over the place is distracting, so it’s useful to pull all of +<a href="../libraries/pl.func.html#">pl.func</a> into the local context. Here is the filter example, this time the right +way around:</p> + +<pre> +> utils.import <span class="string">'pl.func'</span> +> tablex.filter({<span class="number">1</span>,-<span class="number">2</span>,<span class="number">10</span>,-<span class="number">1</span>,<span class="number">2</span>},bind(ops.gt, _1, <span class="number">0</span>)) +{<span class="number">1</span>,<span class="number">10</span>,<span class="number">2</span>} +</pre> + + +<p><a href="../libraries/pl.tablex.html#merge">tablex.merge</a> does a general merge of two tables. This example shows the +usefulness of binding the last argument of a function.</p> + +<pre> +> S1 = {john=<span class="number">27</span>, jane=<span class="number">31</span>, mary=<span class="number">24</span>} +> S2 = {jane=<span class="number">31</span>, jones=<span class="number">50</span>} +> intersection = bind(tablex.merge, _1, _2, <span class="keyword">false</span>) +> union = bind(tablex.merge, _1, _2, <span class="keyword">true</span>) +> = intersection(S1,S2) +{jane=<span class="number">31</span>} +> = union(S1,S2) +{mary=<span class="number">24</span>,jane=<span class="number">31</span>,john=<span class="number">27</span>,jones=<span class="number">50</span>} +</pre> + + +<p>When using <a href="../libraries/pl.func.html#bind">bind</a> with <a href="https://www.lua.org/manual/5.1/manual.html#pdf-print">print</a>, we got a function of precisely two arguments, +whereas we really want our function to use varargs like <a href="https://www.lua.org/manual/5.1/manual.html#pdf-print">print</a>. This is the role +of <code>_0</code>:</p> + +<pre> +> _DEBUG = <span class="keyword">true</span> +> p = bind(<span class="global">print</span>,<span class="string">'start>'</span>, _0) +<span class="keyword">return</span> <span class="keyword">function</span> (fn,_v1) + <span class="keyword">return</span> <span class="keyword">function</span>(...) <span class="keyword">return</span> fn(_v1,...) <span class="keyword">end</span> +<span class="keyword">end</span> + +> p(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>) +start> <span class="number">1</span> <span class="number">2</span> <span class="number">3</span> <span class="number">4</span> <span class="number">5</span> +</pre> + + +<p>I’ve turned on the global <code>_DEBUG</code> flag, so that the function generated is +printed out. It is actually a function which <em>generates</em> the required function; +the first call <em>binds the value</em> of <code>_v1</code> to ‘start>’.</p> + +<p><a name="Placeholder_Expressions"></a></p> + +<h3>Placeholder Expressions</h3> + +<p>A common pattern in Penlight is a function which applies another function to all +elements in a table or a sequence, such as <a href="../libraries/pl.tablex.html#map">tablex.map</a> or <a href="../libraries/pl.seq.html#filter">seq.filter</a>. Lua does +anonymous functions well, although they can be a bit tedious to type:</p> + +<pre> +> = tablex.map(<span class="keyword">function</span>(x) <span class="keyword">return</span> x*x <span class="keyword">end</span>, {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">16</span>} +</pre> + + +<p><a href="../libraries/pl.func.html#">pl.func</a> allows you to define <em>placeholder expressions</em>, which can cut down on +the typing required, and also make your intent clearer. First, we bring contents +of <a href="../libraries/pl.func.html#">pl.func</a> into our context, and then supply an expression using placeholder +variables, such as <code>_1</code>,<code>_2</code>,etc. (C++ programmers will recognize this from the +Boost libraries.)</p> + +<pre> +> utils.import <span class="string">'pl.func'</span> +> = tablex.map(_1*_1, {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{<span class="number">1</span>,<span class="number">4</span>,<span class="number">9</span>,<span class="number">16</span>} +</pre> + + +<p>Functions of up to 5 arguments can be generated.</p> + +<pre> +> = tablex.map2(_1+_2,{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>}, {<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>}) +{<span class="number">11</span>,<span class="number">22</span>,<span class="number">33</span>} +</pre> + + +<p>These expressions can use arbitrary functions, altho they must first be +registered with the functional library. <a href="../libraries/pl.func.html#register">func.register</a> brings in a single +function, and <a href="../libraries/pl.func.html#import">func.import</a> brings in a whole table of functions, such as <a href="https://www.lua.org/manual/5.1/manual.html#5.6">math</a>.</p> + +<pre> +> sin = register(<span class="global">math</span>.sin) +> = tablex.map(sin(_1), {<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{<span class="number">0.8414709848079</span>,<span class="number">0.90929742682568</span>,<span class="number">0.14112000805987</span>,-<span class="number">0.75680249530793</span>} +> import <span class="string">'math'</span> +> = tablex.map(cos(<span class="number">2</span>*_1),{<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>}) +{-<span class="number">0.41614683654714</span>,-<span class="number">0.65364362086361</span>,<span class="number">0.96017028665037</span>,-<span class="number">0.14550003380861</span>} +</pre> + + +<p>A common operation is calling a method of a set of objects:</p> + +<pre> +> = tablex.map(_1:sub(<span class="number">1</span>,<span class="number">1</span>), {<span class="string">'one'</span>,<span class="string">'four'</span>,<span class="string">'x'</span>}) +{<span class="string">'o'</span>,<span class="string">'f'</span>,<span class="string">'x'</span>} +</pre> + + +<p>There are some restrictions on what operators can be used in PEs. For instance, +because the <code>__len</code> metamethod cannot be overriden by plain Lua tables, we need +to define a special function to express `#_1':</p> + +<pre> +> = tablex.map(Len(_1), {<span class="string">'one'</span>,<span class="string">'four'</span>,<span class="string">'x'</span>}) +{<span class="number">3</span>,<span class="number">4</span>,<span class="number">1</span>} +</pre> + + +<p>Likewise for comparison operators, which cannot be overloaded for <em>different</em> +types, and thus also have to be expressed as a special function:</p> + +<pre> +> = tablex.filter(Gt(_1,<span class="number">0</span>), {<span class="number">1</span>,-<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>,-<span class="number">3</span>}) +{<span class="number">1</span>,<span class="number">2</span>,<span class="number">4</span>} +</pre> + + +<p>It is useful to express the fact that a function returns multiple values. For +instance, <a href="../libraries/pl.tablex.html#pairmap">tablex.pairmap</a> expects a function that will be called with the key +and the value, and returns the new value and the key, in that order.</p> + +<pre> +> = pairmap(Args(_2,_1:upper()),{fred=<span class="number">1</span>,alice=<span class="number">2</span>}) +{ALICE=<span class="number">2</span>,FRED=<span class="number">1</span>} +</pre> + + +<p>PEs cannot contain <code>nil</code> values, since PE function arguments are represented as +an array. Instead, a special value called <code>Nil</code> is provided. So say +<code>_1:f(Nil,1)</code> instead of <code>_1:f(nil,1)</code>.</p> + +<p>A placeholder expression cannot be automatically used as a Lua function. The +technical reason is that the call operator must be overloaded to construct +function calls like <code>_1(1)</code>. If you want to force a PE to return a function, use +<a href="../libraries/pl.func.html#I">func.I</a>.</p> + +<pre> +> = tablex.map(_1(<span class="number">10</span>),{I(<span class="number">2</span>*_1),I(_1*_1),I(_1+<span class="number">2</span>)}) +{<span class="number">20</span>,<span class="number">100</span>,<span class="number">12</span>} +</pre> + + +<p>Here we make a table of functions taking a single argument, and then call them +all with a value of 10.</p> + +<p>The essential idea with PEs is to ‘quote’ an expression so that it is not +immediately evaluated, but instead turned into a function that can be applied +later to some arguments. The basic mechanism is to wrap values and placeholders +so that the usual Lua operators have the effect of building up an <em>expression +tree</em>. (It turns out that you can do <em>symbolic algebra</em> using PEs, see +<a href="../examples/symbols.lua.html#">symbols.lua</a> in the examples directory, and its test runner <code>testsym.lua</code>, which +demonstrates symbolic differentiation.)</p> + +<p>The rule is that if any operator has a PE operand, the result will be quoted. +Sometimes we need to quote things explicitly. For instance, say we want to pass a +function to a filter that must return true if the element value is in a set. +<code>set[_1]</code> is the obvious expression, but it does not give the desired result, +since it evaluates directly, giving <code>nil</code>. Indexing works differently than a +binary operation like addition (set+<em>1 </em>is_ properly quoted) so there is a need +for an explicit quoting or wrapping operation. This is the job of the <code>_</code> +function; the PE in this case should be <code>_(set)[_1]</code>. This works for functions +as well, as a convenient alternative to registering functions: <code>_(math.sin)(_1)</code>. +This is equivalent to using the `lines' method:</p> + +<pre> +<span class="keyword">for</span> line <span class="keyword">in</span> I(_(f):read()) <span class="keyword">do</span> <span class="global">print</span>(line) <span class="keyword">end</span> +</pre> + + +<p>Now this will work for <em>any</em> ‘file-like’ object which which has a <code>read</code> method +returning the next line. If you had a LuaSocket client which was being ‘pushed’ +by lines sent from a server, then <code>_(s):receive '*l'</code> would create an iterator +for accepting input. These forms can be convenient for adapting your data flow so +that it can be passed to the sequence functions in `pl.seq'.</p> + +<p>Placeholder expressions can be mixed with sequence wrapper expressions. +<a href="../libraries/pl.lexer.html#lua">lexer.lua</a> will give us a double-valued sequence of tokens, where the first +value is a type, and the second is a value. We filter out only the values where +the type is ‘iden’, extract the actual value using <code>map</code>, get the unique values +and finally copy to a list.</p> + +<pre> +> str = <span class="string">'for i=1,10 do for j = 1,10 do print(i,j) end end'</span> +> = seq(lexer.lua(str)):filter(<span class="string">'=='</span>,<span class="string">'iden'</span>):map(_2):unique():copy() +{i,<span class="global">print</span>,j} +</pre> + + +<p>This is a particularly intense line (and I don’t always suggest making everything +a one-liner!); the key is the behaviour of <code>map</code>, which will take both values of +the sequence, so <code>_2</code> returns the value part. (Since <code>filter</code> here takes extra +arguments, it only operates on the type values.)</p> + +<p>There are some performance considerations to using placeholder expressions. +Instantiating a PE requires constructing and compiling a function, which is not +such a fast operation. So to get best performance, factor out PEs from loops like +this;</p> + +<pre> +<span class="keyword">local</span> fn = I(_1:f() + _2:g()) +<span class="keyword">for</span> i = <span class="number">1</span>,n <span class="keyword">do</span> + res[i] = tablex.map2(fn,first[i],second[i]) +<span class="keyword">end</span> +</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/08-additional.md.html b/docs/manual/08-additional.md.html new file mode 100644 index 0000000..4e7cfc5 --- /dev/null +++ b/docs/manual/08-additional.md.html @@ -0,0 +1,816 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Simple_Input_Patterns">Simple Input Patterns </a></li> +<li><a href="#Command_line_Programs_with_Lapp">Command-line Programs with Lapp </a></li> +<li><a href="#Simple_Test_Framework">Simple Test Framework </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><strong>Additional Libraries</strong></li> + <li><a href="../manual/09-discussion.md.html">Technical Choices</a></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Additional Libraries</h2> + +<p>Libraries in this section are no longer considered to be part of the Penlight +core, but still provide specialized functionality when needed.</p> + +<p><a id="sip"/></p> + +<p><a name="Simple_Input_Patterns"></a></p> + +<h3>Simple Input Patterns</h3> + +<p>Lua string pattern matching is very powerful, and usually you will not need a +traditional regular expression library. Even so, sometimes Lua code ends up +looking like Perl, which happens because string patterns are not always the +easiest things to read, especially for the casual reader. Here is a program +which needs to understand three distinct date formats:</p> + +<pre> +<span class="comment">-- parsing dates using Lua string patterns +</span>months={Jan=<span class="number">1</span>,Feb=<span class="number">2</span>,Mar=<span class="number">3</span>,Apr=<span class="number">4</span>,May=<span class="number">5</span>,Jun=<span class="number">6</span>, +Jul=<span class="number">7</span>,Aug=<span class="number">8</span>,Sep=<span class="number">9</span>,Oct=<span class="number">10</span>,Nov=<span class="number">11</span>,Dec=<span class="number">12</span>} + +<span class="keyword">function</span> check_and_process(d,m,y) + d = <span class="global">tonumber</span>(d) + m = <span class="global">tonumber</span>(m) + y = <span class="global">tonumber</span>(y) + .... +<span class="keyword">end</span> + +<span class="keyword">for</span> line <span class="keyword">in</span> f:lines() <span class="keyword">do</span> + <span class="comment">-- ordinary (English) date format +</span> <span class="keyword">local</span> d,m,y = line:match(<span class="string">'(%d+)/(%d+)/(%d+)'</span>) + <span class="keyword">if</span> d <span class="keyword">then</span> + check_and_process(d,m,y) + <span class="keyword">else</span> <span class="comment">-- ISO date?? +</span> y,m,d = line:match(<span class="string">'(%d+)%-(%d+)%-(%d+)'</span>) + <span class="keyword">if</span> y <span class="keyword">then</span> + check_and_process(d,m,y) + <span class="keyword">else</span> <span class="comment">-- <day> <month-name> <year>? +</span> d,mm,y = line:match(<span class="string">'%(d+)%s+(%a+)%s+(%d+)'</span>) + m = months[mm] + check_and_process(d,m,y) + <span class="keyword">end</span> + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>These aren’t particularly difficult patterns, but already typical issues are +appearing, such as having to escape ‘-’. Also, <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.match">string.match</a> returns its +captures, so that we’re forced to use a slightly awkward nested if-statement.</p> + +<p>Verification issues will further cloud the picture, since regular expression +people try to enforce constraints (like year cannot be more than four digits) +using regular expressions, on the usual grounds that you shouldn’t stop using a +hammer when you are enjoying yourself.</p> + +<p><a href="../libraries/pl.sip.html#">pl.sip</a> provides a simple, intuitive way to detect patterns in strings and +extract relevant parts.</p> + +<pre> +> sip = <span class="global">require</span> <span class="string">'pl.sip'</span> +> dump = <span class="global">require</span>(<span class="string">'pl.pretty'</span>).dump +> res = {} +> c = sip.compile <span class="string">'ref=$S{file}:$d{line}'</span> +> = c(<span class="string">'ref=hello.c:10'</span>,res) +<span class="keyword">true</span> +> dump(res) +{ + line = <span class="number">10</span>, + file = <span class="string">"hello.c"</span> +} +> = c(<span class="string">'ref=long name, no line'</span>,res) +<span class="keyword">false</span> +</pre> + + +<p><a href="../libraries/pl.sip.html#compile">sip.compile</a> creates a pattern matcher function, which takes a string and a +table as arguments. If the string matches the pattern, then <code>true</code> is returned +and the table is populated according to the captures within the pattern.</p> + +<p>Here is another version of the date parser:</p> + +<pre> +<span class="comment">-- using SIP patterns +</span><span class="keyword">function</span> check(t) + check_and_process(t.day,t.month,t.year) +<span class="keyword">end</span> + +shortdate = sip.compile(<span class="string">'$d{day}/$d{month}/$d{year}'</span>) +longdate = sip.compile(<span class="string">'$d{day} $v{mon} $d{year}'</span>) +isodate = sip.compile(<span class="string">'$d{year}-$d{month}-$d{day}'</span>) + +<span class="keyword">for</span> line <span class="keyword">in</span> f:lines() <span class="keyword">do</span> + <span class="keyword">local</span> res = {} + <span class="keyword">if</span> shortdate(str,res) <span class="keyword">then</span> + check(res) + <span class="keyword">elseif</span> isodate(str,res) <span class="keyword">then</span> + check(res) + <span class="keyword">elseif</span> longdate(str,res) <span class="keyword">then</span> + res.month = months[res.mon] + check(res) + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>SIP captures start with ‘$’, then a one-character type, and then an +optional variable name in curly braces.</p> + +<pre> +Type Meaning +v identifier +i possibly signed integer +f floating-point number +r rest of line +q quoted <span class="global">string</span> (quoted using either ' <span class="keyword">or</span> ") +p a path name +( anything inside balanced parentheses +[ anything inside balanced brackets +{ anything inside balanced curly brackets +< anything inside balanced angle brackets +</pre> + + +<p>If a type is not one of the above, then it’s assumed to be one of the standard +Lua character classes, and will match one or more repetitions of that class. +Any spaces you leave in your pattern will match any number of spaces, including +zero, unless the spaces are between two identifier characters or patterns +matching them; in that case, at least one space will be matched.</p> + +<p>SIP captures (like <code>$v{mon}</code>) do not have to be named. You can use just <code>$v</code>, but +you have to be consistent; if a pattern contains unnamed captures, then all +captures must be unnamed. In this case, the result table is a simple list of +values.</p> + +<p><a href="../libraries/pl.sip.html#match">sip.match</a> is a useful shortcut if you want to compile and match in one call, +without saving the compiled pattern. It caches the result, so it is not much +slower than explicitly using <a href="../libraries/pl.sip.html#compile">sip.compile</a>.</p> + +<pre> +> sip.match(<span class="string">'($q{first},$q{second})'</span>,<span class="string">'("john","smith")'</span>,res) +<span class="keyword">true</span> +> res +{second=<span class="string">'smith'</span>,first=<span class="string">'john'</span>} +> res = {} +> sip.match(<span class="string">'($q,$q)'</span>,<span class="string">'("jan","smit")'</span>,res) <span class="comment">-- unnamed captures +</span><span class="keyword">true</span> +> res +{<span class="string">'jan'</span>,<span class="string">'smit'</span>} +> sip.match(<span class="string">'($q,$q)'</span>,<span class="string">'("jan", "smit")'</span>,res) +<span class="keyword">false</span> <span class="comment">---> oops! Can't handle extra space! +</span>> sip.match(<span class="string">'( $q , $q )'</span>,<span class="string">'("jan", "smit")'</span>,res) +<span class="keyword">true</span> +</pre> + + +<p>As a general rule, allow for whitespace in your patterns.</p> + +<p>Finally, putting a ‘$’ at the end of a pattern means ‘capture the rest of the +line, starting at the first non-space’. It is a shortcut for ‘$r{rest}’, +or just ‘$r’ if no named captures are used.</p> + +<pre> +> sip.match(<span class="string">'( $q , $q ) $'</span>,<span class="string">'("jan", "smit") and a string'</span>,res) +<span class="keyword">true</span> +> res +{<span class="string">'jan'</span>,<span class="string">'smit'</span>,<span class="string">'and a string'</span>} +> res = {} +> sip.match(<span class="string">'( $q{first} , $q{last} ) $'</span>,<span class="string">'("jan", "smit") and a string'</span>,res) +<span class="keyword">true</span> +> res +{first=<span class="string">'jan'</span>,rest=<span class="string">'and a string'</span>,last=<span class="string">'smit'</span>} +</pre> + + +<p><a id="lapp"/></p> + +<p><a name="Command_line_Programs_with_Lapp"></a></p> + +<h3>Command-line Programs with Lapp</h3> + +<p><a href="../libraries/pl.lapp.html#">pl.lapp</a> is a small and focused Lua module which aims to make standard +command-line parsing easier and intuitive. It implements the standard GNU style, +i.e. short flags with one letter start with ‘-’, and there may be an additional +long flag which starts with ‘–’. Generally options which take an argument expect +to find it as the next parameter (e.g. ‘gcc test.c -o test’) but single short +options taking a value can dispense with the space (e.g. ‘head -n4 +test.c’ or <code>gcc -I/usr/include/lua/5.1 …</code>)</p> + +<p>As far as possible, Lapp will convert parameters into their equivalent Lua types, +i.e. convert numbers and convert filenames into file objects. If any conversion +fails, or a required parameter is missing, an error will be issued and the usage +text will be written out. So there are two necessary tasks, supplying the flag +and option names and associating them with a type.</p> + +<p>For any non-trivial script, even for personal consumption, it’s necessary to +supply usage text. The novelty of Lapp is that it starts from that point and +defines a loose format for usage strings which can specify the names and types of +the parameters.</p> + +<p>An example will make this clearer:</p> + +<pre> +<span class="comment">-- scale.lua +</span> lapp = <span class="global">require</span> <span class="string">'pl.lapp'</span> + <span class="keyword">local</span> args = lapp <span class="string">[[ + Does some calculations + -o,--offset (default 0.0) Offset to add to scaled number + -s,--scale (number) Scaling factor + <number> (number) Number to be scaled + ]]</span> + + <span class="global">print</span>(args.offset + args.scale * args.number) +</pre> + + +<p>Here is a command-line session using this script:</p> + +<pre> +$ lua scale.lua +scale.lua:missing required parameter: scale + +Does some calculations + -o,<span class="comment">--offset (default 0.0) Offset to add to scaled number +</span> -s,<span class="comment">--scale (number) Scaling factor +</span> <number> (number ) Number to be scaled + +$ lua scale.lua -s <span class="number">2.2</span> <span class="number">10</span> +<span class="number">22</span> + +$ lua scale.lua -s <span class="number">2.2</span> x10 +scale.lua:unable to convert to number: x10 + +....(usage as before) +</pre> + + +<p>There are two kinds of lines in Lapp usage strings which are meaningful; option +and parameter lines. An option line gives the short option, optionally followed +by the corresponding long option. A type specifier in parentheses may follow. +Similarly, a parameter line starts with ‘<NAME>’, followed by a type +specifier.</p> + +<p>Type specifiers usually start with a type name: one of ‘boolean’, ‘string’,‘number’,‘file-in’ or +‘file-out’. You may leave this out, but then <em>must</em> say ‘default’ followed by a value. +If a flag or parameter has a default, it is not <em>required</em> and is set to the default. The actual +type is deduced from this value (number, string, file or boolean) if not provided directly. +‘Deduce’ is a fancy word for ‘guess’ and it can be wrong, e.g ‘(default 1)’ +will always be a number. You can say ‘(string default 1)’ to override the guess. +There are file values for the predefined console streams: stdin, stdout, stderr.</p> + +<p>The boolean type is the default for flags. Not providing the type specifier is equivalent to +‘(boolean default false)<code>. If the flag is meant to be 'turned off' then either the full +'(boolean default true)</code> or the shortcut ’(default true)‘ will work.</p> + +<p>An alternative to <code>default</code> is <code>optional</code>:</p> + +<pre> +<span class="keyword">local</span> lapp = <span class="global">require</span> <span class="string">'pl.lapp'</span> +<span class="keyword">local</span> args = lapp <span class="string">[[ + --cmd (optional string) Command to run. +]]</span> + +<span class="keyword">if</span> args.cmd <span class="keyword">then</span> + <span class="global">os</span>.execute(args.cmd) +<span class="keyword">end</span> +</pre> + + +<p>Here we’re implying that <code>cmd</code> need not be specified (just as with <code>default</code>) but if not +present, then <code>args.cmd</code> is <code>nil</code>, which will always test false.</p> + +<p>The rest of the line is ignored and can be used for explanatory text.</p> + +<p>This script shows the relation between the specified parameter names and the +fields in the output table.</p> + +<pre> +<span class="comment">-- simple.lua +</span><span class="keyword">local</span> args = <span class="global">require</span> (<span class="string">'pl.lapp'</span>) <span class="string">[[ +Various flags and option types + -p A simple optional flag, defaults to false + -q,--quiet A simple flag with long name + -o (string) A required option with argument + -s (default 'save') Optional string with default 'save' (single quotes ignored) + -n (default 1) Optional numerical flag with default 1 + -b (string default 1) Optional string flag with default '1' (type explicit) + <input> (default stdin) Optional input file parameter, reads from stdin +]]</span> + +<span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="global">pairs</span>(args) <span class="keyword">do</span> + <span class="global">print</span>(k,v) +<span class="keyword">end</span> +</pre> + + +<p>I’ve just dumped out all values of the args table; note that args.quiet has +become true, because it’s specified; args.p defaults to false. If there is a long +name for an option, that will be used in preference as a field name. A type or +default specifier is not necessary for simple flags, since the default type is +boolean.</p> + +<pre> +$ simple -o test -q simple.lua +p <span class="keyword">false</span> +input file (<span class="number">781</span>C1BD8) +quiet <span class="keyword">true</span> +o test +input_name simple.lua +D:\dev\lua\lapp>simple -o test simple.lua one two three +<span class="number">1</span> one +<span class="number">2</span> two +<span class="number">3</span> three +p <span class="keyword">false</span> +quiet <span class="keyword">false</span> +input file (<span class="number">781</span>C1BD8) +o test +input_name simple.lua +</pre> + + +<p>The parameter input has been set to an open read-only file object - we know it +must be a read-only file since that is the type of the default value. The field +input_name is automatically generated, since it’s often useful to have access to +the original filename.</p> + +<p>Notice that any extra parameters supplied will be put in the result table with +integer indices, i.e. args[i] where i goes from 1 to #args.</p> + +<p>Files don’t really have to be closed explicitly for short scripts with a quick +well-defined mission, since the result of garbage-collecting file objects is to +close them.</p> + +<h4>Enforcing a Range and Enumerations</h4> + +<p>The type specifier can also be of the form ‘(’ MIN ‘..’ MAX ‘)’ or a set of strings +separated by ‘|’.</p> + +<pre> +<span class="keyword">local</span> lapp = <span class="global">require</span> <span class="string">'pl.lapp'</span> +<span class="keyword">local</span> args = lapp <span class="string">[[ + Setting ranges + <x> (1..10) A number from 1 to 10 + <y> (-5..1e6) Bigger range + <z> (slow|medium|fast) +]]</span> + +<span class="global">print</span>(args.x,args.y) +</pre> + + +<p>Here the meaning of ranges is that the value is greater or equal to MIN and less or equal +to MAX. +An ‘enum’ is a <em>string</em> that can only have values from a specified set.</p> + +<h4>Custom Types</h4> + +<p>There is no builti-in way to force a parameter to be a whole number, but +you may define a custom type that does this:</p> + +<pre> +lapp = <span class="global">require</span> (<span class="string">'pl.lapp'</span>) + +lapp.add_type(<span class="string">'integer'</span>,<span class="string">'number'</span>, + <span class="keyword">function</span>(x) + lapp.<span class="global">assert</span>(<span class="global">math</span>.ceil(x) == x, <span class="string">'not an integer!'</span>) + <span class="keyword">end</span> +) + +<span class="keyword">local</span> args = lapp <span class="string">[[ + <ival> (integer) Process PID +]]</span> + +<span class="global">print</span>(args.ival) +</pre> + + +<p><a href="../libraries/pl.lapp.html#add_type">lapp.add_type</a> takes three parameters, a type name, a converter and a constraint +function. The constraint function is expected to throw an assertion if some +condition is not true; we use <a href="../libraries/pl.lapp.html#assert">lapp.assert</a> because it fails in the standard way +for a command-line script. The converter argument can either be a type name known +to Lapp, or a function which takes a string and generates a value.</p> + +<p>Here’s a useful custom type that allows dates to be input as <a href="../classes/pl.Date.html#">pl.Date</a> values:</p> + +<pre> +<span class="keyword">local</span> df = Date.Format() + +lapp.add_type(<span class="string">'date'</span>, + <span class="keyword">function</span>(s) + <span class="keyword">local</span> d,e = df:parse(s) + lapp.<span class="global">assert</span>(d,e) + <span class="keyword">return</span> d + <span class="keyword">end</span> +) +</pre> + + +<h4>‘varargs’ Parameter Arrays</h4> + +<pre> +lapp = <span class="global">require</span> <span class="string">'pl.lapp'</span> +<span class="keyword">local</span> args = lapp <span class="string">[[ +Summing numbers + <numbers...> (number) A list of numbers to be summed +]]</span> + +<span class="keyword">local</span> sum = <span class="number">0</span> +<span class="keyword">for</span> i,x <span class="keyword">in</span> <span class="global">ipairs</span>(args.numbers) <span class="keyword">do</span> + sum = sum + x +<span class="keyword">end</span> +<span class="global">print</span> (<span class="string">'sum is '</span>..sum) +</pre> + + +<p>The parameter number has a trailing ‘…’, which indicates that this parameter is +a ‘varargs’ parameter. It must be the last parameter, and args.number will be an +array.</p> + +<p>Consider this implementation of the head utility from Mac OS X:</p> + +<pre> +<span class="comment">-- implements a BSD-style head +</span><span class="comment">-- (see http://www.manpagez.com/man/1/head/osx-10.3.php) +</span> +lapp = <span class="global">require</span> (<span class="string">'pl.lapp'</span>) + +<span class="keyword">local</span> args = lapp <span class="string">[[ +Print the first few lines of specified files + -n (default 10) Number of lines to print + <files...> (default stdin) Files to print +]]</span> + +<span class="comment">-- by default, lapp converts file arguments to an actual Lua file object. +</span><span class="comment">-- But the actual filename is always available as <file>_name. +</span><span class="comment">-- In this case, 'files' is a varargs array, so that 'files_name' is +</span><span class="comment">-- also an array. +</span><span class="keyword">local</span> nline = args.n +<span class="keyword">local</span> nfile = #args.files +<span class="keyword">for</span> i = <span class="number">1</span>,nfile <span class="keyword">do</span> + <span class="keyword">local</span> file = args.files[i] + <span class="keyword">if</span> nfile > <span class="number">1</span> <span class="keyword">then</span> + <span class="global">print</span>(<span class="string">'==> '</span>..args.files_name[i]..<span class="string">' <=='</span>) + <span class="keyword">end</span> + <span class="keyword">local</span> n = <span class="number">0</span> + <span class="keyword">for</span> line <span class="keyword">in</span> file:lines() <span class="keyword">do</span> + <span class="global">print</span>(line) + n = n + <span class="number">1</span> + <span class="keyword">if</span> n == nline <span class="keyword">then</span> <span class="keyword">break</span> <span class="keyword">end</span> + <span class="keyword">end</span> +<span class="keyword">end</span> +</pre> + + +<p>Note how we have access to all the filenames, because the auto-generated field +<code>files_name</code> is also an array!</p> + +<p>(This is probably not a very considerate script, since Lapp will open all the +files provided, and only close them at the end of the script. See the <code>xhead.lua</code> +example for another implementation.)</p> + +<p>Flags and options may also be declared as vararg arrays, and can occur anywhere. +If there is both a short and long form, then the trailing “…” must happen after the long form, +for example “-x,–network… (string)…”,</p> + +<p>Bear in mind that short options can be combined (like ‘tar -xzf’), so it’s +perfectly legal to have ‘-vvv’. But normally the value of args.v is just a simple +<code>true</code> value.</p> + +<pre> +<span class="keyword">local</span> args = <span class="global">require</span> (<span class="string">'pl.lapp'</span>) <span class="string">[[ + -v... Verbosity level; can be -v, -vv or -vvv +]]</span> +vlevel = <span class="keyword">not</span> args.v[<span class="number">1</span>] <span class="keyword">and</span> <span class="number">0</span> <span class="keyword">or</span> #args.v +<span class="global">print</span>(vlevel) +</pre> + + +<p>The vlevel assigment is a bit of Lua voodoo, so consider the cases:</p> + +<pre> +* No -v flag, v is just { <span class="keyword">false</span> } +* One -v flags, v is { <span class="keyword">true</span> } +* Two -v flags, v is { <span class="keyword">true</span>, <span class="keyword">true</span> } +* Three -v flags, v is { <span class="keyword">true</span>, <span class="keyword">true</span>, <span class="keyword">true</span> } +</pre> + + +<h4>Defining a Parameter Callback</h4> + +<p>If a script implements <code>lapp.callback</code>, then Lapp will call it after each +argument is parsed. The callback is passed the parameter name, the raw unparsed +value, and the result table. It is called immediately after assignment of the +value, so the corresponding field is available.</p> + +<pre> +lapp = <span class="global">require</span> (<span class="string">'pl.lapp'</span>) + +<span class="keyword">function</span> lapp.callback(parm,arg,args) + <span class="global">print</span>(<span class="string">'+'</span>,parm,arg) +<span class="keyword">end</span> + +<span class="keyword">local</span> args = lapp <span class="string">[[ +Testing parameter handling + -p Plain flag (defaults to false) + -q,--quiet Plain flag with GNU-style optional long name + -o (string) Required string option + -n (number) Required number option + -s (default 1.0) Option that takes a number, but will default + <start> (number) Required number argument + <input> (default stdin) A parameter which is an input file + <output> (default stdout) One that is an output file +]]</span> +<span class="global">print</span> <span class="string">'args'</span> +<span class="keyword">for</span> k,v <span class="keyword">in</span> <span class="global">pairs</span>(args) <span class="keyword">do</span> + <span class="global">print</span>(k,v) +<span class="keyword">end</span> +</pre> + + +<p>This produces the following output:</p> + +<pre> +$ args -o name -n <span class="number">2</span> <span class="number">10</span> args.lua ++ o name ++ n <span class="number">2</span> ++ start <span class="number">10</span> ++ input args.lua +args +p <span class="keyword">false</span> +s <span class="number">1</span> +input_name args.lua +quiet <span class="keyword">false</span> +output file (<span class="number">781</span>C1B98) +start <span class="number">10</span> +input file (<span class="number">781</span>C1BD8) +o name +n <span class="number">2</span> +</pre> + + +<p>Callbacks are needed when you want to take action immediately on parsing an +argument.</p> + +<h4>Slack Mode</h4> + +<p>If you’d like to use a multi-letter ‘short’ parameter you need to set +the <code>lapp.slack</code> variable to <code>true</code>.</p> + +<p>In the following example we also see how default <code>false</code> and default <code>true</code> flags can be used +and how to overwrite the default <code>-h</code> help flag (<code>–help</code> still works fine) - this applies +to non-slack mode as well.</p> + +<pre> +<span class="comment">-- Parsing the command line ---------------------------------------------------- +</span><span class="comment">-- test.lua +</span><span class="keyword">local</span> lapp = <span class="global">require</span> <span class="string">'pl.lapp'</span> +<span class="keyword">local</span> pretty = <span class="global">require</span> <span class="string">'pl.pretty'</span> +lapp.slack = <span class="keyword">true</span> +<span class="keyword">local</span> args = lapp <span class="string">[[ +Does some calculations + -v, --video (string) Specify input video + -w, --width (default 256) Width of the video + -h, --height (default 144) Height of the video + -t, --time (default 10) Seconds of video to process + -sk,--seek (default 0) Seek number of seconds + -f1,--flag1 A false flag + -f2,--flag2 A false flag + -f3,--flag3 (default true) A true flag + -f4,--flag4 (default true) A true flag +]]</span> + +pretty.dump(args) +</pre> + + +<p>And here we can see the output of <code>test.lua</code>:</p> + +<pre> +$> lua test.lua -v abc <span class="comment">--time 40 -h 20 -sk 15 --flag1 -f3 +</span><span class="comment">----> +</span>{ + width = <span class="number">256</span>, + flag1 = <span class="keyword">true</span>, + flag3 = <span class="keyword">false</span>, + seek = <span class="number">15</span>, + flag2 = <span class="keyword">false</span>, + video = abc, + time = <span class="number">40</span>, + height = <span class="number">20</span>, + flag4 = <span class="keyword">true</span> +} +</pre> + + +<p><a name="Simple_Test_Framework"></a></p> + +<h3>Simple Test Framework</h3> + +<p><a href="../libraries/pl.test.html#">pl.test</a> was originally developed for the sole purpose of testing Penlight itself, +but you may find it useful for your own applications. (<a href="http://lua-users.org/wiki/UnitTesting">There are many other options</a>.)</p> + +<p>Most of the goodness is in <a href="../libraries/pl.test.html#asserteq">test.asserteq</a>. It uses <a href="../libraries/pl.tablex.html#deepcompare">tablex.deepcompare</a> on its two arguments, +and by default quits the test application with a non-zero exit code, and an informative +message printed to stderr:</p> + +<pre> +<span class="keyword">local</span> test = <span class="global">require</span> <span class="string">'pl.test'</span> + +test.asserteq({<span class="number">10</span>,<span class="number">20</span>,<span class="number">30</span>},{<span class="number">10</span>,<span class="number">20</span>,<span class="number">30.1</span>}) + +<span class="comment">--~ test-test.lua:3: assertion failed +</span><span class="comment">--~ got: { +</span><span class="comment">--~ [1] = 10, +</span><span class="comment">--~ [2] = 20, +</span><span class="comment">--~ [3] = 30 +</span><span class="comment">--~ } +</span><span class="comment">--~ needed: { +</span><span class="comment">--~ [1] = 10, +</span><span class="comment">--~ [2] = 20, +</span><span class="comment">--~ [3] = 30.1 +</span><span class="comment">--~ } +</span><span class="comment">--~ these values were not equal</span> +</pre> + + +<p>This covers most cases but it’s also useful to compare strings using <a href="https://www.lua.org/manual/5.1/manual.html#pdf-string.match">string.match</a></p> + +<pre> +<span class="comment">-- must start with bonzo the dog +</span>test.assertmatch (<span class="string">'bonzo the dog is here'</span>,<span class="string">'^bonzo the dog'</span>) +<span class="comment">-- must end with an integer +</span>test.assertmatch (<span class="string">'hello 42'</span>,<span class="string">'%d+$'</span>) +</pre> + + +<p>Since Lua errors are usually strings, this matching strategy is used to test ‘exceptions’:</p> + +<pre> +test.assertraise(<span class="keyword">function</span>() + <span class="keyword">local</span> t = <span class="keyword">nil</span> + <span class="global">print</span>(t.bonzo) +<span class="keyword">end</span>,<span class="string">'nil value'</span>) +</pre> + + +<p>(Some care is needed to match the essential part of the thrown error if you care +for portability, since in Lua 5.2 +the exact error is “attempt to index local ’t' (a nil value)” and in Lua 5.3 the error +is “attempt to index a nil value (local ’t')”)</p> + +<p>There is an extra optional argument to these test functions, which is helpful when writing +test helper functions. There you want to highlight the failed line, not the actual call +to <code>asserteq</code> or <code>assertmatch</code> - line 33 here is the call to <code>is_iden</code></p> + +<pre> +<span class="keyword">function</span> is_iden(str) + test.assertmatch(str,<span class="string">'^[%a_][%w_]*$'</span>,<span class="number">1</span>) +<span class="keyword">end</span> + +is_iden <span class="string">'alpha_dog'</span> +is_iden <span class="string">'$dollars'</span> + +<span class="comment">--~ test-test.lua:33: assertion failed +</span><span class="comment">--~ got: "$dollars" +</span><span class="comment">--~ needed: "^[%a_][%w_]*$" +</span><span class="comment">--~ these strings did not match</span> +</pre> + + +<p>Useful Lua functions often return multiple values, and <a href="../libraries/pl.test.html#tuple">test.tuple</a> is a convenient way to +capture these values, whether they contain nils or not.</p> + +<pre> +T = test.tuple + +<span class="comment">--- common error pattern +</span><span class="keyword">function</span> failing() + <span class="keyword">return</span> <span class="keyword">nil</span>,<span class="string">'failed'</span> +<span class="keyword">end</span> + +test.asserteq(T(failing()),T(<span class="keyword">nil</span>,<span class="string">'failed'</span>)) +</pre> + + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/docs/manual/09-discussion.md.html b/docs/manual/09-discussion.md.html new file mode 100644 index 0000000..fa16686 --- /dev/null +++ b/docs/manual/09-discussion.md.html @@ -0,0 +1,232 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" + "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html> +<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> +<head> + <title>Penlight Documentation</title> + <link rel="stylesheet" href="../ldoc_fixed.css" type="text/css" /> +</head> +<body> + +<div id="container"> + +<div id="product"> + <div id="product_logo"></div> + <div id="product_name"><big><b></b></big></div> + <div id="product_description"></div> +</div> <!-- id="product" --> + + +<div id="main"> + + +<!-- Menu --> + +<div id="navigation"> +<br/> +<h1>Penlight</h1> + +<ul> + <li><a href="../index.html">Index</a></li> +</ul> + +<h2>Contents</h2> +<ul> +<li><a href="#Modularity_and_Granularity">Modularity and Granularity </a></li> +<li><a href="#Defining_what_is_Callable">Defining what is Callable </a></li> +</ul> + + +<h2>Manual</h2> +<ul class="nowrap"> + <li><a href="../manual/01-introduction.md.html">Introduction</a></li> + <li><a href="../manual/02-arrays.md.html">Tables and Arrays</a></li> + <li><a href="../manual/03-strings.md.html">Strings. Higher-level operations on strings.</a></li> + <li><a href="../manual/04-paths.md.html">Paths and Directories</a></li> + <li><a href="../manual/05-dates.md.html">Date and Time</a></li> + <li><a href="../manual/06-data.md.html">Data</a></li> + <li><a href="../manual/07-functional.md.html">Functional Programming</a></li> + <li><a href="../manual/08-additional.md.html">Additional Libraries</a></li> + <li><strong>Technical Choices</strong></li> +</ul> +<h2>Libraries</h2> +<ul class="nowrap"> + <li><a href="../libraries/pl.html">pl</a></li> + <li><a href="../libraries/pl.Set.html">pl.Set</a></li> + <li><a href="../libraries/pl.app.html">pl.app</a></li> + <li><a href="../libraries/pl.array2d.html">pl.array2d</a></li> + <li><a href="../libraries/pl.class.html">pl.class</a></li> + <li><a href="../libraries/pl.compat.html">pl.compat</a></li> + <li><a href="../libraries/pl.comprehension.html">pl.comprehension</a></li> + <li><a href="../libraries/pl.config.html">pl.config</a></li> + <li><a href="../libraries/pl.data.html">pl.data</a></li> + <li><a href="../libraries/pl.dir.html">pl.dir</a></li> + <li><a href="../libraries/pl.file.html">pl.file</a></li> + <li><a href="../libraries/pl.func.html">pl.func</a></li> + <li><a href="../libraries/pl.import_into.html">pl.import_into</a></li> + <li><a href="../libraries/pl.input.html">pl.input</a></li> + <li><a href="../libraries/pl.lapp.html">pl.lapp</a></li> + <li><a href="../libraries/pl.lexer.html">pl.lexer</a></li> + <li><a href="../libraries/pl.luabalanced.html">pl.luabalanced</a></li> + <li><a href="../libraries/pl.operator.html">pl.operator</a></li> + <li><a href="../libraries/pl.path.html">pl.path</a></li> + <li><a href="../libraries/pl.permute.html">pl.permute</a></li> + <li><a href="../libraries/pl.pretty.html">pl.pretty</a></li> + <li><a href="../libraries/pl.seq.html">pl.seq</a></li> + <li><a href="../libraries/pl.sip.html">pl.sip</a></li> + <li><a href="../libraries/pl.strict.html">pl.strict</a></li> + <li><a href="../libraries/pl.stringio.html">pl.stringio</a></li> + <li><a href="../libraries/pl.stringx.html">pl.stringx</a></li> + <li><a href="../libraries/pl.tablex.html">pl.tablex</a></li> + <li><a href="../libraries/pl.template.html">pl.template</a></li> + <li><a href="../libraries/pl.test.html">pl.test</a></li> + <li><a href="../libraries/pl.text.html">pl.text</a></li> + <li><a href="../libraries/pl.types.html">pl.types</a></li> + <li><a href="../libraries/pl.url.html">pl.url</a></li> + <li><a href="../libraries/pl.utils.html">pl.utils</a></li> + <li><a href="../libraries/pl.xml.html">pl.xml</a></li> +</ul> +<h2>Classes</h2> +<ul class="nowrap"> + <li><a href="../classes/pl.Date.html">pl.Date</a></li> + <li><a href="../classes/pl.List.html">pl.List</a></li> + <li><a href="../classes/pl.Map.html">pl.Map</a></li> + <li><a href="../classes/pl.MultiMap.html">pl.MultiMap</a></li> + <li><a href="../classes/pl.OrderedMap.html">pl.OrderedMap</a></li> +</ul> +<h2>Examples</h2> +<ul class="nowrap"> + <li><a href="../examples/seesubst.lua.html">seesubst.lua</a></li> + <li><a href="../examples/sipscan.lua.html">sipscan.lua</a></li> + <li><a href="../examples/symbols.lua.html">symbols.lua</a></li> + <li><a href="../examples/test-cmp.lua.html">test-cmp.lua</a></li> + <li><a href="../examples/test-data.lua.html">test-data.lua</a></li> + <li><a href="../examples/test-listcallbacks.lua.html">test-listcallbacks.lua</a></li> + <li><a href="../examples/test-pretty.lua.html">test-pretty.lua</a></li> + <li><a href="../examples/test-symbols.lua.html">test-symbols.lua</a></li> + <li><a href="../examples/testapp.lua.html">testapp.lua</a></li> + <li><a href="../examples/testclone.lua.html">testclone.lua</a></li> + <li><a href="../examples/testconfig.lua.html">testconfig.lua</a></li> + <li><a href="../examples/testglobal.lua.html">testglobal.lua</a></li> + <li><a href="../examples/testinputfields.lua.html">testinputfields.lua</a></li> + <li><a href="../examples/testinputfields2.lua.html">testinputfields2.lua</a></li> + <li><a href="../examples/testxml.lua.html">testxml.lua</a></li> + <li><a href="../examples/which.lua.html">which.lua</a></li> +</ul> + +</div> + +<div id="content"> + + <h2>Technical Choices</h2> + +<p><a name="Modularity_and_Granularity"></a></p> + +<h3>Modularity and Granularity</h3> + +<p>In an ideal world, a program should only load the libraries it needs. Penlight is +intended to work in situations where an extra 100Kb of bytecode could be a +problem. It is straightforward but tedious to load exactly what you need:</p> + +<pre> +<span class="keyword">local</span> data = <span class="global">require</span> <span class="string">'pl.data'</span> +<span class="keyword">local</span> List = <span class="global">require</span> <span class="string">'pl.List'</span> +<span class="keyword">local</span> array2d = <span class="global">require</span> <span class="string">'pl.array2d'</span> +<span class="keyword">local</span> seq = <span class="global">require</span> <span class="string">'pl.seq'</span> +<span class="keyword">local</span> utils = <span class="global">require</span> <span class="string">'pl.utils'</span> +</pre> + + +<p>This is the style that I follow in Penlight itself, so that modules don’t mess +with the global environment; also, <code>stringx.import()</code> is not used because it will +update the global <a href="https://www.lua.org/manual/5.1/manual.html#5.4">string</a> table.</p> + +<p>But <code>require 'pl'</code> is more convenient in scripts; the question is how to ensure +that one doesn’t load the whole kitchen sink as the price of convenience. The +strategy is to only load modules when they are referenced. In ‘init.lua’ (which +is loaded by <code>require 'pl'</code>) a metatable is attached to the global table with an +<code>__index</code> metamethod. Any unknown name is looked up in the list of modules, and +if found, we require it and make that module globally available. So when +<a href="../libraries/pl.tablex.html#deepcompare">tablex.deepcompare</a> is encountered, looking up <a href="../libraries/pl.tablex.html#">tablex</a> causes ‘pl.tablex’ to be +required. .</p> + +<p>Modifying the behaviour of the global table has consequences. For instance, there +is the famous module <a href="../libraries/pl.strict.html#">strict</a> which comes with Lua itself (perhaps the only +standard Lua module written in Lua itself) which also does this modification so +that global variiables must be defined before use. So the implementation in +‘init.lua’ allows for a ‘not found’ hook, which ‘pl.strict.lua’ uses. Other +libraries may install their own metatables for <code>_G</code>, but Penlight will now +forward any unknown name to the <code>__index</code> defined by the original metatable.</p> + +<p>But the strategy is worth the effort: the old ‘kitchen sink’ ‘init.lua’ would +pull in about 260K of bytecode, whereas now typical programs use about 100K less, +and short scripts even better - for instance, if they were only needing +functionality in <a href="../libraries/pl.utils.html#">utils</a>.</p> + +<p>There are some functions which mark their output table with a special metatable, +when it seems particularly appropriate. For instance, <a href="../libraries/pl.tablex.html#makeset">tablex.makeset</a> creates a +<a href="../libraries/pl.Set.html#">Set</a>, and <a href="../libraries/pl.seq.html#copy">seq.copy</a> creates a <a href="../classes/pl.List.html#">List</a>. But this does not automatically result in +the loading of <a href="../libraries/pl.Set.html#">pl.Set</a> and <a href="../classes/pl.List.html#">pl.List</a>; only if you try to access any of these +methods. In ‘utils.lua’, there is an exported table called <code>stdmt</code>:</p> + +<pre> +stdmt = { List = {}, Map = {}, Set = {}, MultiMap = {} } +</pre> + + +<p>If you go through ‘init.lua’, then these plain little ‘identity’ tables get an +<code>__index</code> metamethod which forces the loading of the full functionality. Here is +the code from ‘list.lua’ which starts the ball rolling for lists:</p> + +<pre> +List = utils.stdmt.List +List.__index = List +List._name = <span class="string">"List"</span> +List._class = List +</pre> + + +<p>The ‘load-on-demand’ strategy helps to modularize the library. Especially for +more casual use, <code>require 'pl'</code> is a good compromise between convenience and +modularity.</p> + +<p>In this current version, I have generally reduced the amount of trickery +involved. Previously, <a href="../classes/pl.Map.html#">Map</a> was defined in <a href="../libraries/pl.class.html#">pl.class</a>; now it is sensibly defined +in <a href="../classes/pl.Map.html#">pl.Map</a>; <a href="../libraries/pl.class.html#">pl.class</a> only contains the basic class mechanism (and returns that +function.) For consistency, <a href="../classes/pl.List.html#">List</a> is returned directly by <code>require 'pl.List'</code> +(note the uppercase ‘L’), Also, the amount of module dependencies in the +non-core libraries like <a href="../libraries/pl.config.html#">pl.config</a> have been reduced.</p> + +<p><a name="Defining_what_is_Callable"></a></p> + +<h3>Defining what is Callable</h3> + +<p>‘utils.lua’ exports <code>function_arg</code> which is used extensively throughout Penlight. +It defines what is meant by ‘callable’. Obviously true functions are immediately +passed back. But what about strings? The first option is that it represents an +operator in ‘operator.lua’, so that ‘<’ is just an alias for <a href="../libraries/pl.operator.html#lt">operator.lt</a>.</p> + +<p>We then check whether there is a <em>function factory</em> defined for the metatable of +the value.</p> + +<p>(It is true that strings can be made callable, but in practice this turns out to +be a cute but dubious idea, since <em>all</em> strings share the same metatable. A +common programming error is to pass the wrong kind of object to a function, and +it’s better to get a nice clean ‘attempting to call a string’ message rather than +some obscure trace from the bowels of your library.)</p> + +<p>The other module that registers a function factory is <a href="../libraries/pl.func.html#">pl.func</a>. Placeholder +expressions cannot be directly calleable, and so need to be instantiated and +cached in as efficient way as possible.</p> + +<p>(An inconsistency is that <code>utils.is_callable</code> does not do this thorough check.)</p> + +</div> <!-- id="content" --> +</div> <!-- id="main" --> +<div id="about"> +<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 1.4.6</a></i> +<i style="float:right;">Last updated 2018-11-23 21:07:42 </i> +</div> <!-- id="about" --> +</div> <!-- id="container" --> +</body> +</html> diff --git a/doc/manual/01-introduction.md b/docs_topics/01-introduction.md index a8bf26a..a8bf26a 100644 --- a/doc/manual/01-introduction.md +++ b/docs_topics/01-introduction.md diff --git a/doc/manual/02-arrays.md b/docs_topics/02-arrays.md index 9ee292f..9ee292f 100644 --- a/doc/manual/02-arrays.md +++ b/docs_topics/02-arrays.md diff --git a/doc/manual/03-strings.md b/docs_topics/03-strings.md index 3808175..3808175 100644 --- a/doc/manual/03-strings.md +++ b/docs_topics/03-strings.md diff --git a/doc/manual/04-paths.md b/docs_topics/04-paths.md index 4367fe6..4367fe6 100644 --- a/doc/manual/04-paths.md +++ b/docs_topics/04-paths.md diff --git a/doc/manual/05-dates.md b/docs_topics/05-dates.md index c2431cf..c2431cf 100644 --- a/doc/manual/05-dates.md +++ b/docs_topics/05-dates.md diff --git a/doc/manual/06-data.md b/docs_topics/06-data.md index 8c759d7..8c759d7 100644 --- a/doc/manual/06-data.md +++ b/docs_topics/06-data.md diff --git a/doc/manual/07-functional.md b/docs_topics/07-functional.md index 5921a3d..5921a3d 100644 --- a/doc/manual/07-functional.md +++ b/docs_topics/07-functional.md diff --git a/doc/manual/08-additional.md b/docs_topics/08-additional.md index 2c99497..2c99497 100644 --- a/doc/manual/08-additional.md +++ b/docs_topics/08-additional.md diff --git a/doc/manual/09-discussion.md b/docs_topics/09-discussion.md index 7942d95..7942d95 100644 --- a/doc/manual/09-discussion.md +++ b/docs_topics/09-discussion.md diff --git a/lua/pl/utils.lua b/lua/pl/utils.lua index 2f973ec..9869926 100644 --- a/lua/pl/utils.lua +++ b/lua/pl/utils.lua @@ -11,7 +11,7 @@ local append = table.insert local _unpack = table.unpack -- always injected by 'compat' local utils = { - _VERSION = "1.5.4", + _VERSION = "1.6.0", lua51 = compat.lua51, setfenv = compat.setfenv, getfenv = compat.getfenv, diff --git a/penlight-scm-1.rockspec b/penlight-scm-2.rockspec index 35a834b..b5dbb1c 100644 --- a/penlight-scm-1.rockspec +++ b/penlight-scm-2.rockspec @@ -1,5 +1,5 @@ package = "penlight" -version = "scm-1" +version = "scm-2" source = { url = "git://github.com/stevedonovan/Penlight.git", @@ -64,5 +64,5 @@ build = { ["pl.types"] = "lua/pl/types.lua", ["pl.import_into"] = "lua/pl/import_into.lua" }, - copy_directories = {"doc", "tests"} + copy_directories = {"docs", "tests"} } diff --git a/tests/test-dir.lua b/tests/test-dir.lua index 6c208e8..a99b7e5 100644 --- a/tests/test-dir.lua +++ b/tests/test-dir.lua @@ -20,11 +20,11 @@ asserteq(filtered, {"foobar", "foonbar"}) local normpath = path.normpath -local doc_files = dir.getfiles(normpath "doc/", "*.ld") -asserteq(doc_files, {normpath "doc/config.ld"}) +local doc_files = dir.getfiles(normpath "docs/", "*.css") +asserteq(doc_files, {normpath "docs/ldoc_fixed.css"}) -local all_doc_files = dir.getallfiles(normpath "doc/", "*.ld") -asserteq(all_doc_files, {normpath "doc/config.ld"}) +local all_doc_files = dir.getallfiles(normpath "docs/", "*.css") +asserteq(all_doc_files, {normpath "docs/ldoc_fixed.css"}) local test_samples = dir.getallfiles(normpath "tests/lua") table.sort(test_samples) diff --git a/tests/test-path.lua b/tests/test-path.lua index 56e14cc..1f4531b 100644 --- a/tests/test-path.lua +++ b/tests/test-path.lua @@ -23,11 +23,11 @@ testpath ([[../../alice/jones]],'../../alice','jones','') testpath ([[alice]],'','alice','') testpath ([[/path-to/dog/]],[[/path-to/dog]],'','') -asserteq( path.isdir( "doc" ), true ) -asserteq( path.isdir( "doc/config.ld" ), false ) +asserteq( path.isdir( "docs" ), true ) +asserteq( path.isdir( "docs/index.html" ), false ) -asserteq( path.isfile( "doc" ), false ) -asserteq( path.isfile( "doc/config.ld" ), true ) +asserteq( path.isfile( "docs" ), false ) +asserteq( path.isfile( "docs/index.html" ), true ) local norm = path.normpath local p = norm '/a/b' |