1<?php
2
3namespace Dokuwiki\Plugin\Commonmark;
4
5use League\CommonMark\Environment\Environment;
6use League\CommonMark\Parser\MarkdownParser;
7use Dokuwiki\Plugin\Commonmark\Extension\CommonmarkToDokuwikiExtension;
8use Dokuwiki\Plugin\Commonmark\Extension\FootnoteToDokuwikiExtension;
9use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
10use Dokuwiki\Plugin\Commonmark\Extension\TableExtension;
11use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
12use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
13
14class Commonmark {
15    public static function RendtoDW($markdown, $frontmatter_tag = 'off'): string {
16        # create environment
17        $environment = self::createDWEnvironment();
18
19        # create parser
20        $parser = new MarkdownParser($environment);
21        # create Dokuwiki Renderer
22        $DWRenderer = new DWRenderer($environment);
23
24        # separate frontmatter and main text
25        $FMresult = self::ExtractFrontmatter($markdown);
26        $frontmatter = $FMresult->getFrontMatter();
27        $markdownOnly = $FMresult->getContent();
28        $tagStr = ''; # initialize tag string
29        //print_r($frontmatter);
30
31        # extract tags only
32        if(!empty($frontmatter) && gettype($frontmatter) == "array") { // frontmatter must be array if valid
33            if (array_key_exists('tags', $frontmatter)) {
34                $tags = $frontmatter['tags'];
35                $tagStr = "{{tag>";
36                foreach ($tags as $tag) {
37                    $tagStr = $tagStr. "\"". $tag. "\" ";
38                }
39                $tagStr = $tagStr. "}}";
40                //echo $tagStr;
41            }
42        }
43
44        // pre-processing: convert slash inside wikilink to colon & image wikilinks
45        $markdownOnly = self::ParseDokuwikiWikilinks($markdownOnly);
46        $document = $parser->parse($markdownOnly);
47        $renderResult = $DWRenderer->renderNode($document);
48
49        if($frontmatter_tag == 'off') {
50            return $renderResult;
51        } elseif($frontmatter_tag == 'upper') {
52            return $tagStr."\n\n".$renderResult;
53        } else {
54            return $renderResult."\n\n".$tagStr;
55        }
56    }
57
58    // Temporary implementation: separate method for frontmatter extraction
59    // Since som parsed frontmatter info must be included in main text, it should be merged
60    public static function ExtractFrontmatter($markdown) {
61        $frontMatterExtension = new FrontMatterExtension();
62        $result = $frontMatterExtension->getFrontMatterParser()->parse($markdown);
63
64        return $result;
65    }
66
67    // replace slash in MD wikilink to colon to match DW syntax
68    public static function ParseDokuwikiWikilinks($text) {
69        $pattern = "/(?:\[\[\b|(?!^)\G)[^\/|\]]*\K\/+/";
70        $result = preg_replace($pattern, ":", $text);
71        $pattern = "/!\[\[(.*)\]\]/";
72        $result = preg_replace($pattern, '{{$1}}', $result);
73        return $result;
74    }
75
76    public static function createDWEnvironment(): Environment {
77        $config = [];
78        $environment = new Environment($config);
79        $environment->addExtension(new CommonMarkToDokuWikiExtension());
80        $environment->addExtension(new FootnoteToDokuwikiExtension());
81        $environment->addExtension(new StrikethroughExtension());
82        $environment->addExtension(new TableExtension());
83        $environment->addExtension(new FrontMatterExtension());
84
85        $environment->mergeConfig([
86            'html_input' => 'allow',
87        ]);
88
89        return $environment;
90    }
91}
92
93?>