fix(notes): ignore todo-looking lines inside fenced code blocks by rudycelekli · Pull Request #69 · rociiu/talorys · GitHub
Skip to content

fix(notes): ignore todo-looking lines inside fenced code blocks - #69

Merged
rociiu merged 1 commit into
rociiu:mainfrom
rudycelekli:fix/notes-todo-count-in-code-fences-20261017
Oct 22, 2026
Merged

rociiu merged 1 commit into
rociiu:mainfrom
rudycelekli:fix/notes-todo-count-in-code-fences-20261017

Conversation

@rudycelekli

@rudycelekli rudycelekli commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Problem: the notes todo counter (taskStats, shown on the note list and in the editor) and toggleTaskLine treat any line that looks like - [ ] text as a todo, even inside a fenced code block. A note that documents Markdown with an example in a code fence gets inflated "x of y done" counts for items the preview renders as plain code and that cannot be checked.

Fix: track fenced blocks the same way the editor's highlighter already does (a line starting with three backticks or tildes toggles the fence) and skip those lines in both functions. Todos outside fences behave as before.

Test: new apps/web/test/writer-tasks.test.ts; both cases fail on main and pass now. Web suite, tsc --noEmit -p apps/web and biome lint apps/web pass.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@rociiu rociiu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A single line starting with three backticks disables every todo below it.

fencedLines treats any line that starts with ``` or ~~~ as opening or closing a fence. The preview (remark, CommonMark) is stricter, so the two can disagree. For example:

```npm install```
- [ ] real todo

To the preview, the first line is a paragraph with inline code, because a backtick fence's info string can't contain backticks. So - [ ] real todo renders as a clickable checkbox. fencedLines instead treats that line as an opening fence, so every todo after it:

  • drops out of the taskStats "x of y done" count;
  • does nothing when clicked in the preview, because toggleTaskLine returns the text unchanged.

On main those todos work, so this is a regression. The highlighter has the same loose rule (WriterEditor.tsx:73, :232), but there it only affected colors.

Other cases where the two disagree:

  • A line indented 4+ spaces (` ```) is indented code, not a fence.
  • A ~~~ line inside a block opened with backticks (or the reverse) doesn't close it.
  • A closing fence must use the same character, be at least as long as the opener, and have nothing after it but spaces. So ```js inside an open block is content.

Suggested fix: open a fence only on ^ {0,3}({3,}|~{3,})`, where a backtick fence's remaining text contains no backticks. Close it only on the same character, at least as long, followed by nothing but spaces. Please add a test with the inline ```code``` line followed by a todo.

@rociiu rociiu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review notes. The main concern: the new fence detection doesn't match CommonMark, which is what the preview (react-markdown) renders. When the two disagree, real todos outside code blocks stop counting and can't be toggled from the preview. That's a regression from main.

Two more points outside the diff lines:

  • The editor's own toggle paths skip the fence check (toggleTaskAt, used by Cmd+Enter, clicking [ ], and toggleTaskAtCursor). They still use plain TASK_RE, so Cmd+Enter on - [ ] example inside a ``` block flips it to [x] and edits the code example, even though the counter and preview say it isn't a todo.
  • Duplicated fence logic. The highlighter still has its own /^\s*(```|~~~)/ in highlightLine and in the render loop, each with its own toggle. Once the matching rules are fixed, the render loop should use fencedLines(lines) / FENCE_RE so the highlighter, counter and toggle agree.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flips state on any ``` or ~~~ line. In CommonMark a fence closes only on the same character with at least the same length as the opener.

Example: a note documenting Markdown uses a ````md (or ~~~) block containing a example. The inner closes the block early, and the real closing fence then opens a new one. Every real - [ ] below it drops out of `taskStats`, and clicking its checkbox in the preview does nothing, because `toggleTaskLine` returns the text unchanged.

Suggestion: remember the opening fence's character and length, and close only on a line of the same character that is at least as long and has nothing else on it.

};

const TASK_RE = /^(\s*(?:[-*+]|\d+[.)])\s+)\[([ xX])\](\s|$)/;
const FENCE_RE = /^\s*(```|~~~)/;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also matches lines CommonMark does not treat as fences:

  • lines indented 4+ spaces (indented code)
  • a backtick fence whose info string contains a backtick, e.g. ```npm i``` on its own line, which is inline code

Either one opens a phantom fence, and every todo after it in the note stops counting or toggling. Something like /^ {0,3}({3,}|~{3,})/` plus a no-backticks-in-info check for backtick fences would match the renderer.

@rociiu

rociiu commented Oct 22, 2026

Copy link
Copy Markdown
Owner

@rociiu
rociiu merged commit f10a8eb into rociiu:main Oct 22, 2026
1 check passed
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.

2 participants