# $Id$

start = publidoc


publidoc = element publidoc {
   publidoc.attributes,
   publidoc.content
}

publidoc.attributes =
   version.attribute
version.attribute = attribute version { "1.0" }

publidoc.content =
   document
 | top.topic


# =============================================================================
#                                  TOP LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ top.head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

top.head = element head { top.head.content }

top.head.content =
   (title, shorttitle?, subtitle?)?
 & (identifier, identifier?)?
 & copyright*
 & collection?
 & contributors?
 & date?
 & place?
 & (source, source?)?
 & keywordset?
 & subjectset?
 & abstract?
 & cover?
 & annotation*

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ document ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ document
document = element document { document.attributes, document.content }

document.attributes =
   document.id.attribute
 & document.type.attribute?
 & lang.attribute?
document.id.attribute = attribute id { xsd:NMTOKEN }
document.type.attribute = attribute type { xsd:NCName }
lang.attribute = attribute xml:lang { xsd:language }

document.content =
   top.head?,
   (division | topic)+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ topic ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

top.topic = element topic { top.topic.attributes, top.topic.content }

top.topic.attributes =
   topic.id.attribute
 & topic.type.attribute?
 & lang.attribute?
topic.id.attribute = attribute id { xsd:NMTOKEN }
topic.type.attribute = attribute type { xsd:NCName }

top.topic.content =
   top.head?,
   header?,
   ((section+, bibliography?) | bibliography),
   footer?


# =============================================================================
#                                 DIVISION LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ division ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ division
division = element division { division.content }

division.content =
   division.head?,
   (division | topic)+

# ~~~~~~ division.head
division.head = element head { division.head.content }

division.head.content =
   (title, shorttitle?, subtitle?)?
 & abstract?
 & annotation*


# =============================================================================
#                                COMPONENT LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ component.head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

component.head = element head { component.head.content }

component.head.content =
   (title, shorttitle?, subtitle?)?
 & contributors?
 & date?
 & place?
 & keywordset?
 & subjectset?
 & abstract?
 & annotation*

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ topic ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

topic = element topic { topic.attributes, topic.content }

topic.attributes =
   (topic.id.attribute | xmlid.attribute)?
 & topic.type.attribute?
 & lang.attribute?
xmlid.attribute = attribute xml:id { xsd:ID }

topic.content =
   component.head?,
   header?,
   ((section+, bibliography?) | bibliography),
   footer?


# =============================================================================
#                                 SECTION LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ header ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

header = element header { header.content }

header.content =
   block+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ section
section = element section { section.attributes, section.content }

section.attributes =
   section.type.attribute?
 & lang.attribute?
 & for.attribute?
section.type.attribute = attribute type { xsd:NCName }
for.attribute = attribute for { xsd:NCName }

section.content =
   section.head?,
   (section+ | block+)

# ~~~~~~ section.head
section.head = element head { section.head.content }

section.head.content =
   (title, shorttitle?, subtitle?)?
 & keywordset?
 & subjectset?
 & abstract?
 & audio*
 & annotation*

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bibliography ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ bibliography
bibliography = element bibliography { bibliography.content }

bibliography.content =
   bibliography.entry+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ footer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

footer = element footer { footer.content }

footer.content =
   block+


# =============================================================================
#                                 BLOCK LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ block ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ block
block = (p | speech | \list | blockquote | table | media)

# ~~~~~~ block.head
block.head = element head { block.head.content }

block.head.content =
   (title, shorttitle?, subtitle?)?

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

p = element p { p.content }

p.content =
   inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ speech ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ speech
speech = element speech { speech.content }

speech.content =
   speaker?,
   stage?,
   (p | blockquote)+

# ~~~~~~ speaker
speaker = element speaker { speaker.content }

speaker.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ list
\list = element list {
   block.head?,
   (  (attribute type {"ordered"}?, item, item+)
    | (attribute type {"glossary"}, glossary.item+) )
}

# ~~~~~~ item
item = element item { item.content }

item.content =
   inlines
 | block+

# ~~~~~~ glossary.item
glossary.item = element item { glossary.item.content }

glossary.item.content =
   label,
   block+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blockquote ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ blockquote
blockquote = element blockquote { blockquote.content }

blockquote.content =
   block.head?,
   (p | speech | \list)+,
   attribution?

# ~~~~~~ attribution
attribution = element attribution { attribution.content }

attribution.content =
   inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ table
table = element table { table.content }

table.content =
   block.head?,
   tgroup+,
   table.caption?

# ~~~~~~ tgroup
tgroup = element tgroup { tgroup.attributes, tgroup.content }

tgroup.content =
   thead?,
   tbody

tgroup.attributes =
   cols.attribute
 & align.attribute?
 & colsep.attribute?
 & rowsep.attribute?
cols.attribute = attribute cols { xsd:positiveInteger }
align.attribute = attribute align { "left"  |  "right"  | "center" | "justify" }
colsep.attribute = attribute colsep { "0" | "1" }
rowsep.attribute = attribute rowsep { "0" | "1" }

# ~~~~~~ thead, tbody
thead = element thead { thead.attributes, thead.content }
tbody = element tbody { tbody.attributes, tbody.content }

thead.attributes =
   valign.attribute?
tbody.attributes =
   valign.attribute?
valign.attribute = attribute valign { "top" | "middle" | "bottom" }

thead.content =
   row+
tbody.content =
   row+

# ~~~~~~ row
row = element row { row.attributes, row.content }

row.attributes =
   valign.attribute?
 & rowsep.attribute?

row.content =
  table.entry+

# ~~~~~~ table.entry
table.entry = element entry { table.entry.attributes, table.entry.content }

table.entry.attributes =
   align.attribute?
 & valign.attribute?
 & colsep.attribute?
 & rowsep.attribute?

table.entry.content =
   inlines
 | (p | media)+

# ~~~~~~ table.caption
table.caption = element caption { caption.content }

caption.content =
   inlines
 | (p | speech | \list | blockquote)+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ media ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ media
media = element media { media.content }

media.content =
   block.head?,
   (image | audio | video)+,
   media.caption?,
   link?

# ~~~~~~ image
image = element image { image.attributes, image.content }
hotspot.image = element image {image.attributes }

image.attributes =
   media.id.attribute
 & image.type?
media.id.attribute = attribute id { xsd:NMTOKEN }
image.type = attribute type { "cover" | "thumbnail" | "icon" | "animation" }

image.content =
   copyright?,
   hotspot*

# ~~~~~~ audio
audio = element audio { audio.attributes }

audio.attributes =
   media.id.attribute
 & audio.type?
audio.type = attribute type { "music" | "voice" | "background" | "smil" }

# ~~~~~~ video
video = element video { video.attributes }

video.attributes =
   media.id.attribute

# ~~~~~~ hotspot
hotspot = element hotspot { hotspot.attributes, hotspot.content }

hotspot.attributes =
   x.attribute
 & y.attribute
 & w.attribute
 & h.attribute?
 & hotspot.type.attribute?
 & xmlid.attribute?
x.attribute = attribute x { xsd:token {pattern = "\d{1,2}(\.\d{1,2})?%"} }
y.attribute = attribute y { xsd:token {pattern = "\d{1,2}(\.\d{1,2})?%"} }
w.attribute = attribute w { xsd:token {pattern = "\d{1,2}(\.\d{1,2})?%"} }
h.attribute = attribute h { xsd:token {pattern = "\d{1,2}(\.\d{1,2})?%"} }
hotspot.type.attribute = attribute type { "normal" | "visible" | "pulse" }
   
hotspot.content =
   ((link | p+ | hotspot.image | audio | video), (spot, scenario?)?)
 | (spot, scenario?)
   
# ~~~~~~ spot
spot = element spot { spot.attributes, spot.content }

spot.attributes =
   dx.attribute?
 & dy.attribute?
 & dw.attribute?
 & dh.attribute?
dx.attribute = attribute dx { xsd:token {pattern = "-?\d{1,2}(\.\d{1,2})?%"} }
dy.attribute = attribute dy { xsd:token {pattern = "-?\d{1,2}(\.\d{1,2})?%"} }
dw.attribute = attribute dw { xsd:token {pattern = "-?\d{1,2}(\.\d{1,2})?%"} }
dh.attribute = attribute dh { xsd:token {pattern = "-?\d{1,2}(\.\d{1,2})?%"} }

spot.content =
   ((p+ | image), audio?)
 | audio
 | video

# ~~~~~~ media.caption
media.caption = element caption { caption.attributes, caption.content }

caption.attributes =
   x.attribute?
 & y.attribute?

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ scenario ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ scenario
scenario = element scenario { scenario.content }

scenario.content =
   init*,
   onclick*

# ~~~~~~ init
init = element init { init.attributes }

init.attributes =
   init.action.attribute
 & target.attribute?
init.action.attribute = attribute action { "hide" }
target.attribute = attribute target { "hotspot" | "spot" }

# ~~~~~~ onclick
onclick = element onclick { onclick.attributes }

onclick.attributes =
   onclick.action.attribute
 & target.attribute?
onclick.action.attribute = attribute action { "show" }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bibliograpgy.entry ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ bibliography.entry
bibliography.entry = element entry { bibliography.entry.content }

bibliography.entry.content =
   identifier.ean?
 & title
 & subtitle?
 & copyright?
 & collection?
 & contributors?
 & date?
 & place?
 & folio?
 & pages?

# ~~~~~~ folio
folio = element folio { folio.content }

folio.content = xsd:positiveInteger | xsd:token {pattern = "[DLXVI]+"}

# ~~~~~~ pages
pages = element pages { pages.content }

pages.content = xsd:positiveInteger


# =============================================================================
#                                 HEAD LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~ title, shorttitle, subtitle ~~~~~~~~~~~~~~~~~~~~~~~~~

title = element title { title.content }
shorttitle = element shorttitle { title.content }
subtitle = element subtitle { title.content }

title.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ identifier ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

identifier = element identifier {
   (attribute type { "ean" }, xsd:token {pattern = "\d{13}"})
 | (attribute type { "uri" }, xsd:anyURI)
}

identifier.ean = element identifier {
   attribute type { "ean" }, xsd:token {pattern = "\d{13}"}
}

identifier.uri = element identifier {
   attribute type { "uri" }, xsd:anyURI
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ copyright ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

copyright = element copyright { copyright.content }

copyright.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ collection ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

collection = element collection { collection.content }

collection.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ contributors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ contributors
contributors = element contributors { contributors.content }

contributors.content =
   contributor+

# ~~~~~~ contributor
contributor = element contributor { contributor.content }

contributor.content =
   (((firstname, secondname?)?, lastname) | label),
   address?,
   link?,
   role+

# ~~~~~~ firstname, secondname, lastname, label
firstname = element firstname { firstname.content }
secondname = element secondname { secondname.content }
lastname = element lastname { lastname.content }
label = element label { label.content }

firstname.content = inlines
secondname.content = inlines
lastname.content = inlines
label.content = inlines

# ~~~~~~ address
address = element address { address.content }

address.content = inlines

# ~~~~~~ role
role = element role { role.content }

role.content = "author" | "illustrator" | "publisher" | "packager"

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ place ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

place = element place { place.content }

place.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ source ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

source = element source {
   (  (attribute type { "book" }, bibliography.entry.content)
    | (attribute type { "file" }, source.content.file)),
   source.content
}

source.content.file =
   identifier.uri
source.content =
   annotation*

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ keyword & subject ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# ~~~~~~ keywordset
keywordset = element keywordset { keywordset.content }

keywordset.content = keyword+

# ~~~~~~ keyword
keyword = element keyword { keyword.content }

keyword.content = mixed { sup*, sub* }

# ~~~~~~ subjectset
subjectset = element subjectset { subjectset.content }

subjectset.content = subject+

# ~~~~~~ subject
subject = element subject { subject.content }

subject.content = xsd:NMTOKEN

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ abstract ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

abstract = element abstract { abstract.content }

abstract.content =
   p+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cover ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

cover = element cover { cover.content }

cover.content =
   cover.image

cover.image = element image { cover.image.attributes }

cover.image.attributes =
   cover.image.id.attribute
cover.image.id.attribute = attribute id { xsd:NMTOKEN }
   
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ annotation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

annotation = element annotation { annotation.content }

annotation.content = inlines


# =============================================================================
#                                 INLINE LEVEL
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

inlines = mixed {
   sup*
 & sub*
 & var*
 & number*
 & math*
 & date*
 & name*
 & note*
 & foreign*
 & highlight*
 & quote*
 & acronym*
 & mentioned*
 & term*
 & stage*
 & literal*
 & initial*
 & link*
 & anchor*
 & image*
 & smil*
}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sub, sup, var ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

sup = element sup { text }

sub = element sub { text }

var = element var { text }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ number ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

number = element number {
   ( attribute type {"roman"}, number.attributes, number.roman.content )
 | ( number.attributes, number.content)
}

number.attributes =
   number.value.attribute?
number.value.attribute = attribute value { xsd:integer | xsd:decimal }

number.content = mixed { sup* }
number.roman.content = xsd:token {pattern = "[DLXVI]+"}

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ math ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

math = element math {
   ( attribute notation {"tex"}, math.attributes, math.tex.content )
 | ( math.attributes, math.content)
}

math.attributes =
   wide.attribute?
wide.attribute = attribute wide { xsd:boolean }

math.content = mixed { sup* & sub* & var* }
math.tex.content = text

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ date ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

date = element date { date.attributes, date.content }

date.attributes =
   date.value.attribute
 & date.of.attribute?
date.value.attribute = attribute value { xsd:date | xsd:gYearMonth | xsd:gYear }
date.of.attribute = attribute of { "birth" | "death" }

date.content = mixed { sup* }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ name ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

name = element name { name.attributes, name.content }

name.attributes =
   name.of.attribute?
name.of.attribute = attribute of
   { "person" | "company" | "book" | "newspaper" | "party" | "painting" }

name.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ note ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

note = element note { note.attributes, note.content }

note.attributes =
   note.label.attribute?
note.label.attribute = attribute label { text }

note.content =
   (w?, block+) | inlines

w = element w { inlines }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ foreign ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

foreign = element foreign { foreign.attributes, foreign.content }

foreign.attributes =
   lang.attribute?

foreign.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ highlight ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

highlight = element highlight { highlight.content }

highlight.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ quote ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

quote = element quote { quote.content }

quote.content =
   (phrase, attribution) | inlines

phrase = element phrase { phrase.content }

phrase.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ acronym ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

acronym = element acronym { acronym.content }

acronym.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mentioned ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

mentioned = element mentioned { mentioned.content }

mentioned.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ term ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

term = element term { term.content }

term.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ stage ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

stage = element stage { stage.content }

stage.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ literal ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

literal = element literal { literal.content }

literal.content = text

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ initial ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

initial = element initial { initial.content }

initial.content =
   c,
   w?

c = element c { text }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ link ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

link = element link { link.attributes, link.content }

link.attributes =
   (uri.attribute | idref.attribute)
uri.attribute = attribute uri { xsd:anyURI }
idref.attribute = attribute idref { xsd:IDREF }

link.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ anchor ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

anchor = element anchor { anchor.attributes, anchor.content }

anchor.attributes =
   anchor.id.attribute
anchor.id.attribute = attribute xml:id { xsd:ID }

anchor.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ smil ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

smil = element smil { smil.attributes, smil.content }

smil.attributes =
   begin.attribute?
 & end.attribute?
begin.attribute = attribute begin { xsd:decimal }
end.attribute = attribute end { xsd:decimal }

smil.content = inlines
