<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright (c) 2010 DeltaXML Ltd.  All rights reserved. -->
<!-- This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License version 3 only,
    as published by the Free Software Foundation.

    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 Lesser General Public License version 3 for more details
    (a copy is included in the LICENSE-LGPL.txt file that accompanied this code).

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/> -->
<!-- $Id: delta-format.rng 6836 2010-07-30 14:15:03Z nigelw $ -->
<grammar xmlns="http://relaxng.org/ns/structure/1.0"
    xmlns:a="http://relaxng.org/ns/compatibility/annotations/1.0"
    datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:ac="http://www.deltaxml.com/ns/track-changes/attribute-change-namespace"
    xmlns:delta="http://www.deltaxml.com/ns/track-changes/delta-namespace"
    xmlns:split="http://www.deltaxml.com/ns/track-changes/split-namespace">
    
    <!-- PATTERNS TO ALLOW INTEGRATION WITH HOST FORMAT -->

    <!-- Level 1 patterns -->
  
    <!-- combine these attributes with all elements, unless they have
        no attributes and are required exactly once in the grammar -->
    <define name="delta-level1-attributes">
      <!-- Rule 2 -->
      <ref name="delta-allow-attribute-changes"/>
      <!-- Rule 3 -->
      <ref name="delta-insertion-with-content-attributes"/>
    </define>

    <!-- combine this rule with the content of any elements which allow
      non-mixed or element only content -->
    <define name="delta-level1-content">
      <!-- Rule 4 -->
      <zeroOrMore>
        <ref name="delta-removed-content"/>
      </zeroOrMore>
    </define>
  
    <!-- combine this with the content of any elements allowing mixed
        content (ie.  content which uses <mixed> or 'interleaves' <text/>)  -->
    <define name="delta-level1-mixed-content">
      <zeroOrMore>
        <choice>
          <!-- Rule 4 -->
          <ref name="delta-removed-content"/>
          <!-- Rule 5 -->
          <ref name="delta-allow-insert-text"/>
        </choice>
      </zeroOrMore>
    </define>


    <!-- Level 2 Patterns.
      Usage Notes:
      
      For each element either add:
        delta-level2-attributes
      or
        delta-level2-wrapper-attributes
      or 
        add neither iff no attributes and required-once element
      
      Also also combine either:
        delta-level2-content
      or
        delta-level2-mixed-content
      to any element with any (non-attribute) content.
      -->

    <!-- combine these attributes with most elements, unless they have
      no attributes and are required exactly once in the grammar -->
    <define name="delta-level2-attributes">
      <!-- Rule 2 -->
      <ref name="delta-allow-attribute-changes"/>
      <!-- Rule 9 -->
      <ref name="delta-split-parent-attributes"/>
      <optional>
        <choice>
          <!-- Rule 3 -->
          <ref name="delta-insertion-with-content-attributes"/>
          <!-- Rule 6 -->
          <ref name="delta-insertion-around-content-attributes"/>
          <!-- Rule 9 -->
          <ref name="delta-split-child-attributes"/>
        </choice>
      </optional>
    </define>
  
    <!-- This pattern is appropriate for combining with an element such as text:span which is a formatting element and
    has no other structural semantics, hence insert/remove with content is not appropriate -->
    <define name="delta-level2-wrapper-attributes">
      <!-- Rule 2 -->
      <ref name="delta-allow-attribute-changes"/>
      <optional>
        <!-- Rule 6 -->
        <ref name="delta-insertion-around-content-attributes"/>
      </optional>
    </define>

    <!-- combine this rule with the content of any elements which allow
    non-mixed or element only content -->
    <define name="delta-level2-content">
      <!-- Rule 8 -->
      <ref name="delta-allow-delta-elements"/>
    </define>
  
    <!-- combine this with the content of any elements allowing mixed
     content (ie:  content which uses <mixed> or 'interleaves' <text/>)  -->
    <define name="delta-level2-mixed-content">
        <interleave>
            <!-- Rule 8 -->
            <ref name="delta-allow-delta-elements"/>
            <!-- Rule 5 -->
            <ref name="delta-allow-insert-text"/>
        </interleave>
    </define>



    <!-- PATTERNS TO REPRESENT RULES FOR INTEGRATION WITH HOST FORMAT -->

    <!-- Rule 1 -->
    <define name="delta-change-transaction-definitions">
        <ref name="delta-tracked-changes"/>
    </define>

    <!-- Rule 2 -->
    <define name="delta-allow-attribute-changes">
        <zeroOrMore>
            <attribute>
                <nsName ns="http://www.deltaxml.com/ns/track-changes/attribute-change-namespace"/>
            </attribute>
        </zeroOrMore>
    </define>

    <!-- Rule 3 -->
    <define name="delta-insertion-with-content-attributes">
        <attribute name="delta:insertion-type">
            <value>insert-with-content</value>
        </attribute>
        <ref name="delta-insertion-change-idref"/>
        <optional>
            <ref name="delta-move-idref"/>
        </optional>
    </define>

    <!-- Rule 3 This definition is general and allows any content, but could be made more
    specific to a host format by defining the content according to Rule 3 -->
    <define name="delta-removed-content">
        <element name="delta:removed-content">
            <ref name="delta-removal-change-idref"/>
            <optional>
                <ref name="delta-move-id"/>
            </optional>
            <ref name="anycontent"/>
        </element>
    </define>

    <!-- Rule 4 (use Rule 8 instead of this for Level 2)-->
    <define name="delta-allow-removed-elements">
        <zeroOrMore>
            <choice>
                <ref name="delta-removed-content"/>
                <ref name="delta-merge"/>
            </choice>
        </zeroOrMore>
    </define>

    <!-- Rule 5 -->
    <define name="delta-allow-insert-text">
        <zeroOrMore>
            <choice>
                <ref name="delta-inserted-text-start"/>
                <ref name="delta-inserted-text-end"/>
            </choice>
        </zeroOrMore>
    </define>

    <!-- Rule 6 -->
    <define name="delta-insertion-around-content-attributes">
        <attribute name="delta:insertion-type">
            <value>insert-around-content</value>
        </attribute>
        <ref name="delta-insertion-change-idref"/>
    </define>

    <!-- Rule 8 -->
    <define name="delta-allow-delta-elements">
        <zeroOrMore>
            <choice>
                <ref name="delta-remove-leaving-content-start"/>
                <ref name="delta-remove-leaving-content-end"/>
                <ref name="delta-removed-content"/>
                <ref name="delta-merge"/>
            </choice>
        </zeroOrMore>
    </define>

    <!-- Rule 9 -->
    <!-- The split parent is the original element that is split -->
    <define name="delta-split-parent-attributes">
        <zeroOrMore>
            <ref name="delta-split-idref"/>
        </zeroOrMore>
    </define>

    <!-- Rule 9 -->
    <!-- The split child is the new element that is created/inserted by the split -->
    <define name="delta-split-child-attributes">
        <attribute name="delta:insertion-type">
            <value>split</value>
        </attribute>
        <ref name="delta-insertion-change-idref"/>
        <ref name="delta-split-id"/>
    </define>

    <!-- PATTERNS FOR MERGE -->

    <define name="delta-merge">
        <element name="delta:merge">
            <ref name="delta-removal-change-idref"/>
            <optional>
                <ref name="delta-move-id"/>
            </optional>
            <element name="delta:leading-partial-content">
                <ref name="anycontent"/>
            </element>
            <element name="delta:intermediate-content">
                <ref name="anyelement"/>
            </element>
            <element name="delta:trailing-partial-content">
                <element>
                    <anyName/>
                    <ref name="anything"/>
                </element>
            </element>
        </element>
    </define>

    <!-- PATTERN FOR REMOVE-LEAVING-CONTENT ELEMENTS -->
    <define name="delta-remove-leaving-content-start">
        <element name="delta:remove-leaving-content-start">
            <ref name="delta-removal-change-idref"/>
            <ref name="delta-end-element-idref"/>
            <element>
              <anyName/>
              <ref name="anything"/>
            </element>  
        </element>
    </define>

    <define name="delta-remove-leaving-content-end">
        <element name="delta:remove-leaving-content-end">
            <ref name="delta-end-element-id"/>
        </element>
    </define>


    <!-- PATTERNS FOR TEXT INSERTION AND REMOVAL -->


    <define name="delta-inserted-text-start">
        <element name="delta:inserted-text-start">
            <ref name="delta-insertion-change-idref"/>
            <ref name="delta-inserted-text-end-idref"/>
            <optional>
                <ref name="delta-move-idref"/>
            </optional>
        </element>
    </define>

    <define name="delta-inserted-text-end">
        <element name="delta:inserted-text-end">
            <ref name="delta-inserted-text-end-id"/>
        </element>
    </define>

    <!-- ATRIBUTES FOR IDs AND IDrefs -->

    <define name="delta-split-id">
        <attribute name="delta:split-id">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-split-idref">
        <attribute>
            <nsName ns="http://www.deltaxml.com/ns/track-changes/split-namespace"/>
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-end-element-id">
        <attribute name="delta:end-element-id">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-end-element-idref">
        <attribute name="delta:end-element-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-move-id">
        <attribute name="delta:move-id">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-move-idref">
        <attribute name="delta:move-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-inserted-text-end-id">
        <attribute name="delta:inserted-text-end-id">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-inserted-text-end-idref">
        <attribute name="delta:inserted-text-end-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-change-id">
        <attribute name="delta:change-id">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-change-idref">
        <attribute name="delta:change-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-change-group-id">
        <attribute name="delta:change-group-id">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-change-group-idref">
        <attribute name="delta:change-group-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-insertion-change-idref">
        <attribute name="delta:insertion-change-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <define name="delta-removal-change-idref">
        <attribute name="delta:removal-change-idref">
            <ref name="delta-NCName"/>
        </attribute>
    </define>

    <!-- PATTERNS FOR MERGE SUPPORT ELEMENTS -->

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

    <define name="anyelement">
        <zeroOrMore>
            <element>
                <anyName/>
                <ref name="anything"/>
            </element>
        </zeroOrMore>
    </define>

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

    <!-- PATTERNS FOR CHANGE TRANSACTIONS (CT) DEFINITIONS AND GROUPING -->

    <define name="delta-tracked-changes">
        <element name="delta:tracked-changes">
            <zeroOrMore>
                <choice>
                    <ref name="delta-change-transaction"/>
                    <ref name="delta-change-transaction-stack"/>
                    <ref name="delta-change-transaction-set"/>
                </choice>
            </zeroOrMore>
        </element>
    </define>

    <define name="delta-change-transaction">
        <element name="delta:change-transaction">
            <ref name="delta-change-id"/>
            <ref name="delta-change-info"/>
            <optional>
                <ref name="delta-change-log"/>
            </optional>
            <optional>
                <ref name="delta-transaction-dependencies"/>
            </optional>

        </element>
    </define>

    <define name="delta-change-transaction-group">
        <ref name="delta-change-group-id"/>
        <ref name="delta-change-info"/>
        <optional>
            <ref name="delta-change-log"/>
        </optional>
        <optional>
            <ref name="delta-change-references"/>
        </optional>
    </define>

    <define name="delta-change-transaction-stack">
        <element name="delta:change-transaction-stack">
            <ref name="delta-change-transaction-group"/>
        </element>
    </define>
    <define name="delta-change-transaction-set">
        <element name="delta:change-transaction-set">
            <ref name="delta-change-transaction-group"/>
        </element>
    </define>

    <define name="delta-change-references">
        <element name="delta:change-references">
            <oneOrMore>
                <choice>
                    <ref name="delta-change-ref"/>
                    <ref name="delta-change-group-ref"/>
                </choice>
            </oneOrMore>
        </element>
    </define>

    <define name="delta-transaction-dependencies">
        <element name="delta:transaction-dependencies">
            <oneOrMore>
                <element name="delta:transaction-dependency">
                    <attribute name="dependency-type">
                        <text/>
                    </attribute>
                    <ref name="delta-change-idref"/>
                </element>
            </oneOrMore>
        </element>
    </define>

    <define name="delta-change-ref">
        <element name="delta:change-ref">
            <ref name="delta-change-idref"/>
        </element>
    </define>
    <define name="delta-change-group-ref">
        <element name="delta:change-group-ref">
            <ref name="delta-change-group-idref"/>
        </element>
    </define>

    <define name="delta-change-log">
        <element name="delta:change-log">
            <!-- TBA info such as 'table cell merge', 'global edit' etc -->
            <ref name="anything"/>
        </element>
    </define>

    <define name="delta-change-info">
        <element name="delta:change-info">
            <optional>
                <ref name="delta-dc-creator"/>
                <ref name="delta-dc-date"/>
            </optional>
        </element>
    </define>

    <!-- BASIC DATA TYPES, using delta- as a prefix to avoid clashes with definitions in ODF -->
  
    <define name="delta-dc-creator">
        <element name="dc:creator">
          <data type="string"/>
        </element>
    </define>

    <define name="delta-dc-date">
        <element name="dc:date">
          <data type="dateTime"/>
        </element>
    </define>

    <define name="delta-NCName">
        <data type="NCName"/>
    </define> 
</grammar>
