fix(blog): نقلقول داخل آیتم فهرست بیرون میآید — خط مسی همهٔ نقلقولها یکخط align میشود
This commit is contained in:
+60
-1
@@ -44,6 +44,64 @@ def _is_junk_paragraph(node: Any) -> bool:
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _lift_lists_flat(node: Any) -> list[Any]:
|
||||||
|
"""گره را به دنبالهای از گرههای نرمال تبدیل میکند — نقلقولهای داخل
|
||||||
|
آیتم فهرست به سطح خود فهرست میآیند تا خط مسی همهٔ نقلقولها یکخط شود."""
|
||||||
|
if not isinstance(node, dict):
|
||||||
|
return [node]
|
||||||
|
flat_content: list[Any] = []
|
||||||
|
for child in node.get("content") or []:
|
||||||
|
flat_content.extend(_lift_lists_flat(child))
|
||||||
|
node["content"] = flat_content
|
||||||
|
|
||||||
|
if node.get("type") not in ("bulletList", "orderedList"):
|
||||||
|
return [node]
|
||||||
|
|
||||||
|
rebuilt: list[Any] = []
|
||||||
|
pending_items: list[Any] = []
|
||||||
|
for li in node.get("content") or []:
|
||||||
|
if not isinstance(li, dict) or li.get("type") != "listItem":
|
||||||
|
pending_items.append(li)
|
||||||
|
continue
|
||||||
|
parts: list[list[Any]] = [[]]
|
||||||
|
for child in li.get("content") or []:
|
||||||
|
if isinstance(child, dict) and child.get("type") == "blockquote":
|
||||||
|
parts.append(child)
|
||||||
|
parts.append([])
|
||||||
|
else:
|
||||||
|
parts[-1].append(child)
|
||||||
|
if len(parts) == 1:
|
||||||
|
pending_items.append(li)
|
||||||
|
continue
|
||||||
|
if parts[0]:
|
||||||
|
li["content"] = parts[0]
|
||||||
|
pending_items.append(li)
|
||||||
|
for part in parts[1:]:
|
||||||
|
if isinstance(part, dict) and part.get("type") == "blockquote":
|
||||||
|
if pending_items:
|
||||||
|
rebuilt.append({**node, "content": pending_items})
|
||||||
|
pending_items = []
|
||||||
|
rebuilt.append(part)
|
||||||
|
else:
|
||||||
|
pending_items.extend(part)
|
||||||
|
if pending_items:
|
||||||
|
rebuilt.append({**node, "content": pending_items})
|
||||||
|
return rebuilt
|
||||||
|
|
||||||
|
|
||||||
|
def _lift_doc(doc: Any) -> Any:
|
||||||
|
lifted = _lift_lists_flat(doc)
|
||||||
|
if len(lifted) == 1 and isinstance(lifted[0], dict) and lifted[0].get("type") == "doc":
|
||||||
|
return lifted[0]
|
||||||
|
content: list[Any] = []
|
||||||
|
for part in lifted:
|
||||||
|
if isinstance(part, dict) and part.get("type") == "doc":
|
||||||
|
content.extend(part.get("content") or [])
|
||||||
|
else:
|
||||||
|
content.append(part)
|
||||||
|
return {"type": "doc", "content": content}
|
||||||
|
|
||||||
|
|
||||||
def _walk(node: Any) -> Any:
|
def _walk(node: Any) -> Any:
|
||||||
if isinstance(node, list):
|
if isinstance(node, list):
|
||||||
return [_walk(item) for item in node]
|
return [_walk(item) for item in node]
|
||||||
@@ -73,4 +131,5 @@ def sanitize_doc(doc: Any) -> Any:
|
|||||||
"""سند TipTap را درجا پاک میکند (سایر ساختارها دستنخورده برمیگردند)."""
|
"""سند TipTap را درجا پاک میکند (سایر ساختارها دستنخورده برمیگردند)."""
|
||||||
if not isinstance(doc, dict):
|
if not isinstance(doc, dict):
|
||||||
return doc
|
return doc
|
||||||
return _walk(doc)
|
walked = _walk(doc)
|
||||||
|
return _lift_doc(walked)
|
||||||
|
|||||||
Reference in New Issue
Block a user