xref: /plugin/commonmark/src/Dokuwiki/Plugin/Commonmark/DWRenderer.php (revision 04daf66e74fc793b6e6c32f98097335e0dc22075)
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     */
608ec9a8f2SSungbin Jeon    public function getOption(string $option, $default = null)
618ec9a8f2SSungbin Jeon    {
62b0a36678SSungbin Jeon        return $this->environment->getConfiguration()->get('renderer/' . $option, $default);
638ec9a8f2SSungbin Jeon    }
648ec9a8f2SSungbin Jeon
6594a075eeSSungbin Jeon    public function renderNodes(iterable $nodes): string
668ec9a8f2SSungbin Jeon    {
6794a075eeSSungbin Jeon        $output = '';
688ec9a8f2SSungbin Jeon
6994a075eeSSungbin Jeon        $isFirstItem = true;
7094a075eeSSungbin Jeon
7194a075eeSSungbin Jeon        foreach ($nodes as $node) {
72*04daf66eSAdrien Beau            if (! $isFirstItem && $node instanceof AbstractBlock) {
7394a075eeSSungbin Jeon                $output .= $this->getBlockSeparator();
7494a075eeSSungbin Jeon            }
7594a075eeSSungbin Jeon
7694a075eeSSungbin Jeon            $output .= $this->renderNode($node);
7794a075eeSSungbin Jeon
7894a075eeSSungbin Jeon            $isFirstItem = false;
7994a075eeSSungbin Jeon        }
8094a075eeSSungbin Jeon
8194a075eeSSungbin Jeon        return $output;
8294a075eeSSungbin Jeon    }
8394a075eeSSungbin Jeon
8494a075eeSSungbin Jeon    public function renderNode(Node $node)
8594a075eeSSungbin Jeon    {
8694a075eeSSungbin Jeon        $renderers = $this->environment->getRenderersForClass(\get_class($node));
8794a075eeSSungbin Jeon
888ec9a8f2SSungbin Jeon        foreach ($renderers as $renderer) {
8994a075eeSSungbin Jeon            \assert($renderer instanceof NodeRendererInterface);
9094a075eeSSungbin Jeon            if (($result = $renderer->render($node, $this)) !== null) {
918ec9a8f2SSungbin Jeon                return $result;
928ec9a8f2SSungbin Jeon            }
938ec9a8f2SSungbin Jeon        }
948ec9a8f2SSungbin Jeon
9594a075eeSSungbin Jeon        throw new \RuntimeException('Unable to find corresponding renderer for node type ' . \get_class($node));
9694a075eeSSungbin Jeon
978ec9a8f2SSungbin Jeon    }
988ec9a8f2SSungbin Jeon
998ec9a8f2SSungbin Jeon
1008ec9a8f2SSungbin Jeon}