7 Script Templates

This section covers the following topics:

7.1 About Script Templates

Script templates are the text-based conversion templates that were primarily used in earlier versions of Dynamic Converter. They are plain-text files that must be hand-coded with elements, indexes, macros, pragmas, and Idoc Script. You can still use this template format in Dynamic Converter, but Classic HTML Conversion templates (see Chapter 5, "HTML Conversion Templates") have, for the most part, replaced script templates.

Note:

See the Content Server developer documentation for more information on Idoc Script.

The following is the code for a very simple script template:

{## unit}{## header}
<html>
<body>
{## /header}
<p>Here is the document you requested.
{## insert element=property.title} by
{## insert element=property.author}</p>

<p>Below is the document itself</p>
{## insert element=body}

{## footer}
</body>
</html>
{## /footer}{## /unit}

The {## unit}, {## /unit}, {## header}, {## /header}, {## footer} and {## /footer} macros can be ignored for the moment. Their purpose is described in Macros.

The remainder of the file is regular HTML code with the exception of three macros in the form {## insert element=xxx}. Dynamic Converter uses this template plus the source file to create its output. To accomplish this, Dynamic Converter reads through the template file, writing it byte for byte to the output file unless character mapping is performed on the template. This continues until the template contains a properly formatted macro. Dynamic Converter reads the macro and executes the macro's command. Usually this means inserting an HTML version of some element from the source file into the output file. Dynamic Converter then continues reading the template and executing macros until the end of the template file is reached.

In the example above, the first {## insert} macro uses the element syntax (described in Insert Element: {## INSERT}) to insert the title of the document. The second macro inserts the author of the document and the third macro inserts the entire body of the document. The resulting HTML might look like this (HTML that is the result of a macro is in bold):

<html>
<body>
<p>Here is the document you requested.
A Poem by
Phil Boutros</p>

<p>Below is the document itself</p>
<p>Roses are red</p>
<p>Violets are blue</p>
<p>I'm a programmer</p>
<p>and so are you</p>

</body>
</html>

7.2 Elements

This section covers the following topics:

7.2.1 Element Tree

Dynamic Converter uses the concept of an element tree to make various pieces and attributes of the source file individually addressable from within a script template.

The nodes of the element tree are used to generate a path to a specific element, and a period is used to separate the nodes in this path. For example, the path of the author property of a document is Property.Author.

For convenience, certain nodes in an element path may be skipped because they represent the obvious default behavior. These nodes include the Sections node (Sections.Current.Body.Title is equivalent to Body.Title), and the Body and Contents nodes (Body.Contents.Headings.1.Body is equivalent to Headings.1.Body).

Important:

These nodes may not be skipped if they are the last node in the path (Heading.1.Body is not equivalent to Headings.1).

There are two types of elements in the element tree: leaf elements and repeatable elements (see "Leaf Elements" and "Repeatable Elements", respectively).

Figure 7-1 Example of an Element Tree

An example of an element tree

7.2.2 Leaf Elements

Leaf elements are single identifiable pieces of the source file like the author property (Property.Author) or the preface of the document (Body.Contents.Preface). This type of element is a valid target for inserting, testing and linking using the {## INSERT}, {## F} and {## LINK...} macros. The last node in this type of path must be a valid leaf node in the document tree. Valid leaf nodes are shown in italics in the element tree example in Element Tree.

7.2.3 Repeatable Elements

Repeatable elements have multiple instances associated with them, like the footnotes in a document (Sections.1.Footnotes). This type of element may not be directly inserted, tested or linked to but its instances may be looped through using the {## REPEAT} macro. The last node in this type of path must be a valid repeatable node in the document tree. Valid repeatable nodes are shown in bold in the element tree example in Element Tree.

Some templates use {## REPEAT} loops to generate one output file per repeatable element. For example, a template may render a presentation file as a group of output files, with one output file for each slide. When an input file contains an exceptionally large number of sections, it is possible for an operating system to run out of file handles. See your operating system's documentation or system administrator to find out how many open file handles are allowed. To avoid this extremely rare problem, set a value for the maxreps attribute of the {## REPEAT} macro or configure the operating system to allow more file handles.

7.2.4 Element Definitions

The following table contains a list of all supported elements and a brief description of each. (See "Indexes" for a description of valid values for x.)

Element Type Description
Property.Author Leaf Author property of the source file.
Property.Title Leaf Title property of the source file.
Property.Subject Leaf Subject property of the source file
Property.Keywords Leaf Keywords property of the source file.
Property.Comments Leaf Comments property of the source file.
Property.Others Repeatable This permits access to all properties not specifically accessible through property elements described above, and includes both the "Name" and the "Body" of the property. Which "Other" properties are supported is file format dependant. Some file formats also allow for additional user definable properties.

Only text properties are accessible. Properties such as Yes/No, numeric values, and dates are not supported.

Property.Others.x.Name Leaf Descriptive name for the property.
Property.Others.x.Body Leaf Text of the property.
Sheets Repeatable See 'Sections' below.
Slides Repeatable See 'Sections' below.
Sections Repeatable Sections are used to represent the highest level of abstraction within the source file. In general, word processor documents will have only one section, the document itself. Spreadsheets have one section for each sheet or chart. Presentations have one section for each slide. Graphics generally have one section but may have more, as in a multi-page TIFF.

For convenience and readability, Sheets and Slides are synonymous with Sections.

Sections.x.Body Leaf This element represents the main textual area of the source file.

For word processing documents, it includes the entire document excluding footnotes, endnotes, headers, footers, and annotations. (Footnote/endnote references are always included automatically in the body. If the template includes footnotes/endnotes, then these references provide a link to the note. Annotation references are not placed in the body unless the template includes annotations, in which case they provide links to the annotations.)

For spreadsheets, it includes the entire sheet.

For graphics, it includes any text that actually appears as text in the file format.

Sections.x.Body.Title Leaf For word processing documents, this element is the text marked with the title style. This may be different than the Property.Title. For all other types, this element will be the "name" of the section. For example, if the source file is a spreadsheet, this element will be the name of the sheet as it appears on the spreadsheet application's navigation tabs.
Sections.x.Body.Contents Leaf For word processing documents, this is the same as Sections.x.Body.

For all other document types, this is the same as the body minus the title, if a title exists.

Sections.x.Body.Contents. Preface Leaf Text between the top of the body and the first heading.
Sections.x.Body.Contents. Headings Repeatable Headings are labels in a word processor document inserted by the author to give a document structure. See "Breaking Documents by Structure" for more information on headings. Dynamic Converter reads this structure and, through the use of the Headings element, allows you to access it.
Sections.x.Body.Contents. Headings.x.Body. Leaf with Leaves and Repeatables below Under each heading, the structure of a complete document from Body down is repeated. See "Breaking Documents by Structure" for a clearer picture of how these elements map to parts of a document.
Sections.x.Body.Contents. Headings.x.Footnotes Repeatable with Leaves below Only footnotes contained in this heading.
Sections.x.Body.Contents. Headings.x.Endnotes Repeatable with Leaves below Only endnotes contained in this heading.
Sections.x.Body.Contents. Headings.x.Annotations Repeatable with Leaves below Only annotations contained in this heading.
Sections.x.Grids Repeatable Only valid for spreadsheet and database formats. This permits access to the "grids" inside a section or sheet of a spreadsheet or database file.
Sections.x.Grids.x.Body Repeatable Only valid for spreadsheet and database formats. This permits access to the "grids" inside a section or sheet of a spreadsheet or database file.
Sections.x.Image Leaf This element represents a graphic image of the content of the section. It is valid only for bitmap, drawing, chart and presentation sections.
Sections.x.BodyOrImage Leaf This element exists to make it easy to build templates that handle a range of section types. In word processing documents, spreadsheets and database sections, BodyOrImage is synonymous with Body. In bitmap, drawing, chart and presentation sections, BodyOrImage is synonymous with Image.
Sections.x.Title Leaf Same as Sections.x.Body.Title. For word processing documents, this element is the text marked with the title style. This may be different than the Property.Title. For all other types, this element will be the "name" of the section. For example, if the source file is a spreadsheet, this element will be the name of the sheet as it appears on the spreadsheet application's navigation tabs.
Sections.x.Type Leaf This element exists only for query purposes. It is valid only at the ELEMENT of a {## IF...} macro.

This element is normally used only for query purposes, but it may be inserted as well. See "Conditional: {## IF...}, {## ELSEIF...}, and {## ELSE}" for further details on how to use this in an {## IF} macro.

Sections.x.Footnotes Repeatable All footnotes.
Sections.x.Footnotes.x.Body Leaf The complete footnote reference and content text.
Sections.x.Footnotes.x. Reference Leaf The reference number for the footnote.
Sections.x.Footnotes.x. Content Leaf The content text for the footnote.
Sections.x.Footnotes Repeatable All footnotes.
Sections.x.Endnotes.x.Body Repeatable with Leaves below The complete endnote reference and content text.
Sections.x.Endnotes.x. Reference Repeatable with Leaves below The reference number for the endnote.
Sections.x.Endnotes.x. Content Repeatable with Leaves below The content text for the endnote.
Sections.x.Annotations Repeatable All annotations.
Sections.x.Annotations.x. Body Leaf The complete annotation reference and content text.
Sections.x.Annotations.x. Reference Leaf The reference text for the annotation.
Sections.x.Annotations.x. Content Leaf The content text for the annotation.
Sections.x.Slidenotes Repeatable All slide notes.

Please note that converting the slide notes will slow down the conversion process for PowerPoint files.

Sections.x.Slidenotes.x.Body Leaf The notes for the current slide.

It is recommended that you write slide notes at the end of the output file for performance reasons (PowerPoint files keep slide notes at the end of the file, not next to each slide). Not doing so will slow conversion, as the technology will be forced to perform excessive seeking in the input file.

Sections.x.Headers Repeatable All headers.
Sections.x.Headers.x.Body Leaf Text of the header.
Sections.x.Footers Repeatable All footers.
Sections.x.Footers.x.Body Leaf Text of the footer.
Pragma.Charset Leaf The HTML text string associated with the character set of the characters that Dynamic Converter is generating. In order for Dynamic Converter to correctly code the character set into the HTML it generates, all templates should include a META tag that uses the {## INSERT} macro as follows.

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset={## INSERT ELEMENT=pragma.charset}">

If the template does not include this line, the user will have to manually select the correct character set in their browser.

Pragma.SourceFileName Leaf The name of the source document being converted. Note that this does NOT include the path name.
Pragma.CSSFile Leaf This element is used to insert the name of the Cascading Style Sheet (CSS) file into HTML documents. This name is typically used in conjunction with an HTML <LINK> tag to reference styles contained in the CSS file generated by Dynamic Converter.

When used with the {## INSERT} macro, this pragma will generate the URL of the CSS file that is created. This macro must be used with {## INSERT} inside every template file that inserts contents of the source file and when the selected HTML flavor supports CSS. The CSS file will only be created if the selected HTML flavor supports CSS.

When used with the {## IF} macro, the conditional will be true if the selected HTML flavor supports Cascading Style Sheets or not.

If CSS is required for the output, {## IF element=pragma.embeddedcss} or {## IF element=pragma.cssfile} must be used. However, Dynamic Converter does not differentiate between the two, as the choice of using embedded CSS vs. external CSS is your decision and you may even wish to mix the two in the output.

An example of how to use this pragma that works when exporting either CSS or non-CSS flavors of HTML would be as follows:

{## IF ELEMENT=Pragma.CSSFile}
    <LINK REL=STYLESHEET
   HREF="{## INSERT
   ELEMENT=Pragma.CSSFile}">
    </LINK>
{## /IF}
Pragma.EmbeddedCSS Leaf This element is used to insert CSS style definitions in a single block in the <HEAD> of the document.

When used with the {## INSERT} macro, this pragma will insert the block of CSS style definitions needed for use later in the file. This macro must be used inside every output HTML file where {## INSERT} is used to insert document content.

When used with the {## IF} macro, the conditional will be true if the selected HTML flavor supports CSS.

If CSS is required for the output, {## IF element=pragma.embeddedcss} or {## IF element=pragma.cssfile} must be used. However, Dynamic Converter does not differentiate between the two, as the choice of using embedded CSS vs. external CSS is your decision and you may even wish to mix the two in the output.

If a style is used anywhere in the input document, that style will show up in the embedded CSS generated for all the output HTML files generated for the input file. Consider a template that splits its output into multiple HTML files. In this example, the input file contains the "MyStyle" style. It does not matter if during the conversion only one output HTML file actually references the "MyStyle" style. The "MyStyle" style definition will still show up in the embedded CSS for all the output files, including those files that never reference this style.

Pragma.JsFile Leaf This element is used to insert the name of the JavaScript file into HTML documents. This name is typically used in conjunction with an HTML <SCRIPT> tag to reference JavaScript contained in the .js file generated by HTML Export.

When used with the {## INSERT} macro, this pragma will generate the URL of the JavaScript file that is created. This macro must be used with {## NSERT} inside every template file that inserts contents of the source file when:

  • The selected HTML flavor supports JavaScript.

  • The javaScriptTabs option has been set to true.

The JavaScript file will only be created if the selected HTML flavor supports JavaScript.

When used with the {## IF} macro, the conditional will depend upon whether the selected HTML flavor supports JavaScript or not.


7.3 Indexes

Repeatable nodes have an associated index variable that has a current value at any given time in the export process. For elements that contain repeatable nodes as part of their paths, the instance of the repeatable element must be specified by using a number or one of the index variable keywords.

This section covers the following topics:

7.3.1 Index Variable Keywords

The possible values for this index (referred to as 'x' in element definitions (see "Element Definitions") are as follows:

7.3.1.1 Whole Number

For numeric values, the number is simply inserted as another node in the path.

Note:

Dynamic Converter indexes begin counting with 1 (not 0).

For example, Slides.1.Image references the first slide in a presentation and Footnotes.2.Body references the second footnote in a document.

If it cannot be guaranteed that elements are within the document which the template is applied on, they should not be explicitly referenced. For example, referencing Sections.4.Body may result in unexpected behavior in documents that have fewer than four sections.

Requesting a non-existent element will not cause an error in Dynamic Converter. The insertion will just be ignored. However, if other HTML surrounding the insertion depends on the results of the insert, the output may be invalid HTML.

7.3.1.2 Current, Next, Previous, First, and Last

The 'current', 'next', 'previous', 'first', and 'last' keywords are fairly self-explanatory. When the script template is processed, these variables are replaced with the appropriate index value. For example, Slides.Current.Image references the current slide and Slides.Next.Image refers to the next slide.

'Next' and 'previous' do not change the value of the index, as was the case in earlier versions of Dynamic Converter. As a result, the only places where the index is changed are inside of a {## REPEAT} loop and as the result of a {## LINK} statement.

{## REPEAT…}

The initial value of the index variable for any given repeatable element typically is 1. For {## REPEAT} loops, the index is incremented with each iteration. Termination of a {## REPEAT} loop resets the counter to its initial value. Actually, it is more accurate to say that the scope of the index is the repeat loop.

The following template fragment uses current in a repeat loop, which outputs all the footnotes in the source file:

{## REPEAT element=footnotes}
{## INSERT element=footnotes.current.body}
{## /REPEAT}

When a template containing a repeat statement is the target of a {## link} statement that specifies the element to be used as the repeat element, the initial value of the index will be determined by the {## LINK} processing.

{## LINK…}

The {## LINK} statement does not affect the index variable in the context of the current template. The {## LINK} statement can only affect index variables when both an element and a template are specified. In this case only the index variables in the target for the specified element are affected.

If the element specified in the {## LINK} contains a next or previous keyword, the value of current in the target file will be affected. The initial value of current in the target will be the value of (current in the source)+1 for next. Similarly, previous has the effect of decrementing the value of current.

The following example uses a single template file and the {## link} macro to create a set of HTML files, one for each slide in a presentation. The {## link} does the dual job of driving the generation of the HTML files and providing a "next" link for navigation. Notice the use of the next keyword in the {## if} macro that checks to see if there is a next slide:

{## unit}
<html>
<body>
<!-- insert the current slide -->
{## insert element=slides.current.image width=300}
<hr />
<!-- Is there a next slide? -->
{## if element=slides.next.image}
    <!-- If yes, generate a URL to an HTML file containing
        the next slide. The HTML file is generated using
        the current template (because there is no template
        attribute). While generating the new HTML file, the
        value of the index on slides will be its current
        value plus 1 once control returns to this template,
        the value of the index on slides is unchanged. -->
   <p><a href="{## link element=
   slides.next.image}">Next</a></p>
{## else}
    <!-- If no, create a link to the HTML containing the
        first slide. -->
    <p><a href="{## link element=
    slides.1.image}">First</a></p>
{## /if}
</body>
</html>
{## /unit}

7.3.1.3 Up, Down, Left, and Right

In addition to the Current, Next, Previous, First, and Last index variable keywords, repeatable grid elements have four additional keywords:

  • Up

  • Down

  • Left

  • Right

These keywords may only appear immediately after the Grids node in the document tree. For example, Grids.Up.Body is legal, but Sections.Left.Grids.1.Body is not. Use of these keywords is otherwise self-explanatory.

Note, too, that individual grids are only addressable relative to each other. In other words, while it is possible to specify the "up" grid, it is not possible to arbitrarily specify a grid directly (i.e., "5, 7").

7.3.2 Creating a Set of HTML Files for Each Slide in a Presentation

The following example uses a single script template file and the {## LINK...} macro to create a set of HTML files, one for each slide in a presentation. The {## LINK...} does the dual job of driving the generation of the HTML files and providing a "next" link for navigation. Notice the use of the Next keyword in the {## IF...} macro that checks to see if there is a next slide.

<html>
<body>
<!-- Insert the current slide -->
{## INSERT ELEMENT=Slides.Current.Image WIDTH=300}
<hr />
<!-- Is there a next slide? -->
{## IF ELEMENT=Slides.Next.Image}
<!-- If yes, generate a URL to an HTML file containing the next slide. The HTML file is generated using the current template (because there is no TEMPLATE attribute). While generating the new HTML file, the value of the index on Slides is its current value plus 1 once control returns to this template, the value of the index on Slides is unchanged. -->
<p><a href="{## LINK ELEMENT=Slides.Next.Image}">Next</a></p>
{## ELSE}
<!-- If no, create a link to the HTML containing the first slide. -->
<p><a href="{## LINK ELEMENT=Slides.1.Image}">First</a></p>
{## /IF}
</body>
</html>

7.4 Macros

This section covers the following topics:

7.4.1 About Macros

Macros are commands to Dynamic Converter within script templates. Despite their casual similarity to HTML tags, they are not bound by any of the rules that tags would usually follow inside an HTML file. Macros may appear anywhere in the script template file, except inside another macro.

In the documentation and examples, the pieces of a macro are always shown delimited by spaces. However, semicolons may also delimit them. This option was added to accommodate certain HTML editors. In certain editors, URLs entered into dialog boxes may not have non-quoted spaces. This made it difficult or impossible to use the {## LINK} macro in these situations.

For example, {## INSERT ELEMENT=Sections.1.Body} may also be written as {##;INSERT;ELEMENT=Sections.1.Body}.

Note that template macro string parameters and options support sprintf style escaped characters. This means that characters such as \x22, \r and %% are supported. Also note that most template attribute values may be quoted. The exception is template element strings, which may not be quoted at this time.

For example:

{## ANCHOR aref="next" format="<a href=\"%url\">Next</a><br/>\r\n"}

7.4.2 Units: {## UNIT}, {## HEADER}, and {## FOOTER}

If a template file is going to make use of the {## UNIT} macro at all, this macro must be the first macro in the template file. It delimits the beginning and end of each unit. Unit boundaries are used when determining where to break the document when breaking based on content size (see "Breaking Documents by Content Size").

A unit consists of a header, a footer (both of which are optional), and a body (which may be empty). To ensure that the header is the first item in the template and the footer is the last item, text between the {## UNIT} tag and the {## HEADER} tag will be ignored, as will text between the {## /FOOTER} tag and the {## /UNIT} tag, including whitespace. The header and footer of a unit will be output in every page containing that unit, enclosing that portion of the unit's body that is able to fit in a particular page. The entire template is a unit that may contain additional units.

Syntax

{## UNIT [BREAK]}
    [{## HEADER}
        any HTML
     {## /HEADER}]

        any HTML

    [{## FOOTER}
        any HTML
    {## /FOOTER}]
{## /UNIT}
Attributes
BREAK
Attribute Description
BREAK This optional attribute forces a page break before inserting the unit contents unless doing so would cause the body of the first page to be empty. One situation where this attribute would be useful would be to force a page break between each section of a document, perhaps to get one presentation slide per page.

The {## UNIT} macro and its BREAK attribute are ignored when SCCOPT_EX_PAGESIZEpagesize is set to zero.

It is sometimes important to make sure that a break does not occur in the midst of text that is intended to be on the same page. To prevent breaks like this from occurring, enclose the text that should be kept on the same page inside a nested {## UNIT}{## HEADER} pair. For example, to prevent a page break from occurring while a link is being created, the template author might write something like the following:

{## unit}{## header}
<a href="{## link element=sections.current.body}">Link</a>
{## /header}{## /unit}

7.4.3 Insert Element: {## INSERT}

This macro inserts an element of the source file into the output file at the current location.

Syntax

{## INSERT [ELEMENT=element [WIDTH=width] [HEIGHT=height] [SUPPRESS=suppress] [TRUNCATE=truncate]] | [NUMBER=number] [URLENCODE]}
Attribute Description
ELEMENT This attribute describes which part of the source file should be placed in the output file at the location of the macro. See "Element Definitions" for the possible values for this attribute. If the value of this attribute is not in the element tree, Dynamic Converter considers it to be a custom element and the EX_CALLBACK_ID_PROCESSELEMENTSTR callback is called.

Example: {## INSERT ELEMENT=Sections.1.Body}

WIDTH This optional attribute defines the width in pixels of the element being inserted. It is currently only valid for the Image element. If the WIDTH attribute is not present but the HEIGHT attribute is, the width of the image is calculated automatically based on the shape of the element. If neither the WIDTH and HEIGHT attributes are present, the image's original dimensions are used. If the image's original dimensions are unknown, the defaults assume a HEIGHT and WIDTH of 200.

Example: {## INSERT ELEMENT=Slides.1.Image WIDTH=400}

HEIGHT This optional attribute defines the height in pixels of the element being inserted. It is currently only valid for the Image element. If the HEIGHT attribute is not present, but the WIDTH attribute is, the height of the image is calculated automatically based on the shape of the element.

Example: {## INSERT ELEMENT=Slides.1.Image HEIGHT=400}

SUPPRESS This optional attribute allows certain things to be suppressed from the output. This is very useful if elements need to be inserted in contexts where HTML is not appropriate, such as passing information to Java applets, ActiveX controls, or populating parts of a form. Possible values are as follows:

TAGS: All HTML tags are suppressed from the output of the element, however the text may still contain HTML character codes like &quot; or &#123;

For non-embedded graphics such as presentations and graphic files, the URL of the converted graphic will not be suppressed. The <img> tag that would normally surround the URL is suppressed, however.

For embedded graphics such as those found in word processing sections and spread sheets, both the URL and the <IMG> tag are suppressed. Since there would be no way to access the resulting converted embedded graphic, conversion of the graphic is not done.

Example:

<form method="POST">
<input type="text" size="20" name="Author"
value="{## INSERT ELEMENT=Property.Author SUPPRESS=TAGS}">
</form>

BOOKMARKS: Turns off all bookmarks in the inserted section. Bookmarks automatically precede many inserted elements so that other template elements may link to them. SUPPRESS=BOOKMARKS is provided to prevent problems with nested <a> tags. Note that this represents a subset of the suppression behavior provided by SUPPRESS=TAGS.

INVALIDXMLTAGCHARS: Drops from the output all characters that are not allowed in XML tag names. This is designed to allow template authors to {## INSERT} custom document property names inside angle brackets ("<" and ">") to create XML tags. Most characters in Unicode and its subset character sets may be used as part of XML tag names. Illegal tag characters include "control" characters such as line feed and carriage return. In addition there are special rules for what characters can be the first character in a tag name.

Example:

{## REPEAT Sections.Property.Others}
<{## INSERT ELEMENT=Property.Others.Current.Name SUPPRESS=InvalidXMLTagChars}>
<{## INSERT ELEMENT=Property.Others.Current.Body SUPPRESS=InvalidXMLTagChars}>
</{## INSERT ELEMENT=Property.Others.Current.Name
SUPPRESS=InvalidXMLTagChars}>
{/## REPEAT}

produces something similar to the following:

<MyProperty>PropertyValue</MyProperty>

TRUNCATE When set, this attribute forces a maximum length in characters for the inserted element. This allows elements to be truncated rather than broken across pages when the page size option is in use. Truncated elements will end with the truncation identifier which is "…" (three periods). All elements that have a truncate value will be no more than the specified number of characters in length including the length of the truncation identifier. In Dynamic Converter, elements are inserted in their entirety if no truncation size is specified. The value of this attribute must be greater than or equal to five characters.

An example of a situation where element truncation is useful is to limit the size of entries when building a table of contents.

The TRUNCATE attribute implies suppression of tags for the insert. It also auto applies the no source formatting option for the insert.

Note that the TRUNCATE attribute cannot be used with custom elements, because the custom element definition precludes the existence of any other attributes to {## INSERT}.

The TRUNCATE attribute has three special aspects to its behavior when grids are being inserted:

When truncation is in effect, the truncation size refers to the number of characters of content in each cell, not the number of characters in the grid as a whole.

While truncation normally causes all markup tags to be suppressed, when grids are in use, the table tags are retained (assuming that the output flavor supports tables).

Users are reminded that only one grid size may be selected for each spreadsheet sheet or database inserted. The size of the grid will be based in part on the TRUNCATE value if one or both the grid dimensions are not specified and the SCCOPT_EX_PAGESIZE option is in use. In this situation, if a grid from a single sheet is inserted in more than one place in the template, and there are differing TRUNCATE values, then the grid dimensions will be based on the largest TRUNCATE value specified.

NUMBER This attribute allows the developer to retrieve the total instance count or the current index value of any repeatable element. This can be very useful for writing JavaScript, BasicScript, etc. Two special keywords do not appear in the element tree but can be used as nodes in the following special case.

Count and CountB0: When appended to a repeating element and used with the NUMBER attribute, these nodes allow the developer to insert a text representation of the number of instances of the given repeatable element. Count gives the count assuming the first index is 1 and CountB0 gives it assuming the first index is 0.

Example: If a presentation has three slides, the template fragment,

<P>{## INSERT NUMBER=Slides.Count}
<P>{## INSERT NUMBER=Slides.CountB0}

produces the following text:

<P>3
<P>2

Value and ValueB0: When appended to a repeating element and used with the NUMBER attribute, these nodes allow the developer to insert a text representation of the current value of the index of the given repeatable element. Value gives the count assuming the first index is 1 and ValueB0 gives it assuming the first index is 0.

Example: If the current value of the index on Slides is 2, the template fragment,

<P>{## INSERT NUMBER=Slides.Current.Value}
<P>{## INSERT NUMBER=Slides.Current.ValueB0}

Produces the following text:

<P>2
<P>1
URLENCODE This optional attribute causes the inserted element to be URL encoded. As such, it is ignored unless it is specified as part of an insert that contains a file name. The following elements may be URL encoded:
  • pragma.sourcefilename

  • pragma.cssfile

  • pragma.embeddedcss

  • pragma.jsfile

In addition, the following elements will be URL encoded when the section type is "Archive" or "AR":

  • sections.x.fullname

  • sections.x.basename

  • sections.x.body

  • sections.x.title

  • sections.x.reflink

For all other {## INSERT} tags, this attribute is ignored. As such, you should note that Dynamic Converter does not modify any URLs coming out of the input documents being converted. These URLs continue to be passed through as is. This attribute is also ignored if the URL was created using the EX_CALLBACK_ID_CREATENEWFILE callback. Such URLs are assumed to already be URL-encoded.


Inserting Properties

Because of the special ways that properties are used in documents, property strings are inserted into the output HTML a little differently than the way other {## INSERT} macros work.

The property is always inserted as if the SCCOPT_NO_SOURCEFORMATTING option were set. This prevents formatting characters such as new lines from interfering with the property strings.

The property is always inserted as if the script template specified Suppress=Tags. This provides you with maximum control over how property strings are presented.

7.4.4 Conditional: {## IF...}, {## ELSEIF...}, and {## ELSE}

This macro allows an area of the script template to be used based on information about an element of the source file.

Syntax

{## IF ELEMENT=element [CONDITION=Exists|NotExists]
[VALUE=value]}
    any HTML
{## /IF}

or

{## IF ELEMENT=element [[CONDITION=Exists|NotExists] |
[VALUE=value]]}
    any HTML
{## ELSE}
    any HTML
{## /IF}

or

{## IF ELEMENT=element [[CONDITION=Exists|NotExists] |
[VALUE=value]]}
    any HTML
{## ELSEIF ELEMENT=element [[CONDITION=Exists|NotExists] |
[VALUE=value]]}}
    any HTML
{## ELSE}
    any HTML
{## /IF}

Note:

Multiple {## ELSEIF} statements may be used after {## IF}. In addition, {## ELSE} is not required when using {## ELSEIF}.
Attribute Description
ELEMENT This attribute describes which part of the source file should be tested. See "Element Definitions" for the possible values for this attribute. If neither the CONDITION nor VALUE attribute exists, the element is tested for existence.
CONDITION Defines the condition the element is tested for, possible values are EXISTS and NOTEXISTS.
VALUE Defines the values the element should be tested against. The VALUE attribute is currently valid only for the Sections.x.Type element for testing of the type of a section of the source file.

Possible values include:

  • ar = archive

  • bm = bitmap

  • ch = chart

  • db = database

  • dr = drawing

  • mm = multimedia

  • pr = presentation

  • ss = spreadsheet

  • wp = word processing document

Examples:

{## if element=property.comment}
  <p><b>Comment property exists</b></p>
{## else}
  <p><i>Comment property does not exist</i></p>
{## /if}
{## if element=sections.1.type value=wp}
  <p><b>The source file is a word processor file</b></p>
{## /if}
{## if element=sections.1.type value=ss}
  <p>Spreadsheet</p>
{## elseif element=sections.1.type value=ar}
  <p>Archive</p>
{## elseif element=sections.1.type value=ch}
  <p>Chart</p>
{## else}
  <p>Not ss, ar, or ch</p>
{## /if}
{## if element=sections.current.type value=pr
    condition=notexists}
    <p>We can do something here for all document types
    other than presentations.</p>
{## else}
  <p>This is used only for presentations.</p>
{## /if}

7.4.5 Loop: {## REPEAT}

This command allows an area of the script template to be repeated, once for each occurrence of an element.

Syntax

{## REPEAT ELEMENT=element [MAXREPS=maxreps] [SORT=sort]}
    any HTML
{## /REPEAT}
Attribute Description
ELEMENT This attribute describes what part of the source file should be repeated on. It must be a repeatable element. See "Element Definitions" for the possible values for this attribute.

Any HTML may be defined between the {## REPEAT... } macro and its closing {## /REPEAT} macro. This HTML is repeated once for each instance for the element specified. In addition, the word Current may be used in any other {##} tag as the element-index of the element being repeated. For instance, the following HTML in the template will produce a list of the footnotes in the document.

Example:

<HTML>
<BODY>
<P>Here are the footnotes
{## REPEAT ELEMENT=Footnotes}
<P>{## INSERT ELEMENT=Footnotes.Current.Body}
{## /REP}
<P>No more footnotes
</BODY>
</HTML>

Similarly, the following HTML in the template will insert the names of all the items in an archive:

{## repeat element=sections}
  {## insert element=sections.current.fullname}
{## /repeat}
MAXREPS This attribute limits the total number of loops the repeat statement may make to the value specified. It is useful for preventing exceptionally large documents from producing an unwieldy amount of output.
SORT This optional attribute defines whether to sort the output or not. This attribute is ignored if the input file is not an archive file of arctype file. All sorts are done based on the character encoding of the values in the input file. The sorts are also case insensitive at this time. Valid values of the sort attribute are:
  • fullname: sort by Sections.Current.FullName

  • basename: sort by Sections.Current.BaseName

  • none: no sorting is done. This is the default.


7.4.6 Linking With Structured Breaking: {## LINK}

This macro generates a relative URL to a piece of the document produced by Dynamic Converter. Normally this URL would then be encapsulated by the template with HTML anchor tags to create a link. {## LINK} is particularly powerful when used within a {## REPEAT} loop.

Syntax

{## LINK ELEMENT=element [TOP]}

or

{## LINK TEMPLATE=template}

or

{## LINK ELEMENT=element TEMPLATE=template [TOP]}
Attribute Description
ELEMENT Defines the element that is the target for the link. The URL that the {## LINK...} macro generates will point to the first instance of this element in the output file. If this attribute is not present, the resulting URL will link to any output file that was produced with the specified script template. If such a file does not exist, the specified script template is used to generate a file.

Remember that each element has one or more index values, some of which may be variables. An example of this type of index variable is the "current" in Sections.Current.Body. Use of {## LINK} affects the value of those index variables, which may cause subtle side effects in the behavior of the linked template file.

For a description of how {## LINK} affects the index of inserted elements more information, see "Indexes".

TEMPLATE The name of a template file which must exist in the same directory as the original template file. If this attribute is not present, the current template will be used. If an element was specified in the {## LINK}, then the template must contain a {## INSERT} statement using that element.

It is important to note that while the template language is normally case-insensitive, the case of the template file names specified here is important. The file name specified for the template is passed as is to the operating system. On operating systems such as UNIX, if the wrong case is given for the template file name, the template file will not be found and an error will be returned.

TOP This attribute is only meaningful if an element is specified in the {## LINK} command. When this attribute exists, the generated URL will not contain a bookmark, and therefore the resulting link will always jump to the top of the HTML file containing the specified element. This is useful if the top of the script template has navigation or other information that the developer would like the user to see.

7.4.6.1 {## LINK} Usage Scenarios

Using the first syntax shown at the beginning of this section, a URL for the element bookmark is inserted in the document. Normally this syntax is used to create intradocument links to aid navigation. An example would be creating a link to the next section of the document.

In the second syntax, a URL is created to an output file generated by the specified template. This template is run on the same source document, but may extract different parts of the document. Normally, in this syntax, the "main" template contains a link to a second HTML file. This second file is generated using the template specified by the {## LINK} command and contains other document elements. As an example, the "main" template could produce a file containing the body of the document and a link to the second HTML file, which contains the footnotes and endnotes.

The third and most powerful syntax also produces the URL of a file generated by the specified template. This template is then expected to contain an insertion of the specified element. Normally this syntax is used with repeatable elements. It allows the author to generate multiple output files with sequential pieces of the document. As such it provides a way to break large documents up into smaller, more readable pieces. An example of where this syntax would be used is a template that generates a "table of contents" in one HTML file (perhaps a separate HTML frame). The entries in the table are then links to other HTML files generated by different templates.

Note that a {## LINK} statement which specifies a template does not always result in a new file being created. New files are only created if the target of the link does not exist yet. So if for example two {## LINK} statements specify the same element and template, only one HTML file is produced and the same URL will be used by both {## LINK} statements.

7.4.6.2 {## LINK} Archive File Example

The following template generates a list of links to all the extracted and converted files from the source archive file (represented by decompressedFile in the following example):

{## repeat element=sections}
   <p><a href="{## link element=sections.current.decompressedFile}">
   {## insert Element=sections.current.fullname}</a></p>
{## /repeat}

7.4.6.3 {## LINK} Presentation File Example

The following example (template.htm) uses the first syntax to generate a set of HTML files, one for each slide in a presentation. Each slide will include links to the previous and next slides and the first slide. Note the use of {## IF} macros so the first and last slides do not have Previous and Next links respectively:

template.htm
    <html>
    <body>
    {## insert element=slides.current.image width=300}
    <hr />
    {## if element=slides.previous.image}
       <p><a href={## link element=slides.previous.image}>
    previous</a></p>
    {## /if}
    {## if element=slides.next.image}
       <p><a href={## link element=
       slides.next.image}>Next</a></p>
    {## /if}
    </body>
    </html>

Due to the side effects of {## LINK} using the element attribute, there can be some confusion over what values "current," "previous" and "next" have when each {## LINK} is processed. To better illustrate how this template works, consider running it on a presentation that contains three slides:

First Output File

Since no template is specified in the {## LINK} statements, template.htm is (re)used as the template for all {## LINK} statements. For the first slide, nothing interesting happens until slides.next is encountered. Since slides.current is 1 in this case, slides.next refers to slides.2 and the {## LINK} is performed on slides.2.image. This {## LINK} fills in the anchor tag with the URL for the output file containing the second slide. Since no file containing slides.2 exists, {## LINK} opens a new file.

Second Output File

For the second slide the template is rerun. slides.current now refers to slides.2, slides.previous refers to slides.1 and slides.next refers to slides.3. The {## INSERT} statement will insert the second slide.

The {## IF} statement referring to slides.previous succeeds. Since the file containing slides.1 already exists, no additional file is created. The anchor tag will be filled in with the URL for the first output file.

The {## IF} statement referring to slides.next also succeeds and the anchor tag will be filled in with the URL for the output file containing the third slide. Since no file containing slides.3 exists, {## LINK} opens a new file.

Third Output File

For the third slide the template is rerun. slides.current now refers to slides.3 and slides.previous refers to slides.2. slides.next refers to slides.4, which does not exist. The {## INSERT} statement will insert the third slide.

The {## IF} statement referring to slides.previous succeeds. Since the file containing slides.2 already exists, no additional file is created. The anchor tag will be filled in with the URL for the second output file.

The {## IF} statement referring to slides.next fails. At this point processing is essentially complete.

7.4.7 Linking With Content Size Breaking: {## ANCHOR}

This macro generates a relative URL to a piece of the document produced by Dynamic Converter when doing document breaking based on content size.

Syntax

{## ANCHOR AREF=type [STEP=stepval] FORMAT="anchorfmt" [ALTLINK="element"] [ALTTEXT="text"]}
Attribute Description
AREF Indicates the relation of the target of the link to the current file. Allowable values for this attribute are:
  • nsertStart: links to first page of the inserted element

  • InsertEnd: links to last page of the inserted element

  • Next: links to next page in the inserted element

  • Prev: links to previous page in the inserted element

  • FirstFile: links to first page created for the entire document

  • LastFile: links to last page created for the entire document

STEP This attribute is used to insert a link to "fast forward/rewind" through the output pages. This attribute may only be used if AREF is "next" or "prev." It is specified as a non-zero positive integer. For example, to insert a link to skip ahead five pages in a document, the following statement could be used:
{## unit aref="next" step="5" format="<p><a href=\"%url\">Next</a></p>"}

If not specified, the default value of the STEP attribute is one (1), which corresponds to the next/previous page. This attribute has no meaning when aref equals "insertstart," "insertend," "firstfile," or "lastfile."

FORMAT This is an sprintf style format string specifying the text to output as the link. Dynamic Converter replaces the %url format specifier with the target URL into the format string. For example:
{## anchor aref="next" format="<a href=\"%url\">Next</a><br/>\r\n"}
ALTLINK An attribute used to specify the target of the anchor if it cannot be resolved based on the anchor type. For example, the final file of a breakable element has no "next" file, and thus would resolve to nothing. However, if the altlink attribute is specified, the anchor will be generated using a URL to the first file found containing the specified element.

Note that no EX_CALLBACK_ID_ALTLINK callback will be made if an EX_CALLBACK_ID_ALTLINK attribute is specified in the {## ANCHOR} statement.

For example:

{## anchor aref=next format="<a href=\"%url\">Next</a>" altlink=headings.next.body}
ALTTEXT Text to be output if the anchor cannot be resolved. If this attribute is not specified, no text will be output if the anchor target does not exist. For example:

{## anchor aref=next format="<a href=\"%url\">Next</a>" alttext="Next"}


7.4.8 Comment Put in the Output File: {## IGNORE}

This macro causes {##} statements in an area of the template file to be ignored by the template parser. Any text between the {## IGNORE} and {## /IGNORE} tags will be written to the output file as-is. This macro allows {##} statements in an area of the template to be commented out for debugging purposes, or to actually write out the text of another {##} macro. However, the browser will parse any HTML tags inside the ignored block and the text will be formatted accordingly. This macro can ignore all {##} macros except for an {## /IGNORE} macro. No escape sequence has been implemented for this purpose. As a result, {## IGNORE} statements cannot be nested. If they are nested, a run time template parser error will occur.

Syntax

{## IGNORE}
    any HTML or other {##} macros
{## /IGNORE}

Note:

To fully comment out a section of the script template, surround the ## IGNORE statements with HTML comments, for example:

<!--{## Ignore} (everything between here and the end HTML comment is commented out) {## /Ignore}-->

7.4.9 Comment Not Put in the Output File: {## COMMENT}

The {## COMMENT} macro allows the template writer to include comments in the template without including them in the final output files. {## COMMENT} provides the functionality of {## ignore}, but the text inside the {## COMMENT} block is not rendered to the output files and is not included in page size calculations. Like {## IGNORE}, {## COMMENT} macros may not be nested.

Syntax

{## COMMENT}
   any HTML or other {##} macros
{## /COMMENT}

7.4.10 Including Other Templates: {## INCLUDE}

This command allows other templates to be inserted into the current template. It works in a manner similar to the C/C++ # include directive.

Syntax

{## INCLUDE TEMPLATE=template}
Attribute Description
TEMPLATE This attribute gives the name of the template to insert.

7.4.11 Setting Options Within the Template: {## OPTION}

This macro sets an option to a given value. All {## OPTION} statements are executed in the order in which they are encountered. Remember when using this template macro that the {## UNIT} tag must be the first template macro in any template.

Options set in the template have template scope. This means that, for example, if a {## LINK} macro references another template, options in the referenced template are not affected by the option settings from the parent template. Similarly, when the files contained in an archive file are converted, Export recursively calls itself to perform the exports of the child documents in the archive. Each child document is converted using a copy of the parent template, and that copy does not inherit the option values from the parent template.

Options set using {## OPTION} in the template are not inherited by the dynamic conversions performed on files within archives. Each child conversion receives a fresh copy of all option values as originally set with DASetOption.

Remember that setting an option in the template overrides any option value set by an application within the scope of the template.

Syntax

{## OPTION OPTION=value}
Attribute Description
OPTION See the table below for the supported options and their values.

Supported Options and Values

Option Description
SCCOPT_GRAPHIC_TYPE This option sets the format of the graphics produced by Dynamic Converter when it converts document embeddings.

The supported values are:

  • FI_GIF: GIF graphics

  • FI_JPEGFIF: JPEG graphics

  • FI_PNG: PNG graphics

  • FI_NONE: no graphic conversion

The default is FI_JPEGFIF.

SCCOPT_GIF_INTERLACED This option specifies whether GIF output should be interlaced or non-interlaced. Interlaced GIFs are useful when graphics are to be downloaded over slow Internet connections. They allow the browser to begin to render a low-resolution view of the graphic quickly and then increase the quality of the image as it is received. There is no real penalty for using interlaced graphics.

The supported values are:

  • 0 or FALSE (i.e., non-interlaced)

  • 1or TRUE (i.e., interlaced)

SCCOPT_JPEG_QUALITY This options sets the lossyness of JPEG compression. This should be a value between 1 and 100 (percent), with 100 being the highest quality but the least compression, and 1 being the lowest quality but the most compression.
SCCOPT_GRAPHIC_SIZEMETHOD This option determines the method used to size graphics. You can choose among three methods, each of which involves some degree of trade off between the quality of the resulting image and speed of conversion:
  • SCCGRAPHIC_QUICKSIZING

  • SCCGRAPHIC_SMOOTHSIZING

  • SCCGRAPHIC_SMOOTHGRAYSCALESIZING

Using the quick sizing option results in the fastest conversion of color graphics, though the quality of the converted graphic will be somewhat degraded.

The smooth sizing option results in a more accurate representation of the original graphic, as it uses antialiasing. Antialiased images may appear smoother and can be easier to read, but rendering when this option is set will require additional processing time.

Please note that the smooth sizing option does not work on images which have a width or height of more than 4,096 pixels.

The grayscale-only option also uses antialiasing, but only for grayscale graphics, and the quick sizing option for any color graphics.

SCCOPT_GRAPHIC_OUTPUTDPI This option specifies the output graphics device's resolution in dots per inch (dpi), and only applies to images whose size is specified in physical units (in/cm). For example, consider a 1-inch square, 100-dpi graphic that is to be rendered on a 50-dpi device (with this option set to '50'). In this case, the size of the resulting WBMP, TIFF, BMP, JPEG, GIF, or PNG will be 50 x 50 pixels.

The valid values are any integer between 0 and 2400 (dpi).

SCCOPT_GRAPHIC_SIZELIMIT This option sets the maximum size of the exported graphic (in pixels). It may be used to prevent inordinately large graphics from being converted to equally cumbersome output files, thus preventing bandwidth waste.

This option takes precedence over all other options and settings that affect the size of a converted graphic.

SCCOPT_GRAPHIC_WIDTHLIMIT This option allows a hard limit to be set for how wide (in pixels) a converted graphic may be. Any images wider than this limit will be resized to match the limit. It should be noted that regardless whether the SCCOPT_GRAPHIC_HEIGHTLIMIT option is set or not, any resized images will preserve their original aspect ratio. Images smaller than this width are not enlarged when using this option.
SCCOPT_GRAPHIC_HEIGHTLIMIT This option allows a hard limit to be set for how high (in pixels) a converted graphic may be. Any images higher than this limit will be resized to match the limit. It should be noted that regardless whether the SCCOPT_GRAPHIC_WIDTHLIMIT option is set or not, any resized images will preserve their original aspect ratio. Images smaller than this height are not enlarged when using this option.
SCCOPT_EX_FONTFLAGS This option is used to turn off specified font-related markup in the output. Naturally, if the requested output flavor or other option settings prevent markup of the specified type from being written, this option cannot be used to turn it back on. However, specifying the size, color and font face of characters may all be suppressed by bitwise OR-ing together the appropriate combination of flags in this option.
  • SUPPRESS_SIZE

  • SUPPRESS_COLOR

  • SUPPRESS_SIZECOLOR

  • SUPPRESS_FACE

  • SUPPRESS_SIZEFACE

  • SUPPRESS_COLORFACE

  • SUPPRESS_ALL

  • SUPPRESS_NONE

SCCOPT_EX_GRIDROWS This option specifies the number of rows that each template "grid" (applicable only to spreadsheet or database files) should contain.

Setting this option to zero ("0") means that no limit is placed on the number of rows in the grid.

SCCOPT_EX_GRIDCOLS This option specifies the number of columns that each template "grid" (applicable only to spreadsheet or database files) should contain.

Setting this option to zero ("0") means that no limit is placed on the number of columns in the grid.

SCCOPT_EX_GRIDADVANCE This option specifies how the "previous" and "next" relationships will work between grids.
  • ACROSS: The input spreadsheet or database is traversed by rows.

  • DOWN: The input spreadsheet or database is traversed by columns.

This option has no effect on up/down or left/right navigation.

SCCOPT_EX_GRIDWRAP This option specifies how the "previous" and "next" relationships work between grids at the edges of the spreadsheet or database.

Consider a spreadsheet that has been broken into 9 grids by HTML Export as follows:

Surrounding text describes grid_flag.gif.

If this option is set to TRUE, then the Grids.Next.Body value after Grid 3 will be Grid 4. Likewise, the Grids.Previous.Body value before Grid 4 will be Grid 3.

If this option is set to FALSE, then the Grids.Next.Body after Grid 3 will not exist as far as template navigation is concerned. Likewise, the Grids.Previous.Body before Grid 4 will not exist as far as template navigation is concerned.

In other words, this option specifies whether the "previous" and "next" relationships "wrap" at the edges of the spreadsheet or database.


7.4.12 Copying Files: {## COPY}

The {## COPY} macro is used to copy extra, static files into the output directory along with the output from the converted document. For example, if you have added a company logo that was not in the original input document, {## COPY} can be used to make it a part of the converted output document. Other examples include graphics used to mimic "buttons" for navigation, outside CSS files, or a piece of Java code to be run.

Syntax

{## COPY FILE=file}
Attribute Description
FILE This is the name of the file to be copied. If a relative path name is specified as part of the file, then it must be relative to the directory containing the root template file.

For example:

{## COPY FILE=uparrow.gif}


The {## COPY} macro may occur anywhere inside a template. If the {## COPY} is inside a {## IF}, then the {## COPY} will only be executed if the condition is TRUE. In {## REPEAT} loops, the {## COPY} will only be performed if the loop is executed one or more times. In addition, if the {## REPEAT} loops more than once, Dynamic Converter detects this and the {## COPY} is executed only once.

As its name suggests, the {## COPY} macro is a straight file copy. Therefore, no conversions are performed as part of the copy. For example, graphics formats are not changed and graphics are not resized. Template authors should also remember to use {## GRAPHIC} when graphics and other files are copied so that space will be created for the external graphic in the text buffer size calculations.

Since the only action Dynamic Converter takes is to copy the requested file, it is up to the template author to make use of the copied file at another point in the template. For example, a graphic file may be copied and then the template can use an <img> tag which references the copied graphic. The following snippet of template code would do this:

{## copy FILE=Picture.JPG
{## graphic PATH=Picture.JPG}
<img src="Picture.JPG">

Note:

If the file copy fails, Dynamic Converter will continue and no error will be reported.

7.4.13 Deprecated Template Macros

Earlier releases of Dynamic Converter used different macro syntax where template macros were expected to start with {Inso} rather than {##}. In addition some words that had been abbreviated must now be spelled out ("insert" instead of "ins"). The old syntax will continue to be supported for the foreseeable future. However, it has been deprecated.

The old Inso macros and their new equivalents are as follows:

  • {insoins} is now {## insert}

  • {insoif} ... {/insoif} is now {## if} ... {## /if}

  • {insoelseif} ... {/insoelseif} is now {## elseif} ... {## /elseif}

  • {insoelse} ... {/insoelse} is now {## else} ... {## /else}

  • {insoignore} ... {/insoignore} is now {## ignore} ... {## /ignore}

  • {insolink} is now {## link}

  • {insorep} ... {/insorep} is now {## repeat} ... {## /repeat}

You cannot mix old-style Inso macros with the new {##} macro style in the same template.

No new or future features that Dynamic Converter will include support the old syntax. Thus, for example, the old syntax has not been extended to include support for the new {## UNIT} macros.

7.5 Pragmas

Pragmas provide access to certain document elements that are not logically part of the element tree. The following pragmas are supported:

7.5.1 Pragma.Charset

This pragma represents the HTML text string associated with the character set of the characters that Dynamic Converter is generating. In order for Dynamic Converter to correctly code the character set into the HTML it generates, all templates should include a META tag that uses the {## INSERT} macro as follows:

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset={## INSERT ELEMENT=pragma.charset}">

If the template does not include this line, the user will have to manually select the correct character set in their browser.

7.5.2 Pragma.CSSFile

This pragma is used to insert the name of the Cascading Style Sheet (CSS) file into HTML documents. This name is typically used in conjunction with an HTML <LINK> tag to reference styles contained in the CSS file generated by Dynamic Converter.

When used with the {## INSERT} macro, this pragma will generate the URL of the CSS file that is created. This macro must be used with {## INSERT} inside every template file that inserts contents of the source file and when the selected HTML flavor supports CSS. The CSS file will only be created if the selected HTML flavor supports CSS.

When used with the {## IF} macro, the conditional will be true if the selected HTML flavor supports Cascading Style Sheets or not.

If CSS is required for the output, {## IF element=pragma.embeddedcss} or {## IF element=pragma.cssfile} must be used. However, Dynamic Converter does not differentiate between the two, as the choice of using embedded CSS vs. external CSS is your decision and you may even wish to mix the two in the output.

An example of how to use this pragma that works when exporting either CSS or non-CSS flavors of HTML would be as follows:

{## IF ELEMENT=Pragma.CSSFile}
    <LINK REL=STYLESHEET
      HREF="{## INSERT
      ELEMENT=Pragma.CSSFile}">
    </LINK>
{## /IF}

7.5.3 Pragma.EmbeddedCSS

This pragma is used to insert CSS style definitions in a single block in the <HEAD> of the document.

When used with the {## INSERT} macro, this pragma will insert the block of CSS style definitions needed for use later in the file. This macro must be used inside every output HTML file where {## INSERT} is used to insert document content.

When used with the {## IF} macro, the conditional will be true if the selected HTML flavor supports CSS.

If CSS is required for the output, {## IF element=pragma.embeddedcss} or {## IF element=pragma.cssfile} must be used. However, Dynamic Converter does not differentiate between the two, as the choice of using embedded CSS vs. external CSS is your decision and you may even wish to mix the two in the output.

If a style is used anywhere in the input document, that style will show up in the embedded CSS generated for all the output HTML files generated for the input file. Consider a template that splits its output into multiple HTML files. In this example, the input file contains the "MyStyle" style. It does not matter if during the conversion only one output HTML file actually references the "MyStyle" style. The "MyStyle" style definition will still show up in the embedded CSS for all the output files, including those files that never reference this style.

7.5.4 Pragma.JsFile

This pragma is used to insert the name of the JavaScript file into HTML documents. This name is typically used in conjunction with an HTML <SCRIPT> tag to reference JavaScript contained in the .js file generated by HTML Export.

When used with the {## INSERT} macro, this pragma will generate the URL of the JavaScript file that is created. This macro must be used with {## INSERT} inside every template file that inserts contents of the source file when:

  1. The selected HTML flavor supports JavaScript.

  2. The javaScriptTabs option has been set to true.

The JavaScript file will only be created if the selected HTML flavor supports JavaScript.

When used with the {## IF} macro, the conditional will depend upon whether the selected HTML flavor supports JavaScript or not.

7.5.5 Pragma.SourceFileName

This pragma represents the name of the source document being converted.

Note:

The Pragma.SourceFileName pragma does not include the path name.

7.6 Sample Script Templates

Dynamic Converter comes with a number of sample script templates that you can check into Content Server and begin using right away. The sample script templates are available in the /ucm/Distribution/DynamicConverterSamples directory.

The following sample layout templates are available:

These sample script templates are provided as Hypertext Content Server Template (HCST) files.

7.6.1 Basic

Figure 7-2 shows an example of the Basic script template.

Figure 7-2 Example of the Basic Script Template

Sample of the basic script template
Description of "Figure 7-2 Example of the Basic Script Template"

The Basic sample script template contains the following code:

<html>
<head>
{## if element=property.title}
    <title>{## insert element=property.title suppress=tags}</title>
{## else}
    <title>Converted {## insert element=pragma.sourcefilename}</title>
{## /if}

{## if element=pragma.cssfile}
    <link rel="stylesheet" href="{## insert element=pragma.cssfile}"</link>
{## /if}

<$defaultPageTitle="Converted Content"$>
<$include std_html_head_declarations$>
</head>

<$include body_def$>
<$include std_page_begin$>
<$include std_header$>

<table border="0" cellpadding="0" cellspacing="0" width="550">
<tr><td>

{## repeat element=sections}
    <p align="center">{## insert element=sections.current.bodyorimage width=500}</p>
    <hr size="3"></hr>
{## /repeat}

</td></tr>
</table>

<$include std_page_end$>
</body>
</html>

7.6.2 Elements

Figure 7-3 shows an example of the Elements script template.

Figure 7-3 Example of the Elements Script Template

Sample Elements Script template
Description of "Figure 7-3 Example of the Elements Script Template"

See Appendix E, "Elements Script Template" for a more elaborate explanation of the Elements template.

7.6.3 Plain

The Plain sample script template contains the following code:

<html>
<head>
{## if element=property.title}
    <title>{## insert element=property.title suppress=tags}</title>
{## else}
     <title>Converted {## insert element=pragma.sourcefilename}</title>
{## /if}

{## if element=pragma.cssfile}
     <link rel="stylesheet" href="{## insert element=pragma.cssfile}"</link>
{## /if}

<$defaultPageTitle="Converted Content"$>
<$include std_html_head_declarations$>
</head>

<$include body_def$>
<$include std_page_begin$>
<$include std_header$>

<table border="0" cellpadding="0" cellspacing="0" width="550">
<tr><td>
{## repeat element=sections}
    {## if element=sections.current.type value=wp}
        {## insert element=sections.current.bodyorimage width=500}

        {## if element=sections.current.footnotes.1.body}
        <br></br>
        {## repeat element=sections.current.footnotes}
        {## insert element=sections.current.footnotes.current.body}
        <br></br>
        {## /repeat}
    {## /if}

        {## if element=sections.current.endnotes.1.body}
            <br><br>
            {## repeat element=sections.current.endnotes}
            {## insert element=sections.current.endnotes.current.body}
            <br></br>
        {## /repeat}
        {## /if}
    {## else}
    <h1>{## insert element=sections.current.body.title suppress=tags}</h1>
    {## insert element=sections.current.bodyorimage width=500}
    <br></br><hr></hr><br></br>
    {## /if}
{## /repeat}

</td></tr>
</table>

<$include std_page_end$>
</body>
</html>

7.6.4 SimpleToc

Figure 7-4 shows an example of the Simple TOC script template.

Figure 7-4 Example of the Simple TOC Script Template

Sample Simple TOC Script template
Description of "Figure 7-4 Example of the Simple TOC Script Template"

The SimpleToc sample script template contains the following code:

<html>
<head>
{## if element=property.title}
    <title>{## insert element=property.title suppress=tags}</title>
{## else}
    <title>Converted {## insert element=pragma.sourcefilename}</title>
{## /if}

{## if element=pragma.cssfile}
    <link rel="stylesheet" href="{## insert element=pragma.cssfile}"</link>
{## /if}

<$defaultPageTitle="Converted Content"$>
<$include std_html_head_declarations$>
</head>

<$include body_def$>
<$include std_page_begin$>
<$include std_header$>

<table border="0" cellpadding="0" cellspacing="0" width="550">
<tr><td>
    {## repeat element=sections}
    {## if element=sections.current.title}
        <a href="{## link element=sections.current.bodyorimage}">
          {## insert element=sections.current.title suppress=tags}
        </a>
        <br></br>
    {## /if}

    {## if element=sections.current.type value=wp}
        {## if element=sections.current.headings.1.body}
        {## repeat element=sections.current.headings}
        <a href="{## link element=sections.current.headings.current.body}">
          {## insert element=sections.current.headings.current.title suppress=tags}
        </a>
     <br></br>

    {## if element=sections.current.headings.current.headings.1.body}
     {## repeat element=sections.current.headings.current.headings}
      &#160;&#160;&#160;&#160;&#160;
      <a href="{## link element=sections.current.headings.current.headings.current.body}">
      {## insert element=sections.current.headings.current.headings.current.title suppress=tags}
      </a>
   <br></br>
{## /repeat}
{## /if}
{## /repeat}
{## /if}
{## /if}
{## /repeat}

    <hr size="3"></hr>
    {## repeat element=sections}
    {## insert element=sections.current.bodyorimage width=500}
    <hr size="3"></hr>
    {## /repeat}

    {## if element=property.author}
      <p><b>Author:</b><br></br>
        {## insert element=property.author suppress=tags}
      </p>
    {## /if}
    <br></br>
    {## if element=property.title}
       <p><b>Title:</b><br></br>{## insert element=property.title suppress=tags}</p>
    {## /if}
    <br></br>
    {## if element=property.subject}
       <p><b>Subject:</b><br></br>{## insert element=property.subject suppress=tags}</p>
    {## /if}
    <br></br>
    {## if element=property.keywords}
      <p><b>Keywords:</b><br></br>{## insert element=property.keywords suppress=tags}</p>
    {## /if}
    <br></br>
    {## if element=property.comment}
      <p><b>Comment:</b><br></br>{## insert element=property.comment suppress=tags}</p>
    {## /if}
    <br></br>
</td></tr>
</table>

<$include std_page_end$>
</body>
</html>

7.6.5 Slideshow, Slideshowb, and Slideshowc

The Slideshow templates can be used to convert PowerPoint presentations. See "Configuring Slideshow Template Files for PowerPoint Presentations".

Slideshow

The Slideshow sample script template contains the following code:

<html>
<head>
{## if element=property.title}
    <title>{## insert element=property.title suppress=tags}</title>
{## else}
    <title>Converted {## insert element=pragma.sourcefilename}</title>
{## /if}

{## if element=pragma.cssfile}
     <link rel="stylesheet" href="{## insert element=pragma.cssfile}"</link>
{## /if}

<$defaultPageTitle="Converted Content"$>
<$include std_html_head_declarations$>
</head>

<$include body_def$>
<$include std_page_begin$>
<$include std_header$>

<script language="JavaScript"><!--
if (document.images)
{
    {## repeat element=sections}
    thumb{## insert number=sections.current.value} = new Image;
    thumb{## insert number=sections.current.value}.src = "{## insert element=sections.current.image width=400 suppress=tags}";
    {## /repeat}
}

function swapem(iname,gname)
{
    if (document.images)
     {
      document.images[iname].src = eval(gname + ".src");
     }
}

function openawindow( pageToLoad, winName, width, height, center)
{
/* Opens a new window on the users desktop.
   Arguments:
   pageToLoad - The URL of a page to load in the browser window.
                This can be a relative URL or fully qualified.
   winName -    Name of the new window.
   width   -    The horizontal size of the new window.
   height  -    The vertical size of the new window.
   center  -    toggle centering on 4.0 browsers.
                1=centered window 0=no centering

    Values in the "args" section below can all be toggled in the
      same fashion as the center toggle.  Just modify the appropriate
    value in the args section to be either 0 or 1.

    A call to this function might look like this:
    &lt;a href="javascript:openAWindow('ice.html','ice',375,250,1)"&gt;Ice&lt;/a&gt;

    Created by Glenn Davis of Project Cool, Inc. for general use.  If
    you use this routine please leave all comments in place so that
    others may benefit as well.


*/
   if ((parseInt(navigator.appVersion)) < 4){swidth = 640} else {swidth = (screen.width-10)}
   if ((parseInt(navigator.appVersion)) < 4){sheight = 480} else {sheight = (screen.height-60)}

   args = "width=" + swidth + ","
   + "height=" + sheight + ","
   + "location=0,"
   + "menubar=0,"
   + "resizable=1,"
   + "scrollbars=0,"
   + "status=0,"
   + "titlebar=0,"
   + "toolbar=0,"
   + "hotkeys=0,"
   + "screenx=" + 0  + ","  //NN Only
   + "screeny=" + 0  + ","  //NN Only
   + "left=" + 0  + ","     //IE Only
   + "top=" + 0 ;           //IE Only

     window.open( pageToLoad,winName,args );
}

// --></script><div align="center"><center>

<table border="0" cellpadding="0" cellspacing="0" width="550">
<tr><td>

{## if element=property.title}
    <p><h3>{## insert element=property.title suppress=tags}</h3></p>
{## /if}

{## if element=property.subject}
    <p><h3>{## insert element=property.subject suppress=tags}</h3></p>
{## /if}

<p><h3>{## insert number=sections.count} slides by {## insert element=property.author suppress=tags}</p>

<table border="0" cellpadding="0" cellspacing="0" width="550">
    <tr>

    <td valign="top">
    <table>
        {## repeat element=sections}
          <tr><td>
         <a href="javascript:openawindow('{## link element=sections.current.bodyorimage template=slideshowbtemplate.hcst}','bigslide', 640,480,1)" onMouseOver="swapem('thumbimg','thumb{## insert number=sections.current.value}')">
       <font size="1">{## insert element=sections.current.body.title suppress=tags}</font>
       </a>
       </td></tr>
       {## /repeat}
     </td></tr>
   </table>
   </td>

   <td>
   <img src="<$HttpWebRoot$>images/space.gif" border="0" width="50"></img>
   </td>

   <td valign="top">
     <img name="thumbimg" src="{## insert element=sections.1.image width=400 suppress=tags}"></img>
   </td>
   </tr>
</table>

</td></tr>
</table>

<$include std_page_end$>
</body>
</html>

Slideshowb

The Slideshowb sample script template contains the following code:

<html>

<head>
{## if element=property.title}
    <title>{## insert element=property.title suppress=tags}</title>
{## else}
    <title>converted {## insert element=pragma.sourcefilename}</title>
{## /if}
{## if element=pragma.cssfile}<link rel="stylesheet" href="{## insert element=pragma.cssfile}"></link>{## /if}
</head>

<body bgcolor="BLACK" topmargin="0" leftmargin="0" scroll="No">

<p><center>
<a href="{## if element=sections.next.bodyorimage}{## link element=sections.next.image}{## else}{## link template=slideshowctemplate.hcst}{## /if}">
<img border="0" src="{## insert element=sections.current.image width=640 height=480 suppress=tags}" width="100%" height="100%"></img></a></center></p>
</body>
</html>

Slideshowc

The Slideshowc sample script template contains the following code:

<html>
<head>
{## if element=property.title}
    <title>{## insert element=property.title suppress=tags}</title>
{## else}
    <title>converted {## insert element=pragma.sourcefilename}</title>
{## /if}
{## if element=pragma.cssfile}<link rel="stylesheet" href="{## insert element=pragma.cssfile}"></link>{## /if}
</head>
<body bgcolor="black">
<font color="white" size="+5">

<center>This is the end of the presentation.
<p><a href="{## link element=sections.1.bodyorimage template=slideshowbtemplate.hcst}">Return to start of presentation.</a></p>
</center>

</font>
</body></html>

7.6.6 Textout

The Textout sample script template contains the following code:

<html>
<head>
{## if element=property.title}
   <title>{## insert element=property.title suppress=tags}</title>
{## else}
   <title>Converted {## insert element=pragma.sourcefilename}</title>
{## /if}

{## if element=pragma.cssfile}
   <link rel="stylesheet" href="{## insert element=pragma.cssfile}"</link>
{## /if}

<$defaultPageTitle="Converted Content"$>
<$include std_html_head_declarations$>
</head>

<$include body_def$>
<$include std_page_begin$>
<$include std_header$>

<table border="0" cellpadding="0" cellspacing="0" width="550">
<tr><td>
   
<h1><font color="0000FF">Document Body</font></h1>
{## repeat element=sections}
   <h2><font color="0000FF">Section </font>{## insert number=sections.current.value}</h2>
   
   {## if element=sections.current.type value=ss}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>spreadsheet<font color="0000FF">&quot;</font>
      </p>
      <p>
      <font color="0000FF"><b>Title</b>=&quot;</font>
      {## insert element=sections.current.title}<font color="0000FF">&quot;</font>
      </p>
      {## insert element=sections.current.bodyorimage width=500}
      {## elseif element=sections.current.type value=pr}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>presentation<font color="0000FF">&quot;</font>
      </p>
      <h3><font color="0000FF">Image</font></h3>
      {## if element=sections.current.image}
         {## insert element=sections.current.image width=500}
      {## else}
         <p><font color="0000FF">Image is empty</font></p>
      {## /if}
      <h3><font color="0000FF">Image Text</font></h3>
      {## if element=sections.current.body}
         {## insert element=sections.current.body}
      {## else}
         <p><font color="0000FF">Image text is empty</font></p>
      {## /if}
      {## elseif element=sections.current.type value=dr}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>vector graphic drawing<font color="0000FF">&quot;</font>
      </p>
      <h3><font color="0000FF">Image</font></h3>
      {## if element=sections.current.image}
         {## insert element=sections.current.image width=500}
      {## else}
         <p><font color="0000FF">Image is empty</font></p>
      {## /if}
      <h3><font color="0000FF">Image Text</font></h3>
      {## if element=sections.current.body}
         {## insert element=sections.current.body}
      {## else}
         <p><font color="0000FF">Image text is empty</font></p>
      {## /if}
      {## elseif element=sections.current.type value=bm}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>bitmap<font color="0000FF">&quot;</font>
      </p>
      <h3><font color="0000FF">Image</font></h3>
      {## if element=sections.current.image}
         {## insert element=sections.current.image width=500}
      {## else}
         <p><font color="0000FF">Image is empty</font></p>
      {## /if}
      <h3><font color="0000FF">Image Text</font></h3>
      {## if element=sections.current.body}
         {## insert element=sections.current.body}
      {## else}
         <p><font color="0000FF">Image text is empty</font></p>
      {## /if}
      {## elseif element=sections.current.type value=wp}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>bitmap<font color="0000FF">&quot;</font>
      </p>
      <h2><font color="0000FF">Section Body</font></h2>
      {## insert element=sections.current.contents width=500}
      {## elseif element=sections.current.type value=ar}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>archive<font color="0000FF">&quot;</font>
      </p>
      {## insert element=sections.current.bodyorimage width=500}
      {## elseif element=sections.current.type value=db}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>database<font color="0000FF">&quot;</font>
      </p>
      {## insert element=sections.current.bodyorimage width=500}
      {## elseif element=sections.current.type value=ch}
      <p>
      <font color="0000FF"><b>Section Type</b>=&quot;</font>chart<font color="0000FF">&quot;</font>
      </p>
      <h3><font color="0000FF">Image</font></h3>
      {## if element=sections.current.image}
         {## insert element=sections.current.image width=500}
      {## else}
         <p><font color="0000FF">Image is empty</font></p>
      {## /if}
      <h3><font color="0000FF">Image Text</font></h3>
      {## if element=sections.current.body}
         {## insert element=sections.current.body}
      {## else}
         <p><font color="0000FF">Image text is empty</font></p>
      {## /if}
   {## else}
      <p>
      <font color="0000FF"><b>Section Type</b> is not one of wp, ss, pr, dr, bm, db, ch, or ar<font></p>
      </p>
      {## insert element=sections.current.bodyorimage width=500}
   {## /if}
{## /repeat}

</td></tr>
</table>

<$include std_page_end$>
</body>
</html>

7.7 Setting Script Template Formatting Options

You can control formatting options for script templates by editing the Script Template Conversion Cnfiguration Settings (see "Script Template Conversion Configuration Settings") on the Dynamic Converter Configuration page (see "Dynamic Converter Configuration Page").

The settings that you can change include:

7.7.1 Changing the Format Used for Converted Graphics

If you want to change the format to be used for converted graphics, edit the following option:

# SCCOPT_GRAPHIC_TYPE
#
# Determines what graphic format will be used for exported graphics.
# Setting this to "none" disables graphic output.
#
graphictype     gif
#graphictype    jpeg
#graphictype    png
#graphictype    none

Lines that begin with "#" have been commented out. So the above example shows the default setting, with the gif format selected. To use the jpeg format, instead, you would simply comment the first line and uncomment the second line, thus:

#graphictype    gif
graphictype    jpeg
#graphictype    png
#graphictype    none

7.7.2 Generating Bullets and Numbers for Lists

If you want to generate bullets and numbers for lists instead of HTML list tags, you would edit the following option:

# SCCOPT_GENBULLETSANDNUMS

#
# Generate Bullets and Numbers.  Bullets and numbers will be generated for
# lists instead of using HTML list tags (<ol>, <ul>, <li>, etc.) when
# rendering lists in a document.
#
genbulletsandnums   no
#genbulletsandnums  yes

Again, comment one line and uncomment another, thus:

#genbulletsandnums  no
genbulletsandnums   yes

7.8 Breaking Documents by Structure

One of the most powerful features of the template architecture is the ability to break long word processor documents up into logical pieces and create powerful navigation aids to access them.

To understand how this is done, you must first understand the document tree as it relates to word processing documents. The somewhat complex graphic below attempts to show how the elements in the tree relate to a real-world document (see figure below).

The following are some examples of elements and the data they would produce if run against the document shown in the preceding image. Note the omission of the default nodes body and contents in the second two examples:

body.contents.headings.2.body.title

would produce "Present Day."

body.contents.headings.2.body.contents.headings.1.body.title

would produce "Commercial."

body.contents.preface

would produce "The History of Flight" and the text below it, up to but not including "Introduction."

headings.2.headings.1.headings.3.title

would produce "McDonnell-Douglas."

headings.2.headings.1.headings.3.contents

would produce the text below "McDonnell-Douglas" but above "Military."

Figure 7-5 Breaking up documents by structure

Sample of breaking up a document by structure

Breaking documents requires that Dynamic Converter understands the logical divisions in the structure of a document. Currently the only formats that can give Dynamic Converter this information in an unambiguous manner are Microsoft Word 95 and higher and WordPerfect 6.0 and higher. In these formats, the breaking information is available if the author placed table-of-contents information in the document. Refer to the appropriate software manual for information on the necessary procedure for including this information. That is not to say that the document must have a table of contents, only that the information to build one must be present.

It should be noted that some word processing formats, including Microsoft Word 2002 (XP), allow users to specify TOC entries in multiple ways. Dynamic Converter only supports two of these methods:

TOC specified through… Supported in Dynamic Converter?
Applied heading styles Yes
Custom styles with outline levels Yes
Outline level applied as a paragraph attribute No
TOC entries No

Additionally, if a heading style is applied to text inside a table in the original document, Dynamic Converter will not break on that heading. This is because Dynamic Converter will not break within tables.

Indexes and Structure-Based Breaking

All repeatable nodes have an associated index variable that has a current value at any given time in the conversion process. For elements that contain repeatable nodes as part of their path, the instance of the repeatable element must be specified by using a number or one of several index variable keywords. See "Index Variable Keywords" for more information on the possible values for the index variables.

7.9 Breaking Documents by Content Size

In addition to breaking documents by structure (see "Setting Script Template Formatting Options"), Dynamic Converter also supports breaking documents based on the amount of content to be placed in each output file or "page." Documents can even be broken based on both their structure and content size.

To break documents by content size, two things must be done. First, the SCCOPT_EX_PAGESIZEpageSize option must be set (see "Setting Options Within the Template: {## OPTION}"). The second thing that must be done is that the template used must be equipped with the {## UNIT} construct (see "Units: {## UNIT}, {## HEADER}, and {## FOOTER}").

The basic idea behind the unit template construct is to tell Dynamic Converter what things should be repeated on every "page" and what pieces should only be shown once. In other words, the unit template construct provides a mechanism for grouping template text and document elements. Unit boundaries are used when determining where to break the document when spanning pages.

Here are some examples of the kinds of things the template author might want to appear on every page:

  • The <META> tag inserting the output document character set.

  • A company copyright message.

  • Navigational elements to link the previous/next pages together.

Typical examples of things that would not go on every page would be:

  • The actual content of the document.

  • Structural navigational elements like the links for a table of contents.

A unit consists of a header, a footer (both of which are optional), and a body. Items that are to be repeated at the beginning or end of every unit should be placed in the header or footer respectively.

A unit is delimited by the {## UNIT} template macro. Similarly, the {## HEADER} and {## FOOTER} template macros delimit the header and footer respectively. The body is everything that is left between the header and the footer. The {## UNIT} macro must be the first macro in the template. The body frequently contains nested units. The body may be empty.

To ensure that the header is the first item in the template and the footer is the last item, text between the {## UNIT} tag and the {## HEADER} tag will be ignored, as will text between the {## /FOOTER} tag and the {## /UNIT} tag, including whitespace. The header and footer of a unit will be output in every page containing that unit, enclosing that portion of the unit's body that is able to fit in a particular page. The entire template is a unit that may contain additional units.

7.9.1 A Sample Size Breaking Template

By way of example, let's take another look at the very simple template from About Script Templates. To make things more interesting, let's insert the character set into the template with a <meta> tag. Let's also insert some better navigation to improve movement between the pages. The modified version of the template is as follows:

{## unit}{## header}
<html><head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;
charset={## insert element=pragma.charset}" /></head>
<body>
{## anchor aref="prev" format="<p><a href=\"%url\">Prev</a></p>"}
{## /header}
<p>Here is the document you requested.
{## insert element=property.title} by
{## insert element=property.author}</p>

<p>Below is the document itself</p>
{## insert element=body}
{## footer}
{## anchor aref="next" format="<p><a href=\"%url\">Next</a></p>"}
</body>
</html>
{## /footer}{## /unit}

A very small value (about 20 characters) is used for the page size option. The resulting HTML might look like this (HTML that is the result of a macro is in bold):

file1.htm

<html><head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ASCII"/></head>
<body>
<p>Here is the document you requested.</p>
<p>A Poem by Phil Boutros</p>
<p><a href="file2.htm">Next</a></p>
</body>
</html>

file2.htm

<html><head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ASCII" /></head>
<body>
<p><a href="file1.htm">Next</a></p>
<p>Below is the document itself</p>
<p>Roses are red</p>
<p>Violets are blue</p>
<p><a href="file3.htm">Prev</a></p>
</body>
</html>

file3.htm

<html><head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ASCII" /></head>
<body>
<p><a href="file2.htm">Prev</a></p>
<p>I'm a programmer</p>
<p>and so are you</p>
</body>
</html>

There are several things to note here:

  • The page size option value does not apply to the text from the template, only the text inserted from the source document. Each page contains roughly 20 characters of visible input document text.

  • The {## INSERT} of the character set is part of the {## HEADER} and therefore is inserted into all the output pages.

  • Text from the body of the unit is inserted sequentially. Thus "as is" template text such as the line "<p>Below is the document itself</p>" is only inserted once.

  • The {## ANCHOR} tags only insert links to the previous/next page if there actually is a previous/next page. Thus the first page does not have a link to the non-existent previous page.

7.9.2 Templates Without {## UNIT} Macros

The {## UNIT} macro is only required in templates that are designed to break pages based on size using the SCCOPT_EX_PAGESIZEpageSize option. An example of a template that would not perform any size-based breaking is one that defines an HTML <FRAME>, but does not include any document content. Another example where size-based breaking might not be desired is a table of contents page, even though a table of contents page does contain document content.

A template that does not conform to the {## UNIT} format is a not a size-based breaking template. Support for this type of template will continue for the indefinite future. The template will be considered to not be a size-based breaking template if the first macro tag encountered is something other than {## UNIT}. This means that there cannot be any {## UNIT}, {## HEADER} or {## FOOTER} macros later in the template. The value of the SCCOPT_EX_PAGESIZEpageSize option will be ignored for this type of template.

7.9.3 Indexes and Size-Based Breaking

As mentioned earlier, all repeatable nodes have an associated index variable. See "Index Variable Keywords" for information about using index variable keywords such as "Next" and "Last."

7.10 Using Grids to Navigate Spreadsheet and Database Files

In order to support spreadsheets (and database files, though they are not as common), a template-based navigation concept known as a "grid" is available. Grids offer a way to consistently navigate a spreadsheet or database in an intuitive fashion.

Grids can be used to present the output of large spreadsheets in smaller pieces, so that less scrolling is necessary. It can also be used to help prevent the HTML versions of large spreadsheets from overwhelming browsers, potentially causing them to lock up. Grids can also be used to halt processing of large spreadsheets before they waste too much CPU time.

To use grids, you should use the new grid template element (see "Element Definitions"). Grids may only be used in templates that have been enabled with the {## UNIT} template macro. It is also important to set the grid-related options (see "Setting Options Within the Template: {## OPTION}").

The grid support has some important limitations:

  1. The output file format and flavor are expected to supports tables, although this is not required.

  2. Grids are only used when converting spreadsheets and database input files. Grids are not available for word processing files at this time.

  3. Due to size constraints, grid support works best if the contents of the cells in the input file do not make use of a lot of formatting (bold, special fonts, text color, etc.).

To further explain the grid system, consider a multi-sheet spreadsheet workbook as an example. Each sheet in the spreadsheet workbook is broken into a collection of grids. Each grid has a fixed maximum size and is a rectangular portion of the spreadsheet. The size of the grid is specified as a number of spreadsheet cells. For example, consider the 7 x 10 spreadsheet in Figure 7-6.

Figure 7-6 Example 7 X 10 Spreadsheet

Sample 7 x 10 spreadsheet

If you wanted to break it up into 3 x 4 grids, nine grids would be produced as shown in Figure 7-7.

Figure 7-7 Example 7 x 10 Spreadsheet Split Up in 3 X 4 Grids

Sample 7 x 10 Spreadsheet split up in 3 X 4 Grids

Normally, all grids have the same number of cells. The exception is that grids at the right or bottom edge of the spreadsheet may be smaller than the normal size. Grids will never be larger than the requested size. For this reason, grids can easily be navigated by using "up," "down," "left," or "right." One thing that grids cannot do is address individual cells in a spreadsheet (except, of course, in the degenerate case of a grid whose size is 1 x 1).

Dynamic Converter does not force deck/page breaks between each grid. Therefore, if the template writer wants to limit each deck/page to only one grid, they should force the break in the template.

Grid Support When Tables Are Not Available

Not all output flavors supported by Dynamic Converter support the creation of tables. If the output flavor does not support tables, Dynamic Converter will still support grids. However, Dynamic Converter's normal non-table output will be what is presented in grid form. For example, if "[A1]" represents the contents of cell A1, then we would export the following for a grid of size (2 x 2):

If grids.1.body is:

[A1]
[A2]
[B1]
[B2]

then grids.right.body is:

[C1]
[C2]
[D1]
[D2]

and grids.down.body is:

[A3]
[A4]
[B3]
[B4]