commit - 51d10b6fa8a8b60a714a894943377221cc93e435
commit + b1bb43919e8bed91acc21b4bb94d0ad9d34e3105
blob - 63304b2e41e165570a3cebe1e71b59a1842dc2b6
blob + 78ffd2d86e14a6fd54c1f34f719bcfabcef1a14a
--- nezzontli_ctl/preview.py
+++ nezzontli_ctl/preview.py
return {m.group(1): m.group(2) for m in _KV_RE.finditer(raw)}
+_CODE_FENCE_RE = re.compile(r"```[^\n]*\n.*?\n```", re.DOTALL)
+
+
+def _split_plain_paragraphs(text, base_offset):
+ """[(párrafo, offset_absoluto), ...] separados por 1+ líneas en blanco,
+ salteando los que quedan vacíos."""
+ parts = []
+ cursor = 0
+ for m in re.finditer(r"\n{2,}", text):
+ para = text[cursor:m.start()]
+ if para.strip():
+ parts.append((para, base_offset + cursor))
+ cursor = m.end()
+ tail = text[cursor:]
+ if tail.strip():
+ parts.append((tail, base_offset + cursor))
+ return parts
+
+
def split_paragraphs_with_offsets(chunk):
"""[(párrafo, offset_en_chunk), ...] separados por 1+ líneas en blanco,
salteando los que quedan vacíos. Un tramo largo de texto plano (sin
imagen (si la había) se volvía a mover el preview. Sin más fórmulas
después, se quedaba pegado ahí el resto del documento. Con un anchor
por párrafo, el sync tiene puntos de referencia repartidos parejo en
- todo el texto, no solo donde hay imágenes/fórmulas."""
+ todo el texto, no solo donde hay imágenes/fórmulas.
+
+ Los bloques ```código``` son un párrafo atómico, nunca se parten por
+ las líneas en blanco que tengan adentro (código con espaciado entre
+ funciones/comentarios, típico) — si se parten, cada pedazo reabre su
+ propio widget Markdown con su propio margen y el bloque se ve hecho
+ pedazos con huecos enormes en vez de un solo bloque de código."""
parts = []
cursor = 0
- for m in re.finditer(r"\n{2,}", chunk):
- para = chunk[cursor:m.start()]
- if para.strip():
- parts.append((para, cursor))
+ for m in _CODE_FENCE_RE.finditer(chunk):
+ parts.extend(_split_plain_paragraphs(chunk[cursor:m.start()], cursor))
+ parts.append((m.group(0), m.start()))
cursor = m.end()
- tail = chunk[cursor:]
- if tail.strip():
- parts.append((tail, cursor))
+ parts.extend(_split_plain_paragraphs(chunk[cursor:], cursor))
return parts