Insert non-breaking space in [R]Markdown math expression for HTML output

Insert non-breaking space in [R]Markdown math expression for HTML output

我正在 bookdown 中写科学报告,我想使用 non-breaking spaces as thousands separators follwoing the SI/ISO 31-0 standard

实际上,我更喜欢 non-breaking thin space (U+202F/ ) 但为了简单起见,让我们考虑一下 U+00A0/ 在这里。

我设置了一个 knitr 挂钩来即时执行此操作:

knitr::knit_hooks$set(inline=function(output)
                               ifelse(is.numeric(output),
                                      prettyNum(round(output, 1),
                                                big.mark=' '),
                                      output))

只要我不在数学表达式中使用任何内联 R-expressions 返回数值输出 > 999,它就可以正常工作。

下面的 bookdown MWE 说明了这个问题:

---
output:
  bookdown::html_document2: default
---
```{r set-output-hook, include=FALSE}
knitr::knit_hooks$set(inline=function(output)
                               ifelse(is.numeric(output),
                                      prettyNum(round(output, 1),
                                                big.mark=' '),
                                      output))
```

This works:
The product of $\pi$ and `r 1000` is `r pi*1000`.

This fails to render: 
$\pi\cdot`r 1000`=`r pi*1000`$

This renders but is cumbersome as it requires me to know *a priori* which
values might exceed 999:
$\pi\cdot1000=`r as.character(round(pi*1000, 1))`$

我试图追踪它并想出了以下 rmarkdown MWE:

---
output:
  rmarkdown::html_document:
    keep_md: true
---

| Rmarkdown    | Render     | HTML                                                | Markdown     |
|--------------|------------|-----------------------------------------------------|--------------|
| `1000`       | 1000       |`1000`                                               | `1000`       |
|`00$`      |00$      |`<span class="math inline">\(1000\)</span>`          |`00$`      |
|              |            |                                                     |              |
|  `100,0`     | 100,0      |`100,0`                                              | `100,0`      |
|`0,0$`     |0,0$     |`<span class="math inline">\(100,0\)</span>`         |`0,0$`     |
|              |            |                                                     |              |
|  `100 0`     | 100 0      |`100 0`                                              | `100 0`      |
|`0 0$`     |0 0$     |`<span class="math inline">\(100 0\)</span>`         |`0 0$`     |
|              |            |                                                     |              |
|  `100&nbsp;0`| 100&nbsp;0 |`100 0`                                              | `100&nbsp;0` |
|`0&nbsp;0$`|0&nbsp;0$|`<span class="math inline">\(100&amp;nbsp;0\)</span>`|`0&nbsp;0$`|

table前两列足以看出问题: 每对行在文本和数学上下文中显示数字 1000 1 000);没有任何 space,使用逗号,使用简单的 space,并使用 non-breaking space 作为千位分隔符。 后者无法在数学上下文中呈现。

为了找出问题所在,我检查了生成的 HTML 和 Markdown (keep_md: true) 输出,并将相应的代码添加为第三列和第四列,以便更好地了解发生了什么。

为清楚起见,这里是上述 rmarkdown MWE 的调整版本,将简单的 spaces 替换为 _,将 non-breaking spaces 替换为 -在 HTML 和 Markdown 输出列中:

---
output:
  rmarkdown::html_document:
    keep_md: true
---

| Rmarkdown    | Render     | HTML                                                | Markdown     |
|--------------|------------|-----------------------------------------------------|--------------|
| `1000`       | 1000       |`1000`                                               | `1000`       |
|`00$`      |00$      |`<span_class="math_inline">\(1000\)</span>`          |`00$`      |
|              |            |                                                     |              |
|  `100,0`     | 100,0      |`100,0`                                              | `100,0`      |
|`0,0$`     |0,0$     |`<span_class="math_inline">\(100,0\)</span>`         |`0,0$`     |
|              |            |                                                     |              |
|  `100 0`     | 100 0      |`100_0`                                              | `100_0`      |
|`0 0$`     |0 0$     |`<span_class="math_inline">\(100_0\)</span>`         |`0_0$`     |
|              |            |                                                     |              |
|  `100&nbsp;0`| 100&nbsp;0 |`100-0`                                              | `100&nbsp;0` |
|`0&nbsp;0$`|0&nbsp;0$|`<span_class="math_inline">\(100&amp;nbsp;0\)</span>`|`0&nbsp;0$`|

据我所知

  1. 这不是 bookdown 问题,因为它可以通过普通 rmarkdown 重现。
    • 我只是提到书本,因为我很乐意 bookdown-specific work-around。
  2. 这不是 rmarkdown 问题,因为生成的 Markdown 看起来与我期望的完全一样。
    • 我只是提到 rmarkdown,因为我很乐意 rmarkdown-specific work-around。
  3. 这不是 MathJax 问题,因为 HTML 代码将普通的 & 替换为 &amp;,我不希望它能正确呈现。
    • 无论如何,我会很高兴 MathJax-related work-around。
  4. 我怀疑是 pandoc 在代码和数学上下文中将 & 替换为 &amp; 而不是在文本上下文中。
    • 我确定如果有办法说服pandoc 这样做,通过rmarkdown YAML header.

任何关于如何将 &nbsp; 从字面上从 Markdown 转移到数学上下文中的 HTML 的想法可能会帮助我弄清楚其余部分。


附录:

由于 by @tarleb0&nbsp;0$ 不是有效的 Latex。 但是,手动修改 HTML 以包含 \(100&nbsp;0\)MathJax treats non-breaking spaces as spaces 一样工作正常。 由于我不关心通过 LaTex 输出 PDF,这意味着不将 0&nbsp;0$ 转换为 \(100&amp;nbsp;0\) 而是转换为 \(100&nbsp;0\)(就像 100&nbsp;0 未转换为 100&amp;nbsp;0 或者)将 Markdown 转换为 HTML 将是我所需要的。

Pandoc 希望数学环境包含 LaTeX 数学标记,而不是 HTML。转换失败,因为 pandoc 试图将 0&nbsp;000$ 输出为 LaTeX,但这给出了 \(100&amp;nbsp;000\) 而不是你想要的。

作为解决方案,您可以尝试在挂钩中使用文字 narrow no-break space unicode 字符“”。

或者,可以使用 pandoc lua filter (or possibly a R pandoc-filter) 强制 pandoc 不加改变地传递数学内容:

-- filename: force plain math
function Math (el)
  if el.mathtype == 'DisplayMath' then
    return pandoc.RawInline('html', '\[' .. el.text .. '\]')
  else -- InlineMath
    return pandoc.RawInline('html', '\(' .. el.text .. '\)')
  end
end

保存到文件并通过添加

使用它
output:
  bookdown::html_document2:
    pandoc_args: --lua-filter=force-plain-math.lua

到您的文档。