1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeaunamespace ComboStrap; 4*04fd306cSNickeau 5*04fd306cSNickeau 6*04fd306cSNickeauclass MarkupRenderer 7*04fd306cSNickeau{ 8*04fd306cSNickeau 9*04fd306cSNickeau /** 10*04fd306cSNickeau * Setting the mime to instructions will just not do any render processing. 11*04fd306cSNickeau * Just parse tree/instructions processing if needed 12*04fd306cSNickeau */ 13*04fd306cSNickeau public const INSTRUCTION_EXTENSION = "i"; 14*04fd306cSNickeau 15*04fd306cSNickeau const CANONICAL = "markup:renderer"; 16*04fd306cSNickeau const XHTML_RENDERER = "xhtml"; 17*04fd306cSNickeau const DEFAULT_RENDERER = self::XHTML_RENDERER; 18*04fd306cSNickeau const METADATA_EXTENSION = "meta"; 19*04fd306cSNickeau /** 20*04fd306cSNickeau * @var string source of the renderer is a markup (and not instructions) 21*04fd306cSNickeau */ 22*04fd306cSNickeau private string $markupSource; 23*04fd306cSNickeau /** 24*04fd306cSNickeau * @var array source of the rendere is instructions 25*04fd306cSNickeau */ 26*04fd306cSNickeau private array $instructionsSource; 27*04fd306cSNickeau 28*04fd306cSNickeau private Mime $requestedMime; 29*04fd306cSNickeau 30*04fd306cSNickeau /** 31*04fd306cSNickeau * @var mixed 32*04fd306cSNickeau */ 33*04fd306cSNickeau private $cacheAfterRendering = true; 34*04fd306cSNickeau private string $renderer; 35*04fd306cSNickeau 36*04fd306cSNickeau /** 37*04fd306cSNickeau * @var WikiPath the context path 38*04fd306cSNickeau * May be null (ie markup rendering without any context such as webcode) 39*04fd306cSNickeau */ 40*04fd306cSNickeau private WikiPath $requestedContextPath; 41*04fd306cSNickeau 42*04fd306cSNickeau /** 43*04fd306cSNickeau * @var ?Path the path from where the instructions/markup where created 44*04fd306cSNickeau * This is mandatory to add cache dependency informations 45*04fd306cSNickeau * and set the path that is executing 46*04fd306cSNickeau */ 47*04fd306cSNickeau private ?Path $executingPath; 48*04fd306cSNickeau 49*04fd306cSNickeau 50*04fd306cSNickeau /** 51*04fd306cSNickeau * @param string $markup 52*04fd306cSNickeau * @param Path|null $executingPath - the source of the markup - may be null (case of webcode) 53*04fd306cSNickeau * @param WikiPath|null $contextPath - the requested markup path - may be null (case of webcode) 54*04fd306cSNickeau * @return MarkupRenderer 55*04fd306cSNickeau */ 56*04fd306cSNickeau public static function createFromMarkup(string $markup, ?Path $executingPath, ?WikiPath $contextPath): MarkupRenderer 57*04fd306cSNickeau { 58*04fd306cSNickeau $markupRenderer = (new MarkupRenderer()) 59*04fd306cSNickeau ->setMarkup($markup); 60*04fd306cSNickeau if ($executingPath != null) { 61*04fd306cSNickeau $markupRenderer->setRequestedExecutingPath($executingPath); 62*04fd306cSNickeau } 63*04fd306cSNickeau if ($contextPath != null) { 64*04fd306cSNickeau $markupRenderer->setRequestedContextPath($contextPath); 65*04fd306cSNickeau } 66*04fd306cSNickeau return $markupRenderer; 67*04fd306cSNickeau 68*04fd306cSNickeau } 69*04fd306cSNickeau 70*04fd306cSNickeau private function setMarkup(string $markup): MarkupRenderer 71*04fd306cSNickeau { 72*04fd306cSNickeau $this->markupSource = $markup; 73*04fd306cSNickeau return $this; 74*04fd306cSNickeau } 75*04fd306cSNickeau 76*04fd306cSNickeau public static function createFromMarkupInstructions($instructions, FetcherMarkup $fetcherMarkup): MarkupRenderer 77*04fd306cSNickeau { 78*04fd306cSNickeau return (new MarkupRenderer()) 79*04fd306cSNickeau ->setInstructions($instructions) 80*04fd306cSNickeau ->setRequestedContextPath($fetcherMarkup->getRequestedContextPath()) 81*04fd306cSNickeau ->setRequestedExecutingPath($fetcherMarkup->getExecutingPathOrNull()); 82*04fd306cSNickeau } 83*04fd306cSNickeau 84*04fd306cSNickeau public static function createFromInstructions($instructions): MarkupRenderer 85*04fd306cSNickeau { 86*04fd306cSNickeau return (new MarkupRenderer())->setInstructions($instructions); 87*04fd306cSNickeau } 88*04fd306cSNickeau 89*04fd306cSNickeau 90*04fd306cSNickeau public function setRequestedMimeToInstruction(): MarkupRenderer 91*04fd306cSNickeau { 92*04fd306cSNickeau try { 93*04fd306cSNickeau $this->setRequestedMime(Mime::createFromExtension(self::INSTRUCTION_EXTENSION)); 94*04fd306cSNickeau } catch (ExceptionNotFound $e) { 95*04fd306cSNickeau throw new ExceptionRuntime("Internal error: the mime is internal and should be good"); 96*04fd306cSNickeau } 97*04fd306cSNickeau return $this; 98*04fd306cSNickeau 99*04fd306cSNickeau } 100*04fd306cSNickeau 101*04fd306cSNickeau public function setRequestedMime(Mime $requestedMime): MarkupRenderer 102*04fd306cSNickeau { 103*04fd306cSNickeau $this->requestedMime = $requestedMime; 104*04fd306cSNickeau return $this; 105*04fd306cSNickeau } 106*04fd306cSNickeau 107*04fd306cSNickeau public function getOutput() 108*04fd306cSNickeau { 109*04fd306cSNickeau 110*04fd306cSNickeau $extension = $this->requestedMime->getExtension(); 111*04fd306cSNickeau switch ($extension) { 112*04fd306cSNickeau case self::INSTRUCTION_EXTENSION: 113*04fd306cSNickeau /** 114*04fd306cSNickeau * Get the instructions adapted from {@link p_cached_instructions()} 115*04fd306cSNickeau * 116*04fd306cSNickeau * Note that this code may not run at first rendering 117*04fd306cSNickeau * 118*04fd306cSNickeau * Why ? 119*04fd306cSNickeau * Because dokuwiki asks first page information 120*04fd306cSNickeau * via the {@link pageinfo()} method. 121*04fd306cSNickeau * This function then render the metadata (ie {@link p_render_metadata()} and therefore will trigger 122*04fd306cSNickeau * the rendering with this function 123*04fd306cSNickeau * ```p_cached_instructions(wikiFN($id),false,$id)``` 124*04fd306cSNickeau * 125*04fd306cSNickeau * The best way to manipulate the instructions is not before but after 126*04fd306cSNickeau * the parsing. See {@link \action_plugin_combo_instructionspostprocessing} 127*04fd306cSNickeau * 128*04fd306cSNickeau */ 129*04fd306cSNickeau return p_get_instructions($this->markupSource); 130*04fd306cSNickeau 131*04fd306cSNickeau default: 132*04fd306cSNickeau /** 133*04fd306cSNickeau * The code below is adapted from {@link p_cached_output()} 134*04fd306cSNickeau * $ret = p_cached_output($file, 'xhtml', $pageid); 135*04fd306cSNickeau */ 136*04fd306cSNickeau if (!isset($this->instructionsSource)) { 137*04fd306cSNickeau $executingPath = null; 138*04fd306cSNickeau if (isset($this->executingPath)) { 139*04fd306cSNickeau $executingPath = $this->executingPath; 140*04fd306cSNickeau } 141*04fd306cSNickeau 142*04fd306cSNickeau $contextPath = null; 143*04fd306cSNickeau if (isset($this->requestedContextPath)) { 144*04fd306cSNickeau $contextPath = $this->requestedContextPath; 145*04fd306cSNickeau } 146*04fd306cSNickeau 147*04fd306cSNickeau $this->instructionsSource = MarkupRenderer::createFromMarkup($this->markupSource, $executingPath, $contextPath) 148*04fd306cSNickeau ->setRequestedMimeToInstruction() 149*04fd306cSNickeau ->getOutput(); 150*04fd306cSNickeau } 151*04fd306cSNickeau 152*04fd306cSNickeau /** 153*04fd306cSNickeau * Render 154*04fd306cSNickeau */ 155*04fd306cSNickeau $result = p_render($this->getRendererNameOrDefault(), $this->instructionsSource, $info); 156*04fd306cSNickeau $this->cacheAfterRendering = $info['cache'] !== null ? $info['cache'] : false; 157*04fd306cSNickeau return $result; 158*04fd306cSNickeau 159*04fd306cSNickeau } 160*04fd306cSNickeau 161*04fd306cSNickeau 162*04fd306cSNickeau } 163*04fd306cSNickeau 164*04fd306cSNickeau private function setInstructions(array $instructions): MarkupRenderer 165*04fd306cSNickeau { 166*04fd306cSNickeau $this->instructionsSource = $instructions; 167*04fd306cSNickeau return $this; 168*04fd306cSNickeau } 169*04fd306cSNickeau 170*04fd306cSNickeau 171*04fd306cSNickeau function getRendererNameOrDefault(): string 172*04fd306cSNickeau { 173*04fd306cSNickeau if (isset($this->renderer)) { 174*04fd306cSNickeau return $this->renderer; 175*04fd306cSNickeau } 176*04fd306cSNickeau /** 177*04fd306cSNickeau * Note: This value is passed to {@link p_get_renderer} to get the renderer class 178*04fd306cSNickeau */ 179*04fd306cSNickeau return self::DEFAULT_RENDERER; 180*04fd306cSNickeau } 181*04fd306cSNickeau 182*04fd306cSNickeau public function setRendererName(string $rendererName): MarkupRenderer 183*04fd306cSNickeau { 184*04fd306cSNickeau $this->renderer = $rendererName; 185*04fd306cSNickeau return $this; 186*04fd306cSNickeau } 187*04fd306cSNickeau 188*04fd306cSNickeau public function getCacheAfterRendering() 189*04fd306cSNickeau { 190*04fd306cSNickeau return $this->cacheAfterRendering; 191*04fd306cSNickeau } 192*04fd306cSNickeau 193*04fd306cSNickeau /** 194*04fd306cSNickeau * The page context in which this markup was requested 195*04fd306cSNickeau * @param WikiPath $path 196*04fd306cSNickeau * @return $this 197*04fd306cSNickeau */ 198*04fd306cSNickeau public function setRequestedContextPath(WikiPath $path): MarkupRenderer 199*04fd306cSNickeau { 200*04fd306cSNickeau $this->requestedContextPath = $path; 201*04fd306cSNickeau return $this; 202*04fd306cSNickeau } 203*04fd306cSNickeau 204*04fd306cSNickeau public function setRequestedMimeToXhtml(): MarkupRenderer 205*04fd306cSNickeau { 206*04fd306cSNickeau try { 207*04fd306cSNickeau return $this->setRequestedMime(Mime::createFromExtension("xhtml")); 208*04fd306cSNickeau } catch (ExceptionNotFound $e) { 209*04fd306cSNickeau throw new ExceptionRuntime("Internal error", 0, $e); 210*04fd306cSNickeau } 211*04fd306cSNickeau } 212*04fd306cSNickeau 213*04fd306cSNickeau /** 214*04fd306cSNickeau * @throws ExceptionNotFound 215*04fd306cSNickeau */ 216*04fd306cSNickeau private function getRequestedContextPath(): WikiPath 217*04fd306cSNickeau { 218*04fd306cSNickeau 219*04fd306cSNickeau if (!isset($this->requestedContextPath)) { 220*04fd306cSNickeau throw new ExceptionNotFound("No requested context path"); 221*04fd306cSNickeau } 222*04fd306cSNickeau return $this->requestedContextPath; 223*04fd306cSNickeau 224*04fd306cSNickeau } 225*04fd306cSNickeau 226*04fd306cSNickeau public function setRequestedExecutingPath(?Path $executingPath): MarkupRenderer 227*04fd306cSNickeau { 228*04fd306cSNickeau $this->executingPath = $executingPath; 229*04fd306cSNickeau return $this; 230*04fd306cSNickeau } 231*04fd306cSNickeau 232*04fd306cSNickeau 233*04fd306cSNickeau} 234