1*8ec9a8f2SSungbin Jeon<?php 2*8ec9a8f2SSungbin Jeon 3*8ec9a8f2SSungbin Jeon/* 4*8ec9a8f2SSungbin Jeon * This file is part of the clockoon/dokuwiki-commonmark-plugin package. 5*8ec9a8f2SSungbin Jeon * 6*8ec9a8f2SSungbin Jeon * (c) Sungbin Jeon <clockoon@gmail.com> 7*8ec9a8f2SSungbin Jeon * 8*8ec9a8f2SSungbin Jeon * Original code based on the followings: 9*8ec9a8f2SSungbin Jeon * - CommonMark JS reference parser (https://bitly.com/commonmark-js) (c) John MacFarlane 10*8ec9a8f2SSungbin Jeon * - league/commonmark (https://github.com/thephpleague/commonmark) (c) Colin O'Dell <colinodell@gmail.com> 11*8ec9a8f2SSungbin Jeon * 12*8ec9a8f2SSungbin Jeon * For the full copyright and license information, please view the LICENSE 13*8ec9a8f2SSungbin Jeon * file that was distributed with this source code. 14*8ec9a8f2SSungbin Jeon */ 15*8ec9a8f2SSungbin Jeon 16*8ec9a8f2SSungbin Jeonnamespace Dokuwiki\Plugin\Commonmark; 17*8ec9a8f2SSungbin Jeon 18*8ec9a8f2SSungbin Jeonuse League\CommonMark\Block\Element\AbstractBlock; 19*8ec9a8f2SSungbin Jeonuse League\CommonMark\Block\Renderer\BlockRendererInterface; 20*8ec9a8f2SSungbin Jeonuse League\CommonMark\Inline\Element\AbstractInline; 21*8ec9a8f2SSungbin Jeonuse League\CommonMark\Inline\Renderer\InlineRendererInterface; 22*8ec9a8f2SSungbin Jeonuse League\CommonMark\ElementRendererInterface; 23*8ec9a8f2SSungbin Jeonuse League\CommonMark\EnvironmentInterface; 24*8ec9a8f2SSungbin Jeon 25*8ec9a8f2SSungbin Jeon/** 26*8ec9a8f2SSungbin Jeon * Renders a parsed AST to DW 27*8ec9a8f2SSungbin Jeon */ 28*8ec9a8f2SSungbin Jeonfinal class DWRenderer implements ElementRendererInterface 29*8ec9a8f2SSungbin Jeon{ 30*8ec9a8f2SSungbin Jeon /** 31*8ec9a8f2SSungbin Jeon * @var EnvironmentInterface 32*8ec9a8f2SSungbin Jeon */ 33*8ec9a8f2SSungbin Jeon protected $environment; 34*8ec9a8f2SSungbin Jeon 35*8ec9a8f2SSungbin Jeon /** 36*8ec9a8f2SSungbin Jeon * @param EnvironmentInterface $environment 37*8ec9a8f2SSungbin Jeon */ 38*8ec9a8f2SSungbin Jeon public function __construct(EnvironmentInterface $environment) 39*8ec9a8f2SSungbin Jeon { 40*8ec9a8f2SSungbin Jeon $this->environment = $environment; 41*8ec9a8f2SSungbin Jeon } 42*8ec9a8f2SSungbin Jeon 43*8ec9a8f2SSungbin Jeon /** 44*8ec9a8f2SSungbin Jeon * @param string $option 45*8ec9a8f2SSungbin Jeon * @param mixed $default 46*8ec9a8f2SSungbin Jeon * 47*8ec9a8f2SSungbin Jeon * @return mixed|null 48*8ec9a8f2SSungbin Jeon */ 49*8ec9a8f2SSungbin Jeon public function getOption(string $option, $default = null) 50*8ec9a8f2SSungbin Jeon { 51*8ec9a8f2SSungbin Jeon return $this->environment->getConfig('renderer/' . $option, $default); 52*8ec9a8f2SSungbin Jeon } 53*8ec9a8f2SSungbin Jeon 54*8ec9a8f2SSungbin Jeon /** 55*8ec9a8f2SSungbin Jeon * @param AbstractInline $inline 56*8ec9a8f2SSungbin Jeon * 57*8ec9a8f2SSungbin Jeon * @throws \RuntimeException 58*8ec9a8f2SSungbin Jeon * 59*8ec9a8f2SSungbin Jeon * @return string 60*8ec9a8f2SSungbin Jeon */ 61*8ec9a8f2SSungbin Jeon public function renderInline(AbstractInline $inline): string 62*8ec9a8f2SSungbin Jeon { 63*8ec9a8f2SSungbin Jeon $renderers = $this->environment->getInlineRenderersForClass(\get_class($inline)); 64*8ec9a8f2SSungbin Jeon 65*8ec9a8f2SSungbin Jeon /** @var InlineRendererInterface $renderer */ 66*8ec9a8f2SSungbin Jeon foreach ($renderers as $renderer) { 67*8ec9a8f2SSungbin Jeon if (($result = $renderer->render($inline, $this)) !== null) { 68*8ec9a8f2SSungbin Jeon return $result; 69*8ec9a8f2SSungbin Jeon } 70*8ec9a8f2SSungbin Jeon } 71*8ec9a8f2SSungbin Jeon 72*8ec9a8f2SSungbin Jeon throw new \RuntimeException('Unable to find corresponding renderer for inline type ' . \get_class($inline)); 73*8ec9a8f2SSungbin Jeon } 74*8ec9a8f2SSungbin Jeon 75*8ec9a8f2SSungbin Jeon /** 76*8ec9a8f2SSungbin Jeon * @param AbstractInline[] $inlines 77*8ec9a8f2SSungbin Jeon * 78*8ec9a8f2SSungbin Jeon * @return string 79*8ec9a8f2SSungbin Jeon */ 80*8ec9a8f2SSungbin Jeon public function renderInlines(iterable $inlines): string 81*8ec9a8f2SSungbin Jeon { 82*8ec9a8f2SSungbin Jeon $result = []; 83*8ec9a8f2SSungbin Jeon foreach ($inlines as $inline) { 84*8ec9a8f2SSungbin Jeon $result[] = $this->renderInline($inline); 85*8ec9a8f2SSungbin Jeon } 86*8ec9a8f2SSungbin Jeon 87*8ec9a8f2SSungbin Jeon return \implode('', $result); 88*8ec9a8f2SSungbin Jeon } 89*8ec9a8f2SSungbin Jeon 90*8ec9a8f2SSungbin Jeon /** 91*8ec9a8f2SSungbin Jeon * @param AbstractBlock $block 92*8ec9a8f2SSungbin Jeon * @param bool $inTightList 93*8ec9a8f2SSungbin Jeon * 94*8ec9a8f2SSungbin Jeon * @throws \RuntimeException 95*8ec9a8f2SSungbin Jeon * 96*8ec9a8f2SSungbin Jeon * @return string 97*8ec9a8f2SSungbin Jeon */ 98*8ec9a8f2SSungbin Jeon public function renderBlock(AbstractBlock $block, bool $inTightList = false): string 99*8ec9a8f2SSungbin Jeon { 100*8ec9a8f2SSungbin Jeon $renderers = $this->environment->getBlockRenderersForClass(\get_class($block)); 101*8ec9a8f2SSungbin Jeon 102*8ec9a8f2SSungbin Jeon /** @var BlockRendererInterface $renderer */ 103*8ec9a8f2SSungbin Jeon foreach ($renderers as $renderer) { 104*8ec9a8f2SSungbin Jeon if (($result = $renderer->render($block, $this, $inTightList)) !== null) { 105*8ec9a8f2SSungbin Jeon return $result; 106*8ec9a8f2SSungbin Jeon } 107*8ec9a8f2SSungbin Jeon } 108*8ec9a8f2SSungbin Jeon 109*8ec9a8f2SSungbin Jeon throw new \RuntimeException('Unable to find corresponding renderer for block type ' . \get_class($block)); 110*8ec9a8f2SSungbin Jeon } 111*8ec9a8f2SSungbin Jeon 112*8ec9a8f2SSungbin Jeon /** 113*8ec9a8f2SSungbin Jeon * @param AbstractBlock[] $blocks 114*8ec9a8f2SSungbin Jeon * @param bool $inTightList 115*8ec9a8f2SSungbin Jeon * 116*8ec9a8f2SSungbin Jeon * @return string 117*8ec9a8f2SSungbin Jeon */ 118*8ec9a8f2SSungbin Jeon public function renderBlocks(iterable $blocks, bool $inTightList = false): string 119*8ec9a8f2SSungbin Jeon { 120*8ec9a8f2SSungbin Jeon $result = []; 121*8ec9a8f2SSungbin Jeon foreach ($blocks as $block) { 122*8ec9a8f2SSungbin Jeon $result[] = $this->renderBlock($block, $inTightList); 123*8ec9a8f2SSungbin Jeon } 124*8ec9a8f2SSungbin Jeon 125*8ec9a8f2SSungbin Jeon $separator = $this->getOption('block_separator', "\n"); 126*8ec9a8f2SSungbin Jeon 127*8ec9a8f2SSungbin Jeon return \implode($separator, $result); 128*8ec9a8f2SSungbin Jeon } 129*8ec9a8f2SSungbin Jeon}