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 if(get_class($node->firstChild()) == 'League\CommonMark\Extension\CommonMark\Node\Inline\Link') { 60 // set headingName as [[<Url>|<text>]] 61 $headingName = '[['.$node->firstChild()->getUrl() . '|' . $node->firstChild()->firstChild()->getLiteral() . ']]'; 62 } else { 63 $headingName = $node->firstChild()->getLiteral(); 64 } 65 $headingInfo[$headingName] = array( 66 'level' => $node->getLevel(), 67 'startline' => $node->getStartLine(), 68 'endline' => $node->getEndLine() 69 ); 70 } 71 } 72 73 if($frontmatter_tag == 'off') { 74 return array('text'=>$renderResult, 'heading'=>$headingInfo); 75 } elseif($frontmatter_tag == 'upper') { 76 return array('text'=>$tagStr."\n\n".$renderResult, 'heading'=>$headingInfo); 77 //return $tagStr."\n\n".$renderResult; 78 } else { 79 return array('text'=>$renderResult."\n\n".$tagStr, 'heading'=>$headingInfo); 80 //return $renderResult."\n\n".$tagStr; 81 } 82 } 83 84 // Temporary implementation: separate method for frontmatter extraction 85 // Since some parsed frontmatter info must be included in main text, it should be merged 86 public static function ExtractFrontmatter($markdown) { 87 $frontMatterExtension = new FrontMatterExtension(); 88 $result = $frontMatterExtension->getFrontMatterParser()->parse($markdown); 89 90 return $result; 91 } 92 93 // replace slash in MD wikilink to colon to match DW syntax 94 public static function ParseDokuwikiWikilinks($text) { 95 $pattern = "/(?:\[\[\b|(?!^)\G)[^\/|\]]*\K\/+/"; 96 $result = preg_replace($pattern, ":", $text); 97 $pattern = "/!\[\[(.*)\]\]/"; 98 $result = preg_replace($pattern, '{{$1}}', $result); 99 return $result; 100 } 101 102 public static function createDWEnvironment(): Environment { 103 $config = []; 104 $environment = new Environment($config); 105 $environment->addExtension(new CommonMarkToDokuWikiExtension()); 106 $environment->addExtension(new FootnoteToDokuwikiExtension()); 107 $environment->addExtension(new StrikethroughExtension()); 108 $environment->addExtension(new TableExtension()); 109 $environment->addExtension(new FrontMatterExtension()); 110 111 $environment->mergeConfig([ 112 'html_input' => 'allow', 113 ]); 114 115 return $environment; 116 } 117} 118 119?> 120