diff --git a/README.md b/README.md
index 6b212f4..6593930 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ This package provides Python implementations of the following
[ProseMirror](https://prosemirror.net/) packages:
- [`prosemirror-model`](https://github.com/ProseMirror/prosemirror-model) version 1.18.1
-- [`prosemirror-transform`](https://github.com/ProseMirror/prosemirror-transform) version 1.7.1
+- [`prosemirror-transform`](https://github.com/ProseMirror/prosemirror-transform) version 1.7.5
- [`prosemirror-test-builder`](https://github.com/ProseMirror/prosemirror-test-builder)
- [`prosemirror-schema-basic`](https://github.com/ProseMirror/prosemirror-schema-basic) version 1.1.2
- [`prosemirror-schema-list`](https://github.com/ProseMirror/prosemirror-schema-list)
diff --git a/prosemirror/transform/structure.py b/prosemirror/transform/structure.py
index 7240f5f..ce878b0 100644
--- a/prosemirror/transform/structure.py
+++ b/prosemirror/transform/structure.py
@@ -122,14 +122,17 @@ def can_split(doc, pos, depth=None, types_after=None):
if node.type.spec.get("isolating"):
return False
rest = node.content.cut_by_index(index, node.child_count)
+ if types_after and len(types_after) > i:
+ override_child = types_after[i + 1]
+ rest = rest.replace_child(
+ 0, override_child["type"].create(override_child.get("attrs"))
+ )
after = None
if types_after and len(types_after) > i:
after = types_after[i]
if not after:
after = node
if isinstance(after, dict):
- if after != node:
- rest = rest.replace_child(0, after["type"].create(after.get("attrs")))
if not node.can_replace(index + 1, node.child_count) or not after[
"type"
].valid_content(rest):
diff --git a/prosemirror/transform/transform.py b/prosemirror/transform/transform.py
index 131d03b..ac67a4d 100644
--- a/prosemirror/transform/transform.py
+++ b/prosemirror/transform/transform.py
@@ -1,3 +1,4 @@
+import re
from typing import Union
from prosemirror.model import Fragment, Mark, MarkType, Node, NodeType, Slice
@@ -156,24 +157,43 @@ def clear_incompatible(self, pos, parent_type, match=None):
if match is None:
match = parent_type.content_match
node = self.doc.node_at(pos)
- del_steps = []
+ repl_steps = []
cur = pos + 1
for i in range(node.child_count):
child = node.child(i)
end = cur + child.node_size
allowed = match.match_type(child.type, child.attrs)
if not allowed:
- del_steps.append(ReplaceStep(cur, end, Slice.empty))
+ repl_steps.append(ReplaceStep(cur, end, Slice.empty))
else:
match = allowed
for j in range(len(child.marks)):
if not parent_type.allows_mark_type(child.marks[j].type):
self.step(RemoveMarkStep(cur, end, child.marks[j]))
+ if child.is_text and not parent_type.spec.get("code"):
+ newline = re.compile(r"\r?\n|\r")
+ slice = None
+ m = newline.search(child.text)
+ while m:
+ if slice is None:
+ slice = Slice(
+ Fragment.from_(
+ parent_type.schema.text(
+ " ", parent_type.allowed_marks(child.marks)
+ )
+ ),
+ 0,
+ 0,
+ )
+ repl_steps.append(
+ ReplaceStep(cur + m.start(), cur + m.end(), slice)
+ )
+ m = newline.search(child.text, m.end())
cur = end
if not match.valid_end:
fill = match.fill_before(Fragment.empty, True)
self.replace(cur, cur, Slice(fill, 0, 0))
- for item in reversed(del_steps):
+ for item in reversed(repl_steps):
self.step(item)
return self
@@ -240,11 +260,13 @@ def replace_range(self, from_, to, slice):
d = preferred_depth - 1
while d >= 0:
- type = left_nodes[d].type
- def_ = defines_content(type)
- if def_ and from__.node(preferred_target_index).type.name != type.name:
+ left_node = left_nodes[d]
+ def_ = defines_content(left_node.type)
+ if def_ and not left_node.same_markup(
+ from__.node(abs(preferred_target) - 1)
+ ):
preferred_depth = d
- elif def_ or not type.is_text_block:
+ elif def_ or not left_node.type.is_text_block:
break
d -= 1
diff --git a/tests/prosemirror_transform/tests/test_trans.py b/tests/prosemirror_transform/tests/test_trans.py
index 573a3d8..a1cf79c 100644
--- a/tests/prosemirror_transform/tests/test_trans.py
+++ b/tests/prosemirror_transform/tests/test_trans.py
@@ -502,6 +502,18 @@ def test_wrap(doc, expect, type, attrs, test_transform):
"code_block",
None,
),
+ (
+ doc(p("one", img(), "two", img(), "three")),
+ doc(pre("onetwothree")),
+ "code_block",
+ None,
+ ),
+ (
+ doc(pre("one\ntwo\nthree")),
+ doc(p("one two three")),
+ "paragraph",
+ None,
+ ),
],
)
def test_set_block_type(doc, expect, node_type, attrs, test_transform):
@@ -718,6 +730,16 @@ def test_set_node_attribute(doc, expect, attr, value, test_transform):
doc(blockquote(blockquote(blockquote(p("hi"))))).slice(3, 6, True),
doc(p("hi")),
),
+ (
+ doc(ul(li(p("list1"), blockquote(p(""))))),
+ doc(blockquote(p("one"))),
+ doc(ul(li(p("list1"), blockquote(p("one"))))),
+ ),
+ (
+ doc(ul(li(p("list1"), ul(li(p("list2"), blockquote(p(""))))))),
+ doc(blockquote(p("one"))),
+ doc(ul(li(p("list1"), ul(li(p("list2"), blockquote(p("one"))))))),
+ ),
],
)
def test_replace(doc, source, expect, test_transform):