6.17 Conditional Content

In some cases you may want to create content that only displays for a given output format (or only displays when not rendering to a format). You can accomplish this by creating divs, spans and code blocks with the .content-visible and .content-hidden classes.

E.g., you have a home assignment file and you want to have two versions of it: one for questions only, and the other for questions and solutions.

You can set a metadata variable in yaml, e.g., solutions: true or solutions: false.

---
title: "Quiz: Linear Regression and Hypothesis Testing (p1)"
from: markdown+tex_math_single_backslash
solution: false
# solution: true
format:
  pdf:
    include-in-header: ../latex/preamble.tex
    fontsize: 12pt
---

Then, in the body of your document, you can use the following syntax to conditionally include or exclude content based on the value of the solutions variable.

::: {.content-visible when-meta="solutions"}
This content will only be visible if `solutions` is set to `true`.

Put your solutions here.
:::

Expected behavior:

  • If solutions: true, the content will be displayed.
  • If solutions: false, the content will be hidden.

You can use multiple levels of metadata keys separated by periods. For example,

::: {.content-hidden unless-meta="path.to.metadata"}

This content will be hidden unless there exists a metadata entry like such:

```yml
path:
  to:
    metadata: true
```

:::

You need to use unless-meta="path.to.metadata" to refer to your user defined metadata key.

Change file name based on metadata:

  • when params.solution is true, render to quiz-solutions.pdf
  • when params.solution is false, render to quiz-question.pdf
  • both files can be generated using render-quiz.sh script, see the shared library.
  • To support Quarto Preview, create symlinks that link solution/question files to quiz.pdf. The file name quiz.pdf is used in Quarto Preview to load files; it has to be consistent with quiz.qmd.

Work flow:

  • When editing the quiz, use quarto render (⇧ + ⌘ + K) to preview the quiz.
  • When ready to generate the final files, run render-quiz file.qmd in terminal to generate files with specific suffixes (_solution.pdf or _question.pdf).

6.17.1 Set up multiple profiles

You can also set up multiple profiles in _quarto.yml, so you can just run quarto render --profile with-solutions / --profile no-solutions in terminal to render the document with or without solutions.

project:
  type: book
  output-dir: docs

profiles:
  with-solutions:
    metadata:
      solutions: true
  
  no-solutions:
    metadata:
      solutions: false

You can then render the document with solutions using --profile argument:

quarto render --profile with-solutions

Default profile

To define a default profile, add a default option to the profile key. For example, to make the with-solutions profile the default, you can use the following configuration:

profile:
  default: with-solutions

Then, you can simply run quarto render without specifying a profile, and it will use the with-solutions profile by default.


6.17.2 Conditional Code Blocks

Q: Conditional contents NOT working for code blocks.

A: It’s because .content-visible runs after code execution. knitr executes the chunk and emits output even if the wrapper later hides the surrounding Markdown. Control the chunk itself with the meta flag.

Solution: Use params in rmarkdown.

  1. In the YAML header, define a parameter solution with a default value of false.

    ---
    title: "Home Assignment"
    from: markdown+tex_math_single_backslash
    params:
      solution: false
      # solution: true
    ---
    • solution: false means do not show solutions by default.
    • solution: true means show solutions.
  2. Using a code chunk to get the value of the parameter. Put it at the beginning of the document as part of a global setup.

    ```{r echo=FALSE} 
    .solution <- params$solution
    ```
  3. For following code chunks, you can use eval=.solution, include=.solution to control whether to evaluate and include the chunk based on the value of .solution.

    ```{r eval=.solution, include=.solution} 
    # R code for solution
    summary(cars)
    ```
    • When .solution is TRUE, the chunk will be evaluated and included in the output.
      • If you still want to evaluate but not include in the output, use include=.solution only
    • when .solution is FALSE, the chunk will not be evaluated or included in the output.
  4. For regular text, use fenced divs with .content-visible and when-meta="solution" to conditionally include or exclude content based on the value of the solution parameter.

    ::: {.content-visible when-meta="params.solution"}
    This content will only be visible if `solution` is set to `true`.
    
    Put your solutions here.
    :::
    • Use the attributes unless-meta and when-meta, and use periods . to separate metadata keys.
    • solution is a second-level key under params, so you need to use params.solution to refer to it.

Use scenarios:

  • When preparing the assignment, you can set solution: true to see the solutions while editing.
  • After you finish editing, set solution: false to hide the solutions before submission.

When you want to render the document with solutions, you can set the parameter solution to true in the YAML header or use command line arguments.

ref: