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