How to add code folding to output chunks in rmarkdown html documents

dayne :

I really appreciate the "code_folding" feature in RMarkdown. However, what I really need is to have the code show all the time and toggle the display on the output.

---
title: "test file"
author: "dayne"
date: "June 10, 2016"
output: 
  html_document:
    code_folding: hide
---

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

Here is a basic example.

```{r}
3 + 4
```

Is there a way to toggle the output rather than the code? The best (but not ideal) solution I have thought of is to add collapse=TRUE to the chunks, but then the code and the output still display at the same time.

Link to the compiled document: http://rpubs.com/daynefiler/188408

Martin Schmelzer :

TOC:

  1. Full control over which chunks should be folded

  2. Fold all chunks that contain more than one line of code/output


1. Full control over which chunks should be folded

I wanted to have the same functionality as well and did the following:

I created a JavaScript that looks as follows:

$(document).ready(function() {

  $chunks = $('.fold');

  $chunks.each(function () {

    // add button to source code chunks
    if ( $(this).hasClass('s') ) {
      $('pre.r', this).prepend("<div class=\"showopt\">Show Source</div><br style=\"line-height:22px;\"/>");
      $('pre.r', this).children('code').attr('class', 'folded');
    }

    // add button to output chunks
    if ( $(this).hasClass('o') ) {
      $('pre:not(.r)', this).has('code').prepend("<div class=\"showopt\">Show Output</div><br style=\"line-height:22px;\"/>");
      $('pre:not(.r)', this).children('code:not(r)').addClass('folded');

      // add button to plots
      $(this).find('img').wrap('<pre class=\"plot\"></pre>');
      $('pre.plot', this).prepend("<div class=\"showopt\">Show Plot</div><br style=\"line-height:22px;\"/>");
      $('pre.plot', this).children('img').addClass('folded');

    }
  });

  // hide all chunks when document is loaded
  $('.folded').css('display', 'none')

  // function to toggle the visibility
  $('.showopt').click(function() {
    var label = $(this).html();
    if (label.indexOf("Show") >= 0) {
      $(this).html(label.replace("Show", "Hide"));
    } else {
      $(this).html(label.replace("Hide", "Show"));
    }
    $(this).siblings('code, img').slideToggle('fast', 'swing');
  });
});

Since I am no JS crack it might not be perfect, but it does what it is supposed to. Include it in your Rmd file:

<script src="js/hideOutput.js"></script>

I also wrote some CSS definitions to style the button:

.showopt {
  background-color: #004c93;
  color: #FFFFFF; 
  width: 100px;
  height: 20px;
  text-align: center;
  vertical-align: middle !important;
  float: right;
  font-family: sans-serif;
  border-radius: 8px;
}

.showopt:hover {
    background-color: #dfe4f2;
    color: #004c93;
}

pre.plot {
  background-color: white !important;
}

After including both, the JS file and the stylesheet, you can hide chunks by wrapping a div container around them with one of the following classes:

Hide output only

<div class="fold o">
```{r}
  ...
```
</div>

Hide source code

<div class="fold s">
```{r}
  ...
```
</div>

Hide both

<div class="fold s o">
```{r}
  ...
```
</div>

The script detects the type of each chunk (e.g. source code, text output or plot output) and labels the buttons accordingly.

The result looks like this:

enter image description here

enter image description here


2. Fold all chunks that contain more than one line of code/output

Here is a version of the script that adds the folding feature to all chunks that are longer than one line:

$(document).ready(function() {
  $plots = $('img.plot');
  $chunks = $('pre').has('code');
  $chunks = $chunks.filter(function(idx) {
    return $(this).children('code').outerHeight(false) > parseInt($(this).css('line-height'));
  });

  $chunks.each(function () {
    if($(this).hasClass('r')) {
      $(this).append("<div class=\"showopt\">Show Source</div><br style=\"line-height:22px;\"/>");
    } else {
      $(this).append("<div class=\"showopt\">Show Output</div><br style=\"line-height:22px;\"/>");
    }
  });

  $plots.each(function () {
    $(this).wrap('<pre class=\"plot\"></pre>');
    $(this).parent('pre.plot').prepend("<div class=\"showopt\">Show Plot</div><br style=\"line-height:22px;\"/>");
  });

  // hide all chunks when document is loaded
  $chunks.children('code').toggle();
  $('pre.plot').children('img').toggle();
  // function to toggle the visibility
  $('.showopt').click(function() {
    var label = $(this).html();
    if (label.indexOf("Show") >= 0) {
      $(this).html(label.replace("Show", "Hide"));
    } else {
      $(this).html(label.replace("Hide", "Show"));
    }
    $(this).siblings('code, img').slideToggle('fast', 'swing');
  });
});

Just include it with <script src="js/hideAll.js"></script> and you don't need to wrap div containers around your code chunks. One thing you have to add in your Rmd document though is the following global chunk option:

```{r, echo = F}
knitr::opts_chunk$set(out.extra = 'class="plot"')
```

It is needed to identify graphical output.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How to show code but hide output in RMarkdown?

How to make code chunks depend on all previous chunks in knitr/rmarkdown?

using webpack code splitting, how to load chunks and HTML layout?

How to evaluate all chunks in Rmarkdown

Reduce space between code chunks and code output in rmarkdown beamer presentation

Missing horizontal scroll bar in R Markdown HTML code chunks and output

Change color of error messages in RMarkdown code output (HTML, PDF)

RMarkdown document - How to delay knitr evaluation of an inline code piece until later chunks have processed?

Numbered Code Chunks in RMarkdown

Does rmarkdown allow captions and references for code chunks?

`bookdown`/`rmarkdown`/`knitr`: Line wrapping in code chunks

RMarkdown reveal.js presentation code folding

How to merge and print multiple code chunks in RMarkdown?

How do I get a number (or text) from a data frame in a code chunk in to text in RMarkdown html output?

How to not execute certain Rmarkdown chunks based on a parameter?

How can I add line numbers that go across chunks in Rmarkdown?

How to parse a text table in rmarkdown code chunks

Add toc entries for html generated in r chunks in rmarkdown

Code folding in rmarkdown: can't get div wrapper to work

How to display line numbers for code chunks in rmarkdown HTML and PDF

Add a CSS class to single code chunks in RMarkdown

Avoid text-wrapping of code in Rmarkdown html output

Verbatim code chunks with double quotation marks in RMarkdown

How to add a line break in Rmarkdown code?

Knitting/Rendering R Markdown Output: Can I prevent code from showing in PDF output but allow code folding in HTML output?

How to print RMarkdown chunk code output in Console?

How to get the HTML code of a RMarkdown Document?

Remove italics (# comments) in Rmarkdown code chunks in pdf

Can I merge the code of successive code chunks with no output echoed in a rmarkdown html_document