Как добавить сворачивание кода в выходные fragmentы в rmarkdown html-документах
Я очень ценю функцию «code_folding» в RMarkdown. Тем не менее, мне действительно нужно, чтобы код отображался все время и переключал отображение на выходе.
--- title: "test file" author: "dayne" date: "June 10, 2016" output: html_document: code_folding: hide --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE) ``` Here is a basic example. ```{r} 3 + 4 ```
Есть ли способ переключить вывод, а не код? Лучшее (но не идеальное) решение, о котором я думал, состоит в том, чтобы добавить collapse=TRUE
к кускам, но тогда код и вывод все равно отображаются одновременно.
Ссылка на скомпилированный документ: http://rpubs.com/daynefiler/188408
- Как связать две координаты с линией, используя Листовку в R
- Эффективный способ rbind data.frames с разными столбцами
- Непосредственное создание фиктивной переменной, заданной в разреженной матрице в R
- Как просмотреть данные из файла .RData?
- Участок с условными цветами на основе значений в R
- Получение пути к сценарию R
- Переопределить функцию, импортированную в пространстве имен
- R-Project не применимый метод для «мета», применяемый к объекту classа «характер»,
- R: как суммировать столбцы, сгруппированные по фактору?
- Извлечение уникальных чисел из строки в R
- Многострочные методы обхода комментариев?
- Создайте порядковый номер (счетчик) для строк внутри каждой группы данных (дубликат)
- Как вы нарисуете линию в многозначной среде в R?
TOC:
-
Полный контроль над тем, какие куски должны быть свернуты
-
Сложите все куски, содержащие более одной строки кода / вывода
1. Полный контроль над тем, какие куски должны быть свернуты
Я хотел иметь такую же функциональность, как и сделать следующее:
Я создал JavaScript, который выглядит следующим образом:
$(document).ready(function() { $chunks = $('.fold'); $chunks.each(function () { // add button to source code chunks if ( $(this).hasClass('s') ) { $('pre.r', this).prepend("
Show Source
"); $('pre.r', this).children('code').attr('class', 'folded'); } // add button to output chunks if ( $(this).hasClass('o') ) { $('pre:not(.r)', this).has('code').prepend("Show Output
"); $('pre:not(.r)', this).children('code:not(r)').addClass('folded'); // add button to plots $(this).find('img').wrap(''); $('pre.plot', this).prepend("
Show Plot
"); $('pre.plot', this).children('img').addClass('folded'); } }); // hide all chunks when document is loaded $('.folded').css('display', 'none') // function to toggle the visibility $('.showopt').click(function() { var label = $(this).html(); if (label.indexOf("Show") >= 0) { $(this).html(label.replace("Show", "Hide")); } else { $(this).html(label.replace("Hide", "Show")); } $(this).siblings('code, img').slideToggle('fast', 'swing'); }); });Поскольку я не являюсь JS-трещиной, он может быть не идеальным, но он делает то, что он должен. Включите его в свой файл Rmd:
Я также написал некоторые определения CSS для стилизации кнопки:
.showopt { background-color: #004c93; color: #FFFFFF; width: 100px; height: 20px; text-align: center; vertical-align: middle !important; float: right; font-family: sans-serif; border-radius: 8px; } .showopt:hover { background-color: #dfe4f2; color: #004c93; } pre.plot { background-color: white !important; }
После включения обоих файлов JS и таблицы стилей вы можете скрыть куски, обернув вокруг них контейнер div одним из следующих classов:
Скрыть только вывод
```{r} ... ```Скрыть исходный код
```{r} ... ```Скрыть оба
```{r} ... ```Сценарий обнаруживает тип каждого fragmentа (например, исходный код, текстовый вывод или вывод графика) и соответствующим образом намечает кнопки.
Результат выглядит следующим образом:
![]()
![]()
2. Сложите все куски, содержащие более одной строки кода / вывода
Вот версия скрипта, которая добавляет функцию сгибания ко всем fragmentам длиной более одной строки:
$(document).ready(function() { $plots = $('img.plot'); $chunks = $('pre').has('code'); $chunks = $chunks.filter(function(idx) { return $(this).children('code').outerHeight(false) > parseInt($(this).css('line-height')); }); $chunks.each(function () { if($(this).hasClass('r')) { $(this).append("
Show Source
"); } else { $(this).append("Show Output
"); } }); $plots.each(function () { $(this).wrap(''); $(this).parent('pre.plot').prepend("
Show Plot
"); }); // hide all chunks when document is loaded $chunks.children('code').toggle(); $('pre.plot').children('img').toggle(); // function to toggle the visibility $('.showopt').click(function() { var label = $(this).html(); if (label.indexOf("Show") >= 0) { $(this).html(label.replace("Show", "Hide")); } else { $(this).html(label.replace("Hide", "Show")); } $(this).siblings('code, img').slideToggle('fast', 'swing'); }); });Просто
его с помощью
и вам не нужно обертывать контейнеры div вокруг ваших fragmentов кода. Одна вещь, которую вы должны добавить в свой документ Rmd, является следующей глобальной опцией:
```{r, echo = F} knitr::opts_chunk$set(out.extra = 'class="plot"') ```
Это необходимо для определения графического вывода.
Быстрый хакерский способ переключения раздела (необязательно кода):
Включите разделы для переключения с
и <\div>
в ваш .Rmd-файл
1. How many users are in the second, but not the first, user table? ```{r} setdiff(user2, user) %>% nrow() ```
Поместите это внизу файла .Rmd (или в идеале в файл .js, связанный со всеми вашими страницами).
Поместите это в свой .css-файл (вам нужно будет играть с высотой для вашей кнопки).
.toggle { height: 1.55em; overflow-y: hidden; } .toggle.open { height: auto; }
Я прямо скопировал javascript из источника другого документа Rmarkdown, где я установил code_folding: show
. Я сохранил javascript как py_code_folding.js
и добавил в начало моего документа Rmarkdown. Единственным ограничением является то, что мне пришлось жестко кодировать в своем javascript, хочу ли я, чтобы блоки первоначально отображались или скрывались.
window.initializePythonCodeFolding = 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 = 10000; // select all R code blocks var rCodeBlocks = $('pre.python'); rCodeBlocks.each(function() { // create a collapsable div to wrap the code in var 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 = $('' + (show ? 'Hide' : 'Code') + ''); var showCodeButton = $(''); showCodeButton.append(showCodeText); showCodeButton .attr('data-toggle', 'collapse') .attr('data-target', '#' + id) .attr('aria-expanded', show) .attr('aria-controls', id); var buttonRow = $(''); var buttonCol = $(''); 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'); }); }); } $(document).ready(function () { window.initializePythonCodeFolding("show" === "show"); });