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}
                           <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>
                   </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>