<?xml version="1.0" ?>
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         xmlns:doc="http://infrae.com/ns/silva_document"
         xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <start>
    <ref name="document" />
  </start>

  <define name="document">
    <element name="doc:doc">
      <zeroOrMore>
        <ref name="root" />
      </zeroOrMore>
    </element>
  </define>
  <!-- first I'll do the containment rules, then a list of individual elements,
        then the table element and last are the attributes -->

  <!-- toplevel elements allowed on root -->
  <define name="root">
    <choice>
      <ref name="toplevel" />
      <ref name="table" />
    </choice>
  </define>

  <!-- toplevel elements that can be located everywhere in the tree -->
  <define name="toplevel">
    <choice>
      <ref name="heading" />
      <ref name="p" />
      <ref name="pre" />
      <ref name="image" />
      <ref name="list" />
      <ref name="nlist" />
      <ref name="dlist" />
      <ref name="toc" />
      <ref name="codesource" />
    </choice>
  </define>

  <!-- inline markup -->
  <define name="markup">
    <choice>
      <ref name="em" />
      <ref name="strong" />
      <ref name="super" />
      <ref name="sub" />
      <ref name="underline" />
      <ref name="br" />
      <ref name="link" />
      <ref name="index" />
      <ref name="abbreviation" />
      <ref name="acronym" />
      <text />
    </choice>
  </define>

  <define name="textmarkup">
    <choice>
      <ref name="em" />
      <ref name="strong" />
      <ref name="super" />
      <ref name="sub" />
      <ref name="underline" />
      <ref name="br" />
      <text />
    </choice>
  </define>

  <define name="headingmarkup">
    <choice>
      <ref name="em-heading" />
      <ref name="super-heading" />
      <ref name="sub-heading" />
      <ref name="link-heading" />
      <ref name="index" />
      <text />
    </choice>
  </define>

  <define name="headingtextmarkup">
    <choice>
      <ref name="em-heading" />
      <ref name="super-heading" />
      <ref name="sub-heading" />
      <text />
    </choice>
  </define>
  
  <!-- individual elements -->
  
  <define name="heading">
    <element name="doc:heading">
      <attribute name="type">
        <choice>
          <value>normal</value>
          <value>sub</value>
          <value>subsub</value>
          <value>paragraph</value>
          <value>subparagraph</value>
        </choice>
      </attribute>
      <oneOrMore>
        <ref name="headingmarkup" />
      </oneOrMore>
    </element>
  </define>

  <define name="p">
    <element name="doc:p">
      <attribute name="type">
        <choice>
          <value>normal</value>
          <value>lead</value>
          <value>annotation</value>
        </choice>      
      </attribute>
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="pre">
    <element name="doc:pre">
      <oneOrMore>
        <text />
      </oneOrMore>
    </element>
  </define>

  <define name="image">
    <element name="doc:image">
      <attribute name="path">
        <text />
      </attribute>
      <attribute name="title">
        <text />
      </attribute>
      <attribute name="link_to_hires">
        <choice>
          <value>0</value>
          <value>1</value>
        </choice>
      </attribute>
      <optional>
        <attribute name="target">
          <text />
        </attribute>
      </optional>
      <optional>
        <attribute name="link">
          <text />
        </attribute>
      </optional>
      <optional>
        <attribute name="alignment">
          <choice>
            <value>float-left</value>
            <value>image-left</value>
            <value>none</value>
            <value>image-center</value>
            <value>float-right</value>
            <value>image-right</value>
          </choice>
        </attribute>
    </element>
  </define>

  <define name="list">
    <element name="doc:list">
      <attribute name="type">
        <choice>
          <value>disc</value>
          <value>square</value>
          <value>circle</value>
          <value>1</value>
          <value>I</value>
          <value>i</value>
          <value>A</value>
          <value>a</value>
          <value>none</value>
        </choice>
      </attribute>
      <oneOrMore>
        <ref name="listitem" />
      </oneOrMore>
    </element>
  </define>

  <define name="nlist">
    <element name="doc:nlist">
      <attribute name="type">
        <choice>
          <value>disc</value>
          <value>square</value>
          <value>circle</value>
          <value>1</value>
          <value>I</value>
          <value>i</value>
          <value>A</value>
          <value>a</value>
          <value>none</value>
        </choice>
      </attribute>
      <oneOrMore>
        <ref name="nlistitem" />
      </oneOrMore>
    </element>
  </define>

  <define name="dlist">
    <element name="doc:dlist">
      <attribute name="type">
        <choice>
          <value>normal</value>
          <value>compact</value>
        </choice>
      </attribute>
      <oneOrMore>
        <element name="doc:dt">
          <oneOrMore>
            <ref name="markup" />
          </oneOrMore>
        </element>
        <element name="doc:dd">
          <oneOrMore>
            <ref name="markup" />
          </oneOrMore>
        </element>
      </oneOrMore>
    </element>
  </define>

  <define name="toc">
    <element name="doc:toc">
      <attribute name="toc_depth">
        <text />
      </attribute>
      <optional>
        <ref name="rendered_html"/>
      </optional>
    </element>
  </define>

  <define name="codesource">
    <element name="doc:source">
      <attribute name="id">
        <text />
      </attribute>
      <zeroOrMore>
        <element name="parameter">
          <attribute name="key">
            <text />
          </attribute>
          <text />
        </element>
      </zeroOrMore>
      <optional>
        <ref name="rendered_html"/>
      </optional>
    </element>
  </define>

  <define name="external_data">
    <element name="doc:external_data">
      <ref name="someAttributes" />
    </element>
  </define>

  <define name="listitem">
    <element name="doc:li">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="nlistitem">
    <element name="doc:li">
      <oneOrMore>
        <ref name="toplevel" />
      </oneOrMore>
    </element>
  </define>

  <define name="em">
    <element name="doc:em">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>

  <define name="em-heading">
    <element name="doc:em">
      <oneOrMore>
        <ref name="headingmarkup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="strong">
    <element name="doc:strong">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="super">
    <element name="doc:super">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>

  <define name="super-heading">
    <element name="doc:super">
      <oneOrMore>
        <ref name="headingmarkup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="sub">
    <element name="doc:sub">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="sub-heading">
    <element name="doc:sub">
      <oneOrMore>
        <ref name="headingmarkup" />
      </oneOrMore>
    </element>
  </define>

  <define name="underline">
    <element name="doc:underline">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>

  <define name="link">
    <element name="doc:link">
      <attribute name="href">
        <text />
      </attribute>
      <optional>
        <attribute name="target">
          <text />
        </attribute>
      </optional>
      <oneOrMore>
        <ref name="textmarkup" />
      </oneOrMore>
    </element>
  </define>

  <define name="link-heading">
    <element name="doc:link">
      <attribute name="href">
        <text />
      </attribute>
      <optional>
        <attribute name="target">
          <text />
        </attribute>
      </optional>
      <oneOrMore>
        <ref name="headingtextmarkup" />
      </oneOrMore>
    </element>
  </define>
  
  <define name="index">
    <element name="doc:index">
      <attribute name="name">
        <text />
      </attribute>
    </element>
  </define>

  <define name="br">
    <element name="doc:br">
      <empty />
    </element>
  </define>

  <define name="abbreviation">
    <element name="doc:abbr">
      <optional>
      <attribute name="title">
        <text />
      </attribute>
      </optional>
      <oneOrMore>
        <ref name="textmarkup" />
      </oneOrMore>
    </element>
  </define>

  <define name="acronym">
    <element name="doc:acronym">
      <optional>
      <attribute name="title">
        <text />
      </attribute>
      </optional>
      <oneOrMore>
        <ref name="textmarkup" />
      </oneOrMore>
    </element>
  </define>

  <!-- table elements -->
  <define name="table">
    <element name="doc:table">
      <attribute name="columns">
        <text />
      </attribute>
      <attribute name="type">
        <text />
      </attribute>
      <attribute name="column_info">
        <text />
      </attribute>
      <oneOrMore>
        <choice>
          <ref name="tableheading" />
          <ref name="tablerow" />
        </choice>
      </oneOrMore>
    </element>
  </define>

  <define name="tableheading">
    <element name="doc:row_heading">
      <oneOrMore>
        <ref name="markup" />
      </oneOrMore>
    </element>
  </define>

  <define name="tablerow">
    <element name="doc:row">
      <oneOrMore>
        <element name="doc:field">
          <zeroOrMore>
            <ref name="toplevel" />
          </zeroOrMore>
        </element>
      </oneOrMore>
    </element>
  </define>

  <!-- define a general attribute rule, so we can skip the attrs for now... -->
  <define name="someAttributes">
    <zeroOrMore>
      <attribute>
        <anyName />
      </attribute>
    </zeroOrMore>
  </define>

  
  <define name="rendered_html">
    <element name="rendered_html">
      <!-- namespacing? -->
      <ref name="anything"/>
    </element>
  </define>

  <define name="anything">
    <zeroOrMore>
      <choice>
        <element>
          <anyName/>
          <ref name="anything"/>
        </element>
        <attribute>
          <anyName/>
        </attribute>
        <text/>
      </choice>
    </zeroOrMore>
  </define>
</grammar>

