This example uses the macros from the numbered table example and extends it by adding a caption to the table. The caption will contain the number of items in the table, and it is generated automatically so we never need update it when the number of items in the table changes (even supposing we remember).

The table looks like this:

The 5 best fruits
1 Bananas
2 Apples
3 Peaches
4 Oranges
5 Lemons

Given what we did in the last example, you might think to yourself that this is clearly a trivial extension. If the table caption followed the table instead of preceedng it, you'd be right. In that case, we'd simply use the num macro to get the number.

More difficult is the case where we want the table caption to be BEFORE the table, as shown above. In that case, we need to know how many rows are in the table before we print the caption. But to know this, we need to have already processed the table itself (and presumably to have already produced the html to display it).

Fortunately, m4 provides a very simple solution. We use a diversion to temporarily store the output from processing the table html. Then we make the caption (using the num macro of course). Finally, we undivert the html output from the table. In this way we get to have our cake and eat it too.

Here's what the whole thing looks like in htm4l:

define(`num', `1') define(`incnum', `define(`num', incr(num))') define(`my_row', `<tr> <td align="center"><strong>num</strong></td> <td> $1 </td> </tr> incnum') divert(1) my_row(`Bananas') my_row(`Apples') my_row(`Peaches') my_row(`Oranges') my_row(`Lemons') divert(0) <center> The decr(num) best fruits <table border="1" cellpadding="5"> undivert(1) </table> </center>

The macro call divert(1) begins diverting output to diversion number 1. This causes all the html generated by the my_row macros to be stored elsewhere (we don't care where). Calling divert(0) diverts text back to standard output (its normal destination). Finally, the undivert(1) call causes m4 to ouput (again to standard output) whatever text has accumulated in diversion number 1.

This may seem odd and take a little while to fully understand. It's actually very simple. Just think of a diversion as being something like a variable in a programming language. It's not, but that's not a bad way to get a first idea of what's going on. Read your m4 documentation for more detail.

Back to the htm4l home page. Back to the htm4l examples page.
© Terry Jones (terry <AT> Last modified: Mon Oct 2 02:21:32 CEST 2006