代码折叠在书中 [英] Code folding in bookdown

查看:168
本文介绍了代码折叠在书中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

RMarkdown中的HTML代码折叠选项非常棒。该选项使程序化方法对感兴趣的人透明,而不会迫使观众翻阅数英里的代码。通过散文和交互式图形输出,代码的紧密放置使整个项目更容易被更广泛的受众使用,并且减少了对额外文档的需求。

对于一个更大的项目,我使用了bookdown,它效果很好。唯一的问题是没有代码折叠选项。
代码折叠当前未在bookdown中启用。 (请参阅在代码中启用代码折叠功能



我知道我不需要一个选项来实现它。我只需要将正确的代码粘贴到正确的地方。但是什么代码和哪里?

一种可行的替代方法是将代码块放置在页面中块的输出之下。或者,最后,把它们作为附录。我可以用html做到这一点,但不能像rbookdown那样重现。



要使用@ Yihui的提示来折叠html输出中的所有代码,您需要将以下代码粘贴到外部文件中(我将它命名为 header .html here):

编辑:我修改了函数 toggle_R 在点击时显示隐藏全球显示全球

 < script type =text / javascript> 

//在R中切换R源代码块的可见性Markdown输出
函数toggle_R(){
var x = document.getElementsByClassName('r');
if(x.length == 0)return;
函数toggle_vis(o){
var d = o.style.display;
o.style.display =(d =='block'|| d =='')? 无:块;
}

(i = 0; 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 =隐藏全球;


document.write('< input onclick =toggle_R();type =buttonvalue =隐藏全局id =myButton1style =position:绝对;顶部:10%;右侧:2%; z-index:200>< /输入>')

< / script>

在这个脚本中,您可以直接修改与按钮关联的位置和CSS代码 style 选项或将其添加到您的css文件中。我必须将 z-index 设置为较高的值以确保它显示在其他部门之上。

请注意,此JavaScript代码仅折叠R代码在中使用 echo = TRUE ,这被称为 class =r。这是通过命令 var x = document.getElementsByClassName('r');



来定义的文件放在你的rmarkdown脚本的YAML头文件中,如下例所示:

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

Stackoverflow问题
< https://stackoverflow.com/questions/45360998/code-folding-in-bookdown>
$ b```{r setup,include = FALSE}
knitr :: opts_chunk $ set(echo = TRUE)
```

# #R降价

这是一个R Markdown文档。 Markdown是用于创作HTML,PDF和MS Word文档的简单格式化语法。有关使用R Markdown的更多详细信息,请参阅< http://rmarkdown.rstudio.com> ;.

当您单击** Knit **按钮时,将生成一个文档,其中包含文档中的任何嵌入式R代码块的内容以及输出。您可以像这样嵌入一个R代码块:

```{r cars}
汇总(汽车)
```



新编辑:每个区块的本地隐藏/显示按钮



我终于找到了解决方案!

在查看普通html输出的代码折叠行为(没有任何书名)时,我可以将它添加到bookdown中。主要的JavaScript函数需要找到 .sourceCode class divisions来处理bookdown。但是,这也需要 bootstrap 的补充JavaScript函数,但不是全部。这适用于 gitbook html_document2

下面是步骤:


  1. 在与您的Rmd文件相同的目录中创建 js 文件夹

  2. 下载JavaScript函数 transition.js collapse.js 例如: https://github.com/twbs/bootstrap/tree/v3.3.7/js 和store他们在 js 文件夹中

  3. js 文件夹中创建一个新文件使用以下代码调用 codefolding.js 。这与rmarkdown code_folding选项相同,但添加了 pre.sourceCode 来查找R代码块:

codefolding.js 代码:

 窗口.initializeCodeFolding = function(show){

//处理程序显示全部并隐藏全部
$(#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');
});
});

//唯一代码元素ID索引
var currentIndex = 1;

//选择所有R代码块
var rCodeBlocks = $('pre.sourceCode,pre.r,pre.python,pre.bash,pre.sql,pre.cpp,pre .stan');
rCodeBlocks.each(function(){

//创建一个collapsable div来包装代码
var div = $('< div class =collapse r-代码崩溃>< / div>);
if(show)
div.addClass('in');
var id ='rcode-643E0F36'+ currentIndex ++;
div.attr('id',id);
$(this).before(div);
$(this).detach()。appendTo(div);

//在
上方添加一个显示代码按钮var showCodeText = $('< span>'+(show?'隐藏':'代码')+'< / span>') ;
var showCodeButton = $('< button type =buttonclass =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);
$ b $ //更新显示/隐藏按钮的状态
div.on('hidden.bs.collapse',function(){
showCodeText.text('Code') ;
});
div.on('show.bs.collapse',function(){
showCodeText.text('Hide');
});
});




$ b $ ol $ start $ $
  • 在下面的rmarkdown脚本中,所有三个函数都被读取并包含在标题中,这样 js 文件夹对最终文档本身无用。阅读js函数时,默认情况下,我还添加了 show 代码块的选项,但您可以选择使用 hide

    rmarkdown code:

      title:Toggle R code
    author:StatnMap
    date:'`r format(Sys.time(),%d%B, %y)`'
    输出:
    bookdown :: html_document2:
    包括:
    in_header:header.html
    bookdown :: gitbook:
    包含:
    in_header:header.html
    ---

    Stackoverflow问题
    < https://stackoverflow.com/questions/45360998/code-folding-in -bookdown>

    $ b```{r setup,include = FALSE}
    #为每个块添加一个公共类名
    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 =\\\
    ),
    '< / script>
    < script>',
    paste(collapsejs,collapse =\\\
    ),
    '< / script>
    < script>',
    粘贴(codejs,collapse =\\\
    ),
    '< / script>
    < style type =text / css>
    .code-folding-btn {margin-bottom:4px;}
    .row {display:flex;}
    .collapse {display:none;}
    .in {display:block}
    < script>
    $(document).ready(function(){
    window.initializeCodeFolding(show===show);
    });
    < / script>
    ',sep =\\\


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

    ## R降价

    这是一个R Markdown文档。 Markdown是用于创作HTML,PDF和MS Word文档的简单格式化语法。有关使用R Markdown的更多详细信息,请参阅< http://rmarkdown.rstudio.com> ;.

    当您单击** Knit **按钮时,将生成一个文档,其中包含文档中的任何嵌入式R代码块的内容以及输出。你可以像这样嵌入一个R代码块:

    ```{r cars}
    汇总(汽车)
    ```
    $ b $``` `{r plot}
    plot(cars)
    ```

    脚本显示Rstudio浏览器中的按钮,但效果不佳。然而,这与firefox是可以接受的。

    你会发现在这段代码中有一点 css ,但是你当然可以修改这个位置颜色和任何你想要在这些按钮与一些更多的CSS。



    编辑:合并全局和本地按钮



    编辑2017-11-13:全局代码折叠按钮与单个集合按钮完美集成。功能 toggle_R 最终不是必需的,但您需要在引导程序中获取函数 dropdown.js



    调用<$时,全局按钮直接在代码块中调用c $ c> js files:

     ```{htmlTemp3,echo = FALSE,eval = true} 
    codejs< - readr :: read_lines(/ mnt / Data / autoentrepreneur / js / codefolding.js)
    collapsejs< - readr :: read_lines(/ mnt / autoentrepreneur / js / collapse.js)
    transitionjs< - readr :: read_lines(/ mnt / Data / autoentrepreneur / js / transition.js)
    dropdownjs< - readr :: read_lines( ($ /
    < script>',
    粘贴(transitionjs,collapse =\\\
    ),
    '< / script>
    < script>',
    paste(collapsejs,collapse =\\\
    ),
    '< / script>
    < script>',
    paste(codejs,collapse =\\\
    ),
    '< / script>
    < script>',
    paste(dropdownjs,collapse =\\\
    ),
    '< / 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%;
    剩下: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 =\\\
    ),
    paste0('
    < script>
    document.write(\'< div class =btn-group拉右style =position:absolute; top:20%; right:2%; z-index:200>< button type =buttonclass =btn btn-default btn-xs dropdown-toggle data-toggle =dropdownaria-haspopup =truearia-expanded =truedata-_extension-text-contrast =>< span>代码< / span>< span class =caret >< / span>< / button>< ul class =dropdown-menustyle =min-width:50px;>< li>< a id =rmd-show-all -codehref =#>显示所有代码< / a>< / li>< li>< a id =rmd-hide-all-codehref =#>隐藏所有代码< ; / a>< / li>< / ul>< / div> \')
    < / script>
    ')


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

    新的全局按钮显示下拉菜单,可在显示所有代码或隐藏所有代码之间进行选择。使用 window.initializeCodeFolding(show===show)默认显示所有代码,而使用 window.initializeCodeFolding(show ===hide),所有代码默认都是隐藏的。


    The Code folding option in RMarkdown for html documents is awesome. That option makes the programmatic methodology transparent for those who are interested, without forcing the audience to scroll through miles of code. The tight placement of code with prose and interactive graphical output makes the whole project more accessible to a wider audience, and furthermore it reduces the need for additional documentation.

    For a larger project, I'm using bookdown, and it works great. The only problem is that there is no code-folding option. Code folding is not currently enabled in bookdown. (see Enable code folding in bookdown )

    I know I don't need an option to make it happen. I just need to paste the right code in the right place or places. But what code and where?

    A viable alternative would be to put the code chunk below the chunk's outputs in the page. Or, finally, to put them as an appendix. I could do that with html but not reproducible like rbookdown.

    解决方案

    Global Hide/Show button for the entire page

    To use @Yihui's hint for a button that fold all code in the html output, you need to paste the following code in an external file (I named it header.html here):

    Edit: I modified function toggle_R so that the button shows Hide Global or Show Global when clicking on it.

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

    In this script, you are able to modify the position and css code associated to the button directly with the style options or add it in your css file. I had to set the z-index at a high value to be sure it appears over other divisions.
    Note that this javascript code only fold R code called with echo=TRUE, which is attributed a class="r" in the html. This is defined by command var x = document.getElementsByClassName('r');

    Then, you call this file in the YAML header of your rmarkdown script, as in the example below:

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

    New Edit: Local Hide/show button for each chunk

    I finally found the solution !
    While looking at the code folding behavior for normal html output (no bookdown), I was able to add it to bookdown. The main javascript function needs to find .sourceCode class divisions to work with bookdown. However, this also requires complementary javascript functions of bootstrap, but not all. This works with gitbook and html_document2.
    Here are the steps:

    1. Create a js folder in the same directory than your Rmd file
    2. Download javascript functions transition.js and collapse.js here for instance: https://github.com/twbs/bootstrap/tree/v3.3.7/js and store them in your js folder
    3. Create a new file in the js folder called codefolding.js with the following code. This is the same as for rmarkdown code_folding option but with pre.sourceCode added to find R code chunks:

    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. In the following rmarkdown script, all three functions are read and included as is in the header, so that the js folder in not useful for the final document itself. When reading the js functions, I also added the option to show code blocks by default, but you can choose to hide them with 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)
    ```
    

    This script shows the buttons in the Rstudio browser but does not work well. However, this is ok with firefox.
    You'll see that there is a little css in this code, but of course you can modify the position and color and whatever you want on these buttons with some more css.

    Edit: Combine Global and local buttons

    Edit 2017-11-13: Global code-folding button well integrated with individual bloc buttons. Function toggle_R is finally not necessary, but you need to get function dropdown.js in bootstrap.

    Global button is called directly in the code chunk when calling js files:

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

    The new global button shows a dropdown menu to choose between "show all code" or "hide all code". Using window.initializeCodeFolding("show" === "show") all codes are shown by default, whereas using window.initializeCodeFolding("show" === "hide"), all codes are hidden by default.

    这篇关于代码折叠在书中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆