Frequently Asked Questions
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
.Rfiles - Python code: Creates
.pyfiles - Julia code: Creates
.jlfiles - 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:
- Open your terminal.
- Execute the following command:
quarto add coatless-quarto/ripperYour project structure should look like:
your-project/
├── _extensions/
│ └── ripper/
│ ├── _extension.yml
│ └── ripper.lua
└── your-document.qmdIs 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 position of the script links section?
Yes! Use the script-links-position option:
extensions:
ripper:
script-links-position: "top" # "top", "bottom", "custom", or "none"For custom positioning, use the "custom" option and place a marker div in your document:
---
extensions:
ripper:
script-links-position: "custom"
---
## Introduction
Some content...
::: {#ripper-links}
:::
## Analysis
More content...
```{r}
x <- 1:10
mean(x)
```The links section will appear where you placed the marker div.
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.
How do I hide the script links section?
Set script-links-position: "none":
extensions:
ripper:
script-links-position: "none"The scripts will still be generated, but no links section will appear in your rendered document.
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 withscrollableclass
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.RFor multiple script files:
# Script files
The code for this document can be found here:
- example.R
- example.py
- example.jlThe 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: falseorinclude: 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 + yWhat 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:
- Creates additional script files as a side effect
- 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:
- The
{ripper}extension is properly installed in your_extensions/ripper/directory - You’ve added
filters: - ripperto your document’s YAML front matter (note the hyphen!) - Your document contains code blocks with supported language identifiers
- Your code blocks are visible (not using
echo: falseorinclude: false) - You have write permissions in the document directory
- You’re using Quarto v1.7 or later
Enable debug mode to see detailed logging:
extensions:
ripper:
debug: trueCheck 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: falseIncorrect:
ripper:
include-yaml: falseMy 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: trueYou’ll see messages like:
[ripper] Collected code block for language: r (52 bytes)
[ripper] Skipping unsupported language: textCan 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).
The script links section appears in the wrong place
Check your script-links-position setting:
extensions:
ripper:
script-links-position: "top" # or "bottom", "custom", "none"For custom positioning, ensure you’ve placed the marker div:
::: {#ripper-links}
:::Enable debug mode to see positioning messages:
[ripper] Insert position: bottom
[ripper] Inserting 3 block(s) at bottom of documentHow can I see what the extension is doing?
Enable debug mode:
extensions:
ripper:
debug: trueThis 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 withscrollableclass
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