瀏覽代碼

添加 提示词格式

visuddhinanda 1 年之前
父節點
當前提交
84355015c4
共有 1 個文件被更改,包括 234 次插入217 次删除
  1. 234 217
      api-v8/app/Http/Api/MdRender.php

+ 234 - 217
api-v8/app/Http/Api/MdRender.php

@@ -1,4 +1,5 @@
 <?php
+
 namespace App\Http\Api;
 
 use Illuminate\Support\Str;
@@ -12,9 +13,10 @@ use App\Tools\RedisClusters;
 use Illuminate\Support\Facades\Log;
 use App\Tools\Markdown;
 
-define("STACK_DEEP",8);
+define("STACK_DEEP", 8);
 
-class MdRender{
+class MdRender
+{
     /**
      * 文字渲染模式
      * read 阅读模式
@@ -22,17 +24,17 @@ class MdRender{
      */
     protected $options = [
         'mode' => 'read',
-        'channelType'=>'translation',
-        'contentType'=>"markdown",
-        'format'=>'react',
-        'debug'=>[],
-        'studioId'=>null,
-        'lang'=>'zh-Hans',
-        'footnote'=>false,
-        'paragraph'=>false,
-        ];
-
-    public function __construct($options=[])
+        'channelType' => 'translation',
+        'contentType' => "markdown",
+        'format' => 'react',
+        'debug' => [],
+        'studioId' => null,
+        'lang' => 'zh-Hans',
+        'footnote' => false,
+        'paragraph' => false,
+    ];
+
+    public function __construct($options = [])
     {
         foreach ($options as $key => $value) {
             $this->options[$key] = $value;
@@ -42,90 +44,94 @@ class MdRender{
     /**
      * 将句子模版组成的段落复制一份,为了实现巴汉逐段对读
      */
-    private function preprocessingForParagraph($input){
-        if(!$this->options['paragraph']){
+    private function preprocessingForParagraph($input)
+    {
+        if (!$this->options['paragraph']) {
             return $input;
         }
-        $paragraphs = explode("\n\n",$input);
+        $paragraphs = explode("\n\n", $input);
         $output = [];
         foreach ($paragraphs as $key => $paragraph) {
             # 判断是否是纯粹的句子模版
             $pattern = "/\{\{sent\|id=([0-9].+?)\}\}/";
             $replacement = '';
-            $space = preg_replace($pattern,$replacement,$paragraph);
-            $space = str_replace('>','',$space);
-            if(empty(trim($space))){
-                $output[] = str_replace('}}','|text=origin}}',$paragraph);
-                $output[] = str_replace('}}','|text=translation}}',$paragraph);
-            }else{
+            $space = preg_replace($pattern, $replacement, $paragraph);
+            $space = str_replace('>', '', $space);
+            if (empty(trim($space))) {
+                $output[] = str_replace('}}', '|text=origin}}', $paragraph);
+                $output[] = str_replace('}}', '|text=translation}}', $paragraph);
+            } else {
                 $output[] = $paragraph;
             }
         }
 
-        return implode("\n\n",$output);
+        return implode("\n\n", $output);
     }
 
     /**
      * 按照{{}}把字符串切分成三个部分。模版之前的,模版,和模版之后的
      */
-    private function tplSplit($tpl){
-        $before = strpos($tpl,'{{');
-        if($before === FALSE){
+    private function tplSplit($tpl)
+    {
+        $before = strpos($tpl, '{{');
+        if ($before === FALSE) {
             //未找到
-            return ['data'=>[$tpl,'',''],'error'=>0];
-        }else{
+            return ['data' => [$tpl, '', ''], 'error' => 0];
+        } else {
             $pointer = $before;
             $stack = array();
             $stack[] = $pointer;
-            $after = substr($tpl,$pointer+2) ;
-            while (!empty($after) && count($stack)>0 && count($stack)<STACK_DEEP) {
-                $nextBegin = strpos($after,"{{");
-                $nextEnd = strpos($after,"}}");
-                if($nextBegin !== FALSE){
-                    if($nextBegin < $nextEnd){
+            $after = substr($tpl, $pointer + 2);
+            while (!empty($after) && count($stack) > 0 && count($stack) < STACK_DEEP) {
+                $nextBegin = strpos($after, "{{");
+                $nextEnd = strpos($after, "}}");
+                if ($nextBegin !== FALSE) {
+                    if ($nextBegin < $nextEnd) {
                         //有嵌套找到最后一个}}
                         $pointer = $pointer + 2 + $nextBegin;
                         $stack[] = $pointer;
-                        $after = substr($tpl,$pointer+2);
-                    }else if($nextEnd !== FALSE){
+                        $after = substr($tpl, $pointer + 2);
+                    } else if ($nextEnd !== FALSE) {
                         //无嵌套有结束
                         $pointer = $pointer + 2 + $nextEnd;
                         array_pop($stack);
-                        $after = substr($tpl,$pointer+2);
-                    }else{
+                        $after = substr($tpl, $pointer + 2);
+                    } else {
                         //无结束符 没找到
                         break;
                     }
-                }else if($nextEnd !== FALSE){
+                } else if ($nextEnd !== FALSE) {
                     $pointer = $pointer + 2 + $nextEnd;
                     array_pop($stack);
-                    $after = substr($tpl,$pointer+2);
-                }else{
+                    $after = substr($tpl, $pointer + 2);
+                } else {
                     //没找到
                     break;
                 }
             }
-            if(count($stack)>0){
-                if(count($stack) === STACK_DEEP){
-                    return ['data'=>[$tpl,'',''],'error'=>2];
-                }else{
+            if (count($stack) > 0) {
+                if (count($stack) === STACK_DEEP) {
+                    return ['data' => [$tpl, '', ''], 'error' => 2];
+                } else {
                     //未关闭
-                    return ['data'=>[$tpl,'',''],'error'=>1];
+                    return ['data' => [$tpl, '', ''], 'error' => 1];
                 }
-            }else{
-                return ['data'=>
-                        [
-                            substr($tpl,0,$before),
-                            substr($tpl,$before,$pointer-$before+2),
-                            substr($tpl,$pointer+2)
-                        ],
-                        'error'=>0
+            } else {
+                return [
+                    'data' =>
+                    [
+                        substr($tpl, 0, $before),
+                        substr($tpl, $before, $pointer - $before + 2),
+                        substr($tpl, $pointer + 2)
+                    ],
+                    'error' => 0
                 ];
             }
         }
     }
 
-    private function wiki2xml(string $wiki,$channelId=[]):string{
+    private function wiki2xml(string $wiki, $channelId = []): string
+    {
         /**
          * 渲染markdown里面的模版
          */
@@ -135,39 +141,40 @@ class MdRender{
             $arrWiki = $this->tplSplit($remain);
             $buffer[] = $arrWiki['data'][0];
             $tpl = $arrWiki['data'][1];
-            if(!empty($tpl)){
+            if (!empty($tpl)) {
                 /**
                  * 处理模版 提取参数
                  */
-                $tpl = str_replace("|\n","|",$tpl);
+                $tpl = str_replace("|\n", "|", $tpl);
                 $pattern = "/\{\{(.+?)\|/";
                 $replacement = '<MdTpl class="tpl" name="$1"><param>';
-                $tpl = preg_replace($pattern,$replacement,$tpl);
-                $tpl = str_replace("}}","</param></MdTpl>",$tpl);
-                $tpl = str_replace("|","</param><param>",$tpl);
+                $tpl = preg_replace($pattern, $replacement, $tpl);
+                $tpl = str_replace("}}", "</param></MdTpl>", $tpl);
+                $tpl = str_replace("|", "</param><param>", $tpl);
                 /**
                  * 替换变量名
                  */
                 $pattern = "/<param>([a-z]+?)=/";
                 $replacement = '<param name="$1">';
-                $tpl = preg_replace($pattern,$replacement,$tpl);
+                $tpl = preg_replace($pattern, $replacement, $tpl);
                 //tpl to react
-                $tpl = str_replace('<param','<span class="param"',$tpl);
-                $tpl = str_replace('</param>','</span>',$tpl);
-                $tpl = $this->xml2tpl($tpl,$channelId);
+                $tpl = str_replace('<param', '<span class="param"', $tpl);
+                $tpl = str_replace('</param>', '</span>', $tpl);
+                $tpl = $this->xml2tpl($tpl, $channelId);
                 $buffer[] = $tpl;
             }
             $remain = $arrWiki['data'][2];
         } while (!empty($remain));
 
-        $html = implode('' , $buffer);
+        $html = implode('', $buffer);
 
         return $html;
     }
-    private function xmlQueryId(string $xml, string $id):string{
-        try{
+    private function xmlQueryId(string $xml, string $id): string
+    {
+        try {
             $dom = simplexml_load_string($xml);
-        }catch(\Exception $e){
+        } catch (\Exception $e) {
             Log::error($e);
             return "<div></div>";
         }
@@ -175,11 +182,11 @@ class MdRender{
         foreach ($tpl_list as $key => $tpl) {
             foreach ($tpl->children() as  $param) {
                 # 处理每个参数
-                if($param->getName() === "param"){
-                    foreach($param->attributes() as $pa => $pa_value){
+                if ($param->getName() === "param") {
+                    foreach ($param->attributes() as $pa => $pa_value) {
                         $pValue = $pa_value->__toString();
-                        if($pa === "name" && $pValue === "id"){
-                            if($param->__toString() === $id){
+                        if ($pa === "name" && $pValue === "id") {
+                            if ($param->__toString() === $id) {
                                 return $tpl->asXML();
                             }
                         }
@@ -189,24 +196,25 @@ class MdRender{
         }
         return "<div></div>";
     }
-    public static function take_sentence(string $xml):array{
+    public static function take_sentence(string $xml): array
+    {
         $output = [];
-        try{
+        try {
             $dom = simplexml_load_string($xml);
-        }catch(\Exception $e){
+        } catch (\Exception $e) {
             Log::error($e);
             return $output;
         }
         $tpl_list = $dom->xpath('//MdTpl');
         foreach ($tpl_list as $key => $tpl) {
-            foreach($tpl->attributes() as $a => $a_value){
-                if($a==="name"){
-                    if($a_value->__toString() ==="sent"){
+            foreach ($tpl->attributes() as $a => $a_value) {
+                if ($a === "name") {
+                    if ($a_value->__toString() === "sent") {
                         foreach ($tpl->children() as  $param) {
                             # 处理每个参数
-                            if($param->getName() === "param"){
+                            if ($param->getName() === "param") {
                                 $sent = $param->__toString();
-                                if(!empty($sent)){
+                                if (!empty($sent)) {
                                     $output[] = $sent;
                                     break;
                                 }
@@ -218,25 +226,26 @@ class MdRender{
         }
         return $output;
     }
-    private function xml2tpl(string $xml, $channelId=[]):string{
+    private function xml2tpl(string $xml, $channelId = []): string
+    {
         /**
          * 解析xml
          * 获取模版参数
          * 生成react 组件参数
          */
-        try{
+        try {
             //$dom = simplexml_load_string($xml);
             $doc = new \DOMDocument();
-            $xml = str_replace('MdTpl','dfn',$xml);
+            $xml = str_replace('MdTpl', 'dfn', $xml);
             $xml = mb_convert_encoding($xml, 'HTML-ENTITIES', "UTF-8");
-            $ok = $doc->loadHTML($xml,LIBXML_NOERROR  | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
-        }catch(\Exception $e){
+            $ok = $doc->loadHTML($xml, LIBXML_NOERROR  | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
+        } catch (\Exception $e) {
             Log::error($e);
             Log::error($xml);
             return "<span>xml解析错误{$e}</span>";
         }
 
-        if(!$ok){
+        if (!$ok) {
             return "<span>xml解析错误</span>";
         }
         /*
@@ -254,8 +263,8 @@ class MdRender{
              */
             $props = [];
             $tpl_name = '';
-            foreach($tpl->attributes as $a => $a_value){
-                if($a_value->nodeName==="name"){
+            foreach ($tpl->attributes as $a => $a_value) {
+                if ($a_value->nodeName === "name") {
                     $tpl_name = $a_value->nodeValue;
                     break;
                 }
@@ -264,24 +273,23 @@ class MdRender{
             $child = $tpl->firstChild;
             while ($child) {
                 # 处理每个参数
-                if($child->nodeName === "span"){
+                if ($child->nodeName === "span") {
                     $param_id++;
                     $paramName = "";
-                    foreach($child->attributes as $pa => $pa_value){
-                        if($pa_value->nodeName === "name"){
+                    foreach ($child->attributes as $pa => $pa_value) {
+                        if ($pa_value->nodeName === "name") {
                             $nodeText = $pa_value->nodeValue;
                             $props["{$nodeText}"] = $child->nodeValue;
                             $paramName = $pa_value;
                         }
                     }
-                    if(empty($paramName)){
+                    if (empty($paramName)) {
                         foreach ($child->childNodes as $param_child) {
                             # code...
-                            if($param_child->nodeType ===3){
+                            if ($param_child->nodeType === 3) {
                                 $props["{$param_id}"] = $param_child->nodeValue;
                             }
                         }
-
                     }
                 }
                 $child = $child->nextSibling;
@@ -293,19 +301,20 @@ class MdRender{
             //TODO 判断$channelId里面的是否都是uuid
             $channelInfo = [];
             foreach ($channelId as $key => $id) {
-                $channelInfo[] = Channel::where('uid',$id)->first();
+                $channelInfo[] = Channel::where('uid', $id)->first();
             }
-            $tplRender = new TemplateRender($props,
-                                        $channelInfo,
-                                        $this->options['mode'],
-                                        $this->options['format'],
-                                        $this->options['studioId'],
-                                        $this->options['debug'],
-                                        $this->options['lang'],
-                                    );
+            $tplRender = new TemplateRender(
+                $props,
+                $channelInfo,
+                $this->options['mode'],
+                $this->options['format'],
+                $this->options['studioId'],
+                $this->options['debug'],
+                $this->options['lang'],
+            );
             $tplRender->options($this->options);
             $tplProps = $tplRender->render($tpl_name);
-            if($this->options['format']==='react' && $tplProps){
+            if ($this->options['format'] === 'react' && $tplProps) {
                 $props = $doc->createAttribute("props");
                 $props->nodeValue = $tplProps['props'];
                 $tpl->appendChild($props);
@@ -313,55 +322,56 @@ class MdRender{
                 $attTpl->nodeValue = $tplProps['tpl'];
                 $tpl->appendChild($attTpl);
                 $htmlElement = $doc->createElement($tplProps['tag']);
-                $htmlElement->nodeValue=$tplProps['html'];
+                $htmlElement->nodeValue = $tplProps['html'];
                 $tpl->appendChild($htmlElement);
             }
         }
         $html = $doc->saveHTML();
-        $html = str_replace(['<dfn','</dfn>'],['<MdTpl','</MdTpl>'],$html);
+        $html = str_replace(['<dfn', '</dfn>'], ['<MdTpl', '</MdTpl>'], $html);
         switch ($this->options['format']) {
             case 'react':
                 return trim($html);
                 break;
             case 'unity':
-                if($tplProps){
-                    return "{{"."{$tplProps['tpl']}|{$tplProps['props']}"."}}";
-                }else{
+                if ($tplProps) {
+                    return "{{" . "{$tplProps['tpl']}|{$tplProps['props']}" . "}}";
+                } else {
                     return '';
                 }
                 break;
             case 'html':
-                if(isset($tplProps)){
-                    if(is_array($tplProps)){
+                if (isset($tplProps)) {
+                    if (is_array($tplProps)) {
                         return '';
-                    }else{
+                    } else {
                         return $tplProps;
                     }
-                }else{
+                } else {
                     Log::error('tplProps undefine');
                     return '';
                 }
                 break;
             case 'tex':
-                if(isset($tplProps)){
-                    if(is_array($tplProps)){
+                if (isset($tplProps)) {
+                    if (is_array($tplProps)) {
                         return '';
-                    }else{
+                    } else {
                         return $tplProps;
                     }
-                }else{
+                } else {
                     Log::error('tplProps undefine');
                     return '';
                 }
                 break;
-            default: /**text simple markdown */
-                if(isset($tplProps)){
-                    if(is_array($tplProps)){
+            default:
+                /**text simple markdown */
+                if (isset($tplProps)) {
+                    if (is_array($tplProps)) {
                         return '';
-                    }else{
+                    } else {
                         return $tplProps;
                     }
-                }else{
+                } else {
                     Log::error('tplProps undefine');
                     return '';
                 }
@@ -372,53 +382,54 @@ class MdRender{
     /**
      * 将markdown文件中的模版转换为标准的wiki模版
      */
-    private function markdown2wiki(string $markdown): string{
+    private function markdown2wiki(string $markdown): string
+    {
         //$markdown = mb_convert_encoding($markdown,'UTF-8','UTF-8');
-        $markdown = iconv('UTF-8','UTF-8//IGNORE',$markdown);
+        $markdown = iconv('UTF-8', 'UTF-8//IGNORE', $markdown);
         /**
          * nissaya
          * aaa=bbb\n
          * {{nissaya|aaa|bbb}}
          */
-        if($this->options['channelType']==='nissaya'){
-            if($this->options['contentType'] === "json"){
+        if ($this->options['channelType'] === 'nissaya') {
+            if ($this->options['contentType'] === "json") {
                 $json = json_decode($markdown);
                 $nissayaWord = [];
-                if(is_array($json)){
+                if (is_array($json)) {
                     foreach ($json as $word) {
-                        if(count($word->sn) === 1){
+                        if (count($word->sn) === 1) {
                             //只输出第一层级
                             $str = "{{nissaya|";
-                            if(isset($word->word->value)){
+                            if (isset($word->word->value)) {
                                 $str .= $word->word->value;
                             }
                             $str .= "|";
-                            if(isset($word->meaning->value)){
+                            if (isset($word->meaning->value)) {
                                 $str .= $word->meaning->value;
                             }
                             $str .= "}}";
                             $nissayaWord[] = $str;
                         }
                     }
-                }else{
-                    Log::error('json data is not array',['data'=>$markdown]);
+                } else {
+                    Log::error('json data is not array', ['data' => $markdown]);
                 }
 
-                $markdown = implode('',$nissayaWord);
-            }else if($this->options['contentType'] === "markdown"){
-                $lines = explode("\n",$markdown);
+                $markdown = implode('', $nissayaWord);
+            } else if ($this->options['contentType'] === "markdown") {
+                $lines = explode("\n", $markdown);
                 $newLines = array();
                 foreach ($lines as  $line) {
-                    if(strstr($line,'=') === FALSE){
+                    if (strstr($line, '=') === FALSE) {
                         $newLines[] = $line;
-                    }else{
-                        $nissaya = explode('=',$line);
-                        $meaning = array_slice($nissaya,1);
-                        $meaning = implode('=',$meaning);
+                    } else {
+                        $nissaya = explode('=', $line);
+                        $meaning = array_slice($nissaya, 1);
+                        $meaning = implode('=', $meaning);
                         $newLines[] = "{{nissaya|{$nissaya[0]}|{$meaning}}}";
                     }
                 }
-                $markdown = implode("\n",$newLines);
+                $markdown = implode("\n", $newLines);
             }
         }
         //$markdown = preg_replace("/\n\n/","<div></div>",$markdown);
@@ -426,29 +437,29 @@ class MdRender{
         /**
          * 处理 mermaid
          */
-        if(strpos($markdown,"```mermaid") !== false){
-            $lines = explode("\n",$markdown);
+        if (strpos($markdown, "```mermaid") !== false) {
+            $lines = explode("\n", $markdown);
             $newLines = array();
             $mermaidBegin = false;
             $mermaidString = array();
             foreach ($lines as  $line) {
-                if($line === "```mermaid"){
+                if ($line === "```mermaid") {
                     $mermaidBegin = true;
                     $mermaidString = [];
                     continue;
                 }
-                if($mermaidBegin){
-                    if($line === "```"){
-                        $newLines[] = "{{mermaid|".base64_encode(\json_encode($mermaidString))."}}";
+                if ($mermaidBegin) {
+                    if ($line === "```") {
+                        $newLines[] = "{{mermaid|" . base64_encode(\json_encode($mermaidString)) . "}}";
                         $mermaidBegin = false;
-                    }else{
+                    } else {
                         $mermaidString[] = $line;
                     }
-                }else{
+                } else {
                     $newLines[] = $line;
                 }
             }
-            $markdown = implode("\n",$newLines);
+            $markdown = implode("\n", $newLines);
         }
 
         /**
@@ -468,12 +479,12 @@ class MdRender{
         #替换术语
         $pattern = "/\[\[(.+?)\]\]/";
         $replacement = '{{term|$1}}';
-        $markdown = preg_replace($pattern,$replacement,$markdown);
+        $markdown = preg_replace($pattern, $replacement, $markdown);
 
         #替换句子模版
         $pattern = "/\{\{([0-9].+?)\}\}/";
         $replacement = '{{sent|id=$1}}';
-        $markdown = preg_replace($pattern,$replacement,$markdown);
+        $markdown = preg_replace($pattern, $replacement, $markdown);
 
         /**
          * 替换多行注释
@@ -486,34 +497,34 @@ class MdRender{
          * bla
          * }}
          */
-        if(strpos($markdown,"```\n") !== false){
-            $lines = explode("\n",$markdown);
+        if (strpos($markdown, "```\n") !== false) {
+            $lines = explode("\n", $markdown);
             $newLines = array();
             $noteBegin = false;
             $noteString = array();
             foreach ($lines as  $line) {
 
-                if($noteBegin){
-                    if($line === "```"){
+                if ($noteBegin) {
+                    if ($line === "```") {
                         $newLines[] = "}}";
                         $noteBegin = false;
-                    }else{
+                    } else {
                         $newLines[] = $line;
                     }
-                }else{
-                    if($line === "```"){
+                } else {
+                    if ($line === "```") {
                         $noteBegin = true;
                         $newLines[] = "{{note|";
                         continue;
-                    }else{
-                       $newLines[] = $line;
+                    } else {
+                        $newLines[] = $line;
                     }
                 }
             }
-            if($noteBegin){
+            if ($noteBegin) {
                 $newLines[] = "}}";
             }
-            $markdown = implode("\n",$newLines);
+            $markdown = implode("\n", $newLines);
         }
 
         /**
@@ -523,68 +534,73 @@ class MdRender{
          */
         $pattern = "/`(.+?)`/";
         $replacement = '{{note|$1}}';
-        $markdown = preg_replace($pattern,$replacement,$markdown);
+        $markdown = preg_replace($pattern, $replacement, $markdown);
 
         return $markdown;
     }
 
-    private function markdownToHtml($markdown){
-        $markdown = str_replace('MdTpl','mdtpl',$markdown);
-        $markdown = str_replace(['<param','</param>'],['<span','</span>'],$markdown);
+    private function markdownToHtml($markdown)
+    {
+        $markdown = str_replace('MdTpl', 'mdtpl', $markdown);
+        $markdown = str_replace(['<param', '</param>'], ['<span', '</span>'], $markdown);
 
         $html = Markdown::render($markdown);
-        if($this->options['format']==='react'){
+        if ($this->options['format'] === 'react') {
             $html = $this->fixHtml($html);
         }
-        $html = str_replace('<hr>','<hr />',$html);
+        $html = str_replace('<hr>', '<hr />', $html);
         //给H1-6 添加uuid
-        for ($i=1; $i<7 ; $i++) {
-            if(strpos($html,"<h{$i}>")===false){
+        for ($i = 1; $i < 7; $i++) {
+            if (strpos($html, "<h{$i}>") === false) {
                 continue;
             }
             $output = array();
             $input = $html;
-            $hPos = strpos($input,"<h{$i}>");
+            $hPos = strpos($input, "<h{$i}>");
             while ($hPos !== false) {
-                $output[] = substr($input,0,$hPos);
-                $output[] = "<h{$i} id='".Str::uuid()."'>";
-                $input = substr($input,$hPos+4);
-                $hPos = strpos($input,"<h{$i}>");
+                $output[] = substr($input, 0, $hPos);
+                $output[] = "<h{$i} id='" . Str::uuid() . "'>";
+                $input = substr($input, $hPos + 4);
+                $hPos = strpos($input, "<h{$i}>");
             }
             $output[] = $input;
-            $html = implode('',$output);
+            $html = implode('', $output);
         }
-        $html = str_replace('mdtpl','MdTpl',$html);
+        $html = str_replace('mdtpl', 'MdTpl', $html);
         return $html;
     }
-    private function  fixHtml($html) {
+    private function  fixHtml($html)
+    {
         $doc = new \DOMDocument();
         libxml_use_internal_errors(true);
         $html = mb_convert_encoding($html, 'HTML-ENTITIES', "UTF-8");
-        $doc->loadHTML('<span>'.$html.'</span>',LIBXML_NOERROR  | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
+        $doc->loadHTML('<span>' . $html . '</span>', LIBXML_NOERROR  | LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
         $fixed = $doc->saveHTML();
         $fixed = mb_convert_encoding($fixed, "UTF-8", 'HTML-ENTITIES');
         return $fixed;
     }
-    public static function init(){
+    public static function init()
+    {
         $GLOBALS["MdRenderStack"] = 0;
     }
-    public function convert($markdown,$channelId=[],$queryId=null){
-        if(isset($GLOBALS["MdRenderStack"]) && is_numeric($GLOBALS["MdRenderStack"])){
+    public function convert($markdown, $channelId = [], $queryId = null)
+    {
+        if (isset($GLOBALS["MdRenderStack"]) && is_numeric($GLOBALS["MdRenderStack"])) {
             $GLOBALS["MdRenderStack"]++;
-        }else{
+        } else {
             $GLOBALS["MdRenderStack"] = 1;
         }
-        if($GLOBALS["MdRenderStack"]<3){
-            $output  =  $this->_convert($markdown,$channelId,$queryId);
-        }else{
+        if ($GLOBALS["MdRenderStack"] < 3) {
+            $output  =  $this->_convert($markdown, $channelId, $queryId);
+        } else {
             $output  = $markdown;
         }
         $GLOBALS["MdRenderStack"]--;
         return $output;
     }
-    private function _convert($markdown,$channelId=[],$queryId=null){
-        if(empty($markdown)){
+    private function _convert($markdown, $channelId = [], $queryId = null)
+    {
+        if (empty($markdown)) {
             switch ($this->options['format']) {
                 case 'react':
                     return "<span></span>";
@@ -596,8 +612,8 @@ class MdRender{
         }
         $wiki = $this->markdown2wiki($markdown);
         $wiki = $this->preprocessingForParagraph($wiki);
-        $markdownWithTpl = $this->wiki2xml($wiki,$channelId);
-        if(!is_null($queryId)){
+        $markdownWithTpl = $this->wiki2xml($wiki, $channelId);
+        if (!is_null($queryId)) {
             $html = $this->xmlQueryId($markdownWithTpl, $queryId);
         }
         $html = $this->markdownToHtml($markdownWithTpl);
@@ -607,54 +623,55 @@ class MdRender{
         switch ($this->options['format']) {
             case 'react':
                 //生成可展开组件
-                $html = str_replace("<div/>","<div></div>",$html);
+                $html = str_replace("<div/>", "<div></div>", $html);
                 $pattern = '/<li><div>(.+?)<\/div><\/li>/';
                 $replacement = '<li><MdTpl name="toggle" tpl="toggle" props=""><div>$1</div></MdTpl></li>';
-                $output = preg_replace($pattern,$replacement,$html);
+                $output = preg_replace($pattern, $replacement, $html);
                 break;
             case 'text':
             case 'simple':
+            case 'prompt':
                 $html = strip_tags($html);
-                $output = htmlspecialchars_decode($html,ENT_QUOTES);
+                $output = htmlspecialchars_decode($html, ENT_QUOTES);
                 //$output = html_entity_decode($html);
                 break;
             case 'tex':
                 $html = strip_tags($html);
-                $output = htmlspecialchars_decode($html,ENT_QUOTES);
+                $output = htmlspecialchars_decode($html, ENT_QUOTES);
                 //$output = html_entity_decode($html);
                 break;
             case 'unity':
-                $html = str_replace(['<strong>','</strong>','<em>','</em>'],['[%b%]','[%/b%]','[%i%]','[%/i%]'],$html);
+                $html = str_replace(['<strong>', '</strong>', '<em>', '</em>'], ['[%b%]', '[%/b%]', '[%i%]', '[%/i%]'], $html);
                 $html = strip_tags($html);
-                $html = str_replace(['[%b%]','[%/b%]','[%i%]','[%/i%]'],['<b>','</b>','<i>','</i>'],$html);
-                $output = htmlspecialchars_decode($html,ENT_QUOTES);
+                $html = str_replace(['[%b%]', '[%/b%]', '[%i%]', '[%/i%]'], ['<b>', '</b>', '<i>', '</i>'], $html);
+                $output = htmlspecialchars_decode($html, ENT_QUOTES);
                 break;
             case 'html':
-                $output = htmlspecialchars_decode($html,ENT_QUOTES);
+                $output = htmlspecialchars_decode($html, ENT_QUOTES);
                 //处理脚注
-                if($this->options['footnote'] && isset($GLOBALS['note']) && count($GLOBALS['note'])>0){
+                if ($this->options['footnote'] && isset($GLOBALS['note']) && count($GLOBALS['note']) > 0) {
                     $output .= '<div><h1>endnote</h1>';
                     foreach ($GLOBALS['note'] as $footnote) {
-                        $output .= '<p><a name="footnote-'.$footnote['sn'].'">['.$footnote['sn'].']</a> '.$footnote['content'].'</p>';
+                        $output .= '<p><a name="footnote-' . $footnote['sn'] . '">[' . $footnote['sn'] . ']</a> ' . $footnote['content'] . '</p>';
                     }
                     $output .= '</div>';
                     unset($GLOBALS['note']);
                 }
                 //处理图片链接
-                $output = str_replace('<img src="','<img src="'.config('app.url'),$output);
+                $output = str_replace('<img src="', '<img src="' . config('app.url'), $output);
                 break;
             case 'markdown':
                 //处理脚注
                 $footnotes = array();
-                if($this->options['footnote'] && isset($GLOBALS['note']) && count($GLOBALS['note'])>0){
+                if ($this->options['footnote'] && isset($GLOBALS['note']) && count($GLOBALS['note']) > 0) {
                     foreach ($GLOBALS['note'] as $footnote) {
-                        $footnotes[] = '[^'.$footnote['sn'].']: ' . $footnote['content'];
+                        $footnotes[] = '[^' . $footnote['sn'] . ']: ' . $footnote['content'];
                     }
                     unset($GLOBALS['note']);
                 }
                 //处理图片链接
-                $output = str_replace('/attachments/',config('app.url')."/attachments/",$markdownWithTpl);
-                $output = $output . "\n\n" . implode("\n\n",$footnotes);
+                $output = str_replace('/attachments/', config('app.url') . "/attachments/", $markdownWithTpl);
+                $output = $output . "\n\n" . implode("\n\n", $footnotes);
                 break;
         }
         return $output;
@@ -664,20 +681,20 @@ class MdRender{
     /**
      * string[] $channelId
      */
-    public static function render($markdown,$channelId,$queryId=null,$mode='read',$channelType='translation',$contentType="markdown",$format='react'){
+    public static function render($markdown, $channelId, $queryId = null, $mode = 'read', $channelType = 'translation', $contentType = "markdown", $format = 'react')
+    {
 
-            $mdRender = new MdRender(
-                            [
-                                'mode'=>$mode,
-                                'channelType'=>$channelType,
-                                'contentType'=>$contentType,
-                                'format'=>$format
-                            ]);
+        $mdRender = new MdRender(
+            [
+                'mode' => $mode,
+                'channelType' => $channelType,
+                'contentType' => $contentType,
+                'format' => $format
+            ]
+        );
 
-            $output  = $mdRender->convert($markdown,$channelId,$queryId);
+        $output  = $mdRender->convert($markdown, $channelId, $queryId);
 
         return $output;
     }
-
-
 }