====== Spoiler Plugin ====== ---- plugin ---- description: Adds initially hidden sections author : Heikki Hokkanen email : hoxu@users.sf.net type : syntax lastupdate : 2007-07-19 compatible : Lemming, Anteater, Rincewind, Angua, Adora Belle, Weatherwax, Binky, Ponder Stibbons, Hrun, Detritus, Elenor of Tsort, Frusterick Manners, Greebo, !Hogfather depends : conflicts : similar : folded tags : hide downloadurl: https://wiki.hokkanen.org/_media/projects/dokuwiki/spoiler-plugin-2007-07-19.tgz ---- //Spoiler tag for DokuWiki. Allows sections that are initially hidden, and are shown when a “Show” button is clicked. The spoiler can be hidden again by pressing the button. An optional title can be given, otherwise a “Spoiler:” text is shown before the button.// ===== Syntax ===== Content with default title The butler did it! This spoiler contains another spoiler 8-o You can make a button for this code with [[doku>plugin:custombuttons]]. See [[https://wiki.hokkanen.org/projects/dokuwiki/spoiler]] FIXME for images, playground, and download. ===== Discussion ===== **Patch to work with 2020-07-29 "Hogfather"**\\ in ''lib/plugins/spoiler/syntax.php'' change the following lines (65+91) function handle($match, $state, $pos, &$handler){ function render($mode, &$renderer, $data) { to function handle($match, $state, $pos, Doku_Handler $handler){ function render($mode, Doku_Renderer $renderer, $data) { -- halbbit //2021-01-23// ---- **I'd like to see it work within a list** * * Foo * Bar This would be a very helpful bonus to this already very helpful plugin. Yes, it doesn't work with latest Dokuwiki version. Perhaps author would never come with solution as plugin released in 2007... ---- **Patch to provide control over all 'spoiler' items in a page** Usage: %%~~SPOILER:open|Label Text~~%% %%~~SPOILER:close|Label Text~~%% %%~~SPOILER:hide|Label Text~~%% %%~~SPOILER~~%% Default behaviour is ''open'', which is to un-hide all ''spoiler'' items, this is opposite of using %%%% without %%~~SPOILER~~%%. Permitted modes are: * ''open '': All spoiler tags are expanded and visible when the page is rendered * ''close'': All spoiler tags are collapsed (closed) and visible when the page is rendered * ''hide '': All spoiler tags are not visible and the button to open/close them is not rendered The ''Label Text'' works similar to %%%%. Here are the code changes to ''style.css'' and ''syntax.php'': *** ./style.css Wed Jul 18 14:14:43 2007 --- ./new_style.css Tue Nov 17 15:43:41 2009 *************** *** 24,26 **** --- 24,47 ---- margin-top: 0.5em; } + .spoilerctrl { + margin-top: 0.5em; + margin-bottom: 1em; + } + + .spoilerctrl .title { + /* font-size: 110%; */ + font-size: 90%; + font-weight: bold; + display: block; + float: left; + } + + .spoilerctrl .title:after { + content: ': '; + } + + + .spoilerctrl input { + font-size: 70%; + } *** ./syntax.php Thu Jul 19 15:32:57 2007 --- ./new_syntax.php Tue Nov 17 15:43:41 2009 *************** *** 56,61 **** --- 56,62 ---- function connectTo($mode) { // Lookahead assertion: check that there is an end tag. $this->Lexer->addEntryPattern('\r\n]*?>(?=.*?)', $mode, 'plugin_spoiler'); + $this->Lexer->addSpecialPattern('~~SPOILER[^~\r\n]*?~~', $mode, 'plugin_spoiler'); } function postConnect() { *************** *** 73,88 **** $title = substr($options, strpos($options, '|') + 1); } ! return array($state, $title); break; case DOKU_LEXER_MATCHED : break; case DOKU_LEXER_UNMATCHED : ! return array($state, $match); break; case DOKU_LEXER_EXIT : break; case DOKU_LEXER_SPECIAL : break; } return array($state); --- 74,108 ---- $title = substr($options, strpos($options, '|') + 1); } ! return array($state, $title, ''); break; case DOKU_LEXER_MATCHED : break; case DOKU_LEXER_UNMATCHED : ! return array($state, $match, ''); break; case DOKU_LEXER_EXIT : break; case DOKU_LEXER_SPECIAL : + // "~~SPOILER" options "~~" + $options = substr($match, 8, -2); + + $endPos = strlen($options) + 1; + if (strpos($options, '|') !== False) { + $endPos = strpos($options,'|'); + $title = substr($options, $endPos + 1); + } + + $switch = 'show'; + $options = substr($options,1,$endPos - 1); + if (strpos($options, ':') !== False) { + $startPos = strpos($options,':'); + $switch = substr($options, $startPos + 1, $endPos - ($startPos + 1)); + } + + if ($title == '') $title = 'Spoiler Control'; + + return array($state, $title, $switch); break; } return array($state); *************** *** 90,96 **** function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ ! list($state, $payload) = $data; switch ($state) { case DOKU_LEXER_ENTER : --- 110,116 ---- function render($mode, &$renderer, $data) { if($mode == 'xhtml'){ ! list($state, $payload, $switch) = $data; switch ($state) { case DOKU_LEXER_ENTER : *************** *** 100,105 **** --- 120,139 ---- break; case DOKU_LEXER_MATCHED : break; + case DOKU_LEXER_SPECIAL : + $script = "if (this.value == 'Show All') { spoilerControl(1); this.value = 'Hide All' } else { spoilerControl(0); this.value = 'Show All' }"; + switch($switch){ + case 'close': + $renderer->doc .= '
'. $payload .'
'; + break; + case 'hide': + $renderer->doc .= ''; + break; + default: + $renderer->doc .= '
'. $payload .'
'; + break; + } + break; case DOKU_LEXER_UNMATCHED : $renderer->doc .= $renderer->_xmlEntities($payload); break;
Also, add the file ''script.js'': function spoilerControl(state) { var el = document.getElementsByTagName('DIV'); for(var j=0; j < el.length; j++) { var className = el[j].className; if (className == "spoiler") { if (state == 1) { el[j].style.display = ''; }else { el[j].style.display = 'none'; } } } } This extra file hides away any 'spoiler' items when printing (call it ''print.css''): div.dokuwiki .spoiler { visibility: hidden; display: none; } div.dokuwiki .spoilerctrl { visibility: hidden; display: none; } -- Chris Usher //2009-11-17// ---- ==== Problems ==== * Spoiler will not work in a table * Use [[.:include]] * Bug with apostrophe **'** in spoiler title * Put string ''$payload = str_replace("'","’",$payload);'' after string ''list($state, $payload) = $data; '' * Spoiler can't hold ''include'' syntax inside. Include will be showed under it * No spacing after first paragraph in spoiler, cause it come without '

' html tags.