1<?php 2/** 3 * Div Syntax Component of the Wrap Plugin 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Anika Henke <anika@selfthinker.org> 7 */ 8 9if(!defined('DOKU_INC')) die(); 10 11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 12require_once(DOKU_PLUGIN.'syntax.php'); 13 14class syntax_plugin_wrap_div extends DokuWiki_Syntax_Plugin { 15 protected $special_pattern = '<div\b[^>\r\n]*?/>'; 16 protected $entry_pattern = '<div\b.*?>(?=.*?</div>)'; 17 protected $exit_pattern = '</div>'; 18 19 function getType(){ return 'formatting';} 20 function getAllowedTypes() { return array('container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs'); } 21 function getPType(){ return 'stack';} 22 function getSort(){ return 195; } 23 // override default accepts() method to allow nesting - ie, to get the plugin accepts its own entry syntax 24 function accepts($mode) { 25 if ($mode == substr(get_class($this), 7)) return true; 26 return parent::accepts($mode); 27 } 28 29 /** 30 * Connect pattern to lexer 31 */ 32 function connectTo($mode) { 33 $this->Lexer->addSpecialPattern($this->special_pattern,$mode,'plugin_wrap_'.$this->getPluginComponent()); 34 $this->Lexer->addEntryPattern($this->entry_pattern,$mode,'plugin_wrap_'.$this->getPluginComponent()); 35 } 36 37 function postConnect() { 38 $this->Lexer->addExitPattern($this->exit_pattern, 'plugin_wrap_'.$this->getPluginComponent()); 39 $this->Lexer->addPattern('[ \t]*={2,}[^\n]+={2,}[ \t]*(?=\n)', 'plugin_wrap_'.$this->getPluginComponent()); 40 } 41 42 /** 43 * Handle the match 44 */ 45 function handle($match, $state, $pos, Doku_Handler $handler){ 46 global $conf; 47 switch ($state) { 48 case DOKU_LEXER_ENTER: 49 case DOKU_LEXER_SPECIAL: 50 $data = strtolower(trim(substr($match,strpos($match,' '),-1)," \t\n/")); 51 return array($state, $data); 52 53 case DOKU_LEXER_UNMATCHED: 54 $handler->_addCall('cdata', array($match), $pos); 55 break; 56 57 case DOKU_LEXER_MATCHED: 58 // we have a == header ==, use the core header() renderer 59 // (copied from core header() in inc/parser/handler.php) 60 $title = trim($match); 61 $level = 7 - strspn($title,'='); 62 if($level < 1) $level = 1; 63 $title = trim($title,'='); 64 $title = trim($title); 65 66 $handler->_addCall('header',array($title,$level,$pos), $pos); 67 // close the section edit the header could open 68 if ($title && $level <= $conf['maxseclevel']) { 69 $handler->addPluginCall('wrap_closesection', array(), DOKU_LEXER_SPECIAL, $pos, ''); 70 } 71 break; 72 73 case DOKU_LEXER_EXIT: 74 return array($state, ''); 75 } 76 return false; 77 } 78 79 /** 80 * Create output 81 */ 82 function render($mode, Doku_Renderer $renderer, $indata) { 83 static $type_stack = array (); 84 85 if (empty($indata)) return false; 86 list($state, $data) = $indata; 87 88 if($mode == 'xhtml'){ 89 /** @var Doku_Renderer_xhtml $renderer */ 90 switch ($state) { 91 case DOKU_LEXER_ENTER: 92 $sectionEditStartData = ['target' => 'plugin_wrap_start']; 93 $sectionEditEndData = ['target' => 'plugin_wrap_end']; 94 if (!defined('SEC_EDIT_PATTERN')) { 95 // backwards-compatibility for Frusterick Manners (2017-02-19) 96 $sectionEditStartData = 'plugin_wrap_start'; 97 $sectionEditEndData = 'plugin_wrap_end'; 98 } 99 // add a section edit right at the beginning of the wrap output 100 $renderer->startSectionEdit(0, $sectionEditStartData); 101 $renderer->finishSectionEdit(); 102 // add a section edit for the end of the wrap output. This prevents the renderer 103 // from closing the last section edit so the next section button after the wrap syntax will 104 // include the whole wrap syntax 105 $renderer->startSectionEdit(0, $sectionEditEndData); 106 107 case DOKU_LEXER_SPECIAL: 108 $wrap = $this->loadHelper('wrap'); 109 $attr = $wrap->buildAttributes($data, 'plugin_wrap'); 110 111 $renderer->doc .= '<div'.$attr.'>'; 112 if ($state == DOKU_LEXER_SPECIAL) $renderer->doc .= '</div>'; 113 break; 114 115 case DOKU_LEXER_EXIT: 116 $renderer->doc .= '</div>'; 117 $renderer->finishSectionEdit(); 118 break; 119 } 120 return true; 121 } 122 if($mode == 'odt'){ 123 switch ($state) { 124 case DOKU_LEXER_ENTER: 125 $wrap = plugin_load('helper', 'wrap'); 126 array_push ($type_stack, $wrap->renderODTElementOpen($renderer, 'div', $data)); 127 break; 128 129 case DOKU_LEXER_EXIT: 130 $element = array_pop ($type_stack); 131 $wrap = plugin_load('helper', 'wrap'); 132 $wrap->renderODTElementClose ($renderer, $element); 133 break; 134 } 135 return true; 136 } 137 return false; 138 } 139} 140