You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为react-markdown添加自定义语法,使{{}}内文本变蓝且兼容原有语法?

为react-markdown添加{{ }}自定义蓝色文本语法

你的现有实现存在几个问题:

  • 拆分文本后生成了多个<h2>或<p>标签,这不符合HTML规范(每个标题/段落应该是单个元素)
  • 依赖text.children[0]获取文本内容的方式很脆弱,当Markdown元素包含多个子节点时会失效
  • 只能处理<h2>和<p>元素,其他Markdown元素(比如列表项、链接文本等)中的{{ }}无法被识别

更可靠的方案是通过remark插件解析{{ }}语法,将其转换为自定义AST节点,再统一渲染为蓝色文本。这样能确保所有Markdown元素中的{{ }}都能生效,同时保持原有Markdown结构的正确性。

修正后的实现代码

import React from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

// 自定义remark插件:解析{{ }}语法
const remarkCustomBlueText = () => {
  return (tree) => {
    // 遍历AST节点
    const visitNode = (node) => {
      if (node.type === "text" && node.value.includes("{{")) {
        // 拆分文本为普通文本和{{ }}包裹的部分
        const parts = node.value.split(/({{(.*?)}})/);
        const newChildren = [];
        
        parts.forEach(part => {
          if (part.startsWith("{{") && part.endsWith("}}")) {
            // 创建自定义节点
            newChildren.push({
              type: "blueText",
              value: part.slice(2, -2).trim(), // 去掉{{ }}并去除首尾空格
              data: { hName: "span" }
            });
          } else if (part) {
            // 保留普通文本节点
            newChildren.push({ type: "text", value: part });
          }
        });
        
        // 替换原文本节点为新的子节点数组
        node.type = "textParent";
        node.children = newChildren;
      }
      
      // 递归处理子节点
      if (node.children) {
        node.children.forEach(visitNode);
      }
    };
    
    visitNode(tree);
  };
};

const CustomMarkdown = ({ children }) => {
  return (
    <ReactMarkdown 
      remarkPlugins={[remarkGfm, remarkCustomBlueText]} 
      components={{
        // 渲染自定义blueText节点
        blueText: ({ value }) => (
          <span style={{ color: "blue" }}>{value}</span>
        )
      }}
    >
      {children}
    </ReactMarkdown>
  );
};

export default CustomMarkdown;

方案说明

  1. remark插件解析语法:通过遍历AST树,识别包含{{ }}的文本节点,将其拆分为普通文本和自定义blueText节点,确保所有Markdown元素中的{{ }}都能被处理。
  2. 统一渲染自定义节点:在components中添加blueText的渲染逻辑,将其转换为蓝色的<span>标签。
  3. 兼容性保障:该方案不会破坏原有Markdown语法,无论是在标题、段落、列表还是其他元素中的{{ }}都能正常显示为蓝色。

内容的提问来源于stack exchange,提问作者Шэйд

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 20:00:28