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 3 (https://www.gnu.org/licenses/gpl-3.0.html) 11 * @author halbbit (osi@abwesend.de) 12 heavily based on the abandoned version of Heikki Hokkanen <hoxu@users.sf.net> 13 */ 14 15if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 16if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 17require_once(DOKU_PLUGIN.'syntax.php'); 18 19class syntax_plugin_spoiler extends DokuWiki_Syntax_Plugin { 20 21 function getInfo(){ 22 return array( 23 'author' => 'halbbit', 24 'email' => 'supp3@gmx.net', 25 'date' => '2021-03-03', 26 'name' => 'spoiler2 plugin', 27 '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', 28 'url' => 'http://wiki.splitbrain.org/plugin:spoiler2', 29 ); 30 } 31 32 function getType(){ 33 return 'container'; 34 } 35 36 function getPType() { 37 return 'block'; 38 } 39 40 function getAllowedTypes() { 41 return array('container', 'substition', 'protected', 'disabled', 'formatting', 'paragraphs'); 42 } 43 44 function getSort(){ 45 return 195; 46 } 47 48 // override default accepts() method to allow nesting 49 // - ie, to get the plugin accepts its own entry syntax 50 function accepts($mode) { 51 // ($mode == 'plugin_spoiler') 52 if ($mode == substr(get_class($this), 7)) return true; 53 54 return parent::accepts($mode); 55 } 56 57 function connectTo($mode) { 58 // Lookahead assertion: check that there is an end tag. 59 $this->Lexer->addEntryPattern('<spoiler[^>\r\n]*?>(?=.*?</spoiler>)', $mode, 'plugin_spoiler'); 60 } 61 62 function postConnect() { 63 $this->Lexer->addExitPattern('</spoiler>', 'plugin_spoiler'); 64 } 65 66 function handle($match, $state, $pos, Doku_Handler $handler){ 67 switch ($state) { 68 case DOKU_LEXER_ENTER : 69 // "<spoiler" options ">" 70 $options = substr($match, 7, -1); 71 72 $title = 'Spoiler'; 73 if (strpos($options, '|') !== False) { 74 $title = substr($options, strpos($options, '|') + 1); 75 } 76 77 return array($state, $title); 78 break; 79 case DOKU_LEXER_MATCHED : 80 break; 81 case DOKU_LEXER_UNMATCHED : 82 return array($state, $match); 83 break; 84 case DOKU_LEXER_EXIT : 85 break; 86 case DOKU_LEXER_SPECIAL : 87 break; 88 } 89 return array($state); 90 } 91 92 function render($mode, Doku_Renderer $renderer, $data) { 93 if($mode == 'xhtml'){ 94 list($state, $payload) = $data; 95 96 switch ($state) { 97 case DOKU_LEXER_ENTER : 98 $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' }"; 99 $renderer->doc .= '<div class="spoiler"><div class="title">'. $payload .'</div><input type="button" value="Show" onClick="'. $script .'" /><div class="content" style="display: none">'; 100 // two open div tags 101 break; 102 case DOKU_LEXER_MATCHED : 103 break; 104 case DOKU_LEXER_UNMATCHED : 105 $renderer->doc .= $renderer->_xmlEntities($payload); 106 break; 107 case DOKU_LEXER_EXIT : 108 $renderer->doc .= '</div></div>'; 109 break; 110 } 111 112 return true; 113 } 114 return false; 115 } 116} 117 118// VIM: ex: noet ts=4 sw=4 enc=utf-8 : 119