web-dev-qa-db-fra.com

Pliage de code dans la comptabilité

L'option de pliage de 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 à parcourir des kilomètres de code. Le placement serré du code avec de la prose et une sortie graphique interactive rend l'ensemble du projet plus accessible à un public plus large, et en outre, il réduit le besoin de documentation supplémentaire.

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

Je sais que je n'ai pas besoin d'une option pour y arriver. J'ai juste besoin de coller le bon code au bon endroit ou aux bons endroits. Mais quel code et où?

Une alternative viable serait de mettre le morceau de code sous les sorties du morceau dans la page. Ou, enfin, de les mettre en annexe. Je pourrais le faire avec du HTML mais pas reproductible comme rbookdown.

44
Alex P

Bouton Masquer/Afficher global pour la page entière

Pour utiliser le conseil de @ Yihui pour un bouton qui plie tout le code dans la sortie html, vous devez coller le code suivant dans un fichier externe (je l'ai nommé header.html Ici):

Edit: J'ai modifié la fonction toggle_R Pour que le bouton affiche 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 pouvez modifier la position et le code css associés au bouton directement avec les options style ou les ajouter dans votre fichier css. J'ai dû définir le z-index À une valeur élevée pour être sûr qu'il apparaît sur les autres divisions.
Notez que ce code javascript ne plie que le code R appelé avec echo=TRUE, Auquel est attribué un class="r" En html. Ceci est défini par la commande var x = document.getElementsByClassName('r');

Ensuite, vous appelez ce fichier dans l'en-tête YAML de votre script rmarkdown, 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 édition: bouton Masquer/afficher local pour chaque bloc

J'ai enfin trouvé la solution!
En regardant le comportement de repliement du code pour une sortie html normale (pas de bookdown), j'ai pu l'ajouter à bookdown. La fonction javascript principale doit trouver les divisions de classe .sourceCode Pour travailler avec bookdown. Cependant, cela nécessite également des fonctions javascript complémentaires de bootstrap , mais pas toutes. Cela fonctionne avec gitbook et html_document2.
Voici les étapes:

  1. Créez un dossier js dans le même répertoire que votre fichier Rmd
  2. Téléchargez les fonctions javascript transition.js Et collapse.js Ici par exemple: https://github.com/twbs/bootstrap/tree/v3.3.7/js et stockez-les dans votre dossier js
  3. Créez un nouveau fichier dans le dossier js appelé codefolding.js Avec le code suivant. C'est la même chose que pour l'option rmarkdown code_folding mais avec pre.sourceCode Ajouté pour trouver des morceaux de code R:

Code 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. Dans le script rmarkdown suivant, les trois fonctions sont lues et incluses telles quelles dans l'en-tête, de sorte que le dossier js n'est pas utile pour le document final lui-même. Lors de la lecture des fonctions js, j'ai également ajouté l'option aux blocs de code show par défaut, mais vous pouvez choisir de les masquer avec hide.

code 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/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 du navigateur Rstudio mais ne fonctionne pas bien. Cependant, c'est correct avec Firefox.
Vous verrez qu'il y a un peu css dans ce code, mais bien sûr vous pouvez modifier la position et la couleur et ce que vous voulez sur ces boutons avec un peu plus de css.

Modifier: combiner les boutons globaux et locaux

Edit 2017-11-13: Bouton de pliage de code global bien intégré avec les boutons de bloc individuels. La fonction toggle_R N'est finalement pas nécessaire, mais vous devez obtenir la fonction dropdown.js dans le bootstrap.

Le bouton global est appelé directement dans le bloc de code lors de l'appel de fichiers 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")
```

Le nouveau bouton global affiche un menu déroulant pour choisir entre "afficher tout le code" ou "masquer tout le code". En utilisant window.initializeCodeFolding("show" === "show") tous les codes sont affichés par défaut, tandis qu'en utilisant window.initializeCodeFolding("show" === "hide"), tous les codes sont masqués par défaut.

25

J'ai écrit un filtre pour pandoc qui:

  • encapsule tous les blocs de code en HTML5 <details> Mots clés
  • 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 à le personnaliser) via onclick événement javascript

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

Ajouter à la réservation via pandoc_args: ["-F", "path/to/collapse_code.py"]

2
BenPortner

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

0
John