1<?php 2/** 3 * DokuWiki Plugin flowcharts (Syntax Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Jakob Schwichtenberg <mail@jakobschwichtenberg.com> 7 */ 8 9use dokuwiki\Parsing\Parser; 10 11// must be run within Dokuwiki 12if (!defined('DOKU_INC')) { 13 die(); 14} 15/** 16* if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/'); 17* if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 18* require_once(DOKU_PLUGIN.'syntax.php'); 19*/ 20 21class syntax_plugin_flowcharts extends DokuWiki_Syntax_Plugin 22{ 23 function getType(){ return 'protected'; } 24 25 // must return a number lower than returned by native 'code' mode (200) 26 function getSort(){ return 158; } 27 28 /** 29 * Connect lookup pattern to lexer. 30 * 31 * @param string $mode Parser mode 32 */ 33 function connectTo($mode) { 34 $this->Lexer->addEntryPattern('<flow>(?=.*?</flow>)',$mode,'plugin_flowcharts'); 35 } 36 function postConnect() { 37 $this->Lexer->addExitPattern('</flow>','plugin_flowcharts'); 38 } 39 40 41 /** 42 * Handle matches of the flowcharts syntax 43 */ 44 function handle($match, $state, $pos, Doku_Handler $handler){ 45 switch ($state) { 46 case DOKU_LEXER_ENTER: 47 return array($state, ''); 48 49 case DOKU_LEXER_UNMATCHED : 50 return array($state, $match); 51 52 case DOKU_LEXER_EXIT : 53 return array($state, ''); 54 55 } 56 return false; 57 } 58 59 60 /** 61 * Render xhtml output or metadata 62 */ 63 function render($mode, Doku_Renderer $renderer, $indata) { 64 if($mode == 'xhtml'){ 65 list($state, $match) = $indata; 66 switch ($state) { 67 68 case DOKU_LEXER_ENTER : 69 // securityLevel loose allows more advanced functionality such as subgraphs to run. 70 // @todo: this should be an option in the interface. 71 $renderer->doc .= '<div class="mermaid">'; 72 break; 73 case DOKU_LEXER_UNMATCHED : 74 $instructions = $this->p_get_instructions($match); 75 $xhtml = $this->p_render($instructions); 76 $renderer->doc .= $xhtml; 77 break; 78 case DOKU_LEXER_EXIT : 79 $renderer->doc .= "</div>"; 80 break; 81 } 82 return true; 83 } 84 return false; 85 } 86 87 /* 88 * Get the parser instructions siutable for the mermaid 89 * 90 */ 91 function p_get_instructions($text) { 92 93 $modes = array(); 94 95 // add default modes 96 $std_modes = array('internallink', 'media','externallink'); 97 98 foreach($std_modes as $m){ 99 $class = 'dokuwiki\\Parsing\\ParserMode\\'.ucfirst($m); 100 $obj = new $class(); 101 $modes[] = array( 102 'sort' => $obj->getSort(), 103 'mode' => $m, 104 'obj' => $obj 105 ); 106 } 107 108 // add formatting modes 109 $fmt_modes = array('strong','emphasis','underline','monospace', 110 'subscript','superscript','deleted'); 111 foreach($fmt_modes as $m){ 112 $obj = new \dokuwiki\Parsing\ParserMode\Formatting($m); 113 $modes[] = array( 114 'sort' => $obj->getSort(), 115 'mode' => $m, 116 'obj' => $obj 117 ); 118 } 119 120 // Create the parser and handler 121 $Parser = new Parser(new Doku_Handler()); 122 123 //add modes to parser 124 foreach($modes as $mode){ 125 $Parser->addMode($mode['mode'],$mode['obj']); 126 } 127 128 // Do the parsing 129 $p = $Parser->parse($text); 130 131 return $p; 132 } 133 134 public function p_render($instructions) { 135 $Renderer = p_get_renderer('flowcharts'); 136 137 $Renderer->smileys = getSmileys(); 138 $Renderer->entities = getEntities(); 139 $Renderer->acronyms = getAcronyms(); 140 $Renderer->interwiki = getInterwiki(); 141 142 // Loop through the instructions 143 foreach ($instructions as $instruction) { 144 // Execute the callback against the Renderer 145 if(method_exists($Renderer, $instruction[0])){ 146 call_user_func_array(array(&$Renderer, $instruction[0]), $instruction[1] ? $instruction[1] : array()); 147 } 148 } 149 150 return $Renderer->doc; 151 } 152 153} 154 155