Improve formatting for help pages?
Is it possible to improve how the content of help pages is formatted when a student uses an exercise to open a help page? Students will open help pages often, since these are learning documents.
The current formatting is odd, but legible (so feel free to close the issue immediately). Two adjustments would make a big difference:
- Disable text wrap
- Display titles in header case (vs _t_h_i_s _c_a_s_e)
To quickly see how the help pages display, just add a ?plot chunk to a tutorial:
---
title: "Help pages display awkwardly"
output: tutor::tutorial
runtime: shiny_prerendered
---
```{r setup, include=FALSE}
library(tutor)
```
```{r help, exercise = TRUE}
?plot
```
I think this would be great. I think I spoke to both @hadley and @jjallaire at rstudio::conf about my wish to have help in RStudio generally be more user-friendly for novices. For example, if you have dplyr loaded, ?filter brings you to two topics, but that could be changed to a wikipedia-style interface where the first one in the search path displays by default and there is a "disambiguation" link at the top to access other functions with the same name.
Yes, help rendering is currently pretty terrible. I think we need to either transform the text-based help as you suggest or try to get HTML help working (that I'd much prefer).
Some of the suggested improvements are easy to achieve by calling tools::Rd2txt_options() in a setup chunk:
tools::Rd2txt_options(underline_titles = FALSE, width = 75)
75 seems to be the default width in an exercise chunk.
Calling ?filter shows the disambiguation and the help for stats::filter on my system.
Wrapping can be turned off for all output chunks by adding the following CSS:
.tutorial-exercise-output pre code { white-space: pre; }
I achieved it by using the following YAML header
output:
learnr::tutorial:
css: css/nowrap.css
and adding a file nowrap.css with the above contents in the css directory below the .Rmd document.
(Turning off the wrapping has no effect in the RStudio viewer, but works in Firefox.)
Ideally, the font size in the input and output elements would adapt to fit approximately 75 characters (or slightly more). This can be achieved by using vw units for the font size.
Demo: https://krlmlr.shinyapps.io/adaptive/.
Implementation: I removed the min-width for the list of topics (because it messes up the calculations) but increased its width to 30 %. I ended up with the following CSS, though I don't fully understand it:
.tutorial-exercise-output pre code {
white-space: pre;
font-size: 1.25vw;
}
.tutorial-exercise-code-editor {
font-size: 1.4vw;
}
.topics {
width: 68%;
}
.topicsContainer {
min-width: 1px;
width: 30%;
}
.topicsList {
min-width: 1px;
width: 30%;
}
@media screen and (max-width: 767px) {
.tutorial-exercise-output pre code {
font-size: 1.85vw;
}
.tutorial-exercise-code-editor {
font-size: 1.9vw;
}
.topics {
width: 99%;
}
.topicsContainer {
width: 1%;
}
}
I had the same issue and currently have this quick hack which monkey patches the ? operator
#help_format = 'iframe' # for modern browsers (need srcdoc attribute on iframe)
help_format = 'div' # also works for internet explorer and rstudio browser
`?` = function(e1, ...)
{
# quote, in case somebody types ?sum(1,2,3) for example
dc = as.character(eval(substitute(quote(e1))))
if(dc[1] == "?")
stop('?? is not available') # have not thought about this yet
if(dc[1] == '::')
{
file = help(dc[3], dc[2])
} else
{
file = help(dc[1])
}
rd = utils:::.getHelpFile(file)
tf = tempfile(fileext = ".html")
tools:::Rd2HTML(rd, tf)
if(help_format == 'iframe')
{
out = tags$iframe(srcdoc = readChar(tf, file.info(tf)$size), sandbox="allow-same-origin",
style="width:100%; min-height:26em; height:100%;")
} else if(help_format == 'div')
{
htm = readChar(tf, file.info(tf)$size) %>%
gsub('^.+<body[^>]*>','',.) %>%
gsub('</body.+$','',.)
out = tags$div(HTML(trimws(htm)),
style="width:100%; height:26em; overflow:auto; border:1px solid #e0e0e0; padding:1em;")
}
unlink(tf)
out
}
A downside is that it uses two internal functions. If need be, utils:::.getHelpFile has minimal dependencies and can be copied from the utils library and slighly rewritten. I have not checked if the same goes for tools:::Rd2HTML. There might also be a better way to retrieve html help.
This breaks the normal behavior of ? of course, but inside a learnr-markdown document it has no side effects.
I had the same issue and currently have this quick hack which monkey patches the ? operator
#help_format = 'iframe' # for modern browsers (need srcdoc attribute on iframe) help_format = 'div' # also works for internet explorer and rstudio browser `?` = function(e1, ...) { # quote, in case somebody types ?sum(1,2,3) for example dc = as.character(eval(substitute(quote(e1)))) if(dc[1] == "?") stop('?? is not available') # have not thought about this yet if(dc[1] == '::') { file = help(dc[3], dc[2]) } else { file = help(dc[1]) } rd = utils:::.getHelpFile(file) tf = tempfile(fileext = ".html") tools:::Rd2HTML(rd, tf) if(help_format == 'iframe') { out = tags$iframe(srcdoc = readChar(tf, file.info(tf)$size), sandbox="allow-same-origin", style="width:100%; min-height:26em; height:100%;") } else if(help_format == 'div') { htm = readChar(tf, file.info(tf)$size) %>% gsub('^.+<body[^>]*>','',.) %>% gsub('</body.+$','',.) out = tags$div(HTML(trimws(htm)), style="width:100%; height:26em; overflow:auto; border:1px solid #e0e0e0; padding:1em;") } unlink(tf) out }A downside is that it uses two internal functions. If need be,
utils:::.getHelpFilehas minimal dependencies and can be copied from the utils library and slighly rewritten. I have not checked if the same goes fortools:::Rd2HTML. There might also be a better way to retrieve html help.This breaks the normal behavior of ? of course, but inside a learnr-markdown document it has no side effects.
This works nicely! However, it fails to load the image(s) in the help page if any. For example ? points:
