Update Concepts et objets de MACAO : précision ajouterReponse TAT authored by Eliott Sammier's avatar Eliott Sammier
......@@ -5,15 +5,17 @@
[[_TOC_]]
# Dans Macao 1 et 2 :
![Macao_12_concepts_annotation](uploads/5b30aec165b2f85bf18735f72fb6f9e3/Macao_12_concepts_annotation.png)
---
----
## Parties
Un module contient une ou plusieurs parties _(ex: "Reconnaître les syllabes")_. Côté code, une partie a la même représentation qu'un module, c'est un élément sans contenu propre, décrit comme un `<item>` MosMod dans [`imsmanifest.xml`](https://gitlab.tetras-libre.fr/macao/macao-legacy/-/blob/main/Basilisk/MACAO/macao_12/imsmanifest.xml)
Un module contient une ou plusieurs parties _(ex: "Reconnaître les syllabes")_. Côté code, une partie a la même représentation qu'un module, c'est un élément sans contenu propre, décrit comme un `<item>` MosMod dans [`imsmanifest.xml`](https://gitlab.tetras-libre.fr/macao/macao-legacy/-/blob/main/Basilisk/MACAO/macao_12/imsmanifest.xml)
<details><summary>Exemple XML</summary>
<details>
<summary>Exemple XML</summary>
```xml
<organization>
......@@ -45,21 +47,28 @@ Un module contient une ou plusieurs parties _(ex: "Reconnaître les syllabes")_.
<!-- ... -->
</organization>
```
</details>
**Données à extraire :**
- [x] ID -> attribut `identifier`
- [x] Titre -> élément `<title>`
- [x] Descendants dans l'arbre -> éléments `<item>`
----
- [x] ID -\> attribut `identifier`
- [x] Titre -\> élément `<title>`
- [x] Descendants dans l'arbre -\> éléments `<item>`
---
## Sous-parties
Les "feuilles" de l'arborescence visible dans le panneau de gauche, éléments non dépliables _(ex: "Reconnaître les syllabes en anglais oral")_. Une sous-partie contient plusieurs **pages**, dont la première est affichée quand on sélectionne la sous-partie. Une sous-partie est décrite dans un fichier `sco/MosEtp###`, qui déclare un objet `MosSCO` pour définir son contenu.
```js
oSco = new MosSCO("MosEtp129", "> Reconnaître les syllabes en anglais oral", "MACAO", "MACAO 1 - S'entraîner à la reconnaissance", "", "macao_fusion_ss_barre", "fr");
```
Peu d'infos utiles : nom du fichier, titre (déjà défini dans le `<title>`), titre du "stage" (constant), titre du module parent (déjà connu grâce au manifest), et quelques champs constants.
Peu d'infos utiles : nom du fichier, titre (déjà défini dans le `<title>`), titre du "stage" (constant), titre du module parent (déjà connu grâce au manifest), et quelques champs constants.\
Ensuite quelques lignes inutiles, puis on passe à la déclaration des pages.
```js
oSco.tabPages[oSco.tabPages.length] = new PageContenu("Repérer les syllabes orales", "pg861", "exercice", "");
......@@ -68,140 +77,166 @@ oSco.tabPages[oSco.tabPages.length] = new PageContenu("Commentaire", "pg636", "c
// ^ titre ^ id ^ type
// [...]
```
Le plus important est l'ID de la page `"pgXXX"`, et éventuellement le type (`"exercice"` ou `"cours"`), le titre de la page étant déclaré aussi dans la page elle-même.
**Données à extraire :**
- Dans le manifest
- [x] ID -> attribut `identifier`
- [x] Titre -> élément `<title>`
- [x] ID -\> attribut `identifier`
- [x] Titre -\> élément `<title>`
- Dans le fichier `MosEtp###.html`
- [~] Titre -> `<title>`
- [x] Liste des pages (titre, ID) -> arguments de `new PageContenu()`
----
- [~] Titre -\> `<title>`
- [x] Liste des pages (titre, ID) -\> arguments de `new PageContenu()`
---
## Pages ou activités
Les "unités de navigation". La section centrale de Macao affiche toujours 1 page, dont le nom est indiqué en haut à droite _(ex: "Repérer les syllabes orales")_. Une page contient une "activité", qui peut être un cours (sans saisie interactive) ou un des 4 types d'exercices (`QC, QM, TAT, GD` dans `MosMtr/scripts/contenu/ClasseExercice___.js` + `ClasseCours.js`) ***[À confirmer: autres types de contenus?]***. Elle est décrite dans un fichier `contenu/pages/pg###.html`, qui déclare un objet `Cours` ou `Exercice___` pour définir son contenu.
Les "unités de navigation". La section centrale de Macao affiche toujours 1 page, dont le nom est indiqué en haut à droite _(ex: "Repérer les syllabes orales")_. Une page contient une "activité", qui peut être un cours (sans saisie interactive) ou un des 4 types d'exercices (`QC, QM, TAT, GD` dans `MosMtr/scripts/contenu/ClasseExercice___.js` + `ClasseCours.js`) **_\[À confirmer: autres types de contenus?\]_**. Elle est décrite dans un fichier `contenu/pages/pg###.html`, qui déclare un objet `Cours` ou `Exercice___` pour définir son contenu.
**Données à extraire (communes à toutes les activités) :**
- [x] Type d'activité -> premier appel de constructeur `new ___()`
- [x] [Commentaires](#commentaires) -> éléments `<div id="divCmt___">` dans `<div id="zoneInvisible">`
- Dans les descriptions, commentaires, blocs HTML divers
- [ ] [Images](#images) -> éléments `<img id="MosImg___">`
- [ ] Objets Flash -> appels de fonction `PF_clipAV(...)`
- [ ] Pages d'aide/docs -> appels de fonction `SCO_ouvrirDoc(...)`
- [x] Type d'activité -\> premier appel de constructeur `new ___()`
- [x] [Commentaires](#commentaires) -\> éléments `<div id="divCmt___">` dans `<div id="zoneInvisible">`
- [ ] Dans les descriptions, commentaires, blocs HTML divers
- [ ] [Images](#images) -\> éléments `<img id="MosImg___">`
- [ ] Objets Flash -\> appels de fonction `PF_clipAV(...)`
- [ ] Pages d'aide/docs -\> appels de fonction `SCO_ouvrirDoc(...)`
### Cours
Du texte, très souvent des audios, mais parfois aussi des objets Flash spécialisés (voir #11).
Du texte, très souvent des audios, mais parfois aussi des objets Flash spécialisés (voir #11).\
**Quantité :** 59
<details><summary>Exemples</summary>
<details>
<summary>Exemples</summary>
**Exemple de cours simple** : `pg686.html`, mémento _"L'accentuation des auxiliaires"_
![Screenshot_2024-05-15_15-58-10](uploads/6406297d502d9cd9e05360a6715f631a/Screenshot_2024-05-15_15-58-10.png)
Exemple de "cours" avec un **exercice en Flash** : `pg455.html`, première page de _"> Reconnaître les marques de l'accentuation"_
**Exemple de cours simple** : `pg686.html`, mémento _"L'accentuation des auxiliaires"_\
![Screenshot_2024-05-15_15-58-10](uploads/6406297d502d9cd9e05360a6715f631a/Screenshot_2024-05-15_15-58-10.png)\
Exemple de "cours" avec un **exercice en Flash** : `pg455.html`, première page de _"\> Reconnaître les marques de l'accentuation"_\
![Screenshot_2024-05-15_15-57-31](uploads/b967e6b37d1409105e910ea43c786ca3/Screenshot_2024-05-15_15-57-31.png)
</details>
**Données à extraire :**
- [ ] Contenu du cours (texte/HTML) -> élément `<div id="STY_zoneCours">`
- [ ] Contenu du cours (texte/HTML) -\> élément `<div id="STY_zoneCours">`
### ExerciceQC
*(Question Choix?)*
Une question avec plusieurs réponses prédéfinies. Existe en variante QCU (une seule bonne réponse) et QCM (plusieurs bonnes réponses).
_(Question Choix?)_\
Une question avec plusieurs réponses prédéfinies. Existe en variante QCU (une seule bonne réponse) et QCM (plusieurs bonnes réponses).\
**Quantité :** 39 QCU, 9 QCM
<details><summary>Exemples</summary>
**Exemple QCU** : `pg381.html`, la première page de *"> Reconnaître les auxiliaires"*
<details>
<summary>Exemples</summary>
**Exemple QCU** : `pg381.html`, la première page de _"\> Reconnaître les auxiliaires"_\
![Screenshot_2024-05-15_14-59-01](uploads/bb4795264824c0140f49bb7a2126d5d2/Screenshot_2024-05-15_14-59-01.png)
**Exemple QCM** : `pg8412.html`, page *"Vérifier la place de l'accent primaire (3)"* dans la sous-partie *"> Utiliser les marques de l'accentuation"*
**Exemple QCM** : `pg8412.html`, page _"Vérifier la place de l'accent primaire (3)"_ dans la sous-partie _"\> Utiliser les marques de l'accentuation"_
Il s'avère que les 9 exercices QCM sont tous dans la même sous-partie, et sont utilisés sémantiquement comme plusieurs QCU :
![Screenshot_2024-05-15_15-22-19](uploads/4be84e866d324dc5205bd1aa0fb808f3/Screenshot_2024-05-15_15-22-19.png)
Il s'avère que les 9 exercices QCM sont tous dans la même sous-partie, et sont utilisés sémantiquement comme plusieurs QCU : ![Screenshot_2024-05-15_15-22-19](uploads/4be84e866d324dc5205bd1aa0fb808f3/Screenshot_2024-05-15_15-22-19.png)\
Dans cet exemple, on a 3 mots ayant chacun 3 réponses possibles dont 1 bonne, mais l'exercice est implémenté comme un QCM de 9 choix possibles ; on peut tout à fait cocher les 3 choix pour "narrator".
</details>
**Données à extraire :**
- [ ] Consigne -> `<div id="STY_question">`
- [ ] Choix de réponses
- [x] Correction -> dans la fonction `entrerDonnees()`, `exo.tabStylesR[nr] = CODE_V` ou `CODE_F` pour chaque valeur de `nr`
- [x] Commentaires de succès et d'échec -> `divCmtSucces` et `divCmtSugg#` *(cf. commentaires d'activité)*
- [ ] Consigne -\> `<div id="STY_question">`
- [ ] Choix de réponses
- [x] Correction -\> dans la fonction `entrerDonnees()`, `exo.tabStylesR[nr] = CODE_V` ou `CODE_F` pour chaque valeur de `nr`
- [x] Commentaires de succès et d'échec -\> `divCmtSucces` et `divCmtSugg#` _(cf. commentaires d'activité)_
### ExerciceQM
*(Question Multiple?)*
Comme ExerciceQC mais avec plusieurs questions, chacune ayant une seule bonne réponse.
_(Question Multiple?)_\
Comme ExerciceQC mais avec plusieurs questions, chacune ayant une seule bonne réponse.\
**Quantité :** 8
<details><summary>Exemple</summary>
<details>
<summary>Exemple</summary>
`pg262.html`, la toute première page de Macao 1
`pg262.html`, la toute première page de Macao 1\
![Screenshot_2024-05-15_14-56-47](uploads/59667940add90fb4f94f55cdb370be6b/Screenshot_2024-05-15_14-56-47.png)
</details>
**Données à extraire :**
- [ ] Consigne -> `<div id="STY_question">`
- [ ] Choix de réponses -> tableau dans `<div id="STY_texteQM">`, chaque ligne (`<tr>`) est une question, chaque cellule de colonne (`<td>`) est une case à cocher. Son `id` indique aussi ses coordonnées (ex: `id="lienRepImg13"` = ligne 1 choix 3)
- [ ] Correction -> dans la fonction `entrerDonnees()`, `exo.tabStylesR[nr] = '3'` indiquent le numéro du choix correct pour chaque numéro de ligne `nr`
- [x] Commentaires de succès et d'échec -> `divCmtSucces` et `divCmtSugg#` *(cf. commentaires d'activité)*
- [ ] Consigne -\> `<div id="STY_question">`
- [ ] Choix de réponses -\> tableau dans `<div id="STY_texteQM">`, chaque ligne (`<tr>`) est une question, chaque cellule de colonne (`<td>`) est une case à cocher. Son `id` indique aussi ses coordonnées (ex: `id="lienRepImg13"` = ligne 1 choix 3)
- [ ] Correction -\> dans la fonction `entrerDonnees()`, `exo.tabStylesR[nr] = '3'` indiquent le numéro du choix correct pour chaque numéro de ligne `nr`
- [x] Commentaires de succès et d'échec -\> `divCmtSucces` et `divCmtSugg#` _(cf. commentaires d'activité)_
### ExerciceTAT
Un texte à trous, avec pour chaque "trou" une liste déroulante de choix de mots.
Un texte à trous, avec pour chaque "trou" une liste déroulante de choix de mots.\
**Quantité :** 12
<details><summary>Exemple</summary>
<details>
<summary>Exemple</summary>
`pg20.html`, page _"Ecoutez et complétez (2)"_ dans la sous-partie _"> Reconnaître les déterminants"_
`pg20.html`, page _"Ecoutez et complétez (2)"_ dans la sous-partie _"\> Reconnaître les déterminants"_\
![Screenshot_2024-05-15_15-40-29](uploads/23944659726f54961ea79cb4e87d2772/Screenshot_2024-05-15_15-40-29.png)
</details>
**Données à extraire :**
- [ ] Consigne -> `<div id="STY_question">`
- [ ] Texte avec position des "trous" -> contenu dans `<div id="STY_texteTAT">`.
- [ ] Consigne -\> `<div id="STY_question">`
- [ ] Texte avec position des "trous" -\> contenu dans `<div id="STY_texteTAT">`.\
Chaque trou est un élément `<select class="STY_selectTAT" id="champTrou#">` et son numéro est indiqué dans l'`id`.
- [ ] Choix pour chaque trou et correction -> appels `exo.ajouterReponse(index, correction, valeur)`.
- [ ] Choix pour chaque trou et correction -\> appels `exo.ajouterReponse(index, correction, valeur)`.\
Paramètre "correction" = `ng` pour faux, `nw` pour juste.
- [x] Commentaires de succès et d'échec -> `divCmtSucces` et `divCmtSugg#` *(cf. commentaires d'activité)*
- [x] Commentaires de succès et d'échec -\> `divCmtSucces` et `divCmtSugg#` _(cf. commentaires d'activité)_
### ExerciceGD
*(Glisser-Déposer ?)*
Le plus complexe, avec des objets à glisser et placer librement ou dans des cases.
_(Glisser-Déposer ?)_\
Le plus complexe, avec des objets à glisser et placer librement ou dans des cases.\
**Quantité :** 5
<details><summary>Exemple</summary>
<details>
<summary>Exemple</summary>
`pg545.html`, page _"Compléter une transcription (1)"_ dans _"> Utiliser les symboles phonétiques"_
`pg545.html`, page _"Compléter une transcription (1)"_ dans _"\> Utiliser les symboles phonétiques"_\
![Screenshot_2024-05-15_15-51-35](uploads/4c4963cf1ea6c82296d9f2022b9a712a/Screenshot_2024-05-15_15-51-35.png)
</details>
**Données à extraire :**
- [ ] Consigne -> `<div id="STY_question">`
- [ ] Éléments à déplacer -> éléments `<div id="exoGDd#">` (le `d` est pour *déplaçable*, et est suivi de son numéro/ID)
- [ ] Cibles de déplacement -> éléments `<div id="exoGDc#">` (le `c` est pour *cible*, suivi aussi de son numéro/ID)
- [ ] Correction -> liste de `new PaireGD(deplacable, cible, correct, decalageX, decalageY)` indiquent pour chaque déplaçable sa cible associée et si il est juste (`ng` = faux, `nw` = juste).
- [ ] Positions de tous les éléments -> offsets CSS `absolute`, sûrement à refaire manuellement.
- [x] Commentaires de succès et d'échec -> `divCmtSucces` et `divCmtSugg#` *(cf. commentaires d'activité)*
- [ ] Consigne -\> `<div id="STY_question">`
- [ ] Éléments à déplacer -\> éléments `<div id="exoGDd#">` (le `d` est pour _déplaçable_, et est suivi de son numéro/ID)
- [ ] Cibles de déplacement -\> éléments `<div id="exoGDc#">` (le `c` est pour _cible_, suivi aussi de son numéro/ID)
- [ ] Correction -\> liste de `new PaireGD(deplacable, cible, correct, decalageX, decalageY)` indiquent pour chaque déplaçable sa cible associée et si il est juste (`ng` = faux, `nw` = juste).
- [ ] Positions de tous les éléments -\> offsets CSS `absolute`, sûrement à refaire manuellement.
- [x] Commentaires de succès et d'échec -\> `divCmtSucces` et `divCmtSugg#` _(cf. commentaires d'activité)_
### Inutilisés
ExerciceCURS, ExerciceEXP, ExerciceSEQ
ExerciceCURS, ExerciceEXP, ExerciceSEQ
---
----
## Pages d'aide ou "docs"
Dans `contenu/pages/`, les fichiers `*.htm` et `pgd###.html` sont des pages d'aide. Au lieu d'être chargées dans la section centrale, elles peuvent être ouvertes dans une nouvelle fenêtre pop-up avec la fonction `SCO_ouvrirDoc()`, souvent appelée depuis un lien `<a>` dans les pages classiques.
```html
cliquez pour voir la définition d'un <a href="javascript:parent.SCO_ouvrirDoc('pgd171','PAGE')">phonème</a>
```
Ces pages peuvent inclure des objets Flash comme les autres, mais pas d'exercice.
## Contenus des pages
### Commentaires
Certains exercices ont des commentaires, des blocs HTML structurés chargés dans une `<div id="zoneInvisible">`, qui sont déplacés dans la `<div id="STY_zoneCommentaire">` à droite en réponse à certaines actions.
- Commentaire de succès : `<div id="divCmtSucces">`
- Commentaire d'échec : `<div id="divSugg#">`, numérotés à partir de 1
- Autres commentaires : `<div id="divCmt#">`, numérotés à partir de 1, contiennent un petit texte d'aide.
......@@ -209,22 +244,28 @@ Certains exercices ont des commentaires, des blocs HTML structurés chargés dan
:warning: Les commentaires **peuvent contenir de la mise en forme et des objets Flash** (peut-être même des images ?)
### Images
Les images intégrées dans le contenu d'une page sont reconnaissables par un `id="MosImg###`, à la différence de celles utilisées pour l'UI (boutons). Leur chemin est toujours dans `contenu/media/`.
```html
<img id="MosImg17" src="../media/phon_recognition_54_juste.png">
```
### Objets Flash et audio
TODO
----
---
# Dans Macao 3
## Modules / Parties
Idem que Macao12 avec `imsmanifest.xml`, mais le nommage devient `seq######`
## Sous-parties
Idem que Macao12, mais le nommage devient `act######`. De même, le fichier `sco/MosEtp###.html` devient `sco/act######.html`.
Idem que Macao12, mais le nommage devient `act######`. De même, le fichier `sco/MosEtp###.html` devient `sco/act######.html`.\
Des fichiers XML `sco/md_act######.xml` font leur apparition pour chaque sous-partie, mais contiennent des métadonnées pour SCORM qui ne nous intéressent pas.
À la fin du `imsmanifest.xml`, un tag `<resource ... identifier="rsrcact######" ...>` décrit les dépendances de la sous-partie, sous la forme d'une liste de fichiers : pages `pg###.html`, images, SWFs... Potentiellement utile, ou bien redondant si on les retrouve dans le contenu HTML des pages.
......@@ -234,9 +275,11 @@ Même format pour le contenu (JavaScript) de la sous-partie, avec `new MosSCO(..
## Activités
Mêmes types d'activités :
```sh
grep -rE --only-matching --no-filename 'new (Cours|Exercice).+;' macao_3/contenu/pages | sort | uniq
```
```
new Cours();
new ExerciceGD();
......@@ -247,17 +290,58 @@ new ExerciceTAT();
```
### ExerciceTAT
Changements dans le format des réponses, toutes les réponses sont maintenant obfusquées :
Le texte à trous existe maintenant en variante "sélection" (menu déroulant) et "libre" (champ texte), tous les deux des `new ExerciceTAT()`. La différence semble se remarquer avec des lignes de la forme
```js
exo.ajouterReponse('rep117', '1', '3', "k aKDKjNkg'o");
exo.ajouterReponse('rep577', '1', '3', "ok aKDKjNkgNB");
exo.ajouterReponse('rep982', '1', '3', "ok aKDKjNkg '");
exo.ajouterReponse('rep749', '1', '3', "Bok aKDKjNkg N");
exo.tabSelects[exo.tabSelects.length] = '1';
```
qui définissent quels champs sont des sélecteurs (exemple: comparer `pg4487.html` et `pg1919.html`).
Autre changement, le format des réponses. Tous les libellés sont maintenant obfusqués :
```js
exo.ajouterReponse('rep859', '1', '2', "D8ke8k VOX");
exo.ajouterReponse('rep482', '1', '3', "D8ke8k qOX");
exo.ajouterReponse('rep306', '2', '5', "D8ke8k VOX");
exo.ajouterReponse('rep40', '2', '4', "D8ke8k qOX");
```
Heureusement la fonction de décodage `decodeX()` est statique (clé fixe, ne dépend pas d'autres attributs de l'activité) : [source](https://gitlab.tetras-libre.fr/macao/macao-legacy/blob/main/Basilisk/MACAO/macao_3/MosMtr/scripts/contenu/ClasseExerciceTAT.js#L774)
Autre différence, le texte à trous existe en variante "sélection" (menu déroulant) et "libre" (champ texte), tous les deux des `new ExerciceTAT()`. La différence semble se remarquer avec des lignes de la forme
Le 2e paramètre indique à quel champ appartient la réponse. Le troisième indique la correction, mais ce n'est plus simplement `"ng"` pour faux ou `nw` pour juste, mais une valeur numérique. La logique se passe dans la fonction `exo_ajouterReponse(...)` ([source](https://gitlab.tetras-libre.fr/macao/macao-legacy/blob/main/Basilisk/MACAO/macao_3/MosMtr/scripts/contenu/ClasseExerciceTAT.js#L75))
```js
exo.tabSelects[exo.tabSelects.length] = '1';
function exo_ajouterReponse(lid, num, correction, txt) {
var res = decodeX(txt); // décodage du libellé
// On a un "decalY" qui est la parité (modulo 2) du nombre de trous + le score total
var decalY = (this.tabChamps.length + this.scoreTotal) % 2;
// On calcule un "reste" à partir du numéro de question et de la valeur de "correction"
var reste = correction - num * 2 - 1;
// On décrémente le "reste" si decalY vaut 1
// or decalY vaut 0 ou 1, donc ça revient à `reste = reste - decalY`
if (decalY == 1) {
reste--;
}
// La réponse est correcte (CODE_V) si le reste vaut -1
if (reste == -1) {
correction = CODE_V;
} else {
correction = CODE_F;
}
this.tabReponses[this.tabReponses.length] = new ChampTrou(lid, num, res, correction);
}
```
qui définissent quels champs sont des sélecteurs (exemple: comparer `pg4487.html` et `pg1919.html`).
\ No newline at end of file
La réponse ajoutée est correcte si le `reste` vaut -1.
```
reste == -1
correction - 2*num - decalY - 1 == -1
correction - 2*num - decalY == 0
correction == 2*num + decalY
correction == 2*num + (nChamps + scoreTotal) % 2
```
On a donc besoin d'extraire en plus le nombre de champs et le `scoreTotal` pour déterminer si chaque réponse est vraie ou fausse.
\ No newline at end of file