1<?php 2 3 4// must be run within Dokuwiki 5use ComboStrap\CallStack; 6use ComboStrap\Dimension; 7use ComboStrap\PluginUtility; 8use ComboStrap\TagAttributes; 9use ComboStrap\XmlTagProcessing; 10 11require_once(__DIR__ . '/../vendor/autoload.php'); 12 13/** 14 * Class syntax_plugin_combo_text 15 * A text block that permits to style 16 * paragraph at once 17 * 18 * The output will be a series of {@link syntax_plugin_combo_para paragraph} 19 * with the same properties 20 * 21 * It permits to have several paragraph 22 */ 23class syntax_plugin_combo_text extends DokuWiki_Syntax_Plugin 24{ 25 26 const TAG = "text"; 27 const TAGS = ["typo", self::TAG]; 28 29 /** 30 * Syntax Type. 31 * 32 * Needs to return one of the mode types defined in {@link $PARSER_MODES} in parser.php 33 * @see DokuWiki_Syntax_Plugin::getType() 34 */ 35 function getType(): string 36 { 37 return 'paragraphs'; 38 } 39 40 /** 41 * How Dokuwiki will add P element 42 * 43 * * 'normal' - The plugin can be used inside paragraphs 44 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 45 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 46 * 47 * @see DokuWiki_Syntax_Plugin::getPType() 48 */ 49 function getPType(): string 50 { 51 return 'stack'; 52 } 53 54 /** 55 * @return array 56 * Allow which kind of plugin inside 57 * 58 * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 59 * because we manage self the content and we call self the parser 60 * 61 * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php 62 */ 63 function getAllowedTypes(): array 64 { 65 return array('formatting', 'substition', 'paragraphs'); 66 } 67 68 public function accepts($mode): bool 69 { 70 71 return syntax_plugin_combo_preformatted::disablePreformatted($mode); 72 73 } 74 75 76 function getSort(): int 77 { 78 /** 79 * Less than {@link syntax_plugin_typography_base} 80 */ 81 return 65; 82 } 83 84 85 function connectTo($mode) 86 { 87 88 foreach (self::TAGS as $tag) { 89 $pattern = XmlTagProcessing::getContainerTagPattern($tag); 90 $this->Lexer->addEntryPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 91 } 92 } 93 94 95 function postConnect() 96 { 97 foreach (self::TAGS as $tag) { 98 $this->Lexer->addExitPattern('</' . $tag . '>', PluginUtility::getModeFromTag($this->getPluginComponent())); 99 } 100 101 } 102 103 function handle($match, $state, $pos, Doku_Handler $handler) 104 { 105 106 switch ($state) { 107 108 case DOKU_LEXER_ENTER : 109 110 $attributes = TagAttributes::createFromTagMatch($match,[],[],true); 111 $callStackArray = $attributes->toCallStackArray(); 112 113 return array( 114 PluginUtility::STATE => $state, 115 PluginUtility::ATTRIBUTES => $callStackArray 116 ); 117 118 case DOKU_LEXER_UNMATCHED : 119 return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler); 120 121 case DOKU_LEXER_EXIT : 122 /** 123 * Transform all paragraphs 124 * with the type as class 125 */ 126 $callStack = CallStack::createFromHandler($handler); 127 $openingCall = $callStack->moveToPreviousCorrespondingOpeningCall(); 128 $attributes = $openingCall->getAttributes(); 129 // if there is no EOL, we add one to create at minimal a paragraph 130 $callStack->insertEolIfNextCallIsNotEolOrBlock(); 131 $callStack->processEolToEndStack($attributes); 132 133 /** 134 * Check and add a scroll toggle if the 135 * text is constrained by height 136 */ 137 Dimension::addScrollToggleOnClickIfNoControl($callStack); 138 139 return array(PluginUtility::STATE => $state); 140 141 142 } 143 return array(); 144 145 } 146 147 /** 148 * Render the output 149 * @param string $format 150 * @param Doku_Renderer $renderer 151 * @param array $data - what the function handle() return'ed 152 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 153 * @see DokuWiki_Syntax_Plugin::render() 154 * 155 * 156 */ 157 function render($format, Doku_Renderer $renderer, $data): bool 158 { 159 if ($format == 'xhtml') { 160 161 /** @var Doku_Renderer_xhtml $renderer */ 162 $state = $data[PluginUtility::STATE]; 163 switch ($state) { 164 case DOKU_LEXER_EXIT : 165 case DOKU_LEXER_ENTER : 166 /** 167 * The {@link DOKU_LEXER_EXIT} of the {@link syntax_plugin_combo_text::handle()} 168 * has already created in the callstack the {@link syntax_plugin_combo_para} call 169 */ 170 $renderer->doc .= ""; 171 break; 172 case DOKU_LEXER_UNMATCHED : 173 $renderer->doc .= PluginUtility::renderUnmatched($data); 174 break; 175 } 176 return true; 177 } 178 179 // unsupported $mode 180 return false; 181 } 182 183 184} 185 186