How to extend Pandoc - r-markdown

I am using bookdown for a documentation which is outputted with bookdown::gitbook and bookdown::pdf_book.
In my Rmd files, I am using a div to wrap around notes and warnings styled with a css file. For example:
<div class="note">
This is a note.
</div>
Obviously, HTML and CSS is ignored when generating the PDF file. I was wondering if there is a way to "inject" a small script that would replace the div with, for example, a simple prefix text.
Or, is there another way to have it formatted in HTML and in the PDF without littering my file by adding something lengthy every time like:
if (knitr::is_html_output(excludes='epub')) {
cat('
<div class="note">
This is a note.
</div>
')
} else {
cat('Note: This is a note.')
}
I could also style blockquotes as described here but it is not an option as I still need blockquotes.

The appropriate way to do this is to use a fenced div rather than inserting HTML directly into your markdown and trying to parse it later with LUA. Pandoc already allows you to insert custom styles and process them to both file types. In other words, it will take care of creating the appropriate HTML and LaTeX for you, and then you just need to style each of them. The Bookdown documentation references this here, but it simply points to further documentation here, and here.
This method will create both your custom classed div in html and apply the same style name in the LaTeX code.
So, for your example, it would look like this:
::: {.note data-latex=""}
This is a note.
:::
The output in HTML will be identical to yours:
<div class="note">
<p>This is a note.</p>
</div>
And you've already got the CSS you want to style that.
The LaTeX code will be as follows:
\begin{note}
This is a note.
\end{note}
To style that you'll need to add some code to your preamble.tex file, which you've already figured out as well. Here's a very simple example of some LaTeX that would simply indent the text from both the left and right sides:
\newenvironment{note}[0]{\par\leftskip=2em\rightskip=2em}{\par\medskip}

I found this answer on tex.stackexchange.com which brought me on the right track to solve my problem.
Here is what I am doing.
Create boxes.lua with following function:
function Div(element)
-- function based on https://tex.stackexchange.com/a/526036
if
element.classes[1] == "note"
or element.classes[1] == "side-note"
or element.classes[1] == "warning"
or element.classes[1] == "info"
or element.classes[1] == "reading"
or element.classes[1] == "exercise"
then
-- get latex environment name from class name
div = element.classes[1]:gsub("-", " ")
div = div:gsub("(%l)(%w*)", function(a, b) return string.upper(a)..b end)
div = "Div"..div:gsub(" ", "")
-- insert element in front
table.insert(
element.content, 1,
pandoc.RawBlock("latex", "\\begin{"..div.."}"))
-- insert element at the back
table.insert(
element.content,
pandoc.RawBlock("latex", "\\end{"..div.."}"))
end
return element
end
Add pandoc_args to _output.yml:
bookdown::pdf_book:
includes:
in_header: latex/preamble.tex
pandoc_args:
- --lua-filter=latex/boxes.lua
extra_dependencies: ["float"]
Create environments in preamble.tex (which is also configured in _output.yml):
I am using tcolorbox instead of mdframed
\usepackage{xcolor}
\usepackage{tcolorbox}
\definecolor{notecolor}{RGB}{253, 196, 0}
\definecolor{warncolor}{RGB}{253, 70, 0}
\definecolor{infocolor}{RGB}{0, 183, 253}
\definecolor{readcolor}{RGB}{106, 50, 253}
\definecolor{taskcolor}{RGB}{128, 252, 219}
\newtcolorbox{DivNote}{colback=notecolor!5!white,colframe=notecolor!75!black}
\newtcolorbox{DivSideNote}{colback=notecolor!5!white,colframe=notecolor!75!black}
\newtcolorbox{DivWarning}{colback=warncolor!5!white,colframe=warncolor!75!black}
\newtcolorbox{DivInfo}{colback=infocolor!5!white,colframe=infocolor!75!black}
\newtcolorbox{DivReading}{colback=readcolor!5!white,colframe=readcolor!75!black}
\newtcolorbox{DivExercise}{colback=taskcolor!5!white,colframe=taskcolor!75!black}
Because I have also images and tables within the boxes, I run into LaTeX Error: Not in outer par mode.. I was able to solve this issue by adding following command to my Rmd file:
```{r, echo = F}
knitr::opts_chunk$set(fig.pos = "H", out.extra = "")
```

Related

RMarkdown References section -name change

I'm currently writing in R Studio an R Markdown document. Since I am not using English, I want to change the name of the # References header to "Referencias". My output is HTML.
I went thru the pandoc documentation and tried reference-section-title: Referencias in my YALM header, with no luck.
The easiest way is to set the metadata field reference-section-title in the YAML header:
---
reference-section-title: Referencias
---
Alternatively, you could write the section title directly into the document, then use a special fenced div with id #refs to place the bibliography anywhere you need it:
# Referencias
::: #refs
:::

Use the title= HTML attribute with RMarkdown

I am trying to understand if it is possible to insert the HTML title= attribute (not necessarily inside an <abbr> tag) within an RMarkdown document (e.g. a blog post written through blogdown)
From W3C: the title attribute specifies extra information about an element. The information is most often shown as a tooltip text when the mouse moves over the element.
The <abbr title="World Health Organization">WHO</abbr> was founded in 1948.
Couldn't find anything regarding using in in RMarkdown tho
You can write raw HTML in Markdown. However, if you are using Hugo >= v0.60.0, raw HTML will be ignored by default. You need to set an option in your config file to enable it:
[markup.goldmark.renderer]
unsafe= true

How can I specify HTML5 output from RMarkdown to get semantic elements like <section>?

I noticed that in HTML produced by knitr from my RMarkdown document, sections are marked up thus:
<div id="chunk_id" class="section level2">
<h2>...</h2>
<p>...</p>
</div>
and so on. I think it's best practice to use a <section> element rather than a <div> here (reference 1, reference 2), so I forked the RMarkdown code to see if I could make a change and a PR. In the code I found the following:
#'#param section_divs Wrap sections in <div> tags (or <section> tags in HTML5),
#' and attach identifiers to the enclosing <div> (or <section>) rather than the
#' header itself. ```
so it seems like there is no need for a change to RMarkdown - it will already use <section> in the way I want, if it is told to output HTML5.
My question is: how do you tell knitr to output HTML5? I have
output:
html_document:
section_divs = TRUE
but no idea how to "switch on" HTML5.

PhpStorm: get correct indentation for YAML code in a .html file

I'm using Zurb Foundation's templating system Panini. It has the option to define data, which can then be inserted into parts of the template, in a block of YAML at the beginning of a .html file, delineated by three dashes.
I'm wondering if I can get PhpStorm/WebStorm to properly indent my YAML (or leave it alone). As it stands, every time I reindent a file, it removes all indentation from my YAML. YAML uses indentation to define it's structure, so changing my indentation breaks my code.
Here's an example of what a file might look like:
---
title: 'Awesome Example'
menu:
-
text: 'The best example'
link: 'http://example.com'
-
text: 'Wikipedia'
link: 'http://en.wikipedia.org'
---
<div>
<p>Lorem ipsum, etc.</p>
</div>
As a workaround, I can make my YAML valid JSON (using braces and brackets to delineate structure), so this isn't an earth-shatering disaster, but using indentation would be easier, if possible.

Django 1.8: How can I make special code blocks for syntax highlighting in django templates?

I want to make a django custom template filter to make special code blocks that look like the following...
Python code
{% highlight python %}
import random
# Generate a random integer in the range 10 to 49.
i = random.randrange(10,50)
print 'Your number is', i
{% endhighlight %}
Ruby code
{% highlight ruby %}
for i in (1..4)
print i," "
end
{% endhighlight %}
R code
{% highlight r %}
require(rpart)
load("C:/Users/Jaysp_000/Downloads/credit.rdata")
# Classification Tree
summary(ct <- rpart(Credit ~ CreditAmount + Age + CreditHistory + Employment, data=credit))
{% endhighlight %}
Does anyone know how I can do create one like this? I wanted to make code blocks that are highlighted according to the right programming language. Like, Ruby code is highlighted accordingly, which is different from R and Python, which are different from one another. Has anyone here created something similar?
Python-Markdown ships with the CodeHilite Extension for highlighting code blocks. No need to use "templates" (in fact Markdown files would not generally be passed through templates, although it is possible if you wanted to write the custom code for it -- see an explanation here).
Simply enable the extension and define the language of the code block on the first line (as explained in the documentation):
:::python
import random
# Generate a random integer in the range 10 to 49.
i = random.randrange(10,50)
print 'Your number is', i
If you also enable Fenced Code Blocks, you can also define the language on them (which eliminates the need to indent the code blocks):
```ruby
for i in (1..4)
print i," "
end
```
Under the hood, CodeHilite uses Pygments to highlight the code, so any language supported by Pygments is automatically supported.
Of course, for this to work you need to enable the extensions. Without any information about how you are using Markdown from Django, I can only provide a few pointers.
If you are calling the Markdown library directly from Python code, then simply include the extensions in the call to markdown.markdown:
body = markdown.markdown(source, extensions=['markdown.extensions.codehilite', 'markdown.extensions.fenced_code'])
Otherwise, you may find the django_markdown library to be helpful. It has a setting for MARKDOWN_EXTENSIONS which you would need to set in your Django settings file:
MARKDOWN_EXTENSIONS = ['markdown.extensions.codehilite', 'markdown.extensions.fenced_code']
Finally, you will need the CSS to tell the browser how to style the highlighted code. The Pygments project provides some default CSS styles which you may find to be a useful starting point (those CSS styles have been neatly packaged up by richeland). You will need to add that CSS to the CSS used by your site (the specifics of which depend on how your Django site is configured and therefore is excluded from this answer).
You can write a custom template tag that parses until an end tag and does something with the contents.