xref: /plugin/commonmark/src/Dokuwiki/Plugin/Commonmark/DWRenderer.php (revision 94a075ee9c5821074e0d7b2c07e7e230fefe6cd9)
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\Node\Block\AbstractBlock;
19use League\CommonMark\Renderer\NodeRendererInterface;
20use League\CommonMark\Node\Inline\AbstractInline;
21use League\CommonMark\Renderer\ChildNodeRendererInterface;
22use League\CommonMark\Environment\EnvironmentInterface;
23
24/**
25 * Renders a parsed AST to DW
26 */
27final class DWRenderer implements ChildNodeRendererInterface
28{
29    /**
30     * @var EnvironmentInterface
31     */
32    protected $environment;
33
34    /**
35     * @param EnvironmentInterface $environment
36     */
37    public function __construct(EnvironmentInterface $environment)
38    {
39        $this->environment = $environment;
40    }
41
42    public function getBlockSeparator(): string
43    {
44        return $this->environment->getConfiguration()->get('renderer/block_separator');
45    }
46
47    public function getInnerSeparator(): string
48    {
49        return $this->environment->getConfiguration()->get('renderer/inner_separator');
50    }
51
52    /**
53     * @param string $option
54     * @param mixed  $default
55     *
56     * @return mixed|null
57     */
58    public function getOption(string $option, $default = null)
59    {
60        return $this->environment->getConfig('renderer/' . $option, $default);
61    }
62
63    public function renderNodes(iterable $nodes): string
64    {
65        $output = '';
66
67        $isFirstItem = true;
68
69        foreach ($nodes as $node) {
70            if (! $isFirstItem && $node instanceof AbstractBlock) {
71                $output .= $this->getBlockSeparator();
72            }
73
74            $output .= $this->renderNode($node);
75
76            $isFirstItem = false;
77        }
78
79        return $output;
80    }
81
82    public function renderNode(Node $node)
83    {
84        $renderers = $this->environment->getRenderersForClass(\get_class($node));
85
86        foreach ($renderers as $renderer) {
87            \assert($renderer instanceof NodeRendererInterface);
88            if (($result = $renderer->render($node, $this)) !== null) {
89                return $result;
90            }
91        }
92
93        throw new \RuntimeException('Unable to find corresponding renderer for node type ' . \get_class($node));
94
95    }
96
97
98}