quarto-dev / quarto-dev/quarto-cli

Native support for R `cli` package ANSI-styled output in knitr engine

Open
#13,815 5 comments 3 reactions 1 assignee View on GitHub

@cderv is already working on this.

Since Dec 22, 2025.

engines-knitr enhancement
Dominant language
JavaScript
Stars
6k
Forks
458
Avg merge
1d 9h
Merged PRs (30d)
41

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)
Terminal Output with R's `cli` package Image

Desired Output

Mirror RStudio with a light grey background for CLI output:

Print method created using the `cli` R package being displayed in Quarto with colors using a light grey shade to match RStudio's print background

Or, just the regular CLI output:

Print method created using the `cli` R package being displayed in Quarto with colors but no background grey shade

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:

  1. Add a chunk option like ansi: true to enable ANSI-to-HTML conversion
  2. Document-level YAML option such as execute: ansi-colors: true
  3. 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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.