xref: /plugin/commonmark/src/Dokuwiki/Plugin/Commonmark/DWRenderer.php (revision c73f5e4d729e7f2b7f7188b6831080ded2816d88)
18ec9a8f2SSungbin Jeon<?php
28ec9a8f2SSungbin Jeon
38ec9a8f2SSungbin Jeon/*
48ec9a8f2SSungbin Jeon * This file is part of the clockoon/dokuwiki-commonmark-plugin package.
58ec9a8f2SSungbin Jeon *
68ec9a8f2SSungbin Jeon * (c) Sungbin Jeon <clockoon@gmail.com>
78ec9a8f2SSungbin Jeon *
88ec9a8f2SSungbin Jeon * Original code based on the followings:
98ec9a8f2SSungbin Jeon * - CommonMark JS reference parser (https://bitly.com/commonmark-js) (c) John MacFarlane
108ec9a8f2SSungbin Jeon * - league/commonmark (https://github.com/thephpleague/commonmark) (c) Colin O'Dell <colinodell@gmail.com>
118ec9a8f2SSungbin Jeon *
128ec9a8f2SSungbin Jeon * For the full copyright and license information, please view the LICENSE
138ec9a8f2SSungbin Jeon * file that was distributed with this source code.
148ec9a8f2SSungbin Jeon */
158ec9a8f2SSungbin Jeon
168ec9a8f2SSungbin Jeonnamespace Dokuwiki\Plugin\Commonmark;
178ec9a8f2SSungbin Jeon
1894a075eeSSungbin Jeonuse League\CommonMark\Node\Block\AbstractBlock;
1994a075eeSSungbin Jeonuse League\CommonMark\Renderer\NodeRendererInterface;
2094a075eeSSungbin Jeonuse League\CommonMark\Node\Inline\AbstractInline;
2194a075eeSSungbin Jeonuse League\CommonMark\Renderer\ChildNodeRendererInterface;
2294a075eeSSungbin Jeonuse League\CommonMark\Environment\EnvironmentInterface;
23b0a36678SSungbin Jeonuse League\CommonMark\Node\Block\Document;
24b0a36678SSungbin Jeonuse League\CommonMark\Node\Node;
258ec9a8f2SSungbin Jeon
268ec9a8f2SSungbin Jeon/**
278ec9a8f2SSungbin Jeon * Renders a parsed AST to DW
288ec9a8f2SSungbin Jeon */
2994a075eeSSungbin Jeonfinal class DWRenderer implements ChildNodeRendererInterface
308ec9a8f2SSungbin Jeon{
318ec9a8f2SSungbin Jeon    /**
328ec9a8f2SSungbin Jeon     * @var EnvironmentInterface
338ec9a8f2SSungbin Jeon     */
348ec9a8f2SSungbin Jeon    protected $environment;
358ec9a8f2SSungbin Jeon
368ec9a8f2SSungbin Jeon    /**
378ec9a8f2SSungbin Jeon     * @param EnvironmentInterface $environment
388ec9a8f2SSungbin Jeon     */
398ec9a8f2SSungbin Jeon    public function __construct(EnvironmentInterface $environment)
408ec9a8f2SSungbin Jeon    {
418ec9a8f2SSungbin Jeon        $this->environment = $environment;
428ec9a8f2SSungbin Jeon    }
438ec9a8f2SSungbin Jeon
4494a075eeSSungbin Jeon    public function getBlockSeparator(): string
4594a075eeSSungbin Jeon    {
4694a075eeSSungbin Jeon        return $this->environment->getConfiguration()->get('renderer/block_separator');
4794a075eeSSungbin Jeon    }
4894a075eeSSungbin Jeon
4994a075eeSSungbin Jeon    public function getInnerSeparator(): string
5094a075eeSSungbin Jeon    {
5194a075eeSSungbin Jeon        return $this->environment->getConfiguration()->get('renderer/inner_separator');
5294a075eeSSungbin Jeon    }
5394a075eeSSungbin Jeon
548ec9a8f2SSungbin Jeon    /**
558ec9a8f2SSungbin Jeon     * @param string $option
568ec9a8f2SSungbin Jeon     * @param mixed  $default
578ec9a8f2SSungbin Jeon     *
588ec9a8f2SSungbin Jeon     * @return mixed|null
598ec9a8f2SSungbin Jeon     */
60*c73f5e4dSChalix    public function getOption(string $option)
618ec9a8f2SSungbin Jeon    {
62*c73f5e4dSChalix        return $this->environment->getConfiguration()->get('renderer/' . $option);
63*c73f5e4dSChalix        // Note: function 'get' does not have a parameter 'default' any more, so I removed it.
648ec9a8f2SSungbin Jeon    }
658ec9a8f2SSungbin Jeon
6694a075eeSSungbin Jeon    public function renderNodes(iterable $nodes): string
678ec9a8f2SSungbin Jeon    {
6894a075eeSSungbin Jeon        $output = '';
698ec9a8f2SSungbin Jeon
7094a075eeSSungbin Jeon        $isFirstItem = true;
7194a075eeSSungbin Jeon
7294a075eeSSungbin Jeon        foreach ($nodes as $node) {
7304daf66eSAdrien Beau            if (! $isFirstItem && $node instanceof AbstractBlock) {
7494a075eeSSungbin Jeon                $output .= $this->getBlockSeparator();
7594a075eeSSungbin Jeon            }
7694a075eeSSungbin Jeon
7794a075eeSSungbin Jeon            $output .= $this->renderNode($node);
7894a075eeSSungbin Jeon
7994a075eeSSungbin Jeon            $isFirstItem = false;
8094a075eeSSungbin Jeon        }
8194a075eeSSungbin Jeon
8294a075eeSSungbin Jeon        return $output;
8394a075eeSSungbin Jeon    }
8494a075eeSSungbin Jeon
8594a075eeSSungbin Jeon    public function renderNode(Node $node)
8694a075eeSSungbin Jeon    {
8794a075eeSSungbin Jeon        $renderers = $this->environment->getRenderersForClass(\get_class($node));
8894a075eeSSungbin Jeon
898ec9a8f2SSungbin Jeon        foreach ($renderers as $renderer) {
9094a075eeSSungbin Jeon            \assert($renderer instanceof NodeRendererInterface);
9194a075eeSSungbin Jeon            if (($result = $renderer->render($node, $this)) !== null) {
928ec9a8f2SSungbin Jeon                return $result;
938ec9a8f2SSungbin Jeon            }
948ec9a8f2SSungbin Jeon        }
958ec9a8f2SSungbin Jeon
9694a075eeSSungbin Jeon        throw new \RuntimeException('Unable to find corresponding renderer for node type ' . \get_class($node));
9794a075eeSSungbin Jeon
988ec9a8f2SSungbin Jeon    }
998ec9a8f2SSungbin Jeon
1008ec9a8f2SSungbin Jeon
1018ec9a8f2SSungbin Jeon}