MdRender.php 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace App\Http\Api;
  3. use Illuminate\Support\Str;
  4. use mustache\mustache;
  5. use App\Models\DhammaTerm;
  6. use App\Models\PaliText;
  7. use App\Http\Controllers\CorpusController;
  8. use Illuminate\Support\Facades\Cache;
  9. use Illuminate\Support\Facades\Log;
  10. class MdRender{
  11. /**
  12. *
  13. */
  14. public static function render($markdown,$channelId,$isArticle=false){
  15. $html = Str::markdown($markdown);
  16. #替换术语
  17. $pattern = "/\[\[(.+?)\]\]/";
  18. $replacement = '{{term|$1}}';
  19. $html = preg_replace($pattern,$replacement,$html);
  20. #替换句子
  21. $pattern = "/\{\{([0-9].+?)\}\}/";
  22. $replacement = '{{sent|$1}}';
  23. $html = preg_replace($pattern,$replacement,$html);
  24. #替换注释
  25. #<code>bla</code>
  26. #{{note:bla}}
  27. #替换术语
  28. $pattern = '/<code>(.+?)<\/code>/';
  29. $replacement = '{{note|$1}}';
  30. $html = preg_replace($pattern,$replacement,$html);
  31. $pattern = "/\{\{(.+?)\}\}/";
  32. $replacement = "\n{{#function}}\n$1\n{{/function}}\n";
  33. $html = preg_replace($pattern,$replacement,$html);
  34. $m = new \Mustache_Engine(array('entity_flags' => ENT_QUOTES));
  35. $html = $m->render($html, array(
  36. 'function' => function($text) use($m,$channelId) {
  37. //1: 解析
  38. $param = explode("|",$text);
  39. //3: 处理业务逻辑
  40. $tplName = trim($param[0]);
  41. $innerString = "";
  42. switch($tplName){
  43. case 'term':
  44. //获取实际的参数
  45. $word = trim($param[1]);
  46. $props = Cache::remember("/term/{$channelId}/{$word}",
  47. 60,
  48. function() use($word,$channelId){
  49. $tplParam = DhammaTerm::where("word",$word)->first();
  50. $output = [
  51. "word" => $word,
  52. "channel" => $channelId,
  53. ];
  54. $innerString = $output["word"];
  55. if($tplParam){
  56. $output["id"] = $tplParam->guid;
  57. $output["meaning"] = $tplParam->meaning;
  58. $innerString = $output["meaning"];
  59. if(!empty($tplParam->other_meaning)){
  60. $output["meaning2"] = $tplParam->other_meaning;
  61. }
  62. }
  63. return $output;
  64. });
  65. break;
  66. case 'note':
  67. if(isset($param[1])){
  68. $props = ["note"=>trim($param[1])];
  69. }
  70. if(isset($param[2])){
  71. $props["trigger"] = trim($param[2]);
  72. $innerString = $props["trigger"];
  73. }
  74. break;
  75. case 'sent':
  76. $tplName = "sentedit";
  77. $innerString = "";
  78. $sentId = trim($param[1]);
  79. $Sent = new CorpusController();
  80. $html = $Sent->getSentTpl($param[1],[$channelId]);
  81. return $html;
  82. break;
  83. case 'quote':
  84. $paraId = trim($param[1]);
  85. $props = Cache::remember("/quote/{$channelId}/{$paraId}",
  86. 60,
  87. function() use($paraId,$channelId){
  88. $para = \explode('-',$paraId);
  89. $output = [
  90. "paraId" => $paraId,
  91. "channel" => $channelId,
  92. "innerString" => $paraId,
  93. ];
  94. if(count($para)<2){
  95. return $output;
  96. }
  97. $PaliText = PaliText::where("book",$para[0])
  98. ->where("paragraph",$para[1])
  99. ->select(['toc','path'])
  100. ->first();
  101. if($PaliText){
  102. $output["pali"] = $PaliText->toc;
  103. $output["paliPath"] = \json_decode($PaliText->path);
  104. $innerString = $PaliText->toc;
  105. }
  106. return $output;
  107. });
  108. break;
  109. case 'exercise':
  110. $exeId = trim($param[1]);
  111. $exeContent = trim($param[2]);
  112. $props = Cache::remember("/quote/{$channelId}/{$exeId}",
  113. 60,
  114. function() use($exeId,$channelId){
  115. $output = [
  116. "id" => $exeId,
  117. "channel" => $channelId,
  118. ];
  119. return $output;
  120. });
  121. #替换句子
  122. $pattern = "/\(\((.+?)\)\)/";
  123. $replacement = '{{sent|$1}}';
  124. Log::info("content{$exeContent}");
  125. $exeContent = preg_replace($pattern,$replacement,$exeContent);
  126. Log::info("content{$exeContent}");
  127. $innerString = MdRender::render($exeContent,$channelId);
  128. break;
  129. default:
  130. break;
  131. }
  132. //4: 返回拼好的字符串
  133. $props = base64_encode(\json_encode($props));
  134. $html = "<MdTpl tpl='{$tplName}' props='{$props}' >{$innerString}</MdTpl>";
  135. return $html;
  136. }
  137. ));
  138. if(substr_count($html,"<p>") === 1){
  139. $html = \str_replace(['<p>','</p>'],'',$html);
  140. }
  141. //LOG::info($html);
  142. return $html;
  143. }
  144. }