Tilt (kramdown) 在渲染 markdown 时阻止 ERB 处理

Tilt (kramdown) preventing ERB processing when rendering markdown

我正在用 Middleman 建立一个网站。我在数据文件中存储了大量信息,因为我将在多个页面上使用相同的信息。 (部分内容对我不起作用,因为数据中的相同文本可以与不同的 HTML 标签一起使用,或者针对不同的页面稍作修改。)

我想在数据文件中编写 markdown,然后在特定页面的 HAML 模板中使用它。当我尝试创建相对于其他页面的 links,同时使用对其他数据文件的引用时,结果 HTML 不是它应该的。

data/pages.yaml:

pageA:
  link: /it-can-change-A.html
  name: PageA name
  info: Some other related info

pageB:
  link: /subject-to-change-B.html
  name: PageB name
  info: Some other related info

pageC:
  link: /some-C.html
  name: PageC name
  info: Some other related info

data/faq.yaml:

testcase: Some text with [internal link to page A](ref.pageA). And *another* [internal reference](ref.pageB).

verbatim: Some text with [internal link to page A](/it-can-change-A.html). And *another* [internal reference](/subject-to-change-B.html).

在尝试找到此问题的根本原因时,我测试了各种方法以从数据文件中提取 "extract" 相对 link 并将它们放入 HAML 模板中。我的最终目标是让案例 (5) 发挥作用。

我直接在我的test.html.md.erb.haml中评论了每段代码的结果:

请注意,HAML 必须在 ERB 之前处理,因此 .haml 需要是最后一个扩展名。如果 .erb 和 .haml 扩展名交换位置,下面的情况 (3) 和 (4) 将产生不同的输出。

/ Pure ERB; ERB is processed before markdown => :)
(1) This is just some text with [ERB link to first page](<%= data.pages.pageA.link %>) and *another* one [to second page](<%= data.pages.pageB.link %>). 

/ ERB inside HAML tag; markdown is not processed => :|
.haml
    (2) This is just some text with [ERB link to first page](<%= data.pages.pageA.link %>) and *another* one [to second page](<%= data.pages.pageB.link %>). 

/ Helper used WITHOUT a tag; ERB is processed before markdown => :)
(3)
= refonly(data.faq.testcase) 

/ Helper used WITH a tag; ERB is processed, but markdown is not => :|
.question1
    (4)
    = refonly(data.faq.testcase)

/ "Tilt-powered" helper used WITHIN a tag; trying to process markdown with Tilt results in "%=%20data.pages.pageA.link%20%" links. Expected behavior: ERB should be processed first, then Tilt should process markdown with actual relative links being the same as in .question1 above => :(
.question2
    (5)
    = mymarkdown(data.faq.testcase)

/ Helper with Tilt to process verbatim text; markdown is processed correctly => :)
.question3
    (6)
    = justmarkdown(data.faq.verbatim)

上面模板中使用的助手:

def refonly(text)
    text.gsub(/ref\.(page[A-Z])/,"<\%= data.pages.\1.link %>")
end

def mymarkdown(text)
    newtext = refonly(text)
    Tilt['markdown'].new(context: @app) { newtext }.render
end

def justmarkdown(text)
    Tilt['markdown'].new(context: @app) { text }.render
end

第一个助手的目的是将数据文件(ref.pageName)中易于编写的引用更改为ERB代码,与(1)中使用的代码相同。第二个助手的目的是在 .md 模板扩展本身无法自动呈现的情况下呈现降价。最后一个助手的目的是表明 Tilt 可以在 (6) 中正确呈现逐字文本,但是当它接受相同的文本作为变量时,它不能在 (5) 中提供相同的输出。

一个。当我使用 "pure ERB" (1) 或 refonly 没有 HAML 标签的助手 (3) 时,输出符合预期:相对路径来自数据文件,然后由默认降价引擎 (kramdown) 处理降价感谢 .md 模板扩展。

乙。当我尝试使用 HAML 标签时,无论是直接使用 ERB 代码 (2),还是使用 refonly 帮助器 (4),ERB 都会被正确处理并放入输出中。但是,由于某些原因,markdown 不会自动处理,即使在 .html 之后直接使用 .md 扩展,因此 markdown 应该在 HAML 和 ERB 位完成后处理。

C。为了 "force" markdown 渲染,我在我的第二个助手中使用了 Tilt。我的意图是将 refonly 返回的文本(具有正确的降价语法,预期的 link 从数据中提取)传递给 Tilt。我的期望是 Tilt 将简单地呈现在 (5) 中传递给它的逐字文本,就像它在 (6) 中所做的那样。相反,结果 link 指向 %=%20data.pages.pageA.link%20%,这似乎是 HTML 代码来逐字显示 ERB 代码。因此,看起来将 newtext 变量传递给 Tilt 会以某种方式停止 ERB 处理,而 ERB 代码会直接传递给 markdown。

我的 主要 问题是:如何确保 Tilt 获得具有相对 link 的正确文本(由 refonly 返回)和在 (5)?

中产生预期输出

我的次要问题:为什么在B.下描述的情况下,中间人不自动处理markdown?

我假设回答我的主要问题需要了解 Ruby 和 Tilt,而回答我的次要问题需要了解 Middleman。虽然解决我的主要问题会很好,但回答次要问题可能会允许完全跳过 Tilt,从而以更简单的方式解决问题。

由于您已经正确地进行了 HAML 解析,并且当您逐字呈现 links 时它可以工作,请尝试使用助手直接注入 links 而无需转到 ERB。由于 HAML 已经 运行 Ruby 代码,我认为也没有必要通过 ERB 传递它。我认为 eval 将使您获得与使用 ERB 相同的效果。像这样:

def refonly(text)
  text.scan(/ref\.(page[A-Z])/).each do |groups|
    page_name = groups[0]
    text.gsub!(/ref\.#{page_name}/, eval("data.pages.#{page_name}.link"))
  end
  text
end

编辑:扫描文本将允许您获取每个 page_name,因此您可以遍历每个并用其 link.

替换每个页面引用