Lexer->addSpecialPattern('----+>>?|----+[^\n]*?----+>>?|<----+|{{background>.+?}}', $mode, 'plugin_revealjs_background'); } /** * Handler to prepare matched data for the rendering process. * * @param $aMatch String The text matched by the patterns. * @param $aState Integer The lexer state for the match. * @param $aPos Integer The character position of the matched text. * @param $aHandler Object Reference to the Doku_Handler object. * @return Integer The current lexer state for the match. * @public * @see render() * @static */ public function handle($match, $state, $pos, Doku_Handler $handler) { $transition_count = 0; $position_count = 0; $data = array(); $data['position'] = $pos; $data['first_chars'] = substr($match, 0, 2); $data['last_chars'] = substr($match, -2); $params = preg_split("/\s+/", ($data['first_chars'] == '{{' ? substr($match, 13, -2) : trim($match,'-<> ') ), 12); foreach ($params as $param) { if (!$data['background_color'] && $this->_is_valid_color($param)) { $data['background_color'] = $param; } elseif (!$data['background_image'] && $this->_is_valid_image($param)) { $data['background_image'] = $param; } elseif (!$data['background_size'] && $this->_is_valid_size($param)) { $data['background_size'] = $param; } elseif ($position_count == 0 && $this->_is_valid_position($param)) { $position_count += 2; $data['background_position'] = $param; } elseif ($position_count < 2 && in_array($param, array('top','bottom','left','right','center'))) { $position_count += 1; if (!$data['background_position']) $data['background_position'] = $param; else $data['background_position'] .= ' '.$param; } elseif (!$data['background_repeat'] && in_array($param, array('repeat','no-repeat'))) { $data['background_repeat'] = $param; } elseif (!$data['background_transition'] && $this->_is_valid_bg_transition($param)) { $data['background_transition'] = $param; } elseif ($transition_count < 2 && $this->_is_valid_transition($param)) { $transition_count += 1; if (!$data['transition']) $data['transition'] = $param; else $data['transition'] .= ' '.$param; } elseif (!$data['transition_speed'] && in_array($param, array('default','fast','slow'))) { $data['transition_speed'] = $param; } elseif (!$data['no_footer'] && $param == 'no-footer') { $data['no_footer'] = true; } } return $data; } /** * Handle the actual output creation. * * @param $aFormat String The output format to generate. * @param $aRenderer Object A reference to the renderer object. * @param $aData Array The data created by the handle() * method. * @return Boolean TRUE if rendered successfully, or * FALSE otherwise. * @public * @see handle() */ public function render($mode, Doku_Renderer $renderer, $data) { global $conf; if($mode == 'xhtml') { // rendering the slideshow if (is_a($renderer, 'renderer_plugin_revealjs')){ $renderer->next_slide_background_color = $data['background_color']; $renderer->next_slide_background_image = $data['background_image'] && substr($data['background_image'], 0, 4) == 'http' ? $data['background_image'] : ml($data['background_image']); /*DokuWiki build link to media file*/ $renderer->next_slide_background_size = $data['background_size']; $renderer->next_slide_background_position = str_replace(',', ' ', $data['background_position']); // we replace "," with " ", because we needed this to distinguish between image size and image position $renderer->next_slide_background_repeat = $data['background_repeat']; $renderer->next_slide_background_transition = substr($data['background_transition'],3); // we cut off "bg-" for Reveal.js (we had "bg-" only to distinguish between background transition and slide transition) $renderer->next_slide_transition = $data['transition']; $renderer->next_slide_transition_speed = $data['transition_speed']; /* could be, that {{no-footer}} is used before a {{background>xxx}} definition and $renderer->next_slide_no_footer is already set to true, so we merge here both with a logical or */ $renderer->next_slide_no_footer = ($data['no_footer'] || $renderer->next_slide_no_footer); if ($data['last_chars'] == '->') { $renderer->open_slide(); $renderer->slide_indicator_headers = false; } elseif ($data['last_chars'] == '>>') { $renderer->open_slide_container(); $renderer->open_slide(); $renderer->slide_indicator_headers = false; } elseif ($data['first_chars'] == '<-') { $renderer->close_slide(); $renderer->slide_indicator_headers = true; } elseif ($data['first_chars'] == '<<') { $renderer->close_slide_container(); $renderer->slide_indicator_headers = true; } } // rendering the normal wiki page elseif ($this->getConf('revealjs_active')) { /* could be, that {{no-footer}} is used before and we need to align the start position definition for the section editing */ if ($renderer->wikipage_next_slide_no_footer_position > 0) { $data['position'] = $renderer->wikipage_next_slide_no_footer_position; $renderer->wikipage_next_slide_no_footer_position = 0; } // process slide details view if ($data['background_color']) { $slide_details_text .= ' '.$data['background_color']; $slide_details_background .= 'background-color:'.$data['background_color'].';'; } if ($data['background_image']) { $slide_details_text .= ' '.$data['background_image']; $slide_details_background .= 'background-image: url("'. (substr($data['background_image'], 0, 4) == 'http' ? $data['background_image'] : ml($data['background_image'])). '");'; } if ($data['background_size']) { $slide_details_text .= ' '.$data['background_size']; $slide_details_background .= 'background-size:'.$data['background_size'].';'; } if ($data['background_position']) { $slide_details_text .= ' '.$data['background_position']; $slide_details_background .= 'background-position:'. str_replace(',', ' ', $data['background_position']).';'; } if ($data['background_repeat']) { $slide_details_text .= ' '.$data['background_repeat']; $slide_details_background .= 'background-repeat:'.$data['background_repeat'].';'; } if ($data['background_transition']) { $slide_details_text .= ' '.$data['background_transition']; } if ($data['transition']) { $slide_details_text .= ' '.$data['transition']; } if ($data['transition_speed']) { $slide_details_text .= ' '.$data['transition_speed']; } /* could be, that {{no-footer}} is used before a {{background>xxx}} definition and $renderer->next_slide_no_footer is already set to true, so we merge here both with a logical or */ if ($data['no_footer'] || $renderer->wikipage_next_slide_no_footer) { $slide_details_text .= ' no-footer'; $renderer->wikipage_next_slide_no_footer = false; } // handle section editing if (in_array($data['last_chars'], array('->','>>','}}'))) { $renderer->wikipage_slide_number += 1; // close edit section, if open if($renderer->wikipage_slide_edit_section_open) { $renderer->wikipage_slide_edit_section_open = false; $renderer->doc .= DOKU_LF.''.DOKU_LF; $renderer->finishSectionEdit($data['position']- 1); } // calculate slide direction if ($data['last_chars'] == '>>') { $slide_direction = '→'; } elseif ($data['last_chars'] == '->') { $slide_direction = '↓'; } else { $slide_direction = ''; $conf['plugin']['revealjs']['slides_with_unknown_direction'] = true; } $sectionEditStartData = ['target' => 'section']; if (!defined('SEC_EDIT_PATTERN')) { // backwards-compatibility for Frusterick Manners (2017-02-19) $sectionEditStartData = 'section'; } /* write slide details to page - we need to use a fake header (