1531e725cSNickeau<?php 2531e725cSNickeau 3531e725cSNickeau 4531e725cSNickeauuse ComboStrap\CallStack; 5531e725cSNickeauuse ComboStrap\LogUtility; 6531e725cSNickeauuse ComboStrap\PluginUtility; 7531e725cSNickeauuse ComboStrap\TagAttributes; 8531e725cSNickeau 9531e725cSNickeau 10531e725cSNickeauif (!defined('DOKU_INC')) die(); 11531e725cSNickeau 12531e725cSNickeau/** 13531e725cSNickeau * Atx headings 14531e725cSNickeau * https://github.github.com/gfm/#atx-headings 15531e725cSNickeau * https://spec.commonmark.org/0.29/#atx-heading 16531e725cSNickeau * http://www.aaronsw.com/2002/atx/intro 17531e725cSNickeau */ 18531e725cSNickeauclass syntax_plugin_combo_headingatx extends DokuWiki_Syntax_Plugin 19531e725cSNickeau{ 20531e725cSNickeau 21531e725cSNickeau 22531e725cSNickeau const TAG = "headingatx"; 23531e725cSNickeau const LEVEL = 'level'; 24531e725cSNickeau const EXIT_PATTERN = "\r??\n"; 25531e725cSNickeau 26531e725cSNickeau 27531e725cSNickeau function getType() 28531e725cSNickeau { 29531e725cSNickeau return 'formatting'; 30531e725cSNickeau } 31531e725cSNickeau 32531e725cSNickeau /** 33531e725cSNickeau * 34531e725cSNickeau * How Dokuwiki will add P element 35531e725cSNickeau * 36531e725cSNickeau * * 'normal' - The plugin can be used inside paragraphs (inline) 37531e725cSNickeau * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 38531e725cSNickeau * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 39531e725cSNickeau * 40531e725cSNickeau * @see DokuWiki_Syntax_Plugin::getPType() 41531e725cSNickeau * 42531e725cSNickeau */ 43531e725cSNickeau function getPType() 44531e725cSNickeau { 45531e725cSNickeau return 'block'; 46531e725cSNickeau } 47531e725cSNickeau 48531e725cSNickeau /** 49531e725cSNickeau * @return array 50531e725cSNickeau * Allow which kind of plugin inside 51531e725cSNickeau * 52531e725cSNickeau * No one of array('baseonly','container', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 53531e725cSNickeau * because we manage self the content and we call self the parser 54531e725cSNickeau * 55531e725cSNickeau * Return an array of one or more of the mode types {@link $PARSER_MODES} in Parser.php 56531e725cSNickeau */ 57531e725cSNickeau function getAllowedTypes() 58531e725cSNickeau { 59531e725cSNickeau return array('formatting', 'substition', 'protected', 'disabled'); 60531e725cSNickeau } 61531e725cSNickeau 62531e725cSNickeau /** 63531e725cSNickeau * 64531e725cSNickeau * @return int 65531e725cSNickeau */ 66531e725cSNickeau function getSort() 67531e725cSNickeau { 68531e725cSNickeau return 49; 69531e725cSNickeau } 70531e725cSNickeau 71531e725cSNickeau 72531e725cSNickeau function connectTo($mode) 73531e725cSNickeau { 74531e725cSNickeau 75531e725cSNickeau $pattern = '\r??\n\s*#{1,6}\s?(?=.*' . self::EXIT_PATTERN . ')'; 76*9337a630SNickeau $this->Lexer->addSpecialPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 77531e725cSNickeau 78531e725cSNickeau } 79531e725cSNickeau 80531e725cSNickeau 81531e725cSNickeau function handle($match, $state, $pos, Doku_Handler $handler) 82531e725cSNickeau { 83531e725cSNickeau 84531e725cSNickeau switch ($state) { 85531e725cSNickeau 86531e725cSNickeau case DOKU_LEXER_SPECIAL : 87531e725cSNickeau 88531e725cSNickeau $attributes = [syntax_plugin_combo_heading::LEVEL => strlen(trim($match))]; 89531e725cSNickeau $callStack = CallStack::createFromHandler($handler); 90531e725cSNickeau 91531e725cSNickeau // Determine the type 92*9337a630SNickeau $context = syntax_plugin_combo_heading::getContext($callStack); 93531e725cSNickeau 94531e725cSNickeau /** 95531e725cSNickeau * The context is needed: 96531e725cSNickeau * * to add the bootstrap class if it's a card title for instance 97531e725cSNickeau * * and to delete {@link syntax_plugin_combo_heading::TYPE_OUTLINE} call 98531e725cSNickeau * in the {@link action_plugin_combo_headingpostprocess} (The rendering is done via Dokuwiki, 99531e725cSNickeau * see the exit processing for more info on the handling of outline headings) 100531e725cSNickeau * 101531e725cSNickeau */ 102531e725cSNickeau return array( 103531e725cSNickeau PluginUtility::STATE => $state, 104531e725cSNickeau PluginUtility::ATTRIBUTES => $attributes, 105531e725cSNickeau PluginUtility::CONTEXT => $context, 106531e725cSNickeau PluginUtility::POSITION => $pos 107531e725cSNickeau ); 108531e725cSNickeau 109531e725cSNickeau 110531e725cSNickeau } 111531e725cSNickeau return array(); 112531e725cSNickeau 113531e725cSNickeau } 114531e725cSNickeau 115531e725cSNickeau /** 116531e725cSNickeau * Render the output 117531e725cSNickeau * @param string $format 118531e725cSNickeau * @param Doku_Renderer $renderer 119531e725cSNickeau * @param array $data - what the function handle() return'ed 120531e725cSNickeau * @return boolean - rendered correctly? (however, returned value is not used at the moment) 121531e725cSNickeau * @see DokuWiki_Syntax_Plugin::render() 122531e725cSNickeau * 123531e725cSNickeau * 124531e725cSNickeau */ 125531e725cSNickeau function render($format, Doku_Renderer $renderer, $data) 126531e725cSNickeau { 127531e725cSNickeau 128531e725cSNickeau /** 129531e725cSNickeau * 130531e725cSNickeau * The atx special call is transformed by the {@link action_plugin_combo_headingpostprocess} 131531e725cSNickeau * into enter and exit call 132531e725cSNickeau */ 133531e725cSNickeau if ($format == 'xhtml') { 134531e725cSNickeau 135531e725cSNickeau /** @var Doku_Renderer_xhtml $renderer */ 136531e725cSNickeau $state = $data[PluginUtility::STATE]; 137531e725cSNickeau switch ($state) { 138531e725cSNickeau 139531e725cSNickeau case DOKU_LEXER_ENTER: 140531e725cSNickeau 141531e725cSNickeau $attributes = $data[PluginUtility::ATTRIBUTES]; 142531e725cSNickeau $context = $data[PluginUtility::CONTEXT]; 143531e725cSNickeau $tagAttributes = TagAttributes::createFromCallStackArray($attributes, syntax_plugin_combo_heading::TAG); 144531e725cSNickeau $pos = $data[PluginUtility::POSITION]; 145531e725cSNickeau syntax_plugin_combo_heading::renderOpeningTag($context, $tagAttributes, $renderer, $pos); 146531e725cSNickeau return true; 147531e725cSNickeau 148531e725cSNickeau 149531e725cSNickeau case DOKU_LEXER_EXIT: 150531e725cSNickeau 151531e725cSNickeau $attributes = $data[PluginUtility::ATTRIBUTES]; 152531e725cSNickeau $tagAttributes = TagAttributes::createFromCallStackArray($attributes); 153531e725cSNickeau $level = $tagAttributes->getValue(syntax_plugin_combo_heading::LEVEL); 154531e725cSNickeau $renderer->doc .= "</h$level>" . DOKU_LF; 155531e725cSNickeau return true; 156531e725cSNickeau 157531e725cSNickeau } 158531e725cSNickeau } else if ($format == renderer_plugin_combo_analytics::RENDERER_FORMAT) { 159531e725cSNickeau 160531e725cSNickeau /** 161531e725cSNickeau * @var renderer_plugin_combo_analytics $renderer 162531e725cSNickeau */ 163531e725cSNickeau syntax_plugin_combo_heading::processMetadataAnalytics($data, $renderer); 164531e725cSNickeau 165531e725cSNickeau } else if ($format == "metadata") { 166531e725cSNickeau 167531e725cSNickeau /** 168531e725cSNickeau * @var Doku_Renderer_metadata $renderer 169531e725cSNickeau */ 170531e725cSNickeau syntax_plugin_combo_heading::processHeadingMetadata($data, $renderer); 171531e725cSNickeau 172531e725cSNickeau } 173531e725cSNickeau 174531e725cSNickeau return false; 175531e725cSNickeau } 176531e725cSNickeau 177531e725cSNickeau 178531e725cSNickeau} 179531e725cSNickeau 180