Frequently Asked Questions

Published

October 31, 2025

Modified

November 23, 2025

General Information

What is the {ripper} extension for Quarto?

The {ripper} extension for Quarto is a Lua filter that automatically extracts code blocks from your document and splits them by programming language into separate, executable script files. It helps you maintain both literate programming documents and standalone scripts from a single source, improving code reusability. The extension also adds a section to your rendered document with links to the generated script files.

What types of code blocks does {ripper} extract?

The {ripper} extension extracts all visible code blocks with supported language identifiers, including:

  • R code: Creates .R files
  • Python code: Creates .py files
  • Julia code: Creates .jl files
  • And 13 other languages (see supported languages below)

Only code blocks with echo: true (the default) are extracted. Code blocks with echo: false or include: false are not accessible to the filter and will not be included in the extracted scripts.

Installation

How do I install the {ripper} extension?

To install the ripper Quarto extension, follow these steps:

  1. Open your terminal.
  2. Execute the following command:
quarto add coatless-quarto/ripper

Your project structure should look like:

your-project/
├── _extensions/
   └── ripper/
       ├── _extension.yml
       └── ripper.lua
└── your-document.qmd

Is the {ripper} extension compatible with all Quarto versions?

The {ripper} extension requires Quarto v1.7 or later.

Do I need to install any additional dependencies?

No additional dependencies are required. The {ripper} extension is a pure Lua filter that works with Quarto’s built-in Pandoc processing.

Usage and Customization

How do I enable the {ripper} extension in my document?

After installing the extension, add it to your document’s YAML front matter:

---
title: "My Analysis"
filters:
  - ripper
---

When you render the document, script files will be automatically created in the same directory as your source document, and a section with links to the files will be added to your rendered output.

Can I control whether YAML metadata is included in the extracted scripts?

Yes! Use the include-yaml option:

---
title: "My Analysis"
filters:
  - ripper
extensions:
  ripper:
    include-yaml: false  # Extracts only code, no YAML data
---

Default behavior (include-yaml: true): YAML metadata is included as commented lines at the top of each script.

Code-only extraction (include-yaml: false): Only the raw code is extracted with no YAML comments.

How are YAML comments formatted for different languages?

The extension automatically selects the appropriate comment style for each language:

  • Languages using #': R, Python, Julia, Bash, Ruby, Perl
  • Languages using //': JavaScript, TypeScript, Rust, Go, C++, C, Java, Scala, PHP
  • SQL: Uses --' for comments

For example, in R:

#' ---
#' title: My Analysis
#' ---
#' 

In JavaScript:

//' ---
//' title: My Analysis
//' ---
//' 

Can I customize the output filename?

Yes! Use the output-name option:

extensions:
  ripper:
    output-name: "analysis-scripts"

This will generate files like analysis-scripts.R and analysis-scripts.py instead of using your document’s filename.

Can I change the output directory for extracted scripts?

Scripts are created in the same directory as your source document (.qmd file). To change this location, you would need to modify the ripper.lua file to specify a different output path.

Does {ripper} work with all Quarto output formats?

Yes! Since {ripper} operates at the Pandoc AST level before format-specific rendering, it works with all Quarto output formats including HTML, PDF, Word, EPUB, and more. The script extraction happens regardless of your document’s output format.

The links section adapts to the output format:

  • Regular formats (HTML, PDF, etc.): Uses # (level 1) header
  • RevealJS presentations: Uses ## (level 2) header with scrollable class

Behavior and Features

What appears in the rendered document?

By default, a section is added at the bottom of your rendered document with links to the generated script files:

For one script file:

# Script file

The code for this document can be found here:

- example.R

For multiple script files:

# Script files

The code for this document can be found here:

- example.R
- example.py
- example.jl

The header uses singular “Script file” for one file and plural “Script files” for multiple files.

What languages are supported?

The extension supports 16 programming languages:

Language Extension Comment Style
R .R #'
Python .py #'
Julia .jl #'
Bash .sh #'
JavaScript .js //'
TypeScript .ts //'
SQL .sql --'
Rust .rs //'
Go .go //'
C++ .cpp //'
C .c //'
Java .java //'
Scala .scala //'
Ruby .rb #'
Perl .pl #'
PHP .php //'

Are code chunk options included in the extracted scripts?

No, code chunk options (like #| label:, #| echo:, #| warning:) are not included in the extracted scripts. These options are processed by Quarto before the Lua filter runs and are not accessible to the filter.

The extension extracts:

  • YAML metadata (optional, as comments)
  • Raw code blocks (always)
  • Execution order (preserved)

It does not extract:

  • Code chunk options (#| directives)
  • Code blocks with echo: false or include: false

If you need chunk options in your extracted scripts, consider using quarto inspect instead of this extension.

How does {ripper} handle multiple code blocks in the same language?

All code blocks in the same language are combined into a single file, separated by blank lines. The order is preserved exactly as it appears in your document.

For example, if you have three R code blocks:

```{r}
x <- 1
```
```{r}
y <- 2
```
```{r}
z <- x + y
```

They become one document.R file:

x <- 1

y <- 2

z <- x + y

What happens if my document has no code blocks?

If no code blocks with supported languages are found, the extension will not create any script files and no links section will be added to your document. Your document renders normally without any side effects.

Does {ripper} affect the original document rendering?

No, the original document content remains completely unchanged. The extension only:

  1. Creates additional script files as a side effect
  2. Adds a links section to your rendered output (unless disabled)

Your document’s code execution, outputs, figures, and all other content remain exactly as they would be without the extension.

Can I exclude certain code blocks from being extracted?

Currently, the extension extracts all visible code blocks with supported language identifiers.

Future versions may include more granular exclusion options.

Why are my echo: false code blocks not in the extracted scripts?

This is a fundamental limitation of the Lua filter approach. When code blocks have echo: false, they are removed from the document AST before the filter sees them. The filter can only access blocks that appear in the rendered output.

If you need to extract all code including hidden blocks, use quarto inspect wrappers instead:

# R approach
quarto::qmd_to_r_script("document.qmd")

Can I extract code chunk options like #| fig.width: 5?

No, chunk options are processed by Quarto before the filter runs and are not accessible. The filter only sees the code content, not the chunk-level directives.

This is a key difference from quarto inspect wrappers, which can preserve chunk options.

Troubleshooting

Script files aren’t being created. What should I do?

First, ensure that:

  1. The {ripper} extension is properly installed in your _extensions/ripper/ directory
  2. You’ve added filters: - ripper to your document’s YAML front matter (note the hyphen!)
  3. Your document contains code blocks with supported language identifiers
  4. Your code blocks are visible (not using echo: false or include: false)
  5. You have write permissions in the document directory
  6. You’re using Quarto v1.7 or later

Enable debug mode to see detailed logging:

extensions:
  ripper:
    debug: true

Check the Quarto rendering output for [ripper] messages.

I set include-yaml: false but still see comments in my output

Double-check your YAML structure. The configuration must be nested under extensions.ripper:

Correct:

extensions:
  ripper:
    include-yaml: false

Incorrect:

ripper:
  include-yaml: false

My code blocks have #| options but they don’t appear in the extracted scripts

This is expected behavior. Code chunk options like #| label:, #| echo:, and #| warning: are processed by Quarto before the filter runs and are not accessible for extraction. The filter extracts only the actual code content.

If you need chunk options in your scripts, use quarto inspect wrappers instead.

Some of my code blocks are missing from the extracted scripts

Check if those blocks have echo: false or include: false. These blocks are not visible to the filter and cannot be extracted. This is a fundamental limitation of the filter-based approach.

Enable debug mode to see which blocks are being collected:

extensions:
  ripper:
    debug: true

You’ll see messages like:

[ripper] Collected code block for language: r (52 bytes)
[ripper] Skipping unsupported language: text

Can I use {ripper} with other Quarto extensions?

Yes, {ripper} is designed to work alongside other Quarto extensions. If you encounter conflicts, try adjusting the order of filters in your YAML front matter. Generally, {ripper} should be placed after filters that modify code blocks.

The extension creates files but they’re empty

Check that your code blocks have the correct language identifier syntax. The language must be specified immediately after the opening backticks:

Correct:

```{r}
code here
```

Incorrect:

``` r
code here
```

Also ensure the language identifier matches the supported languages exactly (case-sensitive).

How can I see what the extension is doing?

Enable debug mode:

extensions:
  ripper:
    debug: true

This will output detailed [ripper] messages showing:

  • Configuration loaded
  • Code blocks collected (with byte counts)
  • Files being written
  • Links section creation
  • Block insertion position

How can I add support for additional languages?

Edit the _extensions/coatless-quarto/ripper/ripper.lua file and add entries to both tables:

-- Add file extension
lang_extensions = {
  ...
  matlab = ".m",
}

-- Add comment style
comment_styles = {
  ...
  matlab = "%'",
}

After making changes, re-render your document.

Advanced Usage

Can I extract code from multiple documents at once?

Yes, simply add the {ripper} filter to each document’s YAML front matter. Each document will generate its own set of script files named after the source document (or custom name if specified).

Can I use the same output name for multiple documents?

Yes, but be careful! If you set output-name: "shared" in multiple documents in the same directory, the last rendered document will overwrite the previous files.

This can be useful for:

  • Incremental building of a shared script library
  • Testing different document variations with same output scripts

Can I version control the extracted scripts?

Yes, though you may want to add them to .gitignore and regenerate them during your build process instead. Since they’re automatically generated from your Quarto documents, tracking both can lead to redundant changes.

Alternatively, you can commit them to version control to provide easy access to standalone scripts without requiring Quarto to be installed.

How does {ripper} work with RevealJS presentations?

The extension works with RevealJS presentations and adapts the links section header:

  • Regular documents: Uses # (level 1) header
  • RevealJS: Uses ## (level 2) header with scrollable class

This ensures the links section fits naturally into your presentation structure.

Can I use {ripper} in a project with multiple output formats?

Yes! The extension works with all output formats. If you render the same document to multiple formats, the script files are generated each time (they’ll be identical unless you change the code).

What’s the performance impact?

Minimal. The extension:

  • Operates during Pandoc’s AST traversal (already happening)
  • Writes small files to disk (fast I/O operation)
  • Adds negligible overhead to rendering time

Debug mode adds minimal overhead (only when enabled).

Comparison with Alternatives

When should I use {ripper} vs quarto inspect?

Use {ripper} when:

  • You want automatic extraction during rendering
  • You don’t need hidden code blocks (echo: false)
  • You don’t need chunk options in scripts
  • You want links to scripts in your rendered document

Use quarto inspect wrappers when:

  • You need to extract all code including hidden blocks
  • You need chunk options in extracted scripts
  • You want a separate extraction step

How does {ripper} compare to knitr::purl()?

knitr::purl() is R-specific and works with .Rmd files:

Feature {ripper} knitr::purl()
Languages 16 R only
File formats .qmd .Rmd
Automatic During render Manual call
Hidden code No Yes
Chunk options No Yes
Document links Yes No

Support

How can I contribute to the {ripper} extension?

For bug reports, feature requests, or contributions, please visit the project’s GitHub repository. Contributions are welcome, including:

  • Additional language support
  • New configuration options
  • Documentation improvements
  • Bug fixes and performance enhancements