【问题标题】:How to add code folding to output chunks in rmarkdown html documents如何将代码折叠添加到 rmarkdown html 文档中的输出块
【发布时间】:2016-10-11 19:44:57
【问题描述】:

我非常感谢 RMarkdown 中的“code_folding”功能。但是,我真正需要的是始终显示代码并在输出上切换显示。

---
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
```

有没有办法切换输出而不是代码?我想到的最好(但不理想)的解决方案是将collapse=TRUE 添加到块中,但是代码和输出仍然同时显示。

编译文档链接:http://rpubs.com/daynefiler/188408

【问题讨论】:

  • 通过了解 toggle the display on output 的含义,我才意识到我的英语太差了。
  • @Psidom 我添加了一个指向已编译文档的链接,演示了“代码折叠”。请注意如何单击“代码”按钮,代码会出现/消失。我想要与输出而不是代码相同的功能。

标签: r r-markdown


【解决方案1】:

这个低保真解决方案怎么样?

<details><summary>Click here</summary>
Some text

```{r code}
# even code
print("Hello world!")
```
</details>

不是我的,但我喜欢。

【讨论】:

  • 非常好——不需要 js 或 css
  • 酷。是否可以修改它,使箭头位于部分标题上以折叠部分?我试过这个:
    # section 2 这里是细节。
    但它会在节标题上方创建箭头。
【解决方案2】:

目录:

  1. 完全控制应该折叠哪些块

  2. 折叠包含多于一行代码/输出的所有块


1。完全控制应该折叠哪些块

我也想拥有相同的功能并做了以下事情:

我创建了一个如下所示的 JavaScript:

$(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');
  });
});

由于我不是 JS 破解者,它可能并不完美,但它做了它应该做的事情。 将其包含在您的 Rmd 文件中:

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

我还写了一些 CSS 定义来设置按钮的样式:

.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;
}

在同时包含 JS 文件和样式表之后,您可以通过使用以下类之一在它们周围包裹一个 div 容器来隐藏块:

仅隐藏输出

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

隐藏源代码

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

两者都隐藏

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

脚本检测每个块的类型(例如源代码、文本输出或绘图输出)并相应地标记按钮。

结果如下:


2。折叠包含多于一行代码/输出的所有块

这是一个脚本版本,它将折叠功能添加到所有超过一行的块中:

$(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');
  });
});

只需将它包含在&lt;script src="js/hideAll.js"&gt;&lt;/script&gt; 中,您就不需要将 div 容器包装在代码块周围。 您必须在 Rmd 文档中添加的一件事是以下全局块选项:

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

需要识别图形输出。

【讨论】:

  • 非常出色的答案。谢谢!
  • 附注:请参阅this page 以在您的 R Markdown 中嵌入自定义 CSS。
  • @MartinDabbelJuSmelter,关于如何在不丢失输出代码块中的默认语法突出显示的情况下使用此 CSS 的任何想法?我认为 R Markdown 在其系统文件夹中的某处有一个默认的 CSS 文件,也许可以将两者集成?
  • 不是像&lt;div class="fold o"&gt;那样指定div,而是像{r,fold_source=TRUE,fold_output=TRUE}这样的chunk选项可以包含吗?
  • 不使用上面的代码。这周我会检查我的代码,看看我写代码后knitr 发生了什么变化。
【解决方案3】:

切换部分的快速简便方法(不一定是代码):

在您的 .Rmd 文件中将要使用 &lt;div class="toggle"&gt;&lt;button&gt;TOGGLE_TEXT&lt;/button&gt; 和 &lt;\div&gt; 切换的部分括起来

1. How many users are in the second, but not the first, user table?

    <div class="toggle"><button>Solution</button>
    ```{r}
    setdiff(user2, user) %>% nrow()
    ```
    </div>

将其放在 .Rmd 文件的底部(或者最好放在链接到所有页面的 .js 文件中)。

<script>
  $(".toggle").click(function() {
    $(this).toggleClass("open");
  });
</script>

将其放入您的 .css 文件中(您必须调整按钮的高度)。

.toggle {
  height: 1.55em;
  overflow-y: hidden;
}
.toggle.open {
  height: auto;
}

【讨论】:

  • 由于已经加载了引导程序,因此使用 &lt;button type="button" class="btn btn-default"&gt;Show session info&lt;/button&gt; 对我有用。
【解决方案4】:

我直接从我设置code_folding: show 的另一个Rmarkdown 文档的源中复制了javascript。我将 javascript 保存为 py_code_folding.js 并将 &lt;script src="py_code_folding.js"&gt;&lt;/script&gt; 添加到我的 Rmarkdown 文档的顶部。唯一的限制是我必须在我的 javascript 中进行硬编码,无论我希望这些块最初是显示还是隐藏。

window.initializePythonCodeFolding = function(show) {

  // handlers for show-all and hide all
  $("#rmd-show-all-code").click(function() {
    $('div.r-code-collapse').each(function() {
      $(this).collapse('show');
    });
  });
  $("#rmd-hide-all-code").click(function() {
    $('div.r-code-collapse').each(function() {
      $(this).collapse('hide');
    });
  });

  // index for unique code element ids
  var currentIndex = 10000;

  // select all R code blocks
  var rCodeBlocks = $('pre.python');
  rCodeBlocks.each(function() {

    // create a collapsable div to wrap the code in
    var div = $('<div class="collapse r-code-collapse"></div>');
    if (show)
      div.addClass('in');
    var id = 'rcode-643E0F36' + currentIndex++;
    div.attr('id', id);
    $(this).before(div);
    $(this).detach().appendTo(div);

    // add a show code button right above
    var showCodeText = $('<span>' + (show ? 'Hide' : 'Code') + '</span>');
    var showCodeButton = $('<button type="button" class="btn btn-default btn-xs code-folding-btn pull-right"></button>');
    showCodeButton.append(showCodeText);
    showCodeButton
        .attr('data-toggle', 'collapse')
        .attr('data-target', '#' + id)
        .attr('aria-expanded', show)
        .attr('aria-controls', id);

    var buttonRow = $('<div class="row"></div>');
    var buttonCol = $('<div class="col-md-12"></div>');

    buttonCol.append(showCodeButton);
    buttonRow.append(buttonCol);

    div.before(buttonRow);

    // update state of button on show/hide
    div.on('hidden.bs.collapse', function () {
      showCodeText.text('Code');
    });
    div.on('show.bs.collapse', function () {
      showCodeText.text('Hide');
    });
  });

}

$(document).ready(function () {
  window.initializePythonCodeFolding("show" === "show");
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-16
    • 2012-07-07
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 2019-04-13
    相关资源
    最近更新 更多