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'): array { 16 // heading info 17 $headingInfo = []; 18 19 // create environment 20 $environment = self::createDWEnvironment(); 21 22 // create parser 23 $parser = new MarkdownParser($environment); 24 // create Dokuwiki Renderer 25 $DWRenderer = new DWRenderer($environment); 26 27 # separate frontmatter and main text 28 $FMresult = self::ExtractFrontmatter($markdown); 29 $frontmatter = $FMresult->getFrontMatter(); 30 $markdownOnly = $FMresult->getContent(); 31 $tagStr = ''; # initialize tag string 32 //print_r($frontmatter); 33 34 # extract tags only 35 if(!empty($frontmatter) && gettype($frontmatter) == "array") { // frontmatter must be array if valid 36 if (array_key_exists('tags', $frontmatter)) { 37 $tags = $frontmatter['tags']; 38 $tagStr = "{{tag>"; 39 foreach ($tags as $tag) { 40 $tagStr = $tagStr. "\"". $tag. "\" "; 41 } 42 $tagStr = $tagStr. "}}"; 43 } 44 } 45 46 // pre-processing: convert slash inside wikilink to colon & image wikilinks 47 $markdownOnly = self::ParseDokuwikiWikilinks($markdownOnly); 48 $document = $parser->parse($markdownOnly); 49 $renderResult = $DWRenderer->renderNode($document); 50 // debug 51 foreach ($document->iterator() as $node) { 52 // if(strpos(get_class($node),'Block') == true) { 53 // echo 'Current node: ' . get_class($node) . '(startline: ' . $node->getStartLine() . ', endline: ' . $node->getEndLine() . ") \n"; 54 // } 55 // else { 56 // echo 'Current node: ' . get_class($node) . "\n"; 57 // } 58 if(get_class($node) == 'League\CommonMark\Extension\CommonMark\Node\Block\Heading') { 59 $headingInfo[$node->firstChild()->getLiteral()] = array( 60 'level' => $node->getLevel(), 61 'startline' => $node->getStartLine(), 62 'endline' => $node->getEndLine() 63 ); 64 } 65 } 66 67 if($frontmatter_tag == 'off') { 68 return array('text'=>$renderResult, 'heading'=>$headingInfo); 69 } elseif($frontmatter_tag == 'upper') { 70 return array('text'=>$tagStr."\n\n".$renderResult, 'heading'=>$headingInfo); 71 //return $tagStr."\n\n".$renderResult; 72 } else { 73 return array('text'=>$renderResult."\n\n".$tagStr, 'heading'=>$headingInfo); 74 //return $renderResult."\n\n".$tagStr; 75 } 76 } 77 78 // Temporary implementation: separate method for frontmatter extraction 79 // Since some parsed frontmatter info must be included in main text, it should be merged 80 public static function ExtractFrontmatter($markdown) { 81 $frontMatterExtension = new FrontMatterExtension(); 82 $result = $frontMatterExtension->getFrontMatterParser()->parse($markdown); 83 84 return $result; 85 } 86 87 // replace slash in MD wikilink to colon to match DW syntax 88 public static function ParseDokuwikiWikilinks($text) { 89 $pattern = "/(?:\[\[\b|(?!^)\G)[^\/|\]]*\K\/+/"; 90 $result = preg_replace($pattern, ":", $text); 91 $pattern = "/!\[\[(.*)\]\]/"; 92 $result = preg_replace($pattern, '{{$1}}', $result); 93 return $result; 94 } 95 96 public static function createDWEnvironment(): Environment { 97 $config = []; 98 $environment = new Environment($config); 99 $environment->addExtension(new CommonMarkToDokuWikiExtension()); 100 $environment->addExtension(new FootnoteToDokuwikiExtension()); 101 $environment->addExtension(new StrikethroughExtension()); 102 $environment->addExtension(new TableExtension()); 103 $environment->addExtension(new FrontMatterExtension()); 104 105 $environment->mergeConfig([ 106 'html_input' => 'allow', 107 ]); 108 109 return $environment; 110 } 111} 112 113?>