Closed cpsievert closed 4 years ago
I used these environments in the bookdown book. The relevant LaTeX code is here: https://github.com/rstudio/bookdown/blob/7a0364b7ffd16b360b7abde36a29a8801675906c/inst/examples/latex/preamble.tex#L58-L88
The icons are here: https://github.com/rstudio/bookdown/tree/master/inst/examples/images
The HTML versions are defined here: https://github.com/rstudio/bookdown/blob/7a0364b7ffd16b360b7abde36a29a8801675906c/inst/examples/css/style.css#L1-L20
And of course, the documentation: https://bookdown.org/yihui/bookdown/custom-blocks.html
Personally I don't quite like the syntax I invented. I wish someone could figure out how to support fenced divs for LaTeX output: http://pandoc.org/MANUAL.html#divs-and-spans i.e. convert ::: foo
to \begin{foo}
. I'm sure @RLesur has the capability since he is familiar with Pandoc filters :)
It looks to be feasible. BTW, there is a Pandoc python filter that does a very similar job https://github.com/chdemko/pandoc-latex-environment I think that the most difficult part is to write the specs. I'm not sure to have fully understood what you need.
Do you want to have a syntax that would be compatible with html output format? I guess your answer is positive.
Do you want to create an environment for all divs? For instance:
::: {.foo}
:::
would give (for any div in the document, maybe risky?)
\begin{foo}
\end{foo}
Or do you prefer something like this:
::: {.block data-type="foo"}
:::
would give (only for divs of class block
)
\begin{foo}
\end{foo}
You also may prefer an API like the above mentioned python filter.
Would you need to pass options to the LaTeX environments?
Since fenced divs is a Pandoc 2 feature, the filter could be written in lua
(advantage: no system dependency).
Very good questions. I agree that the spec requires more thoughts than the actual implementation. I was thinking of something like
::: {.foo data-latex="latex,options,bar=zzz"}
:::
which is converted to
\begin[latex,options,bar=zzz]{foo}
\end{foo}
where the data-latex
attribute is optional.
OK. That's clear. Just another question: what would you want for multiple classes div?
::: {.foo .baz data-latex="latex,options,bar=zzz"}
:::
I guess you just want the first class (I ask to be sure).
Yes, that's exactly what I'd expect.
So, here is the Pandoc lua
filter.
--[[
A Pandoc 2 lua filter converting Pandoc native divs to LaTeX environments
Author: Romain Lesur
License: Public domain
--]]
local pandocList = require 'pandoc.List'
Div = function (div)
-- if the output format is not latex, the object is left unchanged
if FORMAT ~= 'latex' then return nil end
local env = div.classes[1]
-- if the div has no class, the object is left unchanged
if not env then return nil end
local options = div.attributes['data-latex']
local content = div.content
-- build the options character string
local optionsString
if options then
optionsString = '[' .. options .. ']'
else
optionsString = ''
end
-- build the returned list of blocks
local beginEnv = pandocList:new{pandoc.RawBlock('tex', '\\begin' .. optionsString .. '{' .. env .. '}')}
local endEnv = pandocList:new{pandoc.RawBlock('tex', '\\end{' .. env .. '}')}
local returnedList = beginEnv .. content .. endEnv
return returnedList
end
Be aware that this filter will transform fenced divs but also html raw divs (since the native_divs
extension is enabled by default):
<div class="foo baz" data-latex="latex,options,bar=zzz">
Here is a paragraph.
And another.
</div>
is converted to
\begin[latex,options,bar=zzz]{foo}
Here is a paragraph.
And another.
\end{foo}
This is convenient but could have some side effects.
Excellent!! I'll include this in a future version of bookdown (ideally after the stable release of RStudio 1.2, so most people have access to Pandoc 2). Many thanks!
I just incorporated it into the rmarkdown package. Note that originally I made a mistake in my example. The LaTeX environment syntax should be \begin{foo}[latex,options,bar=zzz]
instead of \begin[latex,options,bar=zzz]{foo}
, and sometimes it could also be \begin{foo}[latex,options,bar=zzz]{more options}
, so I decided not to add the square brackets automatically and let users provide the full argument string after the environment.
Another minor change I made was to drop the data-latex
attribute when the output format is not LaTeX: https://github.com/rstudio/rmarkdown/commit/cecd812743826989b539a7b0fcb1b8c08f09c05d#diff-2406dc32c250628c6ff0162c391a7a20R14 since this attribute is unlikely to be useful to other formats such as HTML (hence the HTML code will be a little cleaner).
Many thanks to @RLesur for the lua filter! Finally I can sleep well---I really disliked the block
and block2
hacks I invented originally: https://bookdown.org/yihui/bookdown/custom-blocks.html This new lua filter makes custom blocks much more powerful since you can include anything in the div (even R code blocks).
Hi folks - this is really awesome and works well, for html
and pdf
.
Thank you so much - Merci Romain, XieXie YiHui.
In bookdown
however, I am not getting the expected result, when I compile with YiHui's trick:
bookdown::pdf_book: base_format: "function(..., number_sections) rmarkdown::beamer_presentation(...)"
Therefore, I thought the issue was the code above and the line if FORMAT ~= 'latex' then return nil end
.
But looking at Release Notes for 1.16
clearly states:
Added a Pandoc lua filter to convert fenced Divs to LaTeX environments when the output format is latex or beamer
So clearly, beamer
has been accounted for and I can see that indeed, the above code has been adjusted, line 13!
But as I said, when I compile my book in beamer
the fenced block is ignored. However, if in a custom Lua
filter I copy the entire filtering code, then everything is as expected and works nicely.
Am I messing something up or is bookdown not picking up this filter properly? I am confused, I am sorry. Again - let me repeat - I run my code without the custom filter and the ::: fenced code
is ignored. I run the exact same code with simply your code pasted into a custom Lua
filter, and the ::: fenced code
is properly converted to latex
. Thought i'd bring this up to you, as you would obviously know best.
Again - thank you so much. thomas
hmmm, digging a bit further, i wonder if this could be the issue then... https://github.com/rstudio/rmarkdown/issues/1779
No - I copy this new code in a custom filter and it works just fine. So only conclusion is that in RStudio
, when I click build the book, it's missing this latex-div.lua
filter... or are we required to set it ourselves? I thought it'd be part of bookdown
, so to speak, no?
@tchevri Please try remotes::install_github('rstudio/rmarkdown')
(the relevant commit: https://github.com/rstudio/rmarkdown/commit/fe610c079aad7a6520af634b1012f416f91203b0).
Thank you so much @yihui ! Such fast response - of course, this solved it, sorry i missed it,
RStudio
was telling me i was up to date...
Can I please, please, abuse your kindness before you eat your mooncakes again, please? :-)
It seems an easy solution to my SO question 63116467 is to use ::: {.theorem}
instead of ```{theorem}
.
It works just perfect for non html
output, but for html
, i obviously lose the numbering and the labeling.
Indeed, by just looking at the html
file, I can see that the chunk will automatically add the html
elements <span><strong>Theorem x.x etc </strong></span>
.
Is this something that could be achieved with the ::: {.xxx}
approach as well, getting numbering and labeling?
That would solve so many problems at once and make the book's markdown so easy to read, if you do not mind my thinking so.
I could be wrong, but from my extensive internet search, I feel like a lot of other people would very much benefit from this.
FeiChang GanXie Nin.
thomas
Is this something that could be achieved with the
::: {.xxx}
approach as well, getting numbering and labeling?
That's exactly the tricky part, but I definitely see the usefulness, which is why I just said I'd prioritize it https://github.com/rstudio/bookdown/issues/924#issuecomment-675123262.
Such fast response - of course, this solved it, sorry i missed it,
RStudio
was telling me i was up to date...
Not your fault, since it was only in the development version of rmarkdown.
BTW, I baked some mooncakes a week ago and tasted one yesterday (making mooncakes is very time-consuming so I do it at most twice a year). I feel like you were watching me from somewhere... :)
First off, thanks so much for this template! It's going to save me so much time and agony 🍻.
Have you given any thought to supporting custom blocks in the pdf version? Currently if I try to add something like this to an Rmd:
I get