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