Подтвердить что ты не робот

Сложение кода в книжном шкафу

Опция складывания кода в RMarkdown для html-документов является удивительной. Этот вариант делает программную методологию прозрачной для тех, кто заинтересован, не заставляя аудиторию прокручивать мили кода. Тесное размещение кода с прозой и интерактивным графическим выходом делает весь проект более доступным для более широкой аудитории, а также уменьшает необходимость в дополнительной документации.

Для более крупного проекта я использую bookdown, и он отлично работает. Единственная проблема заключается в том, что не существует опции сложения кода. Сгибание кода в настоящий момент не включено. (см. Включить сгибание кода в книжной книге)

Я знаю, что мне не нужен вариант, чтобы это произошло. Мне просто нужно вставить правильный код в нужное место или в нужное место. Но какой код и где?

Жизнеспособной альтернативой было бы поставить блок кода ниже выходов блока на странице. Или, наконец, поставить их в качестве приложения. Я мог бы сделать это с помощью html, но не воспроизводимым, как rbookdown.

4b9b3361

Ответ 1

Кнопка Global Hide/Show для всей страницы

Чтобы использовать подсказку @Yihui для кнопки, которая складывает весь код в выход html, вам нужно вставить следующий код во внешний файл (я назвал его header.html здесь):

Изменить: я изменил функцию toggle_R, чтобы кнопка отображала Hide Global или Show Global при нажатии на нее.

<script type="text/javascript">

// toggle visibility of R source blocks in R Markdown output
function toggle_R() {
  var x = document.getElementsByClassName('r');
  if (x.length == 0) return;
  function toggle_vis(o) {
    var d = o.style.display;
    o.style.display = (d == 'block' || d == '') ? 'none':'block';
  }

  for (i = 0; i < x.length; i++) {
    var y = x[i];
    if (y.tagName.toLowerCase() === 'pre') toggle_vis(y);
  }

    var elem = document.getElementById("myButton1");
    if (elem.value === "Hide Global") elem.value = "Show Global";
    else elem.value = "Hide Global";
}

document.write('<input onclick="toggle_R();" type="button" value="Hide Global" id="myButton1" style="position: absolute; top: 10%; right: 2%; z-index: 200"></input>')

</script>

В этом script вы можете изменить положение и код css, связанный с кнопкой, напрямую с параметрами style или добавить его в свой файл css. Я должен был установить z-index в высоком значении, чтобы убедиться, что он появляется над другими разделами.
Обратите внимание, что этот код javascript только сбрасывает R-код с echo=TRUE, который присваивается class="r" в html. Это определяется командой var x = document.getElementsByClassName('r');

Затем вы вызываете этот файл в заголовок YAML вашего rmarkdown script, как в примере ниже:

---
title: "Toggle R code"
author: "StatnMap"
date: '`r format(Sys.time(), "%d %B, %Y")`'
output:
  bookdown::html_document2:
    includes:
      in_header: header.html
  bookdown::gitbook:
    includes:
      in_header: header.html
---

Stackoverflow question
<https://stackoverflow.com/info/45360998/code-folding-in-bookdown>

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

## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

Новое редактирование: локальное скрыть/показать кнопку для каждого фрагмента

Наконец-то я нашел решение!
Рассматривая поведение сворачивания кода для обычного вывода html (без bookdown), я смог добавить его в bookdown. Основная функция javascript должна найти .sourceCode деления классов для работы с bookdown. Однако для этого также требуются дополнительные функции javascript bootstrap, но не все. Это работает с gitbook и html_document2.
Вот шаги:

  • Создайте папку js в том же каталоге, что и ваш файл Rmd
  • Загрузите функции javascript transition.js и collapse.js здесь, например: https://github.com/twbs/bootstrap/tree/v3.3.7/js и сохраните их в папке js
  • Создайте новый файл в папке js с именем codefolding.js со следующим кодом. Это то же самое, что и для параметра rmarkdown code_folding, но с добавлением pre.sourceCode для поиска фрагментов кода R:

codefolding.js код:

window.initializeCodeFolding = 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 = 1;

  // select all R code blocks
  var rCodeBlocks = $('pre.sourceCode, pre.r, pre.python, pre.bash, pre.sql, pre.cpp, pre.stan');
  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');
    });
  });

}
  1. В следующем rmarkdown script все три функции считываются и включаются как есть в заголовке, поэтому папка js не используется для самого финального документа. При чтении js-функций я также добавил параметр в show кодовые блоки по умолчанию, но вы можете скрыть их с помощью hide.

Код rmarkdown:

---
title: "Toggle R code"
author: "StatnMap"
date: '`r format(Sys.time(), "%d %B, %Y")`'
output:
  bookdown::html_document2:
    includes:
      in_header: header.html
  bookdown::gitbook:
    includes:
      in_header: header.html
---

Stackoverflow question
<https://stackoverflow.com/info/45360998/code-folding-in-bookdown>


```{r setup, include=FALSE}
# Add a common class name for every chunks
knitr::opts_chunk$set(
  echo = TRUE)
```
```{r htmlTemp3, echo=FALSE, eval=TRUE}
codejs <- readr::read_lines("js/codefolding.js")
collapsejs <- readr::read_lines("js/collapse.js")
transitionjs <- readr::read_lines("js/transition.js")

htmlhead <- 
  paste('
<script>',
paste(transitionjs, collapse = "\n"),
'</script>
<script>',
paste(collapsejs, collapse = "\n"),
'</script>
<script>',
paste(codejs, collapse = "\n"),
'</script>
<style type="text/css">
.code-folding-btn { margin-bottom: 4px; }
.row { display: flex; }
.collapse { display: none; }
.in { display:block }
</style>
<script>
$(document).ready(function () {
  window.initializeCodeFolding("show" === "show");
});
</script>
', sep = "\n")

readr::write_lines(htmlhead, path = "header.html")
```

## R Markdown

This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see <http://rmarkdown.rstudio.com>.

When you click the **Knit** button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:

```{r cars}
summary(cars)
```

```{r plot}
plot(cars)
```

Этот script показывает кнопки в браузере Rstudio, но не работает. Однако, это нормально с firefox.
Вы увидите, что в этом коде немного css, но, конечно, вы можете изменить положение и цвет и все, что хотите на этих кнопках, с помощью еще нескольких css.

Изменить: объединить глобальные и локальные кнопки

Редактировать 2017-11-13: Глобальная кнопка сложения кода хорошо интегрирована с отдельными кнопками блока. Функция toggle_R, наконец, не нужна, но вам нужно получить функцию dropdown.js в бутстрапе.

Глобальная кнопка вызывается непосредственно в блоке кода при вызове js файлов:

```{r htmlTemp3, echo=FALSE, eval=TRUE}
codejs <- readr::read_lines("/mnt/Data/autoentrepreneur/js/codefolding.js")
collapsejs <- readr::read_lines("/mnt/Data/autoentrepreneur/js/collapse.js")
transitionjs <- readr::read_lines("/mnt/Data/autoentrepreneur/js/transition.js")
dropdownjs <- readr::read_lines("/mnt/Data/autoentrepreneur/js/dropdown.js")

htmlhead <- c(
  paste('
<script>',
paste(transitionjs, collapse = "\n"),
'</script>
<script>',
paste(collapsejs, collapse = "\n"),
'</script>
<script>',
paste(codejs, collapse = "\n"),
'</script>
<script>',
paste(dropdownjs, collapse = "\n"),
'</script>
<style type="text/css">
.code-folding-btn { margin-bottom: 4px; }
.row { display: flex; }
.collapse { display: none; }
.in { display:block }
.pull-right > .dropdown-menu {
    right: 0;
    left: auto;
}
.open > .dropdown-menu {
    display: block;
}
.dropdown-menu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 1000;
    display: none;
    float: left;
    min-width: 160px;
    padding: 5px 0;
    margin: 2px 0 0;
    font-size: 14px;
    text-align: left;
    list-style: none;
    background-color: #fff;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
    border: 1px solid #ccc;
    border: 1px solid rgba(0,0,0,.15);
    border-radius: 4px;
    -webkit-box-shadow: 0 6px 12px rgba(0,0,0,.175);
    box-shadow: 0 6px 12px rgba(0,0,0,.175);
}
</style>
<script>
$(document).ready(function () {
  window.initializeCodeFolding("show" === "show");
});
</script>
', sep = "\n"),
  paste0('
<script>
document.write(\'<div class="btn-group pull-right" style="position: absolute; top: 20%; right: 2%; z-index: 200"><button type="button" class="btn btn-default btn-xs dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" data-_extension-text-contrast=""><span>Code</span> <span class="caret"></span></button><ul class="dropdown-menu" style="min-width: 50px;"><li><a id="rmd-show-all-code" href="#">Show All Code</a></li><li><a id="rmd-hide-all-code" href="#">Hide All Code</a></li></ul></div>\')
</script>
')
)

readr::write_lines(htmlhead, path = "/mnt/Data/autoentrepreneur/header.html")
```

Новая глобальная кнопка показывает выпадающее меню, чтобы выбрать между "показать весь код" или "скрыть весь код". Используя window.initializeCodeFolding("show" === "show"), все коды отображаются по умолчанию, а при использовании window.initializeCodeFolding("show" === "hide") все коды скрыты по умолчанию.