quarto-dev / quarto-cli

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

`output: asis` shouldn't be advertised in OJS cell option documentation (was: OJS variables cannot be used / interpolated within non-executed code blocks) #6061

Open jglev opened 1 year ago

jglev commented 1 year ago

Bug description

First, thank you for your work on this wonderful project!!

I am trying to understand whether Observable variables are able to be used within text formatted as code. As part of this, ojs code blocks seem not to honor the output: asis execution option.

Steps to reproduce

  1. Create a Quarto .qmd file with the following contents:
---
format:
  html:
    code-fold: true
    toc: true
    toc-depth: 6
    toc-expand: 2
    toc-location: right
    number-sections: true
    number-depth: 3
    toc-title: Contents
    anchor-sections: true
    smooth-scroll: true
    embed-resources: true  # Make the file self-contained.
execute:
  freeze: auto  # Re-render only when source changes
---

::: {.callout-important title="Enter variables about your project"}
```{ojs}
//| echo: false

viewof example_variable = Inputs.text({label: "Example variable"})

:::

Here is some example code for you to copy and paste:

Test 0: ${example_variable}

Test 1: ${example_variable}

Test 2: ojs example_variable

Test 3:

//| output: asis
//| echo: false
`
\`\`\`
${example_variable}
\`\`\`
`

Test 4:

# example using ${example_variable}

2. Render the file as HTML
3. Type "test123" into the input box.

### Expected behavior

1. All tests should replace "example_variable" with `test123`.
2. Test 3 should render code-block-formatted text, rather than a string.

### Actual behavior

1. Quarto does not interpolate variables within non-executed code blocks. (Is there an existing alternative syntax for this?)
2. The output of Test 3 is parsed as a string, rather than as Markdown.

![image](https://github.com/quarto-dev/quarto-cli/assets/3667562/7cfbf499-d365-449c-bddb-08bd1a0c65fa)

### Your environment

- IDE: VSCode 1.76.0, Quarto plugin 1.88.0
- MacOS Ventura 13.4

### Quarto check output

```bash
$ quarto check

[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.1.1: OK
      Dart Sass version 1.55.0: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.3.433
      Path: /Applications/quarto/bin

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

[✓] Checking Python 3 installation....OK
      Version: 3.7.16 (Conda)
      Path: /Users/<username>/mambaforge/envs/example_project/bin/python
      Jupyter: 4.12.0
      Kernels: python3

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

[✓] Checking R installation...........(None)

      Unable to locate an installed version of R.
      Install R from https://cloud.r-project.org/
cscheid commented 1 year ago

output:asis is not a supported ojs option; I don't quite understand why you're using it. Did our documentation imply otherwise? If so, we need fixing.

mcanouil commented 1 year ago

@cscheid It's listed as an option in the reference page, probably by default in the yaml schema, see https://quarto.org/docs/reference/cells/cells-ojs.html#cell-output.

cscheid commented 1 year ago

@mcanouil yikes, that's bad on our part. Thanks for pointing it out.

@jglev This works:


```{ojs}
foo = "bar"

${foo}.



You'll notice that the precise styling is different from the one you get from the backtick syntax. That's because OJS values are returned wrapped inside span elements (OJS return values are structured, so you can return lists, objects, etc). You'll need to inspect write the element in your browser's devtools and write the appropriate CSS.
jglev commented 1 year ago

Thank you both! I'm sorry to have misunderstood! To confirm, the link that @mcanouil provided is the section I had read.

@cscheid, thank you for that example! To your knowledge, is there a similar workaround for multi-line code snippets? The following currently seems to get parsed with Markdown rules for line breaks (i.e., everything gets moved to a single line):

<code>
${foo}
additional line 1
additional line 2
</code>.

image

(My original context for writing is that I'm trying to write a document that will self-update all of its code examples (which the user is meant to copy and paste) with a value from the user.)

mcanouil commented 1 year ago

Use double spaces or \ at the end of the line to make a line break in markdown (i.e., translated as <br> in HTML).

<code>
${foo}\
additional line 1\
additional line 2\
</code>.
cscheid commented 1 year ago

@jglev The type of code element you're looking for is pre, and not code (@mcanouil's answer will work somewhat, but you'll be fighting the standard CSS styling all the way).

With that said, the contents of a pre node are limited to text only, and so getting what you want won't be entirely easy, precisely because OJS outputs are structured. What you'll need to do instead is write an OJS reactive variable that builds the entire <pre> cell. The OJS execution model is very different from knitr. OJS is producing values that are eventually injected into the document DOM, as opposed to creating markdown (otherwise, we would have to call pandoc over and over again to render, but this is impossible since it's all happening in JavaScript, right?)

You'll need something like this:

```{ojs}
//| echo: false
{
  let result = document.createElement("pre");
  result.textContent = `
${foo}
additional line 1
additional line 2
`;
  return result;
}
jglev commented 1 year ago

@mcanouil and @cscheid, thank you both so much! I haven't used OJS before (I'd never heard of it before reading Quarto's documentation), so I'm very grateful for your help!

Again, thank you for all your work on this project!

mcanouil commented 1 year ago

@cscheid there might be other "default" options that are listed for Observable that should not:

cscheid commented 1 year ago
cscheid commented 9 months ago

This is, annoyingly, very hard to fix in our documentation, because we don't have the ability to provide different schemas for different cell types. We'll consider in 1.5.

cscheid commented 3 months ago

This fix belongs with a future larger redesign of our YAML validation infrastructure to support schemas that change depending on cell types, etc.