TextRenderer.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. namespace App\Services\Template\Renderers;
  3. use App\Services\Template\Contracts\RendererInterface;
  4. use App\Services\Template\ParsedDocument;
  5. use App\Services\Template\ContentNode;
  6. use App\Services\Template\TextNode;
  7. use App\Services\Template\MarkdownNode;
  8. use App\Services\Template\TemplateNode;
  9. // ================== 纯文本渲染器 ==================
  10. class TextRenderer implements RendererInterface
  11. {
  12. private array $templateTexts = [];
  13. public function __construct()
  14. {
  15. $this->initializeTemplateTexts();
  16. }
  17. private function initializeTemplateTexts(): void
  18. {
  19. $this->templateTexts = [
  20. 'note' => function ($params) {
  21. $type = $params['type'] ?? 'info';
  22. $text = $params['text'] ?? '';
  23. $title = $params['title'] ?? '';
  24. $prefix = match ($type) {
  25. 'warning' => '[警告]',
  26. 'error' => '[错误]',
  27. 'success' => '[成功]',
  28. default => '[信息]'
  29. };
  30. return $prefix . ($title ? " $title: " : ' ') . $text;
  31. },
  32. 'info' => function ($params) {
  33. $content = $params['content'] ?? '';
  34. $title = $params['title'] ?? '';
  35. return '[信息]' . ($title ? " $title: " : ' ') . $content;
  36. },
  37. 'warning' => function ($params) {
  38. $message = $params['message'] ?? '';
  39. $title = $params['title'] ?? '';
  40. return '[警告]' . ($title ? " $title: " : ' ') . $message;
  41. }
  42. ];
  43. }
  44. public function render(ParsedDocument $document): string
  45. {
  46. $text = '';
  47. foreach ($document->content as $node) {
  48. $text .= $this->renderNode($node);
  49. }
  50. return $text;
  51. }
  52. private function renderNode(ContentNode $node): string
  53. {
  54. switch ($node->type) {
  55. case 'text':
  56. return $this->renderText($node);
  57. case 'markdown':
  58. return $this->renderMarkdownAsText($node);
  59. case 'template':
  60. return $this->renderTemplate($node);
  61. default:
  62. return '';
  63. }
  64. }
  65. public function renderText(TextNode $text): string
  66. {
  67. return $text->content;
  68. }
  69. private function renderMarkdownAsText(MarkdownNode $markdown): string
  70. {
  71. // 移除 Markdown 标记,返回纯文本
  72. $text = $markdown->content;
  73. // 移除粗体和斜体标记
  74. $text = preg_replace('/\*\*(.*?)\*\*/', '$1', $text);
  75. $text = preg_replace('/\*(.*?)\*/', '$1', $text);
  76. // 移除链接标记,保留链接文本
  77. $text = preg_replace('/\[([^\]]+)\]\([^)]+\)/', '$1', $text);
  78. return $text;
  79. }
  80. public function renderTemplate(TemplateNode $template): string
  81. {
  82. if (!isset($this->templateTexts[$template->name])) {
  83. // 未知模板,返回简化的文本表示
  84. $text = $template->name;
  85. if (!empty($template->parameters)) {
  86. $paramTexts = [];
  87. foreach ($template->parameters as $key => $value) {
  88. if (is_array($value)) {
  89. $nestedText = '';
  90. foreach ($value as $childNode) {
  91. $nestedText .= $this->renderNode($childNode);
  92. }
  93. $paramTexts[] = is_numeric($key) ? $nestedText : "$key: $nestedText";
  94. } else {
  95. $paramTexts[] = is_numeric($key) ? $value : "$key: $value";
  96. }
  97. }
  98. $text .= '(' . implode(', ', $paramTexts) . ')';
  99. }
  100. return $text;
  101. }
  102. $renderer = $this->templateTexts[$template->name];
  103. // 处理参数中的嵌套内容
  104. $processedParams = [];
  105. foreach ($template->parameters as $key => $value) {
  106. if (is_array($value)) {
  107. $nestedText = '';
  108. foreach ($value as $childNode) {
  109. $nestedText .= $this->renderNode($childNode);
  110. }
  111. $processedParams[$key] = $nestedText;
  112. } else {
  113. $processedParams[$key] = $value;
  114. }
  115. }
  116. return $renderer($processedParams);
  117. }
  118. public function registerTemplate(string $name, callable $renderer): void
  119. {
  120. $this->templateTexts[$name] = $renderer;
  121. }
  122. }