Tagged floats (`{value: N, isFloat: true}`) were matched by
`isPlainObject` and rendered as a two-column table with "value" and
"isFloat" headers instead of as a formatted number. This is now fixed.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
Lua `${...}` expression results are rendered using two parallel paths:
- **HTML path** (display path) for visual display in the editor and
- **Markdown path** (copy path) for the *copy button* output.
Every Lua value is classified as one of:
- **Scalar:** number, string, boolean, or `nil`
- **Empty table:** `{}`
- **Array:** a `LuaTable` with only sequential integer keys (no string keys)
- **Array of tables:** an array where every element is a `LuaTable`
- **Record:** a `LuaTable` with any string key (may also have integer keys)
Scalars are rendered as inline Markdown - wiki links, tags, bold, and
other inline syntax are resolved, `nil` renders as `<span data-empty>`.
Empty tables render as `<table data-table-empty>`.
An array of tables renders as a multi-row `<table>`. Column headers
are the union of all element keys. Each cell value recurses through
the same classification.
An array of scalars (or a mix of scalars and tables) renders as `<ul>`
with one `<li>` per element. Each item value recurses.
A record renders as a single-row `<table>` with one column per key.
Cell values recurse.
Every `<td>` carries `data-table-cell-type` and optionally
`data-table-cell-empty`. Every `<li>` carries `data-list-item-type` and
optionally `data-list-item-empty`. The outermost element carries
`data-type`. These attributes allow CSS styling of rendered widgets.
Nesting is **unlimited**. Tables inside cells, lists inside cells,
tables inside list items all render correctly in HTML.
Scalars render as plain text. Lua `nil` renders as `nil`. Empty tables
render as `*(empty table)*`.
An array of tables renders as a pipe-delimited Markdown table. Nested
values in cells are rendered as Lua literals via `toStringAsync()`
(e.g. `{1, 2, 3}` or `{a = 1}`), since Markdown table cells cannot
contain block-level content.
An array of scalars renders as a Markdown list (`- item`). When a list
item is itself multi-line (a sublist) it uses an empty bullet with
two-space indented content on the next line:
```
- 1
- 2
-
- nested 1
- nested 2
```
Nested tables or arrays **beyond the first list nesting** level are
rendered as Lua literals.
A record renders as a single-row Markdown table.
Column headers follow the order returned by `LuaTable.keys`: string keys
in their insertion order, followed by integer keys in ascending order.
For example, `{a = 1, b = 2, 3, d = 4}` produces columns `a
| b | d | 1`. This is consequence of `LuaTable` storing string keys
and the array part separately (for performance).
Arrays mixing plain scalars and record-like tables (e.g. `{1, 2, 3,
{a=3}}`) were previously rendered as a single flat table due to an
internal JS conversion (`toJS`). They now render as a list, with record
elements shown as nested tables - which more accurately reflects their
Lua structure. This is the only divergence from the original
presentation.
To restore the old tabular layout, wrap all elements as records with
a consistent key:
```lua
-- Before (was a flat table, now a list with nested table):
${{1, 2, 3, {a=3}}}
-- After (explicit records, renders as a table):
${{{value=1}, {value=2}, {value=3}, {a=3}}}
```
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
The table style is determined by the header row. After normalizing the
header (filling empty cells between consecutive delimiters), extract
two properties: the column count and whether the header starts with
a delimiter.
For each data row, normalization proceeds in three steps. First, fill in
empty cells between consecutive delimiters (this handles empty cells in
the middle of a row). Second, if the header has no leading delimiter but
the row does, insert an empty cell after the row's leading delimiter (this
corrects the one-position shift caused by the row having a leading pipe
that the header lacks. Third, if the row has fewer cells than the header
column count, pad with empty cells at the end (this handles rows that
are shorter than the header because trailing pipes or cells were
omitted).
The same normalization is applied both in the renderer and the indexer.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
The Markdown parser omits `TableCell` nodes for empty cells, so
`collectNodesOfType` returns fewer cells than columns.
The indexer mapped cells to headers by array index, causing all cells
after an empty one to shift left.
The HTML renderer already solved this: its `TableRow` case walks the
children and injects empty `TableCell` nodes between consecutive
`TableDelimiter` nodes with no cell in between.
This patch extracts that same normalization logic into a reusable
`normalizeTableRow` helper and applies it to each row before collecting
cells.
The original index-based cell-to-header mapping then works correctly
without any positional arithmetic. I feel like this is more elegant
solution to the issue.
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>
For example, with the following table:
```markdown
| a | b | c |
| --- | --- | --- |
| 1 | | 3 |
| 1 | 2 | 3 |
| a | b | c |
| a | b | |
| | b | c |
| x | | |
| | | z |
```
the following query results in dataset with shifted columns
when cells are empty:
```lua
from
index.tag 'table'
where
page == 'test'
order by
pos asc
select {
a, b, c
}
```
This is now fixed and gives correct results:
|0 |1 |2 |
|--|--|--|
|1 | |3 |
|1 |2 |3 |
|a |b |c |
|a |b | |
| |b |c |
|x | | |
| | |z |
Signed-off-by: Matouš Jan Fialka <mjf@mjf.cz>