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.
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)
```
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:
js
dans le même répertoire que votre fichier Rmdtransition.js
Et collapse.js
Ici par exemple: https://github.com/twbs/bootstrap/tree/v3.3.7/js et stockez-les dans votre dossier js
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');
});
});
}
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.
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.
J'ai écrit un filtre pour pandoc qui:
<details>
Mots clésonclick
événement javascriptLe 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"]
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 !