File Inclusion in Htm4l

The ability to include files from elsewhere is an important part of what makes m4 powerful as a macro processor. In practice, you're likely to use this most often to include files of other macros. They, in turn, might include more macros.

For example, the first line of the htm4l source of the page you're looking at (../../../htm4l/examples/inclusion.htm4l) has the following include statement:


The file ../../m4/macros contains macros that are relevant to the production of these htm4l pages. For example, each of the pages is given the same color, and each of the example pages has a special footer macro defined like this:

define(`m4_my_htm4l_example_end', ` <p> <hr> <font size="2"> Back to the htm4l m4_my_url(`htm4l/main', `home page'). Back to the htm4l m4_my_url(`htm4l/examples', `examples page'). </font> <br> <font size="1"> &copy; m4_my_sig (m4_my_email). m4_last_modified </font> m4_html_end ')

That file also contains, as its first line:


So my ~/html/htm4l/m4/macros file includes my ~/html/m4/macro file. This latest file contains macro definitions that are relevant to ALL the html I write. For example, there are macros with my email address (e.g., m4_my_email which is used in the above code).

Finally, that file (~/html/m4/macro) includes /usr/local/www/m4/html-macros which is a file of macros that are used by all users of htm4l on this machine. This file contains basic things like m4_last_modified and m4_html_end that are thought to be useful to writers of html in general.

This hierarchical inclusion of macro files may seem overly complicated, but it is actually quite simple and logical, and it works well in practice. Lower level macros (lower in the hierarchy) can redefine, enhance, or use, the macros defined at the higher levels.

When I start a new collection of related web pages (typically by creating a directory to hold them), I also make a subdirectory called m4 with a file in it called macros that includes the macro file of the logical "parent" of the new directory. When I need to create a special macro for the new set of pages, I do it here. Everything else that is useful is inherited down through the chain of inclusions. It's not exactly object-oriented html, but it works well. Experience using htm4l will make it clear at which level you should put things (assuming you adopt a similar hierarchical approach, which I recommend).

Actually, there's another level in the hierarchy, which is macros defined in an htm4l file for a one-off purpose. When you have to build a table with 4 columns and you need the first and third columns centered and the second in bold, it's trivial to create a quick macro to build the table for you (e.g.,

define(`row', `<tr><td align="center"> $1 </td> <td> <strong> $2 </strong> </td> <td align="center"> $3 </td> <td> $4 </td> </tr>') row(`Someone', `ate', `my', `timtams') row(`Was', `it', `Derek', `Smith?')

This kind of macro is the most fleeting. A need pops up for a quick macro and you just do it. If you're the conservative type of defensive html writer, you can use pushdef and popdef to define and then "undefine" such transient macros in a safe way.

To summarize, there are one-off macros in


which includes


which includes


which includes


One final note about file inclusion. Other html macro packages tell you you can use file inclusion to bring in a file of signature information, by putting something like

#include "signature.html"

(this is the syntax used in Gtml) at the bottom of all your files.

While this is an improvement over putting all the signature information in all your files, you can do better. The problem with this approach is that you may want to (or have to) move or rename the file signature.html. In that case, you'll still need to edit all your source files to include the correct info (which is exactly what you were trying to avoid in the first place).

A better solution is to put a macro call at the bottom of the file. The called macro can include a file (or simply provide the desired text itself, which is the approach I prefer). If the information in question (or the location of the file it lives in etc.) changes, you still only need to edit one file. This extra level of indirection will save you one day.

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