1<?php 2/** 3 * <spoiler> tag for dokuwiki. Allows sections that are initially hidden, and 4 * are shown when a "Show" button is clicked. The spoiler can be hidden again 5 * by pressing the button. 6 * 7 * <spoiler>Content with default title</spoiler> 8 * <spoiler |Plot details>The butler did it!</spoiler> 9 * 10 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 11 * @author Heikki Hokkanen <hoxu@users.sf.net> 12 */ 13 14if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 15if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 16require_once(DOKU_PLUGIN.'syntax.php'); 17 18class syntax_plugin_spoiler extends DokuWiki_Syntax_Plugin { 19 20 function getInfo(){ 21 return array( 22 'author' => 'Heikki Hokkanen', 23 'email' => 'hoxu@users.sf.net', 24 'date' => '2007-07-19', 25 'name' => 'spoiler plugin', 26 'desc' => 'Add <spoiler> tag, allowing sections that are initially hidden and can be made visible by clicking on a button. Another click will hide the spoiler again', 27 'url' => 'http://wiki.splitbrain.org/wiki:plugins', 28 ); 29 } 30 31 function getType(){ 32 return 'container'; 33 } 34 35 function getPType() { 36 return 'block'; 37 } 38 39 function getAllowedTypes() { 40 return array('container', 'substition', 'protected', 'disabled', 'formatting', 'paragraphs'); 41 } 42 43 function getSort(){ 44 return 195; 45 } 46 47 // override default accepts() method to allow nesting 48 // - ie, to get the plugin accepts its own entry syntax 49 function accepts($mode) { 50 // ($mode == 'plugin_spoiler') 51 if ($mode == substr(get_class($this), 7)) return true; 52 53 return parent::accepts($mode); 54 } 55 56 function connectTo($mode) { 57 // Lookahead assertion: check that there is an end tag. 58 $this->Lexer->addEntryPattern('<spoiler[^>\r\n]*?>(?=.*?</spoiler>)', $mode, 'plugin_spoiler'); 59 } 60 61 function postConnect() { 62 $this->Lexer->addExitPattern('</spoiler>', 'plugin_spoiler'); 63 } 64 65 function handle($match, $state, $pos, &$handler){ 66 switch ($state) { 67 case DOKU_LEXER_ENTER : 68 // "<spoiler" options ">" 69 $options = substr($match, 7, -1); 70 71 $title = 'Spoiler'; 72 if (strpos($options, '|') !== False) { 73 $title = substr($options, strpos($options, '|') + 1); 74 } 75 76 return array($state, $title); 77 break; 78 case DOKU_LEXER_MATCHED : 79 break; 80 case DOKU_LEXER_UNMATCHED : 81 return array($state, $match); 82 break; 83 case DOKU_LEXER_EXIT : 84 break; 85 case DOKU_LEXER_SPECIAL : 86 break; 87 } 88 return array($state); 89 } 90 91 function render($mode, &$renderer, $data) { 92 if($mode == 'xhtml'){ 93 list($state, $payload) = $data; 94 95 switch ($state) { 96 case DOKU_LEXER_ENTER : 97 $script = "c = this.parentNode.getElementsByTagName('div')[1]; if (this.value == 'Show') { c.style.display = ''; this.value = 'Hide' } else { c.style.display = 'none'; this.value = 'Show' }"; 98 $renderer->doc .= '<div class="spoiler"><div class="title">'. $payload .'</div><input type="button" value="Show" onClick="'. $script .'" /><div class="content" style="display: none">'; 99 // two open div tags 100 break; 101 case DOKU_LEXER_MATCHED : 102 break; 103 case DOKU_LEXER_UNMATCHED : 104 $renderer->doc .= $renderer->_xmlEntities($payload); 105 break; 106 case DOKU_LEXER_EXIT : 107 $renderer->doc .= '</div></div>'; 108 break; 109 } 110 111 return true; 112 } 113 return false; 114 } 115} 116 117// VIM: ex: noet ts=4 sw=4 enc=utf-8 : 118