1<?php 2 3/** 4 * Plugin QnA: Block syntax 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @author Mykola Ostrovskyy <dwpforge@gmail.com> 8 */ 9 10/* Must be run within Dokuwiki */ 11if(!defined('DOKU_INC')) die(); 12 13if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); 14require_once(DOKU_PLUGIN . 'syntax.php'); 15 16class syntax_plugin_qna_block extends DokuWiki_Syntax_Plugin { 17 18 private $mode; 19 private $questionId; 20 private $maxIdLength; 21 22 /** 23 * Constructor 24 */ 25 public function __construct() { 26 $this->mode = substr(get_class($this), 7); 27 $this->questionId = array(); 28 $this->maxIdLength = 30; 29 } 30 31 /** 32 * What kind of syntax are we? 33 */ 34 public function getType() { 35 return 'container'; 36 } 37 38 public function getPType() { 39 return 'block'; 40 } 41 42 /** 43 * Where to sort in? 44 */ 45 public function getSort() { 46 return 55; 47 } 48 49 /** 50 * 51 */ 52 public function connectTo($mode) { 53 $this->Lexer->addSpecialPattern('\n\?{3}.*?(?=\n)', $mode, $this->mode); 54 $this->Lexer->addSpecialPattern('\n!{3}', $mode, $this->mode); 55 } 56 57 /** 58 * 59 */ 60 public function handle($match, $state, $pos, Doku_Handler $handler) { 61 if ($state == DOKU_LEXER_SPECIAL) { 62 if ($match[1] == '?') { 63 $question = trim(substr($match, 4)); 64 65 if ($question != '') { 66 $identifier = $this->questionToIdentifier($question); 67 68 $data = array('open_question', $question, $identifier); 69 } 70 else { 71 $data = array('close_block'); 72 } 73 } 74 else { 75 $data = array('open_answer'); 76 } 77 } 78 else { 79 $data = false; 80 } 81 82 return $data; 83 } 84 85 /** 86 * 87 */ 88 public function render($mode, Doku_Renderer $renderer, $data) { 89 if ($mode == 'xhtml') { 90 list($tag, $style) = explode('_', $data[0]); 91 92 if ($tag == 'open') { 93 $renderer->doc .= '<div class="qna-' . $style . '">' . DOKU_LF; 94 95 if ($style == 'question') { 96 $renderer->doc .= '<div class="qna-title">'; 97 $renderer->doc .= '<a name="' . $data[2] . '">'; 98 $renderer->doc .= $data[1] . '</a></div>' . DOKU_LF; 99 } 100 } 101 else { 102 $renderer->doc .= '</div>' . DOKU_LF; 103 } 104 105 return true; 106 } 107 elseif ($mode == 'metadata') { 108 if ($data[0] == 'open_question') { 109 $meta['title'] = $data[1]; 110 $meta['id'] = $data[2]; 111 $meta['level'] = $data[3]; 112 $meta['class'] = 'question'; 113 114 $renderer->meta['description']['tableofquestions'][] = $meta; 115 } 116 117 return true; 118 } 119 120 return false; 121 } 122 123 /** 124 * Convert a question title to unique identifier 125 */ 126 private function questionToIdentifier($title) { 127 $identifier = str_replace(':', '', cleanID($title)); 128 $identifier = ltrim($identifier, '0123456789._-'); 129 130 if (utf8_strlen($identifier) > $this->maxIdLength) { 131 $identifier = utf8_substr($identifier, 0, $this->maxIdLength); 132 } 133 134 $identifier = rtrim($identifier, '_'); 135 136 if (isset($this->questionId[$identifier])) { 137 $identifier .= '_' . ++$this->questionId[$identifier]; 138 } 139 else { 140 $this->questionId[$identifier] = 1; 141 } 142 143 return $identifier; 144 } 145} 146