-
Notifications
You must be signed in to change notification settings - Fork 394
Description
Summary
R code using the cli package produces unstyled, plain text output in Quarto HTML documents. The ANSI escape sequences are stripped, losing all formatting (colors, bold, emphasis). While Quarto 1.7+ added ANSI support for Jupyter/Julia, R/knitr documents still lack native handling.
Background
The cli package is widely used in the R ecosystem (tidyverse, devtools, usethis, etc.). Many custom print methods leverage cli for informative output. Without native support, Quarto users see degraded output quality compared to RStudio console or terminal rendering.
Minimal Reproducible Example
Save as cli-demo.qmd and render with quarto render cli-demo.qmd:
---
title: "CLI Output Demo"
format: html
---
```{r}
#| echo: false
library(cli)
demo_behavior <- function() {
cli_h1("Status Report")
cli_alert_success("All tests passed")
cli_alert_warning("Memory usage high")
cli_alert_danger("Connection failed")
}
demo_behavior()
```Output Comparison
| Console Output (Expected) | Quarto Rendered Output (Actual) |
|---|---|
![]() |
![]() |
Desired Output
Mirror RStudio with a light grey background for CLI output:
Or, just the regular CLI output:
Expected vs Actual Behavior
| Aspect | Expected | Actual |
|---|---|---|
| Colors | Styled with appropriate colors (green ✔, yellow ⚠, red ✖) | Plain monochrome text |
| Formatting | Bold headers, styled alerts | No text styling |
| Icons | Unicode symbols rendered with color context | Symbols appear but lack styling |
| Background | Terminal-style grey background | White/default background |
Current Workaround
Users must manually configure custom knitr hooks using fansi in every document:
```{r}
#| include: false
options(crayon.enabled = TRUE, cli.num_colors = 256)
ansi_aware_handler <- function(x, options) {
paste0(
'<pre class="r-output"><code>',
fansi::sgr_to_html(x = htmltools::htmlEscape(x), warn = FALSE, term.cap = "256"),
'</code></pre>'
)
}
knitr::knit_hooks$set(
output = ansi_aware_handler,
message = ansi_aware_handler,
warning = ansi_aware_handler,
error = ansi_aware_handler
)
```This is non-obvious, requires additional dependencies (fansi, htmltools), and must be repeated in every document.
Note
The workaround produces separate <pre> blocks for each cli statement, which may result in extra vertical spacing. This is normal knitr behavior (one output block per cat()/message() call). If desired, CSS can be used to collapse consecutive output blocks:
```{=html}
<style>
pre.r-output {
margin: 0;
padding: 0;
}
pre.r-output + pre.r-output {
border-top: none;
}
</style>
```Proposed Solution
Add native ANSI processing for R/knitr output, similar to the fix in PR #7813. Also consider adding a feature flag or three for the new behavior:
- Add a chunk option like
ansi: trueto enable ANSI-to-HTML conversion - Document-level YAML option such as
execute: ansi-colors: true - Terminal-style background for ANSI output blocks (grey background to visually distinguish from regular output)
Related Issues
| Issue | Title | Status |
|---|---|---|
| #5746 | knitr: process ANSI color codes | Open |
| #3730 | Support ANSI colour output with downlit |
Open |
| #4204 | ASCII escape codes should be stripped or processed to HTML | Closed (Jupyter only) |
| Discussion #3957 | {cli} output not captured by quarto slides | Active |
Environment
- Quarto version: 1.8.26
- R version: 4.5.2
- cli package version: 3.6.5
- OS: macOS 26.2

