<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Publishing on Posit Open Source</title>
    <link>https://opensource.posit.co/topics/publishing/</link>
    <description>Recent content in Publishing on Posit Open Source</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 14 Apr 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://opensource.posit.co/topics/publishing/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Chrome Headless Shell in Quarto</title>
      <link>https://opensource.posit.co/blog/2026-04-14_chrome-headless-shell/</link>
      <pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2026-04-14_chrome-headless-shell/</guid>
      <dc:creator>Christophe Dervieux</dc:creator><description><![CDATA[<p>Quarto uses a headless browser behind the scenes to render 






<a href="https://quarto.org/docs/authoring/diagrams.html" target="_blank" rel="noopener">Mermaid and Graphviz diagrams</a>
 to PNG for print formats like PDF and DOCX. Until now, this meant installing Puppeteer-bundled Chromium via <code>quarto install chromium</code> &mdash; a setup that worked, but came with some rough edges.</p>
<p>Starting with Quarto 1.9, <code>quarto install chromium</code> is deprecated. The recommended replacement is 






<a href="https://developer.chrome.com/blog/chrome-headless-shell" target="_blank" rel="noopener">Chrome Headless Shell</a>
, a lightweight, headless-only browser from Google&rsquo;s 






<a href="https://developer.chrome.com/blog/chrome-for-testing" target="_blank" rel="noopener">Chrome for Testing</a>
 infrastructure.</p>
<h2 id="why-the-switch">Why the switch?
</h2>
<p>Puppeteer-bundled Chromium served Quarto well, but it had limitations that kept coming up:</p>
<ul>
<li><strong>System dependencies in containers</strong>: The Puppeteer Chromium binary requires system libraries that aren&rsquo;t always present in minimal Docker images or WSL environments. This led to cryptic errors that were hard to debug.</li>
<li><strong>No arm64 Linux support</strong>: Puppeteer didn&rsquo;t distribute Chromium builds for arm64 Linux, leaving users without an easy install path.</li>
<li><strong>Large download size</strong>: The full Chromium bundle is significantly larger than what Quarto actually needs for headless rendering.</li>
</ul>
<p>Chrome Headless Shell solves all three. It&rsquo;s purpose-built for headless automation, has fewer system dependencies, ships arm64 Linux builds, and is smaller to download.</p>
<h2 id="installing-chrome-headless-shell">Installing Chrome Headless Shell
</h2>
<p>If you don&rsquo;t already have Chrome or Edge installed on your system, install Chrome Headless Shell:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto install chrome-headless-shell</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Quarto will automatically detect and use any existing Chrome or Edge browser on your system. Chrome Headless Shell is the recommended fallback for environments where a full browser isn&rsquo;t available &mdash; CI servers, Docker containers, and headless VMs.</p>
<h2 id="migrating-from-chromium">Migrating from Chromium
</h2>
<p>If you previously installed Chromium via <code>quarto install chromium</code>, the migration is straightforward:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto uninstall chromium
</span></span><span class="line"><span class="cl">quarto install chrome-headless-shell</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Running <code>quarto check install</code> will warn you if a legacy Chromium installation is detected and suggest the migration.</p>
<h3 id="ci-and-automation">CI and automation
</h3>
<p>If your CI pipeline uses <code>quarto install chromium --no-prompt</code>, it will continue to work &mdash; the command still installs a working headless browser, but now shows a deprecation warning. Updating your scripts to <code>quarto install chrome-headless-shell --no-prompt</code> avoids the warning and uses the new tool directly. In Quarto 1.10, <code>quarto install chromium</code> will transparently redirect to Chrome Headless Shell, so either command will produce the same result.</p>
<h2 id="whats-next">What&rsquo;s next
</h2>
<p>The transition away from Puppeteer Chromium is happening gradually. In Quarto 1.9, <code>quarto install chromium</code> shows a deprecation warning and <code>quarto check install</code> flags any legacy Chromium installation. In the upcoming Quarto 1.10, <code>quarto install chromium</code> will transparently redirect to Chrome Headless Shell, and installing Chrome Headless Shell will auto-remove any legacy Chromium.</p>
<p>If you&rsquo;re still using the old Chromium install, now is a good time to switch.</p>
<p>Learn more on the 


  
  
  





<a href="https://quarto.org/docs/authoring/diagrams.html#chrome-install" target="_blank" rel="noopener">Chrome Install</a>
 documentation page.</p>
<p>The Chromium icon in the 






<a href="thumbnail.png">listing and social card image</a>
 for this post is by <a href="https://icon-icons.com/authors/602-jeremiah" class="external">Jeremiah</a> via <a href="https://icon-icons.com/icon/chromium/104592" class="external">icon-icons.com</a>. License: <a href="https://creativecommons.org/licenses/by/4.0/" class="external">CC BY 4.0</a></p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2026-04-14_chrome-headless-shell/thumbnail.png" length="11265" type="image/png" />
    </item>
    <item>
      <title>Structuring Reproducible Research Projects in R: A Workflow with renv, Quarto, and GitHub</title>
      <link>https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/</link>
      <pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/</guid>
      <dc:creator>Dianyi Yang</dc:creator><description><![CDATA[<p>Increasingly, academic disciplines, including the social sciences, are adopting data-science tools and calling for greater transparency and reproducibility in research. Many leading journals now require authors to share the data and code necessary to replicate published findings as a condition of publication.</p>
<p>Yet preparing replication materials can be daunting, especially for researchers new to data science. It is not uncommon for scholars to struggle to reproduce even their own results, due to issues such as disorganized code and data, software version mismatches, missing random seeds, or differences in operating systems and platforms. While some of these challenges are complex, many reproducibility problems stem from preventable organizational issues. Structuring code and data in a clear, consistent, and tool-friendly manner can significantly reduce these difficulties &mdash; and brings additional benefits at virtually no cost, including smoother collaboration and easier integration with AI tools.</p>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/1.png" data-fig-alt="Comic: on Friday evening a programmer says &#39;I&#39;ll finish this on Monday&#39;; on Monday morning they stare at their code asking &#39;What does this mean?!&#39;" alt="Meme from r/ProgrammerHumor" />
<figcaption aria-hidden="true">Meme from r/ProgrammerHumor</figcaption>
</figure>
<p>In this post, I&rsquo;ll walk through the project structure I use in my own research. It has evolved over time and reflects what I currently consider best practice for reproducible academic work. Adopting a clear structure from the outset makes it significantly easier to reproduce results, onboard collaborators, and maintain projects over the long term.</p>
<p>The structure covers the full research lifecycle: from data cleaning and analysis to manuscript preparation and presentation. The template is built around R and Quarto (the successor to R Markdown), but the underlying principles translate easily to Python and other publishing workflows, including LaTeX. For convenience, I&rsquo;ve created a ready-to-use template on 






<a href="https://github.com/kv9898/academic-project-template" target="_blank" rel="noopener">GitHub</a>
 that you can clone and adapt for your own projects.</p>
<p>The project structure looks like this:</p>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/2.png" data-fig-alt="File explorer showing the project directory tree: folders for _extensions, .quarto, code, data_processed, data_raw, extras, manuscript, outputs, renv, and slides, plus config files like _quarto.yml, .gitattributes, .gitignore, .Rprofile, README.md, and renv.lock" alt="Project structure" />
<figcaption aria-hidden="true">Project structure</figcaption>
</figure>
<p>I&rsquo;ll now break down each component in turn, explaining the purpose of the key folders and files, and the reasoning behind the design.</p>
<h2 id="git-and-github">Git and GitHub
</h2>
<p>One major threat to reproducibility is a file named <code>latest_final_v3_definitive.R</code>. While this naming convention feels natural during exploratory analysis&mdash;especially under deadline pressure&mdash;it quickly becomes impossible to reconstruct what actually changed, when, and why. Future-you (and your collaborators) will not be grateful.</p>
<p>Version control systems like Git solve this problem by recording a structured history of changes through <em>commits</em>. Instead of creating new files for every iteration, you preserve a single evolving project with a transparent timeline. This makes it easy to revisit earlier versions, understand how results evolved, and collaborate without overwriting each other&rsquo;s work.</p>
<p>GitHub builds on this by providing a shared platform for hosting repositories, reviewing changes, managing issues, and coordinating collaboration. It also makes it very clear who introduced a particular change&mdash;an accountability feature that tends to concentrate the mind when committing code.</p>
<p>In the example project structure, several files and folders are Git-related:</p>
<pre><code>.git/ (invisible folder created by Git)
.gitignore
*.gitattributes
*/
└── .gitignore
</code></pre>
<p>The <code>.git/</code> folder is created automatically when you initialize a repository. It contains the full version history and metadata of the project. You generally do not need to interact with it directly&mdash;just avoid modifying or deleting it.</p>
<p>The <code>.gitignore</code> file specifies which files and folders should be tracked or ignored by Git. Since all changes to tracked files are recorded in the project history, a useful rule of thumb is to track only what is necessary to reproduce your results. Files that can be regenerated from code&mdash;such as intermediate data, plots, tables, or compiled PDFs&mdash;are often better ignored to keep the repository clean and lightweight.</p>
<p>The <code>.gitattributes</code> file defines additional rules for how Git should handle specific file types. Compared with <code>.gitignore</code>, it appears less often in many repositories, but it is especially useful when you need file-type-specific behavior. In particular, large raw data files (e.g., large .csv files) and binary formats (such as .rds, .RData, or images) can significantly increase repository size if tracked directly. In these cases, Git Large File Storage (Git LFS) can be used to store the actual files separately, while keeping lightweight pointer files in the main repository history.</p>
<h2 id="data-directories">Data directories
</h2>
<p>I use two separate folders to store raw (<code>data_raw/</code>) and cleaned data (<code>data_processed/</code>). Keeping these distinct makes the workflow more transparent: the original data remains untouched, while processed data can be saved in a format that is fast to load during analysis.</p>
<p>This structure also aligns with common journal expectations that replication code should be able to reproduce results starting from the raw data. By preserving raw inputs and separating preprocessing steps, you make the transformation pipeline explicit rather than implicit.</p>
<pre><code>data_raw/
└── *.csv (tracked through Git LFS)

data_processed/
├── *.rds (not tracked in Git)
└── .gitignore
</code></pre>
<p>In the template, the example raw data file (<code>data_raw/Brexit.csv</code>) is tracked using Git LFS. While the file itself is neither large nor binary (unlike formats such as <code>.dta</code> or <code>.rds</code>), LFS is used here for demonstration purposes. In real-world research projects, raw datasets are often substantial in size, and setting up LFS early helps avoid repository bloat later on.</p>
<p>The <code>data_processed/</code> folder contains the cleaned dataset in <code>.rds</code> format, along with a <code>.gitignore</code> file that excludes all files in this folder (except the <code>.gitignore</code> file itself) from version control. This design encourages regeneration of cleaned data from raw inputs via code, rather than relying on previously saved intermediate objects. It also helps keep the repository lightweight.</p>
<p>The <code>.rds</code> format is used for several reasons. First, it is a native R format that preserves data types and attributes faithfully. Second, it encourages the use of RDS over <code>.RData</code>. Unlike <code>.RData</code>, which loads all stored objects into the global environment under their <em>original</em> names, <code>.rds</code> files require explicit assignment when loaded. This reduces the risk of unintentionally overwriting existing objects and promotes more transparent workflows.</p>
<p>Finally, the <code>.gitignore</code> file inside <code>data_processed/</code> serves an additional purpose: it ensures that the folder itself is tracked by Git. Since Git does not record empty directories, this placeholder guarantees that the directory exists when the project is cloned. This is important because saving cleaned data to a non-existent directory will otherwise result in an error in R.</p>
<p>For researchers working with <strong>confidential</strong> or <strong>restricted</strong> data, it is often helpful to separate sensitive materials from those that can be shared publicly. In some cases, this may mean maintaining a private repository during the research phase and preparing a separate public-facing repository upon publication.</p>
<p>Importantly, simply deleting confidential files before making a repository public is not sufficient. Git preserves the full commit history, meaning sensitive data may still be accessible in earlier revisions. Creating a fresh repository that contains only the materials intended for public release&mdash;such as replication code and non-sensitive data&mdash;helps prevent unintended data leakage.</p>
<p>This approach also makes it easier to curate a clean, well-documented version of the project specifically designed for replication and reuse.</p>
<h2 id="code-organization-and-outputs">Code organization and outputs
</h2>
<pre><code>code/
├── 1_data_cleaning.R
├── 2_descriptive.R
└── 3_main_analysis.R

outputs/
├── *.rds (not tracked in Git)
└── .gitignore
</code></pre>
<p>The <code>code/</code> folder contains all scripts related to data processing and analysis. In the template, these are written in R, but the same structure works equally well for Python scripts (<code>.py</code>), notebooks (<code>.ipynb</code>), or other programming languages.</p>
<p>A key principle is to prefix scripts with numbers and descriptive names that reflect the research workflow: data cleaning, descriptive analysis, and then inferential analysis. If the logical order of steps is unclear, following the sequence in which results appear in the manuscript is often a reliable guide. This makes the analytical pipeline explicit and allows others (and future-you) to reproduce results step-by-step.</p>
<p>Each script should include a header section with basic metadata about its role in the project. This may include the paper title, authors, purpose of the script, input files, and output files. Making inputs and outputs explicit helps clarify dependencies and encourages scripts that transform data rather than rely on objects lingering in the global environment.</p>
<p>Below is an example of an analysis script (<code>code/3_main_analysis.R</code>) I used in the template that follows these principles:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">######## INFO ########</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># PROJECT</span>
</span></span><span class="line"><span class="cl"><span class="c1">## Paper: YOUR PAPER TITLE</span>
</span></span><span class="line"><span class="cl"><span class="c1">## Authors: YOUR NAME</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># R Script</span>
</span></span><span class="line"><span class="cl"><span class="c1">## Purpose: This script performs linear regression analysis.</span>
</span></span><span class="line"><span class="cl"><span class="c1">## Inputs: data_processed/Brexit.rds</span>
</span></span><span class="line"><span class="cl"><span class="c1">## Outputs: outputs/regression_table.rds</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Setup ----</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">tidyverse</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">here</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">modelsummary</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">i_am</span><span class="p">(</span><span class="s">&#34;code/3_main_analysis.R&#34;</span><span class="p">)</span> <span class="c1"># helps with relative paths</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Read in the cleaned data ----</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">brexit_data</span> <span class="o">&lt;-</span> <span class="nf">read_rds</span><span class="p">(</span><span class="nf">here</span><span class="p">(</span><span class="s">&#34;data_processed/Brexit.rds&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Main analysis ----</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">model</span> <span class="o">&lt;-</span> <span class="nf">lm</span><span class="p">(</span><span class="n">leave</span> <span class="o">~</span> <span class="n">turnout</span> <span class="o">+</span> <span class="n">income</span> <span class="o">+</span> <span class="n">noqual</span><span class="p">,</span> <span class="n">data</span> <span class="o">=</span> <span class="n">brexit_data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Output the model summary ----</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">reg_table</span> <span class="o">&lt;-</span> <span class="nf">modelsummary</span><span class="p">(</span><span class="n">model</span><span class="p">,</span> <span class="n">stars</span> <span class="o">=</span> <span class="kc">TRUE</span><span class="p">,</span> <span class="n">output</span> <span class="o">=</span> <span class="s">&#34;latex&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">write_rds</span><span class="p">(</span><span class="n">reg_table</span><span class="p">,</span> <span class="nf">here</span><span class="p">(</span><span class="s">&#34;outputs/regression_table.rds&#34;</span><span class="p">))</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Two additional tips are worth noting. First, the <code># SECTION ----</code> syntax creates collapsible sections and structured outlines in RStudio and the Positron IDE. This makes longer scripts significantly easier to navigate and encourages more intentional organization of code.</p>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/3-pos.png" data-fig-alt="Positron IDE showing collapsible code sections created with the &#39;# Section ----&#39; syntax" alt="Collapsible sections in Positron" />
<figcaption aria-hidden="true">Collapsible sections in Positron</figcaption>
</figure>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/3-rstudio.png" data-fig-alt="RStudio IDE showing collapsible code sections created with the &#39;# Section ----&#39; syntax" alt="Collapsible sections in RStudio" />
<figcaption aria-hidden="true">Collapsible sections in RStudio</figcaption>
</figure>
<p>Second, managing working directories is a seemingly basic task that is frequently mishandled&mdash;especially in collaborative projects. In RStudio, the recommended approach is to work within an <code>.Rproj</code> file, which defines a project root and ensures that relative paths behave consistently across machines. However, in many academic settings (including political science), this practice is not systematically taught. As a result, it is still common to see replication files from top journals that begin with something like <code>setwd(&quot;~/Path/To/Project&quot;)</code>, often commented out with the expectation that collaborators will manually adjust it.</p>
<p>This approach is fragile. It assumes a specific directory structure on every machine and introduces hidden dependencies on local file paths. Code that depends on <code>setwd()</code> is difficult to port, share, or automate.</p>
<p>Positron improves this situation by automatically setting the working directory to the folder opened in the IDE, encouraging a project-level workflow by default. However, many users carry over the habit of opening individual scripts rather than entire project directories.</p>
<p>The <code>here</code> package provides a robust solution that avoids reliance on the working directory altogether. By anchoring a script to the project root using <code>here::i_am()</code> and constructing paths with <code>here()</code>, file references become explicit and portable. This ensures that scripts run consistently across machines, IDEs, and collaboration environments&mdash;regardless of local directory structures.</p>
<p>The <code>outputs/</code> folder complements this approach by providing a dedicated location for all results generated by the code. This includes intermediate objects (e.g., fitted models) and final products (e.g., tables and figures). If intermediate artifacts become numerous, they can be stored in a separate <code>objects/</code> folder. The accompanying <code>.gitignore</code> file ensures that these generated files are not versioned, reinforcing the principle that results should be regenerated from code rather than preserved as static artifacts.</p>
<h2 id="virtual-environments-and-dependencies-renv">Virtual environments and dependencies (<code>renv</code>)
</h2>
<p>Many R users do not update their R or package versions regularly. In practice, the version in use is often determined by when the researcher first learned R&mdash;or when the machine was purchased, whichever is later. Deprecation warnings are politely ignored as long as the code continues to run.</p>
<p>The problem only becomes visible when code that worked perfectly on your old machine suddenly fails on a new machine&mdash;or worse, on a collaborator&rsquo;s machine. At that point, dependency management stops being an abstract concern and becomes a very practical one.</p>
<p>A common solution to this problem is the use of <strong>virtual environments</strong>, which capture the exact package versions used in a project&mdash;a concept long established in the Python ecosystem. In R, the <code>renv</code> package provides a convenient way to create and manage project-specific libraries. Package versions remain fixed within the project, independent of updates to the global R installation or differences across collaborators&rsquo; machines.</p>
<p>The state of the environment is recorded in the <code>renv.lock</code> file, which is committed to Git. This file serves as a snapshot of the project&rsquo;s dependency graph at a given point in time, including package versions and their sources. As a result, the same software environment can be reproduced on any machine with a simple call to <code>renv::restore()</code>.</p>
<p>Three key components related to <code>renv</code> appear in the template structure:</p>
<pre><code>renv/
.Rprofile
renv.lock
</code></pre>
<p>The <code>renv/</code> folder contains the project-specific package library. Most of its contents are not tracked in Git, since the environment can be regenerated from the information stored in <code>renv.lock</code>. Additionally, some packages include compiled C or C++ code that is platform-specific, meaning those installed binaries are not portable across operating systems.</p>
<p>The <code>.Rprofile</code> file includes a line that automatically activates the <code>renv</code> environment when the project is loaded, ensuring that the correct package versions are used without manual setup.</p>
<p>Automatic activation, however, only works when the project is <strong>opened as a whole</strong>&mdash;for example, by opening the <code>.Rproj</code> file or the project folder in Positron. If individual scripts are opened in isolation, the working directory will not be set to the project root at startup, and the project-level <code>.Rprofile</code> will not be executed. This is yet another reason to adopt a project-level workflow rather than treating scripts as standalone files.</p>
<h2 id="quarto-manuscripts-and-presentations">Quarto: manuscripts and presentations
</h2>
<p>The most visible stage of the research lifecycle is the dissemination of results&mdash;through manuscripts, presentations, and other public outputs. For quantitatively oriented researchers (which, if you have read this far, likely includes you), producing well-formatted documents that do justice to your carefully constructed tables and figures is essential.</p>
<p>Quarto is an open-source scientific and technical publishing system built on Pandoc. I use it for all of my manuscript writing and presentation slides, and I recommend it for researchers working in R, Python, or Julia. The template presented here is deliberately centered around Quarto, and in what follows I will briefly explain the reasoning behind that choice.</p>
<h3 id="why-quarto">Why Quarto?
</h3>
<p>What makes Quarto stand out is its ability to run R, Python, or Julia code directly within a document, seamlessly integrating analysis and writing. Tables, figures, and results can therefore be generated and updated automatically as the underlying code changes, ensuring that the manuscript always reflects the current state of the analysis.</p>
<p>Quarto is not a replacement for output formats such as HTML, Microsoft Word, LaTeX, or Typst. Rather, it acts as a <em>unifying</em> layer that can render the same <code>.qmd</code> source file into multiple formats simultaneously. This flexibility allows format decisions to be postponed and adapted to collaborators, institutions, or journal requirements.</p>
<p>Beyond manuscripts, Quarto also supports presentation formats and full websites. Learning a single tool therefore enables the production of academic papers, conference slides, and project or personal websites within a consistent workflow.</p>
<p>While these capabilities may sound familiar to experienced R Markdown users, I would still argue that Quarto is worth trying&mdash;even for those already comfortable with R Markdown&mdash;for four main reasons:</p>
<ol>
<li>
<p><strong>Language-agnostic support</strong>: Quarto is designed to work seamlessly with multiple programming languages (R, Python, Julia). A document can be executed using the native engine for each language&mdash;for example, a Python-only document runs through a Jupyter kernel without requiring R<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>, which is more friendly to non-R users.</p>
</li>
<li>
<p><strong>Native support for extended features</strong>: Quarto includes built-in support for cross-referencing, citations, and advanced formatting without requiring additional packages or complex configurations. In contrast, R Markdown often relies on extensions such as <code>bookdown</code> to achieve similar functionality, which introduces additional dependencies. In practice, many students are taught only the basic R Markdown setup and may not be aware of these extensions. Quarto provides these features out of the box.</p>
</li>
<li>
<p><strong>More scannable code cell/chunk options and syntax</strong>: R Markdown users may be familiar with setting document-wide execution options inside a setup chunk using <code>knitr::opts_chunk$set(...)</code>, and specifying chunk options inline in a comma-separated format. While functional, this approach can become difficult to scan and maintain in larger documents.</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">``<span class="sb">`{r}
</span></span></span><span class="line"><span class="cl"><span class="sb">knitr::opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE, error = FALSE)
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>`<span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>`<span class="sb">`{r barplot, fig.cap=&#39;Bar plot for y by x.&#39;, fig.height=3, fig.width=5}
</span></span></span><span class="line"><span class="cl"><span class="sb"># code for the bar plot
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>``</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>In Quarto, document-level execution options are defined declaratively in YAML, while cell-level options use a multi-line, command-style syntax. This makes both levels of configuration easier to scan, and typically easier to review in diffs and modify.</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="s">```yaml
</span></span></span><span class="line"><span class="cl"><span class="nt">execute</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">echo</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">warning</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">error</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">message</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="s">```</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">``<span class="sb">`{r}
</span></span></span><span class="line"><span class="cl"><span class="sb">#| label: fig-barplot
</span></span></span><span class="line"><span class="cl"><span class="sb">#| fig-cap: &#39;Bar plot for y by x.&#39;
</span></span></span><span class="line"><span class="cl"><span class="sb">#| fig-height: 3
</span></span></span><span class="line"><span class="cl"><span class="sb">#| fig-width: 5
</span></span></span><span class="line"><span class="cl"><span class="sb"># code for the bar plot
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>``</span></span></code></pre></td></tr></table>
</div>
</div></div>
</li>
<li>
<p><strong>Centralized documentation</strong>: While R Markdown benefits from a large community and extensive online resources, its documentation is distributed across multiple sites<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>. Quarto, by contrast, maintains a single, comprehensive 






<a href="https://quarto.org" target="_blank" rel="noopener">documentation portal</a>
 that covers core usage and advanced features in one place, making it easier to navigate and learn systematically.</p>
</li>
</ol>
<h3 id="quarto-project-structure">Quarto project structure
</h3>
<p>The remaining components of the template are primarily related to Quarto. Below, I break down the key elements and explain the reasoning behind their organization.</p>
<pre><code>_extensions
.quarto (created by Quarto; not tracked in Git)
extras/
manuscript/
├── manuscript.pdf (not tracked in Git)
└── manuscript.qmd
slides/
├── slides.pdf (not tracked in Git)
└── slides.qmd
_quarto.yml
</code></pre>
<h3 id="configuration-file">Configuration file
</h3>
<p>The <code>_quarto.yml</code> file serves two main purposes.</p>
<p>First, it defines project-level execution behavior. In particular, the following setting ensures that code is executed relative to the project root, regardless of where individual .qmd files are located:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">project</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">execute-dir</span><span class="p">:</span><span class="w"> </span><span class="l">project</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This provides an additional layer of protection for resolving relative paths correctly. Used together with the here package, it helps ensure that file paths behave consistently across different machines and execution contexts.</p>
<p>Second, <code>_quarto.yml</code> centralizes shared configuration options so they do not need to be repeated in each individual <code>.qmd</code> file. This reduces duplication, minimizes the risk of inconsistencies, and improves readability across documents.</p>
<p>In the template, shared options include the bibliography file and citation style:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">bibliography</span><span class="p">:</span><span class="w"> </span><span class="l">extras/references.bib</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">csl</span><span class="p">:</span><span class="w"> </span><span class="l">extras/apa.csl</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Because these settings are defined at the project level, they apply automatically to both the manuscript and presentation slides.</p>
<h3 id="extras-bibliography-and-citation-styles">Extras: bibliography and citation styles
</h3>
<p>As mentioned above, the <code>extras/</code> folder contains the bibliography file (<code>references.bib</code>) and citation style file (<code>apa.csl</code>). These are referenced in the <code>_quarto.yml</code> configuration file, which means they are automatically available to all <code>.qmd</code> files in the project without needing to specify them individually.</p>
<pre><code>extras/
├── references.bib
└── apa.csl
</code></pre>
<p>Ideally, if you have other supplementary materials that are not part of the core code or data but are still relevant to the project (e.g., codebooks), they could also be stored in this folder. However, I have kept it focused on bibliography-related files for simplicity.</p>
<h4 id="bibliography-file">Bibliography file
</h4>
<p>The <code>references.bib</code> file is a standard BibTeX/BibLaTeX bibliography file familiar to LaTeX users. It contains structured reference entries, including fields such as author, title, journal, year, and other publication metadata.</p>
<p>Entries can be exported from reference managers such as Zotero or Mendeley, or generated directly within Quarto using the Visual Editor. Crucially, the bibliography file is kept separate from both the manuscript and the citation style. This separation allows the same reference database to be shared across manuscripts and slides, while making it easy to change formatting styles without modifying the source content.</p>
<h4 id="citation-style-file">Citation style file
</h4>
<p>The <code>apa.csl</code> file is a Citation Style Language (CSL) file that defines how citations and bibliography entries are formatted. It acts as a translation layer between the structured data in references.bib and the rendered output format.</p>
<p>In this template, the CSL file specifies APA style, which is common in the social sciences. However, switching styles is straightforward: replace the <code>apa.csl</code> file with another CSL file (e.g., Chicago, MLA, or a journal-specific style) and update the reference in <code>_quarto.yml</code>. No changes to the manuscript text are required.</p>
<p>To find a CSL file for a specific discipline or journal, you can browse the 






<a href="https://github.com/citation-style-language/styles" target="_blank" rel="noopener">CSL Style Repository</a>

, which contains thousands of maintained styles.</p>
<h3 id="manuscript">Manuscript
</h3>
<p>Dissemination of research findings is the ultimate goal of the research process, and the manuscript remains its primary vehicle.</p>
<pre><code>manuscript/
├── manuscript.pdf (not tracked in Git)
└── manuscript.qmd
_extensions/
└── kv9898/
    └── orcid/
</code></pre>
<p>The <code>manuscript/</code> folder contains the Quarto source file (<code>manuscript.qmd</code>) and the compiled PDF output (<code>manuscript.pdf</code>). As with other generated artifacts, the PDF is excluded from version control because it can always be regenerated from the source document.</p>
<p>The example <code>manuscript.qmd</code> provides a minimal template illustrating a typical academic structure, including numbered sections, figures, tables, cross-references, and citations. The template is intentionally simple but can be extended with additional formatting and structural elements as needed.</p>
<p>While Quarto&rsquo;s built-in PDF format supports core elements such as title, authors, date, and abstract, more specialized academic requirements&mdash;such as detailed affiliation formatting, ORCID display, keywords, custom headers, or journal-style front matter&mdash;often require additional customization.</p>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/4.png" data-fig-alt="PDF output from the default Quarto template showing title, author, and abstract" alt="Default Quarto PDF template" />
<figcaption aria-hidden="true">Default Quarto PDF template</figcaption>
</figure>
<p>To address this, I created a 






<a href="https://github.com/kv9898/orcid" target="_blank" rel="noopener">custom extension</a>
 that builds on the default PDF format and adds features commonly required in academic manuscripts. The extension is included in the template under <code>_extensions/kv9898/orcid/</code>.</p>
<p>Packaging the manuscript format as a Quarto extension ensures that formatting logic is versioned and shared alongside the project, rather than maintained as ad hoc local tweaks. The extension is activated via the YAML front matter of manuscript.qmd:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="l">orcid-pdf:</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>The resulting PDF output more closely resembles a conventional academic paper, with structured author information, affiliations, ORCID identifiers, and keywords clearly presented. Because the template is implemented as a Quarto extension, it remains portable and reusable across projects, and can be further modified, particularly by those comfortable with LaTeX, to accommodate journal-specific formatting requirements.</p>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/5.png" data-fig-alt="PDF output from the custom orcid extension template with structured affiliations, ORCID identifiers, and keywords" alt="Custom Quarto PDF template" />
<figcaption aria-hidden="true">Custom Quarto PDF template</figcaption>
</figure>
<h3 id="slides">Slides
</h3>
<p>Researchers often need to present their findings at conferences, seminars, or in teaching settings. Quarto supports multiple presentation formats, including Reveal.js, Beamer, and PowerPoint. In this template, I use <em>Beamer</em> to produce PDF slides, which are widely accepted in academic contexts and easy to share or print.</p>
<pre><code>slides/
├── slides.pdf (not tracked in Git)
└── slides.qmd
</code></pre>
<p>The <code>slides/</code> folder contains the Quarto source file (<code>slides.qmd</code>) and the compiled PDF output (<code>slides.pdf</code>). As with the manuscript, the PDF is treated as a generated artifact and excluded from version control.</p>
<p>The resulting slides are indistinguishable from those produced using a traditional LaTeX Beamer workflow. The key difference is that all content&mdash;including code, tables, and figures&mdash;can be generated directly from the same analytical pipeline.</p>
<figure>
<img src="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/6.png" data-fig-alt="Beamer presentation slides generated from Quarto showing a title slide and a content slide with a table" alt="Quarto Beamer template" />
<figcaption aria-hidden="true">Quarto Beamer template</figcaption>
</figure>
<p>In this example, I deliberately reuse the same output objects (e.g., tables and figures) in both the manuscript and the slides. This guarantees consistency across formats and eliminates the risk of discrepancies between what appears in the paper and what is presented publicly.</p>
<p>The example slides also demonstrate practical considerations such as resizing tables and figures to fit slide layouts. They reference the same shared bibliography file used in the manuscript, ensuring consistent citation formatting across outputs. Although only a single reference is included in the example, the template is configured to allow references to span multiple frames, accommodating a realistic bibliography.</p>
<h2 id="readme-file">README file
</h2>
<pre><code>README.md
</code></pre>
<p>Following both GitHub conventions and academic best practice, every project should include a <code>README.md</code> file. This file serves as the primary entry point for others who wish to understand, reproduce, or build upon the research.</p>
<p>In the template, the README provides:</p>
<ul>
<li>A brief project description</li>
<li>Instructions for setting up the environment</li>
<li>Steps to reproduce the analysis, manuscript, and slides</li>
</ul>
<p>Additional placeholders are included for information such as the machine model and operating system used during development. While not always necessary, this metadata can be helpful when troubleshooting platform-specific issues, particularly for projects involving compiled dependencies. The README also notes the approximate time required to run the full analysis and render outputs, which helps set realistic expectations for replication.</p>
<p>Notably, the template does <em>not</em> include a <strong>LICENSE</strong> file by default. This is intentional. The appropriate license for academic code and data depends on disciplinary norms, institutional policies, journal requirements, and the researcher&rsquo;s intended level of openness. Common choices include MIT or GPL licenses for code, and Creative Commons licenses for data. In some cases, more restrictive or custom licenses may be appropriate. Researchers should select a license deliberately, ensuring it aligns with their sharing goals and complies with relevant policies.</p>
<h2 id="github-as-infrastructure--not-just-hosting">GitHub as infrastructure &mdash; not just hosting
</h2>
<p>Once a project is structured clearly and pushed to GitHub, it becomes more than a collection of files. It becomes <em>infrastructure</em>.</p>
<p>A well-organized repository makes <strong>collaboration</strong> dramatically smoother. Issues can serve as lightweight meeting minutes, evolving naturally into task lists. They can be assigned to specific contributors, grouped into milestones, and tracked over time. Pull requests and branching strategies help keep the main branch stable while allowing experimentation and iterative refinement. Code reviews become part of the workflow rather than an afterthought.</p>
<p>These practices, borrowed from software development, translate surprisingly well into academic collaboration. Instead of emailing attachments back and forth, collaborators work against a shared, versioned source of truth.</p>
<p>A clear project structure also makes modern AI tools significantly more useful. When your data, scripts, outputs, and manuscripts are logically organized, AI assistants in VS Code, Positron, or GitHub can reason about your project more effectively. They can trace how tables were generated, suggest improvements to analysis code, help refine writing based on the underlying results, or flag inconsistencies between figures and text. In other words, organization enables <em>context</em> &mdash; and context is what makes AI assistance meaningful rather than superficial.</p>
<p>There are also practical benefits. Once your work is version-controlled and backed up remotely, you no longer fear data loss due to a failed hard drive, a stolen laptop, or accidental overwrites. The repository itself becomes a durable record of the project&rsquo;s evolution.</p>
<p>Perhaps most importantly, a well-structured project reduces the <em>asymmetry of knowledge</em> among collaborators. Instead of each co-author being familiar with only one portion of the workflow, everyone can develop a <em>holistic understanding</em> of how the project fits together &mdash; from raw data to final manuscript. This makes feedback more constructive, collaboration more efficient, and the research process more transparent.</p>
<p>Reproducibility, then, is not merely about satisfying journal requirements. It is about building research projects that are resilient, collaborative, and adaptable &mdash; projects that scale not only across machines, but across people.</p>
<h2 id="conclusion">Conclusion
</h2>
<p>At its core, none of the tools discussed here&mdash;Git, renv, Quarto, or GitHub&mdash;are revolutionary on their own. What matters is how they are combined into a coherent project structure. Once that structure becomes habitual, reproducibility stops being an afterthought and becomes the default.</p>
<p>Adopting this workflow does not require perfect foresight or advanced technical expertise. It simply requires <em>deciding</em>, from the outset, that clarity, versioning, and regeneration will guide the project. The payoff is substantial: <strong>fewer replication headaches, smoother collaboration, better integration with modern tooling, and greater confidence in the durability of your work</strong>.</p>
<p>In the long run, a well-structured project is not just easier to reproduce&mdash;it is easier to think with.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>When R and Python are combined within the same document, however, Quarto uses reticulate under the hood, similar to R Markdown.&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>For example, see 






<a href="https://rmarkdown.rstudio.com/" target="_blank" rel="noopener">R Markdown official documentation</a>
 for the core features, and 






<a href="https://yihui.org/rmarkdown/" target="_blank" rel="noopener">Yihui&rsquo;s personal site</a>
 for more advanced features.&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2026-04-13_reproducible-research-renv-quarto-github/img/3-pos.png" length="142508" type="image/png" />
    </item>
    <item>
      <title>What&#39;s next: Quarto 2</title>
      <link>https://opensource.posit.co/blog/2026-04-06_whats-next-quarto-2/</link>
      <pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2026-04-06_whats-next-quarto-2/</guid>
      <dc:creator>Carlos Scheidegger</dc:creator><description><![CDATA[<p>We&rsquo;re excited to share an early look at Quarto 2. You might be aware that we 





  


  
  
    
  

<a href="https://opensource.posit.co/blog/2026-03-24_1.9-release/">recently released Quarto 1.9</a>
, with support for long-standing requests such as PDF accessibility. Quarto is an excellent choice for authors of scientific and technical documents, and the amount and quality of the work you create with it is genuinely humbling for us. Before anything else, we want to thank you for using Quarto; you&rsquo;re all quite literally the reason we build it.</p>
<p><strong>Quarto 2 is a full rewrite of the Quarto CLI, written from the ground up in Rust</strong> to better support your existing use cases, and enable a number of new, exciting use cases. Most importantly, Quarto 2 will include a built-in collaborative editor, and we plan on adding support for collaborative writing in Posit&rsquo;s commercial products such as Posit Cloud, Connect, and Workbench. With that said, the design of those integrations is still taking shape.</p>
<p>It is also very early in the project. If you interact with the Quarto project solely as a user of the tool, nothing in your workflow will change, and you should proceed as if you didn&rsquo;t know about our plans for Quarto 2. <strong>We don&rsquo;t expect to have a public release of Quarto 2 for at least 6 months. In addition, we will continue to develop and maintain parallel versions until Quarto 2 is a suitable replacement for users of Quarto 1</strong>.</p>
<p>Just like Quarto 1, Quarto 2 is open source and MIT licensed. The GitHub repository for Quarto 2 is currently 






<a href="https://github.com/quarto-dev/q2" target="_blank" rel="noopener"><code>quarto-dev/q2</code></a>
.</p>
<h2 id="why-quarto-2">Why Quarto 2?
</h2>
<p>There are some fundamental pain points in Quarto 1 that can&rsquo;t be solved incrementally. The goal of Quarto 2 is not to change how you currently work with Quarto; instead, we&rsquo;ve arrived at a point where incremental improvements do not provide the value you deserve given our team size and constraints. These are some of the things we want to do in Quarto 2:</p>
<ul>
<li>
<p><strong>A new Markdown parser enables tighter integration with editors for the entire rendering pipeline</strong>.
We know that good error messages, autocompletion, and YAML validation are some of your favorite features in Quarto 1. Quarto has about 1,000 different YAML configuration options, and we know how important it is to be able to provide good error messages. We want to extend this same idea to <em>everything</em> in your Quarto project: Markdown syntax errors, Lua filter errors, broken links, etc. Whenever possible, these should be flagged in your editor of choice.</p>
</li>
<li>
<p><strong>A fundamental solution for long-standing performance problems</strong>.
Quarto 1 is built by integrating a number of tools that work very well in isolation, but aren&rsquo;t designed to be performant when used together. A full rewrite of the Quarto core functionality in a single programming language will enable us to provide much better performance than before.</p>
</li>
<li>
<p><strong>A collaborative editor</strong>.
Quarto 2 will ship with a collaborative editor designed to work directly on the web as well as on the command-line. Keeping in the tradition and ethos of the Quarto project, this will include a robust open-source foundation based on 






<a href="https://automerge.org" target="_blank" rel="noopener">automerge</a>
, as well as a commercial solution for hosted project management. This follows the relationship between Quarto 1 and its integration with other Posit commercial offerings.</p>
</li>
<li>
<p><strong>A visual editor that works well alongside a source editor</strong>.
The visual editor we ship in RStudio, VS Code, and Positron works well if everyone working on the document is using the visual editor. On the other hand, if you choose the visual editor, but your colleague chooses the source editor, then you&rsquo;ll find that the experience is full of sharp edges. Quarto 2 is built from the ground up to support <em>bidirectional</em> editing workflows. A small change in your document using the visual editor shouldn&rsquo;t cause a large change in the <code>.qmd</code> file that is disruptive for your colleagues using a source editor.</p>
</li>
<li>
<p><strong>Support for Quarto 1 projects</strong>.
We aim for Quarto 2 to be backwards compatible with Quarto 1. Concretely, we&rsquo;re aiming to incorporate our Quarto 1 test suite directly into Quarto 2&rsquo;s project, including support for Pandoc and its output formats that our community depends on. Your existing extensions and projects should just work in Quarto 2. Early on, there will be gaps, and Quarto 2 will initially be a better fit for new projects.</p>
</li>
</ul>
<h2 id="what-happens-to-quarto-1-development">What happens to Quarto 1 development?
</h2>
<p>It&rsquo;s not going anywhere, and will be in active development for at least the next year. We&rsquo;ll still provide bugfixes, and accept pull requests.</p>
<h2 id="current-status">Current status
</h2>
<p>The development is happening in a 






<a href="https://github.com/quarto-dev/q2" target="_blank" rel="noopener">separate GitHub repository</a>
. Feel free to look around! However, this code base isn&rsquo;t ready for public consumption, and is very much in flux: that means we&rsquo;re not going to spend a lot of time answering architectural questions about it until things have settled, and all discussion of Quarto should remain in our current discussion forum and issue tracker.</p>
<p>There are big, interesting changes in the Quarto 2 architecture, and they deserve a longer exposition. We are working on those documents right now, and will share them with you in the next few weeks. Stay tuned!</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2026-04-06_whats-next-quarto-2/thumbnail.png" length="98981" type="image/png" />
    </item>
    <item>
      <title>Typst Books, Article Layout, and `typst-gather`</title>
      <link>https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/</link>
      <pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/</guid>
      <dc:creator>Gordon Woodhull</dc:creator><description><![CDATA[<p>Typst is a lightning-fast typesetting system that provides a modern alternative to LaTeX.</p>
<p>The Typst ecosystem is thriving, and Quarto 1.9 brings Typst much closer to feature parity with LaTeX:</p>
<ul>
<li>Typst books</li>
<li>Article layout in Typst</li>
<li>Bundling of Typst packages for offline rendering</li>
</ul>
<h2 id="typst-books">Typst books
</h2>
<p>In Quarto 1.9, a project with type <code>book</code> and format <code>typst</code> is now rendered as a single document with multiple chapters and other book content.</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">_quarto.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">project</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">book</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">book</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;My Book&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">author</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Jane Doe&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">chapters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">index.qmd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">intro.qmd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">summary.qmd</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">format</span><span class="p">:</span><span class="w"> </span><span class="l">typst</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<div class="grid gap-12 items-start md:grid-cols-4">
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-book-part-page.png" data-fig-alt="A Typst book rendered with the orange-book extension, showing the part one page with a colored background and table of contents" alt="Part page" />
<figcaption aria-hidden="true">Part page</figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-book-1.png" data-fig-alt="A Typst book rendered with the orange-book extension, showing the chapter one page with colored headers and sidebar navigation" alt="Chapter page" />
<figcaption aria-hidden="true">Chapter page</figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-book-2.png" data-fig-alt="A Typst book rendered with the orange-book extension, showing the second page from chapter one with colored headers and sidebar navigation" alt="Chapter content" />
<figcaption aria-hidden="true">Chapter content</figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-book-3.png" data-fig-alt="A Typst book rendered with the orange-book extension, showing the chapter two page with colored headers and sidebar navigation" alt="Next chapter" />
<figcaption aria-hidden="true">Next chapter</figcaption>
</figure>
</div>
</div>
<p>All book features previously available in the LaTeX format are now available in Typst:</p>
<ul>
<li>Parts and Chapters</li>
<li>Appendices</li>
<li>Cross-references and chapter-based numbering</li>
<li>Table of Contents</li>
</ul>
<p>List-of-Figures and List-of-Tables support is 






<a href="https://github.com/quarto-dev/quarto-cli/issues/14081" target="_blank" rel="noopener">coming soon</a>
.</p>
<p>The default Typst book uses the bundled Quarto 






<a href="https://github.com/quarto-ext/orange-book" target="_blank" rel="noopener">quarto-orange-book</a>
 extension, which uses 


  
  
  





<a href="#typst-gather"><code>typst-gather</code></a>
 to bundle the Typst 






<a href="https://typst.app/universe/package/orange-book" target="_blank" rel="noopener">orange-book</a>
 package. Orange-book provides a textbook-style layout with colored chapter headers and sidebars.</p>
<p>The orange-book extension supports 






<a href="https://quarto.org/docs/authoring/brand.html" target="_blank" rel="noopener">brand.yml</a>
 customization &mdash; it uses the <code>primary</code> color for chapter headers and sidebars, and the <code>medium</code> logo on the title page. The screenshots above were generated with this <code>_brand.yml</code>:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">_brand.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">color</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">primary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#F36619&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">secondary</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#2E86AB&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">logo</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">images</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">test-logo</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">logo.svg</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">alt</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Test Logo&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">medium</span><span class="p">:</span><span class="w"> </span><span class="l">test-logo</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Since Typst books are implemented as Quarto 






<a href="https://quarto.org/docs/extensions/formats.html" target="_blank" rel="noopener">Format Extensions</a>
, you can customize the appearance by creating your own extension. Typst partials define the overall book structure, while Lua filters handle the necessary AST transformations.</p>
<h2 id="article-layout-in-typst">Article layout in Typst
</h2>
<p>Also in Quarto 1.9, all 






<a href="https://quarto.org/docs/authoring/article-layout.html" target="_blank" rel="noopener">Article Layout</a>
 features now work in Typst, via the Typst 






<a href="https://typst.app/universe/package/marginalia/" target="_blank" rel="noopener">Marginalia</a>
 package.</p>
<p>Specifically:</p>
<ul>
<li>Figures, tables, code listings, and equations can be placed in the margin using the <code>.column-margin</code> class or the <code>column: margin</code> code cell option.</li>
<li>You can also target specific output types with <code>fig-column: margin</code> or <code>tbl-column: margin</code>.</li>
<li>Figure, table, and code listing captions can be placed in the margin with <code>cap-location: margin</code> (or <code>fig-cap-location: margin</code> and <code>tbl-cap-location: margin</code> for specific types).</li>
<li>Footnotes and citations can be displayed in the margin with <code>reference-location: margin</code> and <code>citation-location: margin</code>. When margin citations are enabled, the bibliography is suppressed.</li>
<li>Asides (<code>.aside</code> class) place content in the margin without a footnote number.</li>
</ul>
<div class="grid gap-12 items-start md:grid-cols-3">
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-article.png" data-group="article" data-fig-alt="A page of a Typst article with a margin note and a margin figure using the Marginalia package" alt="Margin note and figure" />
<figcaption aria-hidden="true">Margin note and figure</figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-article-2.png" data-group="article" data-fig-alt="A page of a Typst article using margin captions" alt="Margin captions" />
<figcaption aria-hidden="true">Margin captions</figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-article-3.png" data-group="article" data-fig-alt="A page of a Typst article using margin references" alt="Margin references" />
<figcaption aria-hidden="true">Margin references</figcaption>
</figure>
</div>
</div>
<div class="callout callout-warning" role="note" aria-label="Warning">
<div class="callout-header">
<span class="callout-title">Books with article layout are functional, but need work</span>
</div>
<div class="callout-body">
<p>You can combine book and article layout, but there are some layout quirks when combining the two. We&rsquo;ll work with the orange-book author to integrate Marginalia into the book template.</p>
</div>
</div>
<h2 id="typst-gather"><code>typst-gather</code>
</h2>
<p>Quarto 1.9 automatically stages Typst packages &mdash; from your extensions, from Quarto&rsquo;s bundled extensions, and from Quarto itself &mdash; into the <code>.quarto/</code> cache directory before calling <code>typst compile</code>. This means Typst documents render offline without needing network access.</p>
<p>To make this work, extension authors use the new 






<a href="https://quarto.org/docs/advanced/typst/typst-gather.html" target="_blank" rel="noopener"><code>typst-gather</code></a>
 tool, which scans their <code>.typ</code> files for <code>@preview</code> imports and downloads the packages into the extension directory. Authors run <code>quarto call typst-gather</code> and commit the results. Users of the extension will have the packages staged without any downloads.</p>
<p>This means 


  
  
  





<a href="https://quarto.org/docs/output-formats/typst-custom.html#custom-formats" target="_blank" rel="noopener">Custom Typst Formats</a>
 can depend on Typst packages without copying and pasting Typst code, making them simpler and easier to maintain.</p>
<p>Both Typst books and article layout are built on <code>typst-gather</code> &mdash; orange-book depends on the Typst 






<a href="https://typst.app/universe/package/orange-book" target="_blank" rel="noopener">orange-book</a>
 package, and article layout depends on 






<a href="https://typst.app/universe/package/marginalia/" target="_blank" rel="noopener">Marginalia</a>
. As the Typst package ecosystem grows, we&rsquo;re excited to see what the community builds with Typst packages.</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/typst-article-landscape.png" length="409281" type="image/png" />
    </item>
    <item>
      <title>Quarto 1.9</title>
      <link>https://opensource.posit.co/blog/2026-03-24_1.9-release/</link>
      <pubDate>Tue, 24 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2026-03-24_1.9-release/</guid>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<p>Quarto 1.9 is out! You can get the current release from the 






<a href="https://quarto.org/docs/download/index.html" target="_blank" rel="noopener">download page</a>
.</p>
<p>Sharing your work just got easier with integrated Posit Connect Cloud publishing. Typst users will appreciate book project support and article layouts, while experimental PDF accessibility standards bring PDF/A and PDF/UA compliance to both LaTeX and Typst. This release also introduces LLM-friendly output for websites, the <code>quarto use brand</code> command for keeping your brand assets in sync, and list tables for authoring complex tables with familiar bullet syntax.</p>
<p>You can read about these improvements and some other highlights below. You can find all the changes in this version in the 






<a href="https://quarto.org/docs/download/changelog/1.9/" target="_blank" rel="noopener">Release Notes</a>
.</p>
<h2 id="publish-to-posit-connect-cloud">Publish to Posit Connect Cloud
</h2>
<p>You can now publish documents and websites to 






<a href="https://connect.posit.cloud" target="_blank" rel="noopener">Posit Connect Cloud</a>
 directly from the command line.
For example, publish your Quarto website project with:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto publish posit-connect-cloud</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Posit Connect Cloud is a hosted platform for sharing data applications and documents without managing your own infrastructure. It includes a free tier for unlimited static document publishing.
Read more in 






<a href="https://quarto.org/docs/publishing/posit-connect-cloud.html" target="_blank" rel="noopener">Publishing &gt; Posit Connect Cloud</a>
.</p>
<h2 id="improvements-to-typst-support">Improvements to Typst Support
</h2>
<p>Quarto 1.9 brings substantial improvements to Typst output:</p>
<ul>
<li>


  
  
  





<a href="https://quarto.org/docs/books/book-output.html#typst-output" target="_blank" rel="noopener">Book projects</a>
 can now render to Typst via the bundled <code>orange-book</code> extension, with chapter numbering, cross-references, and professional textbook styling.</li>
<li>






<a href="https://quarto.org/docs/authoring/article-layout.html" target="_blank" rel="noopener">Article layout</a>
 support lets you place content in the margins, create full-width figures, or add side notes.</li>
<li>New options: <code>mathfont</code>, <code>codefont</code>, <code>linestretch</code>, <code>linkcolor</code>, <code>citecolor</code>, <code>filecolor</code>, <code>thanks</code>, and <code>abstract-title</code>.</li>
<li>


  
  
  





<a href="https://quarto.org/docs/output-formats/typst.html#theorems" target="_blank" rel="noopener">Theorem styling</a>
 with four appearance options: <code>simple</code>, <code>fancy</code>, <code>clouds</code>, or <code>rainbow</code>.</li>
</ul>
<p>See 





  


  
  
    
  

<a href="https://opensource.posit.co/blog/2026-03-31_typst-books-and-more/">this blog post</a>
 for details on all the Typst improvements.</p>
<h2 id="pdf-accessibility-experimental">PDF Accessibility (Experimental)
</h2>
<p>We&rsquo;re rolling out experimental support for PDF accessibility standards in 1.9. The new <code>pdf-standard</code> option enables PDF/A archival formats and PDF/UA accessibility compliance for both LaTeX and Typst outputs. Alt text from <code>fig-alt</code> attributes now passes through to PDF for screen reader support, and Typst gains support for alt text on cross-referenced equations.</p>
<p>Read more in our 





  


  
  
    
  

<a href="https://opensource.posit.co/blog/2026-03-05_pdf-accessibility-and-standards/">PDF Accessibility and Standards blog post</a>
 or the documentation for 


  
  
  





<a href="https://quarto.org/docs/output-formats/pdf-basics.html#pdf-accessibility-standards" target="_blank" rel="noopener">LaTeX</a>
 and 


  
  
  





<a href="https://quarto.org/docs/output-formats/typst.html#pdf-accessibility-standards" target="_blank" rel="noopener">Typst</a>
.</p>
<h2 id="output-for-llms">Output for LLMs
</h2>
<p>Quarto can now generate 






<a href="https://llmstxt.org/" target="_blank" rel="noopener">llms.txt</a>
 format output for your website, making your content more accessible to large language models and AI-powered tools.</p>
<p>Enable it in your website configuration:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">_quarto.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">website</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;My Documentation&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">llms-txt</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>When you render your site, Quarto creates:</p>
<ul>
<li>An <code>llms.txt</code> index file at the root of your site listing all pages</li>
<li>A <code>.llms.md</code> markdown file alongside each HTML page (e.g., <code>guide.html</code> gets <code>guide.llms.md</code>)</li>
</ul>
<p>The markdown files contain clean versions of your content&mdash;navigation, sidebars, and scripts are stripped out; tables, code blocks, and callouts are converted to standard markdown.</p>
<p>Read more, including how to customize what appears in LLM output, in 






<a href="https://quarto.org/docs/websites/website-llms.html" target="_blank" rel="noopener">Websites &gt; Output for LLMs</a>
.</p>
<h2 id="quarto-use-brand-command"><code>quarto use brand</code> Command
</h2>
<p>Keep your project&rsquo;s brand assets in sync with an external source using the new <code>quarto use brand</code> command:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-2">
  <div class="code-with-filename-label" id="code-filename-2"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto use brand myorg/shared-brand</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>The command copies brand files from a GitHub repository, local directory, or zip archive into your project&rsquo;s <code>_brand/</code> directory. Quarto walks you through each step&mdash;confirming trust for remote sources, creating the directory if needed, and asking whether to overwrite or remove files.</p>
<p>See 


  
  
  





<a href="https://quarto.org/docs/authoring/brand.html#quarto-use-brand" target="_blank" rel="noopener">Guide &gt; Brand</a>
 for <code>--dry-run</code>, <code>--force</code>, and other options.</p>
<h2 id="list-tables">List Tables
</h2>
<p>List tables provide a new syntax for creating tables with complex content&mdash;multiple paragraphs, code blocks, or nested lists&mdash;using familiar bullet syntax instead of grid table formatting:</p>
<div class="grid gap-12 items-start md:grid-cols-2">
<div class="prose max-w-none">
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">::: {.list-table}
</span></span><span class="line"><span class="cl"><span class="k">-</span> - Function
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Description
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> - <span class="sb">`sum()`</span>
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Add values:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    ``<span class="sb">`python
</span></span></span><span class="line"><span class="cl"><span class="sb">    sum([1, 2, 3])
</span></span></span><span class="line"><span class="cl"><span class="sb">    `</span>`<span class="sb">`
</span></span></span><span class="line"><span class="cl"><span class="sb">
</span></span></span><span class="line"><span class="cl"><span class="sb">- - `</span>len()`
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Count items:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">-</span> Works on lists
</span></span><span class="line"><span class="cl">    <span class="k">-</span> Works on strings
</span></span><span class="line"><span class="cl">:::</span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
<div class="prose max-w-none">
<table>
<thead>
<tr>
<th>Function</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><p><code>sum()</code></p></td>
<td><p>Add values:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="bu">sum</span>([<span class="dv">1</span>, <span class="dv">2</span>, <span class="dv">3</span>])</span></code></pre></div></td>
</tr>
<tr>
<td><p><code>len()</code></p></td>
<td><p>Count items:</p>
<ul>
<li>Works on lists</li>
<li>Works on strings</li>
</ul></td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Each top-level bullet represents a row; nested bullets represent cells. This syntax is much easier to maintain than grid tables, especially when cells contain code or other block elements.</p>
<p>List tables support all the usual table features: captions, cross-references, column widths, and alignment. Thanks to Martin Fischer for the original development, with contributions from Albert Krewinkel and William Lupton.</p>
<p>Find all the details in 


  
  
  





<a href="https://quarto.org/docs/authoring/tables.html#list-tables" target="_blank" rel="noopener">Guide &gt; Tables</a>
.</p>
<h2 id="other-highlights">Other Highlights
</h2>
<ul>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/websites/website-search.html#search-result-highlighting" target="_blank" rel="noopener">Search Result Highlighting</a>
: Improved highlighting of search terms on destination pages, with persistent marks, automatic tab activation for matches inside tabsets, and cross-element highlighting for multi-word searches.</p>
</li>
<li>
<p>Privacy-focused features for websites:</p>
<ul>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/websites/website-tools.html#cookie-consent" target="_blank" rel="noopener">A privacy-first default for cookie consent</a>
: The default for cookie consent has changed to <code>type: express</code>, providing opt-in consent that blocks cookies until users explicitly agree. This privacy-conscious default is designed with modern privacy regulations in mind.</p>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/websites/website-search.html#cookie-consent-and-user-tracking" target="_blank" rel="noopener">Algolia Search Insights avoids cookies</a>
: Use Algolia Insights now uses persistent cookies only if <code>cookie-consent</code> is active, and the user has opted-in.</p>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/websites/website-tools.html#plausible-analytics" target="_blank" rel="noopener">Use Plausible Analytics</a>
: Add privacy-friendly Plausible Analytics to websites via the <code>plausible-analytics</code> configuration option.</p>
</li>
</ul>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/authoring/videos.html#accessibility-label" target="_blank" rel="noopener"><code>aria-label</code> for videos</a>
: Improve accessibility of embedded videos by providing custom descriptive labels for screen readers instead of the default &ldquo;Video Player&rdquo; label.</p>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/output-formats/pdf-basics.html#syntax-highlighting" target="_blank" rel="noopener">New <code>syntax-highlighting</code> Option</a>
: Replaces the deprecated <code>highlight-style</code> (Pandoc 3.8). Supports style names, custom <code>.theme</code> files, <code>none</code>, or <code>idiomatic</code> for format-native highlighting.</p>
</li>
<li>
<p>Metadata and brand extensions now work without a <code>_quarto.yml</code> project. A temporary default project is created in memory.</p>
</li>
<li>
<p>






<a href="https://quarto.org/docs/extensions/engine.html" target="_blank" rel="noopener">Engine extensions</a>
 allow replacement of the execution engine:</p>
<ul>
<li>Julia is now a bundled extension instead of being built-in.</li>
<li><strong>quarto-marimo</strong> will soon change from a filter extension to an engine extension.</li>
<li>New <code>quarto create extension engine</code> command.</li>
<li>New <code>quarto call build-ts-extension</code> command.</li>
<li>New <strong>Quarto API</strong> for engine extensions to use. (This is in flux and will not be documented for the next few releases, but 






<a href="https://quarto-dev.github.io/dev-notes/posts/2026-03-04/" target="_blank" rel="noopener">there is a dev blog post about it</a>
.)</li>
</ul>
</li>
</ul>
<p>Dependency updates:</p>
<ul>
<li><code>pandoc</code> updated to 3.8.3</li>
<li><code>typst</code> updated to 0.14.2</li>
<li><code>esbuild</code> updated to 0.25.10</li>
<li><code>deno</code> updated to 2.4.5</li>
<li><code>mermaid</code> updated to 11.12.0</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>One of the early proposals for PDF accessibility and alt text in the LaTeX ecosystem was provided to us by 






<a href="https://github.com/Schiano-NOAA" target="_blank" rel="noopener">Sam Schiano</a>
 and 






<a href="https://github.com/sbreitbart-NOAA" target="_blank" rel="noopener">Sophie Breitbart</a>
. We want to thank them for bringing into our attention the approach they used in their 






<a href="https://nmfs-ost.github.io/asar/" target="_blank" rel="noopener"><code>{asar}</code> R package</a>
, which influenced some of our design.</p>
<p>In addition, we&rsquo;d like to say a huge thank you to everyone who contributed to this release by opening issues and pull requests:</p>
<p>






<a href="https://github.com/CoryMcCartan" target="_blank" rel="noopener">CoryMcCartan</a>
,







<a href="https://github.com/DanChaltiel" target="_blank" rel="noopener">DanChaltiel</a>
,







<a href="https://github.com/Data-Wise" target="_blank" rel="noopener">Data-Wise</a>
,







<a href="https://github.com/FrankwaP" target="_blank" rel="noopener">FrankwaP</a>
,







<a href="https://github.com/Joao-O-Santos" target="_blank" rel="noopener">Joao-O-Santos</a>
,







<a href="https://github.com/LukasDSauer" target="_blank" rel="noopener">LukasDSauer</a>
,







<a href="https://github.com/MBe-iUS" target="_blank" rel="noopener">MBe-iUS</a>
,







<a href="https://github.com/MarcoPortmann" target="_blank" rel="noopener">MarcoPortmann</a>
,







<a href="https://github.com/MariaBarrioSchez" target="_blank" rel="noopener">MariaBarrioSchez</a>
,







<a href="https://github.com/MateusMolina" target="_blank" rel="noopener">MateusMolina</a>
,







<a href="https://github.com/Selbosh" target="_blank" rel="noopener">Selbosh</a>
,







<a href="https://github.com/ThePurox" target="_blank" rel="noopener">ThePurox</a>
,







<a href="https://github.com/TucoFernandes" target="_blank" rel="noopener">TucoFernandes</a>
,







<a href="https://github.com/aecoleman" target="_blank" rel="noopener">aecoleman</a>
,







<a href="https://github.com/amirhome61" target="_blank" rel="noopener">amirhome61</a>
,







<a href="https://github.com/andrewheiss" target="_blank" rel="noopener">andrewheiss</a>
,







<a href="https://github.com/azankl" target="_blank" rel="noopener">azankl</a>
,







<a href="https://github.com/bensoltoff" target="_blank" rel="noopener">bensoltoff</a>
,







<a href="https://github.com/bruvellu" target="_blank" rel="noopener">bruvellu</a>
,







<a href="https://github.com/byzheng" target="_blank" rel="noopener">byzheng</a>
,







<a href="https://github.com/cbrnr" target="_blank" rel="noopener">cbrnr</a>
,







<a href="https://github.com/chendaniely" target="_blank" rel="noopener">chendaniely</a>
,







<a href="https://github.com/chi-raag" target="_blank" rel="noopener">chi-raag</a>
,







<a href="https://github.com/christopherkenny" target="_blank" rel="noopener">christopherkenny</a>
,







<a href="https://github.com/coatless" target="_blank" rel="noopener">coatless</a>
,







<a href="https://github.com/cynthiahqy" target="_blank" rel="noopener">cynthiahqy</a>
,







<a href="https://github.com/darwindarak" target="_blank" rel="noopener">darwindarak</a>
,







<a href="https://github.com/davidskalinder" target="_blank" rel="noopener">davidskalinder</a>
,







<a href="https://github.com/dmenne" target="_blank" rel="noopener">dmenne</a>
,







<a href="https://github.com/fconil" target="_blank" rel="noopener">fconil</a>
,







<a href="https://github.com/fkgruber" target="_blank" rel="noopener">fkgruber</a>
,







<a href="https://github.com/fkohrt" target="_blank" rel="noopener">fkohrt</a>
,







<a href="https://github.com/fredguth" target="_blank" rel="noopener">fredguth</a>
,







<a href="https://github.com/gadenbuie" target="_blank" rel="noopener">gadenbuie</a>
,







<a href="https://github.com/apps/github-actions" target="_blank" rel="noopener">github-actions[bot]</a>
,







<a href="https://github.com/gsathler-vi" target="_blank" rel="noopener">gsathler-vi</a>
,







<a href="https://github.com/hamgamb" target="_blank" rel="noopener">hamgamb</a>
,







<a href="https://github.com/herosi" target="_blank" rel="noopener">herosi</a>
,







<a href="https://github.com/icarusz" target="_blank" rel="noopener">icarusz</a>
,







<a href="https://github.com/idavydov" target="_blank" rel="noopener">idavydov</a>
,







<a href="https://github.com/jeremy886" target="_blank" rel="noopener">jeremy886</a>
,







<a href="https://github.com/jkrumbiegel" target="_blank" rel="noopener">jkrumbiegel</a>
,







<a href="https://github.com/jmcphers" target="_blank" rel="noopener">jmcphers</a>
,







<a href="https://github.com/jonas37" target="_blank" rel="noopener">jonas37</a>
,







<a href="https://github.com/jorherre" target="_blank" rel="noopener">jorherre</a>
,







<a href="https://github.com/jreades" target="_blank" rel="noopener">jreades</a>
,







<a href="https://github.com/jromanowska" target="_blank" rel="noopener">jromanowska</a>
,







<a href="https://github.com/jtbayly" target="_blank" rel="noopener">jtbayly</a>
,







<a href="https://github.com/juleswg23" target="_blank" rel="noopener">juleswg23</a>
,







<a href="https://github.com/juliasilge" target="_blank" rel="noopener">juliasilge</a>
,







<a href="https://github.com/kathsherratt" target="_blank" rel="noopener">kathsherratt</a>
,







<a href="https://github.com/kusnezoff-alexander" target="_blank" rel="noopener">kusnezoff-alexander</a>
,







<a href="https://github.com/lrrichter" target="_blank" rel="noopener">lrrichter</a>
,







<a href="https://github.com/lwjohnst86" target="_blank" rel="noopener">lwjohnst86</a>
,







<a href="https://github.com/maelle" target="_blank" rel="noopener">maelle</a>
,







<a href="https://github.com/matthiasbaitsch" target="_blank" rel="noopener">matthiasbaitsch</a>
,







<a href="https://github.com/mipmip" target="_blank" rel="noopener">mipmip</a>
,







<a href="https://github.com/mstrms2000" target="_blank" rel="noopener">mstrms2000</a>
,







<a href="https://github.com/multimeric" target="_blank" rel="noopener">multimeric</a>
,







<a href="https://github.com/mvuorre" target="_blank" rel="noopener">mvuorre</a>
,







<a href="https://github.com/mykolaskrynnyk" target="_blank" rel="noopener">mykolaskrynnyk</a>
,







<a href="https://github.com/nichtich" target="_blank" rel="noopener">nichtich</a>
,







<a href="https://github.com/nithinmkp" target="_blank" rel="noopener">nithinmkp</a>
,







<a href="https://github.com/nrichers" target="_blank" rel="noopener">nrichers</a>
,







<a href="https://github.com/orbsmiv" target="_blank" rel="noopener">orbsmiv</a>
,







<a href="https://github.com/paytonej" target="_blank" rel="noopener">paytonej</a>
,







<a href="https://github.com/petrelharp" target="_blank" rel="noopener">petrelharp</a>
,







<a href="https://github.com/phongphuhanam" target="_blank" rel="noopener">phongphuhanam</a>
,







<a href="https://github.com/pm-gusmano" target="_blank" rel="noopener">pm-gusmano</a>
,







<a href="https://github.com/posit-snyk-bot" target="_blank" rel="noopener">posit-snyk-bot</a>
,







<a href="https://github.com/prosoitos" target="_blank" rel="noopener">prosoitos</a>
,







<a href="https://github.com/rabyj" target="_blank" rel="noopener">rabyj</a>
,







<a href="https://github.com/sasja-san" target="_blank" rel="noopener">sasja-san</a>
,







<a href="https://github.com/sbwiecko" target="_blank" rel="noopener">sbwiecko</a>
,







<a href="https://github.com/serialc" target="_blank" rel="noopener">serialc</a>
,







<a href="https://github.com/spaette" target="_blank" rel="noopener">spaette</a>
,







<a href="https://github.com/spraetor" target="_blank" rel="noopener">spraetor</a>
,







<a href="https://github.com/stragu" target="_blank" rel="noopener">stragu</a>
,







<a href="https://github.com/szimmer" target="_blank" rel="noopener">szimmer</a>
,







<a href="https://github.com/the-solipsist" target="_blank" rel="noopener">the-solipsist</a>
,







<a href="https://github.com/thomasp85" target="_blank" rel="noopener">thomasp85</a>
,







<a href="https://github.com/yyzeng" target="_blank" rel="noopener">yyzeng</a>
,







<a href="https://github.com/zhe00a" target="_blank" rel="noopener">zhe00a</a>
.</p>
<p>The airplane departure emoji in the 






<a href="thumbnail.png">listing and social card image</a>
 for this post comes from <a href="https://openmoji.org/" class="external">OpenMoji</a>&ndash; the open-source emoji and icon project. License: <a href="https://creativecommons.org/licenses/by-sa/4.0/#" class="external">CC BY-SA 4.0</a></p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2026-03-24_1.9-release/thumbnail.png" length="57935" type="image/png" />
    </item>
    <item>
      <title>PDF Accessibility and Standards</title>
      <link>https://opensource.posit.co/blog/2026-03-05_pdf-accessibility-and-standards/</link>
      <pubDate>Thu, 05 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2026-03-05_pdf-accessibility-and-standards/</guid>
      <dc:creator>Gordon Woodhull</dc:creator><description><![CDATA[<div class="callout callout-note" role="note" aria-label="Note">
<div class="callout-header">
<span class="callout-title">Pre-release Feature</span>
</div>
<div class="callout-body">
<p>This feature is new in the upcoming Quarto 1.9 release. To use the feature now, you&rsquo;ll need to 






<a href="https://quarto.org/docs/download/prerelease.html" target="_blank" rel="noopener">download and install</a>
 the Quarto pre-release.</p>
</div>
</div>
<p>2025 was a big year for PDF accessibility. LaTeX and Typst both released support for PDF tagging and accessibility standards, just in time for new regulations in the 






<a href="https://en.wikipedia.org/wiki/European_Accessibility_Act" target="_blank" rel="noopener">EU</a>
 (June 2025) and 






<a href="https://accessible.org/ada-title-ii-web-accessibility/" target="_blank" rel="noopener">US</a>
 (April 2026).</p>
<p>Quarto 1.9 brings this support to you as a Quarto user.</p>
<h2 id="what-pdf-standards-do">What PDF Standards Do
</h2>
<p>Currently LaTeX supports the newer UA-2 standard, and Typst supports the older UA-1 standard. Typst is likely to have UA-2 support later in 2026.</p>
<p>Both standards instruct the PDF renderer to provide screen readers:</p>
<ul>
<li>The semantic structure of the text (title, heading, paragraph, figure, etc)</li>
<li>The natural reading order</li>
<li>Spatial coordinates for highlighting and assistive navigation</li>
<li>Required metadata such as title and language</li>
</ul>
<h2 id="how-to-enable-a-pdf-standard-in-quarto">How to enable a PDF Standard in Quarto
</h2>
<p>In Quarto 1.9, specify a PDF standard for your document or project with <code>pdf-standard</code></p>
<div class="grid gap-12 items-start md:grid-cols-2">
<div class="prose max-w-none">
<p><strong>PDF (LaTeX)</strong></p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">pdf</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pdf-standard</span><span class="p">:</span><span class="w"> </span><span class="l">ua-2</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
<div class="prose max-w-none">
<p><strong>Typst</strong></p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">typst</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">pdf-standard</span><span class="p">:</span><span class="w"> </span><span class="l">ua-1</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
</div>
<p><code>pdf-standard</code> takes a single standard name or list of standard names. PDF version is used if provided in the list, but otherwise inferred from the standard.</p>
<p>If you specify a PDF standard, Quarto first instructs LaTeX or Typst to use the standard when producing the PDF, and then validates the output PDF against the standard using veraPDF, an open-source PDF validation tool. If veraPDF is not installed, you&rsquo;ll get a warning but still receive a PDF &ndash; it just won&rsquo;t be validated.</p>
<div class="callout callout-note" role="note" aria-label="Note">
<div class="callout-header">
<span class="callout-title">Installing veraPDF</span>
</div>
<div class="callout-body">
<p>To install veraPDF, you&rsquo;ll first need Java, then run:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-2">
  <div class="code-with-filename-label" id="code-filename-2"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto install verapdf</span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
</div>
<p>When a document passes validation, you&rsquo;ll see output like:</p>
<pre><code>[verapdf]: Validating my-document.pdf against PDF/UA-2... PASSED
</code></pre>
<h2 id="creating-accessible-pdfs">Creating accessible PDFs
</h2>
<p>Quarto&rsquo;s Markdown-based workflow handles many accessibility requirements automatically:</p>
<ul>
<li>Document metadata (title, author, date, language) flows into the PDF&rsquo;s built-in metadata fields.</li>
<li>The semantic structure of Markdown satisfies PDF tagging requirements. For Typst this is always enabled; for LaTeX it is enabled when you specify a standard that requires it.</li>
<li>Alt text for images is carried through to the PDF for screen readers.</li>
</ul>
<p>But you do need to make sure your document has:</p>
<ul>
<li>A <strong>title</strong> in the YAML front matter.</li>
<li><strong>Alt text for every image</strong>, specified with <code>fig-alt</code>. See 


  
  
  





<a href="https://quarto.org/docs/authoring/figures.html#alt-text" target="_blank" rel="noopener">Figures</a>
 for details.</li>
</ul>
<p>See the 


  
  
  





<a href="https://quarto.org/docs/output-formats/pdf-basics.html#accessibility-requirements" target="_blank" rel="noopener">LaTeX</a>
 and 


  
  
  





<a href="https://quarto.org/docs/output-formats/typst.html#accessibility-requirements" target="_blank" rel="noopener">Typst</a>
 documentation for more details.</p>
<h2 id="if-your-document-fails-validation">If your document fails validation
</h2>
<p>LaTeX does not perform validation during PDF generation, so if veraPDF validation fails, that&rsquo;s a warning, and you still get a partially-accessible PDF as long as you use <code>pdf-standard: ua-2</code>.</p>
<p>Typst fails and does not produce a PDF if its built-in validation fails during PDF generation. However, in Typst all accessibility features are on by default, so you can generate a partially-accessible PDF by rendering without <code>pdf-standard</code>.</p>
<h2 id="current-limitations">Current limitations
</h2>
<p>We ran our test suite &ndash; 188 LaTeX examples and 317 Typst examples &ndash; to find where Quarto PDFs do not yet pass UA-1 or UA-2, and where users will need to change their documents.</p>
<h3 id="latex">LaTeX
</h3>
<p>Margin content is the biggest structural blocker. If you use <code>.column-margin</code> divs, <code>cap-location: margin</code>, <code>reference-location: margin</code>, or <code>citation-location: margin</code>, the resulting PDF will not pass UA-2. The underlying <code>sidenotes</code> and <code>marginnote</code> LaTeX packages 






<a href="https://github.com/quarto-dev/quarto-cli/issues/14103" target="_blank" rel="noopener">do not cooperate with PDF tagging</a>
.</p>
<p>(Margin content does work with Typst and passes UA-1 &ndash; see 


  
  
  





<a href="https://quarto.org/docs/output-formats/typst.html#article-layout" target="_blank" rel="noopener">Typst Article Layout</a>
.)</p>
<p>There are smaller upstream issues in Pandoc, LaTeX, and LaTeX packages, 


  
  
  





<a href="https://github.com/quarto-dev/quarto-cli/pull/14097#issuecomment-3947653207" target="_blank" rel="noopener">documented here</a>
.</p>
<h3 id="typst">Typst
</h3>
<p>In our tests, Typst catches every UA-1 violation, and fails to generate the PDF. veraPDF did not detect any violation that Typst did not.</p>
<p>Typst also seems to do a very good job of generating UA-1 compliant output by default &ndash; almost all errors were due to missing titles or missing alt text.</p>
<p>However, we did discover that 


  
  
  





<a href="https://quarto.org/docs/books/book-output.html#typst-output" target="_blank" rel="noopener">Typst books</a>
 are not yet compliant. There is a 






<a href="https://github.com/flavio20002/typst-orange-template/issues/38" target="_blank" rel="noopener">structural problem with the Typst orange-book package</a>
 and we&rsquo;ll work with the maintainers to correct it.</p>
<h2 id="conclusion">Conclusion
</h2>
<p>Although Typst currently targets an the earlier UA-1 standard, today it seems to offer better PDF accessibility than LaTeX.</p>
<p>We expect PDF accessibility support to improve through the LaTeX ecosystem throughout 2026 as awareness of UA-2 and the new regulations spreads.</p>
<p>If you run into accessibility issues with PDF output, please search the 






<a href="https://github.com/orgs/quarto-dev/discussions" target="_blank" rel="noopener">Quarto discussions</a>
 and open a new one with the <code>accessibility</code> label for any issues you discover.</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2026-03-05_pdf-accessibility-and-standards/thumbnail.png" length="41719" type="image/png" />
    </item>
    <item>
      <title>posit::conf(2025) Quarto talks</title>
      <link>https://opensource.posit.co/blog/2025-11-24_conf-talk-videos/</link>
      <pubDate>Mon, 24 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-11-24_conf-talk-videos/</guid>
      <dc:creator>Andrew Holz</dc:creator><description><![CDATA[<p>The posit::conf(2025) session videos are now live! We&rsquo;ve created a curated playlist highlighting all the talks that showcase Quarto&mdash;how it is evolving, how people are using it, and how they&rsquo;re building on top of it.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=RnKN-0bM7C0bwXfQ&amp;list=PLitrm9UndxcvQgAigiiOofTEPAWpROiiK" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen>
</iframe>
<p>Talks included in the playlist, broken up into a few categories for easier browsing, are as follows:</p>
<h1 id="quarto-extensions--advanced-features">Quarto Extensions &amp; Advanced Features
</h1>
<table>
  <thead>
      <tr>
          <th>Speakers</th>
          <th>Title</th>
          <th>Thumbnail</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Carlos Scheidegger (Quarto Team)</strong></td>
          <td>What we&rsquo;re doing to make Quarto fast(er)</td>
          <td>






<a href="https://youtu.be/OBHppBRztO4" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/OBHppBRztO4/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Christophe Dervieux (Quarto Team)</strong></td>
          <td>Beyond the Basics: Expanding Quarto&rsquo;s Capabilities</td>
          <td>






<a href="https://youtu.be/u9ev3mvC-p0" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/u9ev3mvC-p0/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Garrick Aden-Buie</strong></td>
          <td>Theming Made Easy: Introducing brand.yml</td>
          <td>






<a href="https://youtu.be/DPaoNM8Ux04" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/DPaoNM8Ux04/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Gordon Woodhull (Quarto Team)</strong></td>
          <td>Brand YML and Dark Mode in Quarto</td>
          <td>






<a href="https://youtu.be/WNwsgS-klMA" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/WNwsgS-klMA/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>JooYoung Seo</strong></td>
          <td>maidr: Empowering Accessible, Multimodal Data Science with Quarto</td>
          <td>






<a href="https://youtu.be/QR7mdgM8Hf0" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/QR7mdgM8Hf0/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
  </tbody>
</table>
<h1 id="workflow-automation--reporting">Workflow Automation &amp; Reporting
</h1>
<table>
  <thead>
      <tr>
          <th>Speakers</th>
          <th>Title</th>
          <th>Thumbnail</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Becca Krouse</strong></td>
          <td>Instant Impact: Developing {docorator} to Simplify Document Production</td>
          <td>






<a href="https://youtu.be/SWt-lcnYlNM" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/SWt-lcnYlNM/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>John Paul Helveston</strong></td>
          <td>surveydown: A Markdown-Based Platform for Interactive Surveys</td>
          <td>






<a href="https://youtu.be/VwoeFKNvN5k" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/VwoeFKNvN5k/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Keaton Wilson</strong></td>
          <td>Using Quarto to Improve Formatting and Automation</td>
          <td>






<a href="https://youtu.be/vHrI17AeYGs" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/vHrI17AeYGs/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
  </tbody>
</table>
<h1 id="teaching--education">Teaching &amp; Education
</h1>
<table>
  <thead>
      <tr>
          <th>Speakers</th>
          <th>Title</th>
          <th>Thumbnail</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Claus Wilke</strong></td>
          <td>Teaching data visualization with R entirely in Quarto</td>
          <td>






<a href="https://youtu.be/Q7y0YqCuvHc" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/Q7y0YqCuvHc/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Mine Çetinkaya-Rundel (Quarto Team)</strong></td>
          <td>Leveraging LLMs for student feedback in introductory data science courses</td>
          <td>






<a href="https://youtu.be/5gS7AUGwZPs" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/5gS7AUGwZPs/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Ted Laderas</strong></td>
          <td>Empowering Learners with WebR, Pyodide, and Quarto</td>
          <td>






<a href="https://youtu.be/EQ9_MP2PYL8" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/EQ9_MP2PYL8/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
  </tbody>
</table>
<h1 id="business-collaboration--publishing">Business, Collaboration &amp; Publishing
</h1>
<table>
  <thead>
      <tr>
          <th>Speakers</th>
          <th>Title</th>
          <th>Thumbnail</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Andrew Heiss</strong> and <strong>Gabe Osterhout</strong></td>
          <td>Election Night Reporting Using R &amp; Quarto</td>
          <td>






<a href="https://youtu.be/UCloM4GcfVY" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/UCloM4GcfVY/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Bill Pikounis</strong></td>
          <td>Quarto for Business Collaboration and Technical Documentation in Word docx format</td>
          <td>






<a href="https://youtu.be/4-dQ2Q985A0" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/4-dQ2Q985A0/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
      <tr>
          <td><strong>Timothy Keyes</strong></td>
          <td>Trust, but Verify: Lessons from Deploying LLMs</td>
          <td>






<a href="https://youtu.be/HYQaZTLb2Co" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://img.youtube.com/vi/HYQaZTLb2Co/hqdefault.jpg"
      alt="thumb" 
      loading="lazy"
    >
  </figure></div>
</a>
</td>
      </tr>
  </tbody>
</table>
<div class="callout callout-tip" role="note" aria-label="Tip">
<div class="callout-header">
<span class="callout-title">Tip</span>
</div>
<div class="callout-body">
<p><strong>Workshop materials now available:</strong><br>
The Quarto team has published full materials from the two workshops at posit::conf 2025: &ldquo;Branded Websites, Presentations, Dashboards, and PDFs with Quarto&rdquo; and &ldquo;Extending Quarto&rdquo;.<br>
You can access the workshop websites, exercise source code, and full slide decks under a CC BY-SA 4.0 license from the 






  
  

<a href="https://opensource.posit.co/blog/2025-10-27_conf-workshops-materials/">Quarto blog</a>
.</p>
</div>
</div>
<p>We hope you enjoyed this look back at the Quarto sessions from posit::conf(2025). Every year the community brings new ideas, new tools, and new ways of working &mdash; and we&rsquo;d love to see <strong>your</strong> voice added to the mix. We hope to see you next year, and maybe even see <em>you</em> up on stage sharing your own work at posit::conf!</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-11-24_conf-talk-videos/thumbnail.png" length="221625" type="image/png" />
    </item>
    <item>
      <title>posit::conf(2025) Quarto workshop materials</title>
      <link>https://opensource.posit.co/blog/2025-10-27_conf-workshops-materials/</link>
      <pubDate>Mon, 27 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-10-27_conf-workshops-materials/</guid>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<p>At posit::conf(2025), we were thrilled to offer two comprehensive Quarto workshops designed to help users at different stages of their journey with Quarto. Whether you were looking to create beautifully branded outputs or extend Quarto&rsquo;s functionality with custom solutions, these workshops provided hands-on learning experiences with expert instructors.</p>
<p>All materials from both workshops are available online. You can access the full workshop websites, source code, and exercises to learn at your own pace or adapt them for your own teaching; they are both released with a 






<a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" rel="noopener">CC BY-SA 4.0</a>
 license.</p>
<h2 id="branded-websites-presentations-dashboards-and-pdfs-with-quarto">Branded Websites, Presentations, Dashboards, and PDFs with Quarto
</h2>
<p><a href="https://posit-conf-2025.github.io/quarto-brand/" class="rounded">Workshop website</a>
<a href="https://github.com/posit-conf-2025/quarto-brand/" class="rounded"><i></i> Source</a>
<a href="https://github.com/posit-dev/quarto-brand-exercises/" class="rounded"><i></i> Exercises</a></p>
<p>Led by 






<a href="https://ivelasq.rbind.io/" target="_blank" rel="noopener">Isabella Velásquez</a>
, Posit, PBC and 






<a href="https://www.linkedin.com/in/sarakaltman" target="_blank" rel="noopener">Sara Altman</a>
, Posit, PBC.</p>
<blockquote>
<p>Designed for data scientists, analysts, and content creators, this immersive session will teach you how to craft cohesive reports and presentations while refining your workflow with Quarto&rsquo;s latest features.</p>
<p>You will learn how to create dynamic websites, professional PDF documents, engaging presentations, and interactive dashboards using Quarto. This workshop highlights Quarto&rsquo;s powerful theming capabilities, including the new support for brand.yml, which ensures that your work maintains a professional and cohesive style across all formats.</p>
<p>By the end of the session, you&rsquo;ll be equipped to:</p>
<ul>
<li>Build and deploy Quarto websites.</li>
<li>Generate professional presentations and PDF reports.</li>
<li>Create interactive dashboards for data visualization and reporting.</li>
<li>Use brand.yml to define and apply consistent theming across all outputs.</li>
</ul>
<p>Whether you&rsquo;re looking to enhance your personal projects or streamline organizational outputs, this workshop will equip you with the tools to create polished, professional results.</p>
</blockquote>
<h2 id="extending-quarto">Extending Quarto
</h2>
<p><a href="https://posit-conf-2025.github.io/quarto-extend/" class="rounded">Workshop website</a>
<a href="https://github.com/posit-conf-2025/quarto-extend/" class="rounded"><i></i> Source</a>
<a href="https://github.com/posit-conf-2025/quarto-extend-exercises/" class="rounded"><i></i> Exercises</a></p>
<p>Led by 






<a href="https://mine-cr.com/" target="_blank" rel="noopener">Mine Çetinkaya-Rundel</a>
, Posit, PBC + Duke University and 






<a href="https://www.cwick.co.nz/" target="_blank" rel="noopener">Charlotte Wickham</a>
 Posit, PBC.</p>
<blockquote>
<p>In this workshop, we will dive deep into ways of customizing your Quarto
outputs with tooling beyond built-in features. This workshop is designed
for data scientists, analysts, and technical writers looking to extend
Quarto&rsquo;s capabilities to suit their unique workflows better.</p>
<p>Participants will learn how to create custom extensions, including new
formats, templates, and filters, to enhance their document production
process. Through hands-on exercises and real-world examples, you&rsquo;ll gain
practical skills in:</p>
<ul>
<li>Developing and integrating custom formats to support diverse outputs
while reducing repetition across projects.</li>
<li>Substituting Quarto&rsquo;s templates with your own to customize formats
beyond the built-in options.</li>
<li>Implementing filters to automate and streamline content
transformation.</li>
</ul>
<p>By the end of the workshop, you will be able to leverage Quarto&rsquo;s
extensibility to create powerful, tailored solutions for your
documentation needs. Whether you have just worked on a few Quarto
projects or are an everyday user, this workshop will equip you with the
tools and knowledge to take your document workflows to the next level.</p>
</blockquote>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-10-27_conf-workshops-materials/thumbnail.png" length="192305" type="image/png" />
    </item>
    <item>
      <title>Quarto Wizard 1.0.0: Democratising Quarto Extension Management</title>
      <link>https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/</link>
      <pubDate>Mon, 20 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/</guid>
      <dc:creator>Mickaël CANOUIL, _Ph.D._</dc:creator><description><![CDATA[<style>
.quarto-wizard {
   display: inline-block;
   aspect-ratio: 1 / 1;
   height: 1em;
   margin-bottom: -0.15em;
   mask-image: url('assets/media/quarto-wizard.svg');
   mask-size: contain;
   mask-repeat: no-repeat;
   mask-position: center;
   background-color: currentColor;
   vertical-align: baseline;
 }
 .hero-banner {
   border-radius: 1.5rem;
   box-shadow: 0 4px 24px #060c37;
   margin-bottom: 2rem;
 }
 </style>
<div class="callout callout-note" role="note" aria-label="Note">
<div class="callout-header">
<span class="callout-title">Community Contribution</span>
</div>
<div class="callout-body">
<p>The <span class="quarto-wizard" title="Quarto Wizard Logo" aria-label="Quarto Wizard Logo"></span> Quarto Wizard extension and listing directory website are built and maintained by 






<a href="https://mickael.canouil.fr" target="_blank" rel="noopener">Mickaël CANOUIL, <em>Ph.D.</em></a>
.</p>
<p>In this post, he explains what it is and how it can help you manage Quarto extensions directly from Positron or Visual Studio Code.</p>
</div>
</div>
<img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/featured.png" class="hero-banner" data-fig-align="center" data-fig-alt="Cartoon dog wizard wearing blue hat with red band holding magic wand creating HTML and CSS code scrolls in starry night scene." width="600" />
<p>I&rsquo;m absolutely thrilled to announce <strong><span class="quarto-wizard" title="Quarto Wizard Logo" aria-label="Quarto Wizard Logo"></span> Quarto Wizard 1.0.0</strong>, a groundbreaking extension for Visual Studio Code and Positron that transforms how you interact with the Quarto ecosystem.
If you&rsquo;ve ever found yourself wrestling with command-line extension management or struggling to discover the perfect template for your project, this tool is about to become your new best friend.</p>
<p>Install it today from the 






<a href="https://marketplace.visualstudio.com/items?itemName=mcanouil.quarto-wizard" target="_blank" rel="noopener">VS Code marketplace</a>
 or 






<a href="https://open-vsx.org/extension/mcanouil/quarto-wizard" target="_blank" rel="noopener">Open VSX Registry</a>
:</p>
<div class="grid gap-12 items-start md:grid-cols-2">
<div class="prose max-w-none">
<ul>
<li>
<p>Via VS Code or Positron Extensions view:</p>
<ul>
<li>Search for &ldquo;Quarto Wizard&rdquo;.</li>
<li>Click &ldquo;Install&rdquo;.</li>
</ul>
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/extensions-marketplace-light.png" title="Extensions View: Marketplace" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Visual Studio Code Extensions Marketplace showing Quarto Wizard search
results with install button.
" width="500" /></p>
</li>
</ul>
</div>
<div class="prose max-w-none">
<ul>
<li>
<p>Via the command line:</p>
<div class="panel-tabset">
<ul id="tabset-1" class="panel-tabset-tabby">
<li><a data-tabby-default href="#tabset-1-1">Visual Studio Code</a></li>
<li><a href="#tabset-1-2">Positron</a></li>
</ul>
<div id="tabset-1-1">
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">code --install-extension mcanouil.quarto-wizard</span></span></code></pre></td></tr></table>
</div>
</div></div>
<div class="callout callout-tip" role="note" aria-label="Tip">
<div class="callout-header">
<span class="callout-title">Tip</span>
</div>
<div class="callout-body">
<p>Be sure to execute the command <em>Shell Command: Install &lsquo;code&rsquo; command in PATH</em> from Visual Studio Code&rsquo;s Command Palette (<code>Cmd-Shift-P</code> (mac), <code>Ctrl-Shift-P</code> (linux), <code>Ctrl-Shift-P</code> (windows)) if you haven&rsquo;t done so already.</p>
</div>
</div>
</div>
<div id="tabset-1-2">
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">positron --install-extension mcanouil.quarto-wizard</span></span></code></pre></td></tr></table>
</div>
</div></div>
<div class="callout callout-tip" role="note" aria-label="Tip">
<div class="callout-header">
<span class="callout-title">Tip</span>
</div>
<div class="callout-body">
<p>Be sure to execute the command <em>Shell Command: Install &lsquo;positron&rsquo; command in PATH</em> from Positron&rsquo;s Command Palette (<code>Cmd-Shift-P</code> (mac), <code>Ctrl-Shift-P</code> (linux), <code>Ctrl-Shift-P</code> (windows)) if you haven&rsquo;t done so already.</p>
</div>
</div>
</div>
</div>
</li>
</ul>
</div>
</div>
<p>Quarto has revolutionised scientific and technical publishing by enabling reproducible documents that seamlessly blend code, narrative text, and visualisation.
However, one persistent friction point has been managing the rich and ever-growing ecosystem of extensions and templates&mdash;until now.</p>
<h2 id="quarto-wizard-your-gui-for-quarto-extensions"><span class="quarto-wizard" title="Quarto Wizard Logo" aria-label="Quarto Wizard Logo"></span> Quarto Wizard: Your GUI for Quarto extensions
</h2>
<p>I designed <strong>Quarto Wizard</strong> to address a fundamental challenge I&rsquo;ve observed in the community: whilst Quarto&rsquo;s command-line interface is powerful, many users prefer visual interfaces for discovering, installing, and managing extensions.</p>
<h3 id="seamless-ide-integration">Seamless IDE integration
</h3>
<p><strong>Quarto Wizard integrates beautifully with both the VS Code and Positron ecosystems</strong>, appearing as a dedicated icon in the Activity Bar alongside your other development tools.
This provides instant access to extension management without disrupting your coding flow, whether you&rsquo;re in Microsoft&rsquo;s VS Code or Posit&rsquo;s new Positron IDE.</p>
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/vscode-activity-bar-light.png" title="Quarto Wizard Explorer View (Light)" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Quarto Wizard Extensions Installed panel in Visual Studio Code showing
no extensions installed message with green Install Extensions button.
" width="500" /></p>
<p>The solution is <strong>multi-modal installation</strong>: you can now install extensions through multiple pathways that suit your workflow: from the command line, through the web directory, or via the <strong>Quarto Wizard</strong> GUI in your IDE.</p>
<div class="grid gap-12 items-center md:grid-cols-2">
<div class="prose max-w-none">
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/vscode-install-light.png" title="Quarto Wizard: Install Extensions (Light)" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Quarto Wizard extension selection dialog showing list of available
extensions with checkboxes including LIVE, HIGHLIGHT TEXT, GITHUB, and
other Quarto extensions.
" width="500" /></p>
</div>
</div>
<h3 id="intelligent-extension-management">Intelligent extension management
</h3>
<p>The <strong>&ldquo;Recently Installed Extensions&rdquo;</strong> feature helps track your workflow and easily reproduce project setups across different environments.
This is invaluable for researchers collaborating across multiple machines or teaching workshops where consistent setups are essential, regardless of whether team members use VS Code or Positron.</p>
<p>What makes this particularly powerful is that <strong>Quarto Wizard</strong> tracks which extensions were installed through its interface by adding <code>source</code> metadata to the <code>_extensions.yml</code> file, enabling seamless updates and removals.<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>
This source tracking transforms extension maintenance from manual archaeology into an effortless workflow.
The extension maintains detailed metadata about installed extensions, enabling batch operations and dependency tracking.
The Explorer View provides a comprehensive overview of all installed extensions with visual indicators for updates and management options.</p>
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/vscode-update-light.png" title="Quarto Wizard: Explorer View Update (Light)" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Quarto Wizard Extensions Installed panel showing expanded iconify
extension details with update button and version information.
" width="500" /></p>
<h3 id="template-workflow-simplified">Template workflow simplified
</h3>
<p>Beyond extension management, I&rsquo;ve designed <strong>Quarto Wizard</strong> to ease the process of discovering and using document templates.
Once you&rsquo;ve selected a template, <strong>Quarto Wizard</strong> lets you customise and save the document.
The file is not created until you confirm, allowing you to adjust the filename and location.</p>
<div class="grid gap-12 items-center md:grid-cols-2">
<div class="prose max-w-none">
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/vscode-template-light.png" title="Quarto Wizard: Use Template (Light)" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Visual Studio Code showing Quarto Wizard with installed extensions list
and document editor displaying invoice template with YAML frontmatter.
" width="500" /></p>
</div>
</div>
<h2 id="powered-by-a-comprehensive-extension-directory">Powered by a comprehensive extension directory
</h2>
<h3 id="a-curated-catalogue-of-250-extensions">A curated catalogue of 250+ extensions
</h3>
<p>At the heart of <strong>Quarto Wizard</strong> lies the 






<a href="https://m.canouil.dev/quarto-extensions/" target="_blank" rel="noopener">Quarto Extensions directory (m.canouil.dev/quarto-extensions/)</a>
, a comprehensive listing I maintain that catalogues extensions from across the entire Quarto ecosystem.</p>
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/quarto-extensions-home-light.png" title="Mickaël CANOUIL&#39;s Quarto Extensions directory" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Quarto Extensions website displaying grid of extension cards including
webr, Reveal.js Clean theme, and Hikmah Academic templates.
" width="500" /></p>
<p>To date, it includes over 250 extensions contributed by the community, covering a vast array of functionalities from citation management to interactive visualisations.
This directory powers <strong>Quarto Wizard</strong>&rsquo;s discovery features, providing rich metadata about each extension including descriptions, licensing, version tags, and GitHub stars.
The directory is continuously updated through GitHub&rsquo;s API, ensuring you always have access to the latest extensions from the community.</p>
<h3 id="one-click-installation-from-the-web">One-click installation from the web
</h3>
<p>What&rsquo;s particularly exciting is that you can install extensions or use templates <strong>directly from the website itself</strong>.
Each extension listed at 






<a href="https://m.canouil.dev/quarto-extensions/" target="_blank" rel="noopener">m.canouil.dev/quarto-extensions/</a>
 includes multiple installation options: traditional command-line via terminal, or one-click installation through <strong>Quarto Wizard</strong> in VS Code, Positron, or VSCodium.
Simply browse the directory, find the extension you need, and choose your preferred installation method.
The website generates the appropriate commands or launches your IDE directly.
This flexibility means teams with mixed technical backgrounds can all access the same powerful extensions.</p>
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/quarto-extensions-modal-light.png" title="Mickaël CANOUIL&#39;s Quarto Extensions install modal" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Quarto Extensions website with Install Options popup showing manual
terminal command and Quarto Wizard installation options for Visual
Studio Code, Positron, and VSCodium.
" width="500" /></p>
<p>For example, you might want to add the 






<a href="https://github.com/mcanouil/quarto-iconify" target="_blank" rel="noopener"><strong>Iconify</strong></a>
 extension to access over 200,000 open source vector icons in your documents, or the 






<a href="https://github.com/mcanouil/quarto-animate" target="_blank" rel="noopener"><strong>Animate</strong></a>
 extension to bring your presentations to life with CSS animations.
Perhaps the 






<a href="https://github.com/mcanouil/quarto-spotlight" target="_blank" rel="noopener"><strong>Spotlight</strong></a>
 extension for Reveal.js catches your eye for creating dramatic Reveal.js presentations that highlight your mouse position.
All of these extensions (and hundreds more) are just a click away.</p>
<h3 id="template-discovery-made-easy">Template discovery made easy
</h3>
<p>Additionally, the Quarto Extensions directory excels at <strong>template discovery and deployment</strong> which is enhanced with powerful filtering options: you can sort by recently updated, filter by popularity, browse by categories (<em>i.e.</em>, Shortcodes, Filters, Formats, Projects, Reveal.js Plugins), or search for specific functionality.
Each extension clearly indicates whether it&rsquo;s a template with <strong>&ldquo;Use&rdquo;</strong> buttons alongside <strong>&ldquo;Install&rdquo;</strong> options.</p>
<p><img src="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/assets/media/quarto-extensions-template-light.png" title="Mickaël CANOUIL&#39;s Quarto Extensions list view filtered by formats" class="light-content img-thumbnail rounded-3 border-light" data-fig-align="center" data-group="quarto-wizard-light" data-fig-alt="Quarto Extensions website in list view showing Template extensions with
install and use buttons.
" width="500" /></p>
<p>Whether you&rsquo;re crafting an academic paper using journal-specific formats, creating professional invoices with my 






<a href="https://github.com/mcanouil/quarto-invoice" target="_blank" rel="noopener"><strong>Invoice</strong></a>
 extension template, or building stunning presentations with themed templates like my 






<a href="https://github.com/mcanouil/quarto-revealjs-coeos" target="_blank" rel="noopener"><strong>Reveal.js Coeos</strong></a>
 extension, browsing available templates becomes as simple as scrolling through a curated gallery.</p>
<p>This directory creates a seamless experience: instead of manually searching GitHub repositories or memorising command-line syntax, you can browse hundreds of extensions with detailed information at your fingertips.
This transforms extension discovery from a treasure hunt into a curated shopping experience.</p>
<h2 id="addressing-real-workflow-friction">Addressing real workflow friction
</h2>
<p>I designed <strong>Quarto Wizard</strong> and the extension directory at 






<a href="https://m.canouil.dev/quarto-extensions/" target="_blank" rel="noopener">m.canouil.dev/quarto-extensions</a>
 to directly tackle several persistent Quarto pain points I&rsquo;ve encountered:</p>
<ul>
<li>
<p><strong>Discovery challenges</strong>: Finding relevant extensions in the growing ecosystem becomes intuitive through the visual browser interface powered by the comprehensive extensions directory.</p>
</li>
<li>
<p><strong>Command-line intimidation</strong>: Users who prefer graphical interfaces no longer need to memorise terminal commands.</p>
</li>
<li>
<p><strong>Document setup complexity</strong>: Template-based document initialisation eliminates manual YAML configuration.</p>
</li>
<li>
<p><strong>Extension maintenance</strong>: Updates, removals, and dependency management become point-and-click operations rather than command-line archaeology.</p>
</li>
<li>
<p><strong>Source tracking</strong>: <strong>Quarto Wizard</strong> automatically adds source metadata to installed extensions, enabling future updates and proper version management.</p>
</li>
<li>
<p><strong>Stable installations</strong>: <strong>Quarto Wizard</strong> installs extensions from GitHub releases/tags by default instead of the potentially unstable default branch, ensuring more reliable installations and more replicable environments.</p>
</li>
</ul>
<h2 id="perfect-for-diverse-use-cases">Perfect for diverse use cases
</h2>
<p>The extension shines across multiple scenarios:</p>
<ul>
<li>
<p><strong>Academic researchers</strong> can quickly install citation management tools, bibliography extensions like 






<a href="https://github.com/pandoc-ext/multibib" target="_blank" rel="noopener"><strong>Multibib</strong></a>
 or 






<a href="https://github.com/pandoc-ext/section-bibliographies" target="_blank" rel="noopener"><strong>Section Bibliographies</strong></a>
, and journal-specific formatting, whether they&rsquo;re using VS Code or Positron for their analysis work.</p>
</li>
<li>
<p><strong>Data scientists</strong> gain easy access to computational extensions like 






<a href="https://github.com/coatless/quarto-webr" target="_blank" rel="noopener"><strong>WebR</strong></a>
, visualisation tools, and interactive notebook capabilities.
This is particularly powerful in Positron, which is designed specifically for data science workflows.</p>
</li>
<li>
<p><strong>Technical writers</strong> can browse and install extensions for enhanced typography with for example the 






<a href="https://github.com/mcanouil/quarto-highlight-text" target="_blank" rel="noopener"><strong>Highlight Text</strong></a>
 extension for multi-format text highlighting, code highlighting, and advanced formatting options of their Reveal.js presentations with 






<a href="https://github.com/EmilHvitfeldt/quarto-revealjs-editable" target="_blank" rel="noopener"><strong>Reveal.js Editable</strong></a>
 extension in their preferred IDE.</p>
</li>
<li>
<p><strong>Workshop instructors</strong> can ensure all participants have consistent extension setups through guided installation processes, regardless of whether attendees prefer VS Code or Positron.</p>
</li>
</ul>
<h2 id="future-ready-architecture">Future-ready architecture
</h2>
<p>I&rsquo;ve built <strong>Quarto Wizard</strong> on robust foundations that ensure long-term reliability.
The extension integrates with GitHub&rsquo;s API through the 






<a href="https://m.canouil.dev/quarto-extensions/" target="_blank" rel="noopener">Quarto Extensions directory</a>
 for real-time metadata, includes attestation verification for security, and maintains full compatibility with both VS Code and Positron environments.</p>
<p>The modular architecture allows for future enhancements whilst maintaining backwards compatibility.
As the Quarto ecosystem continues expanding and as Positron evolves alongside VS Code, <strong>Quarto Wizard</strong> will support new extension types and project management workflows in both environments.</p>
<h2 id="getting-started-today">Getting started today
</h2>
<p>Begin your <strong>Quarto Wizard</strong> journey by installing the extension from the VS Code marketplace, the Open VSX Registry, or directly through your IDE&rsquo;s Extensions view.
Once installed, the <strong>Quarto Wizard</strong> icon appears in your Activity Bar, providing immediate access to extension management and project tools.</p>
<p>You have multiple paths to explore Quarto extensions:</p>
<ol>
<li><strong>Through Quarto Wizard</strong>: Click the <strong>Quarto Wizard</strong> icon in your IDE&rsquo;s Activity Bar and browse the integrated catalogue.</li>
<li><strong>Via the web directory</strong>: Visit 






<a href="https://m.canouil.dev/quarto-extensions/" target="_blank" rel="noopener">m.canouil.dev/quarto-extensions</a>
 where you can browse all extensions and install them directly from the website.
Each extension offers installation buttons for <strong>Quarto Wizard</strong>, VS Code, Positron, VSCodium, or traditional terminal commands.</li>
<li><strong>Traditional command-line</strong>: Use the familiar <code>quarto add</code> commands if you prefer.</li>
</ol>
<p>Try installing your first extension: perhaps 






<a href="https://github.com/mcanouil/quarto-iconify" target="_blank" rel="noopener"><strong>Iconify</strong></a>
 extension for comprehensive icon support or 






<a href="https://github.com/mcanouil/quarto-github" target="_blank" rel="noopener"><strong>GitHub</strong></a>
 for seamless GitHub linking.
Whether you click &ldquo;Install&rdquo; on the website, use <strong>Quarto Wizard</strong>&rsquo;s interface, or type commands in the terminal, the choice is yours.
The difference in experience compared to traditional command-line installation is immediately apparent, especially when browsing the visual catalogue with its filtering options, popularity indicators, and rich metadata.</p>
<p>I believe <strong>Quarto Wizard</strong> represents a significant step forward in making Quarto&rsquo;s powerful publishing capabilities accessible to users regardless of their comfort level with command-line tools or their choice of IDE.
By providing intuitive visual interfaces for complex operations, <strong>Quarto Wizard</strong> democratises access to the rich Quarto ecosystem whilst maintaining the flexibility and power that makes Quarto exceptional.</p>
<p>The future of reproducible publishing is here, and it&rsquo;s more accessible than ever in whichever modern development environment you prefer.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Quarto CLI does not natively track installation sources as of version 1.8.24 (






<a href="https://github.com/quarto-dev/quarto-cli/issues/11468" target="_blank" rel="noopener">quarto-dev/quarto-cli#11468</a>
).&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-10-20_quarto-wizard-1-0-0/featured.png" length="2512689" type="image/png" />
    </item>
    <item>
      <title>Quarto 1.8</title>
      <link>https://opensource.posit.co/blog/2025-10-13_1.8-release/</link>
      <pubDate>Mon, 13 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-10-13_1.8-release/</guid>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<p>Quarto 1.8 is available! You can get the current release from the 






<a href="https://quarto.org/docs/download/index.html" target="_blank" rel="noopener">download page</a>
.</p>
<p>Quarto 1.8 improves support for light and dark brand colors and logos, brand extensions for sharing brands across Quarto projects, HTML accessibility checks powered by Axe-core, and access to more information about execution context from your code cells.
You can read about these improvements and some other highlights below. You can find all the changes in this version in the 






<a href="https://quarto.org/docs/download/changelog/1.8/" target="_blank" rel="noopener">Release Notes</a>
.</p>
<h2 id="dark-and-light-colors-and-logos-in-brand">Dark and light colors and logos in brand
</h2>
<p>You can now specify <code>light</code> and <code>dark</code> versions of any colors or logo in a brand specification:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">_brand.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">color</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">foreground</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">light</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#333333&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">dark</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#EEEEEE&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">background</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">light</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#EEEEEE&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">dark</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#333333&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">logos</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">medium</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">light</span><span class="p">:</span><span class="w"> </span><span class="l">logo.png</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">dark</span><span class="p">:</span><span class="w"> </span><span class="l">logo-white.png         </span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This works in <code>_brand.yml</code> files as well as <code>brand</code> specified directly in document metadata.
You can also present in dark mode by specifying <code>brand-mode: dark</code> in your <code>format: revealjs</code> presentations.</p>
<p>Read more in the updated 






<a href="https://quarto.org/docs/authoring/brand.html" target="_blank" rel="noopener">Guide &gt; Brand</a>
:</p>
<ul>
<li>


  
  
  





<a href="https://quarto.org/docs/authoring/brand.html#light-and-dark-colors" target="_blank" rel="noopener">Light and dark colors</a>
</li>
<li>


  
  
  





<a href="https://quarto.org/docs/authoring/brand.html#light-and-dark-logos" target="_blank" rel="noopener">Light and dark logos</a>
</li>
<li>


  
  
  





<a href="https://quarto.org/docs/authoring/brand.html#brand-mode" target="_blank" rel="noopener">Brand mode</a>
</li>
</ul>
<h2 id="brand-extensions">Brand extensions
</h2>
<p>Share brand definitions and assets across Quarto projects with a brand extension.</p>
<p>Get started with:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">Terminal</span></div><pre tabindex="0"><code class="language-default" data-lang="default">quarto create extension brand</code></pre></div>
<p>Read more in 






<a href="https://quarto.org/docs/extensions/brand.html" target="_blank" rel="noopener">Extensions &gt; Brand</a>
, and keep an eye out for other ways to reuse and share your brand in future releases.</p>
<h2 id="accessibility-checks-for-html">Accessibility checks for HTML
</h2>
<p>You can add accessibility checks using the 






<a href="https://github.com/dequelabs/axe-core" target="_blank" rel="noopener">Axe-core engine</a>
 to HTML documents (<code>format</code>: <code>html</code>, <code>revealjs</code> and <code>dashboard</code>) with the new <code>axe</code> option.</p>
<p>For example, you can get a summary of violations right in your document preview:</p>
<figure>
<img src="https://quarto.org/docs/output-formats/images/axe-violation.png" class="border" data-fig-alt="A webpage with a box in the bottom left that warns &#39;Serious: Ensure the contrast between foreground and background colors meets WCAG 2 AA minimum contrast ratio thresholds&#39;." alt="A rendered webpage with an accessibility violation warning" />
<figcaption aria-hidden="true">A rendered webpage with an accessibility violation warning</figcaption>
</figure>
<p>Read about your options in 






<a href="https://quarto.org/docs/output-formats/html-accessibility.html" target="_blank" rel="noopener">HTML Accessibility Checks</a>
</p>
<p>We know accessability is a big concern for many of our users, and more improvements will be coming in future releases.</p>
<h2 id="accessing-execution-information">Accessing execution information
</h2>
<p>Quarto sets the <code>QUARTO_EXECUTE_INFO</code> environment variable, which allows you to access information about execution context from code cells.</p>
<p>Read the JSON file located at <code>QUARTO_EXECUTE_INFO</code> and access properties such as <code>document-path</code>, <code>format</code>, <code>metadata</code> and more:</p>
<div class="panel-tabset">
<ul id="tabset-1" class="panel-tabset-tabby">
<li><a data-tabby-default href="#tabset-1-1">R</a></li>
<li><a href="#tabset-1-2">Python</a></li>
<li><a href="#tabset-1-3">Julia</a></li>
</ul>
<div id="tabset-1-1">
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">library</span><span class="p">(</span><span class="n">jsonlite</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">execute_info</span> <span class="o">&lt;-</span> <span class="nf">read_json</span><span class="p">(</span><span class="nf">Sys.getenv</span><span class="p">(</span><span class="s">&#34;QUARTO_EXECUTE_INFO&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">execute_info</span><span class="o">$</span><span class="n">`document-path`</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
<div id="tabset-1-2">
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">json</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">os</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">getenv</span><span class="p">(</span><span class="s2">&#34;QUARTO_EXECUTE_INFO&#34;</span><span class="p">))</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">execute_info</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">execute_info</span><span class="p">[</span><span class="s2">&#34;document-path&#34;</span><span class="p">]</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
<div id="tabset-1-3">
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-julia" data-lang="julia"><span class="line"><span class="cl"><span class="k">using</span> <span class="n">JSON</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">execute_info</span> <span class="o">=</span> <span class="n">JSON</span><span class="o">.</span><span class="n">parsefile</span><span class="p">(</span><span class="nb">ENV</span><span class="p">[</span><span class="s">&#34;QUARTO_EXECUTE_INFO&#34;</span><span class="p">])</span>
</span></span><span class="line"><span class="cl"><span class="n">execute_info</span><span class="p">[</span><span class="s">&#34;document-path&#34;</span><span class="p">]</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
</div>
<p>Read more in 






<a href="https://quarto.org/docs/advanced/quarto-execute-info.html" target="_blank" rel="noopener">Access execution settings from code cells</a>
.</p>
<h2 id="other-highlights">Other Highlights
</h2>
<ul>
<li>
<p>Access 


  
  
  





<a href="https://quarto.org/docs/extensions/lua-api.html#metadata-access" target="_blank" rel="noopener">metadata</a>
 and 


  
  
  





<a href="https://quarto.org/docs/extensions/lua-api.html#variables-access" target="_blank" rel="noopener">variables</a>
 in filters and shortcodes: Use the new <code>quarto.variables.get()</code> and <code>quarto.metadata.get()</code> APIs.</p>
</li>
<li>
<p>The default LaTeX engine is now <code>lualatex</code>.</p>
</li>
</ul>
<p>Dependency updates:</p>
<ul>
<li><code>mermaidjs</code> updated to 11.6.0.</li>
<li>Bootstrap icons updated to v1.13.1</li>
<li><code>QuartoNotebookRunner</code> in <code>julia</code> engine updated to 0.17.3</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>We&rsquo;d like to say a huge thank you to everyone who contributed to this release by opening issues and pull requests:</p>
<p>






<a href="https://github.com/Aariq" target="_blank" rel="noopener">Aariq</a>
,







<a href="https://github.com/AndreasThinks" target="_blank" rel="noopener">AndreasThinks</a>
,







<a href="https://github.com/ArthurData" target="_blank" rel="noopener">ArthurData</a>
,







<a href="https://github.com/Blake-Madden" target="_blank" rel="noopener">Blake-Madden</a>
,







<a href="https://github.com/ColinFay" target="_blank" rel="noopener">ColinFay</a>
,







<a href="https://github.com/DCEW" target="_blank" rel="noopener">DCEW</a>
,







<a href="https://github.com/DanStuder" target="_blank" rel="noopener">DanStuder</a>
,







<a href="https://github.com/Data-Wise" target="_blank" rel="noopener">Data-Wise</a>
,







<a href="https://github.com/EllaKaye" target="_blank" rel="noopener">EllaKaye</a>
,







<a href="https://github.com/EmilHvitfeldt" target="_blank" rel="noopener">EmilHvitfeldt</a>
,







<a href="https://github.com/FrankwaP" target="_blank" rel="noopener">FrankwaP</a>
,







<a href="https://github.com/GabrielCoffee9" target="_blank" rel="noopener">GabrielCoffee9</a>
,







<a href="https://github.com/GeorgRamer" target="_blank" rel="noopener">GeorgRamer</a>
,







<a href="https://github.com/Gewerd-Strauss" target="_blank" rel="noopener">Gewerd-Strauss</a>
,







<a href="https://github.com/GuillaumeDehaene" target="_blank" rel="noopener">GuillaumeDehaene</a>
,







<a href="https://github.com/HarunCelikOtto" target="_blank" rel="noopener">HarunCelikOtto</a>
,







<a href="https://github.com/HayesJohnD" target="_blank" rel="noopener">HayesJohnD</a>
,







<a href="https://github.com/Joao-O-Santos" target="_blank" rel="noopener">Joao-O-Santos</a>
,







<a href="https://github.com/MateusMolina" target="_blank" rel="noopener">MateusMolina</a>
,







<a href="https://github.com/MichaelHatherly" target="_blank" rel="noopener">MichaelHatherly</a>
,







<a href="https://github.com/PeteArm" target="_blank" rel="noopener">PeteArm</a>
,







<a href="https://github.com/Selbosh" target="_blank" rel="noopener">Selbosh</a>
,







<a href="https://github.com/SergeCroise" target="_blank" rel="noopener">SergeCroise</a>
,







<a href="https://github.com/SrShelo" target="_blank" rel="noopener">SrShelo</a>
,







<a href="https://github.com/VisruthSK" target="_blank" rel="noopener">VisruthSK</a>
,







<a href="https://github.com/Vistales" target="_blank" rel="noopener">Vistales</a>
,







<a href="https://github.com/abhiaagarwal" target="_blank" rel="noopener">abhiaagarwal</a>
,







<a href="https://github.com/aborruso" target="_blank" rel="noopener">aborruso</a>
,







<a href="https://github.com/adamblake" target="_blank" rel="noopener">adamblake</a>
,







<a href="https://github.com/adamiturabi" target="_blank" rel="noopener">adamiturabi</a>
,







<a href="https://github.com/alastairrushworth" target="_blank" rel="noopener">alastairrushworth</a>
,







<a href="https://github.com/albertomercurio" target="_blank" rel="noopener">albertomercurio</a>
,







<a href="https://github.com/alecloudenback" target="_blank" rel="noopener">alecloudenback</a>
,







<a href="https://github.com/alex-r-bigelow" target="_blank" rel="noopener">alex-r-bigelow</a>
,







<a href="https://github.com/allefeld" target="_blank" rel="noopener">allefeld</a>
,







<a href="https://github.com/alyst" target="_blank" rel="noopener">alyst</a>
,







<a href="https://github.com/andrewheiss" target="_blank" rel="noopener">andrewheiss</a>
,







<a href="https://github.com/andrewpbray" target="_blank" rel="noopener">andrewpbray</a>
,







<a href="https://github.com/austin-hoover" target="_blank" rel="noopener">austin-hoover</a>
,







<a href="https://github.com/batpigandme" target="_blank" rel="noopener">batpigandme</a>
,







<a href="https://github.com/bauerj" target="_blank" rel="noopener">bauerj</a>
,







<a href="https://github.com/benkeks" target="_blank" rel="noopener">benkeks</a>
,







<a href="https://github.com/benz0li" target="_blank" rel="noopener">benz0li</a>
,







<a href="https://github.com/bkowshik" target="_blank" rel="noopener">bkowshik</a>
,







<a href="https://github.com/blackerby" target="_blank" rel="noopener">blackerby</a>
,







<a href="https://github.com/boshek" target="_blank" rel="noopener">boshek</a>
,







<a href="https://github.com/brandonmontez" target="_blank" rel="noopener">brandonmontez</a>
,







<a href="https://github.com/bryce-carson" target="_blank" rel="noopener">bryce-carson</a>
,







<a href="https://github.com/carschandler" target="_blank" rel="noopener">carschandler</a>
,







<a href="https://github.com/christopherkenny" target="_blank" rel="noopener">christopherkenny</a>
,







<a href="https://github.com/cl-roberts" target="_blank" rel="noopener">cl-roberts</a>
,







<a href="https://github.com/cmadland" target="_blank" rel="noopener">cmadland</a>
,







<a href="https://github.com/co1emi11er2" target="_blank" rel="noopener">co1emi11er2</a>
,







<a href="https://github.com/coatless" target="_blank" rel="noopener">coatless</a>
,







<a href="https://github.com/cpcloud" target="_blank" rel="noopener">cpcloud</a>
,







<a href="https://github.com/daxkellie" target="_blank" rel="noopener">daxkellie</a>
,







<a href="https://github.com/dixslyf" target="_blank" rel="noopener">dixslyf</a>
,







<a href="https://github.com/dkapitan" target="_blank" rel="noopener">dkapitan</a>
,







<a href="https://github.com/econmaett" target="_blank" rel="noopener">econmaett</a>
,







<a href="https://github.com/edavidaja" target="_blank" rel="noopener">edavidaja</a>
,







<a href="https://github.com/edvinsyk" target="_blank" rel="noopener">edvinsyk</a>
,







<a href="https://github.com/ethanwhite" target="_blank" rel="noopener">ethanwhite</a>
,







<a href="https://github.com/fermarsan" target="_blank" rel="noopener">fermarsan</a>
,







<a href="https://github.com/fredguth" target="_blank" rel="noopener">fredguth</a>
,







<a href="https://github.com/fuhrmanator" target="_blank" rel="noopener">fuhrmanator</a>
,







<a href="https://github.com/gadenbuie" target="_blank" rel="noopener">gadenbuie</a>
,







<a href="https://github.com/georgestagg" target="_blank" rel="noopener">georgestagg</a>
,







<a href="https://github.com/ghisvail" target="_blank" rel="noopener">ghisvail</a>
,







<a href="https://github.com/ghost" target="_blank" rel="noopener">ghost</a>
,







<a href="https://github.com/apps/github-actions" target="_blank" rel="noopener">github-actions[bot]</a>
,







<a href="https://github.com/glin" target="_blank" rel="noopener">glin</a>
,







<a href="https://github.com/gregswinehart" target="_blank" rel="noopener">gregswinehart</a>
,







<a href="https://github.com/gwbrck" target="_blank" rel="noopener">gwbrck</a>
,







<a href="https://github.com/halleysfifthinc" target="_blank" rel="noopener">halleysfifthinc</a>
,







<a href="https://github.com/hansfn" target="_blank" rel="noopener">hansfn</a>
,







<a href="https://github.com/hchulkim" target="_blank" rel="noopener">hchulkim</a>
,







<a href="https://github.com/holtzy" target="_blank" rel="noopener">holtzy</a>
,







<a href="https://github.com/htbunn" target="_blank" rel="noopener">htbunn</a>
,







<a href="https://github.com/hturner" target="_blank" rel="noopener">hturner</a>
,







<a href="https://github.com/hugetim" target="_blank" rel="noopener">hugetim</a>
,







<a href="https://github.com/hutch3232" target="_blank" rel="noopener">hutch3232</a>
,







<a href="https://github.com/iagopinal" target="_blank" rel="noopener">iagopinal</a>
,







<a href="https://github.com/ihrke" target="_blank" rel="noopener">ihrke</a>
,







<a href="https://github.com/jameslairdsmith" target="_blank" rel="noopener">jameslairdsmith</a>
,







<a href="https://github.com/jdfoote" target="_blank" rel="noopener">jdfoote</a>
,







<a href="https://github.com/jeremy9959" target="_blank" rel="noopener">jeremy9959</a>
,







<a href="https://github.com/jfy133" target="_blank" rel="noopener">jfy133</a>
,







<a href="https://github.com/jkrumbiegel" target="_blank" rel="noopener">jkrumbiegel</a>
,







<a href="https://github.com/jmgirard" target="_blank" rel="noopener">jmgirard</a>
,







<a href="https://github.com/jonpeake" target="_blank" rel="noopener">jonpeake</a>
,







<a href="https://github.com/jvcarli" target="_blank" rel="noopener">jvcarli</a>
,







<a href="https://github.com/jxpeng98" target="_blank" rel="noopener">jxpeng98</a>
,







<a href="https://github.com/kandolfp" target="_blank" rel="noopener">kandolfp</a>
,







<a href="https://github.com/kapsner" target="_blank" rel="noopener">kapsner</a>
,







<a href="https://github.com/kathsherratt" target="_blank" rel="noopener">kathsherratt</a>
,







<a href="https://github.com/kazuyanagimoto" target="_blank" rel="noopener">kazuyanagimoto</a>
,







<a href="https://github.com/kevinah95" target="_blank" rel="noopener">kevinah95</a>
,







<a href="https://github.com/kippandrew" target="_blank" rel="noopener">kippandrew</a>
,







<a href="https://github.com/koldle" target="_blank" rel="noopener">koldle</a>
,







<a href="https://github.com/lachlansimpson" target="_blank" rel="noopener">lachlansimpson</a>
,







<a href="https://github.com/lbm364dl" target="_blank" rel="noopener">lbm364dl</a>
,







<a href="https://github.com/leovuong" target="_blank" rel="noopener">leovuong</a>
,







<a href="https://github.com/lostmygithubaccount" target="_blank" rel="noopener">lostmygithubaccount</a>
,







<a href="https://github.com/lu-kas" target="_blank" rel="noopener">lu-kas</a>
,







<a href="https://github.com/lukmanaj" target="_blank" rel="noopener">lukmanaj</a>
,







<a href="https://github.com/lwjohnst86" target="_blank" rel="noopener">lwjohnst86</a>
,







<a href="https://github.com/maelle" target="_blank" rel="noopener">maelle</a>
,







<a href="https://github.com/mahmudstat" target="_blank" rel="noopener">mahmudstat</a>
,







<a href="https://github.com/masud90" target="_blank" rel="noopener">masud90</a>
,







<a href="https://github.com/melaniewalsh" target="_blank" rel="noopener">melaniewalsh</a>
,







<a href="https://github.com/mfisher87" target="_blank" rel="noopener">mfisher87</a>
,







<a href="https://github.com/mipmip" target="_blank" rel="noopener">mipmip</a>
,







<a href="https://github.com/mpr1255" target="_blank" rel="noopener">mpr1255</a>
,







<a href="https://github.com/multimeric" target="_blank" rel="noopener">multimeric</a>
,







<a href="https://github.com/musvaage" target="_blank" rel="noopener">musvaage</a>
,







<a href="https://github.com/mvuorre" target="_blank" rel="noopener">mvuorre</a>
,







<a href="https://github.com/nathanj3" target="_blank" rel="noopener">nathanj3</a>
,







<a href="https://github.com/nessan" target="_blank" rel="noopener">nessan</a>
,







<a href="https://github.com/nichtich" target="_blank" rel="noopener">nichtich</a>
,







<a href="https://github.com/odysseu" target="_blank" rel="noopener">odysseu</a>
,







<a href="https://github.com/ofkoru" target="_blank" rel="noopener">ofkoru</a>
,







<a href="https://github.com/olivroy" target="_blank" rel="noopener">olivroy</a>
,







<a href="https://github.com/oyvindbso" target="_blank" rel="noopener">oyvindbso</a>
,







<a href="https://github.com/pagiraud" target="_blank" rel="noopener">pagiraud</a>
,







<a href="https://github.com/parmsam" target="_blank" rel="noopener">parmsam</a>
,







<a href="https://github.com/peter-gy" target="_blank" rel="noopener">peter-gy</a>
,







<a href="https://github.com/pm-gusmano" target="_blank" rel="noopener">pm-gusmano</a>
,







<a href="https://github.com/produnis" target="_blank" rel="noopener">produnis</a>
,







<a href="https://github.com/rabyj" target="_blank" rel="noopener">rabyj</a>
,







<a href="https://github.com/raffaem" target="_blank" rel="noopener">raffaem</a>
,







<a href="https://github.com/randyzwitch" target="_blank" rel="noopener">randyzwitch</a>
,







<a href="https://github.com/rben01" target="_blank" rel="noopener">rben01</a>
,







<a href="https://github.com/rossbowen" target="_blank" rel="noopener">rossbowen</a>
,







<a href="https://github.com/rundel" target="_blank" rel="noopener">rundel</a>
,







<a href="https://github.com/ryanzomorrodi" target="_blank" rel="noopener">ryanzomorrodi</a>
,







<a href="https://github.com/ryjohnson09" target="_blank" rel="noopener">ryjohnson09</a>
,







<a href="https://github.com/s2t2" target="_blank" rel="noopener">s2t2</a>
,







<a href="https://github.com/salim-b" target="_blank" rel="noopener">salim-b</a>
,







<a href="https://github.com/samcarter" target="_blank" rel="noopener">samcarter</a>
,







<a href="https://github.com/serialc" target="_blank" rel="noopener">serialc</a>
,







<a href="https://github.com/sgelzenleuchter" target="_blank" rel="noopener">sgelzenleuchter</a>
,







<a href="https://github.com/skriptum" target="_blank" rel="noopener">skriptum</a>
,







<a href="https://github.com/spaette" target="_blank" rel="noopener">spaette</a>
,







<a href="https://github.com/stragu" target="_blank" rel="noopener">stragu</a>
,







<a href="https://github.com/sun123zxy" target="_blank" rel="noopener">sun123zxy</a>
,







<a href="https://github.com/sverrirarnors" target="_blank" rel="noopener">sverrirarnors</a>
,







<a href="https://github.com/tecosaur" target="_blank" rel="noopener">tecosaur</a>
,







<a href="https://github.com/temospena" target="_blank" rel="noopener">temospena</a>
,







<a href="https://github.com/thatchermo" target="_blank" rel="noopener">thatchermo</a>
,







<a href="https://github.com/topepo" target="_blank" rel="noopener">topepo</a>
,







<a href="https://github.com/tylere" target="_blank" rel="noopener">tylere</a>
,







<a href="https://github.com/winniehell" target="_blank" rel="noopener">winniehell</a>
,







<a href="https://github.com/wklimowicz" target="_blank" rel="noopener">wklimowicz</a>
,







<a href="https://github.com/yogabonito" target="_blank" rel="noopener">yogabonito</a>
,







<a href="https://github.com/youcc" target="_blank" rel="noopener">youcc</a>
,







<a href="https://github.com/yves-amevoin" target="_blank" rel="noopener">yves-amevoin</a>
,







<a href="https://github.com/yyzeng" target="_blank" rel="noopener">yyzeng</a>
.</p>
<p>The lightbulb emoji in the 






<a href="thumbnail.png">listing and social card image</a>
 for this post comes from <a href="https://openmoji.org/" class="external">OpenMoji</a>&ndash; the open-source emoji and icon project. License: <a href="https://creativecommons.org/licenses/by-sa/4.0/#" class="external">CC BY-SA 4.0</a></p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-10-13_1.8-release/thumbnail.png" length="58117" type="image/png" />
    </item>
    <item>
      <title>quarto R package v1.5.0: Streamlined Workflows for R Users</title>
      <link>https://opensource.posit.co/blog/2025-07-28_r-package-release-1.5/</link>
      <pubDate>Mon, 28 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-07-28_r-package-release-1.5/</guid>
      <dc:creator>Christophe Dervieux</dc:creator><description><![CDATA[<p>The quarto R package version 1.5.0 is here! This release focuses on making Quarto more flexible and powerful for R users with significant workflow improvements.</p>
<h2 id="whats-new">What&rsquo;s New
</h2>
<p>Install the latest version from CRAN:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">install.packages</span><span class="p">(</span><span class="s">&#34;quarto&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Major features in this release include:</p>
<ul>
<li>


  
  
  





<a href="#pass-r-values-to-quarto-metadata"><strong>Pass R values to Quarto metadata</strong></a>
 - Set metadata programmatically based on computed values from knitr engine</li>
<li>


  
  
  





<a href="#insert-markdown-in-html-tables"><strong>Insert Markdown in HTML tables for Quarto processing</strong></a>
 - Include Markdown content (equations, links, formatting) in HTML tables</li>
<li>


  
  
  





<a href="#themes-helpers"><strong>Apply Light and Dark Themes to Plots and Tables</strong></a>
 - Change the background and foreground colors of plots and tables based on light &amp; dark themes</li>
<li>


  
  
  





<a href="#work-with-r-scripts"><strong>Work with R scripts and Quarto</strong></a>
 - Extract R code from Quarto documents or prepare R scripts for Quarto rendering</li>
<li>


  
  
  





<a href="#build-paths-from-project"><strong>Build paths from Quarto Project</strong></a>
 - Build paths relative to Quarto project root within R cells</li>
<li>


  
  
  





<a href="#automate-quarto-cli"><strong>Automate Quarto CLI from R</strong></a>
 - New and improved wrappers around Quarto CLI features for easier automation</li>
</ul>
<h2 id="pass-r-values-to-quarto-metadata">Pass R Values to Quarto Metadata
</h2>
<p>Set metadata dynamically based on R computations with <code>write_yaml_metadata_block()</code>. For example, you could check a parameter value, and conditionally include content based on it:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">#| output: asis</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">write_yaml_metadata_block</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">is_france</span> <span class="o">=</span> <span class="n">params</span><span class="o">$</span><span class="n">country</span> <span class="o">==</span> <span class="s">&#34;france&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This will write the following (e.g., when <code>quarto render report.qmd -P country:france</code>):</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">is_france</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Then use Quarto&rsquo;s conditional features:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">::: {.content-visible when-meta=&#34;is_france&#34;}
</span></span><span class="line"><span class="cl"><span class="gu">## Fun fact about France
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">In 2025, France is the most visited country in the world, attracting over 89 million tourists annually!
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:::</span></span></code></pre></td></tr></table>
</div>
</div></div>
<h3 id="improved-yaml-12-compatibility">Improved YAML 1.2 Compatibility
</h3>
<p>The function now correctly handles special edge cases in YAML quoting. Specifically, it automatically quotes octal-like strings that are not supported in YAML 1.1 (like <code>&quot;0888&quot;</code> or <code>&quot;0999&quot;</code>):</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># These octal-like values are automatically quoted to prevent errors</span>
</span></span><span class="line"><span class="cl"><span class="nf">write_yaml_metadata_block</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">code1</span> <span class="o">=</span> <span class="s">&#34;0888&#34;</span><span class="p">,</span>    <span class="c1"># Without quoting: YAML 1.2 interprets as 888 (invalid octal ignored)</span>
</span></span><span class="line"><span class="cl">  <span class="n">code2</span> <span class="o">=</span> <span class="s">&#34;0999&#34;</span>     <span class="c1"># Without quoting: YAML 1.2 interprets as 999 (invalid octal ignored)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Without the automatic quoting, these values would be interpreted as decimal numbers (888 and 999) in YAML 1.2, losing the leading zeros. This could break code that expects string values like file permissions or ID codes that must preserve leading zeros.</p>
<p>This change applies to internal functions that write YAML from R object lists, and so this improvement is particularly important when using <code>execute_params</code> with <code>quarto_render()</code>, where parameter values might include such edge cases:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Parameters with octal-like codes are now handled correctly</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_render</span><span class="p">(</span><span class="s">&#34;report.qmd&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">  <span class="n">execute_params</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">site_code</span> <span class="o">=</span> <span class="s">&#34;0888&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">permission</span> <span class="o">=</span> <span class="s">&#34;0755&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">))</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>For explicit control over quoting, use <code>yaml_quote_string()</code>:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Force specific values to be quoted in YAML output</span>
</span></span><span class="line"><span class="cl"><span class="n">metadata</span> <span class="o">&lt;-</span> <span class="nf">list</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">code1</span> <span class="o">=</span> <span class="nf">yaml_quote_string</span><span class="p">(</span><span class="s">&#34;1.0&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">write_yaml_metadata_block</span><span class="p">(</span><span class="n">.list</span> <span class="o">=</span> <span class="n">metadata</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This will mark the string to be double quoted in YAML, preserving the character representation exactly as provided.</p>
<p>See more examples in the 






<a href="https://quarto-dev.github.io/quarto-r/articles/dynamic-metadata.html" target="_blank" rel="noopener">dynamic metadata vignette</a>
, including how to make parameters available as metadata for conditional content.</p>
<h2 id="insert-markdown-in-html-tables-for-quarto-processing">Insert Markdown in HTML Tables for Quarto Processing
</h2>
<p>Quarto can 


  
  
  





<a href="https://quarto.org/docs/authoring/tables.html#html-tables" target="_blank" rel="noopener">parse Markdown content in HTML tables</a>
, enabling rich formatting like math equations, links, and text styling. The new <code>tbl_qmd_*()</code> functions make this powerful Quarto feature easier to use from R:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="nf">data.frame</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">  <span class="n">Feature</span> <span class="o">=</span> <span class="nf">c</span><span class="p">(</span><span class="s">&#34;Formatting&#34;</span><span class="p">,</span> <span class="s">&#34;Math&#34;</span><span class="p">,</span> <span class="s">&#34;Links&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">  <span class="n">Example</span> <span class="o">=</span> <span class="nf">c</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="nf">tbl_qmd_span</span><span class="p">(</span><span class="s">&#34;**Bold**, *italic*&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nf">tbl_qmd_span</span><span class="p">(</span><span class="s">&#34;$E = mc^2$&#34;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nf">tbl_qmd_span</span><span class="p">(</span><span class="s">&#34;[Quarto docs](https://quarto.org)&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="o">|&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="n">knitr</span><span class="o">::</span><span class="nf">kable</span><span class="p">(</span><span class="n">format</span> <span class="o">=</span> <span class="s">&#34;html&#34;</span><span class="p">,</span> <span class="n">escape</span> <span class="o">=</span> <span class="kc">FALSE</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>These helper functions wrap content in HTML spans with <code>data-qmd-base64</code> attributes that Quarto recognizes for Markdown processing. They work with any table package that supports raw HTML (knitr, kableExtra, DT). For content that only works in Quarto, use the <code>display</code> argument for graceful fallback. See more examples in the 






<a href="https://quarto-dev.github.io/quarto-r/articles/markdown-html-tables.html" target="_blank" rel="noopener">Markdown in HTML tables vignette</a>
, including comparisons of Markdown support in HTML tables across different packages.</p>
<h2 id="apply-light-and-dark-themes-to-plots-and-tables">Apply Light and Dark Themes to Plots and Tables
</h2>
<p>The <code>theme_colors_flextable()</code>, <code>theme_colors_ggplot2()</code>, <code>theme_colors_gt()</code>, <code>theme_colors_plotly()</code>, <code>theme_colors_thematic()</code> helper functions change the background and foreground colors of six popular plot and table packages. These can be used to produce light and dark 


  
  
  





<a href="https://quarto.org/docs/computations/execution-options.html#cell-renderings" target="_blank" rel="noopener"><code>renderings</code></a>
 to match the plot or table with themes in light and dark mode.</p>
<p>The usage of the the results of these functions depends on the package. See the 






<a href="https://quarto-dev.github.io/quarto-r/articles/theme-helpers.html" target="_blank" rel="noopener">Theme Helpers</a>
 article for usage examples of <code>theme_colors_*</code>.</p>
<p>The <code>theme_brand_flextable()</code>, <code>theme_brand_ggplot2()</code>, <code>theme_brand_gt()</code>, <code>theme_brand_plotly()</code>, <code>theme_brand_thematic()</code> helper functions change the background and foreground colors of these packages using corresponding 






<a href="https://posit-dev.github.io/brand-yml/" target="_blank" rel="noopener">brand.yml</a>
 colors. See the 






<a href="https://examples.quarto.pub/lightdark-renderings-examples/ggplot2.html" target="_blank" rel="noopener">Light &amp; Dark Renderings Examples</a>
 for usage examples of <code>theme_brand_*</code>.</p>
<h2 id="work-with-r-scripts-and-quarto">Work with R Scripts and Quarto
</h2>
<h3 id="extract-r-code-from-quarto-documents">Extract R Code from Quarto Documents
</h3>
<p>The new <code>qmd_to_r_script()</code> <a href='https://lifecycle.r-lib.org/articles/stages.html#experimental'><img src='https://img.shields.io/badge/lifecycle-experimental-orange.svg' alt='Experimental lifecycle'></a> function provides an alternative to <code>knitr::purl()</code> that leverages <code>quarto inspect</code> for code extraction:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Extract R code from a Quarto document</span>
</span></span><span class="line"><span class="cl"><span class="nf">qmd_to_r_script</span><span class="p">(</span><span class="s">&#34;analysis.qmd&#34;</span><span class="p">)</span>  <span class="c1"># Creates &#34;analysis.R&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Specify custom output</span>
</span></span><span class="line"><span class="cl"><span class="nf">qmd_to_r_script</span><span class="p">(</span><span class="s">&#34;analysis.qmd&#34;</span><span class="p">,</span> <span class="n">script</span> <span class="o">=</span> <span class="s">&#34;extracted-code.R&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This function uses Quarto&rsquo;s static document analysis rather than R evaluation, making it faster and safer for simple code extraction. It preserves cells options, commenting cells with <code>eval: false</code>, and ignoring content having <code>purl: false</code>. For documents using advanced knitr features like <code>child=</code> chunks or <code>knitr::read_chunk()</code>, <code>knitr::purl()</code> remains the recommended approach as it handles these through actual document processing.</p>
<h3 id="prepare-r-scripts-for-quarto-rendering">Prepare R Scripts for Quarto Rendering
</h3>
<p>Quarto can 


  
  
  





<a href="https://quarto.org/docs/computations/render-scripts.html#knitr" target="_blank" rel="noopener">render R scripts directly</a>
, treating specially formatted comments as Markdown. The <code>add_spin_preamble()</code> function helps prepare R scripts for this feature by adding the required YAML metadata:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Add metadata for rendering</span>
</span></span><span class="line"><span class="cl"><span class="nf">add_spin_preamble</span><span class="p">(</span><span class="s">&#34;analysis.R&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">                  <span class="n">title</span> <span class="o">=</span> <span class="s">&#34;Analysis Report&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                  <span class="n">preamble</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="n">author</span> <span class="o">=</span> <span class="s">&#34;Data Team&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Now render the script with Quarto</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_render</span><span class="p">(</span><span class="s">&#34;analysis.R&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This function adds a minimal spin-style preamble (using <code>#'</code> comments) that Quarto recognizes:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1">#&#39; ---</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&#39; title: Analysis Report</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&#39; author: Data Team</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&#39; ---</span>
</span></span><span class="line"><span class="cl"><span class="c1">#&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Your original R code follows...</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>The preamble enables Quarto&rsquo;s 


  
  
  





<a href="https://quarto.org/docs/computations/execution-options.html#engine-binding" target="_blank" rel="noopener">engine binding</a>
 to properly process the script, allowing you to use R scripts as source documents alongside <code>.qmd</code> files. Learn more about working with R scripts in the 






<a href="https://quarto-dev.github.io/quarto-r/articles/r-scripts.html" target="_blank" rel="noopener">R scripts vignette</a>
.</p>
<h2 id="build-paths-from-quarto-project">Build Paths from Quarto Project
</h2>
<p>Quarto 


  
  
  





<a href="https://quarto.org/docs/advanced/environment-vars.html#variables-quarto-sets" target="_blank" rel="noopener">sets environment variables</a>
 during rendering that identify the project root, but knitr doesn&rsquo;t have direct access to this information by default. The new project navigation functions bridge this gap:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Build paths relative to the Quarto project root</span>
</span></span><span class="line"><span class="cl"><span class="n">data_file</span> <span class="o">&lt;-</span> <span class="nf">project_path</span><span class="p">(</span><span class="s">&#34;data&#34;</span><span class="p">,</span> <span class="s">&#34;analysis.csv&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Explicitly find the project root (searches for _quarto.yml)</span>
</span></span><span class="line"><span class="cl"><span class="n">root</span> <span class="o">&lt;-</span> <span class="nf">find_project_root</span><span class="p">()</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p><code>project_path()</code> <a href='https://lifecycle.r-lib.org/articles/stages.html#experimental'><img src='https://img.shields.io/badge/lifecycle-experimental-orange.svg' alt='Experimental lifecycle'></a> intelligently handles different execution contexts:</p>
<ul>
<li>During <code>quarto render</code>, it uses <code>QUARTO_PROJECT_ROOT</code> or <code>QUARTO_PROJECT_DIR</code> environment variables</li>
<li>In interactive sessions, it automatically detects the project root by searching for <code>_quarto.yml</code>.</li>
<li>Falls back to the current working directory with a warning if no project is found.</li>
</ul>
<p>This ensures your paths work consistently without hardcoding or manual adjustments. For example, you can read a CSV file relative to your project root:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># In posts/2025/analysis/report.qmd, this resolves to ../../../data/results.csv</span>
</span></span><span class="line"><span class="cl"><span class="n">results</span> <span class="o">&lt;-</span> <span class="nf">read.csv</span><span class="p">(</span><span class="nf">project_path</span><span class="p">(</span><span class="s">&#34;data&#34;</span><span class="p">,</span> <span class="s">&#34;results.csv&#34;</span><span class="p">))</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>For more explicit control, consider using <code>here::i_am()</code> and <code>here::here()</code> as an alternative approach. Follow 






<a href="https://github.com/r-lib/here/issues/128" target="_blank" rel="noopener">r-lib/usethis Issue #128</a>
 for improved support in next versions of <code>here</code>.</p>
<h2 id="automate-quarto-cli-from-r">Automate Quarto CLI from R
</h2>
<p>The quarto R package has always been designed as a comprehensive wrapper for the Quarto CLI, enabling seamless integration of Quarto into R workflows and pipelines. This release strengthens that foundation with improved wrappers and new helpers.</p>
<h3 id="extension-management">Extension Management
</h3>
<p>Programmatically manage Quarto extensions:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Add an extension</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_add_extension</span><span class="p">(</span><span class="s">&#34;quarto-journals/jss&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># List installed extensions</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_list_extensions</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Remove an extension</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_remove_extension</span><span class="p">(</span><span class="s">&#34;jss&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<h3 id="project-and-version-management">Project and Version Management
</h3>
<p>New helpers for common CLI tasks:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Create projects from templates</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_create</span><span class="p">(</span><span class="s">&#34;article&#34;</span><span class="p">,</span> <span class="n">name</span> <span class="o">=</span> <span class="s">&#34;my-analysis&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Check if a newer version of Quarto is available</span>
</span></span><span class="line"><span class="cl"><span class="nf">check_newer_version</span><span class="p">()</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<h3 id="document-inspection">Document Inspection
</h3>
<p>Leverage <code>quarto inspect</code> results to answer questions about documents:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Check if a document has parameters (uses quarto inspect internally)</span>
</span></span><span class="line"><span class="cl"><span class="kr">if</span> <span class="p">(</span><span class="nf">has_parameters</span><span class="p">(</span><span class="s">&#34;report.qmd&#34;</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nf">quarto_render</span><span class="p">(</span><span class="s">&#34;report.qmd&#34;</span><span class="p">,</span> <span class="n">execute_params</span> <span class="o">=</span> <span class="nf">list</span><span class="p">(</span><span class="n">year</span> <span class="o">=</span> <span class="m">2025</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>These CLI wrappers enable automation scenarios like CI/CD pipelines, batch processing, and dynamic project management&mdash;all from within R. The consistent interface means you can script complex Quarto workflows without leaving your R environment.</p>
<h2 id="additional-improvements">Additional Improvements
</h2>
<h3 id="familiar-workflows-for-blogdown-users">Familiar Workflows for Blogdown Users
</h3>
<p>The <code>new_blog_post()</code> function provides a familiar workflow for users transitioning from blogdown:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Create a new blog post with automatic date prefix and YAML frontmatter</span>
</span></span><span class="line"><span class="cl"><span class="nf">new_blog_post</span><span class="p">(</span><span class="s">&#34;my-first-quarto-post&#34;</span><span class="p">,</span> <span class="n">dir</span> <span class="o">=</span> <span class="s">&#34;posts&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Similar to blogdown&rsquo;s <code>new_post()</code>, this function automatically creates a new blog post file with proper YAML frontmatter in the appropriate directory structure for Quarto blogs, making the transition from blogdown to Quarto smoother.</p>
<h3 id="migration-helper-for-bookdown-projects">Migration Helper for Bookdown Projects
</h3>
<p>The <code>detect_bookdown_crossrefs()</code> function helps identify bookdown cross-reference syntax that needs conversion:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Scan your bookdown project for cross-references</span>
</span></span><span class="line"><span class="cl"><span class="nf">detect_bookdown_crossrefs</span><span class="p">(</span><span class="s">&#34;my-bookdown-project/&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>The function prints detailed guidance to the console, showing:</p>
<ul>
<li>Which cross-reference patterns need manual conversion</li>
<li>Which patterns can be automatically converted</li>
<li>Specific examples from your files</li>
</ul>
<p>Example output from the 






<a href="https://bookdown.org/yihui/bookdown/" target="_blank" rel="noopener">bookdown book</a>
 sources:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="o">&gt;</span> <span class="nf">detect_bookdown_crossrefs</span><span class="p">(</span><span class="s">&#34;~/Documents/DEV_R/bookdown/inst/examples&#34;</span><span class="p">,</span> <span class="n">verbose</span> <span class="o">=</span> <span class="kc">FALSE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">ℹ <span class="n">Scanning</span> <span class="kr">for</span> <span class="n">bookdown</span> <span class="n">cross</span><span class="o">-</span><span class="n">references</span> <span class="kr">in</span> <span class="m">12</span> <span class="n">.Rmd</span> <span class="n">files...</span>
</span></span><span class="line"><span class="cl"><span class="o">!</span> <span class="n">Found</span> <span class="m">110</span> <span class="n">bookdown</span> <span class="n">cross</span><span class="o">-</span><span class="n">references</span> <span class="n">that</span> <span class="n">should</span> <span class="n">be</span> <span class="n">converted</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">01</span><span class="o">-</span><span class="n">introduction.Rmd</span><span class="o">:</span> <span class="m">3</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">3</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">02</span><span class="o">-</span><span class="n">components.Rmd</span><span class="o">:</span> <span class="m">52</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">5</span> <span class="n">Eq</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">7</span> <span class="n">Fig</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">1</span> <span class="n">Lem</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">1</span> <span class="n">Lemma</span> <span class="n">Div</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">7</span> <span class="n">Numbered</span> <span class="n">Equation</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">17</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">5</span> <span class="n">Tab</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">5</span> <span class="n">Theorem</span> <span class="n">Div</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">4</span> <span class="n">Thm</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">03</span><span class="o">-</span><span class="n">formats.Rmd</span><span class="o">:</span> <span class="m">20</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">4</span> <span class="n">Fig</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">16</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">04</span><span class="o">-</span><span class="n">customization.Rmd</span><span class="o">:</span> <span class="m">5</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">5</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">05</span><span class="o">-</span><span class="n">editing.Rmd</span><span class="o">:</span> <span class="m">8</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">3</span> <span class="n">Fig</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">5</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">06</span><span class="o">-</span><span class="n">publishing.Rmd</span><span class="o">:</span> <span class="m">8</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">3</span> <span class="n">Fig</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">5</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="m">08</span><span class="o">-</span><span class="n">usage.Rmd</span><span class="o">:</span> <span class="m">3</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">3</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">• <span class="n">index.Rmd</span><span class="o">:</span> <span class="m">11</span> <span class="n">references</span>
</span></span><span class="line"><span class="cl"><span class="o">-</span> <span class="m">11</span> <span class="n">Sec</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ℹ <span class="n">Summary</span> <span class="n">of</span> <span class="n">conversion</span> <span class="n">requirements</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">• <span class="m">5</span> <span class="n">Eq</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">17</span> <span class="n">Fig</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">1</span> <span class="n">Lem</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">1</span> <span class="n">Lemma</span> <span class="n">Div</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">7</span> <span class="n">Numbered</span> <span class="n">Equation</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">65</span> <span class="n">Sec</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">5</span> <span class="n">Tab</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">5</span> <span class="n">Theorem</span> <span class="n">Div</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">• <span class="m">4</span> <span class="n">Thm</span> <span class="n">reference</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ℹ <span class="n">Manual</span> <span class="n">conversion</span> <span class="n">requirements</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">• <span class="n">Section</span> <span class="n">headers</span><span class="o">:</span> <span class="m">65</span> <span class="n">references</span> <span class="n">need</span> <span class="n">manual</span> <span class="n">attention</span>
</span></span><span class="line"><span class="cl">• <span class="n">Figure</span> <span class="n">labels</span><span class="o">:</span> <span class="m">17</span> <span class="n">references</span> <span class="n">need</span> <span class="n">manual</span> <span class="n">attention</span>
</span></span><span class="line"><span class="cl">• <span class="n">Table</span> <span class="n">labels</span><span class="o">:</span> <span class="m">5</span> <span class="n">references</span> <span class="n">need</span> <span class="n">manual</span> <span class="n">attention</span>
</span></span><span class="line"><span class="cl">• <span class="n">Equation</span> <span class="n">structure</span><span class="o">:</span> <span class="m">7</span> <span class="n">references</span> <span class="n">need</span> <span class="n">manual</span> <span class="n">attention</span>
</span></span><span class="line"><span class="cl">• <span class="n">Theorem</span> <span class="n">blocks</span><span class="o">:</span> <span class="m">6</span> <span class="n">references</span> <span class="n">need</span> <span class="n">manual</span> <span class="n">attention</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">ℹ <span class="n">For</span> <span class="n">detailed</span> <span class="n">conversion</span> <span class="n">guidance</span><span class="p">,</span> <span class="n">run</span><span class="o">:</span> <span class="n">quarto</span><span class="o">::</span><span class="nf">detect_bookdown_crossrefs</span><span class="p">(</span><span class="s">&#34;~/Documents/DEV_R/bookdown/inst/examples&#34;</span><span class="p">,</span> <span class="n">verbose</span> <span class="o">=</span> <span class="kc">TRUE</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>For converting chunk headers from curly brace syntax to Quarto&rsquo;s YAML style, remember that 






<a href="https://yihui.org/knitr/reference/convert_chunk_header/" target="_blank" rel="noopener"><code>knitr::convert_chunk_header()</code></a>
 is available:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Convert {r label, option=value} to YAML-style chunk options for a single file</span>
</span></span><span class="line"><span class="cl"><span class="n">knitr</span><span class="o">::</span><span class="nf">convert_chunk_header</span><span class="p">(</span><span class="s">&#34;analysis.Rmd&#34;</span><span class="p">,</span> <span class="n">output</span> <span class="o">=</span> <span class="kc">NULL</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># To process multiple files in a directory, you need to iterate:</span>
</span></span><span class="line"><span class="cl"><span class="n">rmd_files</span> <span class="o">&lt;-</span> <span class="nf">list.files</span><span class="p">(</span><span class="s">&#34;my-bookdown-project/&#34;</span><span class="p">,</span> <span class="n">pattern</span> <span class="o">=</span> <span class="s">&#34;\\.Rmd$&#34;</span><span class="p">,</span> 
</span></span><span class="line"><span class="cl">                        <span class="n">full.names</span> <span class="o">=</span> <span class="kc">TRUE</span><span class="p">,</span> <span class="n">recursive</span> <span class="o">=</span> <span class="kc">TRUE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">lapply</span><span class="p">(</span><span class="n">rmd_files</span><span class="p">,</span> <span class="n">knitr</span><span class="o">::</span><span class="n">convert_chunk_header</span><span class="p">,</span> <span class="n">output</span> <span class="o">=</span> <span class="kc">NULL</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Together, these tools address the main syntax differences when migrating from bookdown to Quarto.</p>
<h3 id="enhanced-workflow">Enhanced Workflow
</h3>
<ul>
<li><code>quarto_preview()</code> now returns the preview URL for automation</li>
<li>Better debugging with <code>QUARTO_R_DEBUG=TRUE</code> environment variable</li>
<li>Consistent R version usage in embedded processes</li>
</ul>
<h2 id="breaking-changes">Breaking Changes
</h2>
<h3 id="output-file-handling">Output File Handling
</h3>
<p>The <code>output_file</code> parameter in <code>quarto_render()</code> now sets the <code>output-file</code> metadata field instead of passing the <code>--output</code> CLI flag to Quarto. This change better aligns with Quarto&rsquo;s metadata processing and enables support for multiple output formats:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Sets output-file metadata (like having &#39;output-file: report.html&#39; in YAML)</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_render</span><span class="p">(</span><span class="s">&#34;doc.qmd&#34;</span><span class="p">,</span> <span class="n">output_file</span> <span class="o">=</span> <span class="s">&#34;report.html&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>If you specifically need the old CLI flag behavior, use <code>quarto_args</code>:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Use CLI flag directly</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_render</span><span class="p">(</span><span class="s">&#34;doc.qmd&#34;</span><span class="p">,</span> <span class="n">quarto_args</span> <span class="o">=</span> <span class="nf">c</span><span class="p">(</span><span class="s">&#34;--output&#34;</span><span class="p">,</span> <span class="s">&#34;report.html&#34;</span><span class="p">))</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<h3 id="template-usage">Template Usage
</h3>
<p><code>quarto_use_template()</code> now requires an empty directory and fails with a clear error message when used in non-empty directories:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-r" data-lang="r"><span class="line"><span class="cl"><span class="c1"># Create an empty directory first</span>
</span></span><span class="line"><span class="cl"><span class="nf">dir.create</span><span class="p">(</span><span class="s">&#34;my-article&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="nf">quarto_use_template</span><span class="p">(</span><span class="s">&#34;quarto-journals/jss&#34;</span><span class="p">,</span> <span class="n">dir</span> <span class="o">=</span> <span class="s">&#34;my-article&#34;</span><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This change follows a Quarto CLI update that removed interactive prompting for programmatic use. If you need to use templates in existing directories, use <code>quarto use template</code> directly in the terminal for interactive installation.</p>
<h2 id="learn-more">Learn More
</h2>
<p>Explore the new features and improvements:</p>
<ul>
<li>Documentation for R package: 






<a href="https://quarto-dev.github.io/quarto-r/" target="_blank" rel="noopener">https://quarto-dev.github.io/quarto-r/</a>
</li>
<li>Full changelog: 






<a href="https://quarto-dev.github.io/quarto-r/news/index.html" target="_blank" rel="noopener">https://quarto-dev.github.io/quarto-r/news/index.html</a>
</li>
<li>Report issues: 






<a href="https://github.com/quarto-dev/quarto-r/issues" target="_blank" rel="noopener">https://github.com/quarto-dev/quarto-r/issues</a>
</li>
</ul>
<p>For detailed examples and workflows, check out the new vignettes:</p>
<ul>
<li>






<a href="https://quarto-dev.github.io/quarto-r/articles/dynamic-metadata.html" target="_blank" rel="noopener">Dynamic metadata</a>
</li>
<li>






<a href="https://quarto-dev.github.io/quarto-r/articles/markdown-html-tables.html" target="_blank" rel="noopener">Markdown in HTML tables</a>
</li>
<li>






<a href="https://quarto-dev.github.io/quarto-r/articles/r-scripts.html" target="_blank" rel="noopener">Working with R scripts</a>
</li>
<li>






<a href="https://quarto-dev.github.io/quarto-r/articles/index.html" target="_blank" rel="noopener">All vignettes</a>
</li>
</ul>
<h2 id="acknowledgments">Acknowledgments
</h2>
<p>Special thanks to all contributors that helped make this release:</p>
<p>






<a href="https://github.com/asadow" target="_blank" rel="noopener">@asadow</a>
, 






<a href="https://github.com/caiolivf" target="_blank" rel="noopener">@caiolivf</a>
, 






<a href="https://github.com/caocloud" target="_blank" rel="noopener">@caocloud</a>
, 






<a href="https://github.com/cderv" target="_blank" rel="noopener">@cderv</a>
, 






<a href="https://github.com/coatless" target="_blank" rel="noopener">@coatless</a>
, 






<a href="https://github.com/ColinFay" target="_blank" rel="noopener">@ColinFay</a>
, 






<a href="https://github.com/cwickham" target="_blank" rel="noopener">@cwickham</a>
, 






<a href="https://github.com/davidrsch" target="_blank" rel="noopener">@davidrsch</a>
, 






<a href="https://github.com/DillonHammill" target="_blank" rel="noopener">@DillonHammill</a>
, 






<a href="https://github.com/eitsupi" target="_blank" rel="noopener">@eitsupi</a>
, 






<a href="https://github.com/GeorgeBatten" target="_blank" rel="noopener">@GeorgeBatten</a>
, 






<a href="https://github.com/gordonwoodhull" target="_blank" rel="noopener">@gordonwoodhull</a>
, 






<a href="https://github.com/jennybc" target="_blank" rel="noopener">@jennybc</a>
, 






<a href="https://github.com/jeroen" target="_blank" rel="noopener">@jeroen</a>
, 






<a href="https://github.com/joanbadia" target="_blank" rel="noopener">@joanbadia</a>
, 






<a href="https://github.com/JosephBARBIERDARNAL" target="_blank" rel="noopener">@JosephBARBIERDARNAL</a>
, 






<a href="https://github.com/LiNk-NY" target="_blank" rel="noopener">@LiNk-NY</a>
, 






<a href="https://github.com/llrs-roche" target="_blank" rel="noopener">@llrs-roche</a>
, 






<a href="https://github.com/milanmlft" target="_blank" rel="noopener">@milanmlft</a>
, 






<a href="https://github.com/papayoun" target="_blank" rel="noopener">@papayoun</a>
, 






<a href="https://github.com/petermacp" target="_blank" rel="noopener">@petermacp</a>
, 






<a href="https://github.com/remlapmot" target="_blank" rel="noopener">@remlapmot</a>
, 






<a href="https://github.com/salim-b" target="_blank" rel="noopener">@salim-b</a>
, 






<a href="https://github.com/saudiwin" target="_blank" rel="noopener">@saudiwin</a>
, 






<a href="https://github.com/smzimbo-bayer" target="_blank" rel="noopener">@smzimbo-bayer</a>
, 






<a href="https://github.com/srvanderplas" target="_blank" rel="noopener">@srvanderplas</a>
, and 






<a href="https://github.com/wjschne" target="_blank" rel="noopener">@wjschne</a>
.</p>
<hr>
<p><em>Happy Quarto-ing with R!</em></p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-07-28_r-package-release-1.5/thumbnail.png" length="47355" type="image/png" />
    </item>
    <item>
      <title>From One Notebook to Many Reports: Parameterized reports with the `jupyter` engine</title>
      <link>https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/</link>
      <pubDate>Thu, 24 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/</guid>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<div class="callout callout-tip" role="note" aria-label="Tip">
<div class="callout-header">
<span class="callout-title">Based on a talk at SciPy 2025</span>
</div>
<div class="callout-body">
<p>This post is based on the talk &ldquo;From One Notebook to Many Reports: Automating with Quarto&rdquo; delivered at 






<a href="https://www.scipy2025.scipy.org" target="_blank" rel="noopener">SciPy 2025</a>
 by Charlotte Wickham.
You can find the slides at 






<a href="https://cwickham.github.io/one-notebook-many-reports/" target="_blank" rel="noopener">cwickham.github.io/one-notebook-many-reports</a>
 and example code at 






<a href="https://github.com/cwickham/one-notebook-many-reports" target="_blank" rel="noopener">github.com/cwickham/one-notebook-many-reports</a>
.</p>
</div>
</div>
<h2 id="the-problem-repetitive-reporting">The Problem: Repetitive Reporting
</h2>
<p>Would you rather read a generic &ldquo;Climate summary&rdquo; or a &ldquo;Climate summary for <em>exactly where you live</em>&rdquo;? Reports that are personalized to a specific situation increase engagement and connection. But producing many customized reports manually is tedious and error-prone.</p>
<p>Quarto solves this with parameterized reports&mdash;you create a single document template, then render it multiple times with different parameter values to generate customized outputs automatically.</p>
<p>A great example is the customized soil health reports from Washington Soil Health Initiative&rsquo;s 






<a href="https://washingtonsoilhealthinitiative.com/state-of-the-soils/" target="_blank" rel="noopener">State of the Soils Assessment</a>
, presented at posit::conf(2023) by 






<a href="https://jadeyryan.com" target="_blank" rel="noopener">Jadey Ryan</a>
 (watch on 






<a href="https://youtu.be/lbE5uOqfT70?si=C-d5U5Q2VXo1wlDs" target="_blank" rel="noopener">YouTube</a>
). Jadey demonstrated this approach using R and plain text Quarto files (<code>.qmd</code>).</p>
<p>This post shows you how to apply the same principles using Python: we&rsquo;ll walk through converting a Jupyter notebook (<code>.ipynb</code>) into a parameterized report, then automating the generation of multiple customized outputs. Then I&rsquo;ll give you some tips for making your reports look polished.</p>
<h2 id="the-solution-parameterized-reports">The Solution: Parameterized Reports
</h2>
<h3 id="start-with-a-notebook">Start with a notebook
</h3>
<p>As an example, let&rsquo;s start with a Jupyter notebook analyzing climate data for Corvallis, Oregon.</p>
<figure id="corvallis-ipynb">
<img src="https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/corvallis-ipynb.png" data-fig-alt="Screenshot of a Jupyter notebook with code cells and output, including a plot and text summary." alt="corvallis.ipynb" />
<figcaption aria-hidden="true"><a href="https://github.com/cwickham/one-notebook-many-reports/blob/main/01-one-notebook/corvallis.ipynb"><code>corvallis.ipynb</code></a></figcaption>
</figure>
<p>You can see the full notebook, 






<a href="https://github.com/cwickham/one-notebook-many-reports/blob/main/01-one-notebook/corvallis.ipynb" target="_blank" rel="noopener"><code>corvallis.ipynb</code>, on GitHub</a>
, but here are the key pieces:</p>
<ul>
<li>
<p>The code cells import some data for all of Oregon, and filter it to just rows relevant for Corvallis, then produce a summary sentence and a plot.</p>
</li>
<li>
<p>The document options specify <code>echo: false</code> so no code appears in the final output, and <code>format: typst</code> so the output is a PDF produced via 






<a href="https://typst.app" target="_blank" rel="noopener">Typst</a>
, a modern alternative to LaTeX.</p>
</li>
</ul>
<p>This single notebook can be rendered with Quarto:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto render corvallis.ipynb </span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>The result is a PDF file, <code>corvallis.pdf</code>, a simple report with the title &ldquo;Corvallis&rdquo; and a single sentence summary of the climate data, along with a plot highlighting the mean temperature for this year against the last 30 years.</p>
<figure>
<img src="https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/corvallis-pdf.png" data-fig-alt="Screenshot of a PDF file with the title &#39;Corvallis&#39; that contains a single sentence summary and a plot." alt="corvallis.pdf" />
<figcaption aria-hidden="true"><code>corvallis.pdf</code></figcaption>
</figure>
<p>Now, imagine we want to create this report for the 50 largest cities in Oregon.
Here&rsquo;s the steps we&rsquo;ll take:</p>
<ol>
<li>Turn hardcoded values into variables</li>
<li>Declare those variables parameters</li>
<li>Render the notebook with different parameter values</li>
<li>Automate rendering with many parameter values</li>
</ol>
<h3 id="1-turn-hardcoded-values-into-variables">1. Turn hardcoded values into variables
</h3>
<p>We want a report for each city.
We&rsquo;ll start by creating a variable, <code>city</code>, which we&rsquo;ll designate a parameter in our next step.
In a new code cell at the top of our notebook, we define the variable:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">code</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">city</span> <span class="o">=</span> <span class="s2">&#34;Corvallis&#34;</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Then anywhere we previously hardcoded <code>&quot;Corvallis&quot;</code> in the notebook, we replace it with this variable.</p>
<p>The first occurrence is in the title of the document.
Originally, we had a markdown cell defining a level 1 heading:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-2">
  <div class="code-with-filename-label" id="code-filename-2"><span class="font-mono text-sm">markdown</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"># Corvallis</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>We replace it with a code cell that uses an f-string to produce markdown for a level 1 heading based on the <code>city</code> variable:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-3">
  <div class="code-with-filename-label" id="code-filename-3"><span class="font-mono text-sm">code</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">Markdown(f&#34;# {city}&#34;)</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>In the filtering step the replacement is straightforward, we just change the string to the variable:</p>
<div class="grid gap-12 items-start md:grid-cols-2">
<div class="prose max-w-none">
<p>Before:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-4">
  <div class="code-with-filename-label" id="code-filename-4"><span class="font-mono text-sm">code</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">tmean</span> <span class="o">=</span> <span class="n">tmean_oregon</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pl</span><span class="o">.</span><span class="n">col</span><span class="p">(</span><span class="s2">&#34;city&#34;</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&#34;Corvallis&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
<div class="prose max-w-none">
<p>After:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-5">
  <div class="code-with-filename-label" id="code-filename-5"><span class="font-mono text-sm">code</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">tmean</span> <span class="o">=</span> <span class="n">tmean_oregon</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">pl</span><span class="o">.</span><span class="n">col</span><span class="p">(</span><span class="s2">&#34;city&#34;</span><span class="p">)</span> <span class="o">==</span> <span class="n">city</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
</div>
</div>
<p>Finally, the plot code (using 






<a href="https://plotnine.org" target="_blank" rel="noopener">plotnine</a>
), sets the title of the plot to include the city name:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-6">
  <div class="code-with-filename-label" id="code-filename-6"><span class="font-mono text-sm">code</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">...</span>
</span></span><span class="line"><span class="cl"><span class="o">+</span> <span class="n">labs</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="s2">&#34;Corvallis, OR&#34;</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="o">...</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>We can also use an f-string here to include the <code>city</code> variable:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-7">
  <div class="code-with-filename-label" id="code-filename-7"><span class="font-mono text-sm">code</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="o">...</span>
</span></span><span class="line"><span class="cl"><span class="o">+</span> <span class="n">labs</span><span class="p">(</span><span class="n">title</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">city</span><span class="si">}</span><span class="s2">, OR&#34;</span><span class="p">,</span> <span class="o">...</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="o">...</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Now, we should be able to test our changes by explicitly setting the <code>city</code> variable to something other than &ldquo;Corvallis&rdquo; and re-running the cells.
Since our report is no longer specific to Corvallis, we can rename it <code>climate.ipynb</code>.</p>
<h3 id="2-declare-those-variables-parameters">2. Declare those variables parameters
</h3>
<p>Now we have a variable that represents the parameter, we need to let Quarto know it&rsquo;s a parameter.
Quarto&rsquo;s parameterized reports are implemented using 






<a href="https://papermill.readthedocs.io/en/latest/" target="_blank" rel="noopener">Papermill</a>
, and inherit Papermill&rsquo;s approach: tag the cell defining the parameter with <code>parameters</code>.</p>
<p>In Jupyter, you can add this tag through the cell toolbar:</p>
<img src="https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/corvallis-add-tag.png" data-fig-alt="Screenshot of a Jupyter notebook cell with a tag &#39;parameters&#39; added to it." />
<p>You can see the updated notebook, now a parameterized notebook, on GitHub: 






<a href="hhttps://github.com/cwickham/one-notebook-many-reports/blob/main/02-one-parameterized-report/climate.ipynb"><code>climate.ipynb</code></a>
.</p>
<h3 id="3-render-with-different-parameter-values">3. Render with different parameter values
</h3>
<p>If we render <code>climate.ipynb</code>, it will still produce the same report for Corvallis, because we haven&rsquo;t changed the parameter value:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-8">
  <div class="code-with-filename-label" id="code-filename-8"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">quarto render climate.ipynb</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>But we can now pass parameter values to Quarto with the <code>-P</code> flag:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-9">
  <div class="code-with-filename-label" id="code-filename-9"><span class="font-mono text-sm">Terminal</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Generate report for Portland</span>
</span></span><span class="line"><span class="cl">quarto render climate.ipynb -P city:Portland --output-file portland.pdf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Generate report for Eugene  </span>
</span></span><span class="line"><span class="cl">quarto render climate.ipynb -P city:Eugene --output-file eugene.pdf</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>We&rsquo;ve also added <code>--output-file</code> to ensure each report gets its own filename.</p>
<h3 id="4-automate-rendering-with-many-parameter-values">4. Automate rendering with many parameter values
</h3>
<p>To generate all 50 reports, we need to run <code>quarto render</code> 50 times, each time with a different city as the parameter value.
You could automate this in many ways, but let&rsquo;s use a Python script.
For example, you might have a dataset of cities and their corresponding output filenames:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-10">
  <div class="code-with-filename-label" id="code-filename-10"><span class="font-mono text-sm">gen-reports.py</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">cities</span> <span class="o">=</span> <span class="n">pl</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;city&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;Portland&#34;</span><span class="p">,</span> <span class="s2">&#34;Cottage Grove&#34;</span><span class="p">,</span> <span class="s2">&#34;St. Helens&#34;</span><span class="p">,</span> <span class="s2">&#34;Eugene&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;output_file&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;portland.pdf&#34;</span><span class="p">,</span> <span class="s2">&#34;cottage_grove.pdf&#34;</span><span class="p">,</span> <span class="s2">&#34;st_helens.pdf&#34;</span><span class="p">,</span> <span class="s2">&#34;eugene.pdf&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>I&rsquo;ve generated a small example above, but in reality you would likely read <code>cities</code> in from a file.
Then you could iterate over the rows of this dataset, rendering the notebook for each city:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-11">
  <div class="code-with-filename-label" id="code-filename-11"><span class="font-mono text-sm">gen-reports.py</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">quarto</span> <span class="kn">import</span> <span class="n">render</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">cities</span><span class="o">.</span><span class="n">iter_rows</span><span class="p">(</span><span class="n">named</span><span class="o">=</span><span class="kc">True</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="n">render</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;climate.ipynb&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="n">execute_params</span><span class="o">=</span><span class="p">{</span><span class="s2">&#34;city&#34;</span><span class="p">:</span> <span class="n">row</span><span class="p">[</span><span class="s2">&#34;city&#34;</span><span class="p">]},</span>
</span></span><span class="line"><span class="cl">        <span class="n">output_file</span><span class="o">=</span><span class="n">row</span><span class="p">[</span><span class="s2">&#34;output_file&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Run this script once, and you&rsquo;ll get all 50 custom reports!</p>
<p>You can find the complete working example on GitHub: 






<a href="https://github.com/cwickham/one-notebook-many-reports/tree/main/03-many-reports" target="_blank" rel="noopener">cwickham/one-notebook-many-reports/03-many-reports</a>
.</p>
<h2 id="pretty-reports-brand-and-typst">Pretty Reports: Brand and Typst
</h2>
<p>The steps above to produce parameterized reports apply to any output format supported by Quarto.
However, if you are targeting <code>typst</code> you can take advantage of additional features to create beautiful PDF reports.</p>
<h3 id="brandyml">Brand.yml
</h3>
<p>Quarto supports 






<a href="https://posit-dev.github.io/brand-yml/" target="_blank" rel="noopener">brand.yml</a>
 a way to specify colors, fonts, and logos:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-12">
  <div class="code-with-filename-label" id="code-filename-12"><span class="font-mono text-sm">_brand.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">color</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">palette</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">forest-green</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#2d5a3d&#34;</span><span class="w">     
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">charcoal-grey</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#555555&#34;</span><span class="w">    
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">foreground</span><span class="p">:</span><span class="w"> </span><span class="l">charcoal-grey    </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">primary</span><span class="p">:</span><span class="w"> </span><span class="l">forest-green       </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">typography</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">fonts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">family</span><span class="p">:</span><span class="w"> </span><span class="l">Open Sans</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">source</span><span class="p">:</span><span class="w"> </span><span class="l">google</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">base</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">family</span><span class="p">:</span><span class="w"> </span><span class="l">Open Sans</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">logo</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">medium</span><span class="p">:</span><span class="w"> </span><span class="l">logo.png</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Quarto will detect the <code>_brand.yml</code> file and apply the colors, fonts and logo to your report.
Colors and fonts in your figures will need to be customized in your code, but that is made much easier with the 






<a href="https://posit-dev.github.io/brand-yml/pkg/py/" target="_blank" rel="noopener">brand-yml</a>
 Python package which imports your values from <code>_brand.yml</code>.</p>
<p>You can see a full example of using <code>_brand.yml</code> with <code>climate.ipynb</code> at 






<a href="https://github.com/cwickham/scipy-talk/tree/main/04-branded-reports" target="_blank" rel="noopener">cwickham/one-notebook-many-reports/04-branded-reports</a>
, and learn more about Quarto&rsquo;s support for brand in the 






<a href="https://quarto.org/docs/authoring/brand.html" target="_blank" rel="noopener">Brand guide</a>
.</p>
<h3 id="typst">Typst
</h3>
<p>Learning a little bit of Typst syntax can take your reports from basic to beautiful.
You can include 


  
  
  





<a href="https://quarto.org/docs/output-formats/typst.html#raw-typst" target="_blank" rel="noopener">raw Typst syntax</a>
 in your notebooks, or wrap elements in Typst functions using the 






<a href="https://github.com/christopherkenny/typst-function" target="_blank" rel="noopener">typst-function Quarto extension</a>
.
As an example, you could add a header with the city name and a map of the location:</p>
<figure>
<img src="https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/corvallis-pretty-pdf.png" data-fig-alt="The `corvallis.ipynb` notebook rendered by Quarto to `pdf`. The document has dark green header with the city in white text and a map next to it with the location as an orange dot." alt="corvallis.pdf" />
<figcaption aria-hidden="true"><code>corvallis.pdf</code></figcaption>
</figure>
<p>You can see the source for this example at 






<a href="https://github.com/cwickham/one-notebook-many-reports/tree/main/05-pretty-reports" target="_blank" rel="noopener">cwickham/one-notebook-many-reports/05-pretty-reports</a>
.</p>
<h2 id="jupyter-vs-knitr"><code>jupyter</code> vs <code>knitr</code>
</h2>
<p>The steps for creating a parameterized report above are specific to documents that use the <code>jupyter</code> engine.
With a Jupyter notebook (<code>.ipynb</code>),
or a plain text Quarto document (<code>.qmd</code>) with only Python code cells,
Quarto will default to the <code>jupyter</code> engine.
As described above, the <code>jupyter</code> engine uses cell tags to identify parameters.</p>
<p>If you are working in a <code>.ipynb</code> file, your IDE will likely provide a way to add these tags through the cell toolbar.
If you are working in a <code>.qmd</code> file, you can add tags as a code cell option:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">``<span class="sb">`{python}
</span></span></span><span class="line"><span class="cl"><span class="sb">#| tags: [parameters]
</span></span></span><span class="line"><span class="cl"><span class="sb">city = &#34;Corvallis&#34;
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>``</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>With the <code>jupyter</code> engine, parameters can then be accessed directly as variables, e.g. <code>city</code>, in later code cells.</p>
<p>If you are working in a Quarto document (<code>.qmd</code>) with R code cells, Quarto will default to the <code>knitr</code> engine.
With the <code>knitr</code> engine, you set parameters in the document header under <code>params</code>:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">city</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Corvallis&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>In <code>knitr</code>, parameters are accessed as elements of <code>params</code>, e.g. <code>params$city</code>.</p>
<p>You can read more about setting and using parameters in 






<a href="https://quarto.org/docs/computations/parameters.html" target="_blank" rel="noopener">Guide &gt; Computations &gt; Parameters</a>
.</p>
<h2 id="wrapping-up">Wrapping Up
</h2>
<p>Parameterized reports turn one notebook into many customized outputs.
You&rsquo;ve seen the process of going from a notebook with a hardcoded value to a parameterized report that can be rendered with different values.
You can then automate the rendering in any way you choose to generate dozens of reports at once.</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-07-24_parameterized-reports-python/thumbnail.png" length="381693" type="image/png" />
    </item>
    <item>
      <title>How to use GitHub Codespaces to simplify your Quarto workshops</title>
      <link>https://opensource.posit.co/blog/2025-05-19_quarto-codespaces/</link>
      <pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-05-19_quarto-codespaces/</guid>
      <dc:creator>Mickaël CANOUIL, _Ph.D._</dc:creator><description><![CDATA[<h2 id="what-is-github-codespaces">What Is GitHub Codespaces?
</h2>
<p>






<a href="https://github.com/features/codespaces" target="_blank" rel="noopener">GitHub Codespaces</a>
 is a cloud-powered, on-demand development environment that runs either in your browser or in Visual Studio Code via the 






<a href="https://marketplace.visualstudio.com/items?itemName=GitHub.codespaces" target="_blank" rel="noopener">GitHub Codespaces extension</a>
.
It eliminates the need for lengthy local setup by providing a fully configured development container, complete with all necessary dependencies and tools.
This means that whether you&rsquo;re an instructor or a developer, you can start coding immediately with a consistent environment tailored to your specific project, right on your web browser.</p>
<p>More importantly, the participants of your workshops can use GitHub Codespaces just as easily as you can.
With Codespaces, you and your participants all work on identical environments, minimising the &ldquo;it doesn&rsquo;t work on my machine&rdquo; problems we are all too aware of.</p>
<p>In this post, I am assuming the case of a workshop instructor and a room full of participants with different laptops and operating systems.
Codespaces are also useful for development, though, as you will notice reading on.</p>
<h2 id="the-power-of-combining-quarto-cli-with-codespaces">The Power of Combining Quarto CLI with Codespaces
</h2>
<p>Imagine a world where your participants are instantly equipped with the same environment with all the tools, libraries, and sample projects ready to go in the cloud.
That&rsquo;s the magic of using Codespaces:</p>
<ol>
<li>
<p><strong>Immediate Onboarding:</strong> Workshop participants or students can bypass the hassle of local setup.
They simply launch a Codespace (running on their web browser of choice, independently of operating system), and the pre-configured environment is available immediately.</p>
</li>
<li>
<p><strong>A Consistent Environment:</strong> Ensuring that everyone has the same tools and dependencies can be challenging.
Codespaces lets you pre-define your environment with container configurations, reducing the risk of discrepancies in software versions or settings.</p>
</li>
<li>
<p><strong>Reproducible Workflows:</strong> Whether you&rsquo;re teaching a data science workshop or collaborating on a research paper, reproducibility is crucial.
Because GitHub Codespaces uses the 






<a href="https://containers.dev/" target="_blank" rel="noopener">Dev Container specification</a>
, you can ensure that your code can be run in the same environment.
When participants are ready to run their projects locally, they can use Codespace to build an equivalent Docker container.</p>
</li>
</ol>
<p>GitHub provides 






<a href="https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/setting-up-your-repository/facilitating-quick-creation-and-resumption-of-codespaces" target="_blank" rel="noopener">&ldquo;deep link&rdquo;</a>
 to Codespaces, allowing you to create a link you can share with your students or workshop participants.</p>
<p>For example, the 






<a href="https://github.com/mcanouil/quarto-codespaces" target="_blank" rel="noopener"><code>quarto-codespaces</code> repository</a>
 provides several Dev Container / Codespaces configurations.
The following link will create a new Codespace using the <code>.devcontainer/universal/devcontainer.json</code> configuration file instead of the default <code>.devcontainer/devcontainer.json</code> file.</p>
<p>






<a href="https://codespaces.new/mcanouil/quarto-codespaces?quickstart=1&amp;devcontainer_path=.devcontainer%2Funiversal%2Fdevcontainer.json" target="_blank" rel="noopener"><div class="not-prose"><figure>
    <img class="h-auto max-w-full rounded-lg"
      src="https://github.com/codespaces/badge.svg"
      alt="" 
      loading="lazy"
    >
  </figure></div>
</a>
</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">[<span class="nt">![Open in GitHub Codespaces</span>](<span class="na">https://github.com/codespaces/badge.svg</span>)](https://codespaces.new/mcanouil/quarto-codespaces?quickstart=1&amp;devcontainer_path=.devcontainer%2Funiversal%2Fdevcontainer.json)</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>The link can include a specific branch, a particular file, or even a specific line in a file, allowing you to guide participants directly to the relevant content and setup.
By doing nothing more than clicking that one link, participants create or resume an existing execution environment.</p>
<div class="grid gap-12 items-start md:grid-cols-2">
<div class="prose max-w-none">
<img src="https://opensource.posit.co/blog/2025-05-19_quarto-codespaces/quarto-codespaces-new-001-light.png" data-group="codespaces-light" data-fig-alt="GitHub Codespaces interface showing the &#39;Create codespace&#39; page. The page includes a section with the repository &#39;mcanouil/quarto-codespaces&#39; and a message stating &#39;No codespace to resume&#39;. There are two buttons: &#39;Change options&#39; and &#39;Create new codespace&#39;." />
</div>
<div class="prose max-w-none">
<img src="https://opensource.posit.co/blog/2025-05-19_quarto-codespaces/quarto-codespaces-new-002-light.png" data-group="codespaces-light" data-fig-alt="image_url" alt="Screenshot of Visual Studio Code interface showing a GitHub Codespace for a project named &#39;quarto-codespaces&#39;. The left sidebar contains a file explorer with folders and files such as .devcontainer, .github, init-env.sh, LICENSE, and README.md. The terminal at the bottom displays logs related to configuring the codespace, including commands and their outcomes. The right sidebar has a section titled &#39;Edit with Copilot&#39; explaining how to use Copilot in agent mode." />
</div>
</div>
<h2 id="setting-up-your-own-quarto-codespaces-environment">Setting Up Your Own Quarto-Codespaces Environment
</h2>
<p>If you&rsquo;re considering using Codespaces with Quarto CLI for your next workshop or teaching module, here&rsquo;s how to get started:</p>
<p>Leverage the example provided by the 






<a href="https://github.com/mcanouil/quarto-codespaces" target="_blank" rel="noopener"><code>quarto-codespaces</code> repository</a>
 or 






<a href="https://github.com/codespaces/new/" target="_blank" rel="noopener">create your own Codespaces using the default</a>
.</p>
<h3 id="use-an-existing-docker-image">Use an Existing Docker Image
</h3>
<p>The easiest way to get started is to use an existing Docker image that has Quarto CLI and all the dependencies you need.
There are several pre-built images available with or without the Quarto CLI:</p>
<ul>
<li>Official Docker images:
<ul>
<li>






<a href="https://github.com/quarto-dev/quarto-cli/pkgs/container/quarto" target="_blank" rel="noopener"><code>ghcr.io/quarto-dev/quarto</code></a>
</li>
<li>






<a href="https://github.com/quarto-dev/quarto-cli/pkgs/container/quarto-full" target="_blank" rel="noopener"><code>ghcr.io/quarto-dev/quarto-full</code></a>
</li>
</ul>
</li>
<li>Community Docker images:
<ul>
<li>






<a href="https://github.com/mcanouil/quarto-codespaces/pkgs/container/quarto-codespaces" target="_blank" rel="noopener"><code>ghcr.io/mcanouil/quarto-codespaces</code></a>
</li>
</ul>
</li>
<li>Default Codespaces image:
<ul>
<li>






<a href="https://github.com/devcontainers/images/tree/main/src/universal" target="_blank" rel="noopener"><code>mcr.microsoft.com/devcontainers/universal</code></a>
</li>
</ul>
</li>
</ul>
<p>You can use any of these images as a base for your Codespace.
Inside the <code>.devcontainer/devcontainer.json</code> file, you can specify the image you want to use.
The <code>.devcontainer/devcontainer.json</code> file serves as the blueprint for your Codespace.</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;My Workshop Setup&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;image&#34;</span><span class="p">:</span> <span class="s2">&#34;ghcr.io/mcanouil/quarto-codespaces:latest&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;remoteUser&#34;</span><span class="p">:</span> <span class="s2">&#34;vscode&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;customizations&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;vscode&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;extensions&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;quarto.quarto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;mcanouil.quarto-wizard&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;codespaces&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;openFiles&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;exercises/intro-to-quarto.qmd&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;exercises/computation.qmd&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<dl>
<dt>Line 3</dt>
<dd>The Docker image is specified in the <code>image</code> field.
It&rsquo;s built using a Dev Container specification that you can find in 






<a href="https://github.com/mcanouil/quarto-codespaces/tree/main/.github/.devcontainer" target="_blank" rel="noopener"><code>.github/.devcontainer</code></a>
.</dd>
<dt>Line 8</dt>
<dd>The 






<a href="https://github.com/quarto-dev/quarto" target="_blank" rel="noopener"><code>quarto</code> extension</a>
 for Visual Studio Code / Positron to provide support for Quarto documents.</dd>
<dt>Line 9</dt>
<dd>The 






<a href="https://github.com/mcanouil/quarto-wizard" target="_blank" rel="noopener"><code>quarto-wizard</code> extension</a>
 for Visual Studio Code / Positron to provide assistance in managing Quarto extensions</dd>
<dt>Line 13</dt>
<dd>The <code>openFiles</code> field specifies the files to open when the Codespace is created.
This is useful for guiding participants to the right files or folders.
See the 






<a href="https://docs.github.com/en/codespaces/setting-up-your-project-for-codespaces/configuring-dev-containers/automatically-opening-files-in-the-codespaces-for-a-repository" target="_blank" rel="noopener">Codespaces documentation</a>
 for more information.</dd>
</dl>
<h3 id="configure-the-development-container">Configure the Development Container
</h3>
<p>You can fork the 






<a href="https://github.com/mcanouil/quarto-codespaces" target="_blank" rel="noopener"><code>quarto-codespaces</code> repository</a>
 as a starting point for your own Codespaces.
This repository includes the Dev Container configuration file (<em>i.e.</em>, <code>.devcontainer/devcontainer.json</code>) that instruct Codespaces on how to set up an environment complete with Quarto CLI and other essential tools.</p>
<p>The <code>.devcontainer/devcontainer.json</code> configuration file ensures that every instance of your Codespace is identical, capturing everything from the Quarto CLI version to additional libraries or extensions you might need.</p>
<p>The 






<a href="https://github.com/mcanouil/quarto-codespaces" target="_blank" rel="noopener"><code>quarto-codespaces</code> repository</a>
 is a great starting point as it provides a prebuilt Docker image with the latest Quarto CLI, Python, R, and Julia installed (<em>i.e.</em>, 






<a href="https://github.com/mcanouil/quarto-codespaces/pkgs/container/quarto-codespaces" target="_blank" rel="noopener"><code>ghcr.io/mcanouil/quarto-codespaces</code></a>
 using 






<a href="https://github.com/mcanouil/quarto-codespaces/tree/main/.github/.devcontainer" target="_blank" rel="noopener"><code>.github/.devcontainer/devcontainer.json</code></a>
).</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;Quarto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// &#34;image&#34;: &#34;buildpack-deps:jammy-curl&#34;,
</span></span></span><span class="line"><span class="cl">  <span class="nt">&#34;build&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;dockerfile&#34;</span><span class="p">:</span> <span class="s2">&#34;./Dockerfile&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;context&#34;</span><span class="p">:</span> <span class="s2">&#34;.&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;args&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;VARIANT&#34;</span><span class="p">:</span> <span class="s2">&#34;jammy&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;remoteUser&#34;</span><span class="p">:</span> <span class="s2">&#34;vscode&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;features&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;./quarto-computing-dependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;rDeps&#34;</span><span class="p">:</span> <span class="s2">&#34;rmarkdown,languageserver,nx10/httpgd@v2.0.3,prompt,lintr&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;pythonDeps&#34;</span><span class="p">:</span> <span class="s2">&#34;jupyter,papermill&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;juliaDeps&#34;</span><span class="p">:</span> <span class="s2">&#34;IJulia&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;./uv&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;latest&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;ghcr.io/rocker-org/devcontainer-features/quarto-cli:1&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;release&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;installTinyTex&#34;</span><span class="p">:</span> <span class="s2">&#34;true&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;installChromium&#34;</span><span class="p">:</span> <span class="s2">&#34;false&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;customizations&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;vscode&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;extensions&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;quarto.quarto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;mcanouil.quarto-wizard&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;REditorSupport.r&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;Posit.air-vscode&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;r.rterm.option&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;--no-save&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;--no-restore-data&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;--quiet&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;[r]&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;editor.defaultFormatter&#34;</span><span class="p">:</span> <span class="s2">&#34;Posit.air-vscode&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;editor.formatOnSave&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<dl>
<dt>Line 3</dt>
<dd>The <code>image</code> field specifies the base image for the container.
You can customise this to suit your needs.</dd>
<dt>Line 12</dt>
<dd>The <code>features</code> section allows you to add additional tools or libraries.
See the 






<a href="https://containers.dev/features/" target="_blank" rel="noopener">Dev Container Features available</a>
 for a comprehensive list of available features.</dd>
<dt>Line 13</dt>
<dd>The <code>quarto-computing-dependencies</code> feature is a &ldquo;local&rdquo; custom feature that installs the computing dependencies: R, Python, and Julia.
This is a great way to ensure that your Codespace has everything it needs to run Quarto documents.</dd>
<dt>Line 18</dt>
<dd>The <code>uv</code> feature installs the 






<a href="https://docs.astral.sh/uv/" target="_blank" rel="noopener"><code>uv</code> tool</a>
 to manage Python packages and project dependencies.</dd>
<dt>Line 21</dt>
<dd>The <code>quarto-cli</code> feature installs the Quarto CLI.
You can specify the version you want to install, and it will be automatically downloaded and installed in your Codespace.
You can see the code for this feature in the source repository: 






<a href="https://github.com/rocker-org/devcontainer-features/tree/main/src/quarto-cli" target="_blank" rel="noopener">https://github.com/rocker-org/devcontainer-features/tree/main/src/quarto-cli</a>
.</dd>
<dt>Line 27</dt>
<dd>The <code>customizations</code> section allows you to specify settings and extensions for Visual Studio Code.</dd>
</dl>
<p>You can also add additional features to the <code>devcontainer.json</code> to suit your needs or start directly using the image as is as shown in 


  
  
  





<a href="#use-existing-docker-image">Use an Existing Docker Image</a>
.</p>
<p>For example, you might want to add additional R packages or Python libraries.
You can do this by using the <code>quarto-computing-dependencies</code> custom feature and changing the <code>rDeps</code>, <code>pythonDeps</code>, and <code>juliaDeps</code> fields to include the packages you want to install globally, or by using the <code>postStartCommand</code> field to run a script that installs the packages you need.</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;My Workshop Setup&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;image&#34;</span><span class="p">:</span> <span class="s2">&#34;ghcr.io/mcanouil/quarto-codespaces:latest&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;remoteUser&#34;</span><span class="p">:</span> <span class="s2">&#34;vscode&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;postStartCommand&#34;</span><span class="p">:</span> <span class="s2">&#34;uv venv &amp;&amp; source .venv/bin/activate &amp;&amp; uv pip install -r requirements.txt&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>You can also use the <code>postStartCommand</code> field to run a script that installs the packages you need.</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;My Workshop Setup&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;image&#34;</span><span class="p">:</span> <span class="s2">&#34;ghcr.io/mcanouil/quarto-codespaces:latest&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;remoteUser&#34;</span><span class="p">:</span> <span class="s2">&#34;vscode&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;postStartCommand&#34;</span><span class="p">:</span> <span class="s2">&#34;bash ./init-env.sh --what all --force&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<dl>
<dt>Line 5</dt>
<dd>The <code>postStartCommand</code> field specifies a command to run after the Codespace is started.
In this case, it runs the 






<a href="https://github.com/mcanouil/quarto-codespaces/blob/main/init-env.sh" target="_blank" rel="noopener"><code>init-env.sh</code> script</a>
 from 






<a href="https://github.com/mcanouil/quarto-codespaces" target="_blank" rel="noopener"><code>quarto-codespaces</code> repository</a>
 with the <code>--what all</code> and <code>--force</code> options.</dd>
</dl>
<h2 id="benefits-for-workshops-and-teaching">Benefits for Workshops and Teaching
</h2>
<p>When it comes to educational sessions, consistency and ease-of-use are paramount.
Pairing Codespaces with Quarto CLI brings many direct benefits to a teaching environment:</p>
<ul>
<li><strong>Streamlined Onboarding:</strong> Students and workshop attendees can get right to work without spending time installing and configuring local environments.</li>
<li><strong>Live, Interactive Sessions:</strong> Instructors can demonstrate live edits to Quarto documents.
Changes can be rendered instantly and reflect in each participant&rsquo;s environment: perfect for a hands-on, interactive learning experience.</li>
<li><strong>Collaboration and Version Control:</strong> All changes can be recorded in Git, making it easy to track progress, handle peer reviews, and manage collaborative projects, all within a single hosted environment.</li>
<li><strong>Elimination of &ldquo;Dependency Hell&rdquo;:</strong> With containerised development, all attendees work from the same baseline, ensuring that version conflicts or missing libraries don&rsquo;t derail a session.</li>
</ul>
<h2 id="final-thoughts-and-future-directions">Final Thoughts and Future Directions
</h2>
<p>Whether you&rsquo;re running a workshop, teaching a class, or collaborating on research, using Codespaces can reduce setup hassles, foster reproducibility, and encourage interactive learning.</p>
<p>In addition to the benefits mentioned above, other features further enhance your experience with Codespaces and Quarto CLI:</p>
<ul>
<li><strong>Automated Pipelines:</strong> Integrating CI/CD tools to automatically validate Quarto document renders and catch errors using the exact same environment.
See 






<a href="https://docs.github.com/en/actions/writing-workflows/choosing-where-your-workflow-runs/running-jobs-in-a-container" target="_blank" rel="noopener">GitHub Actions: Running jobs in a container</a>
</li>
<li><strong>Real-Time Co-Editing Features:</strong> Enhancing collaborative sessions with simultaneous multi-user editing directly in Codespaces.
See 






<a href="https://docs.github.com/en/codespaces/developing-in-a-codespace/working-collaboratively-in-a-codespace" target="_blank" rel="noopener">GitHub Codespaces: Real-time collaboration</a>
</li>
</ul>
<p>This post covered the basics of using Codespaces and Quarto together, but there&rsquo;s much more to Codespaces.
Learn more by 






<a href="https://docs.github.com/en/codespaces" target="_blank" rel="noopener">consulting their documentation</a>
.</p>
<p>Happy teaching!</p>
<h2 id="disclaimer">Disclaimer
</h2>
<p>GitHub Codespaces is a product of GitHub, Inc. and comes with a quota of free usage, including CPU hours and storage.
Be sure to check the 






<a href="https://docs.github.com/en/billing/managing-billing-for-your-products/managing-billing-for-github-codespaces/about-billing-for-github-codespaces" target="_blank" rel="noopener">GitHub Codespaces billing documentation</a>
 and your current GitHub plan to avoid unexpected charges.
If you are a student or an educator, you can explore the 






<a href="https://education.github.com/pack" target="_blank" rel="noopener">GitHub Education program</a>
 and 






<a href="https://docs.github.com/en/education/manage-coursework-with-github-classroom/integrate-github-classroom-with-an-ide/using-github-codespaces-with-github-classroom" target="_blank" rel="noopener">GitHub Classroom</a>
.</p>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>Thanks to 






<a href="https://github.com/cscheid" target="_blank" rel="noopener">Carlos Scheidegger</a>
, 






<a href="https://github.com/juliasilge" target="_blank" rel="noopener">Julia Silge</a>
, and 






<a href="https://github.com/coatless" target="_blank" rel="noopener">James J. Balamuta</a>
 for their feedback and suggestions on this post.</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-05-19_quarto-codespaces/featured.png" length="76636" type="image/png" />
    </item>
    <item>
      <title>Quarto 1.7</title>
      <link>https://opensource.posit.co/blog/2025-04-28_1.7-release/</link>
      <pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-04-28_1.7-release/</guid>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<p>Quarto 1.7 is out! You can get the current release from the 






<a href="https://quarto.org/docs/download/index.html" target="_blank" rel="noopener">download page</a>
.</p>
<p>We are especially enthusiastic about the improvements 1.7 brings to dark mode: you can now specify light and dark themes via brand, map computational outputs to themes, and have your website theme follow your viewer&rsquo;s preference.
To celebrate these changes, this site, 





  


<a href="https://opensource.posit.co/.">quarto.org</a>
, now has a light and dark mode.
Toggle the switch in the navigation bar (<i></i>) to see the difference.</p>
<p>You can read about these improvements and some other highlights below. You can find all the changes in this version in the 






<a href="https://quarto.org/docs/download/changelog/1.7/" target="_blank" rel="noopener">Release Notes</a>
.</p>
<h2 id="dark-mode-improvements">Dark Mode Improvements
</h2>
<h3 id="specify-light-and-dark-themes-via-brandyml">Specify light and dark themes via <strong>brand.yml</strong>
</h3>
<p>You can now specify a light and dark brand.
For example, at a project-level you can provide two brand files:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">_quarto.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">brand</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">light</span><span class="p">:</span><span class="w"> </span><span class="l">light-brand.yml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">dark</span><span class="p">:</span><span class="w"> </span><span class="l">dark-brand.yml</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Standalone HTML pages, websites, and dashboards will gain a light switch toggle allowing viewers to switch between the light and dark themes.</p>
<div class="grid gap-12 items-start md:grid-cols-2">
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2025-04-28_1.7-release/light.png" data-fig-alt="Screenshot of a webpage with a light blue body and charcoal text. A switch toggle in the navbar is &#39;off&#39;." alt="light brand" />
<figcaption aria-hidden="true"><code>light</code> brand</figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://opensource.posit.co/blog/2025-04-28_1.7-release/dark.png" data-fig-alt="Screenshot of a webpage with a dark charcoal body and light blue text. A switch toggle in the navbar is &#39;on&#39;." alt="dark brand" />
<figcaption aria-hidden="true"><code>dark</code> brand</figcaption>
</figure>
</div>
</div>
<p>By default Typst documents will use the light brand, but you can set the <code>brand-mode</code> option to use the dark brand instead:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-1">
  <div class="code-with-filename-label" id="code-filename-1"><span class="font-mono text-sm">document.qmd</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nn">---</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">typst</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">brand-mode</span><span class="p">:</span><span class="w"> </span><span class="l">dark</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nn">---</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Read about other ways to set a light and dark brand in 


  
  
  





<a href="https://quarto.org/docs/authoring/brand.html#dark-brand" target="_blank" rel="noopener">Guide &gt; Brand</a>
.</p>
<h3 id="map-computational-outputs-to-themes">Map computational outputs to themes
</h3>
<p>A new code cell option, <code>renderings</code>, allows you to indicate which computational outputs should be displayed in light and dark mode.
Create light and dark versions of your outputs in a single code cell,
and add the option <code>renderings</code> to specify the order of the outputs.
For example, this cell creates a <code>light</code> version of a plot,
then a <code>dark</code> version:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">``<span class="sb">`{r}
</span></span></span><span class="line"><span class="cl"><span class="sb">#| renderings: [light, dark]
</span></span></span><span class="line"><span class="cl"><span class="sb">plot(1:10) # Shown in `</span>light<span class="sb">` mode
</span></span></span><span class="line"><span class="cl"><span class="sb">
</span></span></span><span class="line"><span class="cl"><span class="sb">par(bg = &#34;#000000&#34;, fg = &#34;#FFFFFF&#34;, col.axis = &#34;#FFFFFF&#34;)
</span></span></span><span class="line"><span class="cl"><span class="sb">plot(1:10) # Shown in `</span>dark<span class="sb">` mode
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>``</span></span></code></pre></td></tr></table>
</div>
</div></div>
<img src="https://opensource.posit.co/blog/2025-04-28_1.7-release/index.markdown_strict_files/figure-markdown_strict/unnamed-chunk-1-1.png" width="768" />
<img src="https://opensource.posit.co/blog/2025-04-28_1.7-release/index.markdown_strict_files/figure-markdown_strict/unnamed-chunk-1-2.png" width="768" />
<p>Both outputs are produced, but you&rsquo;ll only see the one corresponding to the current state of the light switch.
Toggle the switch in the navigation bar to see the image change to reflect the theme.</p>
<h3 id="respect-user-color-scheme">Respect user color scheme
</h3>
<p>Set the new <code>html</code> format option <code>respect-user-color-scheme</code> to <code>true</code> if you would like your site to honor the viewer&rsquo;s operating system or browser preference for light or dark mode:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-3">
  <div class="code-with-filename-label" id="code-filename-3"><span class="font-mono text-sm">_quarto.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">format</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">html</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">respect-user-color-scheme</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<h2 id="other-highlights">Other Highlights
</h2>
<ul>
<li>
<p>Typst updated to 0.13.0</p>
</li>
<li>
<p>Pandoc updated to 3.6.3</p>
</li>
<li>
<p>New 






<a href="https://quarto.org/docs/authoring/version.html" target="_blank" rel="noopener"><code>version</code> shortcode</a>
 to insert the version of Quarto used to build your document:</p>
<div class="grid gap-12 items-center md:grid-cols-2">
<div class="prose max-w-none">
<p>Rendered with Quarto 1.9.36</p>
</div>
</div>
</li>
<li>
<p>Updated LaTeX and Beamer template partials:</p>
<ul>
<li>


  
  
  





<a href="https://quarto.org/docs/journals/templates.html#latex-partials" target="_blank" rel="noopener">LaTeX partials</a>
</li>
<li>


  
  
  





<a href="https://quarto.org/docs/journals/templates.html#beamer-partials" target="_blank" rel="noopener">Beamer partials</a>
</li>
</ul>
<p>These changes reflect the updates made in Pandoc 3.5 to separate the LaTeX and Beamer document templates and introduce some additional partials for both.
If you have custom formats that provide custom templates or partials, you may need to update them to work with the new partials.</p>
</li>
<li>
<p>Improvements to the <code>julia</code> engine:</p>
<ul>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/computations/julia.html#juliaup-integration" target="_blank" rel="noopener"><code>juliaup</code> integration</a>
: Use specific versions of Julia in your notebooks.</p>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/computations/julia.html#r-and-python-support" target="_blank" rel="noopener">R and Python support</a>
: Include <code>{r}</code> and <code>{python}</code> executable code cells via the RCall and PythonCall packages.</p>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/computations/julia.html#caching-julia" target="_blank" rel="noopener">Caching</a>
: Save time rendering long-running notebooks by caching results.</p>
</li>
<li>
<p>


  
  
  





<a href="https://quarto.org/docs/computations/julia.html#revise.jl-integration" target="_blank" rel="noopener">Revise.jl integration</a>
: Automatically update function definitions in Julia sessions.</p>
</li>
</ul>
</li>
</ul>
<h2 id="acknowledgements">Acknowledgements
</h2>
<p>We&rsquo;d like to say a huge thank you to everyone who contributed to this release by opening issues and pull requests:</p>
<p>






<a href="https://github.com/AndreasThinks" target="_blank" rel="noopener">AndreasThinks</a>
,







<a href="https://github.com/ArthurData" target="_blank" rel="noopener">ArthurData</a>
,







<a href="https://github.com/BrendonChau" target="_blank" rel="noopener">BrendonChau</a>
,







<a href="https://github.com/DanStuder" target="_blank" rel="noopener">DanStuder</a>
,







<a href="https://github.com/DavidFirth" target="_blank" rel="noopener">DavidFirth</a>
,







<a href="https://github.com/Eli-78-fas" target="_blank" rel="noopener">Eli-78-fas</a>
,







<a href="https://github.com/EllaKaye" target="_blank" rel="noopener">EllaKaye</a>
,







<a href="https://github.com/EmilHvitfeldt" target="_blank" rel="noopener">EmilHvitfeldt</a>
,







<a href="https://github.com/EvoArt" target="_blank" rel="noopener">EvoArt</a>
,







<a href="https://github.com/FMKerckhof" target="_blank" rel="noopener">FMKerckhof</a>
,







<a href="https://github.com/FrankwaP" target="_blank" rel="noopener">FrankwaP</a>
,







<a href="https://github.com/JanPalasek" target="_blank" rel="noopener">JanPalasek</a>
,







<a href="https://github.com/Jocarnail" target="_blank" rel="noopener">Jocarnail</a>
,







<a href="https://github.com/MHellmund" target="_blank" rel="noopener">MHellmund</a>
,







<a href="https://github.com/MichaelHatherly" target="_blank" rel="noopener">MichaelHatherly</a>
,







<a href="https://github.com/Noghpu" target="_blank" rel="noopener">Noghpu</a>
,







<a href="https://github.com/PeneLoopy" target="_blank" rel="noopener">PeneLoopy</a>
,







<a href="https://github.com/Rafnuss" target="_blank" rel="noopener">Rafnuss</a>
,







<a href="https://github.com/SergeCroise" target="_blank" rel="noopener">SergeCroise</a>
,







<a href="https://github.com/TonyFly3000" target="_blank" rel="noopener">TonyFly3000</a>
,







<a href="https://github.com/actuaristai" target="_blank" rel="noopener">actuaristai</a>
,







<a href="https://github.com/alex-r-bigelow" target="_blank" rel="noopener">alex-r-bigelow</a>
,







<a href="https://github.com/andrewheiss" target="_blank" rel="noopener">andrewheiss</a>
,







<a href="https://github.com/ant-durrant" target="_blank" rel="noopener">ant-durrant</a>
,







<a href="https://github.com/antoine4ucsd" target="_blank" rel="noopener">antoine4ucsd</a>
,







<a href="https://github.com/arnaudgallou" target="_blank" rel="noopener">arnaudgallou</a>
,







<a href="https://github.com/aronatkins" target="_blank" rel="noopener">aronatkins</a>
,







<a href="https://github.com/arthurgailes" target="_blank" rel="noopener">arthurgailes</a>
,







<a href="https://github.com/bkowshik" target="_blank" rel="noopener">bkowshik</a>
,







<a href="https://github.com/boshek" target="_blank" rel="noopener">boshek</a>
,







<a href="https://github.com/cbrnr" target="_blank" rel="noopener">cbrnr</a>
,







<a href="https://github.com/cl-roberts" target="_blank" rel="noopener">cl-roberts</a>
,







<a href="https://github.com/cmadland" target="_blank" rel="noopener">cmadland</a>
,







<a href="https://github.com/coatless" target="_blank" rel="noopener">coatless</a>
,







<a href="https://github.com/deepayan" target="_blank" rel="noopener">deepayan</a>
,







<a href="https://github.com/devmcp" target="_blank" rel="noopener">devmcp</a>
,







<a href="https://github.com/dhimmel" target="_blank" rel="noopener">dhimmel</a>
,







<a href="https://github.com/dkapitan" target="_blank" rel="noopener">dkapitan</a>
,







<a href="https://github.com/dmenne" target="_blank" rel="noopener">dmenne</a>
,







<a href="https://github.com/eamcvey" target="_blank" rel="noopener">eamcvey</a>
,







<a href="https://github.com/edavidaja" target="_blank" rel="noopener">edavidaja</a>
,







<a href="https://github.com/fredguth" target="_blank" rel="noopener">fredguth</a>
,







<a href="https://github.com/fuhrmanator" target="_blank" rel="noopener">fuhrmanator</a>
,







<a href="https://github.com/gadenbuie" target="_blank" rel="noopener">gadenbuie</a>
,







<a href="https://github.com/apps/github-actions" target="_blank" rel="noopener">github-actions[bot]</a>
,







<a href="https://github.com/glin" target="_blank" rel="noopener">glin</a>
,







<a href="https://github.com/gwbrck" target="_blank" rel="noopener">gwbrck</a>
,







<a href="https://github.com/hchulkim" target="_blank" rel="noopener">hchulkim</a>
,







<a href="https://github.com/hguturu" target="_blank" rel="noopener">hguturu</a>
,







<a href="https://github.com/hturner" target="_blank" rel="noopener">hturner</a>
,







<a href="https://github.com/ihrke" target="_blank" rel="noopener">ihrke</a>
,







<a href="https://github.com/jdutant" target="_blank" rel="noopener">jdutant</a>
,







<a href="https://github.com/jenslaufer" target="_blank" rel="noopener">jenslaufer</a>
,







<a href="https://github.com/jkrumbiegel" target="_blank" rel="noopener">jkrumbiegel</a>
,







<a href="https://github.com/jmgirard" target="_blank" rel="noopener">jmgirard</a>
,







<a href="https://github.com/joelostblom" target="_blank" rel="noopener">joelostblom</a>
,







<a href="https://github.com/kandolfp" target="_blank" rel="noopener">kandolfp</a>
,







<a href="https://github.com/kapsner" target="_blank" rel="noopener">kapsner</a>
,







<a href="https://github.com/kazuyanagimoto" target="_blank" rel="noopener">kazuyanagimoto</a>
,







<a href="https://github.com/kdheepak" target="_blank" rel="noopener">kdheepak</a>
,







<a href="https://github.com/kingo55" target="_blank" rel="noopener">kingo55</a>
,







<a href="https://github.com/knuesel" target="_blank" rel="noopener">knuesel</a>
,







<a href="https://github.com/kubu4" target="_blank" rel="noopener">kubu4</a>
,







<a href="https://github.com/kv9898" target="_blank" rel="noopener">kv9898</a>
,







<a href="https://github.com/kylie-foster" target="_blank" rel="noopener">kylie-foster</a>
,







<a href="https://github.com/loneguardian" target="_blank" rel="noopener">loneguardian</a>
,







<a href="https://github.com/lwjohnst86" target="_blank" rel="noopener">lwjohnst86</a>
,







<a href="https://github.com/ma2048" target="_blank" rel="noopener">ma2048</a>
,







<a href="https://github.com/markjholmes" target="_blank" rel="noopener">markjholmes</a>
,







<a href="https://github.com/maurosilber" target="_blank" rel="noopener">maurosilber</a>
,







<a href="https://github.com/mipmip" target="_blank" rel="noopener">mipmip</a>
,







<a href="https://github.com/mroavi" target="_blank" rel="noopener">mroavi</a>
,







<a href="https://github.com/mroberts1" target="_blank" rel="noopener">mroberts1</a>
,







<a href="https://github.com/msh855" target="_blank" rel="noopener">msh855</a>
,







<a href="https://github.com/mvuorre" target="_blank" rel="noopener">mvuorre</a>
,







<a href="https://github.com/nathanj3" target="_blank" rel="noopener">nathanj3</a>
,







<a href="https://github.com/odysseu" target="_blank" rel="noopener">odysseu</a>
,







<a href="https://github.com/parmsam" target="_blank" rel="noopener">parmsam</a>
,







<a href="https://github.com/peter-gy" target="_blank" rel="noopener">peter-gy</a>
,







<a href="https://github.com/pvelayudhan" target="_blank" rel="noopener">pvelayudhan</a>
,







<a href="https://github.com/raffaem" target="_blank" rel="noopener">raffaem</a>
,







<a href="https://github.com/robmcd" target="_blank" rel="noopener">robmcd</a>
,







<a href="https://github.com/ryanzomorrodi" target="_blank" rel="noopener">ryanzomorrodi</a>
,







<a href="https://github.com/stragu" target="_blank" rel="noopener">stragu</a>
,







<a href="https://github.com/sun123zxy" target="_blank" rel="noopener">sun123zxy</a>
,







<a href="https://github.com/t-kalinowski" target="_blank" rel="noopener">t-kalinowski</a>
,







<a href="https://github.com/temospena" target="_blank" rel="noopener">temospena</a>
,







<a href="https://github.com/tjni" target="_blank" rel="noopener">tjni</a>
,







<a href="https://github.com/torven-schalk" target="_blank" rel="noopener">torven-schalk</a>
,







<a href="https://github.com/turcotte" target="_blank" rel="noopener">turcotte</a>
,







<a href="https://github.com/wenyaoliu" target="_blank" rel="noopener">wenyaoliu</a>
,







<a href="https://github.com/yhkee0404" target="_blank" rel="noopener">yhkee0404</a>
.</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-04-28_1.7-release/thumbnail-1.7.jpeg" length="90331" type="image/jpeg" />
    </item>
    <item>
      <title>Tip - use Positron to choose colors for your project brand</title>
      <link>https://opensource.posit.co/blog/2025-01-15_quarto-tip-brand-positron/</link>
      <pubDate>Wed, 15 Jan 2025 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2025-01-15_quarto-tip-brand-positron/</guid>
      <dc:creator>Carlos Scheidegger</dc:creator><description><![CDATA[<p>In today&rsquo;s Quarto Tip, we show you how 






<a href="https://positron.posit.co" target="_blank" rel="noopener">Positron</a>

enables a very easy workflow for creating and changing colors in your <code>_brand.yml</code>
file. Quarto 1.6 includes 






<a href="https://posit-dev.github.io/brand-yml/" target="_blank" rel="noopener">support for <code>_brand.yml</code></a>
, a
standard for creating a single style configuration file that is usable across formats and
systems.</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/Mly_DK-2BnI"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<p>Additional links:</p>
<ul>
<li>






  
  

<a href="https://opensource.posit.co/blog/2024-11-25_1.6-release/">Quarto 1.6 release post</a>
</li>
<li>






<a href="https://positron.posit.co/download.html" target="_blank" rel="noopener">Download Positron</a>
</li>
<li>






<a href="https://quarto.org/docs/authoring/brand.html" target="_blank" rel="noopener">Quarto&rsquo;s <code>_brand.yml</code> documentation</a>
</li>
</ul>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2025-01-15_quarto-tip-brand-positron/brand.png" length="165176" type="image/png" />
    </item>
    <item>
      <title>Use `meta` &#43; `include` to customize reusable content</title>
      <link>https://opensource.posit.co/blog/2024-12-12_includes-meta/</link>
      <pubDate>Thu, 12 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2024-12-12_includes-meta/</guid>
      <dc:creator>Ashley Henry</dc:creator><description><![CDATA[<div class="callout callout-tip" role="note" aria-label="Tip">
<div class="callout-header">
<span class="callout-title">Re-posted from posit.co</span>
</div>
<div class="callout-body">
<p>This post was originally published on the 






<a href="https://posit.co/blog/quarto-meta-shortcode-variables/" target="_blank" rel="noopener">Posit Blog</a>
.</p>
<p>The worked example below is also available at: 






<a href="https://github.com/quarto-dev/quarto-examples/tree/main/websites/quarto-meta-includes" target="_blank" rel="noopener">Source</a>
 | 






<a href="https://examples.quarto.pub/quarto-meta-includes/" target="_blank" rel="noopener">Live Website</a>
</p>
</div>
</div>
<p>There may be times when you would like to single-source content across multiple pages/files to reduce the risk of errors, produce consistent content that is easy to maintain, and ultimately save valuable time. 






<a href="https://quarto.org/" target="_blank" rel="noopener">Quarto</a>
 (an open-source technical publishing system), provides an 






<a href="https://quarto.org/docs/authoring/includes.html" target="_blank" rel="noopener">Includes</a>
 feature (the equivalent of an R Markdown &ldquo;child&rdquo; document) that allows you to reuse content across multiple documents/files/pages.</p>
<p>To achieve this, simply create chunks of content (text, tables, code, callouts, images, etc.) and then insert it using the Include shortcode: <code>{{&lt; include _content.qmd &gt;}}</code>.</p>
<p>Typically, you must keep your content general enough so it can be reused in several places. In other words, if you needed to add a name or an image that is specific to that file, you would assume that you wouldn&rsquo;t be able to use an include, or you would have to use several smaller includes sewn into uniquely written content.</p>
<p>But what if you need your single-sourced content to be more specific? You can use Includes with <code>meta</code> shortcode (variables) to add precise values defined at the file level.</p>
<h2 id="walkthrough-example">Walkthrough example
</h2>
<p>Let us walk you through an example of how to achieve this.</p>
<p>Before you begin:</p>
<ul>
<li>Quarto version 1.5+ was used for this walkthrough example.</li>
<li>This has been tested with both new and existing Website projects.</li>
<li>A <code>var</code> shortcode enables you to insert content from the project or file level.</li>
<li>The <code>meta</code> shortcode allows you to insert content from Pandoc metadata (e.g., YAML at the top of the document and/or in <code>_quarto.yml</code>).</li>
<li>As you preview your site, pages will be rendered and updated. However, if you make changes to global options (e.g. <code>_quarto.yml</code> or included files) you need to fully re-render your site to have all of the changes reflected. Consequently, you should always fully <code>quarto render</code> your site before deploying it, even if you have already previewed changes to some pages with the preview server.</li>
</ul>
<h3 id="create-the-content">Create the content:
</h3>
<p>Here is an example of a file with content we want to reuse across several pages.</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">In this document, we cover facts that are unique to the state, like the state&#39;s population, its flower, and animal.</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>This content is general enough to use as each state&rsquo;s introduction but lacks the facts that are unique to each state. So, we could insert the Include into each state&rsquo;s file and then add specific content that is unique to the state:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: New York
</span></span><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{&lt; include _snippets/state-intro.qmd &gt;}}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">New York has a geographical size of 54,555, making it the 27th largest state with an estimated population size of 19.8 million.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">The state&#39;s flower is the Rose, as shown below:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">![](images/ny/flower.png)</span></span></code></pre></td></tr></table>
</div>
</div></div>
<h3 id="why-are-we-doing-this">Why are we doing this?
</h3>
<p>Instead of copying and pasting this content into each file, and then updating it with each state&rsquo;s fact (which introduces a higher risk of making an error), we can use meta variables to insert specific values.</p>
<h3 id="lets-execute">Let&rsquo;s execute
</h3>
<p>First, I create a file within my <code>_snippets</code> directory named <code>facts.qmd</code>. Throughout the file, I am going to insert a unique <code>meta</code> variable for each occurrence that I want the content to be specific to the state:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">{{&lt; meta state &gt;}} covers approximately {{&lt; meta square-miles &gt;}} making it the {{&lt; meta size-rank &gt;}} largest state in the United States. As of 2023, {{&lt; meta state &gt;}} has an approximate population of about {{&lt; meta population &gt;}}.</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>I can define each of the <code>meta</code> variables within the individual file that I plan on reusing this content. So, in my <code>ny.qmd</code> file, I define each variable in the YAML metadata. Then, insert the <code>facts.qmd</code> file with the undefined meta shortcodes using an include:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: New York
</span></span><span class="line"><span class="cl">state-abbr: ny
</span></span><span class="line"><span class="cl">state: New York
</span></span><span class="line"><span class="cl">size-rank: 27th
</span></span><span class="line"><span class="cl">square-miles: 54,555
</span></span><span class="line"><span class="cl">population: 19.8 million
</span></span><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{&lt; include _snippets/facts.qmd &gt;}}</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>As you can see, the rendered file has the meta shortcodes populated with the definitions that you assigned to each value in the file&rsquo;s YAML.</p>
<img src="https://opensource.posit.co/blog/2024-12-12_includes-meta/images/img1.png" style="box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); border-radius: 5px;" data-fig-align="center" />
<p>But, I would also like to add the state&rsquo;s flower and animal with images of each. You can achieve this by editing the document to add this information and images:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">{{&lt; include _snippets/facts.qmd &gt;}}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">New York&#39;s official flower is the Rose:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">![](../images/ny/flower.png)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">And the official animal is the Beaver:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">![](../images/ny/animal.png)</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Or, you can get creative and use <code>meta</code> shortcodes in your image paths so you can continue to manage all of the content in a single file:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">{{&lt; meta state &gt;}}&#39;s official flower is the {{&lt; meta flower &gt;}}, pictured below:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">![<span class="nt">The official {{&lt; meta state &gt;}} state flower, the {{&lt; meta flower &gt;}}</span>](<span class="na">../images/{{&lt; meta state-abbr &gt;}}/flower.png</span>)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Lastly, {{&lt; meta state &gt;}}&#39;s official animal is the {{&lt; meta animal &gt;}}, pictured below:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">![<span class="nt">The official {{&lt; meta state &gt;}} state animal, the {{&lt; meta animal &gt;}}</span>](<span class="na">../images/{{&lt; meta state-abbr &gt;}}/animal.png</span>)</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>As you can see, my image paths have <code>{{&lt; meta state-abbr &gt;}}</code> which is defined in the new-york file as &ldquo;ny&rdquo;.</p>
<p>When we render the project, the image path updates to /images/ny/flower.png pointing to the existing flower image in the <code>ny</code> directory:</p>
<img src="https://opensource.posit.co/blog/2024-12-12_includes-meta/images/img2.png" style="box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); border-radius: 5px;" data-fig-align="center" />
<p>In theory, you could do this for each state as long as each directory follows the same naming conventions, i.e., <code>pa/flower.png</code> and <code>vt/flower.png</code>.</p>
<p>This does require an organized and scalable approach since the images will have to follow the same directory and file-naming conventions, but in doing so, you can create individualized pages and images using a single include.</p>
<h3 id="the-rendered-example">The rendered example
</h3>
<p>Here is New York&rsquo;s page:</p>
<img src="https://opensource.posit.co/blog/2024-12-12_includes-meta/images/img3.png" style="box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); border-radius: 5px;" data-fig-align="center" />
<p>Here is Pennsylvania&rsquo;s page:</p>
<img src="https://opensource.posit.co/blog/2024-12-12_includes-meta/images/img4.png" style="box-shadow: 5px 5px 15px rgba(0, 0, 0, 0.3); border-radius: 5px;" data-fig-align="center" />
<p>Each page was built using a single (shared) file:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">{{&lt; include _snippets/facts.qmd &gt;}}</span></span></code></pre></td></tr></table>
</div>
</div></div>
<h2 id="learn-more-about-quarto-includes">Learn more about Quarto Includes
</h2>
<p>Quarto&rsquo;s Includes feature allows you to improve your content creation process by reducing redundancy and maintaining consistency across multiple documents. Whether you&rsquo;re managing technical documentation, educational materials, or any other content, this approach can help you save time, reduce errors, and deliver polished results.</p>
<p>Learn more with these resources:</p>
<ul>
<li>






<a href="https://quarto.org/docs/get-started/" target="_blank" rel="noopener">Get Started - Quarto</a>
</li>
<li>






<a href="https://quarto.org/docs/authoring/includes.html" target="_blank" rel="noopener">Quarto - Includes</a>
</li>
<li>


  
  
  





<a href="https://quarto.org/docs/authoring/variables.html#meta" target="_blank" rel="noopener">Quarto - meta Variables</a>
</li>
<li>An overview of <a href="https://technicalwriterhq.com/writing/technical-writing/single-source-authoring/" class="external">Single Source Authoring</a></li>
</ul>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2024-12-12_includes-meta/thumbnail.jpg" length="60237" type="image/jpeg" />
    </item>
    <item>
      <title>Quarto website video series</title>
      <link>https://opensource.posit.co/blog/2024-12-04_websites-workshop/</link>
      <pubDate>Wed, 04 Dec 2024 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2024-12-04_websites-workshop/</guid>
      <dc:creator>Charlotte Wickham</dc:creator>
      <dc:creator>Mine Çetinkaya-Rundel</dc:creator><description><![CDATA[<p>Do you need a professional website to showcase your work? If you&rsquo;ve used Quarto to produce a document, you&rsquo;ve already got the technical skills to create a Quarto website. In this video series, taught by 






<a href="https://www.cwick.co.nz/" target="_blank" rel="noopener">Charlotte Wickham</a>
 and 






<a href="https://emilhvitfeldt.com/" target="_blank" rel="noopener">Emil Hvitfeldt</a>
, you&rsquo;ll learn everything else you need to build a website and customize its appearance.</p>
<p>






<a href="https://www.youtube.com/playlist?list=PLitrm9Undxcu7eExaTg9Y-JYLv9O6uxGu" target="_blank" rel="noopener">YouTube Playlist</a>
</p>
<h2 id="quarto-websites-1-build-your-homepage">Quarto Websites 1: Build your homepage
</h2>
<p>In this video, you&rsquo;ll get a running start by using a template we&rsquo;ve designed to be functional and attractive, and that will serve as a foundation for the rest of the video series. You&rsquo;ll customize the content of your homepage, and how it looks, and along the way learn about the two key files in a Quarto website index.qmd and _quarto.yml. Finally, you&rsquo;ll learn one way to publish your website so other people can see it.</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/l7r24gTEkEY"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<p>Links: 






<a href="https://quarto.org/docs/websites/website-about.html" target="_blank" rel="noopener">About pages</a>
 | 


  
  
  





<a href="https://quarto.org/docs/output-formats/html-themes.html#basic-options" target="_blank" rel="noopener">YAML appearance options</a>
</p>
<p>Code: 






<a href="https://github.com/EmilHvitfeldt/website-template" target="_blank" rel="noopener">Starter</a>
 | 






<a href="https://github.com/cwickham/quarto-website-video/tree/v0.1" target="_blank" rel="noopener">Final</a>
</p>
<h2 id="quarto-websites-2-add-pages-and-navigation">Quarto Websites 2: Add pages and navigation
</h2>
<p>Now you&rsquo;ve got a homepage, you&rsquo;ll likely want to add some other pages. In this video, learn how to add pages to your website, and help people find them, by adding them to your website navigation.</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/k65E-8PXZmA"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<p>Links: 






<a href="https://icons.getbootstrap.com/" target="_blank" rel="noopener">Bootstrap icons</a>
 | 


  
  
  





<a href="https://quarto.org/docs/websites/website-navigation.html#top-navigation" target="_blank" rel="noopener">Navigation bar options</a>
 | 






<a href="https://quarto.org/docs/websites/website-navigation.html" target="_blank" rel="noopener">Quarto website navigation</a>
</p>
<p>Code: 






<a href="Starter%20source%20code:%20https://github.com/cwickham/quarto-website-video/tree/v0.1">Starter</a>
 | 






<a href="https://github.com/cwickham/quarto-website-video/tree/v0.2" target="_blank" rel="noopener">Final</a>
</p>
<h2 id="quarto-websites-3-customize-appearance-with-cssscss">Quarto Websites 3: Customize appearance with CSS/SCSS
</h2>
<p>You now have a set of content you are happy with on your website, but how do you customize the look and feel of your site beyond options set in YAML? In this video, you&rsquo;ll start by learning the basics of CSS and SCSS and how to make good design choices. Then, you&rsquo;ll see how to apply these choices to your Quarto website.</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/pAN2Hiq0XGs"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<p>Links: 






<a href="https://colourcontrast.cc/" target="_blank" rel="noopener">Color contrast checker</a>
 | 






<a href="https://fonts.google.com/" target="_blank" rel="noopener">Google fonts</a>
</p>
<p>Code: 






<a href="https://github.com/cwickham/quarto-website-video/tree/v0.2" target="_blank" rel="noopener">Starter</a>
 | 






<a href="https://github.com/cwickham/quarto-website-video/tree/v0.3" target="_blank" rel="noopener">Final</a>
</p>
<h2 id="quarto-websites-4-add-lists-of-content-with-listings">Quarto Websites 4: Add lists of content with listings
</h2>
<p>Adding a listing page to your website is a great way to showcase your projects, talks, publications or blog posts. In this video you&rsquo;ll learn how to create a listing page in Quarto and see two ways to populate it with content: Quarto documents, or a yaml file.</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/bv_Cw-3HI1Y"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<p>Links: 






<a href="https://quarto.org/docs/websites/website-listings.html" target="_blank" rel="noopener">Listings</a>
 | 






<a href="https://www.andrewheiss.com/teaching/" target="_blank" rel="noopener">Andrew Heiss&rsquo; teaching listing</a>
</p>
<p>Code: 






<a href="https://github.com/cwickham/quarto-website-video/tree/v0.3" target="_blank" rel="noopener">Starter</a>
 | 






<a href="https://github.com/cwickham/quarto-website-video/tree/v0.4" target="_blank" rel="noopener">Final</a>
</p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2024-12-04_websites-workshop/quarto-websites.jpg" length="55926" type="image/jpeg" />
    </item>
    <item>
      <title>Quarto 1.6</title>
      <link>https://opensource.posit.co/blog/2024-11-25_1.6-release/</link>
      <pubDate>Mon, 25 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2024-11-25_1.6-release/</guid>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<p>Quarto 1.6 has been officially released! You can get the current release from the 






<a href="https://quarto.org/docs/download/index.html" target="_blank" rel="noopener">download page</a>
.</p>
<p>We are particularly excited about:</p>
<ul>
<li>
<p>Support for <strong>brand.yml</strong>&mdash;a single file that defines your organization&rsquo;s branding and style preferences across formats.</p>
</li>
<li>
<p>RevealJS updates, including the new navigation features: scroll mode and jump to slide.</p>
</li>
<li>
<p>The <code>contents</code> shortcode for reordering your content.</p>
</li>
<li>
<p><code>landscape</code> blocks for placing content on a landscape page.</p>
</li>
<li>
<p>Improvements in how you can specify subpanels of cross-references from code blocks.</p>
</li>
</ul>
<p>You can read about these new features and a couple of breaking changes in the sections below. You can find all the changes in this version in the 






<a href="https://quarto.org/docs/download/changelog/1.6/" target="_blank" rel="noopener">Release Notes</a>
.</p>
<h2 id="cross-format-theming-with-brandyml">Cross-format theming with <strong>brand.yml</strong>
</h2>
<p>






<a href="https://posit-dev.github.io/brand-yml/" target="_blank" rel="noopener"><strong>brand.yml</strong></a>
 is a Posit project outside Quarto that defines brand information using a simple YAML file. Quarto is a flagship adopter of <strong>brand.yml</strong> and supports brand-themed output for <code>html</code>, <code>dashboard</code>, <code>typst</code> and <code>revealjs</code> formats.</p>
<p>As an example, consider the following <code>_brand.yml</code> file:</p>
<div class="code-block code-with-filename" role="group" aria-labelledby="code-filename-0">
  <div class="code-with-filename-label" id="code-filename-0"><span class="font-mono text-sm">_brand.yml</span></div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">color</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">palette</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">dark-grey</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#222222&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">blue</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;#ddeaf1&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">background</span><span class="p">:</span><span class="w"> </span><span class="l">blue</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">foreground</span><span class="p">:</span><span class="w"> </span><span class="l">dark-grey</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">primary</span><span class="p">:</span><span class="w"> </span><span class="l">black</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">logo</span><span class="p">:</span><span class="w"> 
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">medium</span><span class="p">:</span><span class="w"> </span><span class="l">logo.png</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">typography</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">fonts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">family</span><span class="p">:</span><span class="w"> </span><span class="l">Jura</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">source</span><span class="p">:</span><span class="w"> </span><span class="l">google</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">base</span><span class="p">:</span><span class="w"> </span><span class="l">Jura</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">headings</span><span class="p">:</span><span class="w"> </span><span class="l">Jura</span></span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>When this <code>_brand.yml</code> is placed in a project, webpages, presentations, PDF reports, and dashboards will share a common appearance:</p>
<div class="grid gap-12 items-start md:grid-cols-4">
<div class="prose max-w-none">
<figure>
<img src="https://quarto.org/docs/authoring/images/brand-html.png" data-group="brand-formats" data-fig-alt="Screenshot of a webpage. The text is dark grey on a light blue background, using a rounded sans-serif typeface, a logo appears in the navbar." alt="Webpage: html" />
<figcaption aria-hidden="true">Webpage: <code>html</code></figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://quarto.org/docs/authoring/images/brand-dashboard.png" data-group="brand-formats" data-fig-alt="Screenshot of a dashboard. The text is dark grey on a light blue background, using a rounded sans-serif typeface, a logo appears in the navbar." alt="Dashboard dashboard" />
<figcaption aria-hidden="true">Dashboard <code>dashboard</code></figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://quarto.org/docs/authoring/images/brand-revealjs.png" data-group="brand-formats" data-fig-alt="Screenshot of a presentation. The text is dark grey on a light blue background, using a rounded sans-serif typeface, a logo appears in bottom left of the slide." alt="Presentation: revealjs" />
<figcaption aria-hidden="true">Presentation: <code>revealjs</code></figcaption>
</figure>
</div>
<div class="prose max-w-none">
<figure>
<img src="https://quarto.org/docs/authoring/images/brand-typst.png" data-group="brand-formats" data-fig-alt="Screenshot of a PDF document. The text is dark grey on a light blue background, using a rounded sans-serif typeface, a logo appears in top right of the page." alt="PDF: typst" />
<figcaption aria-hidden="true">PDF: <code>typst</code></figcaption>
</figure>
</div>
</div>
<p>View the example: 


  
  
  





<a href="https://github.com/quarto-dev/quarto-examples/tree/main/brand/brand-simple#brand-simple" target="_blank" rel="noopener">Source</a>
 | 






<a href="https://examples.quarto.pub/brand-simple" target="_blank" rel="noopener">Live website</a>
</p>
<p>Get started by reading the Quarto 






<a href="https://quarto.org/docs/authoring/brand.html" target="_blank" rel="noopener">Guide to Brand</a>
.</p>
<h2 id="revealjs-update">RevealJS update
</h2>
<p>Quarto v1.6 updates RevealJS to v5.1.0. With the update comes two notable features:</p>
<p>


  
  
  





<a href="https://quarto.org/docs/presentations/revealjs/presenting.html#jump-to-slide" target="_blank" rel="noopener"><strong>Jump to Slide</strong></a>
: Quickly navigate to a slide. Press <code>G</code> to activate, type a slide number or ID, and hit Enter/Return.</p>
<p>


  
  
  





<a href="https://quarto.org/docs/presentations/revealjs/presenting.html#scroll-view" target="_blank" rel="noopener"><strong>Scroll Mode</strong></a>
: Scroll rather than click to advance slides. Press <code>R</code>, add <code>?view=scroll</code> to your URL, or use the Navigation menu to activate. Automatically activated on small screens.</p>
<h2 id="contents-shortcode">Contents shortcode
</h2>
<p>The <code>contents</code> shortcode lets you compose content in one location in your document and then display it in another. For example, you might use a code cell to generate a plot:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">``<span class="sb">`{python}
</span></span></span><span class="line"><span class="cl"><span class="sb">#| echo: false
</span></span></span><span class="line"><span class="cl"><span class="sb">#| label: a-cell
</span></span></span><span class="line"><span class="cl"><span class="sb">import matplotlib.pyplot as plt
</span></span></span><span class="line"><span class="cl"><span class="sb">plt.plot([1,2,3])
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>``</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Then use the <code>contents</code> shortcode to display that plot in a callout by referencing its label, <code>a-cell</code>:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">::: callout-note
</span></span><span class="line"><span class="cl"><span class="gu">## Note the following plot
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">{{&lt; contents a-cell &gt;}}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:::</span></span></code></pre></td></tr></table>
</div>
</div></div>
<p>Find all the details on our guide page on the 






<a href="https://quarto.org/docs/authoring/contents.html" target="_blank" rel="noopener">contents shortcode</a>
.</p>
<h2 id="landscape-mode">Landscape mode
</h2>
<p>In <code>pdf</code>, <code>docx,</code> and <code>typst</code> formats, you can now put content on a landscape page by placing it inside a 


  
  
  





<a href="https://quarto.org/docs/authoring/article-layout.html#landscape-mode" target="_blank" rel="noopener"><code>landscape</code> block</a>
:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">::: {.landscape}
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">This will appear in landscape.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:::</span></span></code></pre></td></tr></table>
</div>
</div></div>
<h2 id="cross-reference-improvements">Cross-reference improvements
</h2>
<p>It should now be easier to get Quarto to recognize subfloats (subtables, subfigures, etc) when they&rsquo;re emitted by code cells. If the <code>subcap</code> attribute of a code cell has as many entries as the number of outputs from your code cell, Quarto knows to accept those as subfloats. See <a href="https://github.com/quarto-dev/quarto-cli/issues/10328" class="external">#10328</a> for details.</p>
<p>Minimal example:</p>
<div class="code-block"><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">``<span class="sb">`{{r}}
</span></span></span><span class="line"><span class="cl"><span class="sb">#| label: tbl-example
</span></span></span><span class="line"><span class="cl"><span class="sb">#| tbl-cap: I want these images to be interpreted as Tables.
</span></span></span><span class="line"><span class="cl"><span class="sb">#| tbl-subcap:
</span></span></span><span class="line"><span class="cl"><span class="sb">#|   - This is the subcaption for the first subtable
</span></span></span><span class="line"><span class="cl"><span class="sb">#|   - This is the subcaption for the second subtable
</span></span></span><span class="line"><span class="cl"><span class="sb">plot(1:10)
</span></span></span><span class="line"><span class="cl"><span class="sb">plot(11:20)
</span></span></span><span class="line"><span class="cl"><span class="sb">`</span>``</span></span></code></pre></td></tr></table>
</div>
</div></div>
<figure>
<img src="https://opensource.posit.co/blog/2024-11-25_1.6-release/./subcells-and-subfloats.png" class="border" data-fig-alt="Screenshot of a document showing two plots with an overall caption labelled &#39;Table 1&#39;, and each plot with a caption starting &#39;(a)&#39; and &#39;(b)&#39; respectively." alt="The result of executing the above code cell in HTML format" />
<figcaption aria-hidden="true">The result of executing the above code cell in HTML format</figcaption>
</figure>
<h2 id="breaking-changes">Breaking Changes
</h2>
<p>We try very hard to keep Quarto backward compatible. However, in this release, there are a couple of breaking changes due to upstream dependencies. You may be affected if:</p>
<ul>
<li>
<p><strong>You have TypeScript files (<code>*.ts</code>) that you use either with pre- or post-render scripts, or with <code>quarto run</code>, that import Deno standard libraries.</strong></p>
<p>The import syntax has changed. Please see 


  
  
  





<a href="https://quarto.org/docs/projects/scripts.html#deno-scripts" target="_blank" rel="noopener">Deno Scripts</a>
 for the necessary changes.</p>
</li>
<li>
<p><strong>You override the LaTeX <code>graphics.tex</code> partial, or you have a completely custom LaTeX template that doesn&rsquo;t use the <code>graphics.tex</code> partial.</strong></p>
<p>A Pandoc change means some images are now wrapped in <code>\pandocbounded</code>. Consequently, your <code>graphics.tex</code> partial, or your template, needs to define <code>\pandocbounded</code>. You can look at our <a href="https://github.com/quarto-dev/quarto-cli/blob/main/src/resources/formats/pdf/pandoc/graphics.tex" class="external">source code for <code>graphics.tex</code></a> to see the necessary changes and read more about the upstream change in <a href="https://github.com/jgm/pandoc/commit/26b25a4428815b04c255e33e95ee86ca7b6ee30e" class="external">Pandoc commit 26b25a4</a>.</p>
</li>
</ul>
<h2 id="acknowledgments">Acknowledgments
</h2>
<p>We want to say a huge thank you to everyone who contributed to this release by opening issues and pull requests:</p>
<p>






<a href="https://github.com/ArthurData" target="_blank" rel="noopener">ArthurData</a>
,







<a href="https://github.com/Blake-Madden" target="_blank" rel="noopener">Blake-Madden</a>
,







<a href="https://github.com/Coding4Sec" target="_blank" rel="noopener">Coding4Sec</a>
,







<a href="https://github.com/EricMarcon" target="_blank" rel="noopener">EricMarcon</a>
,







<a href="https://github.com/Fgazzelloni" target="_blank" rel="noopener">Fgazzelloni</a>
,







<a href="https://github.com/GeorgRamer" target="_blank" rel="noopener">GeorgRamer</a>
,







<a href="https://github.com/Gewerd-Strauss" target="_blank" rel="noopener">Gewerd-Strauss</a>
,







<a href="https://github.com/GuillaumeDehaene" target="_blank" rel="noopener">GuillaumeDehaene</a>
,







<a href="https://github.com/HarunCelikOtto" target="_blank" rel="noopener">HarunCelikOtto</a>
,







<a href="https://github.com/IULibScholComm" target="_blank" rel="noopener">IULibScholComm</a>
,







<a href="https://github.com/IndrajeetPatil" target="_blank" rel="noopener">IndrajeetPatil</a>
,







<a href="https://github.com/LeoLuongVuong" target="_blank" rel="noopener">LeoLuongVuong</a>
,







<a href="https://github.com/MarcellGranat" target="_blank" rel="noopener">MarcellGranat</a>
,







<a href="https://github.com/Mavoort" target="_blank" rel="noopener">Mavoort</a>
,







<a href="https://github.com/Nenuial" target="_blank" rel="noopener">Nenuial</a>
,







<a href="https://github.com/PeteArm" target="_blank" rel="noopener">PeteArm</a>
,







<a href="https://github.com/ShixiangWang" target="_blank" rel="noopener">ShixiangWang</a>
,







<a href="https://github.com/Steinthal" target="_blank" rel="noopener">Steinthal</a>
,







<a href="https://github.com/Walser52" target="_blank" rel="noopener">Walser52</a>
,







<a href="https://github.com/Xinenomine" target="_blank" rel="noopener">Xinenomine</a>
,







<a href="https://github.com/abbyruthe" target="_blank" rel="noopener">abbyruthe</a>
,







<a href="https://github.com/aborruso" target="_blank" rel="noopener">aborruso</a>
,







<a href="https://github.com/adamblake" target="_blank" rel="noopener">adamblake</a>
,







<a href="https://github.com/albert-ying" target="_blank" rel="noopener">albert-ying</a>
,







<a href="https://github.com/alecloudenback" target="_blank" rel="noopener">alecloudenback</a>
,







<a href="https://github.com/allefeld" target="_blank" rel="noopener">allefeld</a>
,







<a href="https://github.com/aronatkins" target="_blank" rel="noopener">aronatkins</a>
,







<a href="https://github.com/arthur-shaw" target="_blank" rel="noopener">arthur-shaw</a>
,







<a href="https://github.com/astrowonk" target="_blank" rel="noopener">astrowonk</a>
,







<a href="https://github.com/avras" target="_blank" rel="noopener">avras</a>
,







<a href="https://github.com/baker-jr-john" target="_blank" rel="noopener">baker-jr-john</a>
,







<a href="https://github.com/bcm0" target="_blank" rel="noopener">bcm0</a>
,







<a href="https://github.com/blackerby" target="_blank" rel="noopener">blackerby</a>
,







<a href="https://github.com/boshek" target="_blank" rel="noopener">boshek</a>
,







<a href="https://github.com/brandonmontez" target="_blank" rel="noopener">brandonmontez</a>
,







<a href="https://github.com/brianmsm" target="_blank" rel="noopener">brianmsm</a>
,







<a href="https://github.com/bryanhanson" target="_blank" rel="noopener">bryanhanson</a>
,







<a href="https://github.com/carschandler" target="_blank" rel="noopener">carschandler</a>
,







<a href="https://github.com/castedo" target="_blank" rel="noopener">castedo</a>
,







<a href="https://github.com/chaz-clark" target="_blank" rel="noopener">chaz-clark</a>
,







<a href="https://github.com/christopherkenny" target="_blank" rel="noopener">christopherkenny</a>
,







<a href="https://github.com/coatless" target="_blank" rel="noopener">coatless</a>
,







<a href="https://github.com/d-morrison" target="_blank" rel="noopener">d-morrison</a>
,







<a href="https://github.com/danieltomasz" target="_blank" rel="noopener">danieltomasz</a>
,







<a href="https://github.com/daxkellie" target="_blank" rel="noopener">daxkellie</a>
,







<a href="https://github.com/ddlawton" target="_blank" rel="noopener">ddlawton</a>
,







<a href="https://github.com/debruine" target="_blank" rel="noopener">debruine</a>
,







<a href="https://github.com/dsbitor" target="_blank" rel="noopener">dsbitor</a>
,







<a href="https://github.com/e-miz" target="_blank" rel="noopener">e-miz</a>
,







<a href="https://github.com/eculler" target="_blank" rel="noopener">eculler</a>
,







<a href="https://github.com/edavidaja" target="_blank" rel="noopener">edavidaja</a>
,







<a href="https://github.com/edvinsyk" target="_blank" rel="noopener">edvinsyk</a>
,







<a href="https://github.com/eitsupi" target="_blank" rel="noopener">eitsupi</a>
,







<a href="https://github.com/ethanwhite" target="_blank" rel="noopener">ethanwhite</a>
,







<a href="https://github.com/fermarsan" target="_blank" rel="noopener">fermarsan</a>
,







<a href="https://github.com/floesche" target="_blank" rel="noopener">floesche</a>
,







<a href="https://github.com/fradav" target="_blank" rel="noopener">fradav</a>
,







<a href="https://github.com/fredguth" target="_blank" rel="noopener">fredguth</a>
,







<a href="https://github.com/gadenbuie" target="_blank" rel="noopener">gadenbuie</a>
,







<a href="https://github.com/georgestagg" target="_blank" rel="noopener">georgestagg</a>
,







<a href="https://github.com/apps/github-actions" target="_blank" rel="noopener">github-actions[bot]</a>
,







<a href="https://github.com/halleysfifthinc" target="_blank" rel="noopener">halleysfifthinc</a>
,







<a href="https://github.com/hamelsmu" target="_blank" rel="noopener">hamelsmu</a>
,







<a href="https://github.com/hansfn" target="_blank" rel="noopener">hansfn</a>
,







<a href="https://github.com/harrylojames" target="_blank" rel="noopener">harrylojames</a>
,







<a href="https://github.com/hodgesmr" target="_blank" rel="noopener">hodgesmr</a>
,







<a href="https://github.com/holtzy" target="_blank" rel="noopener">holtzy</a>
,







<a href="https://github.com/hugetim" target="_blank" rel="noopener">hugetim</a>
,







<a href="https://github.com/hurak" target="_blank" rel="noopener">hurak</a>
,







<a href="https://github.com/iagopinal" target="_blank" rel="noopener">iagopinal</a>
,







<a href="https://github.com/isabelizimm" target="_blank" rel="noopener">isabelizimm</a>
,







<a href="https://github.com/itsmevictor" target="_blank" rel="noopener">itsmevictor</a>
,







<a href="https://github.com/jameslairdsmith" target="_blank" rel="noopener">jameslairdsmith</a>
,







<a href="https://github.com/javajon" target="_blank" rel="noopener">javajon</a>
,







<a href="https://github.com/jchiquet" target="_blank" rel="noopener">jchiquet</a>
,







<a href="https://github.com/jdfoote" target="_blank" rel="noopener">jdfoote</a>
,







<a href="https://github.com/jido" target="_blank" rel="noopener">jido</a>
,







<a href="https://github.com/jimjam-slam" target="_blank" rel="noopener">jimjam-slam</a>
,







<a href="https://github.com/jkrumbiegel" target="_blank" rel="noopener">jkrumbiegel</a>
,







<a href="https://github.com/jmgirard" target="_blank" rel="noopener">jmgirard</a>
,







<a href="https://github.com/jmhammond" target="_blank" rel="noopener">jmhammond</a>
,







<a href="https://github.com/joelostblom" target="_blank" rel="noopener">joelostblom</a>
,







<a href="https://github.com/johannes-menzel" target="_blank" rel="noopener">johannes-menzel</a>
,







<a href="https://github.com/juliantao" target="_blank" rel="noopener">juliantao</a>
,







<a href="https://github.com/jvcarli" target="_blank" rel="noopener">jvcarli</a>
,







<a href="https://github.com/kazuyanagimoto" target="_blank" rel="noopener">kazuyanagimoto</a>
,







<a href="https://github.com/kbvernon" target="_blank" rel="noopener">kbvernon</a>
,







<a href="https://github.com/kdheepak" target="_blank" rel="noopener">kdheepak</a>
,







<a href="https://github.com/kjohnsen" target="_blank" rel="noopener">kjohnsen</a>
,







<a href="https://github.com/lballabio" target="_blank" rel="noopener">lballabio</a>
,







<a href="https://github.com/leovan" target="_blank" rel="noopener">leovan</a>
,







<a href="https://github.com/loneguardian" target="_blank" rel="noopener">loneguardian</a>
,







<a href="https://github.com/longapalooza" target="_blank" rel="noopener">longapalooza</a>
,







<a href="https://github.com/lucacasonato" target="_blank" rel="noopener">lucacasonato</a>
,







<a href="https://github.com/lukmanaj" target="_blank" rel="noopener">lukmanaj</a>
,







<a href="https://github.com/lwjohnst86" target="_blank" rel="noopener">lwjohnst86</a>
,







<a href="https://github.com/machow" target="_blank" rel="noopener">machow</a>
,







<a href="https://github.com/maelle" target="_blank" rel="noopener">maelle</a>
,







<a href="https://github.com/masud90" target="_blank" rel="noopener">masud90</a>
,







<a href="https://github.com/melaniewalsh" target="_blank" rel="noopener">melaniewalsh</a>
,







<a href="https://github.com/mfisher87" target="_blank" rel="noopener">mfisher87</a>
,







<a href="https://github.com/mipmip" target="_blank" rel="noopener">mipmip</a>
,







<a href="https://github.com/mitzimorris" target="_blank" rel="noopener">mitzimorris</a>
,







<a href="https://github.com/mpr1255" target="_blank" rel="noopener">mpr1255</a>
,







<a href="https://github.com/nessan" target="_blank" rel="noopener">nessan</a>
,







<a href="https://github.com/neuwirthe" target="_blank" rel="noopener">neuwirthe</a>
,







<a href="https://github.com/nichtich" target="_blank" rel="noopener">nichtich</a>
,







<a href="https://github.com/njericha" target="_blank" rel="noopener">njericha</a>
,







<a href="https://github.com/nsarang" target="_blank" rel="noopener">nsarang</a>
,







<a href="https://github.com/olivroy" target="_blank" rel="noopener">olivroy</a>
,







<a href="https://github.com/ozanozbeker" target="_blank" rel="noopener">ozanozbeker</a>
,







<a href="https://github.com/paciorek" target="_blank" rel="noopener">paciorek</a>
,







<a href="https://github.com/pagiraud" target="_blank" rel="noopener">pagiraud</a>
,







<a href="https://github.com/parmsam" target="_blank" rel="noopener">parmsam</a>
,







<a href="https://github.com/pedrohbraga" target="_blank" rel="noopener">pedrohbraga</a>
,







<a href="https://github.com/peteole" target="_blank" rel="noopener">peteole</a>
,







<a href="https://github.com/produnis" target="_blank" rel="noopener">produnis</a>
,







<a href="https://github.com/raffaem" target="_blank" rel="noopener">raffaem</a>
,







<a href="https://github.com/ryarazi" target="_blank" rel="noopener">ryarazi</a>
,







<a href="https://github.com/ryjohnson09" target="_blank" rel="noopener">ryjohnson09</a>
,







<a href="https://github.com/s2t2" target="_blank" rel="noopener">s2t2</a>
,







<a href="https://github.com/salim-b" target="_blank" rel="noopener">salim-b</a>
,







<a href="https://github.com/samlalwani" target="_blank" rel="noopener">samlalwani</a>
,







<a href="https://github.com/sgelzenleuchter" target="_blank" rel="noopener">sgelzenleuchter</a>
,







<a href="https://github.com/skriptum" target="_blank" rel="noopener">skriptum</a>
,







<a href="https://github.com/snhansen" target="_blank" rel="noopener">snhansen</a>
,







<a href="https://github.com/stragu" target="_blank" rel="noopener">stragu</a>
,







<a href="https://github.com/sun123zxy" target="_blank" rel="noopener">sun123zxy</a>
,







<a href="https://github.com/sverrirarnors" target="_blank" rel="noopener">sverrirarnors</a>
,







<a href="https://github.com/topepo" target="_blank" rel="noopener">topepo</a>
,







<a href="https://github.com/truecluster" target="_blank" rel="noopener">truecluster</a>
,







<a href="https://github.com/tylere" target="_blank" rel="noopener">tylere</a>
,







<a href="https://github.com/winniehell" target="_blank" rel="noopener">winniehell</a>
,







<a href="https://github.com/xtimbeau" target="_blank" rel="noopener">xtimbeau</a>
,







<a href="https://github.com/yogabonito" target="_blank" rel="noopener">yogabonito</a>
,







<a href="https://github.com/yurivict" target="_blank" rel="noopener">yurivict</a>
,







<a href="https://github.com/yves-amevoin" target="_blank" rel="noopener">yves-amevoin</a>
.</p>
<p>The palette emoji in the 






<a href="thumbnail.png">listing and social card image</a>
 for this post comes from <a href="https://openmoji.org/" class="external">OpenMoji</a>&ndash; the open-source emoji and icon project. License: <a href="https://creativecommons.org/licenses/by-sa/4.0/#" class="external">CC BY-SA 4.0</a></p>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2024-11-25_1.6-release/thumbnail.png" length="72949" type="image/png" />
    </item>
    <item>
      <title>Quarto dashboards video series</title>
      <link>https://opensource.posit.co/blog/2024-11-22_dashboards-workshop/</link>
      <pubDate>Fri, 22 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2024-11-22_dashboards-workshop/</guid>
      <dc:creator>Charlotte Wickham</dc:creator>
      <dc:creator>Mine Çetinkaya-Rundel</dc:creator><description><![CDATA[<p>If you&rsquo;ve been looking to get your head around Quarto dashboards,
check out the Quarto dashboards video series by 






<a href="https://mine-cr.com/" target="_blank" rel="noopener">Mine Çetinkaya-Rundel</a>
.</p>
<p>Materials: 






<a href="https://youtube.com/playlist?list=PLitrm9UndxcsapDsLimKGn3dEjQZy5vYs&amp;si=oLK2D1PuyF9MKVon" target="_blank" rel="noopener">YouTube playlist</a>
 | 






<a href="https://mine.quarto.pub/quarto-dashboards/" target="_blank" rel="noopener">Slides</a>
 | 






<a href="https://github.com/mine-cetinkaya-rundel/olympicdash" target="_blank" rel="noopener">Starter code</a>
</p>
<h2 id="1-hello-quarto-dashboards">1. Hello, Quarto Dashboards
</h2>
<p>Start by getting to know Quarto dashboards and make your very first dashboard using either R or Python and share it online. 


  
  
  





<a href="https://mine.quarto.pub/quarto-dashboards/1-hello-dashboards/#/title-slide" target="_blank" rel="noopener">Slides</a>
</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/HW7QbqI4fH0"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<h2 id="2-quarto-dashboards-components">2. Quarto Dashboards Components
</h2>
<p>Then, build up your arsenal of dashboard components to add navigation, sidebars, tabsets, value boxes, and fine-tune layout. 


  
  
  





<a href="https://mine.quarto.pub/quarto-dashboards/2-dashboard-components/#/title-slide" target="_blank" rel="noopener">Slides</a>
</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/KdsQgwaY950"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




<h2 id="3-quarto-dashboards-theming-and-styling">3. Quarto Dashboards Theming and Styling
</h2>
<p>Finally, make your dashboard pop by adding a theme and making styling tweaks. 


  
  
  





<a href="https://mine.quarto.pub/quarto-dashboards/3-theming-styling/#/title-slide" target="_blank" rel="noopener">Slides</a>
</p>















  

  
  
  
    
    
  

  
  










  
  
    <div class="w-full aspect-video">
      <iframe
        src="https://www.youtube.com/embed/NigWSB-jG4Y"
        class="w-full h-full"
        
        frameborder="0"
        allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
        allowfullscreen></iframe>
    </div>
  




]]></description>
      <enclosure url="https://opensource.posit.co/blog/2024-11-22_dashboards-workshop/quarto-dashboards.jpg" length="80578" type="image/jpeg" />
    </item>
    <item>
      <title>posit::conf(2024) Quarto talks</title>
      <link>https://opensource.posit.co/blog/2024-11-06_conf-talks/</link>
      <pubDate>Wed, 06 Nov 2024 00:00:00 +0000</pubDate>
      <guid>https://opensource.posit.co/blog/2024-11-06_conf-talks/</guid>
      <dc:creator>Mine Çetinkaya-Rundel</dc:creator>
      <dc:creator>Charlotte Wickham</dc:creator><description><![CDATA[<p>Videos of posit::conf(2024) talks are now posted 






<a href="https://www.youtube.com/watch?v=s_Vh9HIeLVg&amp;list=PL9HYL-VRX0oSFkdF4fJeY63eGDvgofcbn" target="_blank" rel="noopener">on YouTube</a>
. We have also made playlist of talks that are about using, building with, and building on Quarto.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/videoseries?si=Xwt6NHL_f4k9agzh&amp;list=PLNUVZZ6hfXX1Y4Is-SbbMF_HutRDJBwiO" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen>
</iframe>
<p>Talks included in this playlist are as follows:</p>
<ul>
<li>






<a href="https://youtu.be/s_Vh9HIeLVg?si=jsIWeETKQG154dFi" target="_blank" rel="noopener">Updates from Posit, with Hadley Wickham, Charlotte Wickham, George Stagg, and James Blair</a>
</li>
<li>






<a href="https://youtu.be/KqLxy66B3lQ?si=fe1zVCBozVmWKufO" target="_blank" rel="noopener">Andrew Bray - Closeread: bringing Scrollytelling to Quarto</a>
</li>
<li>






<a href="https://youtu.be/VJEBg1Ke0lE?si=LUMa5-IF3gWORr3I" target="_blank" rel="noopener">Meghan Hall - Designing and Deploying Internal Quarto Templates</a>
</li>
<li>






<a href="https://youtu.be/bp1SMhLoz_M?si=tyvyO-FP0AEBV6W2" target="_blank" rel="noopener">David Keyes - Report Design in R: Small Tweaks that Make a Big Difference</a>
</li>
<li>






<a href="https://youtu.be/fsfoqpQYN2k?si=sDUOZTEBXvXLNVHq" target="_blank" rel="noopener">Mine Çetinkaya-Rundel - Reproducible, dynamic, and elegant books with Quarto</a>
</li>
<li>






<a href="https://youtu.be/4zy9R26B8kk?si=rO_5BIjTC3ENVC2c" target="_blank" rel="noopener">Cynthia Huang - Quarto for Knowledge Management</a>
</li>
<li>






<a href="https://youtu.be/UOMcGBMvVdo?si=yo3dFtWScKn06iXy" target="_blank" rel="noopener">Regina Lionheart - Making Waves with R, Python, and Quarto</a>
</li>
<li>






<a href="https://youtu.be/PITfti4JRiU?si=TMi-CJOi04zViU_p" target="_blank" rel="noopener">Joshua Cook - Quarto: A Multifaceted Publishing Powerhouse for Medical Researchers</a>
</li>
<li>






<a href="https://youtu.be/U8_Dc_ru8fg?si=-fEK5Ou57f-QhSba" target="_blank" rel="noopener">Tyler Morgan-Wall - Quarto, AI, and the Art of Getting Your Life Back</a>
</li>
<li>






<a href="https://youtu.be/fzykFa6c3LI?si=wV83nh1WvctfRAiu" target="_blank" rel="noopener">Sean Nguyen - Beyond Dashboards: Dynamic Data Storytelling with Python, R, and Quarto Emails</a>
</li>
<li>






<a href="https://youtu.be/CySpBKJD5vY?si=zQ2TowaD_Wk0Du8X" target="_blank" rel="noopener">Richie Moluno - JSquarto: Bridging JavaScript Documentation with Quarto&rsquo;s Power</a>
</li>
<li>






<a href="https://youtu.be/1gUl-vWqScc?si=nLEJ8JsLzBv8UqqT" target="_blank" rel="noopener">Mika Braginsky - DataPages for interactive data sharing using Quarto</a>
</li>
<li>






<a href="https://youtu.be/ceW3nQssV88?si=caHnzvBHorxWFn00" target="_blank" rel="noopener">Brennan Antone - Democratizing Organizational Surveys with Quarto and Shiny</a>
</li>
</ul>
]]></description>
      <enclosure url="https://opensource.posit.co/blog/2024-11-06_conf-talks/images/thumbnail.jpg" length="176419" type="image/jpeg" />
    </item>
  </channel>
</rss>
