Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

code-tools + echo does not behave consistently on ipynb/qmd #11682

Open
mcanouil opened this issue Dec 13, 2024 · 6 comments
Open

code-tools + echo does not behave consistently on ipynb/qmd #11682

mcanouil opened this issue Dec 13, 2024 · 6 comments
Labels
bug Something isn't working jupyter

Comments

@mcanouil
Copy link
Collaborator

There is a weird unexpected interaction which changes depending on how the options are called on a Jupyter Notebook.

Assuming:

---
title: "Reproducible Quarto Document"
engine: jupyter
---

```{python}
print("Hello, world!")
```

```python
print("Goodbye, world!")
```

Converting it as a Jupyter Notebook via:

quarto convert index.qmd 
QMDIPYNB
Correct:
quarto render index.qmd --to html -M code-tools:true
image
Incorrect:
quarto render index.ipynb --to html -M code-tools:true
image
Correct:
quarto render index.qmd --to html -M code-tools:true -M echo:false
image
Incorrect:
quarto render index.ipynb --to html -M code-tools:true -M echo:false
image
Correct:
quarto render index.qmd --to html -M code-tools:true -M code-fold:true
image
Correct:
quarto render index.ipynb --to html -M code-tools:true -M code-fold:true
image
Correct:
quarto render index.qmd --to html -M code-tools:true -M code-fold:true -M echo:false
image
Incorrect:
quarto render index.ipynb --to html -M code-tools:true -M code-fold:true -M echo:false
image

Originally posted by @mcanouil in #11661 (reply in thread)

@mcanouil mcanouil added the bug Something isn't working label Dec 13, 2024
@mcanouil
Copy link
Collaborator Author

Additionally, code-tools: true only takes effect in Jupyter notebook with code-fold: true (possibly with other options as well).
code-tools: true does not work on default settings.

@cderv
Copy link
Collaborator

cderv commented Dec 24, 2024

I believe this correct code-tools behavior as it was designed.

In short, code-tools: true means to show the menu, but only if there is something to add in the menu

  • View Source needs to be added only if a source is to be included, and .ipynb is not considered a source to include today
  • Hide All / Show All are only added to menu if some folded code are in the document, so when code-fold: true and source code are present (echo: true)
  • If one of the above is to show in the menu, Code Tools menu button is included in the HTML

Probably this should be more clearly documented.

Some more details:

Let me try to show what it is supposed to do and which logic applies to know if this is worth adding it.

code-tools: true means to add a menu button with source: true as default, toggle: true and caption: true. Each config is documented in https://quarto.org/docs/output-formats/html-code.html#code-tools

However, this default logic has some exception

  • Only .qmd are considered source. .ipynb input are not considered source file to include behind view source button.
    This is determined by engine and this is for Jupyter

    canKeepSource: (target: ExecutionTarget) => {
    return !isJupyterNotebook(target.source);
    },

    // if we have request source without an external url,
    // make sure we are able to keep source
    if (codeToolsResolved.source === true) {
    codeToolsResolved.source = !!format.render[kKeepSource];
    }

    If no source to keep, then the menu won't show for it.
    export function codeToolsPostprocessor(format: Format) {
    return (doc: Document): Promise<HtmlPostProcessResult> => {
    return withTiming("codeToolsPostprocessor", () => {
    if (format.render[kKeepSource]) {

  • Then toggle: true by default, only applies when there is something to toggle.

    // if we have requested toggle, make sure there are things to toggle
    if (codeToolsResolved.toggle) {
    const codeDetails = doc.querySelector(".cell > details > .sourceCode");
    // we don't OJS hidden cells in this check, since when echo: false, we emit them hidden
    const codeHidden = doc.querySelector(
    ".cell .sourceCode.hidden:not(div pre.js)",
    );
    codeToolsResolved.toggle = !!codeDetails || !!codeHidden;
    }

    And details will be used only when code-fold: true is set. Default is no folding. So need to show Code tools menu.

Based on all this, I don't see any issue in the example you gave. This is just expected behavior for .ipynb notebook used as input. Maybe we should just documented in more.

In summary, regarding code-tools: true, this is equivalent to

code-tools:
  source: true
  toogle: true
  caption: true

however, for ipynb, it is

code-tools:
  source: false
  toggle: true
  caption: true

and for both .qmd and .ipynb, toggle: true has effect only if code-fold: true because otherwise nothing to show or hide.

You can reproduce the ipynb behavior by setting source: false in .qmd

---
title: "Reproducible Quarto Document"
engine: jupyter
code-tools: 
  source: false
  toggle: true
execute: 
  echo: false
---

```{python}
print("Hello, world!")
```

```python
print("Goodbye, world!")
```

This will give you the result with no code-tools menu.

We could think of making improvement to this (like adding ipynb source as base64 encoded document to download when clicking on the button) but this is a different issue.

@mcanouil
Copy link
Collaborator Author

mcanouil commented Dec 24, 2024

Then quarto render index.ipynb --to html -M code-tools:true -M code-fold:true should not display the code tools menu if ipynb is not a source, but it does.
So the logic you've described does not fully apply.

@cderv
Copy link
Collaborator

cderv commented Dec 24, 2024

Then quarto render index.ipynb --to html -M code-tools:true -M code-fold:true should not display the code tools menu if ipynb is not a source, but it does.

code-fold: true means to apply folding to source code, which happens, and then code-tools: true, will set toggle: true so Show All Code / Hide All Code selector needs to be shown, hence why the code tools menu shows.

Image

It seems I made an error in my short explanation at the top, so I edited it.
I may have explained it wrong previously, but this is what I meant by

toggle: true has effect only if code-fold: true because otherwise nothing to show or hide.

@cderv
Copy link
Collaborator

cderv commented Dec 24, 2024

Let me try to sum up differently current situation. The Code Tools menu is shown only when

  • source: true or source: <external url>
    • 'View Source' needs to be shown in Code Tools menu
  • toggle: true and code-fold: true and echo: true
    • Some code source are folded in the document, and a main toggle is asked for so "Show All Code / Hide All Code" needs to be shown in the Code Tools menu.

When source: false and toggle: false, no code tools menu is included.

Special behavior happens in the following:

  • source: true default, is set to source: false when .ipynb is the source input.
  • toggle: true means show the toggle for hide / show, but they are included only if there is folded code source cells in the document. Which means it won't be added when
    • echo : false is set globally
    • code-fold: false which is the default.

Maybe I missed something, but your different examples all fall into one of this case.

I don't say design could not be improved but it currently behave correctly to me.

The main difference between .qmd and .ipynb is that ipynb source is considered to be included as text in the View Source modal that opens when you click the button.

@mcanouil
Copy link
Collaborator Author

mcanouil commented Dec 24, 2024

I see. I now understand the behaviour but it's not intuitive at all as code-tools is mostly used/described to show the source and with code-fold, the behaviour changes to add tools to control folding.

In my opinion and as a proposed enhancement:

  • code-tools should be ignored under all circumstances for Jupyter Notebook.
  • code-fold should gain a toggle value (as a replacement of the sub option of code-tools or at least as a direct way to control the option) which would trigger the current behaviour for both qmd and ipynb.

Note that this change/enhancement of the code-tools button could be part of more general improvement (consistency also):

"source" would be added the same way as "other links", "other formats".
And folding controls would be put in code-fold which would make things clearer/simpler I believe.
(I don't think there is a need to do a breaking change for these)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working jupyter
Projects
None yet
Development

No branches or pull requests

3 participants