quarto-dev / quarto-cli

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

RevealJS infinite loop when slide title matches Mermaid element id case-insensitively #10455

Open mfisher87 opened 3 months ago

mfisher87 commented 3 months ago

Bug description

When creating a RevealJS output with a Mermaid diagram, you can craft a situation where the deck mysteriously loops. This happens when you have a Mermaid diagram containing elements with IDs that match (case-insensitively) a slide header.

It's easy to get into this situation without realizing it. You can work around it easily if you're aware of this pitfall, perhaps by prefixing all your mermaid diagram's ID strings.

Steps to reproduce

---
title: "Demo: looping slide deck"
subtitle: "💫 Wheee! 💫"
format:
  revealjs: default
---

## Foo

```{mermaid}
gantt
  Foo     :active, magicstring, 2024-01, 2024-02 

Magicstring

This header :point_up: is critical. If I change one character, the bug no longer reproduces. It must match, case-insensitive, the ID of an element in the Mermaid diagram. Any string will work. Case doesn't matter.

This slide will never be displayed; instead, the slide deck will loop from the beginning.

The content below this point doesn't matter.

More slides!


Something!


* `quarto render index.qmd`
* Open `index.html`
* Try to access the string with the header "Magicstring"

See also: https://github.com/mfisher87/sscce-quarto-slides-loop

### Expected behavior

I will be able to access the slide with the header "Magicstring"

### Actual behavior

The slide deck starts from the beginning when I attempt to access that slide.

### Your environment

- IDE: vim
- OS: Pop!_OS 22

### Quarto check output

```bash
$ quarto check
Quarto 1.5.56
[✓] 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.56
      Path: /opt/quarto/bin

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

[✓] Checking LaTeX....................OK
      Using: TinyTex
      Path: /home/robatt/.TinyTeX/bin/x86_64-linux
      Version: 2023

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

[✓] Checking Python 3 installation....OK
      Version: 3.10.14 (Conda)
      Path: /home/robatt/.local/share/miniforge3/bin/python
      Jupyter: (None)

      Jupyter is not available in this Python installation.
      Install with conda install jupyter

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

      Unable to locate an installed version of R.
      Install R from https://cloud.r-project.org/
mcanouil commented 3 months ago

That's not really a Quarto bug. That's HTML specification where IDs should be unique.

Note that Quarto offers identifier-prefix as described in reference pages.

mfisher87 commented 3 months ago

Thanks for the heads up on identifier-prefix! It seems fairly easy for someone to get in to a situation like this, though. It actually took me quite some time to narrow down the reason my slick deck was looping; it didn't even occur to me that Mermaid would be generating HTML elements with identifiers exactly matching the identifiers I chose; I was just trying to choose intuitive names. Perhaps it would be useful to add an entry to the "troubleshooting" portion of the docs, for example:

My internal links or slide decks don't navigate the way I expect

For example, a slide deck which gets in to a loop after a certain point, or an HTML anchor which navigates to the wrong place. This can be caused by conflicting HTML IDs generated by various components of your document. Each slide in a RevealJS deck has a header with an HTML ID generated based on the header name. Additionally, elements of Mermaid diagrams have HTML IDs matching their Mermaid IDs. When these generated IDs match, weird things can happen. Consider using the identifier-prefix option for the HTML format to avoid such conflicts.

cscheid commented 3 months ago

it didn't even occur to me that Mermaid would be generating HTML elements with identifiers exactly matching the identifiers I chose

Unfortunately, we also don't control what MermaidJS will generate, and this can happen at runtime. I'm not sure what we can do from Quarto's side to avoid the behavior from happening.

mfisher87 commented 3 months ago

That makes total sense. No ideas here either (aside from documentation ones :))