VirtualDub source code - Lina

Lina is the HTML compiler for VirtualDub's help system.

Syntax and input

The basic input format to Lina is almost XML, but not quite:

Lina constructs a parse tree from her input and uses that tree to write output. Attributes are quoted as necessary, standalone tags are written without the self-close for greatest compatibility, and redundant whitespace is removed. As a result, it is difficult to make common HTML structural errors.

Parsing phase

All control tags are of the form <lina:xxxx>. Two of these tags are special and execute as soon as they are parsed:

These immediate tags are never placed in the tree; all other control tags are put in the tree and execute only after the entire tree has been parsed.

Lina requires that non-space character data only appear within tags that allow them, and will error if it is present elsewhere, such as immediately inside an <html> tag. The list of tags allowing CDATA can be augmented using <lina:set-option>.

Execution phase

After parsing is complete, Lina then executes the parse tree from top to bottom:

In the process of doing so, three separate stacks are maintained:

When tags are being constructed, plain text and tags copy themselves into the new tag. If a file is being written, the tags are output to that file. Otherwise, the output is discarded.

Control tags

<lina:apply name="macro">...</lina:apply>
Apply the named macro with each of the enclosed children as the given context.
<lina:arg name="argname"/>
Output the named attribute argument from the current macro context.
<lina:attrib name="att-name">...</lina:attrib>
Create an attribute in the currently constructing tag with the given contents.
<lina:cdata>...</lina:cdata>
Insert the enclosed text and tags with whitespace collapsing enabled.
<lina:data>...</lina:data>
Prohibit execution of enclosed tags. This tag is skipped during path searches.
<lina:delay>...</lina:delay>
Copy tags verbatim without execution into the output.
<lina:dump-stack/>
Dump current stacks to standard output for debugging.
<lina:fireball src="src-file" dst="dst-file">
Copy a file.
<lina:for-each name="path">...</lina:for-each>
Execute the tag body as a macro, with all tags referenced by the given path as the contexts.
<lina:if-arg name="arg-name">...</lina:if-arg>
Executes the tag body only if the current macro context has the named attribute argument.
<lina:if-not-arg name="tag-name">.../<lina:if-not-arg>
Executes the tag body only if the current macro context does not have the named attribute argument.
<lina:if-not-present name="tag-name">...</lina:if-not-present>
Executes the tag body only if the current macro context does not have the named tag.
<lina:if-present name="tag-name">...</lina:if-present>
Executes the tag body only if the current macro context has the named tag.
<lina:pre>...</lina:pre>
Insert the enclosed text and tags without whitespace collapsing enabled.
<lina:pull name="path"/>
Execute the contents of the tag specified by the given path in the current context.
<lina:replace from="pattern" to="result">...</lina:replace>
Execute the tag contents, replace all instances of pattern with result in the output, and place the output into a new string tag.
<lina:set-option name="link-truncate" baseurl="base-url" [notruncate]>
Toggles extension truncation for links with the given prefix.
<lina:set-option name="output-dir" target="path">
Sets the output directory for file writes and file copies.
<lina:set-option name="tag-info" tag="tag-name" cdata="y"|"n">
Allows or disallows inline character data (CDATA) for the given tags.
<lina:source>...</lina:source>
Output the source to the enclosed tag structure as text in HTML.
<lina:tag name="tag-name">...</lina:tag>
Create a tag with the given name and body as contents, and then execute the created tag.
<lina:write file="filename">...</lina:write>
Execute the given body and write the output to a file.