xref: /plugin/commonmark/src/Dokuwiki/Plugin/Commonmark/DWRenderer.php (revision 0f46309a0ac22fdc4d1c91b56eae39d6eedaaf00)
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*0f46309aSChalix    public function getOption(string $option, bool $getCommonmarkOption = false)
618ec9a8f2SSungbin Jeon    {
62*0f46309aSChalix        if ($getCommonmarkOption) {
63*0f46309aSChalix            return $this->environment->getConfiguration()->get('commonmark/' . $option);
64*0f46309aSChalix        }
65c73f5e4dSChalix        return $this->environment->getConfiguration()->get('renderer/' . $option);
66c73f5e4dSChalix        // Note: function 'get' does not have a parameter 'default' any more, so I removed it.
678ec9a8f2SSungbin Jeon    }
688ec9a8f2SSungbin Jeon
6994a075eeSSungbin Jeon    public function renderNodes(iterable $nodes): string
708ec9a8f2SSungbin Jeon    {
7194a075eeSSungbin Jeon        $output = '';
728ec9a8f2SSungbin Jeon
7394a075eeSSungbin Jeon        $isFirstItem = true;
7494a075eeSSungbin Jeon
7594a075eeSSungbin Jeon        foreach ($nodes as $node) {
7604daf66eSAdrien Beau            if (! $isFirstItem && $node instanceof AbstractBlock) {
7794a075eeSSungbin Jeon                $output .= $this->getBlockSeparator();
7894a075eeSSungbin Jeon            }
7994a075eeSSungbin Jeon
8094a075eeSSungbin Jeon            $output .= $this->renderNode($node);
8194a075eeSSungbin Jeon
8294a075eeSSungbin Jeon            $isFirstItem = false;
8394a075eeSSungbin Jeon        }
8494a075eeSSungbin Jeon
8594a075eeSSungbin Jeon        return $output;
8694a075eeSSungbin Jeon    }
8794a075eeSSungbin Jeon
8894a075eeSSungbin Jeon    public function renderNode(Node $node)
8994a075eeSSungbin Jeon    {
9094a075eeSSungbin Jeon        $renderers = $this->environment->getRenderersForClass(\get_class($node));
9194a075eeSSungbin Jeon
928ec9a8f2SSungbin Jeon        foreach ($renderers as $renderer) {
9394a075eeSSungbin Jeon            \assert($renderer instanceof NodeRendererInterface);
9494a075eeSSungbin Jeon            if (($result = $renderer->render($node, $this)) !== null) {
958ec9a8f2SSungbin Jeon                return $result;
968ec9a8f2SSungbin Jeon            }
978ec9a8f2SSungbin Jeon        }
988ec9a8f2SSungbin Jeon
9994a075eeSSungbin Jeon        throw new \RuntimeException('Unable to find corresponding renderer for node type ' . \get_class($node));
10094a075eeSSungbin Jeon
1018ec9a8f2SSungbin Jeon    }
1028ec9a8f2SSungbin Jeon
1038ec9a8f2SSungbin Jeon
1048ec9a8f2SSungbin Jeon}