<?xml version="1.0" encoding="utf-8" ?>

<!--
  Copyright (c) 1997-2018
  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
  http://www.polymake.org

  This program is free software; you can redistribute it and/or modify it
  under the terms of the GNU General Public License as published by the
  Free Software Foundation; either version 2, or (at your option) any
  later version: http://www.gnu.org/licenses/gpl.txt.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
===============================================================================

  Relax-NG Schema for polymake v3 automatic documentation files
-->

<grammar xmlns="http://relaxng.org/ns/structure/1.0"
         datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
         ns="http://www.polymake.org/ns/docs#3">

  <start>
    <choice>
      <ref name="Application" />
      <ref name="Version" />
      <ref name="ApplicationList" />
      <ref name="Applications" />
    </choice>
  </start>

  <define name="ApplicationList">
    <element name="applications">
    	<oneOrMore>
    	  <element name="file">
    	    <attribute name="name" />
    	  </element>
    	</oneOrMore>
    </element>
  </define>

  <define name="Applications">
    <element name="polymake_apps">
    	<zeroOrMore>
    		<ref name="Extension" />
    	</zeroOrMore>
      <zeroOrMore>
			<ref name="Application" />
      </zeroOrMore>
    </element>
  </define>

  <define name="Extension">
    <element name="extension">
    	<element name="URI">
    	  <text />
    	</element>
    	<optional>
    	  <element name="name">
    	    <text />
    	  </element>
    	</optional>
    	<optional>
    	  <element name="text">
    	    <text />
    	  </element>
    	</optional>
    	<element name="file">
    		<text />
    	</element>
    </element>
  </define>

  <define name="Application">
    <element name="application">
      <ref name="NameAttr" />

		<optional>
			<attribute name="ext" />
			<attribute name="ext_name" />
		</optional>
		<optional>
	      <ref name="Description" />
		</optional>
		
      <optional>
        <element name="imports-from">
          <ref name="AppList" />
        </element>
      </optional>

      <optional>
        <element name="uses">
          <ref name="AppList" />
        </element>
      </optional>

      <optional>
        <element name="property-types">
          <ref name="PropertyTypes" />
        </element>
      </optional>

      <optional>
        <element name="common-option-lists">
          <ref name="CommonOptionLists" />
        </element>
      </optional>

      <optional>
        <element name="objects">
          <ref name="Objects" />
        </element>
      </optional>

      <optional>
        <element name="user-functions">
          <ref name="FuncList" />
        </element>
      </optional>

    </element>
  </define>

  <define name="AppList">
    <oneOrMore>
      <element name="application">
        <ref name="NameAttr" />
      </element>
    </oneOrMore>
  </define>

  <define name="UserMethods">
    <element name="user-methods">
      <ref name="FuncList" />
    </element>
  </define>

  <define name="FuncList">
    <zeroOrMore>
      <element name="category">
        <attribute name="name" />
        <ref name="Id" />
        <optional>
          <ref name="Description" />
        </optional>
        <zeroOrMore>
          <ref name="Function" />
        </zeroOrMore>
      </element>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="Function" />
    </zeroOrMore>
  </define>

  <define name="Function">
    <element name="function">
      <ref name="NameAttr" />
      <ref name="Id" />
      <zeroOrMore>
        <element name="tparam">
          <attribute name="name" />
	  			<optional>
	  			  <ref name="Description" />
	  			</optional>
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <element name="param">
          <attribute name="name" />
	  <attribute name="type" />
          <attribute name="href" />
          <optional>
	    <attribute name="class" />
          </optional>
          <optional>
            <ref name="Description" />
          </optional>
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <choice>
          <ref name="Option" />
          <element name="options">
            <ref name="Description" />
            <oneOrMore>
              <ref name="Option" />
            </oneOrMore>
          </element>
          <ref name="CommonOptionListRef" />
        </choice>
      </zeroOrMore>
      <optional>
        <element name="return">
          <attribute name="type" />
          <attribute name="href" />
          <optional>
	    <attribute name="class" />
          </optional>
          <optional>
	    <ref name="Description" />
          </optional>
        </element>
      </optional>
      <optional>
        <element name="author">
          <attribute name="name" />
        </element>
      </optional>
      <optional>
        <element name="depends">
          <attribute name="name" />
        </element>
      </optional>
      <optional>
        <ref name="Examples" />
      </optional>
      <optional>
      	<element name="only">
      		<attribute name="name" />
      		<attribute name="href" />
      		<attribute name="class" />
      	</element>
      </optional>
      <optional>
        <ref name="Description" />
      </optional>
    </element>
  </define>

  <define name="PropertyTypes">
    <zeroOrMore>
      <element name="category">
        <attribute name="name" />
        <ref name="Id" />
        <optional>
          <ref name="Description" />
        </optional>
        <oneOrMore>
          <ref name="PropertyType" />
        </oneOrMore>
      </element>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="PropertyType" />
    </zeroOrMore>
  </define>

  <define name="PropertyType">
    <element name="property-type">
      <ref name="NameAttr" />
      <ref name="Id" />

      <zeroOrMore>
        <element name="tparam">
          <attribute name="name" />
	  		 <optional>
	  		   <ref name="Description" />
	  		 </optional>
        </element>
      </zeroOrMore>

     <ref name="Description" />

      <optional>
        <element name="derived-from">
          <attribute name="type" />
          <attribute name="href" />
        </element>
      </optional>

      <optional>
        <ref name="UserMethods" />
      </optional>
    </element>
  </define>

  <define name="Properties">
    <element name="properties">
      <zeroOrMore>
        <element name="category">
          <attribute name="name" />
          <ref name="Id" />
          <optional>
            <ref name="Description" />
          </optional>
          <oneOrMore>
            <ref name="Property" />
          </oneOrMore>
        </element>
      </zeroOrMore>
      <zeroOrMore>
        <ref name="Property" />
      </zeroOrMore>
    </element>
  </define>

  <define name="Permutations">
    <element name="permutations">
      <zeroOrMore>
        <element name="permutation">
          <ref name="NameAttr" />
          <ref name="Id" />
          <ref name="Description" />

          <optional>
            <ref name="Properties" />
          </optional>
          <optional>
            <ref name="UserMethods" />
          </optional>
        </element>
      </zeroOrMore>
    </element>
  </define>

  <define name="Property">
    <element name="property">
      <ref name="NameAttr" />
      <ref name="Id" />
      <attribute name="type" />
      <attribute name="href" />
      <optional>
        	<attribute name="class" />
      </optional>
      <optional>
      	<element name="only">
      		<attribute name="name" />
      		<attribute name="href" />
      		<attribute name="class" />
      	</element>
      </optional>
      <ref name="Description" />

      <optional>
        <element name="depends">
          <attribute name="name" />
        </element>
      </optional>

      <optional>
        <ref name="Examples" />
      </optional>

      <optional>
        <ref name="Properties" />
      </optional>
      <optional>
        <ref name="UserMethods" />
      </optional>
    </element>
  </define>

  <define name="CommonOptionLists">
    <zeroOrMore>
      <element name="category">
        <attribute name="name" />
        <ref name="Id" />
        <optional>
          	<ref name="Description" />
        </optional>
        <oneOrMore>
          <ref name="CommonOptionList" />
        </oneOrMore>
      </element>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="CommonOptionList" />
    </zeroOrMore>
  </define>

  <define name="CommonOptionList">
    <element name="common-option-list">
      <attribute name="name" />
      <ref name="Id" />

      <ref name="Description" />
      <optional>
        <element name="imports-from">
          <oneOrMore>
            <ref name="CommonOptionListRef" />
          </oneOrMore>
        </element>
      </optional>
      <oneOrMore>
        <ref name="Option" />
      </oneOrMore>
    </element>
  </define>

  <define name="CommonOptionListRef">
    <element name="common-option-list">
      <attribute name="name" />
      <attribute name="href" />
      <optional>
	    	<attribute name="class" />
      </optional>
    </element>
  </define>

  <define name="Objects">
    <zeroOrMore>
      <element name="category">
        <attribute name="name" />
        <ref name="Id" />
        <optional>
          <ref name="Description" />
        </optional>
        <oneOrMore>
          <ref name="Object" />
        </oneOrMore>
      </element>
    </zeroOrMore>
    <zeroOrMore>
      <ref name="Object" />
    </zeroOrMore>
  </define>

  <define name="Object">
    <element name="object">
      <attribute name="name" />
      <ref name="Id" />
      <zeroOrMore>
        <element name="tparam">
          <attribute name="name" />
	  			<optional>
	  			  <ref name="Description" />
	  			</optional>
        </element>
      </zeroOrMore>
		<zeroOrMore>
			<element name="specialization">
				<attribute name="name" />
		      <ref name="Id" />
				<optional>
				  <ref name="Description" />
				</optional>
			</element>
		</zeroOrMore>
      <optional>
        <ref name="Description" />
      </optional>

      <zeroOrMore>
        <element name="derived-from">
          <attribute name="object" />
          <attribute name="href" />
        </element>
      </zeroOrMore>

      <optional>
        <ref name="Properties" />
      </optional>
      <optional>
        <ref name="Permutations" />
      </optional>

      <optional>
        <ref name="Examples" />
      </optional>

      <optional>
	<ref name="UserMethods" />
      </optional>
    </element>
  </define>

  <define name="Id">
  	 <choice>
    <attribute name="xml:id">
      <data type="ID" />
    </attribute>
    <attribute name="id" />
	 </choice>
	 <optional>
	   <attribute name="ext" />
		<attribute name="ext_name" />
	 </optional>
  </define>

  <define name="Option">
    <element name="option">
      <attribute name="name" />
      <attribute name="type" />
      <attribute name="href" />
      <optional>
        <attribute name="class" />
      </optional>
      <optional>
        <ref name="Description" />
      </optional>
    </element>
  </define>

  <define name="Examples">
    <element name="examples">
      <oneOrMore>
        <element name="example">
          <oneOrMore>
            <ref name="Description" />
          </oneOrMore>
        </element>
      </oneOrMore>
    </element>
  </define>

  <define name="NameAttr">
    <attribute name="name">
      <data type="string">
        <param name="pattern">[a-zA-Z][a-zA-Z_0-9]*(:?\($\))?|_id</param>
      </data>
    </attribute>
  </define>

  <define name="Description">
    <element name="description">
      <ref name="HTML" />
    </element>
  </define>

  <define name="HTML">
    <oneOrMore>
      <choice>
        <text/>
        <ref name="HTMLelement"/>
      </choice>
    </oneOrMore>
  </define>

  <define name="HTMLelement">
    <element>
      <nsName ns="http://www.w3.org/1999/xhtml" />
      <zeroOrMore>
        <attribute>
	  <anyName/>
	</attribute>
      </zeroOrMore>
      <ref name="HTML"/>
    </element>
  </define>

  <define name="Version">
    <element name="version">
      <choice>
        <element name="commit">
          <text />
        </element>
        <element name="release">
          <text />
        </element>
      </choice>
      <optional>
        <element name="extensions">
          <oneOrMore>
            <ref name="Extension" />
          </oneOrMore>
        </element>
      </optional>
    </element>
  </define>

</grammar>
