在 HTML 输出的 [R]Markdown 数学表达式中插入不间断空格

msc*_*lli 5 markdown mathjax pandoc r-markdown bookdown

我正在 bookdown 中撰写科学报告,我想使用不间断空格作为遵循SI/ISO 31-0 标准的千位分隔符。

\n\n

实际上,我更喜欢不间断的细空格U+202F/  ),但为了简单起见,让我们在这里考虑U+00A0/ 。 

\n\n

我设置了一个knitr钩子来动态执行此操作:

\n\n
knitr::knit_hooks$set(inline=function(output)\n                               ifelse(is.numeric(output),\n                                      prettyNum(round(output, 1),\n                                                big.mark=\' \'),\n                                      output))\n
Run Code Online (Sandbox Code Playgroud)\n\n

只要我不在数学表达式中使用任何返回数值输出 > 999 的内联 R 表达式,这就会按预期工作。

\n\n

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

\n\n
---\noutput:\n  bookdown::html_document2: default\n---\n```{r set-output-hook, include=FALSE}\nknitr::knit_hooks$set(inline=function(output)\n                               ifelse(is.numeric(output),\n                                      prettyNum(round(output, 1),\n                                                big.mark=\' \'),\n                                      output))\n```\n\nThis works:\nThe product of $\\pi$ and `r 1000` is `r pi*1000`.\n\nThis fails to render: \n$\\pi\\cdot`r 1000`=`r pi*1000`$\n\nThis renders but is cumbersome as it requires me to know *a priori* which\nvalues might exceed 999:\n$\\pi\\cdot1000=`r as.character(round(pi*1000, 1))`$\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
---\noutput:\n  rmarkdown::html_document:\n    keep_md: true\n---\n\n| Rmarkdown    | Render     | HTML                                                | Markdown     |\n|--------------|------------|-----------------------------------------------------|--------------|\n| `1000`       | 1000       |`1000`                                               | `1000`       |\n|`$1000$`      |$1000$      |`<span class="math inline">\\(1000\\)</span>`          |`$1000$`      |\n|              |            |                                                     |              |\n|  `100,0`     | 100,0      |`100,0`                                              | `100,0`      |\n|`$100,0$`     |$100,0$     |`<span class="math inline">\\(100,0\\)</span>`         |`$100,0$`     |\n|              |            |                                                     |              |\n|  `100 0`     | 100 0      |`100 0`                                              | `100 0`      |\n|`$100 0$`     |$100 0$     |`<span class="math inline">\\(100 0\\)</span>`         |`$100 0$`     |\n|              |            |                                                     |              |\n|  `100&nbsp;0`| 100&nbsp;0 |`100\xc2\xa00`                                              | `100&nbsp;0` |\n|`$100&nbsp;0$`|$100&nbsp;0$|`<span class="math inline">\\(100&amp;nbsp;0\\)</span>`|`$100&nbsp;0$`|\n
Run Code Online (Sandbox Code Playgroud)\n\n

表的前两列足以看出问题:\n每对行在文本和数学上下文中显示数字1000 1 000);不带任何空格、带逗号、带简单空格以及使用不间断空格作为千​​位分隔符。\n后者无法在数学上下文中呈现。

\n\n

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

\n\n

为了清楚起见,下面是上述 rmarkdown MWE 的调整版本,在 HTML 和 Markdown 输出列中替换简单空格_和不间断空格:-

\n\n
---\noutput:\n  rmarkdown::html_document:\n    keep_md: true\n---\n\n| Rmarkdown    | Render     | HTML                                                | Markdown     |\n|--------------|------------|-----------------------------------------------------|--------------|\n| `1000`       | 1000       |`1000`                                               | `1000`       |\n|`$1000$`      |$1000$      |`<span_class="math_inline">\\(1000\\)</span>`          |`$1000$`      |\n|              |            |                                                     |              |\n|  `100,0`     | 100,0      |`100,0`                                              | `100,0`      |\n|`$100,0$`     |$100,0$     |`<span_class="math_inline">\\(100,0\\)</span>`         |`$100,0$`     |\n|              |            |                                                     |              |\n|  `100 0`     | 100 0      |`100_0`                                              | `100_0`      |\n|`$100 0$`     |$100 0$     |`<span_class="math_inline">\\(100_0\\)</span>`         |`$100_0$`     |\n|              |            |                                                     |              |\n|  `100&nbsp;0`| 100&nbsp;0 |`100-0`                                              | `100&nbsp;0` |\n|`$100&nbsp;0$`|$100&nbsp;0$|`<span_class="math_inline">\\(100&amp;nbsp;0\\)</span>`|`$100&nbsp;0$`|\n
Run Code Online (Sandbox Code Playgroud)\n\n

据我所知

\n\n
    \n
  1. 这不是预订问题,因为它可以通过普通的 rmarkdown 重现。\n\n
      \n
    • 我只是提到 bookdown,因为我很高兴有一个特定于 bookdown 的解决方法。
    • \n
  2. \n
  3. 这不是 rmarkdown 问题,因为生成的 Markdown 看起来与我期望的完全一样。\n\n
      \n
    • 我只是提到 rmarkdown,因为我会对特定于 rmarkdown 的解决方法感到满意。
    • \n
  4. \n
  5. 这不是 MathJax 问题,因为 HTML 代码已将纯文本&替换为&amp;,并且我不希望它能够正确呈现。\n\n
      \n
    • 不管怎样,我会对 MathJax 相关的解决方法感到高兴。
    • \n
  6. \n
  7. 我怀疑是 pandoc 在代码和数学上下文中替换了&by &amp;,但在文本上下文中却没有替换。\n\n
      \n
    • 我确信如果有办法说服 pandoc要这样做,那么通过 rmarkdown YAML 标头来配置它会很容易。
    • \n
  8. \n
\n\n

任何关于如何&nbsp;在数学上下文中从 Markdown 字面​​转换为 HTML 的想法可能会帮助我弄清楚剩下的事情。

\n\n
\n\n

附录:

\n\n

正如@tarleb指出的,它是无效的 Latex。\n但是,手动修改 HTML 以包含工作得很好,因为MathJax 将不间断空格视为空格。\n由于我不关心通过 LaTex 的 PDF 输出,这意味着根本不转换为但到(就像未转换为$100&nbsp;0$\\(100&nbsp;0\\)$100&nbsp;0$\\(100&amp;nbsp;0\\)\\(100&nbsp;0\\)100&nbsp;0100&amp;nbsp;0当将 Markdown 转换为 HTML 时,

\n

tar*_*leb 3

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

\n\n

作为解决方案,您可以尝试在挂钩中使用文字窄不间断空格unicode 字符“ ”。\xe2\x80\xaf

\n\n

或者,可以使用pandoc lua 过滤器(或者可能是R pandoc-filter)来强制 pandoc 不改变地传递数学内容:

\n\n
-- filename: force plain math\nfunction Math (el)\n  if el.mathtype == \'DisplayMath\' then\n    return pandoc.RawInline(\'html\', \'\\\\[\' .. el.text .. \'\\\\]\')\n  else -- InlineMath\n    return pandoc.RawInline(\'html\', \'\\\\(\' .. el.text .. \'\\\\)\')\n  end\nend\n
Run Code Online (Sandbox Code Playgroud)\n\n

保存到文件并通过添加来使用它

\n\n
output:\n  bookdown::html_document2:\n    pandoc_args: --lua-filter=force-plain-math.lua\n
Run Code Online (Sandbox Code Playgroud)\n\n

到您的文档。

\n