137748cd8SNickeau<?php 237748cd8SNickeau/** 337748cd8SNickeau * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 437748cd8SNickeau * 537748cd8SNickeau * This source code is licensed under the GPL license found in the 637748cd8SNickeau * COPYING file in the root directory of this source tree. 737748cd8SNickeau * 837748cd8SNickeau * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 937748cd8SNickeau * @author ComboStrap <support@combostrap.com> 1037748cd8SNickeau * 1137748cd8SNickeau */ 1237748cd8SNickeau 1337748cd8SNickeaunamespace ComboStrap; 1437748cd8SNickeau 1537748cd8SNickeauuse dokuwiki\Extension\SyntaxPlugin; 161fa8c418SNickeauuse syntax_plugin_combo_media; 1737748cd8SNickeau 1837748cd8SNickeau 1937748cd8SNickeau/** 2037748cd8SNickeau * Class Call 2137748cd8SNickeau * @package ComboStrap 2237748cd8SNickeau * 2337748cd8SNickeau * A wrapper around what's called a call 2437748cd8SNickeau * which is an array of information such 2537748cd8SNickeau * the mode, the data 2637748cd8SNickeau * 2737748cd8SNickeau * The {@link CallStack} is the only syntax representation that 2837748cd8SNickeau * is available in DokuWiki 2937748cd8SNickeau */ 3037748cd8SNickeauclass Call 3137748cd8SNickeau{ 3237748cd8SNickeau 3337748cd8SNickeau const INLINE_DISPLAY = "inline"; 3437748cd8SNickeau const BlOCK_DISPLAY = "block"; 3537748cd8SNickeau /** 3637748cd8SNickeau * List of inline components 3737748cd8SNickeau * Used to manage white space before an unmatched string. 3837748cd8SNickeau * The syntax tree of Dokuwiki (ie {@link \Doku_Handler::$calls}) 3937748cd8SNickeau * has only data and no class, for now, we create this 4037748cd8SNickeau * lists manually because this is a hassle to retrieve this information from {@link \DokuWiki_Syntax_Plugin::getType()} 4137748cd8SNickeau */ 4237748cd8SNickeau const INLINE_DOKUWIKI_COMPONENTS = array( 4337748cd8SNickeau /** 4437748cd8SNickeau * Formatting https://www.dokuwiki.org/devel:syntax_plugins#syntax_types 4537748cd8SNickeau * Comes from the {@link \dokuwiki\Parsing\ParserMode\Formatting} class 4637748cd8SNickeau */ 4737748cd8SNickeau "cdata", 4837748cd8SNickeau "unformatted", // ie %% or nowiki 4937748cd8SNickeau "doublequoteclosing", // https://www.dokuwiki.org/config:typography / https://www.dokuwiki.org/wiki:syntax#text_to_html_conversions 5037748cd8SNickeau "doublequoteopening", 5137748cd8SNickeau "singlequoteopening", 5237748cd8SNickeau "singlequoteclosing", 5304fd306cSNickeau "quote_open", 5404fd306cSNickeau "quote_close", 5504fd306cSNickeau "interwikilink", 5637748cd8SNickeau "multiplyentity", 5737748cd8SNickeau "apostrophe", 5804fd306cSNickeau "deleted_open", 5904fd306cSNickeau "deleted_close", 6004fd306cSNickeau "emaillink", 6137748cd8SNickeau "strong", 6237748cd8SNickeau "emphasis", 6337748cd8SNickeau "emphasis_open", 6437748cd8SNickeau "emphasis_close", 6537748cd8SNickeau "underline", 66e4026cd1Sgerardnico "underline_close", 6704fd306cSNickeau "underline_open", 6837748cd8SNickeau "monospace", 6937748cd8SNickeau "subscript", 7004fd306cSNickeau "subscript_open", 7104fd306cSNickeau "subscript_close", 7204fd306cSNickeau "superscript_open", 7304fd306cSNickeau "superscript_close", 7437748cd8SNickeau "superscript", 7537748cd8SNickeau "deleted", 7637748cd8SNickeau "footnote", 7737748cd8SNickeau /** 7837748cd8SNickeau * Others 7937748cd8SNickeau */ 801fa8c418SNickeau "acronym", // abbr 8137748cd8SNickeau "strong_close", 8237748cd8SNickeau "strong_open", 8337748cd8SNickeau "monospace_open", 8437748cd8SNickeau "monospace_close", 8537748cd8SNickeau "doublequoteopening", // ie the character " in "The" 8637748cd8SNickeau "entity", // for instance `...` are transformed in character 8737748cd8SNickeau "linebreak", 8837748cd8SNickeau "externallink", 8937748cd8SNickeau "internallink", 9004fd306cSNickeau "smiley", 9104fd306cSNickeau MediaMarkup::INTERNAL_MEDIA_CALL_NAME, 9204fd306cSNickeau MediaMarkup::EXTERNAL_MEDIA_CALL_NAME, 9337748cd8SNickeau /** 9437748cd8SNickeau * The inline of combo 9537748cd8SNickeau */ 9637748cd8SNickeau \syntax_plugin_combo_link::TAG, 9704fd306cSNickeau IconTag::TAG, 9804fd306cSNickeau NoteTag::TAG_INOTE, 9904fd306cSNickeau ButtonTag::MARKUP_LONG, 10037748cd8SNickeau \syntax_plugin_combo_tooltip::TAG, 10104fd306cSNickeau PipelineTag::TAG, 10204fd306cSNickeau BreadcrumbTag::MARKUP_BLOCK, // only the typo is inline but yeah 10337748cd8SNickeau ); 10437748cd8SNickeau 10537748cd8SNickeau 10637748cd8SNickeau const BLOCK_MARKUP_DOKUWIKI_COMPONENTS = array( 10737748cd8SNickeau "listu_open", // ul 10837748cd8SNickeau "listu_close", 10904fd306cSNickeau "listo_open", 11004fd306cSNickeau "listo_close", 11137748cd8SNickeau "listitem_open", //li 11237748cd8SNickeau "listitem_close", 11337748cd8SNickeau "listcontent_open", // after li ??? 11437748cd8SNickeau "listcontent_close", 11537748cd8SNickeau "table_open", 11637748cd8SNickeau "table_close", 11704fd306cSNickeau "p_open", 11804fd306cSNickeau "p_close", 11904fd306cSNickeau "nest", // seen as enclosing footnotes 12004fd306cSNickeau "hr", 12104fd306cSNickeau "rss" 12204fd306cSNickeau ); 12304fd306cSNickeau 12404fd306cSNickeau /** 12504fd306cSNickeau * Not inline, not block 12604fd306cSNickeau */ 12704fd306cSNickeau const TABLE_MARKUP = array( 12804fd306cSNickeau "tablethead_open", 12904fd306cSNickeau "tablethead_close", 13004fd306cSNickeau "tableheader_open", 13104fd306cSNickeau "tableheader_close", 13204fd306cSNickeau "tablerow_open", 13304fd306cSNickeau "tablerow_close", 13404fd306cSNickeau "tablecell_open", 135*81f56eb9SNicolas GERARD "tablecell_close", 136*81f56eb9SNicolas GERARD "tableheader", 137*81f56eb9SNicolas GERARD "table_align", 138*81f56eb9SNicolas GERARD "table_row", 139*81f56eb9SNicolas GERARD "tablecell", 140*81f56eb9SNicolas GERARD "table_start", 141*81f56eb9SNicolas GERARD "table_end" 14237748cd8SNickeau ); 14337748cd8SNickeau 1441fa8c418SNickeau /** 1451fa8c418SNickeau * A media is not really an image 1461fa8c418SNickeau * but it may contains one 1471fa8c418SNickeau */ 1481fa8c418SNickeau const IMAGE_TAGS = [ 1491fa8c418SNickeau syntax_plugin_combo_media::TAG, 15004fd306cSNickeau PageImageTag::MARKUP 1511fa8c418SNickeau ]; 1524cadd4f8SNickeau const CANONICAL = "call"; 15304fd306cSNickeau const TABLE_DISPLAY = "table-display"; 1541fa8c418SNickeau 15537748cd8SNickeau private $call; 15637748cd8SNickeau 15737748cd8SNickeau /** 15837748cd8SNickeau * The key identifier in the {@link CallStack} 15937748cd8SNickeau * @var mixed|string 16037748cd8SNickeau */ 16137748cd8SNickeau private $key; 16237748cd8SNickeau 16337748cd8SNickeau /** 16437748cd8SNickeau * Call constructor. 16537748cd8SNickeau * @param $call - the instruction array (ie called a call) 16637748cd8SNickeau */ 16737748cd8SNickeau public function __construct(&$call, $key = "") 16837748cd8SNickeau { 16937748cd8SNickeau $this->call = &$call; 17037748cd8SNickeau $this->key = $key; 17137748cd8SNickeau } 17237748cd8SNickeau 17337748cd8SNickeau /** 17437748cd8SNickeau * Insert a tag above 17537748cd8SNickeau * @param $tagName 17637748cd8SNickeau * @param $state 17704fd306cSNickeau * @param $syntaxComponentName - the name of the dokuwiki syntax component (ie plugin_name) 178c3437056SNickeau * @param array $attribute 1794cadd4f8SNickeau * @param string|null $rawContext 1804cadd4f8SNickeau * @param string|null $content - the parsed content 181c3437056SNickeau * @param string|null $payload - the payload after handler 182c3437056SNickeau * @param int|null $position 18337748cd8SNickeau * @return Call - a call 18437748cd8SNickeau */ 18504fd306cSNickeau public static function createComboCall($tagName, $state, array $attribute = array(), string $rawContext = null, string $content = null, string $payload = null, int $position = null, string $syntaxComponentName = null): Call 18637748cd8SNickeau { 18737748cd8SNickeau $data = array( 18837748cd8SNickeau PluginUtility::ATTRIBUTES => $attribute, 1894cadd4f8SNickeau PluginUtility::CONTEXT => $rawContext, 190c3437056SNickeau PluginUtility::STATE => $state, 19104fd306cSNickeau PluginUtility::TAG => $tagName, 192c3437056SNickeau PluginUtility::POSITION => $position 19337748cd8SNickeau ); 19404fd306cSNickeau if ($payload !== null) { 19537748cd8SNickeau $data[PluginUtility::PAYLOAD] = $payload; 19637748cd8SNickeau } 197c3437056SNickeau $positionInText = $position; 19837748cd8SNickeau 19904fd306cSNickeau if ($syntaxComponentName !== null) { 20004fd306cSNickeau $componentName = PluginUtility::getComponentName($syntaxComponentName); 20104fd306cSNickeau } else { 20204fd306cSNickeau $componentName = PluginUtility::getComponentName($tagName); 20304fd306cSNickeau } 20404fd306cSNickeau $obj = plugin_load('syntax', $componentName); 20504fd306cSNickeau if ($obj === null) { 20604fd306cSNickeau throw new ExceptionRuntimeInternal("The component tag ($componentName) does not exists"); 20704fd306cSNickeau } 20804fd306cSNickeau 20937748cd8SNickeau $call = [ 21037748cd8SNickeau "plugin", 21137748cd8SNickeau array( 21204fd306cSNickeau $componentName, 21337748cd8SNickeau $data, 21437748cd8SNickeau $state, 21537748cd8SNickeau $content 21637748cd8SNickeau ), 21737748cd8SNickeau $positionInText 21837748cd8SNickeau ]; 21937748cd8SNickeau return new Call($call); 22037748cd8SNickeau } 22137748cd8SNickeau 22237748cd8SNickeau /** 22337748cd8SNickeau * Insert a dokuwiki call 22437748cd8SNickeau * @param $callName 22537748cd8SNickeau * @param $array 22637748cd8SNickeau * @param $positionInText 22737748cd8SNickeau * @return Call 22837748cd8SNickeau */ 2294cadd4f8SNickeau public static function createNativeCall($callName, $array = [], $positionInText = null): Call 23037748cd8SNickeau { 23137748cd8SNickeau $call = [ 23237748cd8SNickeau $callName, 23337748cd8SNickeau $array, 23437748cd8SNickeau $positionInText 23537748cd8SNickeau ]; 23637748cd8SNickeau return new Call($call); 23737748cd8SNickeau } 23837748cd8SNickeau 23904fd306cSNickeau public static function createFromInstruction($instruction): Call 24037748cd8SNickeau { 24137748cd8SNickeau return new Call($instruction); 24237748cd8SNickeau } 24337748cd8SNickeau 2444cadd4f8SNickeau /** 2454cadd4f8SNickeau * @param Call $call 2464cadd4f8SNickeau * @return Call 2474cadd4f8SNickeau */ 2484cadd4f8SNickeau public static function createFromCall(Call $call): Call 2494cadd4f8SNickeau { 2504cadd4f8SNickeau return self::createFromInstruction($call->toCallArray()); 2514cadd4f8SNickeau } 2524cadd4f8SNickeau 25337748cd8SNickeau 25437748cd8SNickeau /** 25537748cd8SNickeau * 25637748cd8SNickeau * Return the tag name from a call array 25737748cd8SNickeau * 25837748cd8SNickeau * This is not the logical tag. 25937748cd8SNickeau * This is much more what's called: 26037748cd8SNickeau * * the component name for a plugin 26137748cd8SNickeau * * or the handler name for dokuwiki 26237748cd8SNickeau * 26337748cd8SNickeau * For a plugin, this is equivalent 26437748cd8SNickeau * to the {@link SyntaxPlugin::getPluginComponent()} 26537748cd8SNickeau * 26637748cd8SNickeau * This is not the fully qualified component name: 26737748cd8SNickeau * * with the plugin as prefix such as in {@link Call::getComponentName()} 26837748cd8SNickeau * * or with the `open` and `close` prefix such as `p_close` ... 26937748cd8SNickeau * 27037748cd8SNickeau * @return mixed|string 27137748cd8SNickeau */ 27237748cd8SNickeau public function getTagName() 27337748cd8SNickeau { 27404fd306cSNickeau 27537748cd8SNickeau $mode = $this->call[0]; 27637748cd8SNickeau if ($mode != "plugin") { 27737748cd8SNickeau 27837748cd8SNickeau /** 27937748cd8SNickeau * This is a standard dokuwiki node 28037748cd8SNickeau */ 28137748cd8SNickeau $dokuWikiNodeName = $this->call[0]; 28237748cd8SNickeau 28337748cd8SNickeau /** 28437748cd8SNickeau * The dokwuiki node name has also the open and close notion 28537748cd8SNickeau * We delete this is not in the doc and therefore not logical 28637748cd8SNickeau */ 28737748cd8SNickeau $tagName = str_replace("_close", "", $dokuWikiNodeName); 28804fd306cSNickeau return str_replace("_open", "", $tagName); 28904fd306cSNickeau } 29037748cd8SNickeau 29137748cd8SNickeau /** 29237748cd8SNickeau * This is a plugin node 29337748cd8SNickeau */ 29437748cd8SNickeau $pluginDokuData = $this->call[1]; 29504fd306cSNickeau 29604fd306cSNickeau /** 29704fd306cSNickeau * If the tag is set 29804fd306cSNickeau */ 29904fd306cSNickeau $pluginData = $pluginDokuData[1]; 30004fd306cSNickeau if (isset($pluginData[PluginUtility::TAG])) { 30104fd306cSNickeau return $pluginData[PluginUtility::TAG]; 30204fd306cSNickeau } 30304fd306cSNickeau 30437748cd8SNickeau $component = $pluginDokuData[0]; 30537748cd8SNickeau if (!is_array($component)) { 30637748cd8SNickeau /** 30737748cd8SNickeau * Tag name from class 30837748cd8SNickeau */ 30937748cd8SNickeau $componentNames = explode("_", $component); 31037748cd8SNickeau /** 31137748cd8SNickeau * To take care of 31237748cd8SNickeau * PHP Warning: sizeof(): Parameter must be an array or an object that implements Countable 31337748cd8SNickeau * in lib/plugins/combo/class/Tag.php on line 314 31437748cd8SNickeau */ 31537748cd8SNickeau if (is_array($componentNames)) { 31637748cd8SNickeau $tagName = $componentNames[sizeof($componentNames) - 1]; 31737748cd8SNickeau } else { 31837748cd8SNickeau $tagName = $component; 31937748cd8SNickeau } 32037748cd8SNickeau return $tagName; 32104fd306cSNickeau } 32204fd306cSNickeau 32304fd306cSNickeau // To resolve: explode() expects parameter 2 to be string, array given 32404fd306cSNickeau LogUtility::msg("The call (" . print_r($this->call, true) . ") has an array and not a string as component (" . print_r($component, true) . "). Page: " . MarkupPath::createFromRequestedPage(), LogUtility::LVL_MSG_ERROR); 32504fd306cSNickeau return ""; 32604fd306cSNickeau 32737748cd8SNickeau 32837748cd8SNickeau } 32937748cd8SNickeau 33037748cd8SNickeau 33137748cd8SNickeau /** 33237748cd8SNickeau * The parser state 33337748cd8SNickeau * @return mixed 33437748cd8SNickeau * May be null (example eol, internallink, ...) 33537748cd8SNickeau */ 33604fd306cSNickeau public 33704fd306cSNickeau function getState() 33837748cd8SNickeau { 33937748cd8SNickeau $mode = $this->call[0]; 3404cadd4f8SNickeau if ($mode !== "plugin") { 34137748cd8SNickeau 34237748cd8SNickeau /** 34337748cd8SNickeau * There is no state because this is a standard 34437748cd8SNickeau * dokuwiki syntax found in {@link \Doku_Renderer_xhtml} 34537748cd8SNickeau * check if this is not a `...._close` or `...._open` 34637748cd8SNickeau * to derive the state 34737748cd8SNickeau */ 34837748cd8SNickeau $mode = $this->call[0]; 34937748cd8SNickeau $lastPositionSepName = strrpos($mode, "_"); 35037748cd8SNickeau $closeOrOpen = substr($mode, $lastPositionSepName + 1); 35137748cd8SNickeau switch ($closeOrOpen) { 35237748cd8SNickeau case "open": 35337748cd8SNickeau return DOKU_LEXER_ENTER; 35437748cd8SNickeau case "close": 35537748cd8SNickeau return DOKU_LEXER_EXIT; 35637748cd8SNickeau default: 35704fd306cSNickeau /** 35804fd306cSNickeau * Let op null, is used 35904fd306cSNickeau * in {@link CallStack::processEolToEndStack()} 36004fd306cSNickeau * and things can break 36104fd306cSNickeau */ 36237748cd8SNickeau return null; 36337748cd8SNickeau } 36437748cd8SNickeau 36537748cd8SNickeau } else { 36637748cd8SNickeau // Plugin 36737748cd8SNickeau $returnedArray = $this->call[1]; 36837748cd8SNickeau if (array_key_exists(2, $returnedArray)) { 36937748cd8SNickeau return $returnedArray[2]; 37037748cd8SNickeau } else { 37137748cd8SNickeau return null; 37237748cd8SNickeau } 37337748cd8SNickeau } 37437748cd8SNickeau } 37537748cd8SNickeau 37637748cd8SNickeau /** 37737748cd8SNickeau * @return mixed the data returned from the {@link DokuWiki_Syntax_Plugin::handle} (ie attributes, payload, ...) 378040d4aeaSgerardnico * It may be any type. Array, scalar 37937748cd8SNickeau */ 38004fd306cSNickeau public 38104fd306cSNickeau function &getPluginData($attribute = null) 38237748cd8SNickeau { 3834cadd4f8SNickeau $data = &$this->call[1][1]; 3844cadd4f8SNickeau if ($attribute === null) { 3854cadd4f8SNickeau return $data; 3864cadd4f8SNickeau } 3874cadd4f8SNickeau return $data[$attribute]; 3884cadd4f8SNickeau 38937748cd8SNickeau } 39037748cd8SNickeau 39137748cd8SNickeau /** 39237748cd8SNickeau * @return mixed the matched content from the {@link DokuWiki_Syntax_Plugin::handle} 39337748cd8SNickeau */ 39404fd306cSNickeau public 39504fd306cSNickeau function getCapturedContent() 39637748cd8SNickeau { 39737748cd8SNickeau $caller = $this->call[0]; 39837748cd8SNickeau switch ($caller) { 39937748cd8SNickeau case "plugin": 40037748cd8SNickeau return $this->call[1][3]; 40137748cd8SNickeau case "internallink": 40237748cd8SNickeau return '[[' . $this->call[1][0] . '|' . $this->call[1][1] . ']]'; 40337748cd8SNickeau case "eol": 40437748cd8SNickeau return DOKU_LF; 40537748cd8SNickeau case "header": 40637748cd8SNickeau case "cdata": 40737748cd8SNickeau return $this->call[1][0]; 40837748cd8SNickeau default: 40937748cd8SNickeau if (isset($this->call[1][0]) && is_string($this->call[1][0])) { 41037748cd8SNickeau return $this->call[1][0]; 41137748cd8SNickeau } else { 41237748cd8SNickeau return ""; 41337748cd8SNickeau } 41437748cd8SNickeau } 41537748cd8SNickeau } 41637748cd8SNickeau 41737748cd8SNickeau 41804fd306cSNickeau /** 419040d4aeaSgerardnico * Return the attributes of a call 42004fd306cSNickeau */ 42104fd306cSNickeau public 422040d4aeaSgerardnico function &getAttributes(): array 42337748cd8SNickeau { 42437748cd8SNickeau 42504fd306cSNickeau $isPluginCall = $this->isPluginCall(); 42604fd306cSNickeau if (!$isPluginCall) { 42737748cd8SNickeau return $this->call[1]; 428040d4aeaSgerardnico } 429040d4aeaSgerardnico 43004fd306cSNickeau $data = &$this->getPluginData(); 43104fd306cSNickeau if (!is_array($data)) { 43204fd306cSNickeau LogUtility::error("The handle data is not an array for the call ($this), correct the returned data from the handle syntax plugin function", self::CANONICAL); 433040d4aeaSgerardnico // We discard, it may be a third party plugin 434040d4aeaSgerardnico // The log will throw an error if it's on our hand 43504fd306cSNickeau $data = []; 43604fd306cSNickeau return $data; 4374cadd4f8SNickeau } 43804fd306cSNickeau if (!isset($data[PluginUtility::ATTRIBUTES])) { 43904fd306cSNickeau $data[PluginUtility::ATTRIBUTES] = []; 44004fd306cSNickeau } 44104fd306cSNickeau $attributes = &$data[PluginUtility::ATTRIBUTES]; 44204fd306cSNickeau if (!is_array($attributes)) { 44304fd306cSNickeau $message = "The attributes value are not an array for the call ($this), the value was wrapped in an array"; 44404fd306cSNickeau LogUtility::error($message, self::CANONICAL); 44504fd306cSNickeau $attributes = [$attributes]; 4464cadd4f8SNickeau } 4474cadd4f8SNickeau return $attributes; 44837748cd8SNickeau } 44937748cd8SNickeau 45004fd306cSNickeau public 45104fd306cSNickeau function removeAttributes() 45237748cd8SNickeau { 45337748cd8SNickeau 45437748cd8SNickeau $data = &$this->getPluginData(); 45537748cd8SNickeau if (isset($data[PluginUtility::ATTRIBUTES])) { 45637748cd8SNickeau unset($data[PluginUtility::ATTRIBUTES]); 45737748cd8SNickeau } 45837748cd8SNickeau 45937748cd8SNickeau } 46037748cd8SNickeau 46104fd306cSNickeau public 46204fd306cSNickeau function updateToPluginComponent($component, $state, $attributes = array()) 46337748cd8SNickeau { 46437748cd8SNickeau if ($this->call[0] == "plugin") { 46537748cd8SNickeau $match = $this->call[1][3]; 46637748cd8SNickeau } else { 46737748cd8SNickeau $this->call[0] = "plugin"; 46837748cd8SNickeau $match = ""; 46937748cd8SNickeau } 47037748cd8SNickeau $this->call[1] = array( 47137748cd8SNickeau 0 => $component, 47237748cd8SNickeau 1 => array( 47337748cd8SNickeau PluginUtility::ATTRIBUTES => $attributes, 47437748cd8SNickeau PluginUtility::STATE => $state, 47537748cd8SNickeau ), 47637748cd8SNickeau 2 => $state, 47737748cd8SNickeau 3 => $match 47837748cd8SNickeau ); 47937748cd8SNickeau 48037748cd8SNickeau } 48137748cd8SNickeau 4821fa8c418SNickeau /** 4831fa8c418SNickeau * Does the display has been set 4841fa8c418SNickeau * to override the dokuwiki default 4851fa8c418SNickeau * ({@link Syntax::getPType()} 4861fa8c418SNickeau * 4871fa8c418SNickeau * because an image is by default a inline component 4881fa8c418SNickeau * but can be a block (ie top image of a card) 4891fa8c418SNickeau * @return bool 4901fa8c418SNickeau */ 49104fd306cSNickeau public 49204fd306cSNickeau function isDisplaySet(): bool 4931fa8c418SNickeau { 4941fa8c418SNickeau return isset($this->call[1][1][PluginUtility::DISPLAY]); 4951fa8c418SNickeau } 4961fa8c418SNickeau 49704fd306cSNickeau /** 49804fd306cSNickeau * @return string|null 49904fd306cSNickeau * {@link Call::INLINE_DISPLAY} or {@link Call::BlOCK_DISPLAY} 50004fd306cSNickeau */ 50104fd306cSNickeau public 50204fd306cSNickeau function getDisplay(): ?string 50337748cd8SNickeau { 5041fa8c418SNickeau $mode = $this->getMode(); 5051fa8c418SNickeau if ($mode == "plugin") { 5061fa8c418SNickeau if ($this->isDisplaySet()) { 5071fa8c418SNickeau return $this->call[1][1][PluginUtility::DISPLAY]; 5081fa8c418SNickeau } 5091fa8c418SNickeau } 5101fa8c418SNickeau 51137748cd8SNickeau if ($this->getState() == DOKU_LEXER_UNMATCHED) { 51237748cd8SNickeau /** 51337748cd8SNickeau * Unmatched are content (ie text node in XML/HTML) and have 51437748cd8SNickeau * no display 51537748cd8SNickeau */ 51637748cd8SNickeau return Call::INLINE_DISPLAY; 51737748cd8SNickeau } else { 51837748cd8SNickeau $mode = $this->call[0]; 51937748cd8SNickeau if ($mode == "plugin") { 52037748cd8SNickeau global $DOKU_PLUGINS; 52137748cd8SNickeau $component = $this->getComponentName(); 52237748cd8SNickeau /** 52337748cd8SNickeau * @var SyntaxPlugin $syntaxPlugin 52437748cd8SNickeau */ 52537748cd8SNickeau $syntaxPlugin = $DOKU_PLUGINS['syntax'][$component]; 5267dbcdecdSNico if ($syntaxPlugin === null) { 5277dbcdecdSNico // not a syntax plugin (ie frontmatter) 5287dbcdecdSNico return null; 5297dbcdecdSNico } 53037748cd8SNickeau $pType = $syntaxPlugin->getPType(); 53137748cd8SNickeau switch ($pType) { 532dff3a8c8SNico // https://www.dokuwiki.org/devel:syntax_plugins#syntax_types 533dff3a8c8SNico case "substition": 53437748cd8SNickeau case "normal": 53537748cd8SNickeau return Call::INLINE_DISPLAY; 53637748cd8SNickeau case "block": 53737748cd8SNickeau case "stack": 53837748cd8SNickeau return Call::BlOCK_DISPLAY; 53937748cd8SNickeau default: 54037748cd8SNickeau LogUtility::msg("The ptype (" . $pType . ") is unknown."); 54137748cd8SNickeau return null; 54237748cd8SNickeau } 54337748cd8SNickeau } else { 54437748cd8SNickeau if ($mode == "eol") { 54537748cd8SNickeau /** 54637748cd8SNickeau * Control character 54737748cd8SNickeau * We return it as it's used in the 54837748cd8SNickeau * {@link \syntax_plugin_combo_para::fromEolToParagraphUntilEndOfStack()} 54937748cd8SNickeau * to create the paragraph 55037748cd8SNickeau * This is not a block, nor an inline 55137748cd8SNickeau */ 55237748cd8SNickeau return $mode; 55337748cd8SNickeau } 55437748cd8SNickeau 55537748cd8SNickeau if (in_array($mode, self::INLINE_DOKUWIKI_COMPONENTS)) { 55637748cd8SNickeau return Call::INLINE_DISPLAY; 55737748cd8SNickeau } 55837748cd8SNickeau 55937748cd8SNickeau if (in_array($mode, self::BLOCK_MARKUP_DOKUWIKI_COMPONENTS)) { 56037748cd8SNickeau return Call::BlOCK_DISPLAY; 56137748cd8SNickeau } 56237748cd8SNickeau 56304fd306cSNickeau if (in_array($mode, self::TABLE_MARKUP)) { 56404fd306cSNickeau return Call::TABLE_DISPLAY; 56504fd306cSNickeau } 56604fd306cSNickeau 56704fd306cSNickeau LogUtility::warning("The display of the call with the mode (" . $mode . ") is unknown"); 56837748cd8SNickeau return null; 56937748cd8SNickeau 57037748cd8SNickeau 57137748cd8SNickeau } 57237748cd8SNickeau } 57337748cd8SNickeau 57437748cd8SNickeau } 57537748cd8SNickeau 57637748cd8SNickeau /** 57737748cd8SNickeau * Same as {@link Call::getTagName()} 57837748cd8SNickeau * but fully qualified 57937748cd8SNickeau * @return string 58037748cd8SNickeau */ 58104fd306cSNickeau public 58204fd306cSNickeau function getComponentName() 58337748cd8SNickeau { 58437748cd8SNickeau $mode = $this->call[0]; 58537748cd8SNickeau if ($mode == "plugin") { 58637748cd8SNickeau $pluginDokuData = $this->call[1]; 58737748cd8SNickeau return $pluginDokuData[0]; 58837748cd8SNickeau } else { 58937748cd8SNickeau return $mode; 59037748cd8SNickeau } 59137748cd8SNickeau } 59237748cd8SNickeau 59304fd306cSNickeau public 59404fd306cSNickeau function updateEolToSpace() 59537748cd8SNickeau { 59637748cd8SNickeau $mode = $this->call[0]; 59737748cd8SNickeau if ($mode != "eol") { 59837748cd8SNickeau LogUtility::msg("You can't update a " . $mode . " to a space. It should be a eol", LogUtility::LVL_MSG_WARNING, "support"); 59937748cd8SNickeau } else { 60037748cd8SNickeau $this->call[0] = "cdata"; 60137748cd8SNickeau $this->call[1] = array( 60237748cd8SNickeau 0 => " " 60337748cd8SNickeau ); 60437748cd8SNickeau } 60537748cd8SNickeau 60637748cd8SNickeau } 60737748cd8SNickeau 60804fd306cSNickeau public 60904fd306cSNickeau function &addAttribute($key, $value) 61037748cd8SNickeau { 61137748cd8SNickeau $mode = $this->call[0]; 61237748cd8SNickeau if ($mode == "plugin") { 61337748cd8SNickeau $this->call[1][1][PluginUtility::ATTRIBUTES][$key] = $value; 61404fd306cSNickeau // keep the new reference 61504fd306cSNickeau return $this->call[1][1][PluginUtility::ATTRIBUTES][$key]; 61637748cd8SNickeau } else { 61737748cd8SNickeau LogUtility::msg("You can't add an attribute to the non plugin call mode (" . $mode . ")", LogUtility::LVL_MSG_WARNING, "support"); 61804fd306cSNickeau $whatever = []; 61904fd306cSNickeau return $whatever; 62037748cd8SNickeau } 62137748cd8SNickeau } 62237748cd8SNickeau 62304fd306cSNickeau public 62404fd306cSNickeau function getContext() 62537748cd8SNickeau { 62637748cd8SNickeau $mode = $this->call[0]; 62704fd306cSNickeau if ($mode === "plugin") { 62870bbd7f1Sgerardnico return $this->call[1][1][PluginUtility::CONTEXT] ?? null; 62937748cd8SNickeau } else { 63037748cd8SNickeau LogUtility::msg("You can't ask for a context from a non plugin call mode (" . $mode . ")", LogUtility::LVL_MSG_WARNING, "support"); 63137748cd8SNickeau return null; 63237748cd8SNickeau } 63337748cd8SNickeau } 63437748cd8SNickeau 63537748cd8SNickeau /** 63637748cd8SNickeau * 63737748cd8SNickeau * @return array 63837748cd8SNickeau */ 63904fd306cSNickeau public 64004fd306cSNickeau function toCallArray() 64137748cd8SNickeau { 64237748cd8SNickeau return $this->call; 64337748cd8SNickeau } 64437748cd8SNickeau 64504fd306cSNickeau public 64604fd306cSNickeau function __toString() 64737748cd8SNickeau { 64837748cd8SNickeau $name = $this->key; 64937748cd8SNickeau if (!empty($name)) { 65037748cd8SNickeau $name .= " - "; 65137748cd8SNickeau } 65237748cd8SNickeau $name .= $this->getTagName(); 65304fd306cSNickeau $name .= " - {$this->getStateName()}"; 65437748cd8SNickeau return $name; 65537748cd8SNickeau } 65637748cd8SNickeau 6574cadd4f8SNickeau /** 6584cadd4f8SNickeau * @return string|null 6594cadd4f8SNickeau * 6604cadd4f8SNickeau * If the type returned is a boolean attribute, 6614cadd4f8SNickeau * it means you need to define the expected types 6624cadd4f8SNickeau * in the function {@link TagAttributes::createFromTagMatch()} 6634cadd4f8SNickeau * as third attribute 6644cadd4f8SNickeau */ 66504fd306cSNickeau public 66604fd306cSNickeau function getType(): ?string 66737748cd8SNickeau { 66837748cd8SNickeau if ($this->getState() == DOKU_LEXER_UNMATCHED) { 66937748cd8SNickeau return null; 67037748cd8SNickeau } else { 6714cadd4f8SNickeau return $this->getAttribute(TagAttributes::TYPE_KEY); 67237748cd8SNickeau } 67337748cd8SNickeau } 67437748cd8SNickeau 67537748cd8SNickeau /** 67637748cd8SNickeau * @param $key 67737748cd8SNickeau * @param null $default 6784cadd4f8SNickeau * @return array|string|null 67937748cd8SNickeau */ 68004fd306cSNickeau public 68104fd306cSNickeau function &getAttribute($key, $default = null) 68237748cd8SNickeau { 68304fd306cSNickeau $attributes = &$this->getAttributes(); 68437748cd8SNickeau if (isset($attributes[$key])) { 68537748cd8SNickeau return $attributes[$key]; 6864cadd4f8SNickeau } 68737748cd8SNickeau return $default; 6884cadd4f8SNickeau 68937748cd8SNickeau } 69037748cd8SNickeau 6914cadd4f8SNickeau public 6924cadd4f8SNickeau function getPayload() 69337748cd8SNickeau { 69437748cd8SNickeau $mode = $this->call[0]; 69537748cd8SNickeau if ($mode == "plugin") { 69637748cd8SNickeau return $this->call[1][1][PluginUtility::PAYLOAD]; 69737748cd8SNickeau } else { 69837748cd8SNickeau LogUtility::msg("You can't ask for a payload from a non plugin call mode (" . $mode . ").", LogUtility::LVL_MSG_WARNING, "support"); 69937748cd8SNickeau return null; 70037748cd8SNickeau } 70137748cd8SNickeau } 70237748cd8SNickeau 7034cadd4f8SNickeau public 7044cadd4f8SNickeau function setContext($value) 70537748cd8SNickeau { 70637748cd8SNickeau $this->call[1][1][PluginUtility::CONTEXT] = $value; 70737748cd8SNickeau return $this; 70837748cd8SNickeau } 70937748cd8SNickeau 7104cadd4f8SNickeau public 7114cadd4f8SNickeau function hasAttribute($attributeName): bool 71237748cd8SNickeau { 71337748cd8SNickeau $attributes = $this->getAttributes(); 71437748cd8SNickeau if (isset($attributes[$attributeName])) { 71537748cd8SNickeau return true; 71637748cd8SNickeau } else { 71737748cd8SNickeau if ($this->getType() == $attributeName) { 71837748cd8SNickeau return true; 71937748cd8SNickeau } else { 72037748cd8SNickeau return false; 72137748cd8SNickeau } 72237748cd8SNickeau } 72337748cd8SNickeau } 72437748cd8SNickeau 7254cadd4f8SNickeau public 7264cadd4f8SNickeau function isPluginCall() 72737748cd8SNickeau { 72837748cd8SNickeau return $this->call[0] === "plugin"; 72937748cd8SNickeau } 73037748cd8SNickeau 73137748cd8SNickeau /** 73237748cd8SNickeau * @return mixed|string the position (ie key) in the array 73337748cd8SNickeau */ 7344cadd4f8SNickeau public 7354cadd4f8SNickeau function getKey() 73637748cd8SNickeau { 73737748cd8SNickeau return $this->key; 73837748cd8SNickeau } 73937748cd8SNickeau 7404cadd4f8SNickeau public 74104fd306cSNickeau function &getInstructionCall() 74237748cd8SNickeau { 74337748cd8SNickeau return $this->call; 74437748cd8SNickeau } 74537748cd8SNickeau 7464cadd4f8SNickeau public 7474cadd4f8SNickeau function setState($state) 74837748cd8SNickeau { 74937748cd8SNickeau if ($this->call[0] == "plugin") { 75037748cd8SNickeau // for dokuwiki 75137748cd8SNickeau $this->call[1][2] = $state; 75237748cd8SNickeau // for the combo plugin if any 75337748cd8SNickeau if (isset($this->call[1][1][PluginUtility::STATE])) { 75437748cd8SNickeau $this->call[1][1][PluginUtility::STATE] = $state; 75537748cd8SNickeau } 75637748cd8SNickeau } else { 75737748cd8SNickeau LogUtility::msg("This modification of state is not yet supported for a native call"); 75837748cd8SNickeau } 75937748cd8SNickeau } 76037748cd8SNickeau 76137748cd8SNickeau 76237748cd8SNickeau /** 76337748cd8SNickeau * Return the position of the first matched character in the text file 76437748cd8SNickeau * @return mixed 76537748cd8SNickeau */ 7664cadd4f8SNickeau public 7674cadd4f8SNickeau function getFirstMatchedCharacterPosition() 76837748cd8SNickeau { 76937748cd8SNickeau 77037748cd8SNickeau return $this->call[2]; 77137748cd8SNickeau 77237748cd8SNickeau } 77337748cd8SNickeau 77437748cd8SNickeau /** 77537748cd8SNickeau * Return the position of the last matched character in the text file 77637748cd8SNickeau * 77737748cd8SNickeau * This is the {@link Call::getFirstMatchedCharacterPosition()} 77837748cd8SNickeau * plus the length of the {@link Call::getCapturedContent()} 77937748cd8SNickeau * matched content 78037748cd8SNickeau * @return int|mixed 78137748cd8SNickeau */ 7824cadd4f8SNickeau public 7834cadd4f8SNickeau function getLastMatchedCharacterPosition() 78437748cd8SNickeau { 78570bbd7f1Sgerardnico $captureContent = $this->getCapturedContent(); 78670bbd7f1Sgerardnico $length = 0; 78770bbd7f1Sgerardnico if ($captureContent != null) { 78870bbd7f1Sgerardnico $length = strlen($captureContent); 78970bbd7f1Sgerardnico } 79070bbd7f1Sgerardnico return $this->getFirstMatchedCharacterPosition() + $length; 79137748cd8SNickeau } 79237748cd8SNickeau 79337748cd8SNickeau /** 79437748cd8SNickeau * @param $value string the class string to add 79537748cd8SNickeau * @return Call 79637748cd8SNickeau */ 7974cadd4f8SNickeau public 7984cadd4f8SNickeau function addClassName(string $value): Call 79937748cd8SNickeau { 80037748cd8SNickeau $class = $this->getAttribute("class"); 80137748cd8SNickeau if ($class != null) { 80237748cd8SNickeau $value = "$class $value"; 80337748cd8SNickeau } 80437748cd8SNickeau $this->addAttribute("class", $value); 80537748cd8SNickeau return $this; 80637748cd8SNickeau 80737748cd8SNickeau } 80837748cd8SNickeau 80937748cd8SNickeau /** 81037748cd8SNickeau * @param $key 81137748cd8SNickeau * @return mixed|null - the delete value of null if not found 81237748cd8SNickeau */ 8134cadd4f8SNickeau public 8144cadd4f8SNickeau function removeAttribute($key) 81537748cd8SNickeau { 81637748cd8SNickeau 81737748cd8SNickeau $data = &$this->getPluginData(); 81837748cd8SNickeau if (isset($data[PluginUtility::ATTRIBUTES][$key])) { 81937748cd8SNickeau $value = $data[PluginUtility::ATTRIBUTES][$key]; 82037748cd8SNickeau unset($data[PluginUtility::ATTRIBUTES][$key]); 82137748cd8SNickeau return $value; 82237748cd8SNickeau } else { 82337748cd8SNickeau // boolean attribute as first attribute 82437748cd8SNickeau if ($this->getType() == $key) { 82537748cd8SNickeau unset($data[PluginUtility::ATTRIBUTES][TagAttributes::TYPE_KEY]); 82637748cd8SNickeau return true; 82737748cd8SNickeau } 82837748cd8SNickeau return null; 82937748cd8SNickeau } 83037748cd8SNickeau 83137748cd8SNickeau } 83237748cd8SNickeau 8334cadd4f8SNickeau public 8344cadd4f8SNickeau function setPayload($text) 83537748cd8SNickeau { 83637748cd8SNickeau if ($this->isPluginCall()) { 83737748cd8SNickeau $this->call[1][1][PluginUtility::PAYLOAD] = $text; 83837748cd8SNickeau } else { 83937748cd8SNickeau LogUtility::msg("Setting the payload for a non-native call ($this) is not yet implemented"); 84037748cd8SNickeau } 84137748cd8SNickeau } 84237748cd8SNickeau 84337748cd8SNickeau /** 84437748cd8SNickeau * @return bool true if the call is a text call (same as dom text node) 84537748cd8SNickeau */ 8464cadd4f8SNickeau public 8474cadd4f8SNickeau function isTextCall() 84837748cd8SNickeau { 84937748cd8SNickeau return ( 85037748cd8SNickeau $this->getState() == DOKU_LEXER_UNMATCHED || 85137748cd8SNickeau $this->getTagName() == "cdata" || 85237748cd8SNickeau $this->getTagName() == "acronym" 85337748cd8SNickeau ); 85437748cd8SNickeau } 85537748cd8SNickeau 8564cadd4f8SNickeau public 8574cadd4f8SNickeau function setType($type) 85837748cd8SNickeau { 85937748cd8SNickeau if ($this->isPluginCall()) { 86037748cd8SNickeau $this->call[1][1][PluginUtility::ATTRIBUTES][TagAttributes::TYPE_KEY] = $type; 86137748cd8SNickeau } else { 86237748cd8SNickeau LogUtility::msg("This is not a plugin call ($this), you can't set the type"); 86337748cd8SNickeau } 86437748cd8SNickeau } 86537748cd8SNickeau 8664cadd4f8SNickeau public 8674cadd4f8SNickeau function addCssStyle($key, $value) 86837748cd8SNickeau { 86937748cd8SNickeau $style = $this->getAttribute("style"); 87037748cd8SNickeau $cssValue = "$key:$value"; 8714cadd4f8SNickeau if ($style !== null) { 87237748cd8SNickeau $cssValue = "$style; $cssValue"; 87337748cd8SNickeau } 87437748cd8SNickeau $this->addAttribute("style", $cssValue); 87537748cd8SNickeau } 87637748cd8SNickeau 8774cadd4f8SNickeau public 8784cadd4f8SNickeau function setSyntaxComponentFromTag($tag) 87937748cd8SNickeau { 88037748cd8SNickeau 88137748cd8SNickeau if ($this->isPluginCall()) { 88237748cd8SNickeau $this->call[1][0] = PluginUtility::getComponentName($tag); 88337748cd8SNickeau } else { 88437748cd8SNickeau LogUtility::msg("The call ($this) is a native call and we don't support yet the modification of the component to ($tag)"); 88537748cd8SNickeau } 88637748cd8SNickeau } 88737748cd8SNickeau 88837748cd8SNickeau 8894cadd4f8SNickeau public 8904cadd4f8SNickeau function setCapturedContent($content) 89137748cd8SNickeau { 89237748cd8SNickeau $tagName = $this->getTagName(); 89337748cd8SNickeau switch ($tagName) { 89437748cd8SNickeau case "cdata": 89537748cd8SNickeau $this->call[1][0] = $content; 89637748cd8SNickeau break; 89737748cd8SNickeau default: 89837748cd8SNickeau LogUtility::msg("Setting the captured content on a call for the tag ($tagName) is not yet implemented", LogUtility::LVL_MSG_ERROR); 89937748cd8SNickeau } 90037748cd8SNickeau } 90137748cd8SNickeau 9021fa8c418SNickeau /** 9031fa8c418SNickeau * Set the display to block or inline 9041fa8c418SNickeau * One of `block` or `inline` 9051fa8c418SNickeau */ 9064cadd4f8SNickeau public 9074cadd4f8SNickeau function setDisplay($display): Call 9081fa8c418SNickeau { 9091fa8c418SNickeau $mode = $this->getMode(); 9101fa8c418SNickeau if ($mode == "plugin") { 9111fa8c418SNickeau $this->call[1][1][PluginUtility::DISPLAY] = $display; 9121fa8c418SNickeau } else { 9131fa8c418SNickeau LogUtility::msg("You can't set a display on a non plugin call mode (" . $mode . ")", LogUtility::LVL_MSG_WARNING); 9141fa8c418SNickeau } 9151fa8c418SNickeau return $this; 9161fa8c418SNickeau 9171fa8c418SNickeau } 9181fa8c418SNickeau 9191fa8c418SNickeau /** 9201fa8c418SNickeau * The plugin or not 9211fa8c418SNickeau * @return mixed 9221fa8c418SNickeau */ 9234cadd4f8SNickeau private 9244cadd4f8SNickeau function getMode() 9251fa8c418SNickeau { 9261fa8c418SNickeau return $this->call[0]; 9271fa8c418SNickeau } 9281fa8c418SNickeau 9291fa8c418SNickeau /** 9301fa8c418SNickeau * Return if this an unmatched call with space 9311fa8c418SNickeau * in captured content 9321fa8c418SNickeau * @return bool 9331fa8c418SNickeau */ 9344cadd4f8SNickeau public 9354cadd4f8SNickeau function isUnMatchedEmptyCall(): bool 9361fa8c418SNickeau { 9371fa8c418SNickeau if ($this->getState() === DOKU_LEXER_UNMATCHED && trim($this->getCapturedContent()) === "") { 9381fa8c418SNickeau return true; 9391fa8c418SNickeau } 9401fa8c418SNickeau return false; 9411fa8c418SNickeau } 9421fa8c418SNickeau 9434cadd4f8SNickeau public 9444cadd4f8SNickeau function getExitCode() 9454cadd4f8SNickeau { 9464cadd4f8SNickeau $mode = $this->call[0]; 9474cadd4f8SNickeau if ($mode == "plugin") { 94870bbd7f1Sgerardnico $value = $this->call[1][1][PluginUtility::EXIT_CODE] ?? null; 9494cadd4f8SNickeau if ($value === null) { 9504cadd4f8SNickeau return 0; 9514cadd4f8SNickeau } 9524cadd4f8SNickeau return $value; 9534cadd4f8SNickeau } else { 9544cadd4f8SNickeau LogUtility::msg("You can't ask for the exit code from a non plugin call mode (" . $mode . ").", LogUtility::LVL_MSG_WARNING, "support"); 9554cadd4f8SNickeau return 0; 9564cadd4f8SNickeau } 9574cadd4f8SNickeau } 9584cadd4f8SNickeau 95904fd306cSNickeau public 96004fd306cSNickeau function setAttribute(string $name, $value): Call 9614cadd4f8SNickeau { 962040d4aeaSgerardnico $this->getAttributes()[$name] = $value; 9634cadd4f8SNickeau return $this; 9644cadd4f8SNickeau } 9654cadd4f8SNickeau 96604fd306cSNickeau public 96704fd306cSNickeau function setPluginData(string $name, $value): Call 9684cadd4f8SNickeau { 9694cadd4f8SNickeau $this->getPluginData()[$name] = $value; 9704cadd4f8SNickeau return $this; 9714cadd4f8SNickeau } 9724cadd4f8SNickeau 97304fd306cSNickeau public 97404fd306cSNickeau function getIdOrDefault() 97504fd306cSNickeau { 97604fd306cSNickeau $id = $this->getAttribute(TagAttributes::ID_KEY); 97704fd306cSNickeau if ($id !== null) { 97804fd306cSNickeau return $id; 97904fd306cSNickeau } 98004fd306cSNickeau return $this->getAttribute(TagAttributes::GENERATED_ID_KEY); 98104fd306cSNickeau } 98204fd306cSNickeau 98304fd306cSNickeau public 98404fd306cSNickeau function getAttributeAndRemove(string $key) 98504fd306cSNickeau { 98604fd306cSNickeau $value = $this->getAttribute($key); 98704fd306cSNickeau $this->removeAttribute($key); 98804fd306cSNickeau return $value; 98904fd306cSNickeau } 99004fd306cSNickeau 99104fd306cSNickeau private function getStateName(): string 99204fd306cSNickeau { 99304fd306cSNickeau $state = $this->getState(); 99404fd306cSNickeau switch ($state) { 99504fd306cSNickeau case DOKU_LEXER_ENTER: 99604fd306cSNickeau return "enter"; 99704fd306cSNickeau case DOKU_LEXER_EXIT: 99804fd306cSNickeau return "exit"; 99904fd306cSNickeau case DOKU_LEXER_SPECIAL: 100004fd306cSNickeau return "empty"; 100104fd306cSNickeau case DOKU_LEXER_UNMATCHED: 100204fd306cSNickeau return "text"; 100304fd306cSNickeau default: 100404fd306cSNickeau return "unknown " . $state; 100504fd306cSNickeau } 100604fd306cSNickeau } 100704fd306cSNickeau 100837748cd8SNickeau 100937748cd8SNickeau} 1010