Uživatel:KubiV/RandomQuiz: Porovnání verzí
Z WikiSkript
mBez shrnutí editace |
mBez shrnutí editace |
||
Řádek 1: | Řádek 1: | ||
<div id="randomQuizContainer"></div> | <div id="randomQuizContainer"></div> | ||
<script> | |||
$(document).ready(function() { | |||
console.debug("Document ready"); // added debug | |||
function extractQuestions(wikitext) { | |||
const lines = wikitext.split('\n'); | |||
const questions = []; | |||
let i = 0; | |||
while (i < lines.length) { | |||
let line = lines[i].trim(); | |||
if (!line) { | |||
i++; | |||
continue; | |||
} | |||
// Zpracujeme blok otázky začínající '{' | |||
if (line.startsWith('{')) { | |||
let questionLines = []; | |||
while (i < lines.length) { | |||
const currentLine = lines[i].trim(); | |||
questionLines.push(currentLine); | |||
if (currentLine.endsWith('}')) break; | |||
i++; | |||
} | |||
let questionBlock = questionLines.join(' '); | |||
// Odebereme vnější složené závorky | |||
questionBlock = questionBlock.replace(/^\{/, '').replace(/\}$/, '').trim(); | |||
// Zjistíme a odstraníme specifikaci typu | |||
let type = 'checkbox'; | |||
const typeMatch = questionBlock.match(/\|type=[„"]([\[\]\(\)]+)[“"]/); | |||
if (typeMatch) { | |||
type = typeMatch[1] === '[]' ? 'checkbox' : 'radio'; | |||
questionBlock = questionBlock.replace(/\|type=[„"]([\[\]\(\)]+)[“"]/, '').trim(); | |||
} | |||
// Nově odstraníme ' |type=„[]“' nebo ' |type=„()“' pokud je v textu otázky | |||
questionBlock = questionBlock.replace(/\s*\|type=[„"]([\[\]\(\)]+)[“"]/, '').trim(); | |||
// Přidá podmínku, aby text otázky začínal ihned za znakem '{', ale znak '{' se nepřepíše do textu otázky | |||
if (questionBlock.startsWith('{')) { | |||
questionBlock = questionBlock.substring(1).trim(); | |||
} | |||
const currentQuestion = { text: questionBlock, options: [], type: type }; | |||
i++; | |||
// Zpracování následujících řádků jako odpovědí | |||
while (i < lines.length) { | |||
const answerLine = lines[i].trim(); | |||
if (!answerLine) { | |||
i++; | |||
continue; | |||
} | |||
if (answerLine.startsWith('{')) break; | |||
if (answerLine.startsWith('+') || answerLine.startsWith('-')) { | |||
const isCorrect = answerLine.startsWith('+'); | |||
const optionText = answerLine.substring(1).trim(); | |||
currentQuestion.options.push({ text: optionText, correct: isCorrect }); | |||
} else if (answerLine.startsWith('||')) { | |||
if (currentQuestion.options.length > 0) { | |||
currentQuestion.options[currentQuestion.options.length - 1].text += " " + answerLine.substring(2).trim(); | |||
} | |||
} else { | |||
break; | |||
} | |||
i++; | |||
} | |||
if (currentQuestion.options.length > 0) { | |||
questions.push(currentQuestion); | |||
} | |||
} else { | |||
i++; | |||
} | |||
} | |||
return questions; | |||
} | |||
function checkPageForQuiz(pageName) { | |||
return new mw.Api().get({ | |||
action: 'parse', | |||
page: pageName, | |||
prop: 'text', | |||
format: 'json' | |||
}).then(function(result) { | |||
if (!result.parse || !result.parse.text) { | |||
return false; | |||
} | |||
const content = result.parse.text['*']; | |||
return content.includes('<quiz>') || content.includes('class="quiz"'); | |||
}); | |||
} | |||
async function loadRandomQuiz() { | |||
console.debug("loadRandomQuiz called"); // added debug | |||
const data = await $.get('/api.php', { | |||
action: 'query', | |||
list: 'allpages', | |||
apnamespace: 108, | |||
aplimit: 500, | |||
format: 'json' | |||
}); | |||
if (!data.query || !data.query.allpages.length) { | |||
throw new Error('Nenalezeny žádné stránky'); | |||
} | |||
const pages = data.query.allpages.sort(() => Math.random() - 0.5); | |||
for (const page of pages) { | |||
const hasQuiz = await checkPageForQuiz(page.title); | |||
if (hasQuiz) { | |||
return page.title; | |||
} | |||
} | |||
throw new Error('Nenalezena žádná stránka s kvízem'); | |||
} | |||
function loadPageContent(pageName) { | |||
return new mw.Api().get({ | |||
action: 'parse', | |||
page: pageName, | |||
prop: 'wikitext', | |||
format: 'json' | |||
}).then(function(result) { | |||
return { pageName, wikitext: result.parse.wikitext['*'] }; | |||
}); | |||
} | |||
function parseWikitext(wikitext) { | |||
console.debug("parseWikitext called", wikitext); // added debug | |||
return new mw.Api().post({ | |||
action: 'parse', | |||
text: wikitext, | |||
contentmodel: 'wikitext', | |||
prop: 'text', | |||
format: 'json' | |||
}).then(function(result) { | |||
// Trim any surrounding <p> tags | |||
return result.parse.text['*']//.replace(/^<p>|<\/p>$/g, '').trim(); | |||
}); | |||
} | |||
function displayQuiz() { | |||
console.debug("displayQuiz called"); // added debug | |||
var quizContainer = $('#randomQuizContainer'); | |||
quizContainer.html('<p>Načítání kvízu...</p>'); | |||
mw.loader.using(['mediawiki.api', 'ext.quiz']).then(loadRandomQuiz) | |||
.then(loadPageContent) | |||
.then(function({ pageName, wikitext }) { | |||
var questions = extractQuestions(wikitext); | |||
if (questions.length === 0) { | |||
throw new Error('Nenalezeny žádné otázky na stránce'); | |||
} | |||
var randomQuestion = questions[Math.floor(Math.random() * questions.length)]; | |||
const inputType = randomQuestion.type === 'checkbox' ? 'checkbox' : 'radio'; | |||
return Promise.all([ | |||
parseWikitext(randomQuestion.text), | |||
Promise.all(randomQuestion.options.map(opt => parseWikitext(opt.text))) | |||
]).then(function([parsedQuestionText, parsedOptions]) { | |||
// Nová proměnná pro text otázky | |||
let questionDisplayText = parsedQuestionText; | |||
console.log("Otázka:",parsedQuestionText) | |||
// Updated options display: vytvoříme tabulku s inputem vedle textu. | |||
var optionsHtml = `<table style="width: 100%; border-collapse: collapse;">` + | |||
randomQuestion.options.map((opt, index) => { | |||
return `<tr> | |||
<td style="vertical-align: middle; padding: 1px;"> | |||
<input type="${inputType}" name="quizOption" value="${opt.text}" style="margin: 0 10px 0 0; vertical-align: middle; width: 30px; height: 30px;"> | |||
</td> | |||
<td style="vertical-align: middle; padding: 1px;">${parsedOptions[index]}</td> | |||
</tr>`; | |||
}).join('') + `</table>`; | |||
var quizHtml = ` | |||
<form class="quizForm"> | |||
<div class="quizQuestion"> | |||
<p style="font-size: 0.75em;"><a href="/w/${pageName}">${pageName}</a></p> | |||
<p class="questionTitle" style="font-size: 1.25em;">${questionDisplayText}</p> | |||
</div> | |||
<div class="quizOptions"> | |||
${optionsHtml} | |||
</div> | |||
<div class="button-container"> | |||
<button type="button" class="btn btn-primary submitQuiz" style="padding: 5px 10px;">Vyhodnotit</button> | |||
<button type="button" id="nextQuestion" class="btn btn-secondary" style="padding: 5px 10px;">Další otázka</button> | |||
</div> | |||
</form> | |||
`; | |||
quizContainer.html(quizHtml); | |||
$('#nextQuestion').on('click', displayQuiz); | |||
$('.submitQuiz').on('click', function() { | |||
evaluateQuiz(randomQuestion); | |||
}); | |||
mw.hook('wikipage.content').fire(quizContainer); | |||
}); | |||
}).catch(function(error) { | |||
console.error('Chyba při načítání kvízu:', error); | |||
quizContainer.html('<p class="error">Nepodařilo se načíst kvíz: ' + error.message + '</p>'); | |||
}); | |||
} | |||
function evaluateQuiz(question) { | |||
console.debug("evaluateQuiz called", question); // added debug | |||
$('.quizForm input').each(function() { | |||
const $input = $(this); | |||
const optionText = $input.val().trim(); | |||
const corresponding = question.options.find(o => o.text === optionText); | |||
if (corresponding && corresponding.correct) { | |||
$input.closest('tr').css('background-color', 'lightgreen'); // changed from .closest('.proposal') | |||
} | |||
if ($input.is(':checked') && (!corresponding || !corresponding.correct)) { | |||
$input.closest('tr').css('background-color', 'lightcoral'); // changed from .closest('.proposal') | |||
} | |||
}); | |||
} | |||
displayQuiz(); | |||
}); | |||
</script> |
Verze z 7. 2. 2025, 21:44
<script>
$(document).ready(function() {
console.debug("Document ready"); // added debug
function extractQuestions(wikitext) { const lines = wikitext.split('\n'); const questions = []; let i = 0; while (i < lines.length) { let line = lines[i].trim(); if (!line) { i++; continue; } // Zpracujeme blok otázky začínající '{' if (line.startsWith('{')) { let questionLines = []; while (i < lines.length) { const currentLine = lines[i].trim(); questionLines.push(currentLine); if (currentLine.endsWith('}')) break; i++; } let questionBlock = questionLines.join(' '); // Odebereme vnější složené závorky questionBlock = questionBlock.replace(/^\{/, ).replace(/\}$/, ).trim(); // Zjistíme a odstraníme specifikaci typu let type = 'checkbox'; const typeMatch = questionBlock.match(/\|type=[„"]([\[\]\(\)]+)[“"]/); if (typeMatch) { type = typeMatch[1] === '[]' ? 'checkbox' : 'radio'; questionBlock = questionBlock.replace(/\|type=[„"]([\[\]\(\)]+)[“"]/, ).trim(); } // Nově odstraníme ' |type=„[]“' nebo ' |type=„()“' pokud je v textu otázky questionBlock = questionBlock.replace(/\s*\|type=[„"]([\[\]\(\)]+)[“"]/, ).trim(); // Přidá podmínku, aby text otázky začínal ihned za znakem '{', ale znak '{' se nepřepíše do textu otázky if (questionBlock.startsWith('{')) { questionBlock = questionBlock.substring(1).trim(); } const currentQuestion = { text: questionBlock, options: [], type: type }; i++; // Zpracování následujících řádků jako odpovědí while (i < lines.length) { const answerLine = lines[i].trim(); if (!answerLine) { i++; continue; } if (answerLine.startsWith('{')) break; if (answerLine.startsWith('+') || answerLine.startsWith('-')) { const isCorrect = answerLine.startsWith('+'); const optionText = answerLine.substring(1).trim(); currentQuestion.options.push({ text: optionText, correct: isCorrect }); } else if (answerLine.startsWith('||')) { if (currentQuestion.options.length > 0) { currentQuestion.options[currentQuestion.options.length - 1].text += " " + answerLine.substring(2).trim(); } } else { break; } i++; } if (currentQuestion.options.length > 0) { questions.push(currentQuestion); } } else { i++; } } return questions; }
function checkPageForQuiz(pageName) { return new mw.Api().get({ action: 'parse', page: pageName, prop: 'text', format: 'json' }).then(function(result) { if (!result.parse || !result.parse.text) { return false; } const content = result.parse.text['*']; return content.includes('<quiz>') || content.includes('class="quiz"'); }); }
async function loadRandomQuiz() { console.debug("loadRandomQuiz called"); // added debug const data = await $.get('/api.php', { action: 'query', list: 'allpages', apnamespace: 108, aplimit: 500, format: 'json' });
if (!data.query || !data.query.allpages.length) { throw new Error('Nenalezeny žádné stránky'); }
const pages = data.query.allpages.sort(() => Math.random() - 0.5); for (const page of pages) { const hasQuiz = await checkPageForQuiz(page.title); if (hasQuiz) { return page.title; } }
throw new Error('Nenalezena žádná stránka s kvízem'); }
function loadPageContent(pageName) { return new mw.Api().get({ action: 'parse', page: pageName, prop: 'wikitext', format: 'json' }).then(function(result) { return { pageName, wikitext: result.parse.wikitext['*'] }; }); }
function parseWikitext(wikitext) { console.debug("parseWikitext called", wikitext); // added debug return new mw.Api().post({ action: 'parse', text: wikitext, contentmodel: 'wikitext', prop: 'text', format: 'json' }).then(function(result) {
// Trim any surrounding
tags return result.parse.text['*']//.replace(/^
|<\/p>$/g, ).trim(); }); } function displayQuiz() { console.debug("displayQuiz called"); // added debug var quizContainer = $('#randomQuizContainer'); quizContainer.html('
Načítání kvízu...
');
mw.loader.using(['mediawiki.api', 'ext.quiz']).then(loadRandomQuiz) .then(loadPageContent) .then(function({ pageName, wikitext }) { var questions = extractQuestions(wikitext); if (questions.length === 0) { throw new Error('Nenalezeny žádné otázky na stránce'); }
var randomQuestion = questions[Math.floor(Math.random() * questions.length)]; const inputType = randomQuestion.type === 'checkbox' ? 'checkbox' : 'radio';
return Promise.all([ parseWikitext(randomQuestion.text), Promise.all(randomQuestion.options.map(opt => parseWikitext(opt.text))) ]).then(function([parsedQuestionText, parsedOptions]) { // Nová proměnná pro text otázky let questionDisplayText = parsedQuestionText; console.log("Otázka:",parsedQuestionText)
// Updated options display: vytvoříme tabulku s inputem vedle textu.
var optionsHtml = `
` + randomQuestion.options.map((opt, index) => { return ``; }).join() + `
<input type="${inputType}" name="quizOption" value="${opt.text}" style="margin: 0 10px 0 0; vertical-align: middle; width: 30px; height: 30px;"> |
${parsedOptions[index]} |
`;
var quizHtml = ` <form class="quizForm">
<a href="/w/${pageName}">${pageName}</a>
${questionDisplayText}
${optionsHtml}
</form> `;
quizContainer.html(quizHtml); $('#nextQuestion').on('click', displayQuiz); $('.submitQuiz').on('click', function() { evaluateQuiz(randomQuestion); }); mw.hook('wikipage.content').fire(quizContainer); }); }).catch(function(error) { console.error('Chyba při načítání kvízu:', error);
quizContainer.html('
Nepodařilo se načíst kvíz: ' + error.message + '
');
}); }
function evaluateQuiz(question) { console.debug("evaluateQuiz called", question); // added debug $('.quizForm input').each(function() { const $input = $(this); const optionText = $input.val().trim(); const corresponding = question.options.find(o => o.text === optionText);
if (corresponding && corresponding.correct) { $input.closest('tr').css('background-color', 'lightgreen'); // changed from .closest('.proposal') }
if ($input.is(':checked') && (!corresponding || !corresponding.correct)) { $input.closest('tr').css('background-color', 'lightcoral'); // changed from .closest('.proposal') } }); }
displayQuiz();
});
</script>