An insert-table macro

83 views
Skip to first unread message

David Nebauer

unread,
May 13, 2019, 10:38:32 AM5/13/19
to tiddl...@googlegroups.com
Thought I'd leave this here in case it's of use to anyone. I was initially looking for a way to standardise table appearance across my wiki, and then I wanted a way to store table content in a data tiddler and insert that data into another tiddler as a table. Here is example dictionary tiddler MyTableData:

table-caption: Food Colours
column
-headings: [[Food Type]] Name Colour
type
: application/x-tiddler-dictionary

1:Fruit Orange Orange
2:Fruit Apple [[Red, pink, or green]]
3:Vegetable [[Spanish onion]] [[White or yellow]]

The table caption and column headers are defined in fields, while the dictionary rows are the table rows. Spaces are handled using the standard TW convention of double square brackets.

The 'insert-table' macro is called like so:

<$macrocall $name="insert-table"
            source="MyTableData"
            classes={{MyTableStyleClasses}}
            sort-op="!nsort[]"
            align="right center left"/>

Note that all styling is assigned via the macro call: css classes, row sort order, and column alignments. This is an attempt to separate table data (the dictionary tiddler) and styling (the macro call).

Here is the macro tiddler defining the 'insert-table' macro and helper macros:

\define insert-table(source classes sort-op:"nsort[]" align)
<$vars source="$source$" classes="$classes$" sort-op="$sort-op$" align="$align$">
<$set name="uuid-class" value=<<__insert-table_uuid>> >
<$set name="all-classes" value=<<__insert-table_all-classes>> >
<<__insert-table>>
</$set>
</$set>
</$vars>
\end
\define __insert-table_all-classes()
$(classes)$ $(uuid-class)$
\end
\define __insert-table()
<!-- COLUMN ALIGNMENT (optional) -->
<style>
<$set filter="[inserttableenlist[$(align)$]count[]]" name="alignCount">
<$list filter="[range<alignCount>]" variable="alignIndex">
.$(uuid-class)$ tr th:nth-child(<<alignIndex>>) { text-align: <$text text={{{ [inserttableenlist[$(align)$]nth<alignIndex>] }}}/>; }
.$(uuid-class)$ tr td:nth-child(<<alignIndex>>) { text-align: <$text text={{{ [inserttableenlist[$(align)$]nth<alignIndex>] }}}/>; }
</$list>
</$set>
</style>
<!-- STYLE CLASSES (optional) -->
<table class="$(all-classes)$">
<!-- CAPTION (optional) -->
<$list filter="[<source>get[table-caption]]" variable="tableCaption">
<caption><$text text=<<tableCaption>>/></caption>
</$list>
<!-- HEADER ROW (optional) -->
<$list filter="[<source>get[column-headings]]" variable="headingsField">
<thead>
<tr>
<$list filter="[enlist<headingsField>]" variable="heading">
<td><$text text=<<heading>>/></td>
</$list>
</tr>
</thead>
</$list>
<!-- DATA ROWS (required) -->
<tbody>
<$set name="filter" value="[<source>indexes[]$(sort-op)$]">
<$list filter=<<filter>> variable="rowIndex" emptyMessage="<tr><td>***NO TABLE DATA***</td></tr>">
<tr>
<$set name="rowCells" tiddler=<<source>> index=<<rowIndex>> >
<$list filter="[inserttableenlist<rowCells>]" variable="cell" emptyMessage="<td>***NO ROW DATA***</td>">
<td><<cell>></td>
</$list>
</$set>
</tr>
</$list>
</$set>
</tbody>
</table>
\end

The macros use a custom filter operator -- inserttableenlist -- which is a clone of enlist except that it preserves duplicate list items instead of discarding them. This is necessary to enable rows to have duplicate cell values. The macros also use Stephen Hradek's uuid macro (called __insert-table_uuid here). The uuid macro is used to create a unique css class defined in a style element which is then applied to the output table. This enables multiple tables in a single tiddler to have different column alignments.

There is limited display of error messages where table or row data is not found. Missing table captions and column headers are handled gracefully. This 'insert-table' macro is also surprisingly good at accepting fairly complex markup as table cell content.

I have bundled it all up as a plugin (see attached).

Regards,
David.
$__plugins_.dtn_insert-table.tid
Reply all
Reply to author
Forward
0 new messages