Jekyll with Rouge 和 KaTeX 代码中不能有 $

标签 jekyll katex rouge

我正在创建一个新的 Jekyll 博客设置,我想在其中自行托管并生成服务器端的所有内容(基本上除了 Disqus 和 Google Analytics 之外的所有内容)。我希望我的网站即使在关闭 JS 的浏览器上也能正常运行,这就是为什么我在网站生成期间使用 Kramdown+Rouge 进行语法突出显示,并使用 KaTex 来渲染 TeX 公式。

不过我发现了一个问题。当我有这样的例子时:

```bash
$ echo test
test
```

它将破坏 KaTeX 命令:

{% katexmm %}
{{ content }}
{% endkatexmm %}

我找出原因了:

  • rouge 将代码片段变成类似 <span class="gp">$</span> 的内容
  • katexmm预计每个 $与另一个 $ 配对或转义为 \$

我想知道如何解决这个问题,例如通过转义所有 $里面pre ,但留下其他$ (旨在用作实际的 LaTeX 片段)完好无损。或者也许以某种方式配置 jekyll-katex 来忽略未配对的 $ ? ( throw_error: false 选项在文本已使用美元符号匹配后起作用,因此没有帮助)。

我想在配置中修复此问题或代替应用 katexmm ,这样我就不必修改任何帖子的内容。

最佳答案

我设法通过修改 tag 来消除错误来自jekyll-katex解决code (内联,使用单个波形符)和 pre code (使用缩进或 3 个波形符组成的 block ):

# frozen_string_literal: true

require 'jekyll'
require 'jekyll-katex/configuration'
require 'jekyll-katex/katex_js'
require 'nokogiri'

module Jekyll
  module Tags
    # Defines the custom Liquid tag for compile-time rendering of KaTeX math.
    # This differs from the katex tag in that it allows use of `$` and `$$` fencing to mark math mode blocks similar to
    # standard latex.
    #   {% katexmm %}
    #   This is a mixed environment where you can write text as normal but fence off latex math using `$`. Escape
    #   using `\$`. For example.
    #   $latex math with \$$
    #   $$display mode latex$$
    #   {% endkatexmm %}
    class KatexMathModeFixed < Liquid::Block
      LOG_TOPIC = 'KatexMathModeFixed:'
      KATEX ||= Jekyll::Katex::KATEX_JS
      LATEX_TOKEN_PATTERN = /(?<!\\)([$]{2}|[$]{1})(.+?)(?<!\\)\1/m

      def initialize(tag_name, markup, tokens)
        super
        @markup = markup
        @tokens = tokens
        @display_mode_rendering = Jekyll::Katex::Configuration.global_rendering_options.merge(displayMode: true)
        @inline_mode_rendering = Jekyll::Katex::Configuration.global_rendering_options.merge(displayMode: false)
      end

      def render(context)
        enclosed_block = super
        fixed_block = fix_code(enclosed_block)
        rendered_str = fixed_block.to_s.gsub(LATEX_TOKEN_PATTERN) do |match|
          display_mode = match.to_s.start_with? '$$'
          rendering_options = display_mode ? @display_mode_rendering : @inline_mode_rendering
          Jekyll.logger.debug LOG_TOPIC, "Rendering matched block - #{match}"
          KATEX.call('katex.renderToString', Regexp.last_match(2), rendering_options)
        end
        # KaTeX should fix escaped `$` within fenced blocks, this addresses instances outside of math mode
        rendered_str.to_s.gsub(/\\[$]/, '$').to_s
      end

      def fix_code(input)
        updated = false
        html = Nokogiri::HTML.fragment(input)
        Jekyll.logger.debug LOG_TOPIC, "Fixing - #{input}"
        html.css("code, code span").each do |c|
          if c.css('*').empty? && c.content['$']
            updated = true
            Jekyll.logger.debug LOG_TOPIC, "current tag - #{c}"
            content = c.content
            content['$'] = '\$'
            c.content = content
            Jekyll.logger.debug LOG_TOPIC, "current tag now - #{c}/#{content}"
          end
        end
        output = html.to_s
        Jekyll.logger.debug LOG_TOPIC, "Fixed - #{output}"
        if updated then html.to_s else input end
      end
    end
  end
end

Liquid::Template.register_tag('katexmmx', Jekyll::Tags::KatexMathModeFixed)

它可以安装在 _plugins目录。

事实是,这仍然有问题 - 默认情况下 kramdown 仍然尝试使用 mathjax 引擎并生成 <script type="math/tex"> ,所以必须改变。当我调查如何时,我发现kramdown支持math_engine: katex同样 - 我只需要添加字体和 CSS,并且 jekyll-katex变得完全过时(以及我的解决方法,如果有人好奇,我将把它留在这里)。

关于Jekyll with Rouge 和 KaTeX 代码中不能有 $,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53924888/

相关文章:

css - Jekyll 语法高亮显示不起作用 - 未添加类

ruby - Jekyll 中的隔离代码块

ruby-on-rails-5 - Redcarpet 和 Rouge 的语法突出显示在 Rails 5 应用程序中不起作用

css - Github 页面代码块离线和在线表现不同

c++ - 如何在我的站点中使用在线 C++ 编译器

javascript - 如何在 Katex 中创建换行符?

html - 如何设置与父元素相同的高度

javascript - 我如何使用 KaTeX 渲染 $..$ 中的所有内联公式?

Github Pages 显示 future 日期的帖子

yaml - Jekyll - 无法访问自定义前端变量