rstudio / distill

Distill for R Markdown
https://rstudio.github.io/distill/
Apache License 2.0
423 stars 58 forks source link

LaTeX environment support from bookdown #433

Open shamindras opened 2 years ago

shamindras commented 2 years ago

I'm an active distill user and am grateful for this nice blogging package.

I plan to write more technical math related posts and wanted to use LaTeX environments, e.g., theorem, lemma, corollaryetc. I've previously asked about #101.

I recently revived this discussion on stackoverflow. I received a thoughtful solution where a user made many detailed modifications to the CSS to get it working. As a result I'm intentionally cross-posting and raising this an issue here.

Basically, I was a little surprised that distill users would need to go to such lengths to make LaTeX environments work, given that bookdown has implemented rmarkdown versions here and here. I wanted to flag it with the distill team to get the official approach to this.

Here is the minimal reprex to help understand the issue (from the stackoverflow post above).

---
title: "Test Title"
description: |
  Test description
author: Test author
date: 2021-12-31
output:
  distill::distill_article:
    self_contained: false
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library(bookdown)

TL;DR;

Trying to ensure that theorem environments are working in distill::distill_article.

Main theorems

With the definitional background established, let's move onto the main theorem of this article.

\begin{align} g(X{n}) &= g(\theta)+g'({\tilde{\theta}})(X{n}-\theta) \notag \ \sqrt{n}[g(X{n})-g(\theta)] &= g'\left({\tilde{\theta}}\right) \sqrt{n}[X{n}-\theta ] (#eq:align) \end{align}

\begin{theorem}[Delta Method]\label{nthm:deltamethod} g(X{n}) &= g(\theta)+g'({\tilde{\theta}})(X{n}-\theta) \notag \ \sqrt{n}[g(X{n})-g(\theta)] &= g'\left({\tilde{\theta}}\right) \sqrt{n}[X{n}-\theta ] (#eq:align) \end{theorem}

We have a labeled and named theorem below, and \@ref(nthm:deltamethod).

::: {.theorem #pythagoras name="Pythagorean theorem"} For a right triangle, if $c$ denotes the length of the hypotenuse and $a$ and $b$ denote the lengths of the other two sides, we have

$$a^2 + b^2 = c^2$$ :::

We have a labeled and named theorem below, and \@ref(thm:pythagoras).


Could anyone please explain how to get these environments from `bookdown` without needing to modify the CSS for each environment? Since `distill` is meant for technical publishing, I assumed there would be a much easier way to get these `bookdown` `LaTeX` environments working directly. I may have missed them due to my lack of understanding.

<details>
<summary>Session info</summary>
<p>

```r

─ Session info ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 setting  value                       
 version  R version 4.1.2 (2021-11-01)
 os       macOS Monterey 12.0.1       
 system   x86_64, darwin17.0          
 ui       RStudio                     
 language (EN)                        
 collate  en_US.UTF-8                 
 ctype    en_US.UTF-8                 
 tz       America/New_York            
 date     2022-01-02                  

─ Packages ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 package     * version date       lib source             
 assertthat    0.2.1   2019-03-21 [1] standard (@0.2.1)  
 backports     1.2.1   2020-12-09 [1] standard (@1.2.1)  
 bookdown    * 0.24    2021-09-02 [1] CRAN (R 4.1.0)     
 broom         0.7.10  2021-10-31 [1] CRAN (R 4.1.0)     
 cachem        1.0.5   2021-05-15 [1] standard (@1.0.5)  
 cellranger    1.1.0   2016-07-27 [1] standard (@1.1.0)  
 cli           3.1.0   2021-10-27 [1] CRAN (R 4.1.0)     
 clipr         0.7.1   2020-10-08 [1] standard (@0.7.1)  
 colorspace    2.0-2   2021-06-24 [1] standard (@2.0-2)  
 crayon        1.4.1   2021-02-08 [1] standard (@1.4.1)  
 DBI           1.1.1   2021-01-15 [1] standard (@1.1.1)  
 dbplyr        2.1.1   2021-04-06 [1] standard (@2.1.1)  
 desc          1.4.0   2021-09-28 [1] CRAN (R 4.1.0)     
 details       0.2.1   2020-01-12 [1] CRAN (R 4.1.0)     
 digest        0.6.27  2020-10-24 [1] standard (@0.6.27) 
 distill       1.3     2021-10-13 [1] CRAN (R 4.1.0)     
 downlit       0.4.0   2021-10-29 [1] CRAN (R 4.1.0)     
 dplyr       * 1.0.7   2021-06-18 [1] standard (@1.0.7)  
 ellipsis      0.3.2   2021-04-29 [1] standard (@0.3.2)  
 evaluate      0.14    2019-05-28 [1] standard (@0.14)   
 fansi         0.5.0   2021-05-25 [1] standard (@0.5.0)  
 fastmap       1.1.0   2021-01-25 [1] standard (@1.1.0)  
 forcats     * 0.5.1   2021-01-27 [1] CRAN (R 4.1.0)     
 fs            1.5.2   2021-12-08 [1] CRAN (R 4.1.0)     
 generics      0.1.0   2020-10-31 [1] standard (@0.1.0)  
 ggplot2     * 3.3.5   2021-06-25 [1] standard (@3.3.5)  
 glue          1.4.2   2020-08-27 [1] standard (@1.4.2)  
 gtable        0.3.0   2019-03-25 [1] standard (@0.3.0)  
 haven         2.4.1   2021-04-23 [1] standard (@2.4.1)  
 hms           1.1.0   2021-05-17 [1] standard (@1.1.0)  
 htmltools     0.5.1.1 2021-01-22 [1] standard (@0.5.1.1)
 httr          1.4.2   2020-07-20 [1] standard (@1.4.2)  
 jsonlite      1.7.2   2020-12-09 [1] standard (@1.7.2)  
 knitr         1.37    2021-12-16 [1] CRAN (R 4.1.0)     
 lifecycle     1.0.0   2021-02-15 [1] standard (@1.0.0)  
 lubridate     1.7.10  2021-02-26 [1] standard (@1.7.10) 
 magrittr      2.0.1   2020-11-17 [1] standard (@2.0.1)  
 memoise       2.0.0   2021-01-26 [1] standard (@2.0.0)  
 modelr        0.1.8   2020-05-19 [1] standard (@0.1.8)  
 munsell       0.5.0   2018-06-12 [1] standard (@0.5.0)  
 pillar        1.6.1   2021-05-16 [1] standard (@1.6.1)  
 pkgconfig     2.0.3   2019-09-22 [1] standard (@2.0.3)  
 png           0.1-7   2013-12-03 [1] standard (@0.1-7)  
 purrr       * 0.3.4   2020-04-17 [1] standard (@0.3.4)  
 R6            2.5.0   2020-10-28 [1] standard (@2.5.0)  
 Rcpp          1.0.7   2021-07-07 [1] CRAN (R 4.1.0)     
 readr       * 1.4.0   2020-10-05 [1] standard (@1.4.0)  
 readxl        1.3.1   2019-03-13 [1] standard (@1.3.1)  
 reprex        2.0.1   2021-08-05 [1] CRAN (R 4.1.0)     
 rlang         0.4.11  2021-04-30 [1] standard (@0.4.11) 
 rmarkdown     2.11    2021-09-14 [1] CRAN (R 4.1.0)     
 rprojroot     2.0.2   2020-11-15 [1] standard (@2.0.2)  
 rstudioapi    0.13    2020-11-12 [1] CRAN (R 4.1.0)     
 rvest         1.0.0   2021-03-09 [1] standard (@1.0.0)  
 scales        1.1.1   2020-05-11 [1] standard (@1.1.1)  
 sessioninfo   1.1.1   2018-11-05 [1] standard (@1.1.1)  
 stringi       1.6.2   2021-05-17 [1] standard (@1.6.2)  
 stringr     * 1.4.0   2019-02-10 [1] standard (@1.4.0)  
 tibble      * 3.1.2   2021-05-16 [1] standard (@3.1.2)  
 tidyr       * 1.1.3   2021-03-03 [1] standard (@1.1.3)  
 tidyselect    1.1.1   2021-04-30 [1] standard (@1.1.1)  
 tidyverse   * 1.3.1   2021-04-15 [1] CRAN (R 4.1.0)     
 utf8          1.2.2   2021-07-24 [1] CRAN (R 4.1.0)     
 vctrs         0.3.8   2021-04-29 [1] standard (@0.3.8)  
 withr         2.4.2   2021-04-18 [1] standard (@2.4.2)  
 xfun          0.29    2021-12-14 [1] CRAN (R 4.1.0)     
 xml2          1.3.2   2020-04-23 [1] standard (@1.3.2)  
 yaml          2.2.1   2020-02-01 [1] standard (@2.2.1)  

[1] /Library/Frameworks/R.framework/Versions/4.1/Resources/library

cderv commented 2 years ago

Currently Theorem and Proof env are built in bookdown formats only.

There is a way to access some of the feature with other format using what is described in https://bookdown.org/yihui/bookdown/a-single-document.html

output:
  bookdown::html_document2:
    base_format: distill::distill_article

This should work ok of Theorem I guess

---
title: "Test Title"
description: |
  Test description
author: Test author
date: 2021-12-31
output:
  bookdown::html_document2:
    self_contained: false
    base_format: distill::distill_article
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)

TL;DR;

Trying to ensure that theorem environments are working in distill::distill_article.

::: {#pythagoras .theorem name="Pythagorean theorem"} For a right triangle, if $c$ denotes the length of the hypotenuse and $a$ and $b$ denote the lengths of the other two sides, we have

$$a^2 + b^2 = c^2$$ :::

We have a labeled and named theorem below, and \@ref(thm:pythagoras).



![image](https://user-images.githubusercontent.com/6791940/148065835-43aaca17-cf31-4648-9927-be4b5ccfa1bf.png)

You would get the same HTML rendering as in **bookdown**. 

Unfortunately, this is not 100% accurate as all of the **bookdown** features won't work within a **distill** document. Related issue #287 which is linked to https://github.com/rstudio/bookdown/issues/1077

This is definitely something to improve and maybe built in within **distill**. Thanks for the report! 

We are also working on new stuff regarding scientific publishing and those type of consideration (theorem and other env from LaTeX to be available to HTML) is in our concerns. 
shamindras commented 2 years ago

@cderv - this is a very cool solution, and more in line with what I was expecting to change (i.e., yaml). I just tested and the main bookdown environments seem to work in the distill blog article I'm writing. I'll post back if there are any issues as I play with this more.

Could you please post your solution to my stackoverflow post? I can accept it as the official solution. Posting there in your capacity will help other users. Otherwise, I'll add it myself and make sure to credit and link to your approach later today.

One question, I understand that rendering these environments in distill::distill_article is mainly an issue with mathjax. I dug into the bookdown implementation of these environments. I found it is done here (there may be other files as well). Is it possible to load this lua file into the distill mathjax environment to make this easier to customize for distill purposes? Just a thought.

cderv commented 2 years ago

Could you please post your solution to my stackoverflow post?

Will do.

One question, I understand that rendering these environments in distill::distill_article is mainly an issue with mathjax. I dug into the bookdown implementation of these environments. I found it is done here (there may be other files as well). Is it possible to load this lua file into the distill mathjax environment to make this easier to customize for distill purposes? Just a thought.

Rendering LaTeX Math in HTML document is a matter of Mathjax. (i.e \begin{equation}). This is different and this is a JS library.

For theorems and proofs environments, they are only available in LaTeX originally. However, in bookdown there is a special process to handle those environments to mimic them in a HTML output. But as you see, you don't write LaTeX, you write a special markdown syntax (using fenced div with class) that allow us to handle multi format by writing the expected output (either LaTeX or HTML). Recently, we've put the logic into the lua filter so technically you could indeed use only this but it was not designed as portable so I am not sure everything is working 100% (the referencing is not done in Lua for example I believe). This would be done like this

output:
  distill::distill_article:
    self_contained: false
    pandoc_args: !expr rmarkdown::pandoc_lua_filter_args(rmarkdown::pkg_file_lua("custom-environment.lua", "bookdown"))

It seems it works but I am unsure why. However, you're right that this would be the way to go when we tackle the idea of making this a more generic feature: use a lua filter that we can use for different formats.

You could be interested in a new project currently in development that aim to take the experience of R Markdown and other publishing tool to create an improved version, still based on Pandoc, for scientific publishing and content creation which is language agnostic: https://quarto.org. It already have feature like Theorems (here) and other feature found in distill (like layout) but it does not have a distill format per-se. Anyway, you may be interested to follow the work there too.

shamindras commented 2 years ago

Could you please post your solution to my stackoverflow post?

Will do.

Thanks! I just accepted this answer 👍🏾 .

One question, I understand that rendering these environments in distill::distill_article is mainly an issue with mathjax. I dug into the bookdown implementation of these environments. I found it is done here (there may be other files as well). Is it possible to load this lua file into the distill mathjax environment to make this easier to customize for distill purposes? Just a thought.

Rendering LaTeX Math in HTML document is a matter of Mathjax. (i.e \begin{equation}). This is different and this is a JS library.

For theorems and proofs environments, they are only available in LaTeX originally. However, in bookdown there is a special process to handle those environments to mimic them in a HTML output. But as you see, you don't write LaTeX, you write a special markdown syntax (using fenced div with class) that allow us to handle multi format by writing the expected output (either LaTeX or HTML). Recently, we've put the logic into the lua filter so technically you could indeed use only this but it was not designed as portable so I am not sure everything is working 100% (the referencing is not done in Lua for example I believe). This would be done like this

output:
  distill::distill_article:
    self_contained: false
    pandoc_args: !expr rmarkdown::pandoc_lua_filter_args(rmarkdown::pkg_file_lua("custom-environment.lua", "bookdown"))

It seems it works but I am unsure why. However, you're right that this would be the way to go when we tackle the idea of making this a more generic feature: use a lua filter that we can use for different formats.

This seems quite interesting and promising. The lua-filter does seem like a more flexible way to customize LaTeX for such rmarkdown related purposes. Could be cool to see more of the bookdown features implemented in distill.

You could be interested in a new project currently in development that aim to take the experience of R Markdown and other publishing tool to create an improved version, still based on Pandoc, for scientific publishing and content creation which is language agnostic: quarto.org. It already have feature like Theorems (here) and other feature found in distill (like layout) but it does not have a distill format per-se. Anyway, you may be interested to follow the work there too.

This looks very cool indeed! Thanks for flagging it. I'm currently tied to distill and seeing how it works for my site and blogging, but this looks like a really promising toolkit to consider if I move to a more language agnostic blog and website. Appreciate you flagging it.

cderv commented 2 years ago

Could be cool to see more of the bookdown features implemented in distill.

Do not hesitate to open more feature request for what you found missing, or add a 👍 if there is already one open !

acarzfr commented 2 years ago

Hi. If we are using a language other than English, for example, we may want to write "Teorem" instead of "Theorem". We can do this with language in the _bookdown.yml file in bookdown. Is there a way in Distill? I tried the _site.yml file and it didn't work.

cderv commented 2 years ago

@acarzfr There is currently no localization / internationalization feature in distill. See old https://github.com/rstudio/distill/issues/50 about this.

Regarding bookdown feature, the internationalization as described in the doc for bookdown works but distill and bookdown does not play well together (HTML5 vs HTML4). So not 100% sure it works. From bookdown documentation, the file that the bookdown feature will use is _bookdown.yml.

acarzfr commented 2 years ago

@cderv Thanks for the answer.