quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.98k stars 328 forks source link

Quarto render with --execute-params only updates executable code but not shortcode #11167

Open joanbadia opened 1 month ago

joanbadia commented 1 month ago

Bug description

Given a main qmd document test.qmd, when specifying the params externally in a params.yml file and trying the quarto render test.qmd --execute-params params.yaml the parameters are only updated in the portion of executable code (e.g. those included within an R chunk), but not for the shortcodes. Is this an intentional behaviour?

Steps to reproduce

test.qmd


---
title: "Conditional content with params"
format: html 
editor: visual
params:
  print: FALSE
---

::: {.content-hidden unless-meta="params.print"}
If PRINT parameter is TRUE, we'll show this.

shortcode shows PRINT = {{< meta params.print >}}

```{r, echo=FALSE}
cat("executed code shows PRINT = ", params$print)
if(params$print){
  cat("Hello World")
} else {
  cat("Not printing anything, because params$print is FALSE")
}

:::

::: {.content-hidden when-meta="params.print"} If PRINT parameter is FALSE, we'll show this instead.

shortcode shows PRINT = {{< meta params.print >}}

cat("executed code shows PRINT = ", params$print)
if(params$print){
  cat("Hello World")
} else {
  cat("Not printing anything, because params$print is FALSE")
}

:::


`params.yml`
````yml
print: FALSE

Expected behavior

Conditional content with params

If PRINT parameter is FALSE, we’ll show this instead.

shortcode shows PRINT = false

executed code shows PRINT = FALSE

Not printing anything, because params$print is FALSE

Actual behavior

Conditional content with params

If PRINT parameter is FALSE, we'll show this.

shortcode shows PRINT = true

executed code shows PRINT = FALSE

Not printing anything, because params$print is FALSE

Your environment

Quarto check output

Quarto 1.4.555 [>] Checking versions of quarto binary dependencies... Pandoc version 3.1.11: OK Dart Sass version 1.69.5: OK Deno version 1.37.2: OK [>] Checking versions of quarto dependencies......OK [>] Checking Quarto installation......OK Version: 1.4.555 CodePage: 1252

[>] Checking tools....................OK TinyTeX: (not installed) Chromium: (not installed)

[>] Checking LaTeX....................OK Tex: (not detected)

[>] Checking basic markdown render....OK

[>] Checking Python 3 installation....OK Version: 3.11.2 Jupyter: 5.2.0 Kernels: python3

[>] Checking Jupyter engine render....OK

[>] Checking R installation...........OK Version: 4.4.1 knitr: 1.48 rmarkdown: 2.28

[>] Checking Knitr engine render......OK

cscheid commented 1 month ago

Yes, params doesn't currently get forwarded to document metadata. The behavior is intentional (if counterintuitive). The rationale is that since there are other ways to specify parameters outside of metadata, we have two options:

Quarto currently chooses the latter.

mcanouil commented 1 month ago

I don't think there is a bug.

Meta shortcode is to retrieve document (static) metadata, so it returns the correct value.

If you want to output parameters (which are "dynamic metadata"), then you need R inline code in your case `{r} params[["print"]]`.

Your use of parameters won't work for conditional contents.

Side note: the current stable version is 1.5 and you are running 1.4. You might want to upgrade Quarto.

Edit: I think there is an issue opened (or a discussion) regarding computation and conditional contents.

mcanouil commented 1 month ago

Some of the discussion:

joanbadia commented 1 month ago

What I am trying to do are parametrised analyses modules, which would be conditionally executed with an #| eval = params$.... However, if you also use includes in the mix {{< include ....qmd>}}, that often leaves their preceding title displayed and hanging even with the .content-hidden shortcode, unless you go through other means that often breaks the navigation like "asis" (which was the point in using titles in the first place).

I am willing also to create my own shortcode if you guys could give me some pointers, a shortcode of the type .conditional-evaluation, that affects titles and chunks.

My aim would be to achieve something like, but without titles appearing and without breaking navigation:

analysis.qmd

---
title: "Analysis report"
format: html 
params: 
  pca: TRUE
  spca: FALSE
  volcano: TRUE
  topheatmap: FALSE
---

## Differential Analysis

{{< include module-da.qmd >}}

## Dimensionality Reduction

{{< include module-dimred.qmd >}}

module-da.qmd

---
title: "Differential Analysis"
format: html 
---

::: {.content-hidden when-meta="params.volcano"}
### Volcano
```{r}
#| eval !expr params$volcano
my_function...

:::

::: {.content-hidden when-meta="params.topheatmap"}

Top 20 heatmap

#| eval !expr params$topheatmap
my_function...

:::


`module-dimred.qmd`
````qmd
---
title: "Dimensionality Reduction"
format: html 
---

::: {.content-hidden when-meta="params.pca"}
### Principal Component Analysis
```{r}
#| eval !expr params$volcano
my_function...

:::

::: {.content-hidden when-meta="params.spca"}

Sparse Principal Component Analysis

#| eval !expr params$spca
my_function...

:::

mcanouil commented 1 month ago

Note that you are mixing code cells syntax, which isn't recommended by knitr. Quarto uses and recommends YAML syntax. A code cell thus should have nothing between the brackets beside the language.

```{r}
#| echo: false
...

If your titles are conditional on the parameters, why not put them in the code cells?

```{r}
#| output: asis
cat("\n\n## My second level header\n\n)
joanbadia commented 1 month ago

OK, updated the example to remove the {r, echo=FALSE}.

Why I don't put them in the code cells? Because when I have several methods inside a module, then I lose all navigation capabilities within the document when I include it within a R chunk, while the shortcode retains the navigation capabilities. Shortcodes are basically that good. Also, the titles are both for the person that will read the report and for me that might need to go back to that long module, review the code and add more.

Do you know any way to achieve the same thing as your example code with a custom shortcode? Specifically this:

```{r}
#| output: asis
cat("\n\n## My second level header\n\n)


Is it possible at all? I'll try to code it myself if it's possible...
mcanouil commented 1 month ago

@joanbadia Could you open a separate GitHub Dicussion (Q&A) to avoid cluttering this issue?

joanbadia commented 1 month ago

Ok, done, I'll paste the link here in case anyone stumbles into this post and also wants something similar.

For summary, now I am trying to attempt to achieve what I want with a custom lua filter:

https://github.com/quarto-dev/quarto-cli/discussions/11173