* @author Ottmar Gobrecht */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); // we inherit from the XHTML renderer instead directly of the base renderer require_once DOKU_INC.'inc/parser/xhtml.php'; /** * The Renderer */ class renderer_plugin_revealjs extends Doku_Renderer_xhtml { var $base = ''; var $tpl = ''; var $slide_indicator_headers = true; var $slide_number = 0; var $slide_open = false; var $column_open = false; var $notes_open = false; var $quote_open = false; var $fragment_list_open = false; var $no_fragment_list_open = false; var $fragment_style = ''; var $next_slide_background_color = ''; var $next_slide_background_image = ''; var $next_slide_background_size = ''; var $next_slide_background_position = ''; var $next_slide_background_repeat = ''; var $next_slide_background_transition = ''; var $next_slide_transition = ''; var $next_slide_transition_speed = ''; var $next_slide_no_footer = false; /** * the format we produce */ function getFormat(){ // this should be 'revealjs' usally, but we inherit from the xhtml renderer // and produce XHTML as well, so we can gain magically compatibility // by saying we're the 'xhtml' renderer here. return 'xhtml'; } /** * Initialize the rendering */ function document_start() { global $ID; global $conf; global $lang; // merge URL params into plugin conf - changing params direct in the URL is only working, when page is not cached (~~NOCACHE~~) if (count($_GET)){ if (!array_key_exists('plugin', $conf)) { $conf['plugin'] = array('revealjs' => $_GET); } elseif (!array_key_exists('revealjs', $conf['plugin'])) { $conf['plugin']['revealjs'] = $_GET; } else { $conf['plugin']['revealjs'] = array_merge($conf['plugin']['revealjs'], $_GET); } } // call the parent parent::document_start(); // store the content type headers in metadata $headers = array( 'Content-Type' => 'text/html; charset=utf-8' ); p_set_metadata($ID,array('format' => array('revealjs' => $headers) )); $this->base = DOKU_BASE.'lib/plugins/revealjs/'; $this->doc = ' '.tpl_pagetitle($ID, true).' ' . ($this->getConf('show_image_borders') ? '' : ' ') . '
'; } /** * Closes the document */ function document_end(){ // we don't care for footnotes and toc // but cleanup is nice $this->doc = preg_replace('#

\s*

#','',$this->doc); // cleanup quotes - too much whitspace from declaration: "> valid quote" $this->doc = preg_replace('/
“\s*/u','
“',$this->doc); // close maybe open slide and column $this->close_slide_container(); $show_controls = $this->getConf('controls') ? 'true' : 'false'; $show_progress_bar = $this->getConf('show_progress_bar') ? 'true' : 'false'; $size = explode("x", $this->getConf('size')); $auto_slide = $this->getConf('auto_slide'); $loop = $this->getConf('loop') ? 'true' : 'false'; $this->doc .= '
'; } /** * Creates a slide container (section), possibly containing nested slides (sections) */ function open_slide_container () { $this->close_slide_container(); $this->doc .= '
'.DOKU_LF; $this->column_open = true; } /** * Creates a slide (section) */ function open_slide () { $this->close_slide(); $this->doc .= ' next_slide_background_color) { $this->doc .= ' data-background-color="'.$this->next_slide_background_color.'"'; $this->next_slide_background_color = ''; } if ($this->next_slide_background_image) { $this->doc .= ' data-background-image="'.$this->next_slide_background_image.'"'; $this->next_slide_background_image = ''; } if ($this->next_slide_background_size) { $this->doc .= ' data-background-size="'.$this->next_slide_background_size.'"'; $this->next_slide_background_size = ''; } if ($this->next_slide_background_position) { $this->doc .= ' data-background-position="'.$this->next_slide_background_position.'"'; $this->next_slide_background_position = ''; } $data['background_position']; if ($this->next_slide_background_repeat) { $this->doc .= ' data-background-repeat="'.$this->next_slide_background_repeat.'"'; $this->next_slide_background_repeat = ''; } if ($this->next_slide_background_transition) { $this->doc .= ' data-background-transition="'.$this->next_slide_background_transition.'"'; $this->next_slide_background_transition = ''; } if ($this->next_slide_transition) { $this->doc .= ' data-transition="'.$this->next_slide_transition.'"'; $this->next_slide_transition = ''; } if ($this->next_slide_transition_speed) { $this->doc .= ' data-transition-speed="'.$this->next_slide_transition_speed.'"'; $this->next_slide_transition_speed = ''; } if ($this->next_slide_no_footer) { $this->doc .= ' data-state="no-footer"'; $this->next_slide_no_footer = false; } $this->doc .= '>'.DOKU_LF; // mark slide as open $this->slide_open = true; } /** * Closes a slide container (section) */ function close_slide_container () { $this->close_slide(); if ($this->column_open) { $this->doc .= '
'.DOKU_LF; $this->column_open = false; } } /** * Closes a slide (section) */ function close_slide () { if ($this->slide_open) { $this->doc .= ' '.DOKU_LF; $this->slide_open = false; } } /** * DokuWiki sections are not used on a slideshow - so we redeclare it here only */ function section_open($level) {} function section_close() {} /** * Throw away footnote */ function footnote_close() { // recover footnote into the stack and restore old content $footnote = $this->doc; $this->doc = $this->store; $this->store = ''; } /** * No acronyms in a presentation */ function acronym($acronym){ $this->doc .= $this->_xmlEntities($acronym); } /** * Start a table * * @param int $maxcols maximum number of columns * @param int $numrows NOT IMPLEMENTED * @param int $pos byte position in the original source */ function table_open($maxcols = null, $numrows = null, $pos = null, $classes = NULL) { // initialize the row counter used for classes $this->_counter['row_counter'] = 0; $class = 'table'; if($pos !== null) { $sectionEditStartData = ['target' => 'table']; if (!defined('SEC_EDIT_PATTERN')) { // backwards-compatibility for Frusterick Manners (2017-02-19) $sectionEditStartData = 'table'; } $class .= ' '.$this->startSectionEdit($pos, $sectionEditStartData); } $this->doc .= ''. DOKU_LF; } /** * Close a table * * @param int $pos byte position in the original source */ function table_close($pos = null) { $this->doc .= '
'.DOKU_LF; } /** * Open a table header */ function tablethead_open() { $this->doc .= DOKU_TAB.''.DOKU_LF; } /** * Close a table header */ function tablethead_close() { $this->doc .= DOKU_TAB.''.DOKU_LF; } /** * Open a table row */ function tablerow_open($classes = NULL) { $this->doc .= DOKU_TAB.''.DOKU_LF.DOKU_TAB.DOKU_TAB; } /** * Close a table row */ function tablerow_close() { $this->doc .= DOKU_LF.DOKU_TAB.''.DOKU_LF; } /** * Open a table header cell * * @param int $colspan * @param string $align left|center|right * @param int $rowspan */ function tableheader_open($colspan = 1, $align = null, $rowspan = 1, $classes = NULL) { $class = 'class="col'.$this->_counter['cell_counter']++; if(!is_null($align)) { $class .= ' '.$align.'align'; } $class .= '"'; $this->doc .= ' 1) { $this->_counter['cell_counter'] += $colspan - 1; $this->doc .= ' colspan="'.$colspan.'"'; } if($rowspan > 1) { $this->doc .= ' rowspan="'.$rowspan.'"'; } $this->doc .= '>'; } /** * Close a table header cell */ function tableheader_close() { $this->doc .= ''; } /** * Open a table cell * * @param int $colspan * @param string $align left|center|right * @param int $rowspan */ function tablecell_open($colspan = 1, $align = null, $rowspan = 1, $classes = NULL) { $class = 'class="col'.$this->_counter['cell_counter']++; if(!is_null($align)) { $class .= ' '.$align.'align'; } $class .= '"'; $this->doc .= ' 1) { $this->_counter['cell_counter'] += $colspan - 1; $this->doc .= ' colspan="'.$colspan.'"'; } if($rowspan > 1) { $this->doc .= ' rowspan="'.$rowspan.'"'; } $this->doc .= '>'; } /** * Close a table cell */ function tablecell_close() { $this->doc .= ''; } /** * Open a list item * * @param int $level the nesting level * * Default: build list item per item. * This is called "fragment" in reveal.js */ function listitem_open($level, $node=false) { if( !$this->notes_open && !$this->no_fragment_list_open && ($this->getConf('build_all_lists') || $this->fragment_list_open) ) { $this->doc .= '
  • '; } else { $this->doc .= '
  • '; } } /** * Start a block quote */ function quote_open() { if (!$this->quote_open) { $this->doc .= '
    “'; $this->quote_open = true; } } /** * Stop a block quote */ function quote_close() { if ($this->quote_open) { $this->doc .= '”
    '.DOKU_LF; $this->quote_open = false; } } /** * Don't use Geshi. Overwrite the Geshi function. * @author Emmanuel Klinger * @author Andreas Gohr * @param string $type code|file * @param string $text text to show * @param string $language programming language to use for syntax highlighting * @param string $filename file path label * @param string $options highlight options - not used */ function _highlight($type, $text, $language = null, $filename = null, $options = null) { global $ID; global $lang; if($filename) { // add icon list($ext) = mimetype($filename, false); $class = preg_replace('/[^_\-a-z0-9]+/i', '_', $ext); $class = 'mediafile mf_'.$class; $this->doc .= '
    '.DOKU_LF; $this->doc .= '
    '; $this->doc .= hsc($filename); $this->doc .= '
    '.DOKU_LF.'
    '; } if($text{0} == "\n") { $text = substr($text, 1); } if(substr($text, -1) == "\n") { $text = substr($text, 0, -1); } if(is_null($language)) { //@author Emmanuel: This line is changed from the original $this->doc .= '
    '.$this->_xmlEntities($text).'
    '.DOKU_LF; } else { //@author Emmanuel: This line is changed from the original $this->doc .= '
    '.$this->_xmlEntities($text).'
    '.DOKU_LF; } if($filename) { $this->doc .= '
    '.DOKU_LF; } $this->_codeblock++; } }