patrick@73: # $Id$ patrick@73: patrick@73: patrick@73: include "publidoc.rnc" { patrick@73: start = publiquiz patrick@73: patrick@73: document.content = patrick@73: top.head?, patrick@73: (division | topic | quiz)+ patrick@84: patrick@84: division.content = patrick@84: division.head?, patrick@84: (division | topic | quiz)+ patrick@73: } patrick@73: patrick@75: patrick@73: publiquiz = element publiquiz { patrick@73: publiquiz.attributes, patrick@73: publiquiz.content patrick@73: } patrick@73: patrick@73: publiquiz.attributes = patrick@73: version.attribute patrick@73: patrick@73: publiquiz.content = patrick@73: document patrick@73: | top.quiz patrick@73: patrick@73: patrick@73: # ============================================================================= patrick@73: # TOP LEVEL patrick@73: # ============================================================================= patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ quiz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@128: top.quiz = element quiz { top.quiz.attributes, top.quiz.content } patrick@73: patrick@73: top.quiz.attributes = patrick@73: quiz.id.attribute Patrick@158: & quiz.type.attribute? patrick@73: & lang.attribute? patrick@117: quiz.id.attribute = attribute id { xsd:NMTOKEN } Patrick@158: quiz.type.attribute = attribute type { xsd:NCName } patrick@73: patrick@128: top.quiz.content = patrick@128: top.head?, patrick@128: instructions, patrick@128: (engine | composite), patrick@128: help?, patrick@128: answer? patrick@73: patrick@73: # ============================================================================= patrick@73: # COMPONENT LEVEL patrick@73: # ============================================================================= patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ quiz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: quiz = element quiz { quiz.attributes, quiz.content } patrick@73: patrick@73: quiz.attributes = patrick@122: (quiz.id.attribute | quiz.xmlid.attribute)? Patrick@158: & quiz.type.attribute? patrick@73: & lang.attribute? patrick@122: quiz.xmlid.attribute = attribute xml:id { xsd:ID } patrick@73: patrick@73: quiz.content = patrick@73: component.head?, patrick@73: instructions, patrick@87: (engine | composite), patrick@73: help?, patrick@87: answer? patrick@73: patrick@73: patrick@73: # ============================================================================= patrick@73: # SECTION LEVEL patrick@73: # ============================================================================= patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: blanks.section = element section { section.attributes, blanks.section.content } patrick@73: point.section = element section { section.attributes, point.section.content } patrick@73: patrick@73: blanks.section.content = patrick@73: section.head?, patrick@73: (blanks.section+ | blanks.block+) patrick@73: point.section.content = patrick@73: section.head?, patrick@73: (point.section+ | point.block+) patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: instructions = element instructions { section.content } patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ engine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: engine = patrick@87: choices-radio patrick@87: | choices-check patrick@87: | blanks-fill patrick@87: | blanks-select patrick@73: | point patrick@73: | matching patrick@73: | sort patrick@125: | categories patrick@87: | production patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ choices ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@87: choices-radio = element choices-radio { patrick@87: choices.attributes, choices-radio.content } patrick@87: choices-check = element choices-check { patrick@87: choices.attributes, choices-check.content } patrick@73: patrick@73: choices.attributes = patrick@73: shuffle.attribute? patrick@73: shuffle.attribute = attribute shuffle { xsd:boolean } patrick@73: patrick@87: choices-radio.content = patrick@73: choices.right patrick@73: & choices.wrong+ patrick@87: choices-check.content = patrick@73: (choices.right | choices.wrong)+ patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blanks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@87: blanks-fill = element blanks-fill { patrick@87: blanks-fill.attributes, blanks-fill.content } patrick@87: blanks-select = element blanks-select { patrick@87: blanks-select.attributes, blanks-select.content } patrick@73: patrick@87: blanks-fill.attributes = patrick@75: strict.attribute? patrick@87: blanks-select.attributes = patrick@73: multiple.attribute? patrick@73: strict.attribute = attribute strict { xsd:boolean } patrick@73: multiple.attribute = attribute multiple { xsd:boolean } patrick@73: patrick@87: blanks-fill.content = patrick@73: (blanks.block+ | blanks.section+) patrick@87: blanks-select.content = patrick@73: blanks.wrongs?, patrick@73: (blanks.block+ | blanks.section+) patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: point = element point { point.attributes, point.content } patrick@75: patrick@73: point.attributes = patrick@73: point.type.attribute? patrick@73: point.type.attribute = attribute type { patrick@73: "radio" | "radio_button" | "check" | "check_button" } patrick@73: patrick@73: point.content = patrick@73: (point.section+ | point.block+) patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ matching ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: Patrick@161: # ~~~~~~ matching Patrick@169: matching = element matching { matching.attributes, matching.content } Patrick@169: Patrick@169: matching.attributes = Patrick@169: multiple.attribute? patrick@75: patrick@73: matching.content = patrick@73: match, patrick@73: match+ patrick@73: Patrick@161: # ~~~~~~ match Patrick@161: match = element match { match.content } Patrick@161: Patrick@161: match.content = Patrick@161: match.item, Patrick@161: match.item Patrick@161: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sort ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: sort = element sort { sort.attributes, sort.content } patrick@73: patrick@73: sort.attributes = patrick@73: shuffle.attribute? patrick@75: patrick@73: sort.content = patrick@73: comparison?, patrick@73: sort.item, patrick@73: sort.item+ patrick@73: patrick@125: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ categories ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@125: patrick@125: # ~~~~~~ categories Patrick@168: categories = element categories { categories.attributes, categories.content } patrick@125: Patrick@168: categories.attributes = Patrick@168: multiple.attribute? Patrick@168: patrick@125: categories.content = Patrick@174: category.item*, patrick@125: category, patrick@125: category+ patrick@125: patrick@125: # ~~~~~~ category patrick@125: category = element category { category.content } patrick@125: patrick@125: category.content = patrick@125: category.head, patrick@125: category.item* patrick@125: patrick@125: # ~~~~~~ category.head patrick@125: category.head = element head { category.head.content } patrick@125: patrick@125: category.head.content = patrick@125: title, patrick@127: shorttitle?, patrick@125: subtitle? patrick@125: patrick@87: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ production ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@87: patrick@87: production = element production { empty } patrick@87: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ composite ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@77: # ~~~~~~ composite Patrick@161: composite = element composite { composite.attributes, composite.content } Patrick@161: Patrick@161: composite.attributes = Patrick@161: multipage.attribute? Patrick@161: multipage.attribute = attribute multipage { xsd:boolean } patrick@75: patrick@73: composite.content = patrick@85: subquiz, Patrick@154: subquiz+ patrick@77: patrick@85: # ~~~~~~ subquiz patrick@85: subquiz = element subquiz { subquiz.content } patrick@77: patrick@85: subquiz.content = patrick@77: instructions?, Patrick@141: engine, Patrick@141: help?, Patrick@141: answer? patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: help = element help { help.content } patrick@73: patrick@73: help.content = patrick@73: (section+ | block+)?, patrick@73: link* patrick@73: patrick@87: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ answer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@87: answer = element answer { answer.content } patrick@73: patrick@87: answer.content = patrick@81: (section+ | block+)?, patrick@80: link* patrick@73: patrick@73: patrick@73: # ============================================================================= patrick@73: # BLOCK LEVEL patrick@73: # ============================================================================= patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ block ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: blanks.block = Patrick@174: (blanks.p | speech | blanks.list | blockquote | blanks.table | blanks.media) patrick@73: point.block = patrick@73: (point.p | speech | point.list | blockquote | point.table | media) patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: blanks.p = element p { blanks.p.content } patrick@73: point.p = element p { point.p.content } patrick@73: patrick@73: blanks.p.content = patrick@75: blanks.inlines patrick@73: point.p.content = patrick@75: point.inlines patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: # ~~~~~~ list patrick@75: blanks.list = element list { patrick@73: block.head?, patrick@73: ( (attribute type {"ordered"}?, blanks.item, blanks.item+) patrick@73: | (attribute type {"glossary"}, glossary.item+) ) patrick@75: } patrick@75: point.list = element list { patrick@73: block.head?, patrick@73: ( (attribute type {"ordered"}?, point.item, point.item+) patrick@73: | (attribute type {"glossary"}, glossary.item+) ) patrick@75: } patrick@73: patrick@73: # ~~~~~~ item patrick@73: blanks.item = element item { blanks.item.content } patrick@73: point.item = element item { point.item.content } patrick@73: patrick@73: blanks.item.content = patrick@75: blanks.inlines patrick@73: | blanks.block+ patrick@73: point.item.content = patrick@75: point.inlines patrick@73: | point.block+ patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ table ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: blanks.table = element table { blanks.table.content } patrick@73: point.table = element table { point.table.content } patrick@73: patrick@73: blanks.table.content = patrick@73: block.head?, patrick@73: blanks.tgroup+, patrick@111: table.caption? patrick@73: point.table.content = patrick@73: block.head?, patrick@73: point.tgroup+, patrick@111: table.caption? patrick@73: patrick@73: # ~~~~~~ tgroup patrick@73: blanks.tgroup = element tgroup { tgroup.attributes, blanks.tgroup.content } patrick@73: point.tgroup = element tgroup { tgroup.attributes, point.tgroup.content } patrick@73: patrick@73: blanks.tgroup.content = patrick@73: thead?, patrick@73: blanks.tbody patrick@73: point.tgroup.content = patrick@73: thead?, patrick@73: point.tbody patrick@73: patrick@73: # ~~~~~~ tbody patrick@73: blanks.tbody = element tbody { tbody.attributes, blanks.tbody.content } patrick@73: point.tbody = element tbody { tbody.attributes, point.tbody.content } patrick@73: patrick@73: blanks.tbody.content = patrick@73: blanks.row+ patrick@73: point.tbody.content = patrick@73: point.row+ patrick@73: patrick@73: # ~~~~~~ row patrick@148: blanks.row = element row { row.attributes, blanks.row.content } patrick@148: point.row = element row { row.attributes, point.row.content } patrick@73: patrick@73: blanks.row.content = patrick@73: blanks.entry+ patrick@73: point.row.content = patrick@73: point.entry+ patrick@73: patrick@73: # ~~~~~~ entry patrick@73: blanks.entry = element entry { blanks.entry.content } patrick@73: point.entry = element entry { point.entry.content } patrick@73: patrick@73: blanks.entry.content = patrick@75: blanks.inlines patrick@73: | (p | media)+ patrick@73: patrick@73: point.entry.content = patrick@75: point.inlines patrick@73: | (p | media)+ patrick@73: Patrick@174: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ media ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Patrick@174: Patrick@174: # ~~~~~~ blanks.media Patrick@174: blanks.media = element media { blanksmedia.content } Patrick@174: Patrick@174: blanksmedia.content = Patrick@174: block.head?, Patrick@174: (blanks.image | audio | video)+, Patrick@174: media.caption?, Patrick@174: link? Patrick@174: Patrick@174: # ~~~~~~ blanks.image Patrick@174: blanks.image = element image { image.attributes, blanks.image.content } Patrick@174: Patrick@174: blanks.image.content = Patrick@174: copyright?, Patrick@192: blanks.dropzone* Patrick@174: Patrick@192: # ~~~~~~ blanks.dropzone Patrick@192: blanks.dropzone = element dropzone { Patrick@192: blanks.dropzone.attributes, blanks.dropzone.content } Patrick@183: Patrick@192: blanks.dropzone.attributes = Patrick@183: x.attribute Patrick@183: & y.attribute Patrick@174: Patrick@192: blanks.dropzone.content = Patrick@183: blank Patrick@174: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~ choices.right, choices.wrong ~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: choices.right = element right { choices.right.content } patrick@73: choices.wrong = element wrong { choices.right.content } patrick@73: patrick@73: choices.right.content = patrick@73: inlines Patrick@161: | ((p | image | (audio, image?) | video), help?, answer?) patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blanks.wrongs ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: # ~~~~~~ blanks.wrongs patrick@73: blanks.wrongs = element wrongs { blanks.wrongs.content } patrick@73: patrick@73: blanks.wrongs.content = patrick@73: blanks.wrong+ patrick@73: patrick@73: # ~~~~~~ blanks.wrong patrick@73: blanks.wrong = element wrong { blanks.wrong.content } patrick@73: patrick@73: blanks.wrong.content = text patrick@73: Patrick@161: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (match) item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: Patrick@161: match.item = element item { match.item.content } patrick@73: Patrick@161: match.item.content = Patrick@161: inlines patrick@166: | ((p | image | (audio, image?) | video), help?, answer?) patrick@73: patrick@75: # ~~~~~~~~~~~~~~~~~~~~~~~~ (sort) comparison, item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: # ~~~~~~ comparison patrick@73: comparison = element comparison { comparison.content } patrick@73: patrick@73: comparison.content = inlines patrick@73: patrick@73: # ~~~~~~ sort.item patrick@73: sort.item = element item { sort.item.attributes, sort.item.content } patrick@73: patrick@73: sort.item.attributes = patrick@73: item.shuffle.attribute? patrick@73: item.shuffle.attribute = attribute shuffle { xsd:integer } patrick@73: Patrick@161: sort.item.content = Patrick@161: inlines patrick@166: | ((p | image | (audio, image?) | video), help?, answer?) patrick@73: patrick@125: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ (category) item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@125: patrick@125: category.item = element item { category.item.content } patrick@125: Patrick@161: category.item.content = Patrick@161: inlines patrick@166: | ((p | image | (audio, image?) | video), help?, answer?) patrick@125: patrick@73: patrick@73: # ============================================================================= patrick@73: # INLINE LEVEL patrick@73: # ============================================================================= patrick@73: patrick@75: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@75: patrick@75: blanks.inlines = mixed { patrick@75: sup* patrick@75: & sub* patrick@75: & var* patrick@75: & number* patrick@75: & math* patrick@75: & date* patrick@75: & name* patrick@75: & note* patrick@75: & foreign* patrick@75: & highlight* patrick@75: & mentioned* patrick@75: & quote* patrick@75: & acronym* patrick@75: & term* patrick@75: & link* patrick@75: & anchor* Patrick@174: & image* patrick@75: & blank* patrick@75: } patrick@75: point.inlines = mixed { patrick@75: sup* patrick@75: & sub* patrick@75: & var* patrick@75: & number* patrick@75: & math* patrick@75: & date* patrick@75: & name* patrick@75: & note* patrick@75: & foreign* patrick@75: & highlight* patrick@75: & mentioned* patrick@75: & quote* patrick@75: & acronym* patrick@75: & term* patrick@75: & link* patrick@75: & anchor* Patrick@174: & image* patrick@75: & blank* patrick@75: & point.right* patrick@75: & point.wrong* patrick@75: } patrick@75: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blank ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: # ~~~~~~ blank patrick@73: blank = element blank { blank.content } patrick@73: patrick@73: blank.content = patrick@73: text patrick@87: | (s+, help?, answer?) patrick@73: patrick@73: # ~~~~~~ s patrick@73: s = element s { s.content } patrick@73: patrick@73: s.content = text patrick@73: patrick@73: # ~~~~~~~~~~~~~~~~~~~~~~~~~ point.right, point.wrong ~~~~~~~~~~~~~~~~~~~~~~~~~~ patrick@73: patrick@73: point.right = element right { point.right.content } patrick@73: point.wrong = element wrong { point.right.content } patrick@73: patrick@73: point.right.content = inlines