# 
# XML Document Type Definition for GNUstep Documentation Markup
# Language (gsdoc).
# 
# Written by Richard Frith-Macdonald
# Based on GDML by 1997 Yoo C. Chung
 
# This 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 of the License, or (at your option) any later
# version.
# 
# This document 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.
# 
# You should have received a copy of the GNU General
# Public License along with this software; if not, write to the
# Software Foundation, Inc., 31 Milk Street #960789 Boston, MA 02196 USA.


#############################################################################
# Note, the normative form of this document is the DTD.
# This Relax-NG version generated by Adrian Robert using the trang tool.
# It can be used for realtime validation and autocompletion with the
# emacs nxml-mode by James Clark. Get it from
# http://www.thaiopensource.com/download/ .
#
# Set it up with '(load "nxml-mode-20040910/rng-auto.el")' in your .emacs.
# While you're at it, put insert this as well:
# (setq auto-mode-alist (cons '("\\.gsdoc$" . nxml-mode) auto-mode-alist))
#
# Fire up a new emacs and hit 'alt-x customize-apropos rng', then add a file
# "/pathToHome/[username]/.schemas.xml" to 'Rng Schema Locating Files'.
# Then make a file in your home directory called ".schemas.xml" and put in
# it the following lines:
#
#  <?xml version="1.0" encoding="utf-8"?>
#  <locatingRules xmlns="http://thaiopensource.com/ns/locating-rules/1.0">
#     <uri pathSuffix=".gsdoc"
#          uri="$GNUSTEP_SYSTEM_LIBRARY/DTDs/gsdoc-1_0_1.rnc"/>
#  </locatingRules>
#
# (Replace GNUSTEP_SYSTEM_LIBRARY by the correct real path on your system.)
#
# Voila, whenever you edit a .gsdoc file its validity will be continuously
# checked, errors will be highlighted, and you can complete tags and
# attributes using 'ctrl-enter'.  'Ctrl-c ctrl-f' autocloses tags.
#############################################################################


# gsdoc is an XML language - Typical usage:
# <?xml version="1.0"?>
# <!DOCTYPE gsdoc PUBLIC "-//GNUstep//DTD gsdoc 1.0.3//EN"
#       "http://www.gnustep.org/gsdoc.xml">
# <gsdoc base="myDocName">
# </gsdoc>

# ***** Character entities. *****

# General purpose characters for gsdoc.

# copyright symbol

# trademark symbol

# ellipsis (...)

# non breakable space

# ampersand

# apos

# quotation mark (")

# lesser than symbol

# greater than symbol

namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"

# ***** Entity declarations. *****

# Boolean values for attributes
boolean = "yes" | "no"

# Entity for phrase elements.
phrase =
    element.var
  | element.ivar
  | element.em
  | element.code
  | element.strong
  | element.file
  | element.site

# Entity for cross references.
xref =
    element.ref
  | element.uref
  | element.url
  | element.email
  | element.prjref

# Entity for anchors.
anchor = element.label | element.entry

# Entity for simple text level elements.
\text = text | xref | anchor | phrase | element.footnote | element.br

# Entity for list elements.
\list =
    element.list
  | element.enum
  | element.deflist
  | element.qalist
  | element.dictionary

# Entity for block level elements.
block =
    \text
  | \list
  | element.p
  | element.example
  | element.embed
  | element.index

# Entity for definition elements and blocks.
defblock =
    \text
  | \list
  | element.heading
  | element.p
  | element.example
  | element.embed
  | element.index
  | element.class
  | element.category
  | element.protocol
  | element.function
  | element.macro
  | element.type
  | element.variable
  | element.constant
  | element.EOModel
  | element.EOEntity

# ********** End entity declarations


# Used for describing something.
element.desc = element desc { attlist.desc, block* }
attlist.desc &= empty

# A footnote.
element.footnote = element footnote { attlist.footnote, \text* }
attlist.footnote &= empty


# ***** Phrase elements. *****

# The content is a metasyntactic variable or argument name.
element.var = element var { attlist.var, \text* }
attlist.var &= empty

# The content is a metasyntactic ivariable name.
element.ivar = element ivar { attlist.ivar, \text* }
attlist.ivar &= empty

# Emphasize the content.
element.em = element em { attlist.em, \text* }
attlist.em &= empty

# The content is too important that simple emphasizing isn't enough.
element.strong = element strong { attlist.strong, \text* }
attlist.strong &= empty

# The content is either a name for code (e.g. class names), or a
# relatively short code fragment.
element.code = element code { attlist.code, \text* }
attlist.code &= empty

# The content is a file name.
element.file = element file { attlist.file, text* }
attlist.file &= empty

# The content is a fully qualified domain name on the Internet.
element.site = element site { attlist.site, text* }
attlist.site &= empty


# ***** List elements. *****

# An item in a list.
element.item = element item { attlist.item, block* }
attlist.item &= empty

# An enumerated list.
element.enum = element enum { attlist.enum, element.item+ }
attlist.enum &= empty

# A ordinary, unnumbered list.
element.list = element list { attlist.list, element.item+ }
attlist.list &= empty

# A term to defined in a definition list.
element.term = element term { attlist.term, \text* }
attlist.term &= empty

# A definition list.
element.deflist =
  element deflist { attlist.deflist, (element.term, element.desc)+ }
attlist.deflist &= empty

# A question for a question and answer list.
element.question = element question { attlist.question, \text* }
attlist.question &= empty

# An answer for a question and answer list.
element.answer = element answer { attlist.answer, block* }
attlist.answer &= empty

# A question and answer list.
element.qalist =
  element qalist { attlist.qalist, (element.question, element.answer)+ }
attlist.qalist &= empty

# **********


# ***** Cross references. *****

# A reference.
# ID of the reference.
# TYPE of reference, if implied, a reference to a label.
# CLASS specific class for a method, may be one of the following formats -
#   classname, classname(categoryname), (protocolname)
element.ref = element ref { attlist.ref, \text* }
attlist.ref &=
  attribute id { text },
  [ a:defaultValue = "label" ]
  attribute type {
      "class"
    | "category"
    | "protocol"
    | "method"
    | "ivariable"
    | "function"
    | "type"
    | "macro"
    | "variable"
    | "constant"
    | "label"
    | "EOModel"
    | "EOEntity"
    | "tool"
  }?,
  attribute class { text }?

# An e-mail address.
element.email = element email { attlist.email, \text* }
attlist.email &= attribute address { text }?

# A URL.
element.url = element url { attlist.url, empty }
attlist.url &= attribute url { text }?

# A reference to a URL.
# The text contained appears in the output.
element.uref = element uref { attlist.uref, \text* }
attlist.uref &= attribute url { text }

# A reference to a project.
# The text contained appears in the output.
element.prjref = element prjref { attlist.prjref, \text* }
attlist.prjref &=
  attribute prjname { text }?,
  attribute file { text }?


# ***** Anchors. *****

# An anchor for a general reference.
# The text contained appears in the output.
# If the id attribute is omitted, the text is used in its place.
element.label = element label { attlist.label, \text* }
attlist.label &= attribute id { text }?

# An entry for the general index. 
#  The text that is contained appears in the index, and never in
#  the text itself.
# If the id attribute is omitted, the text is used in its place.
element.entry = element entry { attlist.entry, \text* }
attlist.entry &= attribute id { text }?

# Entity for standard elements.
element.GNUstep = element GNUstep { attlist.GNUstep, empty }
attlist.GNUstep &= empty
element.OpenStep = element OpenStep { attlist.OpenStep, empty }
attlist.OpenStep &= empty
element.NotOpenStep = element NotOpenStep { attlist.NotOpenStep, empty }
attlist.NotOpenStep &= empty
element.MacOS-X = element MacOS-X { attlist.MacOS-X, empty }
attlist.MacOS-X &= empty
element.NotMacOS-X = element NotMacOS-X { attlist.NotMacOS-X, empty }
attlist.NotMacOS-X &= empty

# A standard that something is or isn't  compliant with.
standard =
  element.GNUstep
  | element.OpenStep
  | element.NotOpenStep
  | element.MacOS-X
  | element.NotMacOS-X
element.standards = element standards { attlist.standards, standard* }
attlist.standards &= empty


# ***** Argument elements. *****

# An argument.
element.arg = element arg { attlist.arg, text* }
attlist.arg &= attribute type { text }?

# Denotes that the rest of the arguments is a variable list,
# like in printf().
element.vararg = element vararg { attlist.vararg, empty }
attlist.vararg &= empty


# ***** Method elements. *****

# A component for a method selector.
element.sel = element sel { attlist.sel, text* }
attlist.sel &= empty

# A method.  If there is no DESC, it is understood that the element
#    is used to override some information from the same method in the
#    superclass.
# If factory not set, instance method
element.method =
  element method {
    attlist.method,
    ((element.sel, element.arg?),
     (element.sel, element.arg)*,
     element.vararg?),
    element.desc?,
    element.standards?
  }
attlist.method &=
  attribute type { text }?,
  [ a:defaultValue = "no" ] attribute factory { boolean }?,
  [ a:defaultValue = "no" ] attribute init { boolean }?,
  attribute override { "subclass" | "never" }?


# ***** Elements for definitions of classes, functions, etc. *****

# Show what header file something lives in.
element.declared = element declared { attlist.declared, text* }
attlist.declared &= empty

# A macro definition.
element.macro =
  element macro {
    attlist.macro,
    (element.arg*, element.vararg?),
    element.declared?,
    element.desc?,
    element.standards?
  }
attlist.macro &= attribute name { text }

# A type definition.
element.type =
  element type {
    attlist.type, element.declared?, element.desc?, element.standards?
  }
attlist.type &=
  attribute name { text },
  attribute type { text }

# Variable definition.
# VALUE may be set for a constant or a default value
element.variable =
  element variable {
    attlist.variable,
    element.declared?,
    element.desc?,
    element.standards?
  }
attlist.variable &=
  attribute name { text },
  attribute type { text },
  attribute value { text }?

# Ivariable definition.
element.ivariable =
  element ivariable {
    attlist.ivariable, element.desc?, element.standards?
  }
attlist.ivariable &=
  attribute name { text },
  attribute type { text },
  [ a:defaultValue = "public" ]
  attribute validity { "public" | "protected" | "private" }?

# Constant definition.
# VALUE may be set for a constant or a default value
element.constant =
  element constant {
    attlist.constant,
    element.declared?,
    element.desc?,
    element.standards?
  }
attlist.constant &=
  attribute name { text },
  attribute type { text },
  attribute value { text }?,
  attribute role { "except" | "defaults" | "notify" | "key" }?

# A function definition.
element.function =
  element function {
    attlist.function,
    (element.arg*, element.vararg?),
    element.declared?,
    element.desc?,
    element.standards?
  }
attlist.function &=
  attribute name { text },
  attribute type { text }

# Protocol definition.
element.protocol =
  element protocol {
    attlist.protocol,
    element.declared?,
    element.conform*,
    element.desc?,
    element.method*,
    element.standards?
  }
attlist.protocol &= attribute name { text }

# Category definition.
element.category =
  element category {
    attlist.category,
    element.declared?,
    element.conform*,
    element.desc?,
    element.method*,
    element.standards?
  }
attlist.category &=
  attribute name { text },
  attribute class { text }

# Show a protocol a class conforms to.
element.conform = element conform { attlist.conform, text* }
attlist.conform &= empty
element.class =
  element class {
    attlist.class,
    element.declared?,
    element.conform*,
    element.desc?,
    element.ivariable*,
    element.method*,
    element.standards?
  }
attlist.class &=
  attribute name { text },
  attribute super { text }?


# ***** Elements for definitions of EOModels, etc. *****

# a dictionary Item.
element.dictionaryItem =
  element dictionaryItem { attlist.dictionaryItem, block* }
attlist.dictionaryItem &=
  attribute key { text },
  attribute value { text }?

# a dictionary
element.dictionary =
  element dictionary { attlist.dictionary, element.dictionaryItem+ }
attlist.dictionary &= empty
element.EOConnectionDictionary =
  element EOConnectionDictionary {
    attlist.EOConnectionDictionary, element.dictionaryItem+
  }
attlist.EOConnectionDictionary &= empty
element.EOUserDictionary =
  element EOUserDictionary {
    attlist.EOUserDictionary, element.dictionaryItem+
  }
attlist.EOUserDictionary &= empty

# EORelationshipComponent
element.EORelationshipComponent =
  element EORelationshipComponent {
    attlist.EORelationshipComponent, element.EORelationshipComponent*
  }
attlist.EORelationshipComponent &= attribute definition { text }

# EOJoin
element.EOJoin = element EOJoin { attlist.EOJoin, element.desc? }
attlist.EOJoin &=
  attribute relationshipName { text }?,
  attribute joinOperator { text },
  attribute joinSemantic { text },
  attribute sourceAttribute { text },
  attribute destinationAttribute { text }

# EORelationship
element.EORelationship =
  element EORelationship {
    attlist.EORelationship,
    (element.EORelationshipComponent | element.EOJoin*),
    element.EOUserDictionary?,
    element.desc?
  }
attlist.EORelationship &=
  attribute entityName { text },
  attribute destinationEntityName { text },
  attribute name { text },
  attribute isToMany { text }?

# EOAttributeRef
element.EOAttributeRef =
  element EOAttributeRef { attlist.EOAttributeRef, empty }
attlist.EOAttributeRef &= attribute name { text }

# EOPrimaryKeyAttributes
element.EOPrimaryKeyAttributes =
  element EOPrimaryKeyAttributes {
    attlist.EOPrimaryKeyAttributes, element.EOAttributeRef+
  }
attlist.EOPrimaryKeyAttributes &= empty

# EOClassProperties
element.EOClassProperties =
  element EOClassProperties {
    attlist.EOClassProperties, element.EOAttributeRef+
  }
attlist.EOClassProperties &= empty

# EOAttributesUsedForLocking
element.EOAttributesUsedForLocking =
  element EOAttributesUsedForLocking {
    attlist.EOAttributesUsedForLocking, element.EOAttributeRef+
  }
attlist.EOAttributesUsedForLocking &= empty

# EOAttribute
element.EOAttribute =
  element EOAttribute {
    attlist.EOAttribute, element.EOUserDictionary?, element.desc?
  }
attlist.EOAttribute &=
  attribute columnName { text }?,
  attribute definition { text }?,
  attribute externalType { text }?,
  attribute name { text },
  attribute valueClassName { text }?,
  attribute valueType { text }?,
  attribute entityName { text }?,
  attribute isReadOnly { text }?,
  attribute isDerived { text }?,
  attribute isFlattened { text }?

# EOEntity
element.EOEntity =
  element EOEntity {
    attlist.EOEntity,
    element.EOAttribute*,
    element.EOAttributesUsedForLocking?,
    element.EOClassProperties?,
    element.EOPrimaryKeyAttributes?,
    element.EORelationship*,
    element.EOUserDictionary?,
    element.desc?
  }
attlist.EOEntity &=
  attribute name { text },
  attribute externalName { text }?,
  attribute className { text }?,
  attribute modelName { text }?,
  attribute isReadOnly { text }?

# EOModel
element.EOModel =
  element EOModel {
    attlist.EOModel,
    element.EOConnectionDictionary?,
    (element.EOEntity+ | element.list),
    element.EOUserDictionary?,
    element.desc?
  }
attlist.EOModel &=
  attribute name { text },
  attribute version { text }?,
  attribute adaptorName { text },
  attribute adaptorClassName { text }


# ***** Elements for ordinary block level elements. *****

# A line break.
element.br = element br { attlist.br, empty }
attlist.br &= empty

# A paragraph.
element.p = element p { attlist.p, \text* }
attlist.p &= empty

# An example.
element.example = element example { attlist.example, text* }
attlist.example &= attribute caption { text }?

# An embedded object.  If it is of a type that the SGML processor
# cannot handle, then use the content, which is ignored otherwise.
# refer - method of referring to object (default is file)
# src - the reference to the object
# type - Internet media type of the objec
# title - optional title describing object
element.embed = element embed { attlist.embed, block* }
attlist.embed &=
  attribute refer { "file" | "url" }?,
  attribute src { text },
  attribute type { text }?,
  attribute title { text }?


# ***** Elements for document structure such as chapters. *****

# A heading for chapters, sections, ...
element.heading = element heading { attlist.heading, \text* }
attlist.heading &= empty

# A subsubsection.
element.subsubsect =
  element subsubsect { attlist.subsubsect, defblock* }
attlist.subsubsect &= attribute id { text }?

# A subsection.
element.subsect =
  element subsect { attlist.subsect, (defblock | element.subsubsect)* }
attlist.subsect &= attribute id { text }?

# A section.
element.section =
  element section { attlist.section, (defblock | element.subsect)* }
attlist.section &= attribute id { text }?

# A chapter.
element.chapter =
  element chapter { attlist.chapter, (defblock | element.section)* }
attlist.chapter &= attribute id { text }?


# ***** Elements that make searching for things easier. *****

# Table of contents.
element.contents = element contents { attlist.contents, empty }
attlist.contents &= empty

# Index  ... generates an index of the specified type of elements.
# 'scope' determines whether the index is generated for the current file
# or for the whole of the current project, or for everything the software
# can find (global) ... if the document is processed in a standalone manner,
# the scope if always file.  For method or ivariable indexing, if the index
# is inside a class, protocol, or category, only  indexes for that unit
# should be generated.
# 'type' determines the type of entry listed in the index.  The 'title'
# type really only makes sense for a project scope index as it produces
# a list of the files in the project (by title).
element.index = element index { attlist.index, empty }
attlist.index &=
  [ a:defaultValue = "label" ]
  attribute type {
      "class"
    | "category"
    | "protocol"
    | "method"
    | "ivariable"
    | "function"
    | "type"
    | "macro"
    | "variable"
    | "constant"
    | "EOModel"
    | "EOEntity"
    | "label"
    | "title"
    | "tool"
  }?,
  [ a:defaultValue = "file" ]
  attribute scope { "file" | "project" | "global" }?,
  [ a:defaultValue = "normal" ] attribute style { "normal" | "bare" }?,
  attribute target { text }?


# ***** Elements that describe the document itself. *****

# Copyright of the document.
element.copy = element copy { attlist.copy, \text* }
attlist.copy &= empty

# An abstract.
element.abstract = element abstract { attlist.abstract, \text* }
attlist.abstract &= empty

# The version of the document.
element.version = element version { attlist.version, \text* }
attlist.version &= empty

# The date the document was written.
element.date = element date { attlist.date, \text* }
attlist.date &= empty

# An author.
element.author =
  element author {
    attlist.author, element.email?, element.url?, element.desc?
  }
attlist.author &= attribute name { text }

# The title of the document.
element.title = element title { attlist.title, \text* }
attlist.title &= empty


# ***** The topmost structures for the document body. *****

# Unnumbered parts appearing in the front, such as a preface.
element.front =
  element front { attlist.front, element.contents?, element.chapter* }
attlist.front &= empty

# Unnumbered parts appearing in the back, such as an afterword and/or
# indices.
element.back =
  element back { attlist.back, element.chapter*, element.index* }
attlist.back &= empty


# ***** The topmost structures for the document. *****

# The head containing general information about the document.
element.head =
  element head {
    attlist.head,
    element.title,
    element.author*,
    element.version?,
    element.date?,
    element.abstract?,
    element.copy?
  }
attlist.head &= empty

# The main part of the document.
element.body =
  element body {
    attlist.body, element.front?, element.chapter+, element.back?
  }
attlist.body &= empty
# **********


# The entire document.
element.gsdoc =
  element gsdoc { attlist.gsdoc, element.head, element.body }
attlist.gsdoc &=
  attribute base { text }?,
  attribute next { text }?,
  attribute prev { text }?,
  attribute up { text }?,
  attribute stylesheeturl { text }?
start = element.gsdoc
