How it works

The figure on the side shows the global architecture of the Stog engine and the flow of data.

Stog documents are read from the source directory and a stog structure is created. Since some documents may be in the cache and do not need to be recomputed, the small yellow boxes represent the filtering of documents in the stog structure to create a list of documents to compute.

Two modules are represented on the figure (Module 1 and Module 2). More modules can be present, for example when loading plugins.

These modules define functions associated to levels: Here the Module 1 has functions for levels 0, 20 and 30, while Module 2 has functions for levels 1 and 20.

For each level, in ascending order, the stog structure is passed to the function at this level, for each module where there is one. These functions take the stog structure and the list of documents to compute. They return a new stog structure (which may be unchanged, if no document was changed or created).

These "level functions" also take in parameter a data structure which is specific for each module. This data structure is also returned by the functions, as in a regular "fold" function.

When the functions of all levels have been applied, the documents in the final stog structure are outputted to files in the target directory, according to their path in the source directory. The cache is updated with information about dependencies and contents of documents. For each module, a specific function is called to cache the final data associated to the module. All cache information is stored in the .stog/cache directory.

The cached documents and dependencies will be used next time Stog is run, to know which documents must be recomputed, and cached module data will be used to initialize the data structure specific to each module.

Stog comes with two predefined modules, "base" and "blocks", each defining functions for various levels. The "level functions" often apply rewrite rules on the documents' contents (which are XML trees) but can also perform other actions like gathering information in the module-specific data structure to use it in a higher level.

Various levels are required to ensure some treatments or rewrite rules will be applied after others, for example to verify cross-document links. Levels used by predefined modules are numbered like lines in BASIC programs: 0, 50, 100, 120, ... making plugins able to insert new levels.

Modules can define functions for negative levels, for example to make sure they will be applied before level 0.

The first application of a level function to a document uses the type of the document to load the corresponding template; for example, if the document has type "page", then a template page.tmpl will be looked for (in the .stog/templates directory).

Environment

An environment is built containing the site-wide attributes. This environment is a set of rewrite rules. It is passed to every "level function".

A "level function" can enrich this environment with the attributes of a document (using this function). This is what most of the default level functions do, in addition to defining rewrite rules, to get the "rewrite environment" to apply on each document to compute.

The environment is used in the following way to rewrite XML trees. For each encountered node with tag t, t is looked up in the environment for its associated function f.

If no f is found, then the XML node is left untouched and the children of the node are then analysed.

If f is found, then it is called, given the environment, the attributes and the children of the node. Then the function returns a list of XML trees which must then be analysed.

When this analyze reaches a fixpoint, the final XML is returned.

This work is performed by the Xtmpl library.

Besides, the contents of the attributes are also analysed to perform such substitutions, before looking up for the tag in the environment.

Stog comes with predefined functions (in two default modules) associated to some tags, but more can be created in plugins.

For information you can see the source code of the page.

<page title="Evaluation and templating"
navbar-doc="active"
>

<section id="howitworks" title="How it works">
<div class="float-right">
<a href="engine.svg">
<image width="350" src="engine.png" alt="engine's big picture"
title="Data flow in Stog's engine.
 Click on the image to open the .svg file, which
includes some links to reference documentation.">
Data flow in Stog's engine.</image></a>
</div>
<p>
The figure on the side shows the global architecture of the
Stog engine and the flow of data.
</p>
<p><doc href="stog-documents"/> are read from the source directory
and a <a href="refdoc/stog/Stog/Types/index.html#type-stog">stog</a> structure is created.
Since some documents may be in the cache and do not need to be recomputed,
the small yellow boxes represent the filtering of documents in the stog
structure to create a list of documents to compute.
</p>
<p>
Two modules are represented on the figure (Module 1 and Module 2). More modules
can be present, for example when loading <doc href="writing_plugins">plugins</doc>.
</p>
<p>These modules define functions associated to <em>levels</em>: Here
the Module 1 has functions for levels 0, 20 and 30, while Module 2 has
functions for levels 1 and 20.
</p>
<p>For each level, in ascending order, the stog structure is passed
to the function at this level, for each module where there is one.
These functions take the stog structure and the list of documents
to compute. They return a new stog structure (which may be unchanged, if
no document was changed or created).
</p>
<p>These "level functions" also take in parameter a data structure which is
specific for each module. This data structure is also returned by the functions,
as in a regular "fold" function.
</p>
<p>
When the functions of all levels have been applied, the documents in the
final stog structure are outputted to files in the target directory, according
to their path in the source directory. The cache is updated with information
about dependencies and contents of documents. For each module, a specific
function is called to cache the final data associated to the module.
All cache information is stored in the <icode>.stog/cache</icode> directory.
</p>
<p>
The cached documents and dependencies will be used next time Stog is run,
to know which documents must be recomputed, and cached module data will
be used to initialize the data structure specific to each module.
</p>
<p>
Stog comes with two predefined modules, "base" and "blocks", each defining
functions for various levels. The "level functions" often apply rewrite rules
on the documents' contents (which are XML trees) but can also perform other
actions like gathering information in the module-specific data structure
to use it in a higher level.
</p>
<p>Various levels are required to ensure some treatments or rewrite rules
will be applied after
others, for example to verify cross-document links. Levels used by predefined
modules are numbered like lines in BASIC programs: 0, 50, 100, 120, ... making
plugins able to insert new levels.
</p>
<p>Modules can define functions for negative levels, for example to make
sure they will be applied before level 0.
</p>
<p>The first application of a level function to a document uses the
type of the document to load the corresponding template; for example,
if the document has type "page", then a template <icode>page.tmpl</icode> will
be looked for (in the <icode>.stog/templates</icode> directory).
</p>
</section>

<section id="env" title="Environment">
<p>An environment is built containing the
<doc href="stog-main-document">site-wide attributes</doc>.
This environment is a set of rewrite rules. It is passed to every "level function".
</p>
<p>
A "level function" can enrich this environment with the attributes of a document
(using <a href="refdoc/stog/Stog/Engine/index.html#val-doc_env">this function</a>). This is what
most of the default level functions do, in addition to defining rewrite rules,
to get the "rewrite environment" to apply on each document to compute.
</p>
<p>
The environment is used in the following way to rewrite XML trees.
For each encountered node with tag <icode>t</icode>, <icode>t</icode> is looked up
in the environment for its associated <em>function</em> <icode>f</icode>.
</p>
<p>If no <icode>f</icode> is found, then the XML node is left untouched
and the children of the node are then analysed.
</p>
<p>If <icode>f</icode> is found, then it is called, given the environment,
the attributes and the children of the node. Then the function returns
a list of XML trees which must then be analysed.
</p>
<p>When this analyze reaches a fixpoint, the final XML is returned.
</p>
<p>This work is performed by the <ext-a href="https://www.good-eris.net/xtmpl">Xtmpl</ext-a>
library.</p>
<p>Besides, the contents of the attributes are also analysed to perform such substitutions,
before looking up for the tag in the environment.
</p>
<p>Stog comes with <page href="funs">predefined functions</page> (in two default modules)
associated to some tags, but more can be created in
<doc href="writing_plugins">plugins</doc>.
</p>
</section>
</page>