How to use knitr hooks in xaringan?

I'd like to have a chunk option that wraps code and output in a html class.

This works for most Rmd documents but it doesn't with Xaringan:

knitr::knit_hooks$set(
  wrap = function(before, options, envir){
    if (before) {
      paste0('<div class="className">')
    } else paste0('</div>')
  }
)

I know about .className[] but that's not what I need.
Has anyone got any ideas?

The hook is working - you can open the HTML file produce in a text editor to see that you content has been added before and after.

However, xaringan is an R package to use remark.js. You can know more here

remark.js has its own Markdown interpreter so what happens with xaringan is that the content of the input markdown file, it put as-is in the produce HTML file for remark.js to process.
It seems by adding this div, it prevent remark to parse correctly the markdown code inside it. It is not yet supported

Moreover, the not-parsed markdown still present in the resulting HTML is processed by Mathjax which gives you the result you are seeing.

What does not work you in using the remark syntax .className[ ] ?

1 Like

Thanks a lot for a thorough reply. I should hav been more specific about what I meant by "not working". Yes you are absolutely correct, the class got added but the code chunk got parsed as Mathjax.

The reason why I'd like to avoid .className[] is that I am extending xaringan using, among other things some xaringanExtra features, and I want the "framwork" to be as easy to use as possible. I would like it to be used by teachers at my uni so ease of use is highly desirable.

What I need is for all code in a div of that class to be processed with echo=TRUE despite echo= being globally set to FALSE. Also, less typing is better...

So the idea was to have a chunk opt, e.g. panel=TRUE that would take care both of echo= and the wrapper <div>class. I then have some JS that uses xaringanExtra-style tabs and displays the plot in the chunk and the corresponding code in two tabs (see https://and.netlify.app/lectures/01/slides/#5)

And sure, it can be done with .class[] and echo=TRUE but that's not elegant :slight_smile:

Nice idea!

The div is required to apply the JS on ? is that right ?

Among the feature that can be useful to you :

xaringan is not the easiest package to extend as it is specific compare to other tool as it will not use Pandoc to process the markdown content bu only remark.js, you must take that into account for you extension. .class[] may not be elegant, but that is what Remark use for its syntax (and I find it quite elegant). Know that you can use it in the hook too, and this would be better as this is what remark expect if you want a div + markdown to be processed

knitr::knit_hooks$set(
  wrap = function(before, options, envir){
    if (before) {
      '.className['
    } else ']'
  }
)

Did you try that already ?

1 Like

I've tried it now, combining your idea with a opts hook that sets echo= and eval= to TRUE and it works beautifully!
Thanks a lot for your help.

Btw, I like the .class[] markdown and also find it elegant in general but, in this particular case, I need to do several things - set div class and chunk options - at once and I really wanted to do that with a custom chunk option. You made me happy :slight_smile:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.