Exemplo n.º 1
0
def map_fragment(fragment: Fragment, f, parent=None):
    mapped = []
    for i in range(fragment.child_count):
        child = fragment.child(i)
        if getattr(child.content, "size", None):
            child = child.copy(map_fragment(child.content, f, child))
        if child.is_inline:
            child = f(child, parent, i)
        mapped.append(child)
    return fragment.from_array(mapped)
Exemplo n.º 2
0
 def replace_range_with(self, from_, to, node):
     if (not node.is_inline and from_ == to
             and self.doc.resolve(from_).parent.content.size):
         point = insert_point(self.doc, from_, node.type)
         if point is not None:
             from_ = to = point
     return self.replace_range(from_, to, Slice(Fragment.from_(node), 0, 0))
Exemplo n.º 3
0
    def lift(self, range_, target):
        from__ = range_.from_
        to_ = range_.to
        depth = range_.depth

        gap_start = from__.before(depth + 1)
        gap_end = to_.after(depth + 1)
        start = gap_start
        end = gap_end

        before = Fragment.empty
        open_start = 0
        d = depth
        splitting = False
        while d > target:
            if splitting or from__.index(d) > 0:
                splitting = True
                before = Fragment.from_(from__.node(d).copy(before))
                open_start += 1
            else:
                start -= 1
            d -= 1
        after = Fragment.empty
        open_end = 0
        d = depth
        splitting = False
        while d > target:
            if splitting or to_.after(d + 1) < to_.end(d):
                splitting = True
                after = Fragment.from_(to_.node(d).copy(after))
                open_end += 1
            else:
                end += 1
            d -= 1
        return self.step(
            ReplaceAroundStep(
                start,
                end,
                gap_start,
                gap_end,
                Slice(before.append(after), open_start, open_end),
                before.size - open_start,
                True,
            ))
Exemplo n.º 4
0
def _make_step(from_, to, val):
    if val == "+em":
        return AddMarkStep(from_, to, schema.marks["em"].create)
    elif val == "-em":
        return RemoveMarkStep(from_, to, schema.marks["em"].create)
    return ReplaceStep(
        from_,
        to,
        Slice.empty if val is None else Slice(
            Fragment.from_(schema.text(val), 0, 0)),
    )
Exemplo n.º 5
0
 def wrap(self, range_, wrappers):
     content = Fragment.empty
     i = len(wrappers) - 1
     while i >= 0:
         content = Fragment.from_(wrappers[i]["type"].create(
             wrappers[i].get("attrs"), content))
         i -= 1
     start = range_.start
     end = range_.end
     return self.step(
         ReplaceAroundStep(start, end, start, end, Slice(content, 0, 0),
                           len(wrappers), True))
Exemplo n.º 6
0
 def split(self, pos, depth=None, types_after=None):
     if depth is None:
         depth = 1
     pos_ = self.doc.resolve(pos)
     before = Fragment.empty
     after = Fragment.empty
     d = pos_.depth
     e = pos_.depth - depth
     i = depth - 1
     while d > e:
         before = Fragment.from_(pos_.node(d).copy(before))
         type_after = None
         if types_after and len(types_after) > i:
             type_after = types_after[i]
         after = Fragment.from_(
             type_after["type"].create(type_after.get("attrs"), after)
             if type_after else pos_.node(d).copy(after))
         d -= 1
         i -= 1
     return self.step(
         ReplaceStep(pos, pos, Slice(before.append(after), depth, depth),
                     True))
Exemplo n.º 7
0
def fit_left_innter(from__, depth, placed, placed_below):
    content = Fragment.empty
    open_end = 0
    placed_here = placed[depth] if len(placed) > depth else None
    if from__.depth > depth:
        inner = fit_left_innter(from__, depth + 1, placed, placed_below or placed_here)
        open_end = inner["open_end"] + 1
        content = Fragment.from_(from__.node(depth + 1).copy(inner["content"]))
    if placed_here:
        content = content.append(placed_here["content"])
        open_end = placed_here["open_end"]
    if placed_below:
        content = content.append(
            from__.node(depth)
            .content_match_at(from__.index_after(depth))
            .fill_before(Fragment.empty, True)
        )

    return {"content": content, "open_end": open_end}
Exemplo n.º 8
0
 def set_node_markup(self, pos, type, attrs, marks=None):
     node = self.doc.node_at(pos)
     if not node:
         raise ValueError("No node at given position")
     if not type:
         type = node.type
     new_node = type.create(attrs, None, marks or node.marks)
     if node.is_leaf:
         return self.replace_with(pos, pos + node.node_size, new_node)
     if not type.valid_content(node.content):
         raise ValueError(f"Invalid content for node type {type.name}")
     return self.step(
         ReplaceAroundStep(
             pos,
             pos + node.node_size,
             pos + 1,
             pos + node.node_size - 1,
             Slice(Fragment.from_(new_node), 0, 0),
             1,
             True,
         ))
Exemplo n.º 9
0
 def iteratee(node: "Node", pos, *args):
     if (node.is_text_block
             and not node.has_markup(type, attrs) and can_change_type(
                 self.doc,
                 self.mapping.slice(map_from).map(pos), type)):
         self.clear_incompatible(
             self.mapping.slice(map_from).map(pos, 1), type)
         mapping = self.mapping.slice(map_from)
         start_m = mapping.map(pos, 1)
         end_m = mapping.map(pos + node.node_size, 1)
         self.step(
             ReplaceAroundStep(
                 start_m,
                 end_m,
                 start_m + 1,
                 end_m - 1,
                 Slice(
                     Fragment.from_(type.create(attrs, None,
                                                node.marks)), 0, 0),
                 1,
                 True,
             ))
         return False
Exemplo n.º 10
0
     doc(p("<a>hi<b>")),
     doc(blockquote(p("hix"))),
 ),
 (
     doc(p("x<a>hi"), blockquote(p("yy"), "<b>"), p("c")),
     doc(p("<a>hi<b>")),
     doc(p("xhi"), blockquote(p()), p("c")),
 ),
 (doc(p("<a>x")), doc(blockquote(p("hi"), "<a>"),
                      p("b<b>")), doc(p(), p("bx"))),
 (
     doc(p("<a>x")),
     doc(p("b<a>"), blockquote("<b>", p("hi"))),
     doc(p(), blockquote(p()), p("x")),
 ),
 (p("<a>x"), Slice(Fragment.from_([blockquote(), hr()]), 0, 0), p("x")),
 (
     doc(p("foo"), "<a>", p("bar<b>")),
     ol(li(p("<a>a")), li(p("b<b>"))),
     doc(p("foo"), p("a"), ol(li(p("b")))),
 ),
 (
     doc(ul(li(p("ab<a>cd")), li(p("ef<b>gh")))),
     doc(ul(li(p("ABCD")), li(p("EFGH")))).slice(5, 13, True),
     doc(ul(li(p("abCD")), li(p("EFgh")))),
 ),
 (
     doc(ul(li(p("foo")), "<a>", li(p("bar")))),
     ul(li(p("a<a>bc")), li(p("de<b>f"))),
     doc(ul(li(p("foo")), li(p("bc")), li(p("de")), li(p("bar")))),
 ),
Exemplo n.º 11
0
 def place_content(self, fragment, open_start, open_end, pass_, parent=None):
     i = 0
     while i < fragment.child_count:
         child = fragment.child(i)
         placed = False
         last = i == (fragment.child_count - 1)
         d = len(self.open) - 1
         while d >= 0:
             open = self.open[d]
             wrap = None
             if pass_ > 1:
                 wrap = open["match"].find_wrapping(child.type)
                 if wrap and not (parent and len(wrap) and wrap[-1] == parent.type):
                     while len(self.open) - 1 > d:
                         self.close_node()
                     w = 0
                     while w < len(wrap):
                         open["match"] = open["match"].match_type(wrap[w])
                         d += 1
                         open = {
                             "parent": wrap[w].create(),
                             "match": wrap[w].content_match,
                             "content": Fragment.empty,
                             "wrapper": True,
                             "open_end": 0,
                             "depth": d + w,
                         }
                         self.open.append(open)
                         w += 1
             match = open["match"].match_type(child.type)
             if not match:
                 fill = open["match"].fill_before(Fragment.from_(child))
                 if fill:
                     for j in range(fill.child_count):
                         ch = fill.child(j)
                         self.add_node(open, ch, 0)
                         match = open["match"].match_fragment(ch)
                 elif parent and open["match"].match_type(parent.type):
                     break
                 else:
                     d -= 1
                     continue
             while len(self.open) - 1 > d:
                 self.close_node()
             child = child.mark(open["parent"].type.allowed_marks(child.marks))
             if open_start:
                 child = close_node_start(child, open_start, open_end if last else 0)
                 open_start = 0
             self.add_node(open, child, open_end if last else 0)
             open["match"] = match
             if last:
                 open_end = 0
             placed = True
             break
         if not placed:
             break
         i += 1
     if len(self.open) > 1 and (
         i > 0
         and i == fragment.child_count
         or parent
         and self.open[-1]["parent"].type == parent.type
     ):
         self.close_node()
     return Slice(fragment.cut_by_index(i), open_start, open_end)
Exemplo n.º 12
0
 def replace_with(self, from_, to, content):
     return self.replace(from_, to, Slice(Fragment.from_(content), 0, 0))