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

Rails富文本编辑器中代码语法高亮的实现问题

Rails ActionText + Rouge 语法高亮解决方案
  • 核心解决思路:让Rouge生成的HTML代码绕过ActionText的自动转义,同时适配trix-content容器的渲染规则。

1. 编写代码高亮辅助方法

修改app/helpers/application_helper.rb,添加以下方法,通过Nokogiri解析ActionText内容,替换其中的代码块为Rouge高亮后的HTML:

def highlight_action_text_code(content)
  return content unless content.is_a?(ActionText::Content)

  doc = Nokogiri::HTML.fragment(content.to_s)
  doc.css('code').each do |code|
    # 跳过已被pre包裹的code块,避免重复处理
    next if code.parent.name == 'pre'

    # 自动识别代码语言,也可手动指定(比如读取code标签的data-lang属性)
    lexer = Rouge::Lexer.guess(source: code.text)
    formatter = Rouge::Formatters::HTML.new(css_class: 'highlight')
    highlighted_html = formatter.format(lexer.lex(code.text))

    # 替换原code标签为高亮后的pre块
    code.replace(highlighted_html)
  end

  # 返回安全HTML,防止Rails自动转义
  doc.to_html.html_safe
end

2. 视图中使用辅助方法渲染

不要直接渲染ActionText字段,改用上述辅助方法:

<%= highlight_action_text_code(@your_model.your_action_text_attribute) %>

3. 添加样式适配trix-content

在样式文件中补充以下CSS,确保高亮样式在trix容器内正常显示:

.trix-content .highlight {
  background-color: #f8f8f8;
  padding: 1.2rem;
  border-radius: 6px;
  overflow-x: auto;
  margin: 1rem 0;
}

.trix-content .highlight code {
  background: transparent;
  padding: 0;
  font-family: monospace;
}

额外优化

如果需要支持手动指定代码语言,可以让用户在编辑时给code标签添加data-lang属性,然后修改辅助方法中的语言识别逻辑:

lexer = Rouge::Lexer.find(code['data-lang']) || Rouge::Lexer.guess(source: code.text)

不需要退回到text_field,ActionText的富文本编辑体验更贴合需求,只要处理好代码块的渲染逻辑即可。

内容的提问来源于stack exchange,提问作者Taku Mapfumo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 16:14:55