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