%D \module
%D   [      file=x-sch-00,
%D        version=2001.10.02,
%D          title=\CONTEXT\ Style File,
%D       subtitle=XML Schema Basics,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D Schema support was implemented right after euro\TeX\ 2001,
%D when Tobias Burnus send me a schema for the XML figure
%D base. Since it happened that I needed schemata for other
%D projects too, I wrote this mapper. Thanks to Tobias for
%D testing it.

\newcounter\XSDprefix
\newif\ifXDScomposite

\definelist     [xsd:names]
\defineregister [xsd:index] [xsd:indices]

\setuplist      [xsd:names] [expansion=yes]
\setupregister  [xsd:index] [expansion=yes]

\def\dodoXSDkeyval#1#2#3%
  {\framed
     [width=\hsize,background=color,backgroundcolor=xsd:0,
      framecolor=xsd:0,frame=off,align=right]
     {\hbox to 5em % %to 8em % .2\hsize
        {\bf
        %\doifsomething{#1}{#1 }
         \ignorespaces#2\unskip\hss}
        %\ignorespaces#2\unskip:}%
      \space
      \ignorespaces#3\unskip}}

\def\doXSDkeyval#1#2#3#4%
  {\bgroup
   \edef\XSDtemp{\XMLpar{#3}{#4}{}}%
   \doifsomething{\XSDtemp}
     {\def\doXSDtemp{\dodoXSDkeyval{#1}{#2}{\XSDtemp}}%
      \def\doXSDtype{\dodoXSDkeyval{#1}{#2}{\XMLtyp{#3}{#4}{}}}%
      \setupinteraction[color=,contrastcolor=,style=]%
      \processaction
        [#4]
        [  value=>\doXSDtype,
            name=>{\writetolist[xsd:names]{}{\XSDtemp}%
                   \writetoregister[xsd:index]{\XSDtemp}%
                   \ifXDScomposite \else
                     \pagereference[xsd:\XSDprefix:\XSDtemp]%
                   \fi
                   \doXSDtemp},
            type=>{\doifinstringelse{xsd:}{\XSDtemp}
                     {\doXSDtemp}
                     {\gotobox{\doXSDtemp}[xsd:\XSDprefix:\XSDtemp]}},
             ref=>{\doifinstringelse{xsd:}{\XSDtemp}
                     {\doXSDtemp}
                     {\gotobox{\doXSDtemp}[xsd:\XSDprefix:\XSDtemp]}},
         unknown=>\doXSDtemp]}%
   \endgraf
   \egroup}

\def\doXSDkeyvals#1#2#3%
  {\def\docommand##1{\doXSDkeyval{#1}{##1}{#2}{##1}}%
   \processcommalist[#3]\docommand}

\def\dodoXSDbanner#1%
  {\framed
     [width=\hsize,framecolor=xsd:0,frame=off,
      background=color,backgroundcolor=xsd:0]
     {\ignorespaces#1\unskip}}

\def\doXSDtitle#1#2#3%
 {\edef\XSDtemp{\XMLpar{#2}{#3}{}}%
  \dodoXSDbanner
    {{\bf\ignorespaces#1\unskip}%
     \doifsomething{\XSDtemp}
       {:\space\ignorespaces\XSDtemp\unskip
        \pagereference[xsd:\XSDprefix:\XSDtemp]}}}

\def\doXSDbanner#1%
  {\dodoXSDbanner{\bf#1}}

%D We use colored backgrounds for meaningful blocks.

\definecolor [xsd:0] [white]

\definecolor [xsd:1] [s=.30]
\definecolor [xsd:2] [s=.55]
\definecolor [xsd:3] [s=.70]
\definecolor [xsd:4] [s=.85]

\definecolor [xsd:5] [r=.6,g=.7,b=.8]
\definecolor [xsd:6] [r=.7,g=.8,b=.6]
\definecolor [xsd:7] [r=1,g=1,b=.6]
\definecolor [xsd:8] [r=.8,g=.7,b=.6]

\defineframedtext [XSDannotation]     [backgroundcolor=xsd:0]

\defineframedtext [XSDelement]        [backgroundcolor=xsd:5]
\defineframedtext [XSDattribute]      [backgroundcolor=xsd:6]
\defineframedtext [XSDsimpleType]     [backgroundcolor=xsd:7]
\defineframedtext [XSDcomplexType]    [backgroundcolor=xsd:8]

\defineframedtext [XSDcomplexContent] [backgroundcolor=xsd:1]
\defineframedtext [XSDsimpleContent]  [backgroundcolor=xsd:1]
\defineframedtext [XSDattributeGroup] [backgroundcolor=xsd:1]

\defineframedtext [XSDcapsule]        [backgroundcolor=xsd:2]
\defineframedtext [XSDsequence]       [backgroundcolor=xsd:3]

\def\XDSstructures% handy for external settings
  {XSDannotation,
   XSDcomplexType,XSDsimpleType,XSDelement,XSDattribute,
   XSDcomplexContent,XSDsimpleContent,XSDattributeGroup,
   XSDcapsule,XSDsequence}

\setupframedtexts
  [\XDSstructures]
  [width=\hsize,
   offset=.5\bodyfontsize,
   location=none,
   background=color,
   framecolor=xsd:0,
   before=\ifinframed\else\blank\fi,
   after=\ifinframed\else\blank\fi,
   depthcorrection=off,
   rulethickness=1pt,
   strut=no]

\definesymbol[xsd][{\blackrule[width=4em]}]

\def\placeXSDlegenda
  {\startbaselinecorrection
   \starttabulate[|l|l|]
   \HL
   \NC \bf color                   \NC \bf meaning    \NC \NR
   \HL
   \NC \color[xsd:1]{\symbol[xsd]} \NC complexContent \unskip\quad
                                       simpleContent  \unskip\quad
                                       attributeGroup \NC \NR
   \NC \color[xsd:2]{\symbol[xsd]} \NC capsule        \NC \NR
   \NC \color[xsd:3]{\symbol[xsd]} \NC sequence       \NC \NR
   \HL
   \NC \color[xsd:5]{\symbol[xsd]} \NC element        \NC \NR
   \NC \color[xsd:6]{\symbol[xsd]} \NC attribute      \NC \NR
   \NC \color[xsd:7]{\symbol[xsd]} \NC simpleType     \NC \NR
   \NC \color[xsd:8]{\symbol[xsd]} \NC complexType    \NC \NR
   \HL
   \stoptabulate
   \stopbaselinecorrection}

\defineXMLenvironment [xsd:all] [id=]
  {\startXSDcapsule
   \doXSDbanner{all}
   \doXSDkeyvals{all}{xsd:all}{id}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:annotation]
  {\startXSDcapsule
   \doXSDbanner{annotation}
   \startXSDannotation}
  {\stopXSDannotation
   \stopXSDcapsule}

\defineXMLignore [xsd:appInfo]

\defineXMLenvironment [xsd:attribute]
  [id=,name=,ref=,type=,form=,use=,value=]
  {\startXSDattribute
   \doifelsenothing{\XMLpar{xsd:attribute}{ref}{}}
     {\doXSDkeyvals{attribute}{xsd:attribute}{name,type}}
     {\doXSDkeyvals{attribute}{xsd:attribute}{ref}}
   \doXSDkeyvals{attribute}{xsd:attribute}{id,form,use,value}
   \XDScompositetrue}
  {\stopXSDattribute}

\defineXMLenvironment [xsd:attributeGroup] [id=,name=,ref=]
  {\startXSDattributeGroup
   \doXSDtitle{attribute group}{xsd:attributeGroup}{name}
   \doXSDkeyvals{attr group}{xsd:attributeGroup}{id,name,ref}
   \XDScompositetrue}
  {\stopXSDattributeGroup}

\defineXMLenvironment [xsd:choice] [id=,minOccurs=,maxOccurs=]
  {\startXSDcapsule
   \doXSDbanner{choice}
   \doXSDkeyvals{choice}{xsd:choice}{id,minOccurs,maxOccurs}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:complexContent] [id=,mixed=]
  {\startXSDcomplexContent
   \doXSDkeyvals{complex content}{xsd:complexContent}{id,mixed}
   \XDScompositetrue}
  {\stopXSDcomplexContent}

\defineXMLenvironment [xsd:complexType]
     [id=,abstract=,block=,final=,mixed=,name=]
  {\startXSDcomplexType
   \doXSDtitle{complex type}{xsd:complexType}{name}
   \doXSDkeyvals{complex type}{xsd:complexType}{id,abstract,block,final,mixed}
   \XDScompositetrue}
  {\stopXSDcomplexType}

\defineXMLenvironment [xsd:documentation] [source=,xml:lang=]
  {\endgraf\bgroup\setupwhitespace[big]}
  {\endgraf\egroup}

\defineXMLenvironment [xsd:element]
  [name=,type=,ref=,
   abstract=,block=,default=,final=,fixed=,form=,id=,
   minOccurs=,maxOccurs=,nullable=,substitutionGroup=]
  {\startXSDelement
   \doifelsenothing{\XMLpar{xsd:element}{ref}{}}
     {\doXSDkeyvals{element}{xsd:element}{name,type}}
     {\doXSDkeyvals{element}{xsd:element}{ref}}
   \doXSDkeyvals{element}{xsd:element}
     {id,abstract,block,default,final,fixed,form,
      minOccurs,maxOccurs,nullable,substitutionGroup}
   \XDScompositetrue}
  {\stopXSDelement}

\defineXMLenvironment [xsd:extension] [id=,base=]
  {\startXSDcapsule
   \doXSDbanner{extension}
   \doXSDkeyvals{extension}{xsd:extension}{id,base}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:group]
     [id=,name=,ref=,minOccurs=,maxOccurs=]
  {\startXSDcapsule
   \doXSDbanner{group}
   \doXSDkeyvals{group}{xsd:group}{id,name,ref,minOccurs,maxOccurs}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:key] [id=,name=]
  {\startXSDcapsule
   \doXSDbanner{key}
   \doXSDkeyvals{key}{xsd:key}{id,name}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:keyref] [id=,name=,refer=]
  {\startXSDcapsule
   \doXSDbanner{keyref}
   \doXSDkeyvals{key ref}{xsd:keyref}{id,name,refer}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:list] [id=,itemType=]
  {\startXSDcapsule
   \doXSDbanner{list}
   \doXSDkeyvals{list}{xsd:list}{id,itemType}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:redefine] [schemaLocation=]
  {\startXSDcapsule
   \doXSDbanner{redefine}
   \doXSDkeyvals{redefine}{xsd:redefine}{schemaLocation}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:restriction] [id=,base=]
  {\startXSDcapsule
   \doXSDbanner{restriction}
   \doXSDkeyvals{restriction}{xsd:restriction}{id,base}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:schema]
    [attributeFormDefault=,blockDefault=,elementFormDefault=,
     finalDefault=,id=,targetNamespace=,version=]
  {\startXSDcapsule
   \doglobal\increment\XSDprefix
   \doXSDbanner{schema}
   \doXSDkeyvals{schema}{xsd:schema}
    {attributeFormDefault,blockDefault,elementFormDefault,
     finalDefault,id,targetNamespace,version}
   \stopXSDcapsule}
  {}

\defineXMLenvironment [xsd:sequence] [id=,minOccurs=,maxOccurs=]
  {\startXSDsequence
   \doXSDbanner{sequence}
   \doXSDkeyvals{sequence}{xsd:sequence}{id,minOccurs,maxOccurs}
   \XDScompositetrue}
  {\stopXSDsequence}

\defineXMLenvironment [xsd:simpleContent] [id=]
  {\startXSDsimpleContent
   \doXSDkeyvals{simple content}{xsd:simpleContent}{id}
   \XDScompositetrue}
  {\stopXSDsimpleContent}

\defineXMLenvironment [xsd:simpleType] [id=,name=]
  {\startXSDsimpleType
   \doXSDtitle{simple type}{xsd:simpleType}{name}
   \doXSDkeyvals{simple type}{xsd:simpleType}{id}
   \XDScompositetrue}
  {\stopXSDsimpleType}

\defineXMLenvironment [xsd:union] [id=,memberTypes=]
  {\startXSDcapsule
   \doXSDbanner{union}
   \doXSDkeyvals{union}{xsd:union}{id,memberTypes}
   \XDScompositetrue}
  {\stopXSDcapsule}

\defineXMLenvironment [xsd:unique] [id=,name=]
  {\startXSDcapsule
   \doXSDbanner{unique}
   \doXSDkeyvals{unique}{xsd:unique}{id,name}
   \XDScompositetrue}
  {\stopXSDcapsule}

\def\defineXSDfacet
  {\dotripleempty\dodefineXSDfacet}

\def\dodefineXSDfacet[#1][#2][#3]%
  {\defineXMLenvironment[xsd:#1][#2]
     {\startXSDcapsule
      \doXSDkeyvals{#1}{xsd:#1}{#3}
      \XDScompositetrue}
     {\stopXSDcapsule}
   \defineXMLsingular[xsd:#1][#2]
     {\doXSDkeyvals{#1}{xsd:#1}{#3}}}

\defineXSDfacet [duration]     [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [encoding]     [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [enumeration]  [id=,value=,fixed=] [id,value,fixed]

\defineXSDfacet [length]       [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [minLength]    [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [maxLength]    [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [minInclusive] [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [maxInclusive] [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [minExclusive] [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [maxExclusive] [id=,value=,fixed=] [id,value,fixed]

\defineXSDfacet [pattern]      [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [period]       [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [precision]    [id=,value=,fixed=] [id,value,fixed]
\defineXSDfacet [scale]        [id=,value=,fixed=] [id,value,fixed]

\defineXSDfacet [field]        [id=,xpath=]        [id,xpath]
\defineXSDfacet [selector]     [id=,xpath=]        [id,xpath]

\defineXSDfacet
  [any]
  [id=,namespace=,minOccurs=,maxOccurs=,processContents=]
  [id,namespace,minOccurs,maxOccurs,processContent]

\defineXSDfacet
  [anyAttribute]
  [id=,namespace=,processContents=]
  [id,namespace,processContents]

\defineXSDfacet
  [import]
  [id=,namespace=,schemaLocation=]
  [id,namespace,schemaLocation]

\defineXSDfacet
  [include]
  [id=,schemaLocation=]
  [id,schemaLocation]

\defineXSDfacet
  [notation]
  [id=,name=,public=,system=]
  [id,name,public,system]

\endinput
