Skip to content

Task lists: the checkbox replaces the bullet, per item (#892) - #1191

Merged
cscheid merged 5 commits into
mainfrom
bugfix/issue-892
Nov 12, 2026
Merged

cscheid merged 5 commits into
mainfrom
bugfix/issue-892

Conversation

@cscheid

@cscheid cscheid commented Nov 12, 2026

Copy link
Copy Markdown
Member

Closes #892.

Problem

Task-list items in q2 render and q2 preview showed both the list bullet and the checkbox. Quarto 1 hides the bullet with a ul.task-list { list-style: none } rule from its patched Pandoc styles.html template. Q2 never ported that rule. It only ported the two _quarto-rules.scss rules.

Approach

Before choosing a fix, the triage surveyed about 20 markdown renderers and SSGs (claude-notes/issue-reports/892/survey.md, summary in triage.md). Nearly every renderer that ships CSS hides the marker per item. Pandoc, and therefore Quarto 1, hides it per list, so a mixed list still shows a bullet next to the checkbox. We follow the ecosystem. The design decisions are recorded in triage.md § Decisions:

  1. Per-item marker hiding.
    • The HTML writer and q2-preview add class="task-list-item" to every task <li>. The class is additive, and ul.task-list keeps Pandoc's rule that every item must be a task.
    • The theme hides the marker on li.task-list-item and hangs the checkbox into the marker's gutter, so task text lines up with plain items.
  2. Ordered task items keep their numbers by default. The $task-list-ordered-markers theme variable is an escape hatch: set it to false in a theme's scss:defaults layer. It works in both the HTML and revealjs themes and is documented in the themes guide.
  3. An empty - [ ] is a task item. This is what a user has just typed in the collaborative editor. It used to be a parse error. The grammar now accepts it, the reader produces Pandoc's Plain [Str "☐"], and the qmd writer round-trips it. - [ ] with no trailing space is still an ordinary item, as in GFM.
  4. Static checkboxes are disabled. Edit surfaces keep enabled, toggleable checkboxes.

Other fixes found along the way

  • A hoisted item attribute (- [ ] todo {.c}) was dropped on task items. The writer now splits the attribute off before rewriting the task item.
  • The incremental (revealjs) <ol> path in q2-preview didn't render task checkboxes. It now matches the <ul> path.

Review notes

  • Grammar change. parser.c and grammar.json are regenerated. crates/pampa/resources/error-corpus/_autogen-table.json is regenerated with build_error_table.ts; parser state numbers shifted, and every table entry maps one-to-one onto a new state.
  • Snapshots. No insta .snap files changed. The styles.css hash in the phase5 single-doc baseline was re-captured: this is a CSS-only change, doc.html is unchanged, and the reason is noted in the file.
  • Follow-up, not in this PR. bd-nnvvomg6: the HTML writer drops <p> in loose list items that hold a single paragraph. This is general Pandoc parity work and also affects loose task lists.

Tests

  • tree-sitter corpus: 2 new tests (empty task items).
  • pampa test_task_list: 5 new, 3 updated (markup, empty item, attribute composition, qmd round-trip).
  • quarto-sass: 3 new (marker rules, the escape hatch through a user custom.scss, revealjs), 1 updated.
  • preview-renderer integration: 2 new, 3 extended. With the original renderer sources, 5 of these fail.
  • hub-client e2e q2-preview-task-list.spec.ts (Chromium, real q2-preview iframe):
    • every task <li> computes list-style-type: none;
    • the checkbox sits left of the <li> box, and the text starts within 2px of the <li> content edge;
    • plain siblings in the mixed list keep their bullets.
  • cargo xtask verify (full) passes locally.

End-to-end check (inspected): q2 render on claude-notes/issue-reports/892/repro.qmd emits <li class="task-list-item"><label><input type="checkbox" disabled="" />task</label></li> next to <li>plain item</li>. The compiled CSS contains ul>li.task-list-item{list-style-type:none} and the hang rule margin:0 .4em .2em -1.2em.

🤖 Generated with Claude Code

cscheid and others added 5 commits November 12, 2026 09:00
…y (bd-2ydvebkc)

Triage record and repro under claude-notes/issue-reports/892/, plus a
survey of how ~20 markdown renderers/SSGs emit and style task lists.
Root cause: the Quarto 1 styles.html list-style:none rule was never ported
to the Q2 HTML pipeline. Related: bd-nnvvomg6 (loose list items lose <p>).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ydvebkc)

Task items in q2 render and q2 preview showed both the list bullet and the
checkbox: Q2 never ported the `list-style: none` rule Quarto 1 gets from its
patched pandoc styles.html. Following the ecosystem survey
(claude-notes/issue-reports/892/survey.md) the marker is now hidden per item
rather than per list, so task items in mixed lists lose their bullet too.

- HTML writer + q2-preview: every task <li> carries class="task-list-item"
  (additive; ul.task-list keeps Pandoc's all-items rule). Static checkboxes
  are `disabled` (edit surfaces keep enabled, toggleable ones). Fixes a
  hoisted item attr (`- [ ] x {.c}`) being dropped on task items.
- SCSS: hide the marker on li.task-list-item and hang the checkbox into the
  marker gutter (text aligns with plain items); ordered task items keep
  their number unless a theme sets `$task-list-ordered-markers: false`
  (HTML and revealjs).
- Grammar/reader: an empty task item (`- [ ] `, what a user has typed just
  before the text) is a task item, `Plain [Str "☐"]` as in Pandoc, instead
  of a parse error; the qmd writer round-trips it. Regenerated parser.c and
  the pampa parse-error table (_autogen-table.json: state renumbering only).
- q2-preview: the incremental (reveal) <ol> path renders task checkboxes
  like the <ul> path.
- Docs: task lists in the markdown basics guide; the theme variable in the
  HTML themes guide.

Tests: tree-sitter corpus (2 new), pampa test_task_list (5 new, 3
updated), quarto-sass (3 new, 1 updated), preview-renderer integration (2
new, 3 extended), hub-client e2e q2-preview-task-list (computed
list-style-type and checkbox/text geometry). No insta .snap files changed;
the phase5 baseline styles.css hash is re-captured (CSS-only change, doc.html
unchanged).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ebkc)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@posit-snyk-bot

posit-snyk-bot commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

✅ Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
✅ Open Source Security 0 0 0 0 0 issues
✅ Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cscheid
cscheid merged commit 0d7b3cf into main Nov 12, 2026
17 checks passed
@cscheid
cscheid deleted the bugfix/issue-892 branch November 12, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

preview rendering of bullet points is wonky

2 participants