xref: /plugin/commonmark/src/Dokuwiki/Plugin/Commonmark/Commonmark.php (revision 80734199223681576dd58b9113e35ae4786f6692)
18ec9a8f2SSungbin Jeon<?php
28ec9a8f2SSungbin Jeon
38ec9a8f2SSungbin Jeonnamespace Dokuwiki\Plugin\Commonmark;
48ec9a8f2SSungbin Jeon
594a075eeSSungbin Jeonuse League\CommonMark\Environment\Environment;
694a075eeSSungbin Jeonuse League\CommonMark\Parser\MarkdownParser;
71e536badSSungbin Jeonuse Dokuwiki\Plugin\Commonmark\Extension\CommonmarkToDokuwikiExtension;
8f46768a8SSungbin Jeonuse Dokuwiki\Plugin\Commonmark\Extension\FootnoteToDokuwikiExtension;
978c882e7SSungbin Jeonuse League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
10656793f4SSungbin Jeonuse Dokuwiki\Plugin\Commonmark\Extension\TableExtension;
1181da5a38SSungbin Jeonuse League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
1281da5a38SSungbin Jeonuse League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
138ec9a8f2SSungbin Jeon
148ec9a8f2SSungbin Jeonclass Commonmark {
15*80734199SSungbin Jeon    public static function RendtoDW($markdown, $frontmatter_tag = 'off'): array {
16*80734199SSungbin Jeon        // heading info
17*80734199SSungbin Jeon        $headingInfo = [];
18*80734199SSungbin Jeon
19*80734199SSungbin Jeon        // create environment
208ec9a8f2SSungbin Jeon        $environment = self::createDWEnvironment();
218ec9a8f2SSungbin Jeon
22*80734199SSungbin Jeon        // create parser
2394a075eeSSungbin Jeon        $parser = new MarkdownParser($environment);
24*80734199SSungbin Jeon        // create Dokuwiki Renderer
258ec9a8f2SSungbin Jeon        $DWRenderer = new DWRenderer($environment);
268ec9a8f2SSungbin Jeon
2781da5a38SSungbin Jeon        # separate frontmatter and main text
2881da5a38SSungbin Jeon        $FMresult = self::ExtractFrontmatter($markdown);
2981da5a38SSungbin Jeon        $frontmatter = $FMresult->getFrontMatter();
3081da5a38SSungbin Jeon        $markdownOnly = $FMresult->getContent();
318bcf583bSSungbin Jeon        $tagStr = ''; # initialize tag string
3281da5a38SSungbin Jeon        //print_r($frontmatter);
3381da5a38SSungbin Jeon
3481da5a38SSungbin Jeon        # extract tags only
35022ce692SSungbin Jeon        if(!empty($frontmatter) && gettype($frontmatter) == "array") { // frontmatter must be array if valid
36022ce692SSungbin Jeon            if (array_key_exists('tags', $frontmatter)) {
3781da5a38SSungbin Jeon                $tags = $frontmatter['tags'];
387569cca4SSungbin Jeon                $tagStr = "{{tag>";
3981da5a38SSungbin Jeon                foreach ($tags as $tag) {
4081da5a38SSungbin Jeon                    $tagStr = $tagStr. "\"". $tag. "\" ";
4181da5a38SSungbin Jeon                }
424384789bSSungbin Jeon                $tagStr = $tagStr. "}}";
438bcf583bSSungbin Jeon            }
44022ce692SSungbin Jeon        }
4581da5a38SSungbin Jeon
46ac4825fcSSungbin Jeon        // pre-processing: convert slash inside wikilink to colon & image wikilinks
475ba4c344SSungbin Jeon        $markdownOnly = self::ParseDokuwikiWikilinks($markdownOnly);
4881da5a38SSungbin Jeon        $document = $parser->parse($markdownOnly);
4981da5a38SSungbin Jeon        $renderResult = $DWRenderer->renderNode($document);
50*80734199SSungbin Jeon        // debug
51*80734199SSungbin Jeon        foreach ($document->iterator() as $node) {
52*80734199SSungbin Jeon            // if(strpos(get_class($node),'Block') == true) {
53*80734199SSungbin Jeon            //    echo 'Current node: ' . get_class($node) . '(startline: ' . $node->getStartLine() . ', endline: ' . $node->getEndLine() . ") \n";
54*80734199SSungbin Jeon            // }
55*80734199SSungbin Jeon            // else {
56*80734199SSungbin Jeon            //    echo 'Current node: ' . get_class($node) . "\n";
57*80734199SSungbin Jeon            // }
58*80734199SSungbin Jeon            if(get_class($node) == 'League\CommonMark\Extension\CommonMark\Node\Block\Heading') {
59*80734199SSungbin Jeon                $headingInfo[$node->firstChild()->getLiteral()] = array(
60*80734199SSungbin Jeon                    'level' => $node->getLevel(),
61*80734199SSungbin Jeon                    'startline' => $node->getStartLine(),
62*80734199SSungbin Jeon                    'endline' => $node->getEndLine()
63*80734199SSungbin Jeon                );
64*80734199SSungbin Jeon            }
65*80734199SSungbin Jeon        }
6681da5a38SSungbin Jeon
677569cca4SSungbin Jeon        if($frontmatter_tag == 'off') {
68*80734199SSungbin Jeon            return array('text'=>$renderResult, 'heading'=>$headingInfo);
697569cca4SSungbin Jeon        } elseif($frontmatter_tag == 'upper') {
70*80734199SSungbin Jeon            return array('text'=>$tagStr."\n\n".$renderResult, 'heading'=>$headingInfo);
71*80734199SSungbin Jeon            //return $tagStr."\n\n".$renderResult;
727569cca4SSungbin Jeon        } else {
73*80734199SSungbin Jeon            return array('text'=>$renderResult."\n\n".$tagStr, 'heading'=>$headingInfo);
74*80734199SSungbin Jeon            //return $renderResult."\n\n".$tagStr;
757569cca4SSungbin Jeon        }
7681da5a38SSungbin Jeon    }
7781da5a38SSungbin Jeon
7881da5a38SSungbin Jeon    // Temporary implementation: separate method for frontmatter extraction
79*80734199SSungbin Jeon    // Since some parsed frontmatter info must be included in main text, it should be merged
8081da5a38SSungbin Jeon    public static function ExtractFrontmatter($markdown) {
8181da5a38SSungbin Jeon        $frontMatterExtension = new FrontMatterExtension();
8281da5a38SSungbin Jeon        $result = $frontMatterExtension->getFrontMatterParser()->parse($markdown);
8381da5a38SSungbin Jeon
8481da5a38SSungbin Jeon        return $result;
858ec9a8f2SSungbin Jeon    }
868ec9a8f2SSungbin Jeon
87ac4825fcSSungbin Jeon    // replace slash in MD wikilink to colon to match DW syntax
885ba4c344SSungbin Jeon    public static function ParseDokuwikiWikilinks($text) {
89ac4825fcSSungbin Jeon        $pattern = "/(?:\[\[\b|(?!^)\G)[^\/|\]]*\K\/+/";
90ac4825fcSSungbin Jeon        $result = preg_replace($pattern, ":", $text);
915ba4c344SSungbin Jeon        $pattern = "/!\[\[(.*)\]\]/";
92ac4825fcSSungbin Jeon        $result = preg_replace($pattern, '{{$1}}', $result);
93ac4825fcSSungbin Jeon        return $result;
94ac4825fcSSungbin Jeon    }
95ac4825fcSSungbin Jeon
968ec9a8f2SSungbin Jeon    public static function createDWEnvironment(): Environment {
97b0a36678SSungbin Jeon        $config = [];
98b0a36678SSungbin Jeon        $environment = new Environment($config);
998ec9a8f2SSungbin Jeon        $environment->addExtension(new CommonMarkToDokuWikiExtension());
100f46768a8SSungbin Jeon        $environment->addExtension(new FootnoteToDokuwikiExtension());
10178c882e7SSungbin Jeon        $environment->addExtension(new StrikethroughExtension());
102656793f4SSungbin Jeon        $environment->addExtension(new TableExtension());
10381da5a38SSungbin Jeon        $environment->addExtension(new FrontMatterExtension());
104f46768a8SSungbin Jeon
105f46768a8SSungbin Jeon        $environment->mergeConfig([
1068f24791eSSungbin Jeon            'html_input' => 'allow',
107f46768a8SSungbin Jeon        ]);
1088ec9a8f2SSungbin Jeon
1098ec9a8f2SSungbin Jeon        return $environment;
1108ec9a8f2SSungbin Jeon    }
1118ec9a8f2SSungbin Jeon}
1128ec9a8f2SSungbin Jeon
1138ec9a8f2SSungbin Jeon?>