49 votes

Repliage du code dans bookdown

L'option de repli du code dans RMarkdown pour les documents html est géniale. Cette option rend la méthodologie programmatique transparente pour ceux qui sont intéressés, sans forcer le public à faire défiler des kilomètres de code. La disposition serrée du code avec la prose et la sortie graphique interactive rend l'ensemble du projet plus accessible à un public plus large, et réduit en outre le besoin de documentation supplémentaire.

Pour un projet plus important, j'utilise bookdown, et ça fonctionne très bien. Le seul problème est qu'il n'y a pas d'option de repli du code. Le repli du code n'est pas actuellement activé dans bookdown. (voir Activer le repli du code dans bookdown)

Je sais que je n'ai pas besoin d'une option pour que cela se fasse. Je dois simplement coller le bon code au bon endroit ou aux bons endroits. Mais quel code et où ?

Une alternative viable serait de placer le bloc de code sous les sorties du bloc sur la page. Ou, enfin, de les placer en annexe. Je pourrais le faire avec du html mais ce ne serait pas reproductible comme avec rbookdown.

8 votes

Voici mon conseil : github.com/yihui/knitr/blob/master/inst/misc/toggleR.js Utilisez l'option includes pour l'inclure. Vous devez comprendre JavaScript et HTML.

0 votes

Merci pour l'indice!

37voto

Sébastien Rochette Points 3983

Mondial Afficher/Masquer le bouton pour l'ensemble de la page

Utiliser @Yihui du conseil pour un bouton qui se replient tout le code dans le code html de sortie, vous devez coller le code suivant dans un fichier externe (j'ai nommé il header.html ici):

Edit: j'ai modifié la fonction toggle_R , de sorte que le bouton de la montre Hide Global ou Show Global en cliquant dessus.

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

Dans ce script, vous êtes en mesure de modifier la position et le code css associé au bouton directement avec l' style des options ou de l'ajouter dans votre fichier css. J'ai dû mettre de l' z-index à une valeur élevée pour être sûr qu'il s'affiche sur les autres divisions.
Notez que ce code javascript ne plient R code appelé avec echo=TRUE, ce qui est attribuable à un class="r" dans le html. Cela est défini par la commande var x = document.getElementsByClassName('r');

Ensuite, vous appelez ce fichier dans le fichier YAML en-tête de votre rmarkdown script, comme dans l'exemple ci-dessous:

---
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/questions/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)
```

Nouvelle Edit: Local afficher/Masquer le bouton pour chaque morceau

J'ai enfin trouvé la solution !
En regardant le code de pliage comportement normal de la sortie html (pas de bookdown), j'ai été en mesure de l'ajouter à bookdown. La principale fonction javascript doit trouver .sourceCode classe divisions de travailler avec bookdown. Cependant, cela nécessite la complémentarité des fonctions javascript de bootstrap, mais pas tous. Cela fonctionne avec gitbook et html_document2.
Voici les étapes:

  1. Créer un js le dossier dans le même répertoire que votre fichier Mdm
  2. Télécharger des fonctions javascript transition.js et collapse.js ici par exemple: https://github.com/twbs/bootstrap/tree/v3.3.7/js et de les stocker dans votre js le dossier
  3. Créer un nouveau fichier dans l' js le dossier appelé codefolding.js avec le code suivant. C'est le même que pour rmarkdown code_folding option mais avec pre.sourceCode ajouté à trouver R code des morceaux:

codefolding.js code:

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. Dans la suite de rmarkdown script, tous les trois fonctions sont lus et inclus dans l'en-tête, de sorte que l' js le dossier dans pas utile pour la finale du document lui-même. Lors de la lecture de la js fonctions, j'ai aussi ajouté l'option d' show blocs de code par défaut, mais vous pouvez choisir de les masquer avec hide.

rmarkdown code:

---
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/questions/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)
```

Ce script affiche les boutons dans le Rstudio navigateur, mais ne fonctionne pas bien. Cependant, c'est ok avec firefox.
Vous verrez que il y a un peu d' css dans ce code, mais bien sûr, vous pouvez modifier la position et la couleur de ce que vous voulez sur ces boutons avec un peu plus de css.

Edit: Combiner le Global et le local et les boutons

Edit 2017-11-13: code Mondial-pliage bouton bien intégré avec chaque bloc de boutons. La fonction toggle_R n'est finalement pas nécessaire, mais vous avez besoin pour obtenir la fonction dropdown.js dans le bootstrap.

Mondial bouton est appelé directement dans le code chunk lors de l'appel d' js fichiers:

```{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")
```

Le nouveau global bouton affiche un menu déroulant pour choisir entre "montrer tout le code" ou "masquer tous les code". À l'aide de window.initializeCodeFolding("show" === "show") tous les codes sont affichés par défaut, tandis que l'utilisation de window.initializeCodeFolding("show" === "hide"), tous les codes sont cachés par défaut.

0 votes

Merci! Cela ajoute un bouton sur chaque page, comment pourrais-je ajouter un bouton pour chaque morceau, comme dans rmarkdown?

1 votes

Désolé, je suis actuellement en train d'essayer d'utiliser cette réponse mais sans succès pour le moment: stackoverflow.com/questions/37944197/…. Ceci peut être combiné avec celui-ci pour inclure une classe css dans les fragments: stackoverflow.com/questions/37944197/…. Si je réussis, je mettrai à jour ma réponse.

1 votes

J'ai ajouté le script à l'étape actuelle "ne fonctionne pas", peut-être que quelqu'un peut aider à voir quel est le problème.

5voto

John Zobolas Points 39

J'ai créé le R package rtemps qui inclut un modèle bookdown prêt à l'emploi avec des boutons de pliage de code entre autres (largement basé sur la réponse/post de Sébastien Rochette). Vérifiez-le ici !

2voto

BenPortner Points 21

J'ai écrit un filtre pour pandoc qui :

  • enveloppe tous les blocs de code dans des balises HTML5
  • ajoute un bouton local pour plier/déplier le code
  • le texte du bouton bascule entre "Afficher le code" et "Masquer le code" (n'hésitez pas à personnaliser) via l'événement javascript onclick

Le filtre peut être trouvé ici. Nécessite une distribution python avec panflute installée pour fonctionner.

Ajoutez à bookdown via pandoc_args: ["-F", "chemin/vers/collapse_code.py"]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X