Authoring with Expand

Starting a Library

The bare skeleton of an EXPAND library document looks like this:

  <html>
  <head>
  <meta http-equiv="Content-Script-Type" content="text/javascript">
  <script src="/path/to/expand.js"></script>
  </head>

  <body>

  <ul id="library">
   <li>expand MyMacroformat
    <div>
    . . . definition here . . .
    </div>
    <ins class=MyMacroformat> . . . </ins>
   </li>
   <li>expand AnotherMacroformat
    <div>
    . . . definition here . . .
    </div>
    . . . sample invocations here . . .
   </li>
  </ul>

  </body>
  </html>

It is an ordinary HTML document with a well-defined structure. It uses the EXPAND engine JavaScript library, and in its body is a UL element with an ID of id="library". Each list item represents a macroformat definition. The text of each list item must consist of the word "expand" and the name of the macroformat.

The remainder of the list item is a definition followed by at least one example invocation of it. The example invocation is mandatory because it supplies important information.

Macroformat Definitions

The body of an EXPAND macroformat definition is contained within the DIV element. Most of the content is expanded as-is. Within that body element though, any identifiers surrounded by underscores, such as _width_, will be replaced by parameters in each invocation. No matter where the identifier appears, it will be substituted.

If there is at least one example invocation, the first one is used to help define the expansion. It accomplishes two things:

When the definition is encountered, the processor parses the first sample invocation, finding all supplied parameters, both in attributes and in nested elements. It remembers the names and values for all future invocations.

All parameter values in the sample are treated as default values for future invocations. If no matching attribute or nested element is found in a call, the processor supplies the default value. If no explicit value was supplied in the sample, the default value will be an empty string. In future invocations, the processor only searches the macroformats attribute set for attributes supplied somewhere in the sample call. This significantly improves performance in some cases.

Example Macroformat Expander

Here is an example from the sample library. This defines a custom button with three GIF images as backgrounds. It produces a clickable button 25 pixels high, with any desired width. The label is HTML and can be styled.

 <li>expand Button1
  <div>
   <table cellpadding="0" cellspacing="0"
    onclick="_xx_ _onclick_" style="cursor: pointer; cursor: hand; _style_">
    <tr>
     <td><img src="../images/b1-left.gif" height="25" width="5"></td>
     <td style="padding: 0px 10px;" background="../images/b1-bg.gif">
      _body_
     </td>
     <td><img src="../images/b1-right.gif" height="25" width="4"></td>
    </tr>
   </table>
  </div>
  <ins class=Button1 style="" onclick="alert('Yippee!')"><b>Hit Me Baby!</b></ins>

This example builds a button using a table with an image for the left and right end caps and a background image for the center. It defines a special cursor when the mouse is over it, and allows you to define an onclick action.

The parameters are:

body
HTML for the body text. This should be short in this context, but can be styled.
style
Additional style for the button as a whole.
onclick
JavaScript for an onclick action.

The parameter _xx_ ensures that the onclick has embedded spaces. In some browsers the attribute cannot expand with embedded spaces if the attribute in the definition does not have an embedded space. This will expand into an empty string since it will not have a defined value.

The body parameter is special. If no value is explicitly supplied for it, it will receive the entire body of the invocation. That makes it easy to invoke it by HTML such as:

  <ins class=Button1 onclick="alert('Thank You')">Press Me!</ins>

The words Press Me! are assigned to body implicitly because it is the actual body of the tag. If body is given explicitly, the explicit value will be used.