Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • macao/macao-hugo
  • dbeniamine/macao-hugo
2 results
Select Git revision
Loading items
Show changes
Commits on Source (122)
Showing
with 1749 additions and 152 deletions
# From template at https://gitlab.com/pages/hugo # From template at https://gitlab.com/pages/hugo
# Runner configuration
default: default:
# The `hugo_extended` image is required because our theme needs SCSS compilation
# (see https://gohugo.io/installation/linux/#editions)
# The image is pinned to an explicit version number to avoid bugs introduced
# by an automatic upgrade
image: "${CI_TEMPLATE_REGISTRY_HOST}/pages/hugo/hugo_extended:0.128.1" image: "${CI_TEMPLATE_REGISTRY_HOST}/pages/hugo/hugo_extended:0.128.1"
variables: variables:
GIT_SUBMODULE_STRATEGY: recursive # include Hugo themes GIT_SUBMODULE_STRATEGY: recursive # include Hugo themes
GIT_SUBMODULE_FORCE_HTTPS: "true" GIT_SUBMODULE_FORCE_HTTPS: true # the GitLab runner doesn't have SSH to clone
HUGO_ENV: production HUGO_ENV: production
# Jobs configuration
# In this project, the Hugo directory (with `hugo.toml`, `content/` etc...) is
# not the Git root dir, but a subfolder `macao`. This requires a bit of extra
# config for some jobs.
test: test:
# The `test` job just tries to build the site, runs on all branches except
# the default
script: script:
- cd macao - cd macao # move to the hugo dir
- hugo - hugo
rules: rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
pages: pages:
# The `pages` job builds the site to the `public` dir for Pages to publish,
# runs only on the default branch
script: script:
- cd macao - cd macao
- hugo - hugo
# Declare an artifact, the job's output
artifacts: artifacts:
paths: paths:
- macao/public - macao/public
# Config for Pages: directory to serve (default is 'public')
publish: macao/public publish: macao/public
rules: rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
......
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
.idea
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/macao-hugo.iml" filepath="$PROJECT_DIR$/.idea/macao-hugo.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/macao/themes/macao-hugo-theme" vcs="Git" />
</component>
</project>
\ No newline at end of file
This diff is collapsed.
# Macao-Hugo # Macao-Hugo
Expérimentation avec le *static site generator* [Hugo](https://gohugo.io/) pour Macao-New
# Setup Portage de l'application MACAO (Module d'Aide à la Compréhension de l'Anglais Oral), basé sur le générateur de site statique [Hugo](https://gohugo.io/) et la bibliothèque [SurveyJS](https://surveyjs.io/form-library/documentation/overview)
[![License: GPLv3](https://img.shields.io/badge/License-GPLv3-blue.svg)](LICENSE)
# Démo. avec Gitlab Pages
https://macao.pages.tetras-libre.fr/macao-hugo/
# Installation pour le développent
- [Installer Hugo](https://gohugo.io/installation/) **(version 0.124 minimum)** - [Installer Hugo](https://gohugo.io/installation/) **(version 0.124 minimum)**
- `git clone gitlab@gitlab.tetras-libre.fr:macao/macao-hugo.git` - `git clone --recurse-submodules gitlab@gitlab.tetras-libre.fr:macao/macao-hugo.git`
- `cd macao-hugo/macao` - `cd macao-hugo/macao`
Pour lancer en mode développement avec live reload : `hugo server` Pour lancer en mode développement avec live reload : `hugo server`
Pour build le site statique : `hugo` Pour build le site statique : `hugo`
Le contenu de `public/` peut être publié avec n'importe quel serveur HTTP statique. Le contenu de `public/` peut être publié avec n'importe quel serveur HTTP statique.
# Licences
Ce projet, à l'exception des répertoires `macao/content` et `static/media`, est distribué sous licence [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.html), dont les termes sont décrits dans le fichier [`LICENSE`](./LICENSE).
Le contenu des répertoires `macao/content` et `static/media` utilise une licence séparée, décrite dans le fichier [`macao/content/LICENSE.md`](./macao/content/LICENSE.md)
\ No newline at end of file
public/ public/
resources/_gen/ resources/_gen/
.hugo_build.lock .hugo_build.lock
/content/tests/
.idea
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
#correct-indic { body {
border-radius: 8px; // Global theme colors are defined in macao/themes/macao-hugo-theme/assets/_defaults.scss and go to @mixin theme-tetras
padding: 16px; --quizz-backgourd-color: #00000;
transition: opacity 0.1s ease-in-out; --feedback-sucess-color: #FFF2CC;
--feedback-error-color: #FFF2CC;
}
&.hidden { // ***********************************
display: block; // Global
opacity: 0; // ***********************************
* {
line-height: 1.2 !important
} }
p { img.inlineImage {
margin: 0; vertical-align: middle;
height: 1em;
} }
.label { img.inlineImage12 {
font-weight: bold; vertical-align: middle;
height: 1.2em;
} }
&.correct { img.inlineImage14 {
background: #dfd; vertical-align: middle;
height: 1.4em;
}
.label { img.inlineImage16 {
color: var(--sd-rating-good-color); vertical-align: middle;
height: 1.6em;
} }
img.inlineImage18 {
vertical-align: middle;
height: 1.8em;
} }
&.incorrect { img.inlineImage2 {
background: #fdd; vertical-align: middle;
height: 2em;
} }
.label { img.inlineImage22 {
color: var(--sd-rating-bad-color); vertical-align: middle;
height: 2.2em;
} }
img.inlineImage24 {
vertical-align: middle;
height: 2.4em;
} }
#sv-nav-complete { img.inlineImage26 {
display: none; vertical-align: middle;
height: 2.6em;
}
img.inlineImage28 {
vertical-align: middle;
height: 2.8em;
}
img.inlineImage3 {
vertical-align: middle;
height: 3em;
}
.btn-play {
cursor: pointer;
background-color: var(--macao-primary-color);
border-radius: 5px;
border: none;
padding: 5px 10px;
color: white;
}
.notextplay {
font-size: 0; /* hides text */
color: white;
}
.notextplay i {
font-size: medium; /* keep icon visible */
} }
p#gapfill-container { p#gapfill-container {
...@@ -42,8 +91,152 @@ p#gapfill-container { ...@@ -42,8 +91,152 @@ p#gapfill-container {
line-height: 3em; line-height: 3em;
} }
select.sd-dropdown.inline-dropdown { // Tweak the existing SurveyJS styles to have "inline" dropdown menus
// and text fields that don't take too much space
select.sd-dropdown.inline-dropdown, input.sd-input.inline-input {
display: inline-block; display: inline-block;
width: fit-content; width: fit-content;
padding: 8px; padding: 8px;
} }
// ***********************************
// User Feedback in quizz
// ***********************************
#correct-indic.incorrect {
background-color: var(--feedback-error-color);
}
#correct-indic.correct {
background-color: var(--feedback-sucess-color);
}
#correct-indic {
border-radius: 8px;
padding: 16px;
p {
margin: 0;
}
}
// ***********************************
// Hide disabled checkboxes in some quizz
// ***********************************
.hide-disabled-checkboxes {
.sd-checkbox--readonly {
span.sd-checkbox__decorator {
display: none;
}
}
}
// ***********************************
// Align one line radio buttons
// ***********************************
.one-line {
display: flex;
align-items: center;
.sd-question__header {
margin-top: 0;
max-width: 150px;
}
}
// ***********************************
// General look and feel
// ***********************************
.book-page > article {
background-color: var(--secondary-background-color);
border-radius: 15px;
}
.book-page > article {
padding: 16px;
margin-top: 16px;
}
.book-search {
border-radius: 10px;
padding: 0px 5px;
background-color: var(--secondary-background-color);
}
a {
color: var(--macao-primary-color);
}
a:visited {
color: var(--macao-primary-color) !important;
}
a.active {
color: var(--macao-secondary-font-color) !important;
background-color: var(--macao-primary-color);
border-radius: 5px;
padding: 5px;
margin-right: 5px;
}
// Hide element when width is less than 900px
@media (min-width: 900px) {
.book-icon {
display: none;
}
}
.sd-btn {
padding: 5px 10px !important;
}
// ***********************************
// Comment on page
// ***********************************
.comment-trigger {
cursor: pointer;
color: var(--macao-primary-color);
text-decoration: underline;
}
em:not(:has(strong)) {
background-color: lightgray;
padding: 3px;
padding-right: 4px;
border-radius: 5px;
}
// ***********************************
// Dropdowns
// ***********************************
// Min width for dropdowns
.sv-dropdown_select-wrapper {
min-width: 150px !important;
}
// ***********************************
// .sv-title-actions__title
// ***********************************
.sv-title-actions__title {
white-space: break-spaces !important;
}
.one-line {
.sd-question__header {
max-width: 60%;
}
.sv-string-viewer {
display: inline-flex;
align-items: center;
gap: 5px;
max-width: 100%;
flex-wrap: wrap;
}
}
@import "plugins/_scrollbars.scss";
console.log('Custom JS loaded');
$(document).ready(function() {
console.log('Custom JS executed');
// Add specific classes to play buttons
$('button:contains("Play")').html('<i class="fa-solid fa-play"></i> Écouter').addClass('btn-play').prop('title','Écouter');
// Add Title on top of the page
$('.book-header').show();
$('.commentaireInfo').hide();
// $('.commentaireInfo').prop('popover', 'auto');
$('.commentaireInfoGroup').show();
// Comment popover
$('[spanid]').addClass('comment-trigger').each(function (){
const spanid = $(this).attr('spanid');
if($("[commentaireid=" + spanid + "]").length !== 0) {
$(this).popover({
trigger: 'click',
html: true,
placement: 'auto',
content: $("[commentaireid=" + spanid + "]")
});
$("[commentaireid=" + spanid + "]").toggle()
}
});
// $(document).on('click', function() {
// $('[spanid]').popover('hide');
// });
// Simplify th in td
$('th').each(function () {
// Store the current content of the <th>
const content = $(this).html();
// Replace <th> with a <td> containing the same content
$(this).replaceWith(`<td>${content}</td>`);
});
// Tricky way to add gap between play button and the next element
// like http://localhost:1313/macao-hugo/activities/mosorgmacao_fusion_ss_barre/mosmod10/mosmod11/mosetp129/pg334/
$(".btn-play").parent().siblings().css("margin-top", "10px")
if ($(window).width() > 900) {
$('.book-icon').hide();
}
});
/**
* Custom SurveyJS question type for a "fill-in-the-gaps" text,
* with an open-ended text input for each gap
*/
export const gapfillOpenWidget = {
name: "gapfill-open",
title: "Gap-Fill Text (Open)",
/**
* This function should return true when the widget and all needed resources
* are loaded
*/
widgetIsLoaded: function () {
return true;
},
/**
* This function should return true if the widget should be applied to the question */
isFit: function (question) {
return question.getType() === this.name;
},
init() {
//Register a new type using the empty question as the base.
Survey.Serializer.addClass(this.name, [], null, "empty");
},
/** Static HTML template rendered by SurveyJS */
htmlTemplate: '<p id="gapfill-container"><template id="template-gap"><input type="text" class="sd-input inline-input"/></template></p>',
/**
* Function called after the HTML template is rendered. This time we actually have the `question` object
* and the `el` element, to build the question according to the JSON
*/
afterRender: function (question, el) {
// The gap-fill text is made of segments, which are either plain pieces
// of text (strings) or "gaps" (objects).
// We append these to build the text, turning strings into <span>s and
// gaps into <input> text fields
let nbGaps = 0;
const segmentElems = new DocumentFragment(); // a bit faster than mutating the DOM all the time
const gapTemplate = document.getElementById("template-gap").content.firstChild;
for (const segment of question.jsonObj.segments) {
let segmentElem;
if (typeof segment === 'string' || segment instanceof String) {
segmentElem = document.createElement("span");
segmentElem.innerText = segment;
} else {
// It's a gap
// Create the <input> element
segmentElem = gapTemplate.cloneNode(true);
// Add the size attribute if present
if (segment.hasOwnProperty("size")) {
segmentElem.setAttribute("size", segment.size);
}
segmentElem.setAttribute("data-index", nbGaps); // The node knows its index
// Add callback to update the question's value when the input value changes
segmentElem.addEventListener("change", (e) => {
// The input node knows its index, therefore is able to update the question value at the correct index
question.value[parseInt(e.target.getAttribute("data-index"))] = e.target.value;
});
// Add callback to update the DOM nodes when the question's value changes
question.valueChangedCallback = () => {
const gaps = question.wrapperElement.querySelectorAll("#gapfill-container input");
if (question.value instanceof Array && question.value.length === gaps.length) {
for (const i in question.value) {
gaps[i].value = question.value[i];
}
} else {
// Unknown value -> reset all fields
for (const gap of gaps) {
gap.value = "";
}
}
}
nbGaps++;
}
// Add segment
segmentElems.appendChild(segmentElem);
}
// Initialize question value array
question.value = new Array(nbGaps);
// Finally add everything to the DOM
el.appendChild(segmentElems);
},
};
\ No newline at end of file
...@@ -51,11 +51,25 @@ export const gapfillSelectWidget = { ...@@ -51,11 +51,25 @@ export const gapfillSelectWidget = {
optionElem.innerText = opt; optionElem.innerText = opt;
segmentElem.appendChild(optionElem); segmentElem.appendChild(optionElem);
} }
// Add listener to update the question's value when the selector's value changes // Add callback to update the question's value when the selector's value changes
segmentElem.addEventListener("change", (e) => { segmentElem.addEventListener("change", (e) => {
// The select node knows its index, therefore is able to update the question value at the correct index // The select node knows its index, therefore is able to update the question value at the correct index
question.value[parseInt(e.target.getAttribute("data-index"))] = e.target.value; question.value[parseInt(e.target.getAttribute("data-index"))] = e.target.value;
}); });
// Add callback to update the DOM nodes when the question's value changes
question.valueChangedCallback = () => {
const gaps = question.wrapperElement.querySelectorAll("#gapfill-container select");
if (question.value instanceof Array && question.value.length === gaps.length) {
for (const i in question.value) {
gaps[i].value = question.value[i];
}
} else {
// Unknown value -> reset all fields
for (const gap of gaps) {
gap.value = undefined;
}
}
}
nbGaps++; nbGaps++;
} }
// Add segment // Add segment
......
/** /**
* Checks whether a question is correct, and update the correct indicator accordingly. * Checks whether all questions are correctly answered and displays the overall feedback.
*/ */
function checkQuestion(question) { function checkAllQuestions(questions, surveyConfig, converter) {
if (question.isAnswerCorrect()) { let allCorrect = true;
correctIndic.node.className = "correct" questions.forEach((question) => {
correctIndic.labelNode.innerText = "Correct"; if (!question.isAnswerCorrect()) {
// FIXME: this inserts raw HTML (see onTextMarkdown callback) allCorrect = false;
correctIndic.commentNode.innerHTML = question.getPropertyValue("correctComment", ""); }
});
if (allCorrect) {
correctIndic.node.className = "correct";
surveyConfig.correctComment = surveyConfig.correctComment.replace(/\n\n/g, "<br>");
correctIndic.commentNode.innerHTML = converter.renderInline(surveyConfig.correctComment) || "All answers are correct!";
} else { } else {
correctIndic.node.className = "incorrect"; correctIndic.node.className = "incorrect";
correctIndic.labelNode.innerText = "Incorrect"; surveyConfig.incorrectComment = surveyConfig.incorrectComment.replace(/\n\n/g, "<br>");
correctIndic.commentNode.innerHTML = question.getPropertyValue("incorrectComment", ""); correctIndic.commentNode.innerHTML = converter.renderInline(surveyConfig.incorrectComment) || "Some answers are incorrect!";
} }
console.log("question = ", question);
console.log(" correct = ", question.isAnswerCorrect());
} }
function clearQuestion(question) { /**
* Clears all answers and resets the feedback indicator.
*/
function clearAllQuestions(questions) {
questions.forEach((question) => {
question.value = undefined; question.value = undefined;
});
correctIndic.node.className = "hidden"; correctIndic.node.className = "hidden";
correctIndic.commentNode.innerHTML = "";
}
/**
* Toggles the visibility of the help comment for a question.
*/
function toggleHelpComment(question, htmlElement) {
const helpCommentElement = htmlElement.querySelector('.help-comment');
if (helpCommentElement) {
// If help comment is already shown, remove it
helpCommentElement.remove();
} else {
// Otherwise, create and show the help comment
const newHelpCommentElement = document.createElement('div');
newHelpCommentElement.className = 'help-comment';
newHelpCommentElement.innerHTML = question.helpComment;
htmlElement.appendChild(newHelpCommentElement);
}
} }
let correctIndic; let correctIndic;
// The following allows to define complementary attributes in survey JSONS
$(function () { $(function () {
correctIndic = { correctIndic = {
node: document.getElementById("correct-indic"), node: document.getElementById("correct-indic"),
commentNode: document.querySelector("#correct-indic .comment"), commentNode: document.querySelector("#correct-indic .comment"),
labelNode: document.querySelector("#correct-indic .label")
}; };
// Register our custom question types Survey.JsonObject.metaData.addProperty("question", {
Survey.CustomWidgetCollection.Instance.add(gapfillSelectWidget, gapfillSelectWidget.name); name: "customFormat",
type: "text",
category: "general",
default: "",
visibleIndex: 0,
});
// Register custom properties for quiz correction comments Survey.JsonObject.metaData.addProperty("survey", {
Survey.Serializer.addProperty("question", { name: "isSurveySummaryVisible",
name: "correctComment", type: "boolean",
type: "text" category: "general",
default: "false",
visibleIndex: 0,
}); });
Survey.Serializer.addProperty("question", {
name: "incorrectComment",
type: "text" Survey.JsonObject.metaData.addProperty("question", {
name: "helpComment",
type: "text",
category: "general",
default: "",
visibleIndex: 0,
});
Survey.JsonObject.metaData.addProperty("question", {
name: "compComment",
type: "text",
category: "general",
default: "",
visibleIndex: 0,
}); });
Survey.JsonObject.metaData.addProperty("question", {
name: "transcript",
type: "text",
category: "general",
default: "",
visibleIndex: 0,
});
// Load survey model from JSON // Load survey model from JSON
const survey = new Survey.Model(jsonStatic); const survey = new Survey.Model(jsonStatic);
const questions = survey.getAllQuestions();
if (questions.length === 1) {
console.log("Survey has only one question");
console.log(questions[0]);
const regex = /pg\d\d\d/g;
if (questions[0].title.match(regex)) {
questions[0].titleLocation = "hidden";
}
}
// Instantiate `markdown-it`
const converter = markdownit({
html: true // Support HTML tags in the source (unsafe, see documentation)
});
survey.onTextMarkdown.add((_, options) => {
let str = converter.renderInline(options.text);
options.html = str;
});
survey.onAfterRenderQuestion.add((survey, options) => {
if (options.question.customFormat) {
if (options.question.customFormat === "one_line") {
$(options.htmlElement).addClass("one-line");
}
if (options.question.customFormat === "hide_disabled-checkboxes") {
$(options.htmlElement).addClass("hide-disabled-checkboxes");
}
}
// Display compComment if present
if (options.question.compComment) {
const compCommentElement = document.createElement('div');
compCommentElement.className = 'comp-comment';
compCommentElement.innerHTML = options.question.compComment;
options.htmlElement.appendChild(compCommentElement);
}
// Add "Corrigé" button if helpComment is present
if (options.question.helpComment) {
const helpButton = document.createElement('button');
helpButton.innerHTML = 'Corrigé';
helpButton.className = 'sd-btn sd-btn--action nav-input';
helpButton.onclick = () => toggleHelpComment(options.question, options.htmlElement);
options.htmlElement.appendChild(helpButton);
}
if( options.question.getType() === "dropdown" ) {
// Very ugly fix to avoid sliding dropdown on focus
$('.book-article').css({
'will-change' : 'unset',
'transition': 'none',
});
$('.book-page').css({
'will-change' : 'unset',
'transition': 'none',
});
}
});
// Add "Check answers" button // Add "Check answers" button
survey.addNavigationItem({ survey.addNavigationItem({
id: "sv-nav-check", id: "sv-nav-check",
title: "Vérifier", title: "Vérifier",
action: () => { action: () => {
checkQuestion(survey.currentPage.questions[0]); checkAllQuestions(survey.currentPage.questions, jsonStatic, converter);
}, },
css: "nav-button", css: "nav-button",
innerCss: "sd-btn sd-btn--action nav-input" innerCss: "sd-btn sd-btn--action nav-input"
}); });
// Add "Clear answers" button // Add "Clear answers" button
survey.addNavigationItem({ survey.addNavigationItem({
id: "sv-nav-clear", id: "sv-nav-clear",
title: "Effacer", title: "Effacer",
action: () => { action: () => {
clearQuestion(survey.currentPage.questions[0]); clearAllQuestions(survey.currentPage.questions);
}, },
css: "nav-button", css: "nav-button",
innerCss: "sd-btn nav-input" innerCss: "sd-btn nav-input"
}); });
survey.onTextMarkdown.add((survey, options) => { survey.onComplete.add(function (sender) {
// FIXME: this inserts raw HTML from the text, to remove as soon as Macao-Legacy converter if (sender.isSurveySummaryVisible) {
// can actually produce Markdown console.log("Survey summary is visible");
options.html = options.text; const userData = sender.data;
const summaryDiv = document.createElement("div");
summaryDiv.id = "surveySummary";
let html = "<h3>Your Results:</h3><ul>";
sender.getAllQuestions().forEach(q => {
const userAnswer = userData[q.name];
const correctAnswer = q.correctAnswer;
const isCorrect = userAnswer === correctAnswer;
html += `<li><b>${q.title}</b><br>
Your answer: ${userAnswer} <br>
Correct answer: ${correctAnswer} <br>
<span style="color:${isCorrect ? 'green' : 'red'};">
${isCorrect ? "Correct" : "Incorrect"}
</span>`;
// Check if the transcript property exists and add an image if it does
if (q.transcript) {
html += `<br><img src="${q.transcript}" alt="Transcript Image" class="inlineImage">`;
}
html += `</li><br>`;
}); });
survey.onValueChanged.add((_, options) => { html += "</ul>";
console.log(options) summaryDiv.innerHTML = html;
// Append the summary after the survey container
document.getElementById("surveyContainer").appendChild(summaryDiv);
}
}); });
// Ugly tricks to avoid creating a new theme
const customTheme = SurveyTheme.DefaultLightPanelless;
const primColor = getComputedStyle(document.documentElement, null).getPropertyValue('--macao-primary-color');
customTheme.cssVariables["--sjs-primary-backcolor"] = primColor;
customTheme.cssVariables["--sjs-primary-backcolor-dark"] = primColor;
// Apply theme // Apply theme
survey.applyTheme(SurveyTheme.DefaultLightPanelless); survey.applyTheme(SurveyTheme.DefaultLightPanelless);
console.log("Survey theme applied", SurveyTheme.DefaultLightPanelless);
survey.showCompleteButton = false;
// Inflate the survey in the page // Inflate the survey in the page
$("#surveyContainer").Survey({ model: survey }); $("#surveyContainer").Survey({ model: survey });
}); });
$(document).ready(function() {
$('button:contains("Play")').html('<i class="fa-solid fa-play"></i> Écouter').addClass('btn-play').prop('title', 'Écouter');
});
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>full</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
</buildSpec>
<natures>
</natures>
</projectDescription>
+++
title = "Compter les syllabes orales (1)"
weight = 50
+++
<div id="STY_question" class="STY_question" style=" "><p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt" align="">
<br>En cliquant sur la flèche combien de <a class="STY_lienComt" href="javascript:CRS_afficherDetail('1')" onclick="enrPosClic(event,'1')">syllabes</a> entendez-vous ? <br>Pour
chaque mot, écouter et sélectionner 1, 2, 3, 4 ou 5 selon le nombre de syllabes entendues. </p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt" align=""> </p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt" align=""> </p>
<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt" align=""> <b>Nombre de syllabes</b></p>
</div><div id="divConsigne" onclick="SPE_clicDansBulle(event,'divConsigne')"></div>
{{< quiz >}}
{
"elements": [
{
,
"correctComment": "<div id=\"divCmtSucces\" onclick=\"SPE_clicDansBulle(event,'divCmtSucces')\"><p align=\"\">Exact !</p></div>\n ",
"incorrectComment": "<div id=\"divSugg1\" onclick=\"SPE_clicDansBulle(event,'divSugg1')\"><p align=\"\"><b>Voici le corrigé :</b><br><br></p>\n <p align=\"\"><br><br><br><br> <br><br><br>comfortable: 3 syllabes.</p>\n <p align=\"\"><br>history: 2 syllabes.</p>\n <p align=\"\"><br>average: 2 syllabes.</p>\n <p align=\"\"><br>interested: 3 syllabes.</p></div>\n "
}
]
}
+++
title = "Mémento : l'accentuation des syllabes (2)"
weight = 130
+++
<div id="STY_texteCours" class="STY_texteCours" style=" "><p align=""><font color="#a60a69"><br>Lorsqu'une <a class="STY_lienComt" href="javascript:CRS_afficherDetail('1')" onclick="enrPosClic(event,'1')">voyelle</a>
est <a class="STY_lienComt" href="javascript:CRS_afficherDetail('2')" onclick="enrPosClic(event,'2')">réduite</a>, la <a class="STY_lienComt" href="javascript:CRS_afficherDetail('3')" onclick="enrPosClic(event,'3')">syllabe</a> qui la
contient s'entend peu. Cela peut créer une difficulté de reconnaissance, surtout si le mot ne comporte que cette
syllabe. <br><br>Cliquer sur la flèche correspondante pour écouter chacun des énoncés et prêtez attention à la
prononciation des mots écrits en italique :</font></p>
<p align=""><font color="#a60a69"><br><br></font></p>
<table class="STY_tableau" width="500" cellpadding="3" cellspacing="0" valign="top" border="0">
<tr>
<td width="20" valign="top">
<script type="text/javascript">ajDocW(PF_clipAV('clipAV92', 'p2611.swf', '80', '40', 'false', 'Flash', 'false', '', 'Quality:high;wmode:transparent', ''));</script>
</td>
<td valign="top"><p align=""><br>You <i>are</i> going <i>to</i> the cinema tonight, aren't you?<br><br>
</p></td>
</tr>
<tr>
<td valign="top">
<script type="text/javascript">ajDocW(PF_clipAV('clipAV69', 'p2621.swf', '80', '40', 'false', 'Flash', 'false', '', 'Quality:high;wmode:transparent', ''));</script>
</td>
<td valign="top"><p align=""><br>My mother <i>is a</i> good cook.<br><br></p></td>
</tr>
<tr>
<td valign="top">
<script type="text/javascript">ajDocW(PF_clipAV('clipAV72', 'p2631.swf', '80', '40', 'false', 'Flash', 'false', '', 'Quality:high;wmode:transparent', ''));</script>
</td>
<td valign="top"><p align=""><br>There are a lot of people <i>in</i> the shops today.<br><br></p></td>
</tr>
<tr>
<td valign="top">
<script type="text/javascript">ajDocW(PF_clipAV('clipAV67', 'p2641.swf', '80', '40', 'false', 'Flash', 'false', '', 'Quality:high;wmode:transparent', ''));</script>
</td>
<td valign="top"><br>As you know, windfalls are apples <i>that</i> fall off <i>the</i> tree on to the
grass.
</td>
</tr>
</table>
<br><br></div>
+++
title = "Remarquer la syllabe la plus accentuée (1)"
weight = 100
+++
<div id="STY_texteCours" class="STY_texteCours" style=" "><br><font color="#a60a69">Le mot suivant contient
2 </font><font color="#a60a69"><a class="STY_lienComt" href="javascript:CRS_afficherDetail('1')" onclick="enrPosClic(event,'1')">syllabes</a></font> <font color="#a60a69">représentées
par 2 carrés. Ecoutez le mot en cliquant sur la flèche et désignez la syllabe qui s'entend le plus en cliquant
sur le carré correspondant. Plusieurs mots (14) vont vous être proposés successivement.<br></font>
<p align=""><b><font color="#a60a69">
<script type="text/javascript">ajDocW(PF_clipAV('clipAV31', 'e29anj_s1lc_remarque_accen1.swf', '367', '267', 'false', 'Flash', 'false', '', 'Quality:high;wmode:transparent;', ''));</script>
</font></b></p>
</div>