xref: /plugin/commonmark/src/Dokuwiki/Plugin/Commonmark/DWRenderer.php (revision 94a075ee9c5821074e0d7b2c07e7e230fefe6cd9)
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
18*94a075eeSSungbin Jeonuse League\CommonMark\Node\Block\AbstractBlock;
19*94a075eeSSungbin Jeonuse League\CommonMark\Renderer\NodeRendererInterface;
20*94a075eeSSungbin Jeonuse League\CommonMark\Node\Inline\AbstractInline;
21*94a075eeSSungbin Jeonuse League\CommonMark\Renderer\ChildNodeRendererInterface;
22*94a075eeSSungbin Jeonuse League\CommonMark\Environment\EnvironmentInterface;
238ec9a8f2SSungbin Jeon
248ec9a8f2SSungbin Jeon/**
258ec9a8f2SSungbin Jeon * Renders a parsed AST to DW
268ec9a8f2SSungbin Jeon */
27*94a075eeSSungbin Jeonfinal class DWRenderer implements ChildNodeRendererInterface
288ec9a8f2SSungbin Jeon{
298ec9a8f2SSungbin Jeon    /**
308ec9a8f2SSungbin Jeon     * @var EnvironmentInterface
318ec9a8f2SSungbin Jeon     */
328ec9a8f2SSungbin Jeon    protected $environment;
338ec9a8f2SSungbin Jeon
348ec9a8f2SSungbin Jeon    /**
358ec9a8f2SSungbin Jeon     * @param EnvironmentInterface $environment
368ec9a8f2SSungbin Jeon     */
378ec9a8f2SSungbin Jeon    public function __construct(EnvironmentInterface $environment)
388ec9a8f2SSungbin Jeon    {
398ec9a8f2SSungbin Jeon        $this->environment = $environment;
408ec9a8f2SSungbin Jeon    }
418ec9a8f2SSungbin Jeon
42*94a075eeSSungbin Jeon    public function getBlockSeparator(): string
43*94a075eeSSungbin Jeon    {
44*94a075eeSSungbin Jeon        return $this->environment->getConfiguration()->get('renderer/block_separator');
45*94a075eeSSungbin Jeon    }
46*94a075eeSSungbin Jeon
47*94a075eeSSungbin Jeon    public function getInnerSeparator(): string
48*94a075eeSSungbin Jeon    {
49*94a075eeSSungbin Jeon        return $this->environment->getConfiguration()->get('renderer/inner_separator');
50*94a075eeSSungbin Jeon    }
51*94a075eeSSungbin Jeon
528ec9a8f2SSungbin Jeon    /**
538ec9a8f2SSungbin Jeon     * @param string $option
548ec9a8f2SSungbin Jeon     * @param mixed  $default
558ec9a8f2SSungbin Jeon     *
568ec9a8f2SSungbin Jeon     * @return mixed|null
578ec9a8f2SSungbin Jeon     */
588ec9a8f2SSungbin Jeon    public function getOption(string $option, $default = null)
598ec9a8f2SSungbin Jeon    {
608ec9a8f2SSungbin Jeon        return $this->environment->getConfig('renderer/' . $option, $default);
618ec9a8f2SSungbin Jeon    }
628ec9a8f2SSungbin Jeon
63*94a075eeSSungbin Jeon    public function renderNodes(iterable $nodes): string
648ec9a8f2SSungbin Jeon    {
65*94a075eeSSungbin Jeon        $output = '';
668ec9a8f2SSungbin Jeon
67*94a075eeSSungbin Jeon        $isFirstItem = true;
68*94a075eeSSungbin Jeon
69*94a075eeSSungbin Jeon        foreach ($nodes as $node) {
70*94a075eeSSungbin Jeon            if (! $isFirstItem && $node instanceof AbstractBlock) {
71*94a075eeSSungbin Jeon                $output .= $this->getBlockSeparator();
72*94a075eeSSungbin Jeon            }
73*94a075eeSSungbin Jeon
74*94a075eeSSungbin Jeon            $output .= $this->renderNode($node);
75*94a075eeSSungbin Jeon
76*94a075eeSSungbin Jeon            $isFirstItem = false;
77*94a075eeSSungbin Jeon        }
78*94a075eeSSungbin Jeon
79*94a075eeSSungbin Jeon        return $output;
80*94a075eeSSungbin Jeon    }
81*94a075eeSSungbin Jeon
82*94a075eeSSungbin Jeon    public function renderNode(Node $node)
83*94a075eeSSungbin Jeon    {
84*94a075eeSSungbin Jeon        $renderers = $this->environment->getRenderersForClass(\get_class($node));
85*94a075eeSSungbin Jeon
868ec9a8f2SSungbin Jeon        foreach ($renderers as $renderer) {
87*94a075eeSSungbin Jeon            \assert($renderer instanceof NodeRendererInterface);
88*94a075eeSSungbin Jeon            if (($result = $renderer->render($node, $this)) !== null) {
898ec9a8f2SSungbin Jeon                return $result;
908ec9a8f2SSungbin Jeon            }
918ec9a8f2SSungbin Jeon        }
928ec9a8f2SSungbin Jeon
93*94a075eeSSungbin Jeon        throw new \RuntimeException('Unable to find corresponding renderer for node type ' . \get_class($node));
94*94a075eeSSungbin Jeon
958ec9a8f2SSungbin Jeon    }
968ec9a8f2SSungbin Jeon
978ec9a8f2SSungbin Jeon
988ec9a8f2SSungbin Jeon}