Fix chomping images when TODO is typed and converts to a checkbox

This commit is contained in:
Miguel Jacq 2025-11-08 18:13:56 +11:00
parent 39576ac7f3
commit fa23cf4da9
Signed by: mig5
GPG key ID: 59B3F0C24135C6A9
3 changed files with 32 additions and 43 deletions

View file

@ -1,3 +1,7 @@
# 0.2.0.1
* Fix chomping images when TODO is typed and converts to a checkbox
# 0.2.0 # 0.2.0
* Switch back to Markdown editor * Switch back to Markdown editor

View file

@ -245,53 +245,38 @@ class MarkdownEditor(QTextEdit):
self._updating = True self._updating = True
try: try:
# Convert checkbox markdown to Unicode for display c = self.textCursor()
cursor = self.textCursor() block = c.block()
pos = cursor.position() line = block.text()
pos_in_block = c.position() - block.position()
text = self.toPlainText() # Transform only this line:
# - "TODO " at start (with optional indent) -> "- ☐ "
# Convert lines that START with "TODO " into an unchecked checkbox. # - "- [ ] " -> "- ☐ " and "- [x] " -> "- ☑ "
# Keeps any leading indentation. def transform_line(s: str) -> str:
todo_re = re.compile(r"(?m)^([ \t]*)TODO\s") s = s.replace("- [x] ", f"- {self._CHECK_CHECKED_DISPLAY} ")
if todo_re.search(text): s = s.replace("- [ ] ", f"- {self._CHECK_UNCHECKED_DISPLAY} ")
modified_text = todo_re.sub( s = re.sub(
r'^([ \t]*)TODO\b[:\-]?\s+',
lambda m: f"{m.group(1)}- {self._CHECK_UNCHECKED_DISPLAY} ", lambda m: f"{m.group(1)}- {self._CHECK_UNCHECKED_DISPLAY} ",
text, s,
) )
else: return s
modified_text = text
# Replace checkbox markdown with Unicode (for display only) new_line = transform_line(line)
modified_text = modified_text.replace( if new_line != line:
"- [x] ", f"- {self._CHECK_CHECKED_DISPLAY} " # Replace just the current block
) bc = QTextCursor(block)
modified_text = modified_text.replace( bc.beginEditBlock()
"- [ ] ", f"- {self._CHECK_UNCHECKED_DISPLAY} " bc.select(QTextCursor.BlockUnderCursor)
) bc.insertText(new_line)
bc.endEditBlock()
if modified_text != text:
# Count replacements before cursor to adjust position
text_before = text[:pos]
x_count = text_before.count("- [x] ")
space_count = text_before.count("- [ ] ")
# Each markdown checkbox -> unicode shortens by 2 chars ([x]/[ ] -> ☑/☐)
checkbox_delta = (x_count + space_count) * 2
# Each "TODO " -> "- ☐ " shortens by 1 char
todo_count = len(list(todo_re.finditer(text_before)))
todo_delta = todo_count * 1
new_pos = pos - checkbox_delta - todo_delta
# Update the text
self.blockSignals(True)
self.setPlainText(modified_text)
self.blockSignals(False)
# Restore cursor position
cursor = self.textCursor()
cursor.setPosition(max(0, min(new_pos, len(modified_text))))
self.setTextCursor(cursor)
# Restore cursor near its original visual position in the edited line
new_pos = min(block.position() + len(new_line),
block.position() + pos_in_block)
c.setPosition(new_pos)
self.setTextCursor(c)
finally: finally:
self._updating = False self._updating = False

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "bouquin" name = "bouquin"
version = "0.2.0" version = "0.2.0.1"
description = "Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher." description = "Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher."
authors = ["Miguel Jacq <mig@mig5.net>"] authors = ["Miguel Jacq <mig@mig5.net>"]
readme = "README.md" readme = "README.md"