ISSUE
The issue at hand is that you wish to escape part of your header (i.e., the break) and not escape another part (i.e., the math code).
Further Complications
This core issue is further complicated by a number of factors:
- when and how kableExtra is programmed to deal with escaping
- a desire to have a solution that works for both html and LaTeX output
- when and how R evaluates code
A SOLUTION
Here is a solution that will work for both html and LaTeX output, but it is not as clean and straight forward as your original code:
# a new version of `kableExtra::linebreak()` that takes into account what type
# of output is desired as well as how much escaping is necessary
linebreak2 <- function(x, double_escape = TRUE, ...) {
# if LaTeX insert text into a `\makecell[]{}` command and double escape
if(knitr::is_latex_output())
return(linebreak(x, double_escape = double_escape, ...))
# if html output just replace `\n`s with `<br/>`s
if(knitr::is_html_output())
return(gsub("\n", "<br/>", x))
# let x pass through for other types of output
return(x)
}
# build the index named vector outside the pipe flow
# in order to set the names using `linebreak2()`
index <- c(6, 3)
names(index) <- c(
'The droids: everybody\'s favourite',
linebreak2('The Gungans: only beloved of \nthose aged under $3^2$')
)
# proceed as before
starwars %>%
filter(species == 'Gungan' | species == 'Droid') %>%
arrange(species) %>%
select(name, eye_color) %>%
kbl(booktabs = TRUE) %>%
pack_rows(index = index, escape = FALSE)
PDF Output

HTML Output

to force the break) – user12728748 Jul 26 '22 at 15:29