Devious Fish
Support

Perette Barella, Contractor
176 Middlesex Road, Rochester NY 14610
(585) 317-3013 / (585) 482-3819 (facsimile)

M4 and HTML

A light-weight, development-side suite for building specifications-compliant web sites.

1. Introduction

Contents

1.1. Changes in this revision

The latest revision of the m4 package moves to HTML 4.01 strict and starts making heavy use of CSS. Previous releases were HTML 4.0 transitional, but still used little CSS and relied heavily on deprecated HTML elements for formatting.

1.2. Why?

Using m4 is a better way to develop complex static web sites.

  • Managing complexity. Using templates and global replace on a web site only goes so far, and awk(1) or perl(1) scripts to modify pages is a hassle and prone to inaccuracy. Using macros allows you to centralize important data and wrangle it effectively into a final form.
  • Powerful layouts. Because m4 can create results non-linearly using diversions (see an m4 manual) and can source from multiple files, it's easy to create and maintain layouts. Inline macros to create headings can also add navigation elements, and links can automatically populate themselves with text and destination document descriptons.
  • Filling the gap, and keeping it simple. Content management systems solve web maintenance issues by adding complexity on the server. This requires database backends, and puts more load on the server side. By moving complexity to the development side, serving can be as simple as reading a file and sending it to the network– less to maintain, less to break, less to pay for. Individual pages remain as a document, utilizing navigation and layouts defined in included components.

The macro package addresses these issues. It provides a way to centralize common pieces, making it easy to standardize a site's pages. It does so with common, proven open-source tools on the developer-side of things rather than the production-side. Built-in validation at compile time ensures sites are reliable by automatically performing standards compliance checks.

2. Dependencies

The m4 macro package depends on:

  • Bash, the Bourne-again shell.
  • ImageMagick suite of command line jpeg manipulation tools.
    • MAGICK_HOME must be set to the base of the ImageMagick install.
    • On Solaris: LD_LIBRARY_PATH must include MAGICK_HOME/lib.
  • HTML Tidy command line version, available from Source Forge.
    • Use sfcvsget script to get the latest SourceForge distribution (requires CVS be installed on your machine): sfcvsget tidy
  • The OpenSP SGML or compatible validator and DTDs, available from SourceForge.
    • To disable the validator, insert the word 'true' before 'onsgmls' in Include/Makefile.inc.
  • Macintosh: Install XCode, the development suite found on the operating system install DVD.

3. Getting started - stddefs.m4

To configure a new development area:
  1. Set WEBBASE: WEBBASE=$HOME/my_web_project; export WEBBASE
  2. Create the directory: mkdir $WEBBASE
  3. Install the development kit into the directory.
  4. Source files are named *.web, and are processed into *.html. Create a .web file with an editor with the following contents:
        m4_include(stddefs.m4)
        _HEADER(``My New Web Page'')
        Hello, world!
    
  5. Create makefiles: Include/makemake
  6. Build! make
You should now have a working .html file.

4. Path set-up - stddefs.m4

The first line of each .web file must read:

m4_include(stddefs.m4)

stddefs.m4 is created automatically by makeinc(1) during the build process containing relative directory paths to the development root (defined by the WEBBASE environment variable). Definitions include DIR_HERE, DIR_TOP, DIR_INCLUDE. stddefs.m4 also imports your site information (WEBBASE/siteinfo.m4) and the essential m4 macros (DIR_INCLUDE/html.m4).

Always use the following to refer to other parts of your web site to minimize problems should you need to rearrange your site. Consider defining some of your own in your siteinfo.m4 file.

WEBBASE
Environment variable which specifies the root of the development area.
DIR_HERE
The path from WEBBASE to the current directory.
DIR_TOP
Contains a relative path to the top of the HTML work area. In the top directory it's ".", in one directory down it's "..", two directories down "../..", etc.
DIR_INCLUDE
Equivalent to DIR_TOP/Include.
DIR_GFX
Equivalent to DIR_TOP/Graphics.

5. Defining site ownership - siteinfo.m4

The owner information file should go in the base of the development hierarchy ($WEBBASE/siteinfo.m4). It must contain:

SITE_NAME
The name of the site. This is appended before the individual page titles (followed by a dash) in the HTML header's <TITLE> element.
SITE_DOMAIN
Contains the domain name and any leading directory components. (The path relative to WEBBASE is appended to form a complete URL in the page footer.)
SITE_URL
The domain name with leading 'http://'.
SITE_MAIL
Specifies the owner's visible e-mail address.
LINK_MAIL
Specifies the link to send mail to the owner. Usually mailto:SITE_MAIL.)
SITE_OWNER
Specifies the owner's name.
SITE_SNAILMAIL
Specifies the owner's snail-mail address.

This file is also a good place for to call _COPYRIGHT or set other site-wide details.

A navigation menu can be placed in this file, although I personally prefer to put it in a separate file.

6. Basic Page Layout - html.m4

Included automatically from stddefs.m4, html.m4 sets up the quote characters to be ``double accent-grave for an open quote, double apostrophe'' for a close quote.

6.1. HTML Simplification Macros

_HEADER(pagename [, revision])
Creates an HTML 4.01 header, including page title and revision ID if provided.
_REVISION(text)
Inserts text into the revision data at the bottom of the page.
_SUPPRESS_FOOTER
This macro hides the page footer, including page URL, copyright, affiliations, and revision data.
_COPYRIGHT(message)
Invoke this macro prior to _HEADER to set the copyright message in the page footer. Calling this macro with no parameters disables the copyright.
_STYLE(styledata)
Inserts in-line style data into the header. <STYLE> and </STYLE> elements are inserted automatically. STYLE may be used multiple times, combining styledata into one style block.
_STYLESHEET(location [, media])
Inserts a stylesheet <LINK> element into the document header. Invoke this macro after HEADER. Media stylesheets are placed in the header after generic stylesheets.
_DOCLINK(linkdata)
Inserts a <LINK> element into the document header.
_META(name, link)
Adds a <META> element with the given NAME and CONTENT attributes to the document header. If you need to include another type of <META> tag such as HTTP-EQUIV, use the form below.
_META(metatag)
Adds the <META> element to the document header.
_HTTPSTATUS(status-value)
Adds a HTTP-EQUIV <META> tag to the document header with the specified status-value along with a standard message for that status.

6.2. Graphic constants

The following simple macros (constants) are defined in html.m4. They use the relative directory specified in DIR_GFX (found in stddefs.m4, which is created by makeinc). Since DIR_GFX is relative, the path will continue to function when moved to a different system if the directory hierarchy is maintained.

Predefined Pictures of everyday items

ICON_MAILBOX
A mail box, the kind you receive mail in.
ICON_POSTBOX
A mail box, the kind you send mail in.
ICON_SNAILMAIL
A mail box representing snail mail.
ICON_PHONE
A phone.
ICON_HOME
A picture of a house.
ICON_CONSTRUCT
A construction symbol.
ICON_INFO
"Information" symbol - a query mark.

Movement symbols

ICON_UPONE
An icon for movement one level toward the root in a hierarchy.
ICON_TOPLEVEL
An icon for movement to the root of a hierarchy.)
ICON_BACKONE
An icon representing movement one frame/page prior in a sequence.
ICON_FORWARD
An icon representing movement one frame/page forward in a sequence.

6.3. Image and Graphic Macros

_IMAGE(location, img-tag-extra, scale-factor)
Creates an inline image. location is the relative path to the graphic. image-tag-extra is inserted into the IMG tag, and should contain ALT and LONGDESC attributes for accessibility. This macro calls an external script to generate size information for the graphic, then adds HEIGHT and WIDTH attributes to the <IMG> element if the external script returns the data. This allows accelerated page layout, since layout can occur without acquiring graphics. For images not on your site, you should put in <IMG> elements manually, including HEIGHT and WIDTH attributes.

The scale-factor parameter can be used to resize the displayed image. scale-factor is expressed as a percentage of the original image's size. If scaling is requested, hyperlinks will be added to allow the image to be viewed at original size. _THUMBNAIL performs a similar task. However, using scale-factor does not create any thumbnails, relying on the client's browser to do the scaling rather than the macro package.

_THUMBNAIL_QUALITY
This macro sets thumbnail quality. It can be changed to a number between 1 and 99, with 1 representing lowest and 99 highest quality.
_THUMBNAIL(name, max-width, max-height, img-tag-extra)
Creates a single thumbnail for name. See notes under _THUMBNAILS, below. _THUMBNAIL creates a single thumbnail, with no array formatting around it. The img-tax-extra will be inserted into the <IMG> element that is generated; an ALT attribute is suggested at a minimum. A pseudoattribute QUALITY can set the image quality for the single thumbnail; this does not change the setting for _THUMBNAIL_QUALITY.
_THUMBNAILS(names, per-line, max-width, max-height)
Creates thumbnails for names. names may be a space-separated list, and may contain shell wildcards. _THUMBNAILS will generate thumbnail images with the name tn_names, and layout the thumbnails in an array using a <TABLE> element. per-line images will be placed in each row before a new row will be started.

Thumbnails are generated with the constraints of max-width and max-height; one or more constraint must be specified. If both are specified, the image size will be the smaller of the two possible sizes. If one constraint is specified, the thumbnails will all be precisely that dimension.

ALT attributes for the images are created from file names with trailing digits stripped and dashes & underscores changed to spaces.

_CAPTIONEDTHUMBNAILS(caption-file, names, per-line, max-width, max-height)
Behaves like _THUMBNAILS, but reads captions for the images from caption-file. The caption file format is image-file-name tab caption.
_ORDEREDTHUMBNAILS(caption-file, per-line, max-width, max-height)
Behaves like _CAPTIONEDTHUMBNAILS, but the file list is taken in sequence from the caption file. The caption file may contain blank lines and comment lines beginning with #.

6.4. Page layout macros

The following complex macros are defined in html.m4:

_FOOTNOTE(text)
Inserts a numeric reference 1  to text, which gets inserted at the bottom of the page. A link from the footnote back to the point at which this macro appears is also inserted. Footnotes are automatically numbered starting with 1.
_FOOTNOREF(text)
Inserts a footnote without a reference link in the text.
_SET_TABLE_ROW_GROUP(rows-per-group, [class])
Sets up row groups for the _ROW macro. When using this, the table is divided into group of rows-per-group lines, with alternate groups of rows being assigned class class, which defaults to alternateColor. The intent is to make unwieldy tables more legible by alternating colors, like green-bar paper. Thus, setting rows-per-group to 1 will cause every row to alternate. By default, alternating row groups is not used.
_ROW(type, data1, data2, data3, data4...)
Creates a table row, inserting the requisite <TR> and <TH> or <TD> elements. type is either TH or TD. When type is TH, the row count is reset, causing the next group of rows to be rows-per-group large. The header row itself is not part of the row group. (See _SET_TABLE_ROW_GROUP above.)
_ADDRESS(address)
Creates a box with address inside of it. ICON_SNAILMAIL is placed to the left of the address.

6.5. Indexing Macros

When run through the indexer, indexed items are all collected and formatted into a book-like index with links to the respective pages. If using the table of contents module toc3.m4, the links are to the specific chapter, section, or subsection in which the index entry occurs.

_IX(category)
Index category, and include it in the document at the current point.
_INDEX(category, subcategory...)
Index under category, using appropriate subcategories as necessary. Five levels of categorization are supported. Nothing is inserted inline.
_IXSEE(destination, category, subcategory...)
Place a 'See destination' entry into the index under the specified category.
_ISSEEALSO(destination, category, subcategory...)
Place a 'See also destination' entry into the index under the specified category.

6.6. Cross-page metadata features

All _GET_PAGE_* macros should set a dependency on their target file, but do not due to the possibility of circular references.
_GET_PAGE_TITLE(page, pretext, posttext)
Retrieves the title of the page, which is a .web document.
_GET_PAGE_DESCRIPTION(page, pretext, posttext)
Retrieves the description of the specified page. Pretext and posttext are inserted before and after the page title, respectively, only if the page title exists. Thus, _GET_PAGE_DESCRIPTION(``fish.web'',Description:'') will insert "Description:" only if a description was found.
_GET_PAGE_AUTHOR(page, pretext, posttext)
Retrieves the author of the specified page.
_GET_PAGE_COPYRIGHT(page, pretext, posttext)
Retrieves the copyright notice of the specified page.
_LINK(page)
Links to the specified page, using the document's title as the link text.
_LINK_WITH_TITLE(page)
Links to the specified page, using the document's title as the link text and the document's description for the link's TITLE attribute.

6.7. Miscellaneous Macros

m4_cinclude(file, pre-include-text, post-include-text)
Conditional m4_include. If file exists and has size > 0, then insert pre-m4_include-text at the current point in the document, include the file itself, followed by post-include-text.

7. Layout Tables - tablelayout.m4

Using tables for layout is considered bad form due to problems it creates for accessibility features. CSS provides an alternate way to create table-style layouts using the <DIV> element, but this method is problematic for Internet Explorer 6 & 7. The tablelayout.m4 module provides support for CSS tables, using Microsoft's conditional comments to provide backward compatibility (alas using the forbidden table layout) with IE 6 & 7.
_BEGIN_TABLE(number-of-columns, class-extra)
Initiates a table. The table's CSS class is m4columns-number-of-columns.
_BEGIN_ROW
Marks the start of a row. The row's CSS class is m4layoutrow or m4mslayoutrow.
_BEGIN_COLUMN
Marks the start of a column. Not presently supported.
_CELL(class-extra)
Marks the start of a cell. The cell's CSS class is m4layoutcell, or msm4layoutcell for compatibility mode.
_END_TABLE
Completes the table.

8. Navigation Menus - navigation.m4

navigation.m4 has support for creating horizontal and vertical menus, known respectively as navigation bars and navigation menus. Navigation bars and menus may be used independently or together. Precise details such as color can be set via CSS, with the basic form and default colors provided by the m4 package.

By default, the navigation buttons highlight when the mouse hovers over a button; pull-downs display on hover for the navigation bar. Links to the current page highlight with a slightly different color to show it is selected (if the current page is not linked from the navigation menu, nothing is highlighted in this manner).

Notes/Caveats:

  • When printed, navigation components are eliminated from pages.
  • For handheld devices, navigation bars render as a list. Pull-down items display on hover, slightly to the right and below their parent item.
  • Menu bars render as multi-level bulleted lists for Internet Explorer 6.
  • When used in combination, open navigation bar pull-down items render under the content. Adding a Internet Explorer specific style sheet that sets a large margin above the content (DIV.content) is the simplest way to correct the problem.
_NAV_MENU_GROUP (_NAV_BAR_GROUP)(group-name [, link-destination [, class]])
Creates a heading for group-name in the navigation menu. The heading may optionally link to link-destination. There is no corresponding macro for the menu bar. If specified, the UL element surrounding the subsequent navigation items is assigned class.
_NAV_BAR_GROUP_NONE
Terminates the current menu bar grouping, so that the next _NAV_MENU_ITEM call will create an item on the menu bar rather than the pop-up menu.
_NAV_MENU_IMAGE(destination, location, img-tag-extra, scale-factor)
Inserts an image into the navigation menu. The image is linked to destination, if not null. The remaining parameters are the same as those in _IMAGE There is no corresponding macro for the menu bar.
_NAV_MENU_ITEM (_NAV_BAR_ITEM)(destination, item-name [, details [, directory]])
Creates an entry in the navigation menu (navigation bar) for item-name to link to destination. The link title will be set to details, which is typically rendered as pop-up information when hovering over the link. For _NAV_BAR_ITEM only, if the current page is in directory then the item will be shown selected.
_NAV_MENU_COLLAPSE
Enables the automated collapsing menu feature. When enabled, the groups in the navigation menu are shown as headings only except for the one with the selected page, which is left expanded. Twisties are added before the headings, and clicking on the heading will open or close the respective section. As such, group titles should not be links when using the collapsing feature. If JavaScript is not available, this feature does not function.
_NAV_HEADING(heading [, name])
Creates a heading at the current point in the document, and adds a corresponding entry to the navigation menu.
_NAV_SET_HEADING(heading-element)
Specifies the element type that will be surround a heading created with _NAV_HEADING.

9. Generating Tables of Contents - toc3.m4

toc3.m4 generates tables of contents ("TOC"). TOCs are created at the top of an HTML document from _CHAPTER, _SECTION, and _SUBSECTION macros; these table of contents entries are hyperlinked to the appropriate section in the document body. Section headers are automatically inserted along with their numbering in the document body.

The earlier toc.m4 implementation is deprecated and should not be used.

Layout variables (explained below) should be redefined before the first _SECTION or _SUBSECTION begins.

_CHAPTER(section name [, reference-name])
Begins a chapter. Creates the TOC entry with a link to the current location in the document, and puts a header with the section name the the current location. The link name is automatically generated if reference-name is not provided.
_SECTION(section name [, reference-name])
Begins a section. Creates a second-level TOC entry and heading at the present point in the body. You must invoke _CHAPTER prior to _SECTION, or numbering and layout is wrong.
_SUBSECTION(section name [, reference-name])
Begins a subsection. Creates a third-level TOC entry. You must invoke both _CHAPTER and _SECTION prior to _SUBSECTION, or numbering and layout is wrong.
TOC_CHAPTERS_ONLY
Hides sections and subsections in the tables of contents.
TOC_NO_SUBSECTIONS
Hides subsections in the tables of contents.
__CHAPTER_NUM, __SECTION_NUM, __SUBSECT_NUM
Contains the current chapter, section, and subsection number respectively.
_CHAPTER_NAME, __SECTION_NAME, __SUBSECT_NAME
Contains the current chapter, section, or subsection name.
_CHAPTER_TOCFORMAT, _CHAPTER_FORMAT
Defines the TOC and body format for a chapter. Defaults to:
Chapter number. Chapter name
__SECTION_TOCFORMAT, _SECTION_FORMAT
Defines the TOC and body format for a section. Defaults to:
Chapter number.Section number. Section name
Numbering may be removed by calling _UNNUMBERED_SECTIONS.
_SUBSECT_TOCFORMAT, SUBSECT_FORMAT
Defines the TOC and body format for a subsection. Defaults to:
Chapter #.Section #.Subsection #. Subsection name
Numbering may be removed with _UNNUMBERED_SUBSECTIONS.
_TOC_HEADER
Defines the header for the table of contents itself. Defaults to "Contents".

10. Shopping Cart Support - googlecart.m4 & paypalcart.m4

These macros set up the Google or PayPal shopping cart widget. The include file inserts essential pieces of code into the destination file, but requires a few things be set ahead of time:
  • CART_SANDBOX: Must be set to true or false depending on whether interacting with the sandbox/test system.
  • MERCHANT_ID: Must be set to the merchant ID Google assigns you, or the e-mail address associated with the PayPal merchant.
  • MERCHANT_KEY: Must be set to the merchant key Google assigns you. Not used for PayPal.

The Google package provides the following:

  • JavaScript to load the Google cart widget.
  • A note that indicates JavaScript is necessary if it is not available.
  • A note for browsers that don't work right with the cart widget, and a link to Devious Fish explaining the behaviors and alternatives available.

The PayPal package provides the following:

  • A "View Cart" button in the navigation menu and instructions for checking out.
_ADD_CART(title, price, shipping, description, image-file)
Creates a saleable item with the given title, price, description, image and shipping information. The shipping information is written as a fixed price (3.32), a fixed price plus each additional (4.99+3.25), a weight and units (3 lb), or some combination of the above separated by a slash (3 lb/3.32). Pounds (lb), ounces (oz), grams (g), and kilograms (kg) are supported. All units are translated to pounds and rounded up to the next tenth of a pound as necessary.

10.1. Shipping configuration - GoogleCart only

PayPal shipping is configured via the Web. Google shipping is done on a transaction basis, rather than being preconfigured. The following macros provide support for creating a shipping options block:
_SHIPPING_OPTION_BEGIN
Indicates the start of the shipping options block.
_SHIP_FLAT_RATE(carrier, service, cost)
Creates a shipping option with the given parameters.
_SHIP_CARRIER_CALCULATED(carrier, service, fallback-price)
Creates a shipping option with the given carrier and service type. This requires shipping weights be specified for all cart items. A _SHIP_FROM block must be included with the shipping options.
_SHIP_FROM(city, state/province, postal-code, country-code)
Specifies the shipping origin, necessary for carrier-calculated shipping costs.
_SHIP_RESTRICT_DESTINATION(+/- destination, +/- destination ...)
Specifies restrictions for the last-specified shipping scheme. A '+' allows a destination, whereas a '-' excludes a destination. The destination can be:
  • The keywords ALL (equivalent to US), CONTINENTAL_48, FULL_50_STATES. See cart API documentation for details.
  • A 2-digit state code.
  • The keyword POBOX to allow/deny sending to US Post Office Boxes.
  • A country name.
_SHIPPING_OPTION_END
Indicates the end of the shipping options block.

11. Explaining Acronyms - acronym.m4

In addition to the acronym-creating macro below, several useful computer-term macros are pre-defined by acronym.m4.

_ACRONYM(acronym [, expansion [, explanation ]])
Defines acronym as a macro which expands to the acronym name with a surrounding <ACRONYM> element. The first usage of the acronym includes expansion and explanation, but subsequent expansions only include expansion.

12. Filesystem interaction - stdio.m4

These macros provide some basic filesystem interaction.

FILESIZE(file)
Returns the size of file. For example, the source file to this document is 42798 bytes.
FILEDATE(file)
Returns the timestamp of file. For example, the source for this document is dated 2 Sep 10:33 . The result comes from the ls(1) command, so dates within the past 6 months come as dd Mon hh:mm, but older dates appear as dd Mon yyyy.
FILEEXIST(file)
Used to determine if file exists. This macro returns the words "yes" or "no". This call should be used with stdio_ok, not directly through m4_ifelse, when handling conditional actions.
stdio_ok(condition, positive action, negative action)
If condition is true, valuates positive action, otherwise evaluates negative action.
RANDOMFILE(pattern)
Randomly returns the name of an existing pattern matching pattern. pattern is expanded in the manner the shell does.

13. Image slideshows - slideshow.m4 and slideshow.js

These files provide an image slideshow.

_SLIDESHOW(width [, height [, aspect-ratio ]])
Creates the viewer. Images are located by searching the page for images created by _THUMBNAILS. The viewer may be above, below, or between thumbnail images.

The view has first, back, forward, last, and goto support. There is also an automated slideshow feature which changes slides automatically. The default maximum width and height are 450 and 450 respectively, and the aspect ratio is 1.6. Slideshow requires JavaScript be enabled on the client machine.

14. Random image banners - banner.m4 and banner.js

These files provide a random banner advertisement.

_BANNER(banner-directory, img-options, default-image)
Loads a banner advertisement. The banners must be in banner-directory during page build; the list of available banners is determined at compile-time. Banner requires JavaScript be enabled on the client machine; if it is not, default-image is displayed. img-options is added to the <IMG> tag of the banner; this can contain HEIGHT, WIDTH, or other <IMG> attributes.

15. Automatic index and site map pages - buildindex

buildindex(mode, -o output, -t timeframe)
Runs the indexer in one of many modes. By default, it will want to generate a table of contents from in a file index.web for the current directory.
Command line options for buildindex
Mode Mneumonic File Generates
  default index.web Table of contents of HTML files in current directory.
-d deltas delta.web List of files changed within 30 days (or other timeframe set by -t option) and, if available, detail of what those changes are.
-i index indexpage.web Index of those items marked with index tags.
-m map sitemap.web Site map in HTML.
-s site map sitemap.xml
sitemap.xml.gz
XML table of last modified dates readable by search engines.

15.1. Files used by buildindex

15.1.1. readtitle.m4

This package is used to extract titles from a web page. The output is used by buildindex(1) to generate an index.web or delta.web file. This provides a way to generate software-maintained index for a directory or recent change list for a hierarchy. For indexes, files are processed alphabetically by filename. For recent changes, files are processed by most-recent first. The title is determined from the _HEADER macro.

_HEADER_SRC
The name of the source file from which to extract the page title.

To begin using buildindex(1), you must run make buildindex, then make depend. This will set up the dependencies in the makefile to rebuild index.html when index.web is rebuilt.

There are two ways to rebuild index.web. The first is manual. When you want to make a new index, invoke make buildindex to generate the index.web file, then make to build the HTML.

The second way is to create a Makefile.local to force this to occur, like this:

index.web: .FORCE stddefs.m4
index.web:
        ${WEBBASE}/Include/buildindex
.FORCE:

For recent changes lists, replace index.html with delta.html and add the -d option to buildindex(1).

15.1.2. readindex.m4

This file is used by buildindex(1) when run with the -i (index) option to extract the index data from source documents and generate a site-wide index.

16. Makefiles

You can find these files in Include/Makefile.inc and Include/makemake. They work, but Makefiles are one of my weak spots and they could be written much better.

To set up the Makefiles: Set the environment variable WEBBASE to the base directory of your page development hierarchy. Then, while in that directory, invoke: Include/makemake. Finally, do a make alldepend. This will build makefiles for all lower directories.

You can create Make dependencies of your own in a directory by placing them in Makefile.local, then running make depend. This will update Makefile with an m4_include for Makefile.local.

The following make targets are defined:

all
This is the default target. It builds all pages in the current directory, but does not recurse into subdirectories.
build
This builds all pages in the current directory and recurses into subdirectories.
clean
This recursively removes all .html files from the current directory down.
depend
This rebuilds the dependencies for all .web files in the current directory.
builddepend
This builds dependencies from the current directory down.
alldepend
This rebuilds all dependencies starting at the web development base (NOT the current directory!).

17. The package

At present, I've been making some big changes and haven't repackaged. You can download the individual files from my FTP area.

17.1. Uploading

Use rsync(1), which can run over ssh with the -e option. If not available, try rdist(1). See the upload script for an example of rsync(1), which uploads 1 of 4 pages depending on a parameter.

17.2. Other files

makeinc
This generates a stddefs.m4 file in the current directory which m4_include()s html.m4 and sets a few paths to directories. The environment variable WEBBASE specifies the root of the paths generated, and defaults to ~/Web.
linkager
This script goes through a UNIX directory hierarchy, finding fIlEnAmEs and linking FILENAMES, Filenames, and filenames to it. Files are hard-linked (to prevent degrading of filesystem performance and wasting of hundreds of inodes) only if their name ends in .html, directories are symbolically linked always. This allows users to capitalize various likely ways, and still get to your pages. Adjust the #! line at the top of the script for ksh or bash as appropriate. It's good to run in your web server's "distribution area", but not your development area.
mkthumbnails
This script is used by _THUMBNAILS and related macros. This script determines image size, then calculates a new size which meets the maximum height and width specs while maintaining image proportions. If processing multiple files, it generates HTML to layout the thumbnails in an array and to make the thumbnails links to the full size images. ImageMagick's convert(1) is used to create the thumbnails.

18. Examples & Comments

You can find examples on this site by changing the .html extension to .web on any page to reveal the m4 source.

My suggestion is to make liberal use of macros. Don't feel afraid to define local macros with file scope for laying out several items in a list. If you decide to reformat the list, it is much easier to do if you just need to change a macro. In one case, I used macros to switch between a series of table layouts and definition lists— and if the client changes their mind, changing it again is a matter of modifying 3 macros. In this file you're reading now, I've got macros for constants, variables, macros, macro arguments, file names, and make targets. Macros used across several files should, of course, be defined in a new .m4 file which you m4_include().

If you have main body of a page that does not change, but a portion that changes regularly (like a "see also" section), you can use an include file for the "see also" section of the page. That way you can easily keep the basic page in source control, yet avoid polluting source control with frequent additions/deletions of related site links.

Diversions used

The following diagram shows the structure of documents generated with the m4 package, along with the m4 diversions used to implement it. The diversion numbers follow their symbolic names to indicate ordering, but names should always be used in divert commands as numeric values may change. The following diversions are defined in html.m4

<HTML>

<HEAD>

DIV_HEADER (0): start of the HTML header.

DIV_METATAGS (1): <META> elements and m4 package stylesheet inclusions.

DIV_LINKS (2): <LINK> elements and m4 package media-specific stylesheet inclusions.

DIV_STYLESHEET_SITE (3): Site stylesheet inclusions.

DIV_STYLESHEET_SITE_MEDIA (4): Site media-specific stylesheet inclusions.

DIV_STYLE (5): Inline document style definitions.

</HEAD>

<BODY>

DIV_BODY_BEGIN (6): Start of the document body.

DIV_PAGE_TITLE (7):

Page title

CSS: DIV.canvas

CSS: DIV#leftgutter

DIV_LEFT_GUTTER (11): The left gutter contents.

CSS: DIV#content

DIV_CONTENT_BEGIN (12): Used by navigation.m4 to support the navigation menu. Not used by the navigation bar.

DIV_INTRO (13): Introductory text that precedes the table of contents.

DIV_TOC (14): Table of contents.

  1. One
  2. Two
  3. Three

DIV_CONTENT (15):

The main body of the page.

DIV_LOWERCONTENT (16): Lower portion of the content pane.

CSS: DIV#rightgutter

DIV_RIGHT_GUTTER (17): The right gutter contents.

CSS: DIV#footer

DIV_CONTENTBOTTOM (18) Content that belongs at the bottom, below the navigation menu where it can use the full width— such as this very appendix.

DIV_FOOTNOTE (19): Footnotes. CSS: DIV#footnotes

DIV_FOOTER_BEGIN (20): Beginning of document footer (page URL, etc.). CSS: DIV#location contains the URL.

DIV_AFFILIATIONS (21): Affiliaton and associated page information. CSS: DIV#affiliations

DIV_COPYRIGHT (22): Copyright information for the page. CSS: DIV#copyright

DIV_REVISION_BEGIN (23): Formatting information for page revision data.

DIV_REVISION (24): Page revision information. CSS: DIV#revision

DIV_INVOKE (25) Contains snippets of JavaScript to invoke actions set up earlier in the page.

</BODY>

</HTML>

Footnotes: