std.tbl — Lilush API

←index

← std

Overview

Table utilities for deep copying, merging, sorting, searching, and rendering tables as strings or markdown pipe tables.

Functions

NameSignature
renderrender(t, indent) -> output
printprint(t)
copycopy(source_table) -> copy
mergemerge(defaults, options) -> merged
get_value_by_refget_value_by_ref(t, ref) -> value
alphanumsortalphanumsort(o) -> sorted
sort_keyssort_keys(t) -> keys
include_keysinclude_keys(t, pattern) -> matched
exclude_keysexclude_keys(t, pattern) -> matched
longestlongest(t) -> max
containscontains(t, element, fuzzy) -> index
shuffleshuffle(t)
sort_by_str_lensort_by_str_len(t) -> sorted
parse_pipe_table_headerparse_pipe_table_header(header) -> name, align
calc_table_maxescalc_table_maxes(headers, t) -> maxes
pipe_tablepipe_table(headers, t) -> lines
emptyempty(t) -> is_empty

render(t, indent) -> output

Render a table as a formatted string

Produces a human-readable, indented representation of a table. Each key–value pair is placed on its own line; nested tables are indented by two spaces per level. Non-table values are formatted with tostring. If t is not a table, returns tostring(t).

Example output:

{
  name = "Alice",
  scores = {
    math = 95,
    art = 88,
  },
}

print(t)

Print a table to stdout

copy(source_table) -> copy

Create a deep copy of a table, handling cyclic references

Recursively copies all key–value pairs from source_table into a new table. Cyclic references are detected and preserved (the copy will contain the same cycle structure). Metatables are NOT copied.

merge(defaults, options) -> merged

Deep merge an options table into a defaults table

Recursively merges options into defaults. When both values for a key are tables, they are merged recursively. Otherwise the option value overwrites the default. Modifies and returns defaults.

get_value_by_ref(t, ref) -> value

Get a nested table value by dot-separated reference path

Traverses t following the keys named in ref, separated by .. Returns nil as soon as any intermediate key is missing.

Example: get_value_by_ref(t, "server.host.port") is equivalent to t.servert.server.hostt.server.host.port.

alphanumsort(o) -> sorted

Sort an array using natural alphanumeric ordering

Sorts t in place so that embedded numbers compare by value rather than lexicographically (e.g., "file10" sorts after "file9"). Returns the same array (modified in place).

Authored by Paul Kulchenko, creator of ZeroBrane Studio.

sort_keys(t) -> keys

Get sorted keys of a table using natural alphanumeric ordering

Collects all keys from t into a new array and sorts them with alphanumsort. Does not modify t. The returned array contains only keys, not values.

include_keys(t, pattern) -> matched

Filter an array to include only strings matching a pattern

Returns a new array containing only the string elements of t whose value matches pattern (anchored at the start, i.e., ^pattern). Non-string elements are silently skipped. Default pattern is ".*".

exclude_keys(t, pattern) -> matched

Filter an array to exclude strings matching a pattern

Returns a new array containing the string elements of t that do NOT match pattern (anchored at the start, i.e., ^pattern). Non-string elements are silently skipped. Default pattern is ".*".

longest(t) -> max

Get the UTF-8 length of the longest string in an array

Returns the display width of the longest string in the array, correctly handling multi-byte UTF-8 characters using utf.len.

contains(t, element, fuzzy) -> index

Check if an array contains an element, with optional fuzzy matching

Searches for element in the array t. If fuzzy is true and both element and array items are strings, performs pattern matching instead of exact comparison.

shuffle(t)

Shuffle an array in place using Fisher-Yates algorithm

Randomly shuffles the elements of the array t in place using the Fisher-Yates algorithm. This modifies the original array.

sort_by_str_len(t) -> sorted

Sort an array of strings by display length

Sorts the array of strings by their display width (handling multi-byte characters correctly) in ascending order. For equal display widths, strings are sorted lexicographically.

parse_pipe_table_header(header) -> name, align

Parse a pipe table header definition with optional alignment

Splits a header string into a column name and an alignment specifier. Supported formats:

Inputnamealign
"Name""Name""left"
"Name:left""Name""left"
"Name:l""Name""left"
"Name:right""Name""right"
"Name:r""Name""right"
"Name:center""Name""center"
"Name:c""Name""center"

calc_table_maxes(headers, t) -> maxes

Calculate maximum display widths for each column in a table

Returns a table mapping column index (1-based) to the maximum display width of any cell in that column, including the header. Uses utf.display_len for correct handling of wide characters (CJK, emoji).

headers is an array of header definition strings (see parse_pipe_table_header). t is an array of rows, each row being an array of cell values.

pipe_table(headers, t) -> lines

Generate a markdown pipe table from headers and data

Returns an array of strings (one per line) forming a markdown pipe table. headers is an array of header definitions (see parse_pipe_table_header). t is an array of rows, each row being an array of cell values. Column widths are computed by calc_table_maxes. Headers are center-aligned; data cells follow the alignment declared in each header definition.

Example:

local lines = pipe_table(
    { "Name", "Age:right", "City:center" },
    {
        { "Alice", 30, "New York" },
        { "Bob",   25, "Los Angeles" },
    }
)

empty(t) -> is_empty

Check if a table is empty (has no keys)

Returns true if the table has no keys (is empty), false otherwise. Note: This only checks for keys, not for nil values.