1<?php 2/** 3 * DokuWiki plugin Diagram, Splitter component. 4 * 5 * This is a helper for Main component. 6 * The purpose is to describe, how diagram specification should be parsed in conjunction with other lexer modes. 7 * Component also provides simple match handling. 8 * Splitter can't be used without Main because we need to move wiki calls for abbreviations from their places to boxes. 9 * 10 * Should work with any DokuWiki version >= 20070626. 11 * Tested with DokuWiki versions 20090214, 20091225, 20110525a, 20121013, 20130510a, 12 * 20131208, 20140505e, 20140929d, 20150810a, 20160626e, 20170219e, 20180422a, 20200729. 13 * 14 * Install to lib/plugins/diagram/syntax/splitter.php. 15 * 16 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 17 * @author Nikita Melnichenko [http://nikita.melnichenko.name] 18 * @copyright Copyright 2007-2021, Nikita Melnichenko 19 */ 20 21// includes 22if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 23if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 24require_once(DOKU_PLUGIN.'syntax.php'); 25 26/** 27 * DokuWiki plugin Diagram, Splitter component. 28 * 29 * Parses diagram content to get proper wiki calls for abbreviations. 30 */ 31class syntax_plugin_diagram_splitter extends DokuWiki_Syntax_Plugin 32{ 33 /** 34 * Tag name in wiki text. 35 * 36 * @staticvar string 37 */ 38 var $tag_name = '_diagram_'; 39 40 /** 41 * Get syntax type. 42 * 43 * @return string one of the mode types defined in $PARSER_MODES in parser.php 44 */ 45 function getType () 46 { 47 // containers are complex modes that can contain many other modes 48 // plugin generates table, so type should be container 49 return 'container'; 50 } 51 52 /** 53 * Get paragraph type. 54 * 55 * Defines how this syntax is handled regarding paragraphs. This is important 56 * for correct XHTML nesting. Should return one of the following: 57 * - 'normal' - The plugin can be used inside paragraphs 58 * - 'block' - Open paragraphs need to be closed before plugin output 59 * - 'stack' - Special case. Plugin wraps other paragraphs. 60 * 61 * @return string 62 */ 63 function getPType () 64 { 65 // table cannot be put inside paragraphs 66 return 'block'; 67 } 68 69 /** 70 * Get position of plugin's mode in decision list. 71 * 72 * @return integer 73 */ 74 function getSort () 75 { 76 // before Doku_Parser_Mode_table 77 return 55; 78 } 79 80 /** 81 * Get allowed mode types. 82 * 83 * Defines the mode types for other dokuwiki markup that maybe nested within the 84 * plugin's own markup. Needs to return an array of one or more of the mode types 85 * defined in $PARSER_MODES in parser.php 86 * 87 * @return array 88 */ 89 function getAllowedTypes() 90 { 91 return array( 92 'container', 93 'substition', 94 'protected', 95 'disabled', 96 'formatting' 97 ); 98 } 99 100 /** 101 * Connect pattern to lexer. 102 * 103 * @param string $mode 104 */ 105 function connectTo ($mode) 106 { 107 $this->Lexer->addEntryPattern('<'.$this->tag_name.'>', 108 $mode, 'plugin_diagram_splitter'); 109 } 110 111 /** 112 * Connect pattern to lexer (after connectTo). 113 */ 114 function postConnect () 115 { 116 $this->Lexer->addPattern('\n', 117 'plugin_diagram_splitter'); 118 $this->Lexer->addPattern('\|[A-Za-z0-9_]+=', 119 'plugin_diagram_splitter'); 120 $this->Lexer->addPattern('\|[A-Za-z0-9_]+\{[^{}]*\}=', 121 'plugin_diagram_splitter'); 122 $this->Lexer->addPattern('\|[^|=\n]*', 123 'plugin_diagram_splitter'); 124 $this->Lexer->addExitPattern('</'.$this->tag_name.'>', 125 'plugin_diagram_splitter'); 126 } 127 128 /** 129 * Handle the match. 130 * 131 * @param string $match 132 * @param integer $state one of lexer states defined in lexer.php 133 * @param integer $pos position of first 134 * @param Doku_Handler $handler 135 * @return array data for rendering 136 */ 137 function handle ($match, $state, $pos, Doku_Handler $handler) 138 { 139 $res = array(); 140 if ($state == DOKU_LEXER_MATCHED) 141 { 142 if ($match == "\n") 143 $res['type'] = 'newline'; 144 elseif ($match[strlen($match) - 1] == '=') 145 { 146 $res['type'] = 'abbr eval'; 147 // delete first '|', last '=' and whitespase 148 $abbr_and_params = trim(substr($match, 1, -1)); 149 if (preg_match ('/([A-Za-z0-9_]+)\{([^{}]*)\}/', $abbr_and_params, $regs)) 150 { 151 $res['abbr'] = $regs[1]; 152 $res['params'] = $regs[2]; 153 } 154 else 155 $res['abbr'] = $abbr_and_params; 156 } 157 else 158 { 159 $res['type'] = 'command'; 160 // delete first '|' and whitespase 161 $res['command'] = trim(substr($match, 1)); 162 } 163 } 164 if ($state == DOKU_LEXER_UNMATCHED) 165 $res['text'] = $match; 166 return $res; 167 } 168 169 /** 170 * Splitter does not create XHTML text, see Main component. 171 * The function is required after 2020-07-29 "Hogfather" update. 172 * 173 * @param string $mode render mode; only 'xhtml' supported 174 * @param Doku_Renderer $renderer 175 * @param array $data data from handler 176 * @return bool 177 */ 178 function render ($mode, Doku_Renderer $renderer, $data) 179 { 180 return true; 181 } 182} 183