working on doc
authorgrok <grok>
Fri, 12 Aug 2005 09:19:35 +0000 (09:19 +0000)
committergrok <grok>
Fri, 12 Aug 2005 09:19:35 +0000 (09:19 +0000)
doc/developers-guide/developers-guide.xml
doc/developers-guide/introduction.xml
doc/developers-guide/producers.xml

index cabc2c7..d3a2f1c 100755 (executable)
@@ -8,7 +8,7 @@
   ]
 >
 <book>
-  <title>Mir CMS 1.1, developpers guide</title>
+  <title>Mir CMS 1.1: developer's guide</title>
   <bookinfo>
     <revhistory>
       <revision>
 
   <preface> 
       <abstract>
-          This document is meant for helping mir developpers. It is assumed that
-          you have allready installed mir and have some basic knowledge
+          This document is meant for helping mir developers (people that
+          write java code within Mir). It is assumed that
+          you have already installed mir and have some basic knowledge
           on how to use it. However, reading the introduction chapter might
-          also be worthwhile for sysadmins and template designers.
+          also be worthwhile for sysadmins, webmasters and template designers.
       </abstract>
   </preface>
 
index 8b0b253..e83daa8 100755 (executable)
@@ -16,9 +16,9 @@ the dynamic site  (see figure).
 <figure><title>mir architecture (single host)</title>
 <mediaobject>
 <imageobject>
-<imagedata fileref="diagrams/mir-architecture-singlehost.eps" format="EPS"></imagedata></imageobject>
+<imagedata fileref="figures/mir-architecture-singlehost.eps" format="EPS"></imagedata></imageobject>
 <imageobject>
-<imagedata fileref="diagrams/mir-architecture-singlehost.png" format="PNG"></imagedata></imageobject>
+<imagedata fileref="figures/mir-architecture-singlehost.png" format="PNG"></imagedata></imageobject>
 <textobject>
 </textobject>
 </mediaobject>
@@ -35,9 +35,9 @@ site. Mirrors are simple to set up, since only static pages are involved
 <figure><title>mir architecture (mirrored)</title>
 <mediaobject>
 <imageobject>
-<imagedata fileref="diagrams/mir-architecture-mirrored.eps" format="EPS"></imagedata></imageobject>
+<imagedata fileref="figures/mir-architecture-mirrored.eps" format="EPS"></imagedata></imageobject>
 <imageobject>
-<imagedata fileref="diagrams/mir-architecture-mirrored.png" format="PNG"></imagedata></imageobject>
+<imagedata fileref="figures/mir-architecture-mirrored.png" format="PNG"></imagedata></imageobject>
 <textobject>
 </textobject>
 </mediaobject>
@@ -47,7 +47,7 @@ site. Mirrors are simple to set up, since only static pages are involved
 
 <section><title>Concepts used by Mir</title>
 <para>Here's a list of important terms and concepts used by Mir. 
-Many of these concepts will be further detailed latter on in this guide.
+Many of these concepts will be further detailed later on in this guide.
 </para>
 <glossentry id="producers">
   <glossterm>producer</glossterm>
@@ -61,11 +61,11 @@ In many CMS systems, the available variables (data) are hard-coded into the
 software. In practice, this is often not flexible enough
 for web designers.
 Mir allows designers to request the data they need by using
-the producer framework, configured in the "producers.xml" file.
+the producer framework, configured in the <filename>producers.xml</filename> file.
 </para>
 <para>Originally producers were
 mostly used  to generate  pages, but  they are now used  for a  lot of
-other  tasks. In fact, the producers.xml file provides a 
+other  tasks. In fact, the <filename>producers.xml</filename> file provides a 
 simple, xml-based, programing (scripting) language, so that  
 site administrators can script their own custom tasks without
 changing the java code.
@@ -75,13 +75,15 @@ feeds  for the  global wire.
 <figure><title>An example of article generation with the producers framework</title>
 <mediaobject>
 <imageobject>
-<imagedata fileref="diagrams/article-generation-example.eps" format="EPS"></imagedata></imageobject>
+<imagedata fileref="figures/article-generation-example.eps" format="EPS"></imagedata></imageobject>
 <imageobject>
-<imagedata fileref="diagrams/article-generation-example.png" format="PNG"></imagedata></imageobject>
+<imagedata fileref="figures/article-generation-example.png" format="PNG"></imagedata></imageobject>
 <textobject>
 </textobject>
 </mediaobject>
 </figure>
+<para>In the  admin web interface,  producers appear, for  example, on
+the admin->"Generate manually"->"advanced page": (they are called Tasks)</para>
 <para>
 Further information on producers may be found at XXX and in the javadoc 
 (classes Producer, NodedProducer, roducerNode...).
@@ -90,14 +92,14 @@ Further information on producers may be found at XXX and in the javadoc
 </glossentry>
 
 <glossentry id="database">
-  <glossterm>database</glossterm>
+  <glossterm>database access</glossterm>
     <glossdef>
          <para>
 Mir uses a postgres database to store it's data. 
-Currently, the mir.storage, mircoders.storage, mir.entity, and 
-mir.entity.adapter 
+Currently, the <code>mir.storage</code>, <code>mircoders.storage</code>, 
+<code>mir.entity</code>, and <code>mir.entity.adapter</code>
 packages
-are used to acces  the database in Mir. However, these packages 
+are used to access  the database in Mir. However, these packages 
 are obsolete and will be replaced by the 
 <ulink url="http://www.hibernate.org">hibernate</ulink>
 object/relational persistence system. 
@@ -110,10 +112,26 @@ object/relational persistence system.
   <glossterm>localizer</glossterm>
     <glossdef>
          <para>
-FIXME localizers are to allow mir installations to add code seperate from the
-main code. A lot of things can be changed in an installation (and are
-by various mir sites). Think of custom open posting mechanism, open
-posting validation, data model enhancements. 
+Localizers provide a customization framework that allows
+different mir sites to behave differently. Each site can
+write it's own bits of java code that override default behavior.
+This is effectively
+used by various indymedia sites to customize things 
+such  open posting mechanisms, open
+posting validation, data model enhancements, etc.
+</para>
+<para>
+The <classname>MirLocalizer</classname> interface describes 
+the  centralized localizer, that may be accessed via the global 
+<function>MirGlobal.localizer()</function>
+function. The central localizer provides accessors to 
+domain specific localizers 
+(like <classname>MirBasicOpenPostingLocalizer</classname>).  
+</para>
+<para>
+Default behavior is provided by the <classname>MirBasicLocalizer</classname> 
+and it's associated classes. These classes can be extended to 
+override default behavior.
 </para>
        </glossdef>
 </glossentry>
@@ -137,10 +155,10 @@ sites) and velocity (not used at all but supported anyway).
   <glossterm>logger</glossterm>
     <glossdef>
          <para>
-Logging is understood here as "sytem logs" : information written
+Logging is understood here as "system logs" : information written
 out to files that may be used to track what is going on in Mir,
-especially errors and warnings. Mir uses the <ulink href="http://logging.apache.org/log4j/docs">log4j</ulink> logging system.
-This alows us to split logs into different files, making them
+especially errors and warnings. Mir uses the <ulink url="http://logging.apache.org/log4j/docs">log4j</ulink> logging system.
+This allows us to split logs into different files, making them
 easier to understand.
 </para>
        </glossdef>
@@ -150,7 +168,7 @@ easier to understand.
   <glossterm>mircoders packages</glossterm>
     <glossdef>
          <para>
-Originally, the mircoders packages were meant for local developpements,
+Originally, the mircoders packages were meant for local developments,
 as opposed to the core Mir code. This distinction is now obsolete
 and these packages will probably be reorganized in future releases.
 </para>
index 3a49c86..fef4591 100755 (executable)
@@ -1,9 +1,458 @@
 <chapter id="introduction">
-<title>Producers framework</title>
+<title>The producer framework</title>
+
+<section><title>How to use the <filename>producers.xml</filename> file</title>
+  [FIXME: this should be in the user's guide, not here]
+
+  <section><title>Introduction</title>
+  
+  <para>
+  With Mir, it is now possible to set up arbitrary producers using an xml file.
+  </para>
+  
+  <para>
+  Producers consist of "nodes". Every node has a specific function. 
+  For example, it is possible to use a node to generate a file out of a template. 
+  Or it is possible to use a node to enumerate over a collection of articles.
+  </para>
+
+  
+
+  <para>
+  A producer is defined using a Producer tag:
+  
+  <programlisting>    
+    &lt;producer name="content"/&gt;
+  </programlisting>
+  
+  would define a producer named <code>content</code>. 
+  
+  </para><para>
+  
+  In a producer, <emphasis>verbs</emphasis> must be defined. 
+  Verbs are sub-tasks of a producer.
+  
+  <programlisting>
+
+    &lt;producer name="content"&gt;
+      &lt;verbs&gt;
+        &lt;verb name="new"&gt;
+        &lt;/verb&gt;
+        &lt;verb name="all"&gt;
+        &lt;verb&gt;
+      &lt;/verbs&gt;
+    &lt;producer name="content"/&gt;  
+  </programlisting>    
+  
+  would define a producer with verbs named <code>all</code> and <code>new</code>.
+  
+  </para><para>
+  And also the specific nodes and their relationship should be specified:  
+  
+  <programlisting>
+
+    &lt;producer name="content"&gt;
+      &lt;verbs&gt;
+        &lt;verb name="new"&gt;
+        &lt;/verb&gt;
+        &lt;verb name="all"&gt;
+        &lt;verb&gt;
+      &lt;/verbs&gt;
+      &lt;body&gt;           
+        &lt;Generate 
+            generator="/producer/startpage.template" 
+            destination="${config.storageRoot}/index.shtml"/&gt;
+      &lt;/body&gt;  
+    &lt;/producer&gt;  
+  </programlisting>    
+  
+  we will later learn that this producer generates a single file.
+
+  </para><para>
+  Producers can be made to do different things for different verbs: 
+
+  <programlisting>
+
+    &lt;producer name="content"&gt;
+      &lt;verbs&gt;
+        &lt;verb name="new"&gt;
+          &lt;Set key="count" value="3"/&gt;
+        &lt;/verb&gt;
+        &lt;verb name="all"&gt;
+          &lt;Set key="count" value="5"/&gt;
+        &lt;verb&gt;
+      &lt;/verbs&gt;
+      &lt;body&gt;           
+        &lt;Generate 
+            generator="/producer/startpage.template" 
+            destination="${config.storageRoot}/index.shtml"/&gt;
+      &lt;/body&gt;  
+    &lt;/producer&gt;  
+  </programlisting>    
+  
+  if a producer is called with a specific verb, first the nodes of that verb
+  are processed, and only thereafter the body: in our case, if the producer
+  <code>content</code> is called with verb <code>new</code>, first the variable <code>count</code>
+
+  is set to <code>3</code>, and after that, a file is generated.
+  
+</para>  
+  </section>
+<section><title>Node arguments</title>
+  <para>
+  Nodes can have arguments. 
+  Arguments that amount to integer values can be direct expressions.
+  Arguments that amount to text values can be enriched with expressions between ${}.
+  
+  </para>
+  <para>
+  Some examples:
+  <programlisting>
+    &lt;Log message="This article has the following title: ${content.title}"/&gt;
+
+  </programlisting>    
+  <code>Log</code> has 1 mandatory argument, <code>message</code>. This argument should be text, 
+        but can be enriched with expressions enclosed by ${ and }. In this example,
+        the title of an article is logged.
+
+  <programlisting>
+    &lt;Set key="age" value="34+22*(3+2)"/&gt;
+  </programlisting>    
+  <code>Set</code> has 2 mandatory argument: <code>key</code> and <code>value</code>. 
+        The key arugment is a fixed text, 
+        the value argument is a direct expression, in this case of arithmetic nature.
+    
+  </para>
+
+  </section>
+<section><title>Expressions</title>
+
+  
+  <para>
+  Expressions, either direct expressions, or expressions between ${}, can contain the following
+  constructions:
+    </para>
+
+  <para>
+  <table border="1">
+    <tr><td>a string literal</td>       <td><code>'hello'</code></td></tr>
+    <tr><td>a numeric literal</td>      <td><code>2138</code></td></tr>
+
+    <tr><td>a variable reference</td>   <td><code>content.title</code></td></tr>
+    <tr><td>arithmetic operators</td>   <td><code> 3 + 4 *(2+5-2)</code></td></tr>
+    <tr><td>string operators</td>   <td><code> 'hello' ++ ' ' ++ 'Mir'</code></td></tr>
+
+    <tr><td>boolean operators</td>      <td><code>(content.id==3) or (content.id in (5,7,2,8) and (content.title!='hello')</code></td></tr>
+  </table>
+  
+  </para>
+  </section>
+<section><title>Node types and statements</title>
+    <para>
+    Here's  a list of different node types that can be used inside 
+  producer definitions. 
+Currently, there exists only one statement (&lt;nodedefinition&gt;), that
+is declared outside producer definitions.
+    
+
+    Here an overview:
+  
+    </para>
+    <table border="1">
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Set</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Alter a variable's using a free expression</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>key</td>                        <td>The variable</td></tr>
+
+      <tr><td>value</td>                      <td>The expression to set the variable to</td></tr>
+      <tr>
+        <td>Example</td>
+        <td>
+          <code>
+            &lt;Set key="data.result" value="3 + 5 * (5-2)"/&gt;
+
+          </code>
+        </td>
+      </tr>
+      
+      
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Define</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Alter a variable's using a string</td></tr>      
+      <tr><td colspan="2">
+
+              Arguments</td></tr>
+      <tr><td>key</td>                        <td>The variable</td></tr>
+      <tr><td>value</td>                      <td>The string to set the variable to</td></tr>
+      <tr>
+        <td>Example</td>
+
+        <td>
+          <code>
+            &lt;Define key="filename" value="/var/www/${content.id}.shtml"/&gt;
+          </code>
+        </td>
+      </tr>
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>If</code></td></tr>
+
+      <tr><td>Purpose</td>                    <td>Create a conditional part of a producer</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>condition</td>                  <td>The expression to test</td></tr>
+      <tr><td colspan="2">
+              Sub tags</td></tr>
+
+      <tr><td>then</td>                       <td>The part to process if the expression evaluates to true</td></tr>
+      <tr><td>else</td>                      <td>The part to process if the expression evaluates to false</td></tr>
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>nodedefinition</code>&nbsp;&nbsp;(statement)</td></tr>
+
+      <tr><td>Purpose</td>                    <td>Acts as a "function" (or "macro") that can be "called" elsewhere in a producer.
+More precisely, it is a way to define a new producer node type
+inside the  <filename>producers.xml</filename> file.
+(check the <code>Language</code> node in that file for an example).
+</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>name</td>                  <td>The name of the newly created node ("function")</td></tr>
+      <tr><td colspan="2">
+              Sub tags</td></tr>
+
+      <tr><td>parameters</td>                 <td>a list describing the arguments the "function" must be given </td></tr>
+      <tr><td>definition</td>                 <td>the actual body of the function, containing the code that should be executed. Note that this may contain a <code>&lt;sub/&gt;</code> tag that is replaced by the child nodes of the calling node (FIXME is this true???)  </td></tr>
+
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Log</code></td></tr>
+
+      <tr><td>Purpose</td>                    <td>Log a message in the producer log</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>message</td>                    <td>The message to log</td></tr>
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Enumerate</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Enumerate over the results of a query</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>key</td>                        <td>The variable name that receives the enumerated record</td></tr>
+
+      <tr><td>table</td>                      <td>The table that is used to enumerate over</td></tr>
+      <tr><td>selection (optional)</td>       <td>The condition (where clause) of the query.</td></tr>
+      <tr><td>order (optional)</td>           <td>The order in which the results of the query are enumerated.</td></tr>
+      <tr><td>skip (optional)</td>            <td>The number of records to skip</td></tr>
+
+      <tr><td>limit (optional)</td>           <td>The maximum number of records to enumerate</td></tr>
+      <tr><td colspan="2">
+              Sub tags</td></tr>
+      <tr><td colspan="2">
+              This node can have subnodes that will be processed for every enumerated record</td></tr>
+<!--
+      <tr>
+        <td>Remarks</td>
+        <td>
+        </td>
+      </tr>
+      <tr>
+        <td>Example</td>
+        <td>
+          <code>
+            &lt;Generate generator="/producer/content.template" destination="/var/www/${content.date.formatted.yyyy}/${content.date.formatted.MM}/${content.id}.shtml"/&gt;
+          </code>
+        </td>
+      </tr>
+ -->      
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>List</code></td></tr>
+
+      <tr><td>Purpose</td>                    <td>Store the results of a query into a variable</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>key</td>                        <td>The variable name that receives the result list</td></tr>
+      <tr><td>table</td>                      <td>The table that is used to select from</td></tr>
+
+      <tr><td>selection (optional)</td>       <td>The condition (where clause) of the query.</td></tr>
+      <tr><td>order (optional)</td>           <td>The order in which the results of the query are put into the list.</td></tr>
+      <tr><td>skip (optional)</td>            <td>The number of records to skip</td></tr>
+      <tr><td>limit (optional)</td>           <td>The maximum size of the list</td></tr>
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Batch</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Divide the results of a query into batches</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+
+      <tr><td>key</td>                        <td>The variable name that receives the batch</td></tr>
+      <tr><td>infokey</td>                    <td>The variable name that receives meta information on the batches</td></tr>
+      <tr><td>table</td>                      <td>The table that is used to select from</td></tr>
+      <tr><td>batchsize</td>                  <td>The size of a batch (the first batch however varies in size)</td></tr>
+
+      <tr><td>selection (optional)</td>       <td>The condition (where clause) of the query.</td></tr>
+      <tr><td>order (optional)</td>           <td>The order in which the results of the query are put into the list.</td></tr>
+      <tr><td>skip (optional)</td>            <td>The number of records to skip</td></tr>
+      <tr><td>process (optional)</td>         <td>The maximum number of batches to process</td></tr>
+
+      <tr><td>minbatchsize (optional)</td>    <td>The minimal size of the first batch</td></tr>
+      <tr><td colspan="2">
+              Sub tags</td></tr>
+      <tr><td>batches</td>                    <td>The part to process for every batch</td></tr>
+      <tr><td>batchlist</td>                  <td>The part to process once with the meta info</td></tr>
+
+
+
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Generate</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Generate a page using a generator (i.e. an abstraction of a template)</td></tr>
+      <tr><td colspan="2">
+
+              Arguments</td></tr>
+
+      <tr><td>generator</td>                  <td>the generator to use</td></tr>
+      <tr><td>destination</td>                <td>the specification of the destination.</td></tr>
+      <tr><td>parameters</td>                 <td>Additional configuration info for the generator (for
+                                                  freemarker this now only contains the wanted encoding,
+                                                  empty for the default).</td></tr>
+
+      <tr>
+        <td>Remarks</td>
+        <td>
+           This node is used to have an actual page generated. 
+           The generator parameter usually is the name of a template.
+           The destination is the file to be generated. 
+           Variable references are possible in all arguments, and, especially for the
+                 destination attribute, widely used.
+        </td>
+      </tr>
+      <tr>
+        <td>Example</td>
+
+        <td>
+          <code>
+            &lt;Generate generator="/producer/content.template" destination="/var/www/${content.date.formatted.yyyy}/${content.date.formatted.MM}/${content.id}.shtml"/&gt;
+          </code>
+        </td>
+      </tr>
+
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>DeleteFile</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Delete a file</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+      <tr><td>filename</td>                   <td>The filename of the file to delete</td></tr>
+
+
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>SetFileDate</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Set a file's date</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+
+      <tr><td>filename</td>                   <td>The filename</td></tr>
+      <tr><td>date</td>                       <td>The date to use</td></tr>
+      
+      
+      
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Resource</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Make a message resource bundle available</td></tr>      
+      <tr><td colspan="2">
+
+              Arguments</td></tr>
+      <tr><td>key</td>                        <td>The variable in which the bundle will be stored</td></tr>
+      <tr><td>bundle</td>                     <td>The bundle to use</td></tr>
+      <tr><td>language (optional)</td>        <td>The specific language to use</td></tr>
+
+
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>Execute</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Execute a script</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+
+      <tr><td>command</td>                    <td>The command to execute</td></tr>
+
+
+
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>ModifyContent</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Modify a field of an article</td></tr>      
+      <tr><td colspan="2">
+
+              Arguments</td></tr>
+      <tr><td>key</td>                        <td>The variable containing the article</td></tr>
+      <tr><td>field</td>                      <td>The field to modify</td></tr>
+      <tr><td>value</td>                      <td>The value to set the field to</td></tr>
+
+
+
+      <tr><td>Name</td>                       <td bgcolor="#eea8a8"><code>MarkContent</code></td></tr>
+      <tr><td>Purpose</td>                    <td>Mark an article as produced</td></tr>      
+      <tr><td colspan="2">
+              Arguments</td></tr>
+
+      <tr><td>key</td>                        <td>The variable containing the article</td></tr>
+
+
+
+    </table>
+</section>
+</section>
+
+<section><title>How the producer framework is implemented</title>
+
+<para>A Producer is a set of tasks, scripted in xml. Producers allow
+mir installations to have their own actions that can be called for
+instance when a new article is posted.  Originally producers were
+mostly used to generate pages, but they are used for a lot of
+other tasks such as pulling rss feeds for the global wire on
+indymedia.org. Producers are added and configured through the
+<filename>producers.xml</filename> file.</para>
+
+
+<para>The xml nodes contained within a <code>&lt;producer&gt;</code> 
+tag  in the <filename>producers.xml</filename> file define
+a small  program. 
+This program  (or script) may  contain constructs
+such as  <code>if</code> clauses, loops  and variables... The  program is parsed  into a
+tree  of ProducerNodes (figure).   The root  of this  tree is  defined  in a
+NodedProducer (which  is the  only class that  currently implements
+the  Producer  interface).   When  the Producer  is  executed,  the
+<function>produce</function> methods of each  node are recursively called, effectively
+executing the program as it was scripted. </para>
+
+<figure><title>A producer in the <filename>producer.xml</filename> file is parsed into a tree of <classname>ProducerNodes</classname></title>
+<mediaobject>
+<imageobject>
+<imagedata fileref="figures/producer-node-tree-example.eps" format="EPS"></imagedata></imageobject>
+<imageobject>
+<imagedata fileref="figures/producer-node-tree-example.png" format="PNG"></imagedata></imageobject>
+<textobject>
+</textobject>
+</mediaobject>
+</figure>
 
-<section><title>qsdqs</title>
 <para>
-sdfqsdf
 </para>
 </section>
 </chapter>