【问题标题】:Insert non-breaking space in [R]Markdown math expression for HTML output在 HTML 输出的 [R]Markdown 数学表达式中插入不间断空格
【发布时间】:2018-06-22 04:30:09
【问题描述】:

我正在 bookdown 中撰写科学报告,我想使用non-breaking spaces 作为SI/ISO 31-0 standard 后面的千位分隔符。

实际上,我更喜欢不中断的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))

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

下面的 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`       |
|`$1000$`      |$1000$      |`<span class="math inline">\(1000\)</span>`          |`$1000$`      |
|              |            |                                                     |              |
|  `100,0`     | 100,0      |`100,0`                                              | `100,0`      |
|`$100,0$`     |$100,0$     |`<span class="math inline">\(100,0\)</span>`         |`$100,0$`     |
|              |            |                                                     |              |
|  `100 0`     | 100 0      |`100 0`                                              | `100 0`      |
|`$100 0$`     |$100 0$     |`<span class="math inline">\(100 0\)</span>`         |`$100 0$`     |
|              |            |                                                     |              |
|  `100&nbsp;0`| 100&nbsp;0 |`100 0`                                              | `100&nbsp;0` |
|`$100&nbsp;0$`|$100&nbsp;0$|`<span class="math inline">\(100&amp;nbsp;0\)</span>`|`$100&nbsp;0$`|

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

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

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

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

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

据我所知

  1. 这不是 bookdown 问题,因为它可以通过普通的 rmarkdown 复制。
    • 我只是提到了 bookdown,因为我很乐意使用特定于 bookdown 的解决方法。
  2. 这不是 rmarkdown 问题,因为生成的 Markdown 看起来与我预期的完全一样。
    • 我只是提到 rmarkdown,因为我很乐意使用特定于 rmarkdown 的解决方法。
  3. 这不是 MathJax 问题,因为 HTML 代码已将纯 &amp;amp; 替换为 &amp;amp;,我不希望它能够正确呈现。
    • 无论如何,我很乐意使用与 MathJax 相关的解决方法。
  4. 我怀疑是 pandoc 在代码和数学上下文中将 &amp;amp; 替换为 &amp;amp; 而不是在文本上下文中。
    • 我确定如果有办法说服 pandoc 这样做,通过 rmarkdown YAML 标头配置它会很容易。

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


附录:

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

【问题讨论】:

    标签: markdown r-markdown pandoc mathjax bookdown


    【解决方案1】:

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

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

    或者,可以使用pandoc lua filter(或者可能是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
    

    到您的文档。

    【讨论】:

    • 感谢您的回答。我将我对您第一段的想法添加到我的问题中。关于第二段中的第一个建议,你能给我一个关于如何实际实现它的代码示例吗?这会通过单独的knitr 挂钩来完成吗?还是一个人利用某些 pandoc 功能根据目标格式使用不同的文本?
    • 我会完善我的答案并在以后用更好的东西替换它。我意识到我误解了您问题的某些部分并且忘记了 knitr hooks 是如何工作的。
    • Thx, +1 + 被接受为文字 &amp;nbsp; 在我的情况下似乎有效。我将不得不检查 MathJax 是否也可以处理窄版本。过滤器解决方案看起来也很有希望,但我无法对其进行测试,因为这似乎需要 pandoc >=2.0,而我现在在我可以使用的任何系统上都没有可用的测试。
    • 只是一个快速更新:我在我的 Ubuntu 16.04 机器上使用 the deb fileapt-get install -f ./pandoc-2.1-1-amd64.deb 安装了 pandoc 2.1。在上面我的 MWE 的 YAML 标头中添加(现在需要)title: test 后,我也可以成功使用您的 lua 过滤器。
    猜你喜欢
    • 2021-02-07
    • 2018-08-11
    • 1970-01-01
    • 2018-05-01
    • 2022-06-16
    • 2017-10-15
    • 2014-09-29
    • 1970-01-01
    相关资源
    最近更新 更多