quarto-dev / quarto-cli

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

Indenting executable codeblocks makes them malfunction #9970

Open GuillaumeDehaene opened 2 months ago

GuillaumeDehaene commented 2 months ago

Bug description

Normal markdown code supports nesting environments into one-another using indentation. For example, lists can be nested. Paragraphs can be nested into a list bullet-point. Also, indentation can be used to mark a verbatim block.

However, indenting executable code blocks makes them malfunction (for jupyter).

Steps to reproduce

This minimal example compiles to very weird markdown. The resulting html is weird. As far as I can tell, this is due to correct parsing of the weird markdown.

NB: this is a minimal example with a stupid output. The issue persists if using a Markdown(tabulate(...)) example or a matplotlib figure.

---
execute:
    echo: false

format: markdown
---

# Minimal example

```{python}
print("- Foo")
```{python}
print("- Foo")
```

After compilation

# Minimal example

:::: {.cell execution_count="1"}
::: {.cell-output .cell-output-stdout}
    - Foo
:::
::::

    ::: {.cell execution_count=2}

    ::: {.cell-output .cell-output-stdout}
- Foo
```
:::
:::

Expected behavior

I'm not sure what the expected behavior should be, without breaking everything and making everything super complex.

Actual behavior

Your environment

Quarto check output

Quarto 1.5.45 [>] Checking versions of quarto binary dependencies... Pandoc version 3.2.0: OK Dart Sass version 1.70.0: OK Deno version 1.41.0: OK Typst version 0.11.0: OK [>] Checking versions of quarto dependencies......OK [>] Checking Quarto installation......OK Version: 1.5.45 Path: C:\Users\Guillaume\AppData\Local\Programs\Quarto\bin 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....(None)

  Unable to locate an installed version of Python 3.
  Install Python 3 from https://www.python.org/downloads/

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

  Unable to locate an installed version of R.
  Install R from https://cloud.r-project.org/

PS D:\Desktop\Dojo\quarto_bug_report_listings>

I'm not sure why python is not seen but everything compiles as it should:

Python 3.12.4 (tags/v3.12.4:8e8a4ba, Jun 6 2024, 19:30:16) [MSC v.1940 64 bit (AMD64)] on win32

cscheid commented 2 months ago

Unfortunately that's a limitation in our Jupyter setup. Code cells are not part of markdown; they're executed as separate cells in the .ipynb file, and so they need to be "top level".

Yes, this is a bug, but it's a pretty foundational limitation that we won't be able to fix anytime soon.

GuillaumeDehaene commented 2 months ago

I honestly expected as much. Two small questions:

  1. Should I add a remark to the documentation of executable code blocks to say that they don't work when indented?
  2. Have you checked out how weird the markdown is in in the context of the list? From the outside, it looks like there's also a small bug in that generation. If so, it might be possible to fix that bug cheaply, which would hopefully repair indented executable codeblocks in that context?

For reference, I'm pasting the relevant section of the resulting markdown:

normal context

:::: {.cell execution_count="1"}
::: {.cell-output .cell-output-stdout}
    - Foo
:::
::::

list context

    ::: {.cell execution_count=3}

    ::: {.cell-output .cell-output-stdout} \`\`\`

    -   Foo \`\`\` ::: :::

There's a bunch of small differences

mcanouil commented 2 months ago

The issue described here is only for engine: jupyter. knitr and julia engines are working quite differently but ot necessarily as expected.

Quarto documentHTML
````qmd --- execute: echo: false engine: knitr format: markdown --- # Minimal example ```{r} print("- Foo") ``` ```{r} print("- Foo") ``` - Nesting list - Foo - Nesting list: ```{r} print("- Foo") ``` ```` ````markdown --- execute: echo: false toc-title: Table of contents --- # Minimal example :::: cell ::: {.cell-output .cell-output-stdout} [1] "- Foo" ::: :::: ::: {.cell} ::: {.cell-output .cell-output-stdout} ``` [1] "- Foo" ``` ::: ::: - Nesting list - Foo - Nesting list: ::: {.cell} ::: {.cell-output .cell-output-stdout} [1] "- Foo" ::: ::: ````
````qmd --- execute: echo: false engine: julia format: markdown --- # Minimal example ```{julia} print("- Foo") ``` ```{julia} print("- Foo") ``` - Nesting list - Foo - Nesting list: ```{julia} print("- Foo") ``` ```` ````markdown --- execute: echo: false toc-title: Table of contents --- # Minimal example :::: {.cell execution_count="1"} ::: {.cell-output .cell-output-stdout} - Foo ::: :::: ```{julia} print("- Foo") ``` - Nesting list - Foo - Nesting list: ``` {julia} print("- Foo") ``` ````
cderv commented 2 months ago

Interesting...

I know we deal with indent in knitr, but it seems we don't correctly write the cell output div with no indent as they should be.

Fenced div only works when no starting indent

Just to clarify, the support for indented code cell for knitr engine is not a Quarto thing, this is a feature of knitr inherit by Quarto.

Julia engine (from Quarto) does not seem to support it which is what I would have expected.