Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <title>Subjective Questions Print View</title> | |
| <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet"> | |
| <style> | |
| body { | |
| background-color: white; | |
| color: black; | |
| } | |
| .topic-header { | |
| border-bottom: 2px solid #000; | |
| margin-top: 2rem; | |
| margin-bottom: 1rem; | |
| padding-bottom: 0.5rem; | |
| } | |
| .question-container { | |
| margin-bottom: 1.5rem; | |
| page-break-inside: avoid; | |
| } | |
| .question-number { | |
| font-weight: bold; | |
| margin-right: 0.5rem; | |
| } | |
| img { | |
| max-width: 100%; | |
| height: auto; | |
| } | |
| @media print { | |
| .no-print { display: none; } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container mt-4"> | |
| <div class="d-flex justify-content-between align-items-center mb-4 no-print"> | |
| <h1>Questions Preview</h1> | |
| <div> | |
| <button onclick="window.print()" class="btn btn-primary">Print / Save as PDF</button> | |
| <button onclick="window.close()" class="btn btn-secondary">Close</button> | |
| </div> | |
| </div> | |
| {% if grouped_questions %} | |
| {% for topic, questions in grouped_questions.items() %} | |
| <div class="topic-section"> | |
| <h3 class="topic-header">{{ topic }}</h3> | |
| {% for q in questions %} | |
| <div class="question-container"> | |
| <div class="d-flex"> | |
| <div class="question-number">Q{{ q.question_number_within_topic }}.</div> | |
| <div class="flex-grow-1" {% if q.question_json %}data-json="{{ q.question_json | escape }}"{% endif %}> | |
| {{ q.question_html | safe }} | |
| </div> | |
| </div> | |
| </div> | |
| {% endfor %} | |
| </div> | |
| {% endfor %} | |
| {% else %} | |
| <p class="text-center">No questions found in this folder.</p> | |
| {% endif %} | |
| </div> | |
| <script> | |
| // Helper function to convert EditorJS list items to HTML (handles nested lists) | |
| function listItemsToHtml(items) { | |
| let html = ''; | |
| items.forEach(item => { | |
| if (typeof item === 'string') { | |
| html += `<li>${item}</li>`; | |
| } else if (typeof item === 'object' && item !== null) { | |
| if (item.content) { | |
| html += `<li>${item.content}`; | |
| if (item.items && item.items.length > 0) { | |
| html += '<ul>'; | |
| html += listItemsToHtml(item.items); | |
| html += '</ul>'; | |
| } | |
| html += '</li>'; | |
| } | |
| } | |
| }); | |
| return html; | |
| } | |
| // Helper function to convert EditorJS blocks to HTML | |
| function editorJsToHtml(blocks) { | |
| let html = ""; | |
| blocks.forEach(block => { | |
| if (block.type === 'header') { | |
| html += `<h${block.data.level}>${block.data.text}</h${block.data.level}>`; | |
| } | |
| else if (block.type === 'paragraph') { | |
| html += `<p>${block.data.text}</p>`; | |
| } | |
| else if (block.type === 'list') { | |
| html += block.data.style === 'ordered' ? '<ol>' : '<ul>'; | |
| html += listItemsToHtml(block.data.items); | |
| html += block.data.style === 'ordered' ? '</ol>' : '</ul>'; | |
| } | |
| else if (block.type === 'image' || block.type === 'simple-image') { | |
| const url = block.data.url; | |
| const caption = block.data.caption || ''; | |
| html += `<div class="text-center my-2"><img src="${url}" class="img-fluid rounded" style="max-height: 300px;" alt="${caption}"><br><small class="text-muted">${caption}</small></div>`; | |
| } | |
| else if (block.type === 'raw') { | |
| html += block.data.html; | |
| } | |
| }); | |
| return html; | |
| } | |
| // Process any questions that have JSON data and convert to HTML | |
| window.onload = function() { | |
| // Check each question for JSON data and render if needed | |
| document.querySelectorAll('.question-container').forEach(container => { | |
| const questionDiv = container.querySelector('.flex-grow-1'); | |
| if (questionDiv && questionDiv.dataset.json) { | |
| try { | |
| const jsonData = JSON.parse(questionDiv.dataset.json); | |
| if (jsonData.blocks) { | |
| questionDiv.innerHTML = editorJsToHtml(jsonData.blocks); | |
| } | |
| } catch (e) { | |
| console.error('Error parsing question JSON:', e); | |
| } | |
| } | |
| }); | |
| // setTimeout to ensure images render | |
| setTimeout(() => { | |
| window.print(); | |
| }, 500); | |
| }; | |
| </script> | |
| </body> | |
| </html> |