RelaxNG/publidoc.rnc
author Patrick PIERRE
mar., 14 juil. 2015 11:43:06 +0200
changeset 391 970a85a456a6
parent 388 954f6aef52d6
child 397 92b1431dc38d
permissions -rw-r--r--
Changement d'adresse
# $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


# =============================================================================
#                                 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
identifier = element identifier {
   (attribute type { "ean" }, for.attribute?, xsd:token {pattern = "\d{13}"})
 | (attribute type { "uri" }, for.attribute?, xsd:anyURI)
}

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

# ~~~~~~ identifier.uri
identifier.uri = element identifier {
   attribute type { "uri" }, for.attribute?, xsd:anyURI
}

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

copyright = element copyright { copyright.content }

copyright.content = simple.inlines

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

collection = element collection { collection.content }

collection.content = simple.inlines

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

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

contributors.content =
   contributor+

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

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

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

firstname.content = simple.inlines
lastname.content = simple.inlines
label.content = simple.inlines

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

address.content = simple.inlines

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

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

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

place = element place { place.content }

place.content = simple.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 = simple.inlines

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

subjectset.content = subject+

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

subject.content = simple.inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ index ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

indexset.content = head.index+

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

index.content =
   (index.w, index.entry?)
 | (index.entry, (index.w | index.entry)?)
head.index.content =
   index.entry, index.entry?

# ~~~~~~ index.w
index.w = element w { simple.inlines }

# ~~~~~~ index.entry
index.entry = element entry { simple.inlines }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 =
   media.id.attribute

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ annotation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

annotation = element annotation { annotation.content }

annotation.content =
   inlines | p+


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

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

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

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

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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)+

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ top.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.head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

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

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

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

division.attributes =
   division.type.attribute?
division.type.attribute = attribute type { xsd:NCName }

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

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ front ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

front = element front { front.content }

front.content =
   section+


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

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

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

component.head.content =
   (title & shorttitle? & subtitle*)?
 & contributors?
 & date?
 & place?
 & keywordset?
 & subjectset?
 & indexset?
 & 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
# =============================================================================

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ section.head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

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

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

header = element header { header.content }

header.content =
   block+

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

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

section.attributes =
   xmlid.attribute?
 & 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+)

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

bibliography = element bibliography { bibliography.content }

bibliography.content =
   bibliography.entry+

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

footer = element footer { footer.content }

footer.content =
   block+


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

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ block.head ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

block.head.content =
   (title & shorttitle? & subtitle*)?
 & indexset?
 & annotation?

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

block = (p | \list | blockquote | speech | table | table.cals | media)

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

p = element p { p.content }

p.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.attributes, blockquote.content }

blockquote.attributes =
   blockquote.type.attribute?
blockquote.type.attribute = attribute type { xsd:NCName }

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

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

attribution.content = mixed {
   sup* & number* & date* & name* & foreign* & acronym* & term* & literal*
 & highlight* & emphasis* & mentioned* & note* & warning* }

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

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

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

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

speaker.content = inlines

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

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

table.attributes =
   table.type.attribute?
table.type.attribute = attribute type { xsd:NCName }

table.content =
   block.head?,
   ((thead?, tbody+) | tr+),
   table.caption?

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

thead.content =
   tr+
tbody.content =
   tr+

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

tr.attributes =
   align.attribute?
 & valign.attribute?
 & cell.type.attribute?
align.attribute = attribute align { "left"  |  "right"  | "center" | "justify" }
valign.attribute = attribute valign { "top" | "middle" | "bottom" }
cell.type.attribute = attribute type { xsd:NCName }

tr.content =
   (td | th)+

# ~~~~~~ td, th
td = element td { td.attributes, td.content }
th = element th { td.attributes, td.content }

td.attributes =
   align.attribute?
 & valign.attribute?
 & colspan.attribute?
 & rowspan.attribute?
 & cell.type.attribute?
colspan.attribute = attribute colspan { xsd:positiveInteger }
rowspan.attribute = attribute rowspan { xsd:positiveInteger }

td.content =
   inlines
 | (p | media)+

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

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

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ table.cals ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

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

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

tgroup.attributes =
   cols.attribute
cols.attribute = attribute cols { xsd:positiveInteger }

tgroup.content =
   thead.cals?,
   tbody.cals

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

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

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

row.attributes =
   valign.attribute?

row.content =
  table.cals.entry+

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

table.cals.entry.attributes =
   align.attribute?
 & valign.attribute?

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

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

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

media.attributes =
   xmlid.attribute?
 & media.type.attribute?
media.type.attribute = attribute type { xsd:NCName }

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

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

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

media.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.display.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.display.attribute = attribute display { "normal" | "visible" | "pulse" }
hotspot.type.attribute = attribute type { xsd:NCName }

hotspot.content =
   ((link | p+ | image | audio | video), (spot, scenario?)?)
 | (spot, scenario?)
 | empty

# ~~~~~~ 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


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

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

simple.inlines = mixed {
   sup*
 & sub*
 & var*
 & number*
 & acronym*
 & warning*
}

inlines = mixed {
   sup*
 & sub*
 & var*
 & number*
 & acronym*
 & warning*

 & highlight*
 & emphasis*
 & mentioned*
 & literal*
 & term*
 & stage*
 & name*
 & foreign*
 & date*
 & math*
 & quote*
 & initial*
 & note*
 & link*
 & anchor*
 & index*
 & image*
 & audio*
 & smil*
}

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

sup = element sup { mixed { var* & warning* } }

sub = element sub { mixed { var* & warning* } }

var = element var { mixed { warning* } }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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* & warning* }
number.roman.content = xsd:token {pattern = "[MCLXVI]+"}

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

acronym = element acronym { acronym.content }

acronym.content = mixed { sup* & warning* }

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

highlight = element highlight { highlight.content }

highlight.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ emphasis ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

emphasis = element emphasis { emphasis.content }

emphasis.content = inlines

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

mentioned = element mentioned { mentioned.content }

mentioned.content = inlines

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

literal = element literal { literal.content }

literal.content = inlines

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

term = element term { term.content }

term.content = mixed { sup* & warning* }

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

stage = element stage { stage.content }

stage.content = inlines

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

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

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

name.content = mixed { sup* & number* & acronym* & warning* }

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

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

foreign.attributes =
   lang.attribute?

foreign.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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* & number* & warning* }

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

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

math.attributes =
   xmlid.attribute?
 & math.display.attribute?
math.display.attribute = attribute display {
   "wide" | "numbered" | "box"  | "numbered-box" }

math.content =
   mixed { sup* & sub* & var* & warning* }
 | latex

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

latex.attributes =
   plain.attritute?
plain.attritute = attribute plain { xsd:boolean }

latex.content = text

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

quote = element quote { quote.content }

quote.content =
   (phrase, attribution) | inlines

phrase = element phrase { phrase.content }

phrase.content = inlines

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

initial = element initial { initial.content }

initial.content =
   initial.c,
   initial.w?

initial.c = element c { text }
initial.w = element w { inlines }

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

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

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

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

note.w = element w { inlines }

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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 = simple.inlines

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

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

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

anchor.content = simple.inlines

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

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

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

smil.content = inlines

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ warning ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

warning.attributes =
   warning.type.attribute?
warning.type.attribute = attribute type { xsd:NCName }

warning.content = inlines