Lexer->addSpecialPattern('.*?', $mode, 'plugin_flashcards'); } public function handle($match, $state, $pos, Doku_Handler $handler) { $match = trim(substr($match, 12, -13)); // Strip tags // Parse optional attributes preg_match('/heading="(.*?)"/', $match, $headingMatch); preg_match('/subtext="(.*?)"/', $match, $subtextMatch); preg_match('/skiptext="(.*?)"/', $match, $skipTextMatch); preg_match('/nexttext="(.*?)"/', $match, $nextTextMatch); preg_match('/defaultnum="(\d+)"/', $match, $defaultNumMatch); $heading = $headingMatch[1] ?? 'Flashcard Quiz'; $subtext = $subtextMatch[1] ?? 'Answer the following questions:'; $skipText = $skipTextMatch[1] ?? 'Skip'; $nextText = $nextTextMatch[1] ?? 'Next'; $defaultNum = $defaultNumMatch[1] ?? 5; // Default to 5 if not provided // Parse the content within the block if (preg_match('/(.*?)<\/questions>/s', $match, $contentMatch)) { $content = trim($contentMatch[1]); } else { return [ 'heading' => $heading, 'subtext' => $subtext, 'skipText' => $skipText, 'nextText' => $nextText, 'defaultNum' => $defaultNum, 'questions' => [], // No valid content found ]; } // Parse questions and answers using --- as delimiter $questions = []; foreach (preg_split('/---\n/', $content) as $block) { $lines = array_filter(explode("\n", trim($block))); // Filter empty lines $question = array_shift($lines); if (empty($question)) { continue; // Skip empty question blocks } $answers = []; $correctAnswerIndex = null; foreach ($lines as $index => $line) { $line = trim($line); if (strpos($line, '*') !== false) { $correctAnswerIndex = $index; $line = str_replace('*', '', $line); // Remove the correct marker } $answers[] = trim($line, "- "); } if (empty($answers) || $correctAnswerIndex === null) { continue; // Skip questions without valid answers or no correct answer } $questions[] = [ 'question' => trim($question), 'answers' => $answers, 'correct' => $correctAnswerIndex, ]; } return [ 'heading' => $heading, 'subtext' => $subtext, 'skipText' => $skipText, 'nextText' => $nextText, 'defaultNum' => $defaultNum, 'questions' => $questions, ]; } public function render($mode, Doku_Renderer $renderer, $data) { if ($mode !== 'xhtml') return false; $heading = htmlspecialchars($data['heading']); $subtext = htmlspecialchars($data['subtext']); $skipText = htmlspecialchars($data['skipText']); $nextText = htmlspecialchars($data['nextText']); $defaultNum = htmlspecialchars($data['defaultNum']); $questions = json_encode($data['questions'], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP); $renderer->doc .= "

{$heading}

{$subtext}

"; return true; } }