Extract MCQs

Extract MCQs from the webpage

Verzia zo dňa 26.02.2024. Pozri najnovšiu verziu.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, Greasemonkey alebo Violentmonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey, % alebo Violentmonkey.

Na nainštalovanie skriptu si budete musieť nainštalovať rozšírenie, ako napríklad Tampermonkey alebo Userscripts.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie, ako napríklad Tampermonkey.

Na inštaláciu tohto skriptu je potrebné nainštalovať rozšírenie správcu používateľských skriptov.

(Už mám správcu používateľských skriptov, nechajte ma ho nainštalovať!)

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie, ako napríklad Stylus.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

Na inštaláciu tohto štýlu je potrebné nainštalovať rozšírenie správcu používateľských štýlov.

(Už mám správcu používateľských štýlov, nechajte ma ho nainštalovať!)

// ==UserScript==
// @name         Extract MCQs
// @namespace    themrsami
// @version      2.0
// @description  Extract MCQs from the webpage
// @author       You
// @match        http://*/*
// @match        https://*/*
// @grant        GM_registerMenuCommand
// @grant        GM_addStyle
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Add some CSS for the button
    GM_addStyle(`
        #extract-mcqs-button {
            position: fixed;
            bottom: 20px;
            right: 20px;
            padding: 10px 20px;
            font-size: 16px;
            color: white;
            background-color: #007BFF;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            z-index: 9999;
        }
        #extract-mcqs-button:hover {
            background-color: #0056b3;
        }
    `);

    // Create the button
    let button = document.createElement('button');
    button.id = 'extract-mcqs-button';
    button.innerText = 'Extract MCQs';
    document.body.appendChild(button);

GM_registerMenuCommand('Extract MCQs', function() {
// Remove elements that destroy the structure
let elementsToRemove = [
    ...document.querySelectorAll('div[style="margin:30px 0px;"]'),
    ...document.querySelectorAll('div.sf-mobile-ads'),
    ...document.querySelectorAll('div.sf-desktop-ads'),
    ...document.querySelectorAll('span.collapseomatic')
];

for (let element of elementsToRemove) {
    if (element.parentNode) {
        element.parentNode.removeChild(element);
    }
}

let pTags = document.getElementsByTagName('p');
let results = [];

for (let i = 0; i < pTags.length; i++) {
    let imgHref = null;
    let aTag = pTags[i].getElementsByTagName('a')[0];
    if (aTag) {
        let imgTag = aTag.getElementsByTagName('img')[0];
        if (imgTag) {
            imgHref = imgTag.src || imgTag.getAttribute('data-src');
            aTag.parentNode.removeChild(aTag);
        }
    }

    let startsWithNumber = /^\d/.test(pTags[i].textContent);
    let nextSibling = pTags[i].nextElementSibling;
    if (startsWithNumber && nextSibling && nextSibling.tagName.toLowerCase() === 'div' && nextSibling.classList.contains('collapseomatic_content')) {
        let statementAndOptions = pTags[i].innerHTML.split('<br>');
        let statement = statementAndOptions.shift();
        let options = statementAndOptions.join('<br>').replace(/\n/g, '');
        let answerAndExplanation = nextSibling.innerHTML.split('<br>');
        let answer = answerAndExplanation.shift().replace(/\n/g, '');
        let explanation = answerAndExplanation.join('<br>').replace(/\n/g, '');
        results.push({
            statement: statement,
            imgHref: imgHref,
            options: options,
            answer: answer,
            explanation: explanation
        });
    }

    let nextDiv = pTags[i].nextElementSibling;
    if (nextDiv && nextDiv.tagName.toLowerCase() === 'div' && nextDiv.classList.contains('hk1_style-wrap5')) {
        let pre = nextDiv.getElementsByTagName('pre')[0];
        if (pre) {
            let nextP = nextDiv.nextElementSibling;
            if (nextP && nextP.tagName.toLowerCase() === 'p') {
                let nextDiv2 = nextP.nextElementSibling;
                if (nextDiv2 && nextDiv2.tagName.toLowerCase() === 'div' && nextDiv2.classList.contains('collapseomatic_content')) {
                    let statement = pTags[i].textContent;
                    let preContent = pre.textContent.replace(/\n/g, '');
                    let options = nextP.innerHTML.split('<br>').join('<br>').replace(/\n/g, '');
                    let answerAndExplanation = nextDiv2.innerHTML.split('<br>');
                    let answer = answerAndExplanation.shift().replace(/\n/g, '');
                    let explanation = answerAndExplanation.join('<br>').replace(/\n/g, '');
                    results.push({
                        statement: statement,
                        preContent: preContent,
                        options: options,
                        answer: answer,
                        explanation: explanation
                    });
                }
            }
        }

        let del1 = nextDiv.getElementsByClassName('del1')[0];
        if (del1) {
            let statement = pTags[i].textContent + ' ' + del1.textContent;
            let nextP = nextDiv.nextElementSibling;
            if (nextP && nextP.tagName.toLowerCase() === 'p') {
                let nextDiv2 = nextP.nextElementSibling;
                if (nextDiv2 && nextDiv2.tagName.toLowerCase() === 'div' && nextDiv2.classList.contains('collapseomatic_content')) {
                    let options = nextP.innerHTML.split('<br>').join('<br>').replace(/\n/g, '');
                    let answerAndExplanation = nextDiv2.innerHTML.split('<br>');
                    let answer = answerAndExplanation.shift().replace(/\n/g, '');
                    let explanation = answerAndExplanation.join('<br>').replace(/\n/g, '');
                    results.push({
                        statement: statement,
                        options: options,
                        answer: answer,
                        explanation: explanation
                    });
                }
            }
        }
    }
}

console.log(JSON.stringify(results, null, 2));


// ... Your existing code to extract the MCQs ...

// Now let's generate the HTML
let html = `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"="width=device-width, initial-scale=1.0">
    <title>Quiz</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
        @tailwind base;
        @tailwind components;
        @tailwind utilities;

        .option:hover:not(.selected) {
          @apply bg-gray-300;
        }
        .correct {
          @apply bg-green-200;
        }
        .incorrect {
          @apply bg-red-200;
        }
        .selected {
          @apply bg-gray-400;
        }
        .option:hover {
          @apply scale-105;
        }
        .selected {
          @apply scale-110;
        }
        .option:focus {
          @apply ring-4 ring-blue-500 ring-offset-2 ring-offset-gray-100;
        }
    </style>
</head>
<body class="bg-gray-100 p-10">

    <div class="flex justify-between items-center mb-4 sticky top-0 bg-white z-50">
        <div>
            <p class="text-lg font-bold">Time: <span id="timer" class="text-blue-500">00:00</span></p>
        </div>
        <div>
            <p class="text-lg font-bold text-green-500">Correct: <span id="correct-count">0</span></p>
            <p class="text-lg font-bold text-red-500">Incorrect: <span id="incorrect-count">0</span></p>
        </div>
    </div>



    ${results.map((result, index) => `
    <div class="bg-white shadow-md rounded px-8 pt-6 pb-8 mb-4 flex flex-col my-2">
        <div class="md:flex mb-6">
            <div class="md:w-1/2 px-3">
                <label class="block uppercase tracking-wide text-blue-900 text-lg font-bold mb-2" for="grid-first-name">
                    Q${index + 1}: ${result.statement.replace(/^\d+\.\s*/, '')}
                </label>
                ${result.preContent ? `<pre>${result.preContent}</pre>` : ''}
            </div>
            <div class="md:w-1/2 px-3">
                ${result.imgHref ? `<img src="${result.imgHref}" alt="Image" class="mb-4">` : ''}
            </div>
        </div>
        <div class="md:flex mb-6">
            <div class="md:w-full px-3">
                <div id="options-${index}" class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    ${result.options.split('<br>').map((option, optionIndex) => option.trim() !== "" ? `
                    <p class="option cursor-pointer py-2 px-4 rounded bg-blue-100 hover:bg-blue-200" onclick="checkAnswer(${index}, ${optionIndex})">${option}</p>
                    ` : '').join('')}
                </div>
                <button class="mt-3 text-white bg-blue-700 border-0 py-2 px-6 focus:outline-none hover:bg-blue-800 rounded text-lg" onclick="document.getElementById('answer-${index}').classList.toggle('hidden');document.getElementById('explanation-${index}').classList.toggle('hidden');">Show/Hide Answer</button>
                <p id="answer-${index}" class="hidden mt-3 text-grey-darker text-base bg-gray-200 p-4 rounded">${result.answer}</p>
                <p id="explanation-${index}" class="hidden mt-3 text-grey-darker text-base bg-gray-200 p-4 rounded">${result.explanation}</p>
            </div>
        </div>
    </div>
    `).join('')}
    <script src="script.js"></script>
</body>
</html>`;

// Download the file
let blob = new Blob([html], {type: "text/html;charset=utf-8"});
let link = document.createElement("a");
link.href = URL.createObjectURL(blob);
link.download = "quiz.html";
link.click();});

    // Add an event listener to the button
    button.addEventListener('click', function() {
        // Execute the menu command
        GM_executeMenuCommand('Extract MCQs');
    });

})();