Why Sponsor Oils? | source | all docs for version 0.25.0 | all versions | oils.pub
ul-table
is an HTML processor that lets you write tables as bulleted
lists, in Markdown.
It's a short program I wrote because I got tired of reading and writing <tr>
and <td>
and </td>
and </tr>
. And I got tired of aligning numbers by
writing <td class="num">
for every cell.
Let's see how it works. How do you make this table?
Shell | Version |
---|---|
bash | 5.2 |
OSH | 0.25.0 |
With ul-table
, you create a two-level Markdown list, inside <table>
tags:
<table>
- thead
- Shell
- Version
- tr
- [bash](https://www.gnu.org/software/bash/)
- 5.2
- tr
- [OSH](https://oils.pub/)
- 0.25.0
</table>
The header and data rows are at the top level, and the cells are indented under them.
The conversion takes 2 steps: it's Markdown → HTML → HTML.
First, any Markdown processor will produce this list structure, with <ul>
and
<li>
:
Second, our ul-table
plugin parses and transforms that into a table, with
<tr>
and <td>
:
Shell | Version |
---|---|
bash | 5.2 |
OSH | 0.25.0 |
So ul-table
is an HTML processor, not a Markdown processor. But it's
meant to be used with Markdown.
Compared to other table markup formats, ul-table
is shorter, less noisy, and
easier to edit:
Recall that a ul-table
is a two-level Markdown list, between <table>
tags. The top level list contains either:
thead |
zero or one, at the beginning |
tr |
zero or more, after thead |
The second level contains the contents of cells, but you don't write td
or <td>
.
To make the table look nice, I add a <style>
tag, inside Markdown:
<style>
table {
margin: 0 auto;
}
td {
padding-left: 1em;
padding-right: 1em;
}
</style>
HTML attributes like <tr class=foo>
and <td id=bar>
let you format and
style your table.
You can add attributes to cells, columns, and rows.
Name | Age |
---|---|
Alice | 42 |
Bob | 9 |
Add cell attributes with a cell-attrs
tag after the cell contents:
- thead
- Name
- Age
- tr
- Alice
- 42 <cell-attrs class=hi />
- tr
- Bob
- 9
You must use a self-closing tag:
<cell-attrs /> # Yes
<cell-attrs> # No: this is an opening tag
Notice that ul-table
takes the attributes from the <cell-attrs />
tag, and
puts it on the generated <td>
tag.
Name | Age |
---|---|
Alice | 42 |
Bob | 9 |
To add attributes to every cell in a column, put <cell-attrs />
in the
thead
section:
- thead
- Name
- Age <cell-attrs class=num />
- tr
- Alice
- 42 <!-- this cell gets class=num -->
- tr
- Bob
- 9 <!-- this cells gets class=num -->
Then every <td>
in the column will "inherit" those attributes. This is
useful for aligning numbers to the right:
<style>
.num {
align: right;
}
</style>
If the same attribute appears in a column in both thead
and tr
, the values
are concatenated, with a space. Example:
<td class="from-thead from-tr">
Name | Age |
---|---|
Alice | 42 |
Bob | 9 |
To add row attributes, put <row-attrs />
after the - tr
:
- thead
- Name
- Age
- tr
- Alice
- 42
- tr <row-attrs class="special-row" />
- Bob
- 9
This example uses more features, like Markdown and HTML inside cells. You may want to view the source text for this table: doc/ul-table.md.
Shell | Version | Example Code | ||||
---|---|---|---|---|---|---|
bash | 5.2 |
|
||||
dash | 1.5 | Inline HTML | ||||
mksh | 4.0 |
|
||||
zsh | 3.6 | Unordered List
|
||||
yash | 1.0 | Ordered List
|
||||
This is paragraph one. This is paragraph two |
Another cell with ... ... multiple paragraphs. |
Another table:
OSH | YSH |
---|---|
|
|
x | y |
Here are some quirks I ran into when using ul-table
.
(1) CommonMark doesn't allow empty list items:
- thead
-
- above is not rendered as a list item
You can work around this by using a comment, or invisible character:
- tr
- <!-- empty -->
- above is OK
- tr
-
- also OK
(2) Similarly, a cell with a literal hyphen may need a comment or space in front of it:
- tr
- <!-- hyphen --> -
- -
ul-table
is a nice way of writing and maintaining HTML tables. The appendix
has links and details.
TODO: I would like someone to produce a DOM-based implementation!
Our implementation is pretty low-level. It's meant to avoid the "big load anti-pattern" (allocating too much), so it's a necessarily more verbose.
A DOM-based implementation should be much less than 1000 lines.
ul-table
.
I converted the tables in these September posts to ul-table
:
The markup was much shorter and simpler after conversion!
TODO:
<th>
is like <td>
, but it belongs in <thead><tr>
. Browsers make it
bold and centered.<colgroup>
and <col>
often do do what I want.
class=
columns and align them to the
right or left. You have to put class=
on every <td>
cell instead.tfoot
?tbody
?We could help users edit well-formed tables with enforced column names:
- thead
- <cell-attrs ult-name=name /> Name
- <cell-attrs ult-name=age /> Age
- tr
- <cell-attrs ult-name=name /> Hi
- <cell-attrs ult-name=age /> 5
This is a bit verbose, but may be worth it for large tables.
Less verbose syntax idea:
- thead
- <ult col=NAME /> <cell-attrs class=foo /> Name
- <ult col=AGE /> Age
- tr
- <ult col=NAME /> Hi
- <ult col=AGE /> 5
Even less verbose:
- thead
- {NAME} Name
- {AGE} Age
- tr
- {NAME} Hi
- {AGE} 5
The obvious problem is that we might want the literal text {NAME}
in the
header. It's unlikely, but possible.