<?xml version="1.0" encoding="UTF-8"?>
<!-- © TEI Consortium. Dual-licensed under CC-by and BSD2 licenses; see the file COPYING.txt for details. -->
<?xml-model href="http://jenkins.tei-c.org/job/TEIP5-dev/lastSuccessfulBuild/artifact/P5/release/xml/tei/odd/p5odds.rnc" type="application/relax-ng-compact-syntax"?>
<?xml-model href="http://jenkins.tei-c.org/job/TEIP5-dev/lastSuccessfulBuild/artifact/P5/release/xml/tei/odd/p5odds.isosch" type="application/xml" schematypens="http://purl.oclc.org/dsdl/schematron"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0"
     xmlns:rng="http://relaxng.org/ns/structure/1.0"
     xmlns:sqf="http://www.schematron-quickfix.com/validator/process"
     xmlns:sch="http://purl.oclc.org/dsdl/schematron" >
  <teiHeader>
    <fileDesc>
      <titleStmt>
        <title>TEI for the TEI Guidelines</title>
        <author>Sebastian Rahtz</author>
      </titleStmt>
      <publicationStmt>
        <publisher>TEI Consortium</publisher>
      </publicationStmt>
      <sourceDesc>
        <p>authored from scratch</p>
      </sourceDesc>
    </fileDesc>
  </teiHeader>
  <text>
    <body>
      <schemaSpec ident="p5odds" prefix="TEI_"
                  start="TEI schemaSpec elementSpec classSpec macroSpec dataSpec div">
        <moduleRef key="header"/>
        <moduleRef key="core"/>
        <moduleRef key="tei"/>
        <moduleRef key="gaiji"/>
        <moduleRef key="namesdates"/>
        <moduleRef key="textstructure" except="div1 div2 div3 div4 div5 div6 div7"/>
        <moduleRef key="tagdocs"/>
        <moduleRef key="dictionaries"/>
        <moduleRef key="linking"/>
        <moduleRef key="figures"/>
        <moduleRef url="Exemplars/svg11.rng">
          <content>
            <define xmlns="http://relaxng.org/ns/structure/1.0" combine="choice" name="tei_model.graphicLike">
              <ref name="svg"/>
            </define>
          </content>
        </moduleRef>
        <moduleRef url="Exemplars/mathml2-main.rng"/>
        <moduleRef url="Exemplars/relaxng.rng"/>

        <elementSpec module="tagdocs" ident="constraintSpec" mode="change">
          <attList>
            <attDef mode="change" ident="xml:lang" usage="req"/>
          </attList>
        </elementSpec>
        
        <constraintSpec scheme="schematron" ident="when_glosses_English_required" xml:lang="en">
          <desc>Per <ref
          target="https://github.com/TEIC/TEI/issues/2037">ticket
          237</ref>, Council has decided that every specification
          element that has any <gi>gloss</gi> child must have a
          <gi>gloss</gi> child in English. This is in order to make
          figuring out which glosses need translation easier (or
          possible).</desc>
          <constraint>
            <!-- We attempted to enforce this with an abstract
                 pattern, but found that oNVDL does not support
                 abstract patterns. Thus, at least for now, just use
                 a bulky, straightfoward, inelegant, but easier to
                 process pattern. -->
            <sch:pattern id="en-gloss-if-any">
              <sch:rule context="  tei:elementSpec[tei:gloss]
                                 | tei:valItem[tei:gloss]
                                 | tei:attDef[tei:gloss]
                                 | tei:macroSpec[tei:gloss]
                                 | tei:classSpec[tei:gloss]
                                 | tei:dataSpec[tei:gloss]
                                 ">
                <sch:assert test="tei:gloss[ lang('en') ]">If there is any gloss inside <sch:value-of select="name(.)"/>, there must be an English gloss.</sch:assert>
              </sch:rule>
            </sch:pattern>
          </constraint>
        </constraintSpec>

        <!-- The abstract pattern version of the same constraint as above: -->
        <!-- <constraintSpec scheme="schematron" ident="when_glosses_English_required"> -->
        <!--   <desc>Per <ref -->
        <!--   target="https://github.com/TEIC/TEI/issues/2037">ticket -->
        <!--   237</ref>, Council has decided that every specification -->
        <!--   element that has any <gi>gloss</gi> child must have a -->
        <!--   <gi>gloss</gi> child in English. This is in order to make -->
        <!--   figuring out which glosses need translation easier (or -->
        <!--   possible).</desc> -->
        <!--   <constraint> -->
        <!--     <sch:pattern abstract="true" id="en-gloss-if-any"> -->
        <!--       <!\-\- parameter 'gse' is for "glossed specification element (type)" \-\-> -->
        <!--       <sch:rule context="$gse[tei:gloss]"> -->
        <!--    <sch:assert test="tei:gloss[ lang('en') ]">If there is any gloss inside <sch:value-of select="name(.)"/>, there must be an English gloss.</sch:assert> -->
        <!--       </sch:rule> -->
        <!--     </sch:pattern> -->
        <!--   </constraint> -->
        <!-- </constraintSpec> -->

        <!-- <elementSpec ident="elementSpec" mode="change" module="tagdocs"> -->
        <!--   <constraintSpec scheme="schematron" ident="EGIA_elementSpec"> -->
        <!--     <constraint> -->
        <!--       <sch:pattern id="egia-elementSpec" is-a="en-gloss-if-any"> -->
        <!--    <sch:param name="gse" value="tei:elementSpec"/> -->
        <!--       </sch:pattern> -->
        <!--     </constraint> -->
        <!--   </constraintSpec> -->
        <!-- </elementSpec> -->
        
        <!-- <elementSpec ident="valItem" mode="change" module="tagdocs"> -->
        <!--   <constraintSpec scheme="schematron" ident="EGIA_valItem"> -->
        <!--     <constraint> -->
        <!--       <sch:pattern id="egia-valItem" is-a="en-gloss-if-any"> -->
        <!--    <sch:param name="gse" value="tei:valItem"/> -->
        <!--       </sch:pattern> -->
        <!--     </constraint> -->
        <!--   </constraintSpec> -->
        <!-- </elementSpec> -->
        
        <!-- <elementSpec ident="attDef" mode="change" module="tagdocs"> -->
        <!--   <constraintSpec scheme="schematron" ident="EGIA_attDef"> -->
        <!--     <constraint> -->
        <!--       <sch:pattern id="egia-attDef" is-a="en-gloss-if-any"> -->
        <!--    <sch:param name="gse" value="tei:attDef"/> -->
        <!--       </sch:pattern> -->
        <!--     </constraint> -->
        <!--   </constraintSpec> -->
        <!-- </elementSpec> -->
        
        <!-- <elementSpec ident="macroSpec" mode="change" module="tagdocs"> -->
        <!--   <constraintSpec scheme="schematron" ident="EGIA_macroSpec"> -->
        <!--     <constraint> -->
        <!--       <sch:pattern id="egia-macroSpec" is-a="en-gloss-if-any"> -->
        <!--    <sch:param name="gse" value="tei:macroSpec"/> -->
        <!--       </sch:pattern> -->
        <!--     </constraint> -->
        <!--   </constraintSpec> -->
        <!-- </elementSpec> -->
        
        <!-- <elementSpec ident="classSpec" mode="change" module="tagdocs"> -->
        <!--   <constraintSpec scheme="schematron" ident="EGIA_classSpec"> -->
        <!--     <constraint> -->
        <!--       <sch:pattern id="egia-classSpec" is-a="en-gloss-if-any"> -->
        <!--    <sch:param name="gse" value="tei:classSpec"/> -->
        <!--       </sch:pattern> -->
        <!--     </constraint> -->
        <!--   </constraintSpec> -->
        <!-- </elementSpec> -->
        
        <!-- <elementSpec ident="dataSpec" mode="change" module="tagdocs"> -->
        <!--   <constraintSpec scheme="schematron" ident="EGIA_dataSpec"> -->
        <!--     <constraint> -->
        <!--       <sch:pattern id="egia-dataSpec" is-a="en-gloss-if-any"> -->
        <!--    <sch:param name="gse" value="tei:dataSpec"/> -->
        <!--       </sch:pattern> -->
        <!--     </constraint> -->
        <!--   </constraintSpec> -->
        <!-- </elementSpec> -->
        
        <elementSpec ident="egXML" mode="change" module="tagdocs"
                     ns="http://www.tei-c.org/ns/Examples">
          <!-- 
               This definition of <teix:egXML> overrides that of P5 which, for
               some reason I don't grok, does not allow a <teix:egXML> descendant.
                —Syd, 2018-06-13
          -->
          <content>
            <alternate minOccurs="1" maxOccurs="unbounded">
              <textNode/>
              <elementRef key="egXML"/>
              <anyElement/>
            </alternate>
          </content>
        </elementSpec>
        <elementSpec ident="eg" mode="change" module="tagdocs">
          <constraintSpec ident="no_leading_nor_trailing_new_newlines" scheme="schematron" xml:lang="en">
            <desc xml:lang="en" versionDate="2020-12-18">
              In order to prevent inconsistent <soCalled>sizes</soCalled> of the box
              that holds the example in the HTML output, and even moreso to avoid
              getting the <quote>bibliography Show all ⚓</quote> looking ugly at the
              bottom, there should be no leading nor trailing newlines. If you really
              want a newline at the beginning, precede it with U+00A0 (NO-BREAK SPACE);
              if you really want a newline at the end, follow it with U+00A0.
            </desc>
            <constraint>
              <sch:rule context="tei:eg">
                <sch:report test="matches( string(.), '&#x0A;\s*$')">trailing newline not allowed</sch:report>
                <sch:report test="matches( string(.), '^\s*&#x0A;')">leading newline not allowed</sch:report>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </elementSpec>
        <macroSpec ident="anyISOSchematron" mode="add">
          <content>
            <element xmlns="http://relaxng.org/ns/structure/1.0">
              <nsName ns="http://purl.oclc.org/dsdl/schematron"/>
              <zeroOrMore>
                <choice>
                  <attribute>
                    <anyName/>
                  </attribute>
                  <ref name="anyISOSchematron"/>
                  <ref name="anySchematronQuickFix"/>
                  <text/>
                </choice>
              </zeroOrMore>
            </element>
          </content>
        </macroSpec>

        <macroSpec ident="anySchematronQuickFix" mode="add">
          <content>
            <element xmlns="http://relaxng.org/ns/structure/1.0">
              <nsName ns="http://www.schematron-quickfix.com/validator/process"/>
              <zeroOrMore>
                <choice>
                  <attribute>
                    <anyName/>
                  </attribute>
                  <ref name="anySchematronQuickFix"/>
                  <ref name="anyISOSchematron"/>
                  <text/>
                </choice>
              </zeroOrMore>
            </element>
          </content>
        </macroSpec>

        <!-- in examples we'd like to be able to show use of <xi:include>; of course, -->
        <!-- we can't put in an <xi:include> element, or it will be processed! Thus, -->
        <!-- here we use a bogus namespace -->
        <elementSpec ident="include" ns="http://www.example.org/cannot/really/use/XInclude" mode="add">
          <!-- the content and attributes were devised based on my reading of the spec at
               http://www.w3.org/TR/2006/REC-xinclude-20061115/, also having looked at
               Norm Walsh's implementation for DocBook. -sb -->
          <content>
            <optional xmlns="http://relaxng.org/ns/structure/1.0">
              <ref name="fallback"/>
            </optional>
          </content>
          <attList>
            <attDef ident="href">
              <datatype>
                <data xmlns="http://relaxng.org/ns/structure/1.0" type="anyURI">
                  <param name="pattern">[^#]+</param>
                </data>
              </datatype>
            </attDef>
            <attDef ident="parse">
              <defaultVal>xml</defaultVal>
              <valList type="closed">
                <valItem ident="xml"/>
                <valItem ident="text"/>
              </valList>
            </attDef>
            <attDef ident="xpointer">
              <datatype>
                <data xmlns="http://relaxng.org/ns/structure/1.0" type="string"/>
              </datatype>
            </attDef>
            <attDef ident="encoding">
              <datatype>
                <data xmlns="http://relaxng.org/ns/structure/1.0" type="string"/>
              </datatype>
            </attDef>
            <attDef ident="accept">
              <datatype>
                <data xmlns="http://relaxng.org/ns/structure/1.0" type="string"/>
              </datatype>
            </attDef>
            <attDef ident="accept-language">
              <datatype>
                <data xmlns="http://relaxng.org/ns/structure/1.0" type="string"/>
              </datatype>
            </attDef>
          </attList>
        </elementSpec>

        <!-- of course <xi:include> refers to <xi:fallback>, so we need to declare-->
        <!-- that, too, just in case. -->
        <elementSpec ident="fallback" ns="http://www.example.org/cannot/really/use/XInclude" mode="add">
          <content>
            <oneOrMore xmlns="http://relaxng.org/ns/structure/1.0">
              <choice>
                <text/>
                <?NameList?>
              </choice>
            </oneOrMore>
          </content>
        </elementSpec>

        <elementSpec module="tagdocs" ident="gi" mode="change">
          <attList>
            <attDef mode="replace" ident="scheme">
              <valList type="closed">
                <valItem ident="imaginary"/>
                <valItem ident="extreme">
                  <gloss versionDate="2013-10-30" xml:lang="en">Extreme conference proceedings markup</gloss>
                </valItem>
                <valItem ident="balisage">
                  <gloss versionDate="2024-10-11" xml:lang="en">Balisage proceedings markup</gloss>
                </valItem>
                <valItem ident="DBK">
                  <gloss versionDate="2013-10-30" xml:lang="en">Docbook</gloss>
                </valItem>
                <valItem ident="SMIL"/>
                <valItem ident="Schematron"/>
                <valItem ident="HTML"/>
                <valItem ident="SVG"/>
                <valItem ident="XHTML"/>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <elementSpec ident="biblScope" mode="change">
          <attList>
            <attDef mode="replace" ident="type">
              <valList type="closed">
                <valItem ident="chap">
                  <gloss versionDate="2013-10-30" xml:lang="en">Chapter</gloss>
                </valItem>
                <valItem ident="issue">
                  <gloss versionDate="2013-10-30" xml:lang="en">Issue</gloss>
                </valItem>
                <valItem ident="note">
                  <gloss versionDate="2013-10-30" xml:lang="en">Note</gloss>
                </valItem>
                <valItem ident="part">
                  <gloss versionDate="2013-10-30" xml:lang="en">Part</gloss>
                </valItem>
                <valItem ident="pp">
                  <gloss versionDate="2013-10-30" xml:lang="en">Pages</gloss>
                </valItem>
                <valItem ident="vol">
                  <gloss versionDate="2013-10-30" xml:lang="en">Volume</gloss>
                </valItem>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <elementSpec ident="divGen" mode="change">
          <attList>
            <attDef mode="replace" ident="type">
              <valList type="closed">
                <valItem ident="attcat">
                  <gloss versionDate="2013-10-30" xml:lang="en">Catalogue of Attributes</gloss>
                </valItem>
                <valItem ident="attclasscat">
                  <gloss versionDate="2013-10-30" xml:lang="en">Catalogue of Attribute Classes</gloss>
                </valItem>
                <valItem ident="elementcat">
                  <gloss versionDate="2013-10-30" xml:lang="en"> Catalogue of Elements</gloss>
                </valItem>
                <valItem ident="index">
                  <gloss versionDate="2013-10-30" xml:lang="en"> Index</gloss>
                </valItem>
                <valItem ident="macrocat">
                  <gloss versionDate="2013-10-30" xml:lang="en"> Catalogue of Macros</gloss>
                </valItem>
                <valItem ident="modelclasscat">
                  <gloss versionDate="2013-10-30" xml:lang="en">Catalogue of Model Classes</gloss>
                </valItem>
                <valItem ident="deprecationcat">
                  <gloss versionDate="2018-09-10" xml:lang="en">Catalogue of Deprecations</gloss>
                </valItem>
                <valItem ident="toc">
                  <gloss versionDate="2013-10-30" xml:lang="en">Table of Contents</gloss>
                </valItem>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <elementSpec ident="div" mode="change">
          <attList>
            <attDef mode="replace" ident="type">
              <valList type="closed">
                <valItem ident="div1"/>
                <valItem ident="div2"/>
                <valItem ident="div3"/>
                <valItem ident="div4"/>
                <valItem ident="titlePageVerso"/>
                <valItem ident="Dedication"/>
                <valItem ident="section"/>
                <valItem ident="subsection"/>
                <valItem ident="subsubsection"/>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <elementSpec ident="list" mode="change">          
          <!-- MDH 2014-07-29: per https://sourceforge.net/p/tei/bugs/460, 
               changes made to specs should be reflected in Guidelines usage, so 
               the values for @type and @rend below should be reviewed. -->
          <attList>
            <attDef mode="replace" ident="type">
              <valList type="closed">
                <valItem ident="ordered">
                  <gloss versionDate="2013-10-30" xml:lang="en">Numbered list</gloss>
                </valItem>
                <valItem ident="simple">
                  <gloss versionDate="2013-10-30" xml:lang="en">Plain list</gloss>
                </valItem>
                <valItem ident="gloss">
                  <gloss versionDate="2013-10-30" xml:lang="en">Glossary list</gloss>
                </valItem>
                <valItem ident="inline">
                  <gloss versionDate="2013-10-30" xml:lang="en">Inline list</gloss>
                </valItem>
              </valList>
            </attDef>
            <attDef mode="replace" ident="rend">
              <valList type="closed">
                <valItem ident="specList">
                  <gloss versionDate="2013-10-30" xml:lang="en">Specification list</gloss>
                </valItem>
                <valItem ident="numbered">
                  <gloss versionDate="2013-10-30" xml:lang="en">Numbered list</gloss>
                </valItem>
                <valItem ident="ordered">
                  <gloss versionDate="2013-10-30" xml:lang="en">Numbered list</gloss>
                </valItem>
                <valItem ident="simple">
                  <gloss versionDate="2013-10-30" xml:lang="en">Plain list</gloss>
                </valItem>
                <valItem ident="gloss">
                  <gloss versionDate="2013-10-30" xml:lang="en">Glossary list</gloss>
                </valItem>
                <valItem ident="inline">
                  <gloss versionDate="2013-10-30" xml:lang="en">Inline list</gloss>
                </valItem>
                <!-- MDH 2014-07-29: added this value to make changes to 
                     Guidelines source valid per https://sourceforge.net/p/tei/bugs/460.
                -->
                <valItem ident="bulleted">
                  <gloss versionDate="2013-10-30" xml:lang="en">Bulleted list</gloss>
                </valItem>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <elementSpec module="tagdocs" ident="ident" mode="change">
          <attList>
            <attDef mode="replace" ident="type">
              <valList type="closed">
                <valItem ident="field">
                  <gloss versionDate="2013-10-30" xml:lang="en">field used in a metadata standard</gloss>
                </valItem>
                <valItem ident="ge">
                  <gloss versionDate="2013-10-30" xml:lang="en">general entity name</gloss>
                </valItem>
                <valItem ident="rng">
                  <gloss versionDate="2013-10-30" xml:lang="en">RELAX NG identifier</gloss>
                </valItem>
                <valItem ident="frag">
                  <gloss versionDate="2013-10-30" xml:lang="en">DTD fragment identifier</gloss>
                </valItem>
                <valItem ident="macro"/>
                <valItem ident="ns">
                  <gloss versionDate="2013-10-30" xml:lang="en">namespace</gloss>
                </valItem>
                <valItem ident="schema"/>
                <valItem ident="pe">
                  <gloss versionDate="2013-10-30" xml:lang="en">parameter entity name</gloss>
                </valItem>
                <valItem ident="datatype"/>
                <valItem ident="file"/>
                <valItem ident="module"/>
                <valItem ident="class"/>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <classSpec ident="att.translatable" mode="change" type="atts">
          <constraintSpec mode="add" xml:lang="en"
                          ident="require-translatability"
                          scheme="schematron">
            <constraint>
              <sch:rule context="  tei:elementSpec/tei:desc
                                 | tei:elementSpec/tei:gloss
                                 | tei:elementSpec/tei:remarks
                                 | tei:classSpec/tei:desc
                                 | tei:classSpec/tei:gloss
                                 | tei:classSpec/tei:remarks
                                 | tei:macroSpec/tei:desc
                                 | tei:macroSpec/tei:gloss
                                 | tei:macroSpec/tei:remarks
                                 | tei:attDef/tei:desc
                                 | tei:attDef/tei:gloss
                                 | tei:attDef/tei:remarks
                                 | tei:valItem/tei:desc
                                 | tei:valItem/tei:gloss
                                 | tei:valItem/tei:remarks
                                 | tei:moduleSpec/tei:desc
                                 | tei:moduleSpec/tei:gloss
                                 | tei:moduleSpec/tei:remarks
                                 ">
                <sch:assert test="@xml:lang  and  @versionDate">
                  Error: both the versionDate and xml:lang attributes on "<sch:name/>" are required when it is a child of "<sch:value-of select="local-name(..)"/>".
                </sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
          <constraintSpec mode="add" ident="en-first" scheme="schematron" xml:lang="en">
            <desc xml:lang="en" versionDate="2022-05-13">Per ticket
              <ref target="https://github.com/TEIC/TEI/issues/2279">2279</ref>,
              require that the English translatable element goes
              first. Note that we would prefer to be able fire this
              constraint on <said>any member of att.translatable</said>,
              but there is currently no way to do that, so here we
              enumerate them.</desc>
            <constraint>
              <sch:rule context="  tei:elementSpec/tei:desc[1]
                                 | tei:elementSpec/tei:gloss[1]
                                 | tei:elementSpec/tei:remarks[1]
                                 | tei:classSpec/tei:desc[1]
                                 | tei:classSpec/tei:gloss[1]
                                 | tei:classSpec/tei:remarks[1]
                                 | tei:macroSpec/tei:desc[1]
                                 | tei:macroSpec/tei:gloss[1]
                                 | tei:macroSpec/tei:remarks[1]
                                 | tei:attDef/tei:desc[1]
                                 | tei:attDef/tei:gloss[1]
                                 | tei:attDef/tei:remarks[1]
                                 | tei:valItem/tei:desc[1]
                                 | tei:valItem/tei:gloss[1]
                                 | tei:valItem/tei:remarks[1]
                                 | tei:moduleSpec/tei:desc[1]
                                 | tei:moduleSpec/tei:gloss[1]
                                 | tei:moduleSpec/tei:remarks[1]
                                  ">
                <sch:assert test="lang('en')">The first <sch:value-of select="name(.)"/> child of a <sch:value-of select="name(..)"/> should have an @xml:lang that indicates it is in English.</sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
          <constraintSpec mode="add" ident="only-one-each-lang" scheme="schematron" xml:lang="en">
            <desc xml:lang="en" versionDate="2022-05-13">Per ticket <ref target="https://github.com/TEIC/TEI/issues/2279">2279</ref>, require that there be only one
              of any given att.translatable element sibling for any given language. Note that
              we would prefer to be able to say <said>a member of att.translatable</said>, but
              there is currently no way to that, so we enumerate them. Also note that we simply
              compare <att>xml:lang</att> values, such that <val>fr-CA</val> and <val>fr-FR</val>
              would be considered different languages. (We may want to be smarter about this in
              the future.)</desc>
            <constraint>
              <sch:rule context="  tei:elementSpec/tei:desc[ position() gt 1 ]
                                 | tei:elementSpec/tei:gloss[ position() gt 1 ]
                                 | tei:elementSpec/tei:remarks[ position() gt 1 ]
                                 | tei:classSpec/tei:desc[ position() gt 1 ]
                                 | tei:classSpec/tei:gloss[ position() gt 1 ]
                                 | tei:classSpec/tei:remarks[ position() gt 1 ]
                                 | tei:macroSpec/tei:desc[ position() gt 1 ]
                                 | tei:macroSpec/tei:gloss[ position() gt 1 ]
                                 | tei:macroSpec/tei:remarks[ position() gt 1 ]
                                 | tei:attDef/tei:desc[ position() gt 1 ]
                                 | tei:attDef/tei:gloss[ position() gt 1 ]
                                 | tei:attDef/tei:remarks[ position() gt 1 ]
                                 | tei:valItem/tei:desc[ position() gt 1 ]
                                 | tei:valItem/tei:gloss[ position() gt 1 ]
                                 | tei:valItem/tei:remarks[ position() gt 1 ]
                                 | tei:moduleSpec/tei:desc[ position() gt 1 ]
                                 | tei:moduleSpec/tei:gloss[ position() gt 1 ]
                                 | tei:moduleSpec/tei:remarks[ position() gt 1 ]
                                  ">
                <sch:let name="myGI" value="name(.)"/>
                <sch:let name="myType" value="@type"/>
                <sch:let name="hasType" value="if (@type) then true() else false()"/>
                <sch:let name="lang" value="normalize-space( @xml:lang )"/>
                <sch:report test="preceding-sibling::*[ name(.) eq $myGI ][(not(@type) and not($hasType)) or @type eq $myType][ normalize-space( @xml:lang) eq $lang ]">The sibling <sch:value-of select="$myGI"/> children of a <sch:value-of select="name(..)"/> should each have a different @xml:lang; this one duplicates the "<sch:value-of select="$lang"/>" of a preceding sibling.</sch:report>
              </sch:rule>
            </constraint>
          </constraintSpec>
          <constraintSpec ident="all-sibling-parent-desc" scheme="schematron" xml:lang="en">
            <constraint>
              <sch:rule context="*[tei:desc[@versionDate]]">
                <sch:report role="nonfatal" test="count( tei:desc )
                                                  ne
                                                  count( tei:desc[@versionDate] )
                                                  ">
                  Error: sibling 'desc' elements with and without @versionDate.
                </sch:report>
              </sch:rule>
            </constraint>
          </constraintSpec>
          <constraintSpec ident="all-sibling-parent-gloss" scheme="schematron" xml:lang="en">
            <constraint>
              <sch:rule context="*[tei:gloss[@versionDate]]">
                <sch:report role="nonfatal" test="count( tei:gloss )
                                                  ne
                                                  count( tei:gloss[@versionDate] )
                                                  ">
                  Error: sibling 'gloss' elements with and without @versionDate.
                </sch:report>
              </sch:rule>
            </constraint>
          </constraintSpec>
          <constraintSpec ident="all-sibling-parent-remarks" scheme="schematron" xml:lang="en">
            <constraint>
              <sch:rule context="*[tei:remarks[@versionDate]]">
                <sch:report role="nonfatal" test="count( tei:remarks )
                                                  ne
                                                  count( tei:remarks[@versionDate] )
                                                  ">
                  Error: sibling 'remarks' elements with and without @versionDate.
                </sch:report>
              </sch:rule>
            </constraint>
          </constraintSpec>
          <constraintSpec ident="all-sibling-parent-valDesc" scheme="schematron" xml:lang="en">
            <constraint>
              <sch:rule context="*[tei:valDesc[@versionDate]]">
                <sch:report role="nonfatal" test="
                                                  count( tei:valDesc )
                                                  ne
                                                  count( tei:valDesc[@versionDate] )
                                                  ">
                  Error: sibling 'valDesc' elements with and without @versionDate.
                </sch:report>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </classSpec>
        
        <classSpec ident="att.identified" mode="change" type="atts">
          <attList>
            <attDef ident="module" mode="replace">
              <valList type="closed" mode="add">
                <!-- I daresay this should be a generated list —Syd, 2022-04-24 -->
                <valItem ident="tei"/>
                <valItem ident="core"/>
                <valItem ident="analysis"/>
                <valItem ident="certainty"/>
                <valItem ident="cmc"/>
                <valItem ident="corpus"/>
                <valItem ident="dictionaries"/>
                <valItem ident="drama"/>
                <valItem ident="figures"/>
                <valItem ident="gaiji"/>
                <valItem ident="header"/>
                <valItem ident="iso-fs"/>
                <valItem ident="linking"/>
                <valItem ident="msdescription"/>
                <valItem ident="namesdates"/>
                <valItem ident="nets"/>
                <valItem ident="spoken"/>
                <valItem ident="textcrit"/>
                <valItem ident="textstructure"/>
                <valItem ident="transcr"/>
                <valItem ident="verse"/>
                <valItem ident="tagdocs"/>
              </valList>
            </attDef>
          </attList>
        </classSpec>

        <elementSpec ident="exemplum" mode="change">
          <attList>
            <attDef mode="change" ident="xml:lang" usage="req"/>
          </attList>
        </elementSpec>

        <elementSpec ident="idno" mode="change">
          <attList>
            <attDef mode="replace" ident="type">
              <valList type="closed">
                <valItem ident="DOI">
                  <gloss versionDate="2013-10-30" xml:lang="en">Digital Object Identifier</gloss>
                </valItem>
                <valItem ident="FPI">
                  <gloss versionDate="2021-10-10" xml:lang="en">Formal Public Identifier</gloss>
                </valItem>
                <valItem ident="ISBN">
                  <gloss versionDate="2013-10-30" xml:lang="en">International Standard Book Number</gloss>
                </valItem>
                <valItem ident="URI">
                  <gloss versionDate="2024-12-04" xml:lang="en">Uniform Resource Identifier</gloss>
                  <desc versionDate="2013-10-30" xml:lang="en">any form of web address (that is, a URL or a URN)</desc>
                </valItem>
                <valItem ident="URL">
                  <gloss versionDate="2024-12-04" xml:lang="en">Uniform Resource Locator</gloss>
                </valItem>
                <valItem ident="URN">
                  <gloss versionDate="2024-12-04" xml:lang="en">Uniform Resource Name</gloss>
                </valItem>
              </valList>
            </attDef>
          </attList>
        </elementSpec>

        <!--
            Use of <interleave> in a content model means that our
            Stylesheets cannot generate a DTD from that
            ODD. Furthermore, it would be very difficult to impossible
            to alter the Stylesheets do so. Thus although vanilla P5
            allows for <interleave> to occur inside <alternation>,
            <content>, or <sequence>, we are not allowing ourselves to
            use it within P5 at all.
            HOWEVER, we cannot actually delete the entire element here
            because (I think) of the way examples are validated during
            our build process. They (the content of the <egXML>
            elements) are (incorrectly, IMHO) validated against
            p5odds, not against tei_all.
        -->
        <elementSpec module="tagdocs" ident="interleave" mode="change">
          <classes>
            <memberOf key="att.repeatable" mode="delete"/>
          </classes>
        </elementSpec>

        <elementSpec module="tagdocs" ident="alternate" mode="change">
          <content>
            <!--
                What we would like to have is
                  <interleave>
                    <classRef key="model.contentPart" minOccurs="1" maxOccurs="unbounded"/>
                    <alternate>
                      <classRef key="model.contentPart" minOccurs="1" maxOccurs="1"/>
                      <elementRef key="valList" minOccurs="0" maxOccurs="1">
                    </alternate>
                  </interleave>
                OR, equivalently,
                ( model.contentPart+ & ( model.contentPart | valList? ) )
                but
                a) that is not valid in RELAX NG, anyway (because
                   model.contentPart is a member of an interleave
                   more than once); and
                b) even if it were it probably could not be converted to DTD (or to XSD?)
                   due to ambiguity.   

                So the following mildly complex content model does the
                same thing without use of <interleave> and in an
                unambiguous way. (Thus it can be converted to a valid
                DTD.) Here is a briefly annotated version of the ODD
                content model that follows, expressed using the RELAX
                NG compact syntax instead:
                (
                  ( valList, model.contentPart+ )        # starts with <valList>
                  |                                      # (and is followed by %contentPart;s)
                  (                                      # OR
                    model.contentPart,                   # starts with %contentPart;
                    (                                    #   which is followed by
                      valList                            #     <valList>
                      |                                  #     or
                      ( model.contentPart+, valList? )   #     more %contentPart;s and maybe a <valList>
                    )
                  )
                )
            -->
            <alternate minOccurs="1" maxOccurs="1">
              <!--
                  Two possible sets of children: my content either starts with
                  <valList> or with a member of model.contentPart.
              -->
              <sequence minOccurs="1" maxOccurs="1">
                <!-- Content starts with <valList> is simple: a single
                     <valList> followed by one or more members of
                     model.contentPart: -->
                <elementRef key="valList" minOccurs="1" maxOccurs="1"/>
                <classRef key="model.contentPart" minOccurs="1" maxOccurs="unbounded"/>
              </sequence>
              <sequence minOccurs="1" maxOccurs="1">
                <!-- Content starts with a member of model.contentPart is not
                     as simple: after the single initial member of
                     model.contentPart we could either have just a <valList>
                     (for a total of 2 children) or we could have an
                     additional one or more members of model.contentPart,
                     optionally followed by a <valList>. -->
                <classRef key="model.contentPart" minOccurs="1" maxOccurs="1"/>
                <alternate minOccurs="1" maxOccurs="1">
                  <elementRef key="valList" minOccurs="1" maxOccurs="1"/>
                  <sequence minOccurs="1" maxOccurs="1">
                    <classRef key="model.contentPart" minOccurs="1" maxOccurs="unbounded"/>       
                    <elementRef key="valList" minOccurs="0" maxOccurs="1"/>
                  </sequence>
                </alternate>
              </sequence>
            </alternate>
          </content>
        </elementSpec>
        
        <elementSpec module="tagdocs" ident="sequence" mode="change">
          <content>
            <classRef key="model.contentPart" minOccurs="2" maxOccurs="unbounded"/>
          </content>
        </elementSpec>
        
        <elementSpec ident="classes" mode="change" module="tagdocs">
          <constraintSpec mode="add" scheme="schematron" ident="order_of_membership" xml:lang="en">
            <desc>Added per <ref target="https://github.com/TEIC/TEI/issues/2463">#2463</ref>.</desc>
            <constraint>
              <sch:rule context="tei:classes">
                <sch:let name="keys_as_specified" value="tei:memberOf/@key"/>
                <sch:let name="keys_in_order"
                         value="if ( $keys_as_specified = 'att.global' )
                                then ( 'att.global', sort( $keys_as_specified )[. ne 'att.global'] )
                                else sort( $keys_as_specified )" />
                <sch:assert test="string-join( $keys_as_specified ) eq string-join( $keys_in_order )">
                  class membership (in this case of <sch:value-of select="ancestor::*[@ident][1]/@ident"/>) should be specified in sorted order, except att.global goes first.
                </sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </elementSpec>

        <elementSpec ident="content" mode="change" module="tagdocs">
          <content>
            <choice xmlns="http://relaxng.org/ns/structure/1.0">
              <group>
                <ref name="valList"/>
              </group>
              <oneOrMore>
                <ref name="anyRelax"/>
              </oneOrMore>
              <zeroOrMore>
                <ref name="model.contentPart"/>
              </zeroOrMore>
            </choice>
          </content>
        </elementSpec>

        <macroSpec ident="anyRelax" mode="add">
          <content>
            <element xmlns="http://relaxng.org/ns/structure/1.0">
              <nsName ns="http://relaxng.org/ns/structure/1.0"/>
              <zeroOrMore>
                <choice>
                  <attribute>
                    <anyName/>
                  </attribute>
                  <ref name="anyRelax"/>
                  <text/>
                </choice>
              </zeroOrMore>
            </element>
          </content>
        </macroSpec>

        <elementSpec mode="change" ident="TEI">
          <constraintSpec ident="must-have-attglobal" scheme="schematron" mode="add" xml:lang="en">
            <constraint>
              <sch:rule context="tei:elementSpec[not(@mode)]">
                <sch:assert test="tei:classes/tei:memberOf[@key='att.global']">Error: TEI element <sch:value-of select="@ident"/> must be member of att.global class</sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </elementSpec>

        <elementSpec ident="remarks" mode="change">          
          <constraintSpec ident="only-one-remark-per-lang" scheme="schematron" mode="add" xml:lang="en">
            <constraint>
              <sch:rule context="tei:remarks[@xml:lang]">
                <sch:let name="langVal" value="@xml:lang"/>
                <sch:assert test="not(following-sibling::tei:remarks[@xml:lang=$langVal])">
                  Error: There should only be one <sch:value-of select="@ident"/> element per 
                  language. Merge the contents of multiple <sch:value-of select="@ident"/> elements
                  using separate p elements.
                </sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </elementSpec>

        <!-- Per TEI ticket #2285, restrict where <altIdent> can go in GLs. -->
        <elementSpec ident="altIdent" module="tagdocs" mode="change">
          <constraintSpec scheme="schematron" ident="restricted-altIdent-placement" xml:lang="en">
            <constraint>
              <sch:rule context="tei:altIdent">
                <sch:assert test="parent::tei:elementSpec|parent::tei:attDef|parent::tei:valItem">The &lt;altIdent> element should only be used as a child of &lt;elementSpec>, &lt;attDef>, or &lt;valItem>.</sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </elementSpec>
        
        <dataSpec ident="teidata.temporal.working" mode="change">
          <constraintSpec ident="not_in_future" scheme="schematron" xml:lang="en">
            <desc>When a <att>versionDate</att> is specified, its value
            should not be in the future.</desc>
            <!-- Note that this constraint is fired on the specific *attributes* that
            are members of teidata.temporal.working. So if the membership of the datatype
            changes, we should change the context, below, to match. -->
            <constraint>
              <sch:rule context="*[@versionDate]">
                <sch:let name="tomorrow" value="current-date() + 'P1D' cast as xs:dayTimeDuration"/>
                <sch:assert test="@versionDate cast as xs:date le $tomorrow">The date of a translation should not be in the future.</sch:assert>
              </sch:rule>
            </constraint>
          </constraintSpec>
        </dataSpec>
        
      </schemaSpec>
    </body>
  </text>
</TEI>
