RelaxNG/publiquiz.rnc
changeset 476 6c30a3543cd8
parent 472 021552e09b34
child 478 90e0fdca7fb7
equal deleted inserted replaced
475:e415b3d474a1 476:6c30a3543cd8
     1 include "publidoc.rnc" {
     1 include "publidoc.rnc"
     2    start = publiquiz
     2     {
     3 
     3      start = publiquiz
     4    document.content =
     4 
     5       top.head?,
     5      document.content =
     6       (division | topic | quiz)+
     6          document.head?,
     7 
     7          (division | document.topic | document.quiz)+
     8    division.content =
     8 
     9       division.head?,
     9      division.content =
    10       front?,
    10          division.head?,
    11       (division | topic | quiz)+
    11          front?,
    12 
    12          (division | document.topic | document.quiz)+
    13    nowrap.content =
    13 
    14        inlines | blanks.inlines | blanks-m.inlines | blanks-c.inlines
    14      nowrap.content =
    15        | pointing.inlines
    15          inlines | blanks.inlines | blanks-m.inlines | blanks-c.inlines
    16 }
    16          | pointing.inlines
    17 
    17     }
    18 
    18 
    19 publiquiz = element publiquiz {
    19 
    20    publiquiz.attributes,
    20 publiquiz =
    21    publiquiz.content
    21     element publiquiz {
    22 }
    22         publiquiz.attributes,
       
    23         publiquiz.content
       
    24     }
    23 
    25 
    24 publiquiz.attributes =
    26 publiquiz.attributes =
    25    version.attribute
    27     version.attribute
    26 
    28 
    27 publiquiz.content =
    29 publiquiz.content =
    28    document
    30     document
    29  | top.quiz
    31     | quiz
    30 
    32 
    31 
    33 
    32 # =============================================================================
    34 # =============================================================================
    33 #                                  TOP LEVEL
    35 #                                    QUIZ
    34 # =============================================================================
    36 # =============================================================================
    35 
    37 
    36 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ top.quiz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    38 quiz = element quiz { quiz.attributes, quiz.content }
    37 
    39 document.quiz = element quiz { document.quiz.attributes, document.quiz.content }
    38 top.quiz = element quiz { top.quiz.attributes, top.quiz.content }
    40 
    39 
    41 quiz.attributes =
    40 top.quiz.attributes =
    42     quiz.id.attribute?
    41    quiz.id.attribute?
    43     & quiz.type.attribute?
    42  & quiz.type.attribute?
    44     & lang.attribute?
    43  & lang.attribute?
    45 document.quiz.attributes =
       
    46     (quiz.id.attribute | xmlid.attribute)?
       
    47     & quiz.type.attribute?
       
    48     & lang.attribute?
    44 quiz.id.attribute = attribute id { xsd:NMTOKEN }
    49 quiz.id.attribute = attribute id { xsd:NMTOKEN }
    45 quiz.type.attribute = attribute type { xsd:NCName }
    50 quiz.type.attribute = attribute type { xsd:NCName }
    46 
    51 
    47 top.quiz.content =
       
    48    top.head?,
       
    49    instructions?,
       
    50    (engine | composite),
       
    51    help?,
       
    52    answer?
       
    53 
       
    54 
       
    55 # =============================================================================
       
    56 #                                COMPONENT LEVEL
       
    57 # =============================================================================
       
    58 
       
    59 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ quiz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       
    60 
       
    61 quiz = element quiz { quiz.attributes, quiz.content }
       
    62 
       
    63 quiz.attributes =
       
    64    (quiz.id.attribute | xmlid.attribute)?
       
    65  & quiz.type.attribute?
       
    66  & lang.attribute?
       
    67 
       
    68 quiz.content =
    52 quiz.content =
    69    component.head?,
    53     component.head?,
    70    instructions?,
    54     instructions?,
    71    (engine | composite),
    55     (engine | composite),
    72    help?,
    56     help?,
    73    answer?
    57     answer?
       
    58 document.quiz.content =
       
    59     document.component.head?,
       
    60     instructions?,
       
    61     (engine | composite),
       
    62     help?,
       
    63     answer?
    74 
    64 
    75 
    65 
    76 # =============================================================================
    66 # =============================================================================
    77 #                                 SECTION LEVEL
    67 #                                 SECTION LEVEL
    78 # =============================================================================
    68 # =============================================================================
    79 
    69 
    80 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    70 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ section ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    81 
    71 
    82 blanks.section = element section { section.attributes, blanks.section.content }
    72 blanks.section = element section { section.attributes, blanks.section.content }
    83 blanks-m.section = element section {
    73 blanks-m.section =
    84    section.attributes, blanks-m.section.content }
    74     element section { section.attributes, blanks-m.section.content }
    85 blanks-c.section = element section {
    75 blanks-c.section =
    86    section.attributes, blanks-c.section.content }
    76     element section { section.attributes, blanks-c.section.content }
    87 correct.section = element section {
    77 correct.section =
    88    section.attributes, correct.section.content }
    78     element section { section.attributes, correct.section.content }
    89 pointing.section = element section {
    79 pointing.section =
    90    section.attributes, pointing.section.content }
    80     element section { section.attributes, pointing.section.content }
    91 
    81 
    92 blanks.section.content =
    82 blanks.section.content =
    93    section.head?,
    83     section.head?,
    94    (blanks.section+ | blanks.block+)
    84     (blanks.section+ | blanks.block+)
    95 blanks-m.section.content =
    85 blanks-m.section.content =
    96    section.head?,
    86     section.head?,
    97    (blanks-m.section+ | blanks-m.block+)
    87     (blanks-m.section+ | blanks-m.block+)
    98 blanks-c.section.content =
    88 blanks-c.section.content =
    99    section.head?,
    89     section.head?,
   100    (blanks-c.section+ | blanks-c.block+)
    90     (blanks-c.section+ | blanks-c.block+)
   101 correct.section.content =
    91 correct.section.content =
   102    section.head?,
    92     section.head?,
   103    (correct.section+ | correct.block+)
    93     (correct.section+ | correct.block+)
   104 pointing.section.content =
    94 pointing.section.content =
   105    section.head?,
    95     section.head?,
   106    (pointing.section+ | pointing.block+)
    96     (pointing.section+ | pointing.block+)
   107 
    97 
   108 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    98 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ instructions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   109 
    99 
   110 instructions = element instructions { section.content }
   100 instructions = element instructions { section.content }
   111 
   101 
   112 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ engine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   102 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ engine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   113 
   103 
   114 engine =
   104 engine =
   115    choices-radio
   105     choices-radio
   116  | choices-check
   106     | choices-check
   117  | blanks-fill
   107     | blanks-fill
   118  | blanks-select
   108     | blanks-select
   119  | blanks-media
   109     | blanks-media
   120  | blanks-choices
   110     | blanks-choices
   121  | correct-line
   111     | correct-line
   122  | pointing
   112     | pointing
   123  | pointing-categories
   113     | pointing-categories
   124  | matching
   114     | matching
   125  | sort
   115     | sort
   126  | categories
   116     | categories
   127  | wordsearch
   117     | wordsearch
   128  | flashcard
   118     | flashcard
   129  | coloring
   119     | coloring
   130  | memory
   120     | memory
   131  | dictation
   121     | dictation
   132  | production
   122     | production
   133 
   123 
   134 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ choices ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   124 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ choices ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   135 
   125 
   136 choices-radio = element choices-radio {
   126 choices-radio =
   137    choices-radio.attributes, choices-radio.content }
   127     element choices-radio { choices-radio.attributes, choices-radio.content }
   138 choices-check = element choices-check {
   128 choices-check =
   139    choices-check.attributes, choices-check.content }
   129     element choices-check { choices-check.attributes, choices-check.content }
   140 
   130 
   141 choices-radio.attributes =
   131 choices-radio.attributes =
   142    shuffle.attribute?
   132     shuffle.attribute?
   143 choices-check.attributes =
   133 choices-check.attributes =
   144    success.attribute?
   134     success.attribute?
   145  & shuffle.attribute?
   135     & shuffle.attribute?
   146 success.attribute = attribute success { xsd:decimal {maxInclusive="1"} }
   136 success.attribute = attribute success { xsd:decimal {maxInclusive="1"} }
   147 shuffle.attribute = attribute shuffle { xsd:boolean }
   137 shuffle.attribute = attribute shuffle { xsd:boolean }
   148 
   138 
   149 choices-radio.content =
   139 choices-radio.content =
   150    choices.right
   140     choices.right
   151  & choices.wrong+
   141     & choices.wrong+
   152 choices-check.content =
   142 choices-check.content =
   153    (choices.right | choices.wrong)+
   143     (choices.right | choices.wrong)+
   154 
   144 
   155 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blanks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   145 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blanks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   156 
   146 
   157 blanks-fill = element blanks-fill {
   147 blanks-fill =
   158    blanks-fill.attributes, blanks-fill.content }
   148     element blanks-fill { blanks-fill.attributes, blanks-fill.content }
   159 blanks-select = element blanks-select {
   149 blanks-select =
   160    blanks-select.attributes, blanks-select.content }
   150     element blanks-select { blanks-select.attributes, blanks-select.content }
   161 blanks-media = element blanks-media {
   151 blanks-media =
   162    blanks-select.attributes, blanks-media.content }
   152     element blanks-media { blanks-select.attributes, blanks-media.content }
   163 blanks-choices = element blanks-choices {
   153 blanks-choices =
   164    blanks-choices.content }
   154     element blanks-choices { blanks-choices.content }
   165 
   155 
   166 blanks-fill.attributes =
   156 blanks-fill.attributes =
   167    success.attribute?
   157     success.attribute?
   168  & strict.attribute?
   158     & strict.attribute?
   169  & long.attribute?
   159     & long.attribute?
   170 blanks-select.attributes =
   160 blanks-select.attributes =
   171    success.attribute?
   161     success.attribute?
   172  & multiple.attribute?
   162     & multiple.attribute?
   173  & noshuffle.attribute?
   163     & noshuffle.attribute?
   174  & orientation.attribute?
   164     & orientation.attribute?
   175 strict.attribute = attribute strict { xsd:boolean }
   165 strict.attribute = attribute strict { xsd:boolean }
   176 multiple.attribute = attribute multiple { xsd:boolean }
   166 multiple.attribute = attribute multiple { xsd:boolean }
   177 noshuffle.attribute = attribute no-shuffle { "true" | "false" | "alpha" }
   167 noshuffle.attribute = attribute no-shuffle { "true" | "false" | "alpha" }
   178 long.attribute = attribute long { xsd:positiveInteger }
   168 long.attribute = attribute long { xsd:positiveInteger }
   179 orientation.attribute = attribute orientation {"north"|"east"|"west"|"south"}
   169 orientation.attribute = attribute orientation {"north"|"east"|"west"|"south"}
   180 
   170 
   181 blanks-fill.content =
   171 blanks-fill.content =
   182    (blanks.block+ | blanks.section+)
   172     (blanks.block+ | blanks.section+)
   183 blanks-select.content =
   173 blanks-select.content =
   184    blanks.intruders?,
   174     blanks.intruders?,
   185    (blanks.block+ | blanks.section+)
   175     (blanks.block+ | blanks.section+)
   186 blanks-media.content =
   176 blanks-media.content =
   187    blanks-m.intruders?,
   177     blanks-m.intruders?,
   188    (blanks-m.block+ | blanks-m.section+)
   178     (blanks-m.block+ | blanks-m.section+)
   189 blanks-choices.content =
   179 blanks-choices.content =
   190    (blanks-c.block+ | blanks-c.section+)
   180     (blanks-c.block+ | blanks-c.section+)
   191 
   181 
   192 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ correct-line ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   182 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ correct-line ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   193 
   183 
   194 correct-line = element correct-line { correct.attributes, correct.content }
   184 correct-line = element correct-line { correct.attributes, correct.content }
   195 
   185 
   196 correct.attributes =
   186 correct.attributes =
   197    remove-space.attribute?
   187     remove-space.attribute?
   198 remove-space.attribute = attribute remove-space { xsd:boolean }
   188 remove-space.attribute = attribute remove-space { xsd:boolean }
   199 
   189 
   200 correct.content =
   190 correct.content =
   201    correct.intruders?,
   191     correct.intruders?,
   202    (correct.block+ | correct.section+)
   192     (correct.block+ | correct.section+)
   203 
   193 
   204 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pointing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   194 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pointing ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   205 
   195 
   206 pointing = element pointing { pointing.attributes, pointing.content }
   196 pointing = element pointing { pointing.attributes, pointing.content }
   207 
   197 
   208 pointing.attributes =
   198 pointing.attributes =
   209    success.attribute?
   199     success.attribute?
   210  & pointing.type.attribute?
   200     & pointing.type.attribute?
   211 pointing.type.attribute = attribute type { "radio" | "check" }
   201 pointing.type.attribute = attribute type { "radio" | "check" }
   212 
   202 
   213 pointing.content =
   203 pointing.content =
   214    (pointing.section+ | pointing.block+)
   204     (pointing.section+ | pointing.block+)
   215 
   205 
   216 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pointing-categories ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   206 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pointing-categories ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   217 
   207 
   218 # ~~~~~~ pointing-categories
   208 # ~~~~~~ pointing-categories
   219 pointing-categories = element pointing-categories {
   209 pointing-categories =
   220    pointing-c.attributes, pointing-c.content }
   210     element pointing-categories { pointing-c.attributes, pointing-c.content }
   221 
   211 
   222 pointing-c.attributes =
   212 pointing-c.attributes =
   223    success.attribute?
   213     success.attribute?
   224 
   214 
   225 pointing-c.content =
   215 pointing-c.content =
   226    pointing-c.categories,
   216     pointing-c.categories,
   227    pointing.section
   217     pointing.section
   228 
   218 
   229 # ~~~~~~ pointing-c.categories
   219 # ~~~~~~ pointing-c.categories
   230 pointing-c.categories = element categories { pointing-c.categories.content }
   220 pointing-c.categories = element categories { pointing-c.categories.content }
   231 
   221 
   232 pointing-c.categories.content =
   222 pointing-c.categories.content =
   233    pointing-c.category1,
   223     pointing-c.category1,
   234    pointing-c.category2,
   224     pointing-c.category2,
   235    (pointing-c.category3,
   225     (pointing-c.category3,
   236       (pointing-c.category4, pointing-c.category5?)?)?
   226      (pointing-c.category4, pointing-c.category5?)?)?
   237 
   227 
   238 # ~~~~~~ pointing-c.categoryN
   228 # ~~~~~~ pointing-c.categoryN
   239 pointing-c.category1 = element category {
   229 pointing-c.category1 =
   240    attribute id { "1" }, pointing-c.category.content }
   230     element category { attribute id { "1" }, pointing-c.category.content }
   241 pointing-c.category2 = element category {
   231 pointing-c.category2 =
   242    attribute id { "2" }, pointing-c.category.content }
   232     element category { attribute id { "2" }, pointing-c.category.content }
   243 pointing-c.category3 = element category {
   233 pointing-c.category3 =
   244    attribute id { "3" }, pointing-c.category.content }
   234     element category { attribute id { "3" }, pointing-c.category.content }
   245 pointing-c.category4 = element category {
   235 pointing-c.category4 =
   246    attribute id { "4" }, pointing-c.category.content }
   236     element category { attribute id { "4" }, pointing-c.category.content }
   247 pointing-c.category5 = element category {
   237 pointing-c.category5 =
   248    attribute id { "5" }, pointing-c.category.content }
   238     element category { attribute id { "5" }, pointing-c.category.content }
   249 
   239 
   250 pointing-c.category.content = inlines
   240 pointing-c.category.content = inlines
   251 
   241 
   252 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ matching ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   242 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ matching ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   253 
   243 
   254 # ~~~~~~ matching
   244 # ~~~~~~ matching
   255 matching = element matching { matching.attributes, matching.content }
   245 matching = element matching { matching.attributes, matching.content }
   256 
   246 
   257 matching.attributes =
   247 matching.attributes =
   258    success.attribute?
   248     success.attribute?
   259  & multiple.attribute?
   249     & multiple.attribute?
   260  & noshuffle.attribute?
   250     & noshuffle.attribute?
   261  & orientation.attribute?
   251     & orientation.attribute?
   262 
   252 
   263 matching.content =
   253 matching.content =
   264    matching.intruders?,
   254     matching.intruders?,
   265    match,
   255     match,
   266    match+
   256     match+
   267 
   257 
   268 # ~~~~~~ match
   258 # ~~~~~~ match
   269 match = element match { match.content }
   259 match = element match { match.content }
   270 
   260 
   271 match.content =
   261 match.content =
   272    match.item,
   262     match.item,
   273    match.item
   263     match.item
   274 
   264 
   275 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sort ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   265 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sort ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   276 
   266 
   277 sort = element sort { sort.attributes, sort.content }
   267 sort = element sort { sort.attributes, sort.content }
   278 
   268 
   279 sort.attributes =
   269 sort.attributes =
   280    success.attribute?
   270     success.attribute?
   281  & shuffle.attribute?
   271     & shuffle.attribute?
   282  & orientation.attribute?
   272     & orientation.attribute?
   283 
   273 
   284 sort.content =
   274 sort.content =
   285     sort.intruders?,
   275     sort.intruders?,
   286     comparison?,
   276     comparison?,
   287     sort.item,
   277     sort.item,
   291 
   281 
   292 # ~~~~~~ category.head
   282 # ~~~~~~ category.head
   293 category.head = element head { category.head.content }
   283 category.head = element head { category.head.content }
   294 
   284 
   295 category.head.content =
   285 category.head.content =
   296    title
   286     title
   297  & shorttitle?
   287     & shorttitle?
   298  & subtitle*
   288     & subtitle*
   299 
   289 
   300 # ~~~~~~ categories
   290 # ~~~~~~ categories
   301 categories = element categories { categories.attributes, categories.content }
   291 categories = element categories { categories.attributes, categories.content }
   302 
   292 
   303 categories.attributes =
   293 categories.attributes =
   304    success.attribute?
   294     success.attribute?
   305  & multiple.attribute?
   295     & multiple.attribute?
   306  & noshuffle.attribute?
   296     & noshuffle.attribute?
   307  & orientation.attribute?
   297     & orientation.attribute?
   308 
   298 
   309 categories.content =
   299 categories.content =
   310    categories.intruders?,
   300     categories.intruders?,
   311    category,
   301     category,
   312    category+
   302     category+
   313 
   303 
   314 # ~~~~~~ category
   304 # ~~~~~~ category
   315 category = element category { category.content }
   305 category = element category { category.content }
   316 
   306 
   317 category.content =
   307 category.content =
   318    category.head,
   308     category.head,
   319    category.item*
   309     category.item*
   320 
   310 
   321 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wordsearch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   311 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ wordsearch ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   322 
   312 
   323 wordsearch = element wordsearch {wordsearch.attributes, wordsearch.content }
   313 wordsearch = element wordsearch {wordsearch.attributes, wordsearch.content }
   324 
   314 
   325 wordsearch.attributes =
   315 wordsearch.attributes =
   326    strict.attribute ?
   316     strict.attribute ?
   327  & wordlist.attribute ?
   317     & wordlist.attribute ?
   328 
   318 
   329 wordlist.attribute = attribute wordlist { "hidden" | "right" | "left" }
   319 wordlist.attribute = attribute wordlist { "hidden" | "right" | "left" }
   330 
   320 
   331 wordsearch.content =
   321 wordsearch.content =
   332    words
   322     words
   333  & grid
   323     & grid
   334 
   324 
   335 # ~~~~~~ words
   325 # ~~~~~~ words
   336 words = element words {words.content}
   326 words = element words {words.content}
   337 words.content = words.item+
   327 words.content = words.item+
   338 
   328 
   350 
   340 
   351 # ~~~~~~ flashcard
   341 # ~~~~~~ flashcard
   352 flashcard = element flashcard { flashcard.content }
   342 flashcard = element flashcard { flashcard.content }
   353 
   343 
   354 flashcard.content =
   344 flashcard.content =
   355    side1,
   345     side1,
   356    side2
   346     side2
   357 
   347 
   358 # ~~~~~~ side1
   348 # ~~~~~~ side1
   359 side1 = element side1 { side1.content }
   349 side1 = element side1 { side1.content }
   360 
   350 
   361 side1.content =
   351 side1.content =
   386     nomark.attribute?
   376     nomark.attribute?
   387 nomark.attribute = attribute nomark { xsd:boolean }
   377 nomark.attribute = attribute nomark { xsd:boolean }
   388 
   378 
   389 coloring.content =
   379 coloring.content =
   390     palette
   380     palette
   391   & canvas
   381     & canvas
   392   & areas?
   382     & areas?
   393 
   383 
   394 # ~~~~~~ palette
   384 # ~~~~~~ palette
   395 palette = element palette { palette.content }
   385 palette = element palette { palette.content }
   396 
   386 
   397 palette.content =
   387 palette.content =
   419     & delay.attribute?
   409     & delay.attribute?
   420 display.attribute = attribute display { xsd:positiveInteger }
   410 display.attribute = attribute display { xsd:positiveInteger }
   421 delay.attribute = attribute delay { xsd:positiveInteger }
   411 delay.attribute = attribute delay { xsd:positiveInteger }
   422 
   412 
   423 memory.content =
   413 memory.content =
   424    memory.match,
   414     memory.match,
   425    memory.match+
   415     memory.match+
   426 
   416 
   427 # ~~~~~~ memory.match
   417 # ~~~~~~ memory.match
   428 memory.match = element match { memory-m.content }
   418 memory.match = element match { memory-m.content }
   429 
   419 
   430 memory-m.content =
   420 memory-m.content =
   454 
   444 
   455 # ~~~~~~ composite
   445 # ~~~~~~ composite
   456 composite = element composite { composite.attributes, composite.content }
   446 composite = element composite { composite.attributes, composite.content }
   457 
   447 
   458 composite.attributes =
   448 composite.attributes =
   459    success.attribute?
   449     success.attribute?
   460  & multipage.attribute?
   450     & multipage.attribute?
   461 multipage.attribute = attribute multipage { xsd:boolean }
   451 multipage.attribute = attribute multipage { xsd:boolean }
   462 
   452 
   463 composite.content =
   453 composite.content =
   464    subquiz,
   454     subquiz,
   465    subquiz+
   455     subquiz+
   466 
   456 
   467 # ~~~~~~ subquiz
   457 # ~~~~~~ subquiz
   468 subquiz = element subquiz { subquiz.content }
   458 subquiz = element subquiz { subquiz.content }
   469 
   459 
   470 subquiz.content =
   460 subquiz.content =
   471    instructions?,
   461     instructions?,
   472    engine,
   462     engine,
   473    help?,
   463     help?,
   474    answer?
   464     answer?
   475 
   465 
   476 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   466 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ help ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   477 
   467 
   478 help = element help { help.content }
   468 help = element help { help.content }
   479 
   469 
   480 help.content =
   470 help.content =
   481    (section+ | block+)?,
   471     (section+ | block+)?,
   482    link*
   472     link*
   483 
   473 
   484 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ answer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   474 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ answer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   485 
   475 
   486 answer = element answer { answer.content }
   476 answer = element answer { answer.content }
   487 
   477 
   488 answer.content =
   478 answer.content =
   489    (section+ | block+)?,
   479     (section+ | block+)?,
   490    link*
   480     link*
   491 
   481 
   492 
   482 
   493 # =============================================================================
   483 # =============================================================================
   494 #                                 BLOCK LEVEL
   484 #                                 BLOCK LEVEL
   495 # =============================================================================
   485 # =============================================================================
   496 
   486 
   497 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ block ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   487 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ block ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   498 
   488 
   499 blanks.block = (
   489 blanks.block =
   500    blanks.p | blanks.list | blanks.blockquote | blanks.speech | blanks.table
   490     (blanks.p | blanks.list | blanks.blockquote | blanks.speech | blanks.table
   501  | blanks.media)
   491      | blanks.media)
   502 blanks-m.block = (
   492 blanks-m.block =
   503    blanks-m.p | blanks-m.list | blanks-m.blockquote | blanks-m.speech
   493     (blanks-m.p | blanks-m.list | blanks-m.blockquote | blanks-m.speech
   504  | blanks-m.table | blanks-m.media)
   494      | blanks-m.table | blanks-m.media)
   505 blanks-c.block = (
   495 blanks-c.block =
   506    blanks-c.p | blanks-c.list | blanks-c.blockquote | blanks-c.speech
   496     (blanks-c.p | blanks-c.list | blanks-c.blockquote | blanks-c.speech
   507  | blanks-c.table | blanks-c.media)
   497      | blanks-c.table | blanks-c.media)
   508 correct.block = (
   498 correct.block =
   509    correct.p | correct.list | correct.blockquote | correct.speech
   499     (correct.p | correct.list | correct.blockquote | correct.speech
   510  | correct.table | media)
   500      | correct.table | media)
   511 pointing.block = (
   501 pointing.block =
   512    pointing.p | pointing.list | pointing.blockquote | pointing.speech
   502     (pointing.p | pointing.list | pointing.blockquote | pointing.speech
   513  | pointing.table | media)
   503      | pointing.table | media)
   514 
   504 
   515 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   505 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ p ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   516 
   506 
   517 blanks.p = element p { blanks.p.content }
   507 blanks.p = element p { blanks.p.content }
   518 blanks-m.p = element p { blanks-m.p.content }
   508 blanks-m.p = element p { blanks-m.p.content }
   535     dictation.inlines
   525     dictation.inlines
   536 
   526 
   537 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   527 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ list ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   538 
   528 
   539 # ~~~~~~ list
   529 # ~~~~~~ list
   540 blanks.list = element list {
   530 blanks.list =
   541    block.head?,
   531     element list {
   542    (  (attribute type {"ordered"}?, blanks.item, blanks.item+)
   532                 block.head?,
   543     | (attribute type {"glossary"}, item.glossary+) )
   533                 ( (attribute type {"ordered"}?, blanks.item, blanks.item+) |
   544 }
   534                   (attribute type {"glossary"}, item.glossary+) ) }
   545 blanks-m.list = element list {
   535 blanks-m.list =
   546    block.head?,
   536     element list {
   547    (  (attribute type {"ordered"}?, blanks-m.item, blanks-m.item+)
   537                 block.head?,
   548     | (attribute type {"glossary"}, item.glossary+) )
   538                 ( (attribute type {"ordered"}?, blanks-m.item, blanks-m.item+) |
   549 }
   539                   (attribute type {"glossary"}, item.glossary+) ) }
   550 blanks-c.list = element list {
   540 blanks-c.list =
   551    block.head?,
   541     element list {
   552    (  (attribute type {"ordered"}?, blanks.item, blanks.item+)
   542                 block.head?,
   553     | (attribute type {"glossary"}, item.glossary+) )
   543                 ( (attribute type {"ordered"}?, blanks.item, blanks.item+) |
   554 }
   544                   (attribute type {"glossary"}, item.glossary+) ) }
   555 correct.list = element list {
   545 correct.list =
   556    block.head?,
   546     element list {
   557    (  (attribute type {"ordered"}?, correct.item, correct.item+)
   547                 block.head?,
   558     | (attribute type {"glossary"}, item.glossary+) )
   548                 ( (attribute type {"ordered"}?, correct.item, correct.item+) |
   559 }
   549                   (attribute type {"glossary"}, item.glossary+) ) }
   560 pointing.list = element list {
   550 pointing.list =
   561    block.head?,
   551     element list {
   562    (  (attribute type {"ordered"}?, pointing.item, pointing.item+)
   552                 block.head?,
   563     | (attribute type {"glossary"}, item.glossary+) )
   553                 ( (attribute type {"ordered"}?, pointing.item, pointing.item+) |
   564 }
   554                   (attribute type {"glossary"}, item.glossary+) ) }
   565 
   555 
   566 # ~~~~~~ item
   556 # ~~~~~~ item
   567 blanks.item = element item { blanks.item.content }
   557 blanks.item = element item { blanks.item.content }
   568 blanks-m.item = element item { blanks-m.item.content }
   558 blanks-m.item = element item { blanks-m.item.content }
   569 blanks-c.item = element item { blanks-c.item.content }
   559 blanks-c.item = element item { blanks-c.item.content }
   577 correct.item.content = correct.inlines | correct.block+
   567 correct.item.content = correct.inlines | correct.block+
   578 pointing.item.content = pointing.inlines | pointing.block+
   568 pointing.item.content = pointing.inlines | pointing.block+
   579 
   569 
   580 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blockquote ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   570 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ blockquote ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   581 
   571 
   582 blanks.blockquote = element blockquote {
   572 blanks.blockquote =
   583    blockquote.attributes, blanks.blockquote.content }
   573     element blockquote { blockquote.attributes, blanks.blockquote.content }
   584 blanks-m.blockquote = element blockquote {
   574 blanks-m.blockquote =
   585    blockquote.attributes, blanks-m.blockquote.content }
   575     element blockquote { blockquote.attributes, blanks-m.blockquote.content }
   586 blanks-c.blockquote = element blockquote {
   576 blanks-c.blockquote =
   587    blockquote.attributes, blanks-c.blockquote.content }
   577     element blockquote { blockquote.attributes, blanks-c.blockquote.content }
   588 correct.blockquote = element blockquote {
   578 correct.blockquote =
   589    blockquote.attributes, correct.blockquote.content }
   579     element blockquote { blockquote.attributes, correct.blockquote.content }
   590 pointing.blockquote = element blockquote {
   580 pointing.blockquote =
   591    blockquote.attributes, pointing.blockquote.content }
   581     element blockquote { blockquote.attributes, pointing.blockquote.content }
   592 
   582 
   593 blanks.blockquote.content =
   583 blanks.blockquote.content =
   594    block.head?,
   584     block.head?,
   595    (blanks.p | speech | blanks.list)+,
   585     (blanks.p | speech | blanks.list)+,
   596    attribution?
   586     attribution?
   597 blanks-m.blockquote.content =
   587 blanks-m.blockquote.content =
   598    block.head?,
   588     block.head?,
   599    (blanks-m.p | speech | blanks-m.list)+,
   589     (blanks-m.p | speech | blanks-m.list)+,
   600    attribution?
   590     attribution?
   601 blanks-c.blockquote.content =
   591 blanks-c.blockquote.content =
   602    block.head?,
   592     block.head?,
   603    (blanks-c.p | speech | blanks-c.list)+,
   593     (blanks-c.p | speech | blanks-c.list)+,
   604    attribution?
   594     attribution?
   605 correct.blockquote.content =
   595 correct.blockquote.content =
   606    block.head?,
   596     block.head?,
   607    (correct.p | speech | correct.list)+,
   597     (correct.p | speech | correct.list)+,
   608    attribution?
   598     attribution?
   609 pointing.blockquote.content =
   599 pointing.blockquote.content =
   610    block.head?,
   600     block.head?,
   611    (pointing.p | speech | pointing.list)+,
   601     (pointing.p | speech | pointing.list)+,
   612    attribution?
   602     attribution?
   613 
   603 
   614 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ speech ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   604 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ speech ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   615 
   605 
   616 # ~~~~~~ speech
   606 # ~~~~~~ speech
   617 blanks.speech = element speech { blanks.speech.content }
   607 blanks.speech = element speech { blanks.speech.content }
   619 blanks-c.speech = element speech { blanks-c.speech.content }
   609 blanks-c.speech = element speech { blanks-c.speech.content }
   620 correct.speech = element speech { correct.speech.content }
   610 correct.speech = element speech { correct.speech.content }
   621 pointing.speech = element speech { pointing.speech.content }
   611 pointing.speech = element speech { pointing.speech.content }
   622 
   612 
   623 blanks.speech.content =
   613 blanks.speech.content =
   624    blanks.speaker?,
   614     blanks.speaker?,
   625    stage?,
   615     stage?,
   626    (blanks.p | blanks.blockquote)+
   616     (blanks.p | blanks.blockquote)+
   627 blanks-m.speech.content =
   617 blanks-m.speech.content =
   628    blanks-m.speaker?,
   618     blanks-m.speaker?,
   629    stage?,
   619     stage?,
   630    (blanks-m.p | blanks-m.blockquote)+
   620     (blanks-m.p | blanks-m.blockquote)+
   631 blanks-c.speech.content =
   621 blanks-c.speech.content =
   632    blanks-c.speaker?,
   622     blanks-c.speaker?,
   633    stage?,
   623     stage?,
   634    (blanks-c.p | blanks-c.blockquote)+
   624     (blanks-c.p | blanks-c.blockquote)+
   635 correct.speech.content =
   625 correct.speech.content =
   636    correct.speaker?,
   626     correct.speaker?,
   637    stage?,
   627     stage?,
   638    (correct.p | correct.blockquote)+
   628     (correct.p | correct.blockquote)+
   639 pointing.speech.content =
   629 pointing.speech.content =
   640    pointing.speaker?,
   630     pointing.speaker?,
   641    stage?,
   631     stage?,
   642    (pointing.p | pointing.blockquote)+
   632     (pointing.p | pointing.blockquote)+
   643 
   633 
   644 # ~~~~~~ speaker
   634 # ~~~~~~ speaker
   645 blanks.speaker = element speaker { blanks.speaker.content }
   635 blanks.speaker = element speaker { blanks.speaker.content }
   646 blanks-m.speaker = element speaker { blanks-m.speaker.content }
   636 blanks-m.speaker = element speaker { blanks-m.speaker.content }
   647 blanks-c.speaker = element speaker { blanks-c.speaker.content }
   637 blanks-c.speaker = element speaker { blanks-c.speaker.content }
   662 blanks-c.table = element table { table.attributes, blanks-m.table.content }
   652 blanks-c.table = element table { table.attributes, blanks-m.table.content }
   663 correct.table = element table { table.attributes, correct.table.content }
   653 correct.table = element table { table.attributes, correct.table.content }
   664 pointing.table = element table { table.attributes, pointing.table.content }
   654 pointing.table = element table { table.attributes, pointing.table.content }
   665 
   655 
   666 blanks.table.content =
   656 blanks.table.content =
   667    block.head?,
   657     block.head?,
   668    ((thead?, blanks.tbody+) | blanks.tr+),
   658     ((thead?, blanks.tbody+) | blanks.tr+),
   669    blanks.table.caption?
   659     blanks.table.caption?
   670 blanks-m.table.content =
   660 blanks-m.table.content =
   671    block.head?,
   661     block.head?,
   672    ((thead?, blanks-m.tbody+) | blanks-m.tr+),
   662     ((thead?, blanks-m.tbody+) | blanks-m.tr+),
   673    blanks-m.table.caption?
   663     blanks-m.table.caption?
   674 blanks-c.table.content =
   664 blanks-c.table.content =
   675    block.head?,
   665     block.head?,
   676    ((thead?, blanks-c.tbody+) | blanks-c.tr+),
   666     ((thead?, blanks-c.tbody+) | blanks-c.tr+),
   677    blanks-c.table.caption?
   667     blanks-c.table.caption?
   678 correct.table.content =
   668 correct.table.content =
   679    block.head?,
   669     block.head?,
   680    ((thead?, correct.tbody+) | correct.tr+),
   670     ((thead?, correct.tbody+) | correct.tr+),
   681    correct.table.caption?
   671     correct.table.caption?
   682 pointing.table.content =
   672 pointing.table.content =
   683    block.head?,
   673     block.head?,
   684    ((thead?, pointing.tbody+) | pointing.tr+),
   674     ((thead?, pointing.tbody+) | pointing.tr+),
   685    pointing.table.caption?
   675     pointing.table.caption?
   686 
   676 
   687 # ~~~~~~ tbody
   677 # ~~~~~~ tbody
   688 blanks.tbody = element tbody { blanks.tbody.content }
   678 blanks.tbody = element tbody { blanks.tbody.content }
   689 blanks-m.tbody = element tbody { blanks-m.tbody.content }
   679 blanks-m.tbody = element tbody { blanks-m.tbody.content }
   690 blanks-c.tbody = element tbody { blanks-m.tbody.content }
   680 blanks-c.tbody = element tbody { blanks-m.tbody.content }
   691 correct.tbody = element tbody { correct.tbody.content }
   681 correct.tbody = element tbody { correct.tbody.content }
   692 pointing.tbody = element tbody { pointing.tbody.content }
   682 pointing.tbody = element tbody { pointing.tbody.content }
   693 
   683 
   694 blanks.tbody.content =
   684 blanks.tbody.content =
   695    blanks.tr+
   685     blanks.tr+
   696 blanks-m.tbody.content =
   686 blanks-m.tbody.content =
   697    blanks-m.tr+
   687     blanks-m.tr+
   698 blanks-c.tbody.content =
   688 blanks-c.tbody.content =
   699    blanks-c.tr+
   689     blanks-c.tr+
   700 correct.tbody.content =
   690 correct.tbody.content =
   701    correct.tr+
   691     correct.tr+
   702 pointing.tbody.content =
   692 pointing.tbody.content =
   703    pointing.tr+
   693     pointing.tr+
   704 
   694 
   705 # ~~~~~~ tr
   695 # ~~~~~~ tr
   706 blanks.tr = element tr { tr.attributes, blanks.tr.content }
   696 blanks.tr = element tr { tr.attributes, blanks.tr.content }
   707 blanks-m.tr = element tr { tr.attributes, blanks-m.tr.content }
   697 blanks-m.tr = element tr { tr.attributes, blanks-m.tr.content }
   708 blanks-c.tr = element tr { tr.attributes, blanks-c.tr.content }
   698 blanks-c.tr = element tr { tr.attributes, blanks-c.tr.content }
   709 correct.tr = element tr { tr.attributes, correct.tr.content }
   699 correct.tr = element tr { tr.attributes, correct.tr.content }
   710 pointing.tr = element tr { tr.attributes, pointing.tr.content }
   700 pointing.tr = element tr { tr.attributes, pointing.tr.content }
   711 
   701 
   712 blanks.tr.content =
   702 blanks.tr.content =
   713   (blanks.td | blanks.th)+
   703     (blanks.td | blanks.th)+
   714 blanks-m.tr.content =
   704 blanks-m.tr.content =
   715   (blanks-m.td | blanks-m.th)+
   705     (blanks-m.td | blanks-m.th)+
   716 blanks-c.tr.content =
   706 blanks-c.tr.content =
   717   (blanks-c.td | blanks-c.th)+
   707     (blanks-c.td | blanks-c.th)+
   718 correct.tr.content =
   708 correct.tr.content =
   719   (correct.td | correct.th)+
   709     (correct.td | correct.th)+
   720 pointing.tr.content =
   710 pointing.tr.content =
   721   (pointing.td | pointing.th)+
   711     (pointing.td | pointing.th)+
   722 
   712 
   723 # ~~~~~~ td, th
   713 # ~~~~~~ td, th
   724 blanks.td = element td { td.attributes, blanks.td.content }
   714 blanks.td = element td { td.attributes, blanks.td.content }
   725 blanks.th = element th { td.attributes, blanks.td.content }
   715 blanks.th = element th { td.attributes, blanks.td.content }
   726 blanks-m.td = element td { td.attributes, blanks-m.td.content }
   716 blanks-m.td = element td { td.attributes, blanks-m.td.content }
   731 correct.th = element th { td.attributes, correct.td.content }
   721 correct.th = element th { td.attributes, correct.td.content }
   732 pointing.td = element td { td.attributes, pointing.td.content }
   722 pointing.td = element td { td.attributes, pointing.td.content }
   733 pointing.th = element th { td.attributes, pointing.td.content }
   723 pointing.th = element th { td.attributes, pointing.td.content }
   734 
   724 
   735 blanks.td.content =
   725 blanks.td.content =
   736    blanks.inlines
   726     blanks.inlines
   737  | (blanks.p | blanks.media)+
   727     | (blanks.p | blanks.media)+
   738 blanks-m.td.content =
   728 blanks-m.td.content =
   739    blanks-m.inlines
   729     blanks-m.inlines
   740  | (blanks-m.p | blanks-m.media)+
   730     | (blanks-m.p | blanks-m.media)+
   741 blanks-c.td.content =
   731 blanks-c.td.content =
   742    blanks-c.inlines
   732     blanks-c.inlines
   743  | (blanks-c.p | blanks-c.media)+
   733     | (blanks-c.p | blanks-c.media)+
   744 correct.td.content =
   734 correct.td.content =
   745    correct.inlines
   735     correct.inlines
   746  | (correct.p | media)+
   736     | (correct.p | media)+
   747 pointing.td.content =
   737 pointing.td.content =
   748    pointing.inlines
   738     pointing.inlines
   749  | (pointing.p | media)+
   739     | (pointing.p | media)+
   750 
   740 
   751 # ~~~~~~ table.caption
   741 # ~~~~~~ table.caption
   752 blanks.table.caption = element caption { blanks.caption.content }
   742 blanks.table.caption = element caption { blanks.caption.content }
   753 blanks-m.table.caption = element caption { blanks-m.caption.content }
   743 blanks-m.table.caption = element caption { blanks-m.caption.content }
   754 blanks-c.table.caption = element caption { blanks-c.caption.content }
   744 blanks-c.table.caption = element caption { blanks-c.caption.content }
   755 correct.table.caption = element caption { correct.caption.content }
   745 correct.table.caption = element caption { correct.caption.content }
   756 pointing.table.caption = element caption { pointing.caption.content }
   746 pointing.table.caption = element caption { pointing.caption.content }
   757 
   747 
   758 blanks.caption.content =
   748 blanks.caption.content =
   759    blanks.inlines
   749     blanks.inlines
   760  | (blanks.p | speech | blanks.list | blockquote)+
   750     | (blanks.p | speech | blanks.list | blockquote)+
   761 blanks-m.caption.content =
   751 blanks-m.caption.content =
   762    blanks-m.inlines
   752     blanks-m.inlines
   763  | (blanks-m.p | speech | blanks-m.list | blockquote)+
   753     | (blanks-m.p | speech | blanks-m.list | blockquote)+
   764 blanks-c.caption.content =
   754 blanks-c.caption.content =
   765    blanks-c.inlines
   755     blanks-c.inlines
   766  | (blanks-c.p | speech | blanks-c.list | blockquote)+
   756     | (blanks-c.p | speech | blanks-c.list | blockquote)+
   767 correct.caption.content =
   757 correct.caption.content =
   768    correct.inlines
   758     correct.inlines
   769  | (correct.p | speech | correct.list | blockquote)+
   759     | (correct.p | speech | correct.list | blockquote)+
   770 pointing.caption.content =
   760 pointing.caption.content =
   771    pointing.inlines
   761     pointing.inlines
   772  | (pointing.p | speech | pointing.list | blockquote)+
   762     | (pointing.p | speech | pointing.list | blockquote)+
   773 
   763 
   774 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ media ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   764 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ media ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   775 
   765 
   776 # ~~~~~~ media
   766 # ~~~~~~ media
   777 blanks.media = element media { media.attributes, blanks.media.content }
   767 blanks.media = element media { media.attributes, blanks.media.content }
   780 correct.media = element media { media.attributes, correct.media.content }
   770 correct.media = element media { media.attributes, correct.media.content }
   781 pointing.media = element media { media.attributes, pointing.media.content }
   771 pointing.media = element media { media.attributes, pointing.media.content }
   782 dictation.media = element media { media.attributes, dictation.media.content }
   772 dictation.media = element media { media.attributes, dictation.media.content }
   783 
   773 
   784 blanks.media.content =
   774 blanks.media.content =
   785    block.head?,
   775     block.head?,
   786    (blanks.image | audio | video)+,
   776     (blanks.image | audio | video)+,
   787    blanks.media.caption?,
   777     blanks.media.caption?,
   788    link?
   778     link?
   789 blanks-m.media.content =
   779 blanks-m.media.content =
   790    block.head?,
   780     block.head?,
   791    (blanks-m.image | audio | video)+,
   781     (blanks-m.image | audio | video)+,
   792    blanks-m.media.caption?,
   782     blanks-m.media.caption?,
   793    link?
   783     link?
   794 blanks-c.media.content =
   784 blanks-c.media.content =
   795    block.head?,
   785     block.head?,
   796    (image | audio | video)+,
   786     (image | audio | video)+,
   797    blanks-c.media.caption?,
   787     blanks-c.media.caption?,
   798    link?
   788     link?
   799 correct.media.content =
   789 correct.media.content =
   800    block.head?,
   790     block.head?,
   801    (image | audio | video)+,
   791     (image | audio | video)+,
   802    correct.media.caption?,
   792     correct.media.caption?,
   803    link?
   793     link?
   804 pointing.media.content =
   794 pointing.media.content =
   805    block.head?,
   795     block.head?,
   806    (image | audio | video)+,
   796     (image | audio | video)+,
   807    pointing.media.caption?,
   797     pointing.media.caption?,
   808    link?
   798     link?
   809 dictation.media.content =
   799 dictation.media.content =
   810    audio
   800     audio
   811 
   801 
   812 # ~~~~~~ blanks.image
   802 # ~~~~~~ blanks.image
   813 blanks.image = element image { image.attributes, blanks.image.content }
   803 blanks.image = element image { image.attributes, blanks.image.content }
   814 blanks-m.image = element image { image.attributes, blanks-m.image.content }
   804 blanks-m.image = element image { image.attributes, blanks-m.image.content }
   815 
   805 
   816 blanks.image.content =
   806 blanks.image.content =
   817    copyright?,
   807     copyright?,
   818    blanks.dropzone*
   808     blanks.dropzone*
   819 blanks-m.image.content =
   809 blanks-m.image.content =
   820    copyright?,
   810     copyright?,
   821    blanks-m.dropzone*
   811     blanks-m.dropzone*
   822 
   812 
   823 # ~~~~~~ dropzone
   813 # ~~~~~~ dropzone
   824 blanks.dropzone = element dropzone {
   814 blanks.dropzone =
   825    blanks.dropzone.attributes, blanks.dropzone.content }
   815     element dropzone { blanks.dropzone.attributes, blanks.dropzone.content }
   826 blanks-m.dropzone = element dropzone {
   816 blanks-m.dropzone =
   827    blanks-m.dropzone.attributes, blanks-m.dropzone.content }
   817     element dropzone { blanks-m.dropzone.attributes, blanks-m.dropzone.content }
   828 
   818 
   829 blanks.dropzone.attributes =
   819 blanks.dropzone.attributes =
   830    x.attribute
   820     x.attribute
   831  & y.attribute
   821     & y.attribute
   832 blanks-m.dropzone.attributes =
   822 blanks-m.dropzone.attributes =
   833    x.attribute
   823     x.attribute
   834  & y.attribute
   824     & y.attribute
   835  & h.attribute
   825     & h.attribute
   836  & w.attribute
   826     & w.attribute
   837 
   827 
   838 blanks.dropzone.content =
   828 blanks.dropzone.content =
   839    blank
   829     blank
   840 blanks-m.dropzone.content =
   830 blanks-m.dropzone.content =
   841    blank-m
   831     blank-m
   842 
   832 
   843 # ~~~~~~ media.caption
   833 # ~~~~~~ media.caption
   844 blanks.media.caption = element caption {
   834 blanks.media.caption =
   845    caption.attributes, blanks.caption.content }
   835     element caption { caption.attributes, blanks.caption.content }
   846 blanks-m.media.caption = element caption {
   836 blanks-m.media.caption =
   847    caption.attributes, blanks-m.caption.content }
   837     element caption { caption.attributes, blanks-m.caption.content }
   848 blanks-c.media.caption = element caption {
   838 blanks-c.media.caption =
   849    caption.attributes, blanks-c.caption.content }
   839     element caption { caption.attributes, blanks-c.caption.content }
   850 correct.media.caption = element caption {
   840 correct.media.caption =
   851    caption.attributes, correct.caption.content }
   841     element caption { caption.attributes, correct.caption.content }
   852 pointing.media.caption = element caption {
   842 pointing.media.caption =
   853    caption.attributes, pointing.caption.content }
   843     element caption { caption.attributes, pointing.caption.content }
   854 
   844 
   855 # ~~~~~~~~~~~~~~~~~~~~~~~~ choices.right, choices.wrong ~~~~~~~~~~~~~~~~~~~~~~~
   845 # ~~~~~~~~~~~~~~~~~~~~~~~~ choices.right, choices.wrong ~~~~~~~~~~~~~~~~~~~~~~~
   856 
   846 
   857 choices.right = element right { choices.right.content }
   847 choices.right = element right { choices.right.content }
   858 choices.wrong = element wrong { choices.right.content }
   848 choices.wrong = element wrong { choices.right.content }
   859 
   849 
   860 choices.right.content =
   850 choices.right.content =
   861    inlines
   851     inlines
   862  | ((p | image | (audio, image?) | video), help?, answer?)
   852     | ((p | image | (audio, image?) | video), help?, answer?)
   863 
   853 
   864 # ~~~~~~~~~~~~~~~~~~~~ blanks.intruders, blanks-m.intruders  ~~~~~~~~~~~~~~~~~~
   854 # ~~~~~~~~~~~~~~~~~~~~ blanks.intruders, blanks-m.intruders  ~~~~~~~~~~~~~~~~~~
   865 
   855 
   866 blanks.intruders = element intruders { blanks.intruders.content }
   856 blanks.intruders = element intruders { blanks.intruders.content }
   867 blanks-m.intruders = element intruders { blanks-m.intruders.content }
   857 blanks-m.intruders = element intruders { blanks-m.intruders.content }
   879 
   869 
   880 # ~~~~~~~ matching.intruders
   870 # ~~~~~~~ matching.intruders
   881 matching.intruders = element intruders { matching.intruders.content }
   871 matching.intruders = element intruders { matching.intruders.content }
   882 
   872 
   883 matching.intruders.content =
   873 matching.intruders.content =
   884    match.item+
   874     match.item+
   885 
   875 
   886 # ~~~~~~~ match.item
   876 # ~~~~~~~ match.item
   887 match.item = element item { match.item.content }
   877 match.item = element item { match.item.content }
   888 
   878 
   889 match.item.content =
   879 match.item.content =
   890    inlines
   880     inlines
   891  | (p, help?, answer?)
   881     | (p, help?, answer?)
   892 
   882 
   893 # ~~~~~~~~~~~~~~~~~~~~ sort.intruders, comparison, sort.item ~~~~~~~~~~~~~~~~~~
   883 # ~~~~~~~~~~~~~~~~~~~~ sort.intruders, comparison, sort.item ~~~~~~~~~~~~~~~~~~
   894 
   884 
   895 # ~~~~~~~ sort.intruders
   885 # ~~~~~~~ sort.intruders
   896 sort.intruders = element intruders { sort.intruders.content }
   886 sort.intruders = element intruders { sort.intruders.content }
   897 
   887 
   898 sort.intruders.content =
   888 sort.intruders.content =
   899    sort.item+
   889     sort.item+
   900 
   890 
   901 # ~~~~~~ comparison
   891 # ~~~~~~ comparison
   902 comparison = element comparison { comparison.content }
   892 comparison = element comparison { comparison.content }
   903 
   893 
   904 comparison.content = inlines
   894 comparison.content = inlines
   905 
   895 
   906 # ~~~~~~ sort.item
   896 # ~~~~~~ sort.item
   907 sort.item = element item { sort.item.attributes, sort.item.content }
   897 sort.item = element item { sort.item.attributes, sort.item.content }
   908 
   898 
   909 sort.item.attributes =
   899 sort.item.attributes =
   910    item.shuffle.attribute?
   900     item.shuffle.attribute?
   911 item.shuffle.attribute = attribute shuffle { xsd:integer }
   901 item.shuffle.attribute = attribute shuffle { xsd:integer }
   912 
   902 
   913 sort.item.content =
   903 sort.item.content =
   914    inlines
   904     inlines
   915  | (p, help?, answer?)
   905     | (p, help?, answer?)
   916 
   906 
   917 # ~~~~~~~~~~~~~~~~~~~~~ categories.intruders, category.item ~~~~~~~~~~~~~~~~~~~
   907 # ~~~~~~~~~~~~~~~~~~~~~ categories.intruders, category.item ~~~~~~~~~~~~~~~~~~~
   918 
   908 
   919 # ~~~~~~ categories.intruders
   909 # ~~~~~~ categories.intruders
   920 categories.intruders = element intruders { categories.intruders.content }
   910 categories.intruders = element intruders { categories.intruders.content }
   921 
   911 
   922 categories.intruders.content =
   912 categories.intruders.content =
   923    category.item+
   913     category.item+
   924 
   914 
   925 # ~~~~~~ category.item
   915 # ~~~~~~ category.item
   926 category.item = element item { category.item.content }
   916 category.item = element item { category.item.content }
   927 
   917 
   928 category.item.content =
   918 category.item.content =
   929    inlines
   919     inlines
   930  | (p, help?, answer?)
   920     | (p, help?, answer?)
   931 
   921 
   932 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ words.item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   922 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ words.item ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   933 words.item = element item {words.item.content, words.item.attributes }
   923 words.item = element item {words.item.content, words.item.attributes }
   934 
   924 
   935 words.item.content = inlines
   925 words.item.content = inlines
   936 
   926 
   937 words.item.attributes =
   927 words.item.attributes =
   938    startx
   928     startx
   939  & starty
   929     & starty
   940  & endx
   930     & endx
   941  & endy
   931     & endy
   942 
   932 
   943 startx = attribute startx {xsd:token {pattern = "[a-zA-Z]+"}}
   933 startx = attribute startx {xsd:token {pattern = "[a-zA-Z]+"}}
   944 starty = attribute starty {xsd:token {pattern = "\d+"}}
   934 starty = attribute starty {xsd:token {pattern = "\d+"}}
   945 endx = attribute endx {xsd:token {pattern = "[a-zA-Z]+"}}
   935 endx = attribute endx {xsd:token {pattern = "[a-zA-Z]+"}}
   946 endy = attribute endy {xsd:token {pattern = "\d+"}}
   936 endy = attribute endy {xsd:token {pattern = "\d+"}}
   966 #                                 INLINE LEVEL
   956 #                                 INLINE LEVEL
   967 # =============================================================================
   957 # =============================================================================
   968 
   958 
   969 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   959 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ inlines ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   970 
   960 
   971 blanks.inlines = mixed {
   961 blanks.inlines =
   972    sup*
   962     mixed {
   973  & sub*
   963         sup* & sub*
   974  & var*
   964         & var*
   975  & number*
   965         & number*
   976  & acronym*
   966         & acronym*
   977  & warning*
   967         & warning*
   978 
   968 
   979  & highlight*
   969         & highlight*
   980  & emphasis*
   970         & emphasis*
   981  & mentioned*
   971         & mentioned*
   982  & literal*
   972         & literal*
   983  & term*
   973         & term*
   984  & stage*
   974         & stage*
   985  & name*
   975         & name*
   986  & foreign*
   976         & foreign*
   987  & date*
   977         & date*
   988  & math*
   978         & math*
   989  & quote*
   979         & quote*
   990  & initial*
   980         & initial*
   991  & note*
   981         & note*
   992  & link*
   982         & link*
   993  & anchor*
   983         & anchor*
   994  & index*
   984         & index*
   995  & image*
   985         & image*
   996  & audio*
   986         & audio*
   997  & smil*
   987         & smil*
   998  & nowrap*
   988         & nowrap*
   999 
   989 
  1000  & blank*
   990         & blank*
  1001 }
   991     }
  1002 
   992 
  1003 blanks-m.inlines = mixed {
   993 blanks-m.inlines =
  1004    sup*
   994     mixed {
  1005  & sub*
   995         sup* & sub*
  1006  & var*
   996         & var*
  1007  & number*
   997         & number*
  1008  & acronym*
   998         & acronym*
  1009  & warning*
   999         & warning*
  1010 
  1000 
  1011  & highlight*
  1001         & highlight*
  1012  & emphasis*
  1002         & emphasis*
  1013  & mentioned*
  1003         & mentioned*
  1014  & literal*
  1004         & literal*
  1015  & term*
  1005         & term*
  1016  & stage*
  1006         & stage*
  1017  & name*
  1007         & name*
  1018  & foreign*
  1008         & foreign*
  1019  & date*
  1009         & date*
  1020  & math*
  1010         & math*
  1021  & quote*
  1011         & quote*
  1022  & initial*
  1012         & initial*
  1023  & note*
  1013         & note*
  1024  & link*
  1014         & link*
  1025  & anchor*
  1015         & anchor*
  1026  & index*
  1016         & index*
  1027  & image*
  1017         & image*
  1028  & audio*
  1018         & audio*
  1029  & smil*
  1019         & smil*
  1030  & nowrap*
  1020         & nowrap*
  1031 
  1021 
  1032  & blank-m*
  1022         & blank-m*
  1033 }
  1023     }
  1034 
  1024 
  1035 blanks-c.inlines = mixed {
  1025 blanks-c.inlines =
  1036    sup*
  1026     mixed {
  1037  & sub*
  1027         sup* & sub*
  1038  & var*
  1028         & var*
  1039  & number*
  1029         & number*
  1040  & acronym*
  1030         & acronym*
  1041  & warning*
  1031         & warning*
  1042 
  1032 
  1043  & highlight*
  1033         & highlight*
  1044  & emphasis*
  1034         & emphasis*
  1045  & mentioned*
  1035         & mentioned*
  1046  & literal*
  1036         & literal*
  1047  & term*
  1037         & term*
  1048  & stage*
  1038         & stage*
  1049  & name*
  1039         & name*
  1050  & foreign*
  1040         & foreign*
  1051  & date*
  1041         & date*
  1052  & math*
  1042         & math*
  1053  & quote*
  1043         & quote*
  1054  & initial*
  1044         & initial*
  1055  & note*
  1045         & note*
  1056  & link*
  1046         & link*
  1057  & anchor*
  1047         & anchor*
  1058  & index*
  1048         & index*
  1059  & image*
  1049         & image*
  1060  & audio*
  1050         & audio*
  1061  & smil*
  1051         & smil*
  1062  & nowrap*
  1052         & nowrap*
  1063 
  1053 
  1064  & blank-c*
  1054         & blank-c*
  1065 }
  1055     }
  1066 
  1056 
  1067 correct.inlines = mixed {
  1057 correct.inlines =
  1068    sup*
  1058     mixed {
  1069  & sub*
  1059         sup* & sub*
  1070  & var*
  1060         & var*
  1071  & number*
  1061         & number*
  1072  & acronym*
  1062         & acronym*
  1073  & warning*
  1063         & warning*
  1074 
  1064 
  1075  & highlight*
  1065         & highlight*
  1076  & emphasis*
  1066         & emphasis*
  1077  & mentioned*
  1067         & mentioned*
  1078  & literal*
  1068         & literal*
  1079  & term*
  1069         & term*
  1080  & stage*
  1070         & stage*
  1081  & name*
  1071         & name*
  1082  & foreign*
  1072         & foreign*
  1083  & date*
  1073         & date*
  1084  & math*
  1074         & math*
  1085  & quote*
  1075         & quote*
  1086  & initial*
  1076         & initial*
  1087  & note*
  1077         & note*
  1088  & link*
  1078         & link*
  1089  & anchor*
  1079         & anchor*
  1090  & index*
  1080         & index*
  1091  & image*
  1081         & image*
  1092  & audio*
  1082         & audio*
  1093  & smil*
  1083         & smil*
  1094  & nowrap*
  1084         & nowrap*
  1095 
  1085 
  1096  & char*
  1086         & char*
  1097 }
  1087     }
  1098 
  1088 
  1099 pointing.inlines = mixed {
  1089 pointing.inlines =
  1100    sup*
  1090     mixed {
  1101  & sub*
  1091         sup* & sub*
  1102  & var*
  1092         & var*
  1103  & number*
  1093         & number*
  1104  & acronym*
  1094         & acronym*
  1105  & warning*
  1095         & warning*
  1106 
  1096 
  1107  & highlight*
  1097         & highlight*
  1108  & emphasis*
  1098         & emphasis*
  1109  & mentioned*
  1099         & mentioned*
  1110  & literal*
  1100         & literal*
  1111  & term*
  1101         & term*
  1112  & stage*
  1102         & stage*
  1113  & name*
  1103         & name*
  1114  & foreign*
  1104         & foreign*
  1115  & date*
  1105         & date*
  1116  & math*
  1106         & math*
  1117  & quote*
  1107         & quote*
  1118  & initial*
  1108         & initial*
  1119  & note*
  1109         & note*
  1120  & link*
  1110         & link*
  1121  & anchor*
  1111         & anchor*
  1122  & index*
  1112         & index*
  1123  & image*
  1113         & image*
  1124  & audio*
  1114         & audio*
  1125  & smil*
  1115         & smil*
  1126  & nowrap*
  1116         & nowrap*
  1127 
  1117 
  1128  & point*
  1118         & point*
  1129 }
  1119     }
  1130 
  1120 
  1131 dictation.inlines = mixed {
  1121 dictation.inlines = mixed { warning* & dictation.hint* }
  1132    warning*
       
  1133  & dictation.hint*
       
  1134 }
       
  1135 
  1122 
  1136 # ~~~~~~~~~~~~~~~~~~~~~~~~~~ blank, blank-m, blank-c ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1123 # ~~~~~~~~~~~~~~~~~~~~~~~~~~ blank, blank-m, blank-c ~~~~~~~~~~~~~~~~~~~~~~~~~~
  1137 
  1124 
  1138 # ~~~~~~ blank
  1125 # ~~~~~~ blank
  1139 blank = element blank { blank.attributes, blank.content }
  1126 blank = element blank { blank.attributes, blank.content }
  1140 
  1127 
  1141 blank.attributes =
  1128 blank.attributes =
  1142    area.attribute?
  1129     area.attribute?
  1143  & long.attribute?
  1130     & long.attribute?
  1144 area.attribute = attribute area { xsd:boolean }
  1131 area.attribute = attribute area { xsd:boolean }
  1145 
  1132 
  1146 blank.content =
  1133 blank.content =
  1147    text
  1134     text
  1148  | (s+, help?, answer?)
  1135     | (s+, help?, answer?)
  1149 
  1136 
  1150 # ~~~~~~ blank-m
  1137 # ~~~~~~ blank-m
  1151 blank-m = element blank { blank-m.content }
  1138 blank-m = element blank { blank-m.content }
  1152 blank-m.content =
  1139 blank-m.content =
  1153    p
  1140     p
  1154  | math
  1141     | math
  1155  | image
  1142     | image
  1156  | audio
  1143     | audio
  1157  | (s-m+, help?, answer?)
  1144     | (s-m+, help?, answer?)
  1158 
  1145 
  1159 # ~~~~~~ blank-c
  1146 # ~~~~~~ blank-c
  1160 blank-c = element blank { blank-c.attributes, blank-c.content }
  1147 blank-c = element blank { blank-c.attributes, blank-c.content }
  1161 
  1148 
  1162 blank-c.attributes = form.attribute?
  1149 blank-c.attributes = form.attribute?
  1171 s.content = text
  1158 s.content = text
  1172 
  1159 
  1173 # ~~~~~~ s-m
  1160 # ~~~~~~ s-m
  1174 s-m = element s { s-m.content }
  1161 s-m = element s { s-m.content }
  1175 s-m.content =
  1162 s-m.content =
  1176    p
  1163     p
  1177  | math
  1164     | math
  1178  | image
  1165     | image
  1179  | audio
  1166     | audio
  1180 
  1167 
  1181 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ char ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1168 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ char ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1182 
  1169 
  1183 char = element char { char.attributes, char.content }
  1170 char = element char { char.attributes, char.content }
  1184 
  1171 
  1190 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1177 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ point ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1191 
  1178 
  1192 point = element point { point.attributes, point.content }
  1179 point = element point { point.attributes, point.content }
  1193 
  1180 
  1194 point.attributes =
  1181 point.attributes =
  1195    point.ref.attribute?
  1182     point.ref.attribute?
  1196 
  1183 
  1197 point.ref.attribute = attribute ref {
  1184 point.ref.attribute =
  1198    "right" | "cat1" | "cat2" | "cat3" | "cat4" | "cat5" }
  1185     attribute ref { "right" | "cat1" | "cat2" | "cat3" | "cat4" | "cat5" }
  1199 
  1186 
  1200 point.content = inlines
  1187 point.content = inlines
  1201 
  1188 
  1202 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dictation.hint ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1189 # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ dictation.hint ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1203 
  1190 
  1213 
  1200 
  1214 # ~~~~~~ mistake
  1201 # ~~~~~~ mistake
  1215 mistake = element mistake { mistake.attributes, mistake.content }
  1202 mistake = element mistake { mistake.attributes, mistake.content }
  1216 
  1203 
  1217 mistake.attributes =
  1204 mistake.attributes =
  1218    mistake.is.attribute?
  1205     mistake.is.attribute?
  1219 mistake.is.attribute = attribute is { text }
  1206 mistake.is.attribute = attribute is { text }
  1220 
  1207 
  1221 mistake.content = inlines
  1208 mistake.content = inlines