quarto-dev / quarto-dev/quarto-cli

qmd -> ipynb retains code lines only up to the first cell output

Open
#11,558 8 comments 0 reactions 1 assignee View on GitHub

@cscheid is already working on this.

Since Apr 7, 2025.

bug ipynb-format lua
Dominant language
JavaScript
Stars
6k
Forks
458
Avg merge
1d 9h
Merged PRs (30d)
41

Description

Bug description

The output of code into "source" field is only capturing up to the first emitted line of the code cell under engine: knitr.

For instance, if we have:

```{r}
x <- 1 + 1
x
print("Hello R world!")
sapply(1:10, function(x) x^2)
```

In the output.ipynb JSON have:

"source": [
  "x <- 1 + 1\n",
  "x"
],

with

"outputs": [
  {
    "output_type": "stream",
    "name": "stdout",
    "text": [
      "[1] 2"
    ]
  },
  {
    "output_type": "stream",
    "name": "stdout",
    "text": [
      "[1] \"Hello R world!\""
    ]
  },
  {
    "output_type": "stream",
    "name": "stdout",
    "text": [
      " [1]   1   4   9  16  25  36  49  64  81 100"
    ]
  }
],

Looking at the the native format, the results have been evaluated:

  , Div
      ( "" , [ "cell" ] , [] )
      [ CodeBlock
          ( "" , [ "r" , "cell-code" ] , [] ) "x <- 1 + 1\nx"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock ( "" , [] , [] ) "[1] 2" ]
      , CodeBlock
          ( "" , [ "r" , "cell-code" ] , [] )
          "print(\"Hello R world!\")"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock ( "" , [] , [] ) "[1] \"Hello R world!\"" ]
      , CodeBlock
          ( "" , [ "r" , "cell-code" ] , [] )
          "sapply(1:10, function(x) x^2)"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock
              ( "" , [] , [] )
              " [1]   1   4   9  16  25  36  49  64  81 100"
          ]
      ]

So, I think what's happening is only the first CodeBlock is being sent to "source" while the others are being correctly condensed and, then, sent to "output". This is similar for Python code as well.

On a side note, is there a way to have engine: jupyter evaluate code from a Qmd? The evaluate: false doesn't seem to be able to be overridden and the authoring within qmd doesn't seem to retain cell results in the output.

https://quarto.org/docs/computations/r.html#disabling-execution

Steps to reproduce

qmd -> ipynb

---
title: "Quarto Conversion"
format: jupyter
engine: knitr
---

# Overview

Testing a Quarto an R + Python notebook

## Active cells

```{r}
x <- 1 + 1
x
print("Hello R world!")
sapply(1:10, function(x) x^2)
```


```{python}
y = 1 + 6
print(y)
print("Hello Python world!")
[x**2 for x in range(10)]
```

## Inactive cells

```r
print("Goodbye R world!")
2 + 2

sapply(1:10, function(x) x^4)
```

```python
print("Hello Python world!")
print([x**2 for x in range(10)])
8 + 5
```

ipynb format full JSON output
{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# Quarto Conversion\n",
        "\n",
        "# Overview\n",
        "\n",
        "Testing a Quarto an R + Python notebook\n",
        "\n",
        "## Active cells"
      ],
      "id": "4f5a8b04-1046-41f8-9837-604ebaa0db0a"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[1] 2"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[1] \"Hello R world!\""
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            " [1]   1   4   9  16  25  36  49  64  81 100"
          ]
        }
      ],
      "source": [
        "x <- 1 + 1\n",
        "x"
      ],
      "id": "da39a8ca-a365-49e1-8e18-e465c57b33d7"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "7"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Hello Python world!"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
          ]
        }
      ],
      "source": [
        "y = 1 + 6\n",
        "print(y)"
      ],
      "id": "f2d24e33-fbe5-48e1-a4b6-18d181937c61"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Inactive cells\n",
        "\n",
        "``` r\n",
        "print(\"Goodbye R world!\")\n",
        "2 + 2\n",
        "\n",
        "sapply(1:10, function(x) x^4)\n",
        "```\n",
        "\n",
        "``` python\n",
        "print(\"Hello Python world!\")\n",
        "print([x**2 for x in range(10)])\n",
        "8 + 5\n",
        "```"
      ],
      "id": "d346e134-b945-4ad8-beea-cbf09a0b8340"
    }
  ],
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    }
  }
}

qmd -> native

---
title: "Quarto Conversion"
format: native
engine: knitr
---

# Overview

Testing a Quarto an R + Python notebook

## Active cells

```{r}
x <- 1 + 1
x
print("Hello R world!")
sapply(1:10, function(x) x^2)
```


```{python}
y = 1 + 6
print(y)
print("Hello Python world!")
[x**2 for x in range(10)]
```

## Inactive cells

```r
print("Goodbye R world!")
2 + 2

sapply(1:10, function(x) x^4)
```

```python
print("Hello Python world!")
print([x**2 for x in range(10)])
8 + 5
```

Native output
Pandoc
  Meta
    { unMeta =
        fromList
          [ ( "title"
            , MetaInlines [ Str "Quarto" , Space , Str "Conversion" ]
            )
          ]
    }
  [ Header 1 ( "overview" , [] , [] ) [ Str "Overview" ]
  , Para
      [ Str "Testing"
      , Space
      , Str "a"
      , Space
      , Str "Quarto"
      , Space
      , Str "an"
      , Space
      , Str "R"
      , Space
      , Str "+"
      , Space
      , Str "Python"
      , Space
      , Str "notebook"
      ]
  , Header
      2
      ( "active-cells" , [] , [] )
      [ Str "Active" , Space , Str "cells" ]
  , Div
      ( "" , [ "cell" ] , [] )
      [ CodeBlock
          ( "" , [ "r" , "cell-code" ] , [] ) "x <- 1 + 1\nx"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock ( "" , [] , [] ) "[1] 2" ]
      , CodeBlock
          ( "" , [ "r" , "cell-code" ] , [] )
          "print(\"Hello R world!\")"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock ( "" , [] , [] ) "[1] \"Hello R world!\"" ]
      , CodeBlock
          ( "" , [ "r" , "cell-code" ] , [] )
          "sapply(1:10, function(x) x^2)"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock
              ( "" , [] , [] )
              " [1]   1   4   9  16  25  36  49  64  81 100"
          ]
      ]
  , Div
      ( "" , [ "cell" ] , [] )
      [ CodeBlock
          ( "" , [ "python" , "cell-code" ] , [] )
          "y = 1 + 6\nprint(y)"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock ( "" , [] , [] ) "7" ]
      , CodeBlock
          ( "" , [ "python" , "cell-code" ] , [] )
          "print(\"Hello Python world!\")"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock ( "" , [] , [] ) "Hello Python world!" ]
      , CodeBlock
          ( "" , [ "python" , "cell-code" ] , [] )
          "[x**2 for x in range(10)]"
      , Div
          ( "" , [ "cell-output" , "cell-output-stdout" ] , [] )
          [ CodeBlock
              ( "" , [] , [] ) "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"
          ]
      ]
  , Header
      2
      ( "inactive-cells" , [] , [] )
      [ Str "Inactive" , Space , Str "cells" ]
  , CodeBlock
      ( "" , [ "r" ] , [] )
      "print(\"Goodbye R world!\")\n2 + 2\n\nsapply(1:10, function(x) x^4)"
  , CodeBlock
      ( "" , [ "python" ] , [] )
      "print(\"Hello Python world!\")\nprint([x**2 for x in range(10)])\n8 + 5"
  ]
Expected behavior

The source portion of the ipynb should list all of the code; not just the first code blocks after a cell is evaluated.

Actual behavior

All output was retained; but source contained only the lines inside of the cell up to the first line of code that output.

Your environment
  • IDE: VS Code 1.95.3
  • OS: macOS 15.1.1 (24B91)
Quarto check output
Quarto 1.6.37
[✓] Checking environment information...
      Quarto cache location: /Users/ronin/Library/Caches/quarto
[✓] Checking versions of quarto binary dependencies...
      Pandoc version 3.4.0: OK
      Dart Sass version 1.70.0: OK
      Deno version 1.46.3: OK
      Typst version 0.11.0: OK
[✓] Checking versions of quarto dependencies......OK
[✓] Checking Quarto installation......OK
      Version: 1.6.37
      Path: /Applications/quarto/bin

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

[✓] Checking LaTeX....................OK
      Using: Installation From Path
      Path: /opt/homebrew/bin
      Version: undefined

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

[✓] Checking Python 3 installation....OK
      Version: 3.12.7
      Path: /Users/ronin/Documents/GitHub/quarto/colab/build/bin/python3
      Jupyter: 5.7.2
      Kernels: ir, python3

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

[✓] Checking R installation...........OK
      Version: 4.4.2
      Path: /Library/Frameworks/R.framework/Resources
      LibPaths:
        - /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/library
      knitr: 1.49
      rmarkdown: 2.29

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.