latex support in org.ibex.util.Doc
authoradam <adam@megacz.com>
Mon, 22 Mar 2004 11:09:25 +0000 (11:09 +0000)
committeradam <adam@megacz.com>
Mon, 22 Mar 2004 11:09:25 +0000 (11:09 +0000)
darcs-hash:20040322110925-5007d-ea6ee29fab0bc72e585c22f803cd414726e0ec33.gz

Makefile
doc/reference.pdf [new file with mode: 0644]
doc/reference.xml
src/org/ibex/util/Doc.java [new file with mode: 0644]

index b549dc6..4229a71 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -378,3 +378,9 @@ propose-patch:
 
 commit: propose-patch
        darcs push --and-apply xwt@xwt.org:/var/www/org/ibex/core/
+
+reference: build/class/org/ibex/util/Doc.class doc/reference.xml
+       cd doc; java -cp ../build/class org.ibex.util.Doc < reference.xml > reference.tex
+       cd doc; pdflatex reference.tex
+       open doc/reference.pdf
+
diff --git a/doc/reference.pdf b/doc/reference.pdf
new file mode 100644 (file)
index 0000000..d03fad9
Binary files /dev/null and b/doc/reference.pdf differ
index 37b410d..e0365aa 100644 (file)
@@ -1,12 +1,15 @@
-<ibex-doc title="The Ibex Reference">
-    
-    Nitrogen Release
-    
-    by <link url="mailto:adam@ibex.org" text="Adam Megacz"/>
-    
+<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org">
+
 <!-- ----------------------------------------------------------------------- -->
 <section title="Preface">
     
+    <i>
+    If you are reading the html version of this document and are
+    thinking of printing it out, you might be interested in the nicely
+    typeset <link url="reference.pdf" text="pdf version"/> produced
+    with LaTeX.
+    </i>
+
     This document is a <b>reference</b>. It is not a
     <b>specification</b> or a
     <b>tutorial</b>.
@@ -22,7 +25,7 @@
     this is the right document to read. It is assumed that you are already
     familiar with XML and with either JavaScript or ECMAscript. If
     you are not familiar with ECMAscript, some reference materials are
-    provided in <link section="Appendix G"/>
+    provided in <link appendix="G"/>
     
     The <i>shoehorn sequence</i> (how the Ibex Core gets onto the
     client's computer, and how it knows where to download the initial .ibex
@@ -87,7 +90,7 @@
         We will use the terms JavaScript and ECMAScript
         interchangeably in this document.  The Ibex interpreter is not
         completely ECMA-compliant, however (see <link
-        section="Appendix C"/> for details).  </definition>
+        appendix="C"/> for details).  </definition>
     
     </section>
 
     "Object Representation"), and as an XML tag (the "XML
     Representation").
     
-    <font color=red>FIXME: diagram here</font>
+    FIXME: diagram here
     
     All three representations are equally valid, and being able to figure
     out what an action in one representation would mean in terms of the other
     
     Each box has two major visual components, each with subcomponents:
     
-    <font color=red>FIXME: diagram</font>
+    FIXME: diagram
     
-    <list type="unordered">
-
+    <list>
         A <b>path</b>, which consists of zero or more lines and
         curves.  The path may be filled with a color, gradient, or
         texture, and may be stroked with a line of a given thickness
         and color.  If the path is not specified, it defaults to the
         perimiter of the box.
 
+        <list>
             The path has an associated <b>strokecolor</b>, which is a
             color
             
         
             A single line of <b>text</b>, which can be rendered in
             different fonts, colors, and sizes.
+        </list>
 
         The text has an associated <b>font</b>, which currently can be
         any font supported by the <link url="http://www.freetype.org"
 
     The following description of the box application is extremely detailed
     and precise; it is intended for UI designers who need to know the
-    exact order in which each event happens.  <font color=RED>FIXME:
-    easier description</font>.  While this whole process sounds very
+    exact order in which each event happens.  FIXME:
+    easier description.  While this whole process sounds very
     complex, it actually works pretty intuitively. The description below
     is given in great detail since most applications will wind up being
     unintentionally dependent on subtle features of this process.
         order they appear in the document: For each <i>text
         segment</i> <b>t</b>:
 
+        <list>
             Treat <b>t</b> a JavaScript script, and execute it
             with <b>s</b> as the root scope.
+        </list>
 
         For each <i>child element</i> <b>x</b> of <b>X</b>:  
 
+        <list>
             Create a new box <b>b</b>.
             
-            If the name of tag <b>x</b> is not <tt>"box"</tt> (in the
+            If the name of tag <b>x</b> is not "<tt>box</tt>" (in the
             default XML namespace), prepend the tag's namespace
             identifier uri (if any) to the name of the tag, and use
             the result as a key to retrieve a property from the root
             of <b>x</b> into scope <b>s</b>.
             
             Append <b>b</b> as the last child of <b>B</b>.
+        </list>
         
         Apply any attributes on <b>X</b> to <b>B</b>, except for
         <tt>id</tt>.  Since XML specifies that the order of attributes
         cannot be significant, Ibex processes attributes in
         alphabetical order by attribute name.  For example, if
-        <b>X</b> has the attribute <tt>foo="bar"</tt>, then the
+        <b>X</b> has the attribute <tt>foo="bar</tt>", then the
         equivalent of the statement <tt>B.foo="bar";</tt> will be
         performed, with the following exceptions:
 
+        <list>
             If the value portion of the attribute is the string
-            <tt>"true"</tt>, put the boolean <tt>true</tt>. If the
-            value is <tt>"false"</tt>, put the boolean <tt>false</tt>.
+            "<tt>true</tt>", put the boolean <tt>true</tt>. If the
+            value is "<tt>false</tt>", put the boolean <tt>false</tt>.
         
             If the value is a valid ECMAscript number, put it as a
             number (instead of a string).
             attributes' namespace identifier uri (if any) and
             interpret the remainder as a property to be retrieved from
             the root stream (defined later).
+        </list>
     </list>
 
     The last two steps are referred to as the <i>initialization</i> of the
     properties of the user interface to change its appearance, thereby
     giving feedback to the user.
     
-    <font color="red">
+    
     DIAGRAM: graphic here showing the circular feedback cycle.
-    </font>
+    
     
     The Ibex core quits when the last remaining surface has been destroyed.
     
     
     <list type="unordered">
 
-        If the <tt>align</tt> property is <tt>"center"</tt>, then the
+        If the <tt>align</tt> property is "<tt>center</tt>", then the
         alignment point is the center of the box.
         
-        If the <tt>align</tt> property is <tt>"topleft"</tt>,
-        <tt>"bottomleft"</tt>, <tt>"topright"</tt>, or
-        <tt>"bottomright"</tt>, then the alignment point is
+        If the <tt>align</tt> property is "<tt>topleft</tt>",
+        "<tt>bottomleft</tt>", "<tt>topright</tt>", or
+        "<tt>bottomright</tt>", then the alignment point is
         corresponding corner of the box.
         
-        If the <tt>align</tt> property is <tt>"top"</tt>,
-        <tt>"bottom"</tt>, <tt>"right"</tt>, or <tt>"left"</tt>, then
+        If the <tt>align</tt> property is "<tt>top</tt>",
+        "<tt>bottom</tt>", "<tt>right</tt>", or "<tt>left</tt>", then
         the alignment point is middle of the corresponding edge of the
         box.
 
     </list>
 
-    <font color=red>FIXME: diagram</font>
+    FIXME: diagram
     
     When positioning a child box, the alignment point is determined by the
     <i>parent's</i> <tt>align</tt> property.  When positioning a visual
     placed in column zero regardless, but only occupies the available
     set of cells (it does not "hang off the end" of the box).
     
-    <img src="image/layout.png">
+    <img src="image/layout.png"/>
     
     <pre>
         <box cols="3">
         Each box's minimum width is computed recursively as the
         maximum of:
 
+        <list>
             Its <tt>minwidth</tt>
              
             The width of the box's <tt>text</tt> (after applying the
             <tt>transform</tt>) <i>if the box is <tt>packed</tt></i>.
              
             The width of the bounding box enclosing the box's cells.
-            </list>
+        </list>
         
         The minimum width of each cell is computed as the minimum
         width of the box occupying it divided by the box's
         the resulting cells are placed such that the cells' alignment
         point coincides with the parent's alignment point (both
         alignment points are determined by the parent's <tt>align</tt>
-        property).  <font color=red>FIXME: diagram</font>
+        property).  FIXME: diagram
     
         <b>Packed boxes:</b> Each packed box's actual position
         and size is then set to the aggregation of the actual sizes of
     
     <property name="text" type="string" default="&quot;&quot;">
             The box's text; writing <tt>null</tt> to this property sets it
-            to <tt>""</tt>.
+            to "<tt></tt>".
             </property>
     
-    <property name="font" type="stream" default="<tt>.ibex.font.sansserif</tt>">
+    <property name="font" type="stream" default=".ibex.font.sansserif">
             When an object is written to this property, its stream is read
             using the <link url="http://www.freetype.org" text="freetype2
             library"/>, and the resulting font is used to render the
             box's <tt>text</tt>.
             </property>
             
-    <property name="fontsize" type="number" default="<tt>10</tt>">
+    <property name="fontsize" type="number" default="10">
             The size (in points) to render the text.
             </property>
             
 
   <section title="Layout Properties">
     
-    <property name="shrink" type="boolean" default="<tt>false</tt>">
+    <property name="shrink" type="boolean" default="false">
         If set to <tt>true</tt>, this box will shrink
         (horizontally/vertically/both) to the smallest size allowed by
         its children and the bounding box of its path.
         </property>
     
-    <property name="x" type="integer" default="<i>varies</i>">
+    <property name="x" type="integer" default="varies">
         If the box is a root box, this is the (x/y)-coordinate of the
         surface; otherwise it is the distance between the parent's
         alignment point and this box's alignment point.
         </property>
     
-    <property name="globalx" type="integer" default="<i>varies</i>">
+    <property name="globalx" type="integer" default="varies">
         The distance between this box's (left/top) edge and the root
         box's (left/top) edge. A put to this property has the same
         effect as a put to the (<tt>x</tt>/<tt>y</tt>) property,
         except that it is relative to the root box rather than to this
-        box's parent. <font color=red>FIXME is this fakeable?  How is
-        distance measured?</font>
+        box's parent. FIXME is this fakeable?  How is
+        distance measured?
         </property>
     
-    <property name="minwidth" type="integer" default="<tt>0</tt>">
+    <property name="minwidth" type="integer" default="0">
         The desired minimum width and height.
         </property>
     
-    <property name="maxwidth" type="integer" default="<tt>ibex.maxint</tt>">
+    <property name="maxwidth" type="integer" default="ibex.maxint">
         The desired maximum width and height.
         </property>
     
-    <property name="width" type="integer" default="<i>varies</i>">
+    <property name="width" type="integer" default="varies">
         When read, this is the (width/height) of this box.  Writing to
         this property is equivalent to writing to <i>both</i> the
         minimum and maximum (width/height).
         </property>
     
-    <property name="cols" type="integer" default="<tt>0</tt>">
+    <property name="cols" type="integer" default="0">
         The number of (columns/rows) in which to lay out the children of this
         box.  If set to zero, the number of (columns/rows) is unconstrained.
         Either <tt>rows</tt> or <tt>cols</tt> must be zero.  If
         <tt>rows</tt> is set to <tt>0</tt>, and vice versa.
         </property>
     
-    <property name="colspan" type="integer" default="<tt>1</tt>">
+    <property name="colspan" type="integer" default="1">
         The number of (columns/rows) that this box spans within its parent.
         </property>
     
-    <property name="align" type="string" default="<tt>"center"</tt>">
+    <property name="align" type="string" default="center">
         Determines the box's alignment point for positioning its text,
         texture, path, and children.
         </property>
     
-    <property name="visible" type="boolean" default="<tt>true</tt>">
+    <property name="visible" type="boolean" default="true">
         If set to false, this box will be rendered as if its width and
         height were zero. If this is a root box, the associated surface
         will be hidden.
         read back <tt>false</tt>.
         </property>
     
-    <property name="packed" type="boolean" default="<tt>true</tt>">
+    <property name="packed" type="boolean" default="true">
          The layout strategy for this box.
         </property>
     
         enumerate <i>only</i> the box's children and not any other properties.
         </property>
     
-    <property name="clip" type="boolean" default="<tt>true</tt>">
+    <property name="clip" type="boolean" default="true">
         If <tt>true</tt>, the visual representation of this box's
         children will be clipped to the boundaries of this box.
         <b>Note:</b> setting this property to <tt>false</tt> imposes a
         substantial performance penalty.
         </property>
     
-    <property name="numchildren" type="integer" default="<tt>0</tt>">
+    <property name="numchildren" type="integer" default="0">
         The number of children this box has.
         </property>
     
-    <property name="redirect" type="box" default="<tt>thisbox</tt>">
+    <property name="redirect" type="box" default="thisbox">
         Writing to this property sets the box's redirect
         target. This property cannot be read from, and can only be
         written to once.
         </property>
     
-    <property name="surface" type="" default="<tt>null</tt>">
+    <property name="surface" type="" default="null">
         If this box has a parent, this property returns
         <tt><i>parent</i>.surface</tt>; otherwise it returns null.
         This property is a simple building block that the widget
 
   <section title="Other Box Properties">
     
-    <property name="cursor" type="string" default="<tt>null</tt>">
+    <property name="cursor" type="string" default="null">
         The shape that the cursor should take when inside this
-        box. Valid values are: <tt>"default"</tt>, <tt>"wait"</tt>,
-        <tt>"crosshair"</tt>, <tt>"text"</tt>, <tt>"hand"</tt>, and
-        <tt>"move"</tt>, as well as resizing cursors<tt>"east"</tt>,
-        <tt>"west"</tt>, <tt>"north"</tt>, <tt>"south"</tt>,
-        <tt>"northwest"</tt>, <tt>"northeast"</tt>,
-        <tt>"southwest"</tt>, and <tt>"southeast"</tt>. Note that on
+        box. Valid values are: "<tt>default </tt> " , "<tt>wait</tt>",
+        "<tt>crosshair</tt>", "<tt>text</tt>", "<tt>hand</tt>", and
+        "<tt>move</tt>", as well as resizing cursors"<tt>east</tt>",
+        "<tt>west</tt>", "<tt>north</tt>", "<tt>south</tt>",
+        "<tt>northwest</tt>", "<tt>northeast</tt>",
+        "<tt>southwest</tt>", and "<tt>southeast</tt>". Note that on
         some platforms, resize cursors for opposite directions (such
         as <tt>northwest</tt> and <tt>southeast</tt> are the
         same).
         If a box's cursor is <tt>null</tt>, its parent's cursor will
         be used. If the root box's cursor is null, the
-        <tt>"default"</tt> cursor will be used.
+        "<tt>default</tt>" cursor will be used.
         </property>
 
-    <property name="mouse.x" type="integer" default="<i>varies</i>">
+    <property name="mouse.x" type="integer" default="varies">
          The (horizontal/vertical) distance between the mouse cursor and this
          box's (left/top) edge. Puts to this property are ignored. This
          value will not be updated if the mouse is outside the root
          box of the surface and no button was pressed when it left.
         </property>
     
-    <property name="mouse.inside" type="boolean" default="<tt>false</tt>">
+    <property name="mouse.inside" type="boolean" default="false">
         True if the mouse is inside the rendered region of this box or
         any of its children. This value will be false if the mouse is
         inside a portion of this box which is covered up by one of
         in which the currently-executing code resides.
         </property>
        
-    <property name="thisbox" type="box" default="<tt> </tt>">
+    <property name="thisbox" type="box" default=" ">
        Returns a reference to the box itself.
        If <tt>null</tt> is written to this property, and this box is
        the root box of a surface, the box will be detached and the
        detached from its parent.
        </property>
     
-    <property name="indexof()" type="function" default="<tt> </tt>">
+    <property name="indexof()" type="function" default=" ">
         This property is actually a function; invoking
         <tt>parent.indexof(child)</tt> will return the numerical index
         of <tt>child</tt> in <tt>parent</tt> if <tt>child</tt> is a
         has no effect.
         </property>
 
-    <property name="childadded" type=" " default="<tt> </tt>">
+    <property name="childadded" type=" " default=" ">
 
-        These properties are meant to be trapped on <font
-        color=red>FIXME defined later?</font>. Placing a trap on
+        These properties are meant to be trapped on FIXME defined later?. Placing a trap on
         <tt>childadded/childremoved</tt> lets a box receive
         notification when a child is added/removed. In either
         situation, the child will be passed as an argument to the trap
     <property name="Close">
         When the user attempts to close a surface, the value
         <tt>true</tt> will be put to this property. Scripts may trap
-        this property <font color=red>FIXME defined later?</font> to
+        this property FIXME defined later? to
         prevent the window from closing. Putting the value
         <tt>true</tt> to this property on a root box has the same
         effect as putting <tt>null</tt> to the <tt>thisbox</tt>
     
     <pre>
       <!-- org/ibex/themes/monopoly/scrollbar.ibex -->
-      <ibex>
-          <static>
               foo = 12;
       ...
       // elsewhere
     
   <section title="General">
 
-    <table class="props">
-    <tr><td><tt>ibex.box</tt></td>                      <td>reading from this property returns a new box</td></tr>
-    <tr><td><tt>ibex.clone(o)</tt></td>                 <td>creates a clone of object <i>o</i></tr>
-    <tr><td><tt>ibex.bless(s)</tt></td>                 <td>returns a blessed clone of stream <i>s</i></tr>
-    </table>
+    <property name="ibex.box">
+        reading from this property returns a new box
+        </property>
+    <property name="ibex.clone(o)">
+        creates a clone of object
+        </property>
+    <property name="ibex.bless(s)">
+        returns a blessed clone of stream
+        </property>
 
     </section>
 
   <section title="ECMA Library Objects">
 
-    <table class="props">
-    <tr><td><tt>ibex.date</tt></td>                     <td>reading from this property returns a new date</td></tr>
-    <tr><td><tt>ibex.math</tt></td>                     <td>this object contains the ECMA math functions</td></tr>
-    <tr><td><tt>ibex.regexp(s)</tt></td>                <td>return a regexp object corresponding to string <i>s</i></td></tr>
-    <tr><td><tt>ibex.string</tt></td>                   <td>this object contains the ECMA string manipulation functions</td></tr>
-    </table>
+    <property name="ibex.date">
+        reading from this property returns a new date
+        </property>
+    <property name="ibex.math">
+        this object contains the ECMA math functions
+        </property>
+    <property name="ibex.regexp(s)">
+        return a regexp object corresponding to string <i>s</i>
+        </property>
+    <property name="ibex.string">
+        this object contains the ECMA string manipulation functions
+        </property>
 
     </section>
 
   <section title="Networking">
 
     <property name="ibex.net.http">
-        <font color=red><i>not yet implemented</font>
+        not yet implemented
         </property>
 
     <property name="ibex.net.rpc.xml(u)">
         </property>
 
     <property name="ibex.stream.parse.utf8(s)">
+        treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string
         </property>
-        treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string</tr>
 
     <property name="ibex.stream.homedir">
         <tt>ibex.stream.tempdir</tt>
   <section title="Cryptography">
 
     <property name="ibex.crypto.rsa(k,s)">
-        <i><font color=red>not implemented yet:</font></i> return a
+        <i>not implemented yet:</i> return a
         stream which rsa-decrypts stream <i>s</i> with key <i>k</i>
         </property>
 
     <property name="ibex.crypto.rc4(k,s)">
-        <i><font color=red>not implemented yet:</font></i> return a
+        <i>not implemented yet:</i> return a
         stream which rc4-decrypts stream <i>s</i> with key <i>k</i>
         </property>
 
     <property name="ibex.crypto.md5(s)">
-        <i><font color=red>not implemented yet:</font></i> immediately
+        <i>not implemented yet:</i> immediately
         MD5-hash stream <i>s</i>
         </property>
 
     <property name="ibex.crypto.sha1(s)">
-        <i><font color=red>not implemented yet:</font></i> immediately
+        <i>not implemented yet:</i> immediately
         SHA1-hash stream <i>s</i>
         </property>
 
         </box>
     </pre>
 
-    If another script were to set the property <tt>"foo"</tt>
+    If another script were to set the property "<tt>foo</tt>"
     on the box above to the value <tt>5</tt>, the function above would be
     invoked with the argument <tt>5</tt>. The function would then log
-    the string <tt>"foo is 5"</tt>.
+    the string "<tt>foo is 5</tt>".
     
     Within a trap, the expression <tt>trapee</tt> can be used to
     get a reference to the box on which the trap was placed.
     <link section="Box Layout Properties"/>, <link
     section="Child-Control Properties"/>, or <link section="Other Box
     Properties"/> except for <tt>childadded</tt>,
-    <tt>childremoved</tt> and <tt>surface</tt>.  <font
-    color=red>FIXME: remove?</font>
+    <tt>childremoved</tt> and <tt>surface</tt>.  FIXME: remove?
     
     </section>
 
     exception, but will <i>not</i> propagate it to the code which
     triggered the trap. If the trap was a read trap, the value
     <tt>null</tt> will be returned.
-    <font color=red>FIXME: is this right?</font>
-    
+    FIXME: is this right?
     </section>
 
   <section title="Architectural Significance of Traps">
     event/demand driven, traps eliminate the need for separate
     member/getter/setter declarations, often cutting the amount of typing
     you have to do to a third of what it would normally be.
-    
     </section>
 
   <section title="Cloning">
 
-    <I>Cloning</i> is a companion technique for traps; together they can
+    <i>Cloning</i> is a companion technique for traps; together they can
     be used to simulate any sort of environment you might need.  When you
     call <tt>ibex.clone(o)</tt>, Ibex returns a new object (called the
     <i>clone</i>) which compares with equality (<tt>==</tt>) to the
         This ensures that Ibex can automatically add filename
         extensions where needed, according to the following rules:
 
+        <list>
             If the stream is a template to be applied, the string
-            <tt>".ibex"</tt> is appended.
+            "<tt>.ibex</tt>" is appended.
         
-            If the stream is an image, the string <tt>".png"</tt> is
-            appended.  If no stream is found, <tt>".jpeg"</tt> and
-            <tt>".gif"</tt> are tried, in that order.
+            If the stream is an image, the string "<tt>.png</tt>" is
+            appended.  If no stream is found, "<tt>.jpeg</tt>" and
+            "<tt>.gif</tt>" are tried, in that order.
         
-            If the stream is an font, the string <tt>".ttf"</tt> is
+            If the stream is an font, the string "<tt>.ttf</tt>" is
             appended.
+        </list>
         
         Every call to <tt>ibex.bless()</tt> returns a different object
         (which happens to be a clone of the object passed to it) with
     
     <list type="unordered">
 
-        <b>Rendering Context</b> (redrawing the screen)
+        <b>Rendering Context</b> -- (redrawing the screen)
         
         <b>Event Context</b> (executing javascript traps triggered by an event)
         
     </section>
 
   </section>
+
 <!-- ----------------------------------------------------------------------- -->
 <section title="Networking">
     
   <section title="XML-RPC">
     
-    XML-RPC objects can be created by calling <tt>ibex.net.rpc.xml(<<i>XML-RPC
-    URL</i>>)</tt>, and then invoking methods on that object. For example,
+    XML-RPC objects can be created by calling <tt>ibex.net.rpc.xml(<i>XML-RPC
+    URL</i>)</tt>, and then invoking methods on that object. For example,
     
     <pre>
         Press1 += function(v) {
     contact the server <tt>xmlrpc.ibex.org</tt>, route to the
     <tt>/RPC2/</tt> handler and invoke the <tt>getTodaysColor()</tt>
     method on the <tt>color</tt> object with a single string argument
-    <tt>"Friday"</tt>. The return value will be used to change the color
+    "<tt>Friday</tt>". The return value will be used to change the color
     of the box the user clicked on.
     
     Note that in this example we spawned a background thread to handle the
     this string having any special structure or significance.
     
     If an object with an associated non-empty stream is passed as an
-    argument to an XML-RPC method, it will be sent as a <base64>
-    element. If a <base64> element is found in the XML-RPC reply, it
+    argument to an XML-RPC method, it will be sent as a <base64/>
+    element. If a <base64/> element is found in the XML-RPC reply, it
     will be returned as an object with a stream drawn from that byte sequence.
     
     Each object returned by <tt>ibex.net.rpc.xml()</tt> represents a
     authentication if the server supports it; otherwise it will use
     Basic authentication.  Please be aware that many XML-RPC server
     implementations contain a <link
-    url="http://www.ibex.org/faq.html#auth" text="broken implementation
-    of Basic authentication"/>.
+    url="http://www.ibex.org/faq.html#auth" text="broken implementation of Basic authentication"/>.
     
     </section>
 
         </property>
     <property name="ibex.net.security.prohibitedHost">
         A piece of untrusted Ibex code attempted to contact a
-        restricted host.  See Appendix A for details.
+        restricted host.  See <ref appendix="Security Architecture and Considerations"/> for details.
         </property>
     <property name="ibex.net.dns.temporaryFailure">
         An attempt to resolve a hostname failed but it is not known
     <property name="ibex.null.call">
         A JavaScript attempted to call the <tt>null</tt> value
         </property>
-    </table>
     
     If an exception is thrown inside a trap, the exception will propagate
     to the script that triggered the trap.
   </section>
 
 <!-- ----------------------------------------------------------------------- -->
-<section title="A: Security Architecture and Considerations">
+<appendix title="Security Architecture and Considerations">
     
     Due to the expense and hassle imposed by the commercial PKI code
     signing architecture, and the fact that it <link
     is using a proxy which performs DNS lookups), Ibex will provide the
     proxy with the appropriate <link
     url="http://www.ibex.org/x-requestorigin.html"
-    text=""/>X-RequestOrigin</tt></a> header that the proxy needs in order
+    text="X-RequestOrigin"/> header that the proxy needs in order
     to maintain security.
     
     The only remaining possible attack is against a XML-RPC or SOAP
     
     </section>
 
-  </section>
+  </appendix>
 
 <!-- ----------------------------------------------------------------------- -->
-<section title="B: ECMAscript compliance">
+<appendix title="ECMAscript compliance">
     
     Ibex's scripts are written in a modified subset of ECMA-262, revision 3
     (aka JavaScript 1.5). The interpreter strays from the spec in a few
     
     </section>
 
+  </appendix>
+
   <section title="Extensions">
     
     <list type="unordered">
         Is equivalent to:
         <pre>
         } catch(e) {
-           if (e.propname != null &amp;&amp; e.propname >= "foo.bar.baz" &amp;&amp; e.propname < "foo.bar.baz/") {
+           if (e.propname != null &amp;&amp; e.propname >= "foo.bar.baz" &amp;&amp; e.propname &lt; "foo.bar.baz/") {
                // ...
            }
         }
         if it does appear, it must be the last one.
     
         Since Ibex ECMAscripts are wrapped in XML, the lexical token
-        "<tt>lt</tt>" is be interpreted as <tt><</tt>, the lexical
-        token "<tt>gt</tt>" is be interpreted as <tt>></tt>, and the
+        "<tt>lt</tt>" is be interpreted as <tt>&lt;</tt>, the lexical
+        token "<tt>gt</tt>" is be interpreted as <tt>&gt;</tt>, and the
         token "<tt>and</tt>" is interpreted as <tt>&amp;&amp;</tt>.
         Thus these tokens cannot be used as variable names.
     
         technical document.
 
     </list>
-    
     </section>
 
-  </section>
-
 <!-- ----------------------------------------------------------------------- -->
-<section title="C: Logging and Command Line Invocation">
+<appendix title="Logging and Command Line Invocation">
     
     Very early in the loading process, Ibex begins logging messages about
     what it is doing.  Where this output is logged to differs by platform;
     cause it to log <i>lots</i> of information to the log file. This
     option will also substantially decrease Ibex's performance.
     
-  </section>
+  </appendix>
 
 <!-- ----------------------------------------------------------------------- -->
     <!--
-<section title="E: Grammars">
+<appendix title="Grammars">
 
-    <font color=red><i>Grammar support is experimental in this release
+    <i>Grammar support is experimental in this release
     and may not work properly.  It may change in incompatible ways or
-    disappear completely from future releases</i></font>
+    disappear completely from future releases</i>
     
     Grammars are defined with a statement in the following form:
     
          
        The identifier 'whole' is bound to the string matched by the
        entire expression.  If the code block is omitted it behaves
-       as if it were <tt>"{ return whole; }"</tt>.
+       as if it were "<tt>{ return whole; }</tt>".
          
        For every reference to another grammar which was matched in the
        pattern, the *name used to reference that other grammar* will
diff --git a/src/org/ibex/util/Doc.java b/src/org/ibex/util/Doc.java
new file mode 100644 (file)
index 0000000..f2780b0
--- /dev/null
@@ -0,0 +1,226 @@
+package org.ibex.util;
+import java.util.*;
+import java.io.*;
+import org.ibex.util.*;
+
+public class Doc extends XML {
+    public static void main(String[] s) throws Exception {
+        Doc d = new Doc();
+        d.parse(new InputStreamReader(System.in));
+        ((Node)d.nodeStack.elementAt(0)).dumpLatex(System.out);
+        System.out.println("\\end{document}");
+    }
+    
+    Vec top = new Vec();
+    Vec nodeStack = new Vec();
+    public Doc() { nodeStack.addElement(new Node()); }
+
+    public void startElement(Element e) throws Exn {
+        String name = e.getLocalName();
+        if (nodeStack.lastElement() != null && (nodeStack.lastElement() instanceof PRE)) {
+            ((PRE)nodeStack.lastElement()).addText("<" + e.getQName() + ">");
+            buffer++;
+            return;
+        }
+        if (name.equals("ibex-doc")) {
+            String title = "You forgot the title, you idiot!";
+            String author = "Your Mom";
+            String email = null;
+            String subtitle = null;
+            for(int i=0; i<e.getAttrLen(); i++) {
+                if (e.getAttrKey(i).equals("title")) title = e.getAttrVal(i); 
+                if (e.getAttrKey(i).equals("author")) author = e.getAttrVal(i);
+                if (e.getAttrKey(i).equals("email")) email = e.getAttrVal(i);
+                if (e.getAttrKey(i).equals("subtitle")) subtitle = e.getAttrVal(i);
+            }
+            System.out.println("\\documentclass{article}");
+            System.out.println("\\def\\ninept{\\def\\baselinestretch{.95}\\let\\normalsize\\small\\normalsize}");
+            System.out.println("\\ninept");
+            System.out.println("\\usepackage{graphicx}");
+            System.out.println("\\usepackage{amssymb,amsmath,epsfig,alltt}");
+            System.out.println("\\sloppy");
+            System.out.println("\\usepackage{palatino}");
+            System.out.println("\\usepackage{sectsty}");
+            System.out.println("\\allsectionsfont{\\sffamily}");
+            System.out.println("\\sectionfont{\\pagebreak\\leftskip=-2cm\\hrulefill\\\\\\sffamily\\bfseries\\raggedleft\\vspace{1cm}}");
+            System.out.println("\\subsectionfont{\\dotfill\\\\\\sffamily\\raggedright\\hspace{-4cm}}");
+            System.out.println("\\newdimen\\sectskip");
+            System.out.println("\\newdimen\\subsectskip");
+            System.out.println("\\newdimen\\saveskip");
+            System.out.println("\\saveskip=\\leftskip");
+            System.out.println("\\sectskip=-2cm");
+            System.out.println("\\subsectskip=0cm");
+            System.out.println("\\let\\oldsection\\section");
+            System.out.println("\\let\\oldsubsection\\subsection");
+            System.out.println("\\def\\subsection#1{\\leftskip=\\sectskip\\oldsubsection{#1}\\leftskip=0cm}");
+            System.out.println("\\usepackage{parskip}");
+            System.out.println("\\usepackage{tabularx}");
+            System.out.println("\\usepackage{alltt}");
+            System.out.println("\\usepackage[pdftex,bookmarks=true]{hyperref}");
+            System.out.println("");
+            System.out.println("\\begin{document}");
+            System.out.println("");
+            System.out.println("\\title{\\textbf{\\textsf{");
+            System.out.println(title);
+            if (subtitle != null) System.out.println("\\\\{\\large " + subtitle + "}");
+            System.out.println("}}}");
+            if (author != null) {
+                System.out.println("\\author{");
+                System.out.println(author);
+                if (email != null) System.out.println("\\\\{\\tt " + email + "}");
+                System.out.println("}");
+            }
+            System.out.println("");
+            System.out.println("\\maketitle");
+            System.out.println("\\clearpage");
+            System.out.println("\\tableofcontents");
+            System.out.println("\\clearpage");
+            System.out.println("\\onecolumn");
+            nodeStack.addElement(new Node());
+        } else if (name.equals("section") || name.equals("appendix")) {
+            String secname = "unknown";
+            for(int i=0; i<e.getAttrLen(); i++) if (e.getAttrKey(i).equals("title")) secname = e.getAttrVal(i);
+            nodeStack.addElement(new Section(secname, name.equals("appendix")));
+        } else if (name.equals("b")) {       nodeStack.addElement(new B());
+        } else if (name.equals("i")) {       nodeStack.addElement(new I());
+        } else if (name.equals("tt")) {      nodeStack.addElement(new TT());
+        } else if (name.equals("list")) {    nodeStack.addElement(new List());
+        } else if (name.equals("pre")) {     nodeStack.addElement(new PRE());
+        } else if (name.equals("ref")) { buffer++;
+        } else if (name.equals("link")) {
+            buffer++;
+            for(int i=0; i<e.getAttrLen(); i++) if (e.getAttrKey(i).equals("text")) addText(e.getAttrVal(i));
+        } else if (name.equals("definition")) { buffer++;
+        } else if (name.equals("property")) { buffer++;
+        } else { System.err.println("warning: unknown tag " + name);
+        buffer++;
+        }
+    }
+    
+    int buffer = 0;
+    String pending = "";
+    public void whitespace(char[] ch, int start, int length) throws Exn, IOException { characters(ch, start, length); }
+    void addText(String s) { ((Node)nodeStack.lastElement()).addText(s); }
+    public void endElement(Element e) throws Exn, IOException {
+        if (buffer > 0) {
+            buffer--;
+            if (nodeStack.lastElement() instanceof PRE)
+                ((PRE)nodeStack.lastElement()).addText("</" + e.getLocalName() + ">");
+        } else {
+            nodeStack.setSize(nodeStack.size() - 1);
+        }
+    }
+    public void characters(char[] ch, int start, int length) throws Exn, IOException {
+        Node n = ((Node)nodeStack.lastElement());
+        if (n != null) n.addText(new String(ch, start, length));
+    }
+
+    boolean intt = false;
+    class Node {
+        Vec children = new Vec();
+        final Node parent;
+        public Node() { this((Node)nodeStack.lastElement()); }
+        public Node(Node parent) { this.parent = parent; if (parent != null) parent.add(this); }
+        public void add(Node child) { children.addElement(child); }
+        public void addText(String s) { children.addElement(s); }
+        void printText(PrintStream p, String mt2) { p.print(fix(mt2)); }
+        String fix(String mt2) {
+            mt2 = mt2.replaceAll("\\\\", "\\backslash ");
+            mt2 = mt2.replaceAll("LaTeX", "\\LaTeX");
+            mt2 = mt2.replaceAll("\\$", "\\\\\\$ ");
+            mt2 = mt2.replaceAll("\\%", "\\\\% ");
+            mt2 = mt2.replaceAll("#", "\\\\# ");
+            mt2 = mt2.replaceAll("\\{", "\\\\{ ");
+            mt2 = mt2.replaceAll("\\}", "\\\\} ");
+            mt2 = mt2.replaceAll("\\&", "\\\\& ");
+            mt2 = mt2.replaceAll("\\~", "\\\\~ ");
+            mt2 = mt2.replaceAll("_", "\\\\_");
+            if (!intt) {
+                mt2 = mt2.replaceAll("\" ", "'' ");
+                mt2 = mt2.replaceAll("\"\n", "''\n");
+            }
+            mt2 = mt2.replaceAll(" \"", " ``");
+            mt2 = mt2.replaceAll("\"", "``");
+            return mt2;
+        }
+        public void dumpLatex(PrintStream p) {
+            for(int i=0; i<children.size(); i++) {
+                if (children.elementAt(i) instanceof String) {
+                    printText(p, (String)children.elementAt(i));
+                } else {
+                    ((Node)children.elementAt(i)).dumpLatex(p);
+                }
+            }
+        }
+    }
+
+    class PRE extends Node {
+        String myText = "";
+        public void addText(String s) { myText += s; }
+        public void dumpLatex(PrintStream p) {
+            p.println("\n\\begin{verbatim}\n");
+            p.print(myText);
+            p.println("\n\\end{verbatim}\n");
+        }
+    }
+
+    class I extends Node { public void dumpLatex(PrintStream p) { p.print("{\\it "); super.dumpLatex(p); p.print("}"); } }
+    class B extends Node { public void dumpLatex(PrintStream p) { p.print("{\\bf "); super.dumpLatex(p); p.print("}"); } }
+    class TT extends Node { public void dumpLatex(PrintStream p) {
+        p.print("{\\tt ");
+        intt = true;
+        super.dumpLatex(p);
+        intt = false;
+        p.print("}"); } }
+
+    class Section extends Node {
+        String secname;
+        boolean appendix = false;
+        public Section(String secname, boolean appendix) { this.secname = secname; this.appendix = appendix;}
+        public void dumpLatex(PrintStream p) {
+            String secs = "";
+            for(Node n = parent; n != null; n = n.parent) if (n instanceof Section) secs += "sub";
+            if (appendix) {
+                p.println("\n\n\\appendix{"+secname+"}\n");
+            } else {
+                p.println("\n\n\\" + secs + "section{"+secname+"}\n");
+            }
+            super.dumpLatex(p);
+        }
+    }
+
+    class List extends Node {
+        boolean ordered = false;
+        public void dumpLatex(PrintStream p) {
+            p.println("\n\\begin{itemize}%\n");
+            String acc = "";
+            p.print("\n\\item%\n");
+            boolean used = false;
+            for(int i=0; i<children.size(); i++) {
+                if (children.elementAt(i) instanceof String) {
+                    acc += fix(children.elementAt(i).toString());
+                } else {
+                    if (acc.length() > 0) {
+                        if (!used) acc = acc.replaceAll("^\\s*", "");
+                        if (children.elementAt(i) instanceof List) acc = acc.replaceAll("\\n\\s*$", "");
+                        acc = acc.replaceAll("\\n\\s*\\n", "\n\n\\\\item ");
+                        if (acc.trim().length() > 0) {
+                            used = true;
+                            p.print(acc);
+                        }
+                        acc = "";
+                    }
+                    ((Node)children.elementAt(i)).dumpLatex(p);
+                }
+            }
+            if (acc.length() > 0) {
+                if (!used) acc = acc.replaceAll("^\\s*", "");
+                acc = acc.replaceAll("\\n\\s*$", "");
+                p.print(acc.replaceAll("\\n\\s*\\n", "\n\n\\\\item "));
+                acc = "";
+            }
+            p.println("\n\\end{itemize}%\n");
+        }
+    }
+
+}