Переключение вывода чанка с использованием HTML-тега «details» - PullRequest
0 голосов
/ 14 сентября 2018

Я пишу некоторые уроки, используя blogdown. По педагогической причине я хочу, чтобы мои ученики подумали, прежде чем увидели решение. Вот мой текущий код.

Оригинал

---
title: "Toggle Chuck Output Using details Tag"
output: html_document
---

```{r calc, prompt=TRUE, eval=FALSE}
90 + 30
```

<details>
  <summary>Toggle output</summary>
```{r, ref.label='calc', echo=FALSE, prompt=TRUE}
```
</details>

Вот моя попытка:

Чтобы избежать повторной записи тегов HTML, я думаю, что мне нужно определить функцию, похожую на ...

togglable <- function(label, summary = "Toggle output"){
  cat('<details>')
  cat(' <summary>', summary, '</summary>', sep = '')

  # Code to print output using 'ref.label' should go here.
  # The following doesn't work. 
  knitr::knit_print(knitr:::knit_code$get(label))

  cat('</details>')
}

.... затем замените блок <detals>...</details> фрагментом кода R, подобным следующему:

Вариант использования 1 (лучше)

```{r usecase1, echo=FALSE, results='asis'}
togglable(label = "calc")
```

Я пытался заставить его работать, но тщетно.

Еще одна вещь. Если возможно, я бы хотел, чтобы эта функция togglable() переопределяла параметры чанка, чтобы мне даже не нужно было писать echo=FALSE, results='asis', потому что следующий чанк будет выглядеть лучше.

Вариант использования 2 (лучший)

```{r usecase2}
togglable(label = "calc")
```

В заключение я хотел бы задать следующие вопросы.

  1. Как я могу определить эту функцию togglable(), чтобы она работала так же, как оригинальный блок <detals>...</details>?
  2. Возможно ли, что эта функция переопределяет параметры (в частности, echo и results) для фрагмента, где эта функция вызывается? Если да, то как?
  3. В качестве альтернативы, есть ли другая идея, как получить результат исходного кода без повторной записи тегов HTML?

Большое спасибо!

1 Ответ

0 голосов
/ 14 сентября 2018

Это можно сделать с помощью комбинации chunk ref.label (для повторного использования кусков), chunk hook (для печати тега <details>) и option hook (для изменения параметров чанка при отображении результатов.

---
title: "Toggle Chuck Output Using details Tag"
output: html_document
---

```{r setup, include=FALSE}
library(knitr)

knit_hooks$set(showDetails = function(before, options, envir) {
  if (before) {
    return("<details>\n")
  } else {
    return("\n</details>")
  }
})

opts_hooks$set(showDetails = function(options) {
  if(options$showDetails) {
    options$echo = FALSE
    options$results = "asis"
  }
  return(options)
})
```

```{r calc, prompt=TRUE, eval=FALSE}
90 + 30
```


```{r, ref.label="calc", showDetails = TRUE}
```

Как это работает:

  • Хук чанка выполняется до и после каждого чанка, где параметр showDetails не равен NULL. Он печатает (возвращает) соответствующий HTML.
  • Хук опций регулирует другие опции (echo и results) для каждого чанка там showDetails равен TRUE.

Код можно еще улучшить, глобально установив параметры блока calc, чтобы вам не приходилось повторять их для всех остальных блоков «show code only»: добавьте opts_chunk$set(prompt = TRUE, eval = FALSE) к блоку настройки и options$eval = TRUE для опции крючком.

Кроме того, если вы хотите использовать теги <detail> по умолчанию при использовании ref.label, вы можете использовать ref.label в качестве опции hook:

```{r setup, include=FALSE}
library(knitr)

opts_chunk$set(prompt = TRUE, eval = FALSE)

knit_hooks$set(showDetails = function(before, options, envir) {
  if (before) {
    return("<details>\n")
  } else {
    return("\n</details>")
  }
})

opts_hooks$set(ref.label = function(options) {
  options$echo = FALSE
  options$results = "asis"
  options$eval = TRUE
  options$showDetails = TRUE

  return(options)
})
```

```{r calc}
90 + 30
```


```{r, ref.label="calc"}
```
...