text_document/
block.rs

1use crate::format::{BlockFormat, FormatChangeResult, FormattedElement, IsFormat, TextFormat};
2use crate::text::Text;
3use crate::text_document::Element::{ImageElement, TextElement};
4use crate::text_document::{Element, ElementManager, ElementTrait, ModelError};
5use crate::ElementUuid;
6use std::cell::{Cell, RefCell};
7use std::rc::{Rc, Weak};
8
9#[derive(Clone, Debug)]
10pub struct Block {
11    uuid: Cell<usize>,
12    element_manager: Weak<ElementManager>,
13    /// Describes block-specific properties
14    block_format: RefCell<BlockFormat>,
15}
16
17impl PartialEq for Block {
18    fn eq(&self, other: &Self) -> bool {
19        self.uuid == other.uuid && self.block_format == other.block_format
20    }
21}
22
23impl Block {
24    pub(crate) fn new(element_manager: Weak<ElementManager>) -> Self {
25        Block {
26            uuid: Default::default(),
27            element_manager,
28            block_format: Default::default(),
29        }
30    }
31
32    pub fn uuid(&self) -> usize {
33        self.uuid.get()
34    }
35
36    pub fn iter(&self) -> BlockIter {
37        BlockIter::new(self)
38    }
39
40    /// Position of the cursor at the start of the block in the context of the document.
41    pub fn position(&self) -> usize {
42        let mut counter = 0;
43
44        for block in self.element_manager.upgrade().unwrap().block_list() {
45            if block.as_ref().eq(self) {
46                break;
47            }
48            counter += block.text_length();
49            counter += 1;
50        }
51
52        counter
53    }
54
55    /// Number of this block in the whole document
56    pub fn block_number(&self) -> usize {
57        let mut counter = 0;
58
59        for block in self.element_manager.upgrade().unwrap().block_list() {
60            if block.as_ref().eq(self) {
61                break;
62            }
63
64            counter += 1;
65        }
66
67        counter
68    }
69
70    /// get this block formatting
71    pub fn block_format(&self) -> BlockFormat {
72        self.format()
73    }
74
75    pub(crate) fn convert_position_from_document(&self, position_in_document: usize) -> usize {
76        position_in_document - self.position()
77    }
78
79    pub(crate) fn convert_position_from_block_to_child(&self, position_in_block: usize) -> usize {
80        let mut position = 0;
81        for child in self.list_all_children() {
82            if position_in_block == 0 {
83                return 0;
84            }
85
86            let child_end_position = match &child {
87                TextElement(text_rc) => position + text_rc.text_length(),
88                ImageElement(image_rc) => position + image_rc.text_length(),
89                _ => unreachable!(),
90            };
91
92            if (position..=child_end_position).contains(&position_in_block) {
93                return position_in_block - position;
94            }
95
96            position += child_end_position;
97        }
98
99        position
100    }
101
102    /// Returns the position of child in the context of  this block
103    pub(crate) fn position_of_child(&self, uuid: ElementUuid) -> usize {
104        let mut position = 0;
105        for child in self.list_all_children() {
106            if child.uuid() == uuid {
107                break;
108            }
109
110            let length = match &child {
111                TextElement(text_rc) => text_rc.text_length(),
112                ImageElement(image_rc) => image_rc.text_length(),
113                _ => unreachable!(),
114            };
115
116            position += length;
117        }
118
119        position
120    }
121
122    pub(crate) fn text_format_at(&self, position_in_block: usize) -> Option<TextFormat> {
123        if position_in_block == 0 {
124            match self.first_child() {
125                Some(element) => match element {
126                    TextElement(text) => Some(text.text_format()),
127                    ImageElement(_) => None,
128                    _ => None,
129                },
130                None => None,
131            }
132        } else {
133            None
134        }
135    }
136
137    fn first_child(&self) -> Option<Element> {
138        let element_manager = self.element_manager.upgrade().unwrap();
139
140        let next_element = element_manager.next_element(self.uuid())?;
141        match next_element {
142            TextElement(_) => Some(next_element),
143            ImageElement(_) => Some(next_element),
144            _ => None,
145        }
146    }
147
148    /// Find element inside the block using the cursor position in block
149    /// Returns the element
150    fn find_element(&self, position_in_block: usize) -> Option<Element> {
151        let mut position = 0;
152
153        for child in self.list_all_children() {
154            // returns first element if cursor is at first position
155            if position_in_block == 0 {
156                return Some(child);
157            }
158
159            let child_end_position = match &child {
160                TextElement(text_rc) => position + text_rc.text_length(),
161                ImageElement(image_rc) => position + image_rc.text_length(),
162                _ => unreachable!(),
163            };
164
165            if (position..=child_end_position).contains(&position_in_block) {
166                return Some(child);
167            }
168
169            position += child_end_position;
170        }
171
172        None
173    }
174
175    pub(crate) fn insert_plain_text(&self, plain_text: &str, position_in_block: usize) {
176        match self.find_element(position_in_block) {
177            Some(element) => match element {
178                TextElement(text_rc) => text_rc.insert_plain_text(
179                    self.convert_position_from_block_to_child(position_in_block),
180                    &plain_text.to_string(),
181                ),
182                ImageElement(_) => {
183                    let new_text_rc = self.insert_new_text_element(position_in_block);
184                    new_text_rc.set_text(&plain_text.to_string());
185                    new_text_rc.set_format(&self.text_format()).unwrap();
186                }
187                _ => unreachable!(),
188            },
189            None => (),
190        }
191    }
192
193    fn insert_new_text_element(&self, position_in_block: usize) -> Rc<Text> {
194        match self.find_element(position_in_block) {
195            Some(element) => match element {
196                TextElement(text_rc) => {
197                    // split if not at the end of the text
198                    if position_in_block != text_rc.position_in_block() + text_rc.text_length() {
199                        text_rc.split(self.convert_position_from_block_to_child(position_in_block));
200                    }
201                    // insert new text between splits
202                    let element_manager = self.element_manager.upgrade().unwrap();
203                    let new_text_rc = element_manager
204                        .insert_new_text(text_rc.uuid(), crate::text_document::InsertMode::After);
205                    new_text_rc.unwrap()
206                }
207                ImageElement(_) => {
208                    // add text after
209                    let element_manager = self.element_manager.upgrade().unwrap();
210                    let new_text_rc = element_manager
211                        .insert_new_text(element.uuid(), crate::text_document::InsertMode::After);
212                    new_text_rc.unwrap()
213                }
214                _ => unreachable!(),
215            },
216            None => unreachable!(),
217        }
218    }
219
220    pub(crate) fn set_plain_text(&self, plain_text: &str) {
221        self.clear();
222        self.insert_plain_text(plain_text, 0);
223    }
224
225    /// helper function to clear all children of this block. Create a new empty text element.
226    pub(crate) fn clear(&self) {
227        let element_manager = self.element_manager.upgrade().unwrap();
228        let children = self
229            .list_all_children()
230            .iter()
231            .map(|element| element.uuid())
232            .collect();
233
234        element_manager.remove(children);
235
236        element_manager
237            .insert_new_text(self.uuid(), crate::text_document::InsertMode::AsChild)
238            .unwrap();
239    }
240
241    pub fn list_all_children(&self) -> Vec<Element> {
242        let element_manager = self.element_manager.upgrade().unwrap();
243        element_manager.list_all_children(self.uuid())
244    }
245
246    /// Describes the block's character format. The block's character format is the char format of the first block.
247    pub fn text_format(&self) -> TextFormat {
248        match self.first_child().unwrap() {
249            TextElement(text_fragment) => text_fragment.text_format(),
250            ImageElement(_) => TextFormat::new(),
251            _ => unreachable!(),
252        }
253    }
254
255    /// Apply a new char format onto all text fragments of this block
256    pub(crate) fn set_text_format(&self, text_format: &TextFormat) {
257        self.list_all_children()
258            .iter()
259            .filter_map(|element| match element {
260                TextElement(text) => Some(text),
261                ImageElement(_) => None,
262                _ => unreachable!(),
263            })
264            .for_each(|text_fragment: &Rc<Text>| {
265                text_fragment.set_format(text_format).unwrap();
266            });
267    }
268
269    pub(crate) fn split(&self, position_in_block: usize) -> Result<Rc<Block>, ModelError> {
270        let element_manager = self.element_manager.upgrade().unwrap();
271
272        // create block
273        let new_block = element_manager
274            .insert_new_block(self.uuid(), crate::text_document::InsertMode::After)?;
275
276        // split child element at position
277
278        let sub_element = self
279            .find_element(position_in_block)
280            .ok_or_else(|| ModelError::ElementNotFound("sub element not found".to_string()))?;
281
282        let new_text_after_text_split = match sub_element {
283            TextElement(text) => {
284                text.split(self.convert_position_from_block_to_child(position_in_block))
285            }
286            ImageElement(image) => TextElement(
287                element_manager
288                    .insert_new_text(image.uuid(), crate::text_document::InsertMode::After)?,
289            ),
290            _ => unreachable!(),
291        };
292
293        // move fragments from one block to another
294        let all_children_list = self.list_all_children();
295        let mut child_list: Vec<&Element> = all_children_list
296            .iter()
297            .skip_while(|element| element.uuid() != new_text_after_text_split.uuid())
298            .collect();
299        child_list.reverse();
300
301        for child in child_list {
302            element_manager.move_while_changing_parent(child.uuid(), new_block.uuid())?;
303        }
304
305        Ok(new_block)
306    }
307
308    fn analyze_for_merges(&self) {
309        let children = self.list_all_children();
310
311        'first_loop: for _ in 0..children.len() {
312            let children = self.list_all_children();
313            for element_window in children.windows(2) {
314                let first_text = match &element_window[0] {
315                    TextElement(text) => text,
316                    _ => continue,
317                };
318                let second_text = match &element_window[1] {
319                    TextElement(text) => text,
320                    _ => continue,
321                };
322
323                if first_text.text_format() == second_text.text_format() {
324                    self.merge_text_elements(first_text, second_text);
325                    continue 'first_loop;
326                }
327            }
328        }
329
330        // remove empty text
331        //todo!();
332    }
333
334    pub(crate) fn merge_with(&self, other_block: Rc<Block>) -> Result<(), ModelError> {
335        let element_manager = self.element_manager.upgrade().unwrap();
336
337        let mut own_children = self.list_all_children();
338        let mut other_children = other_block.list_all_children();
339
340        own_children.append(&mut other_children);
341        own_children.reverse();
342
343        own_children.iter().try_for_each(|element| {
344            element_manager.move_while_changing_parent(element.uuid(), self.uuid())
345        })?;
346
347        element_manager.remove(vec![other_block.uuid()]);
348
349        Ok(())
350    }
351
352    /// merge to texts, adopts the first text's char format
353    fn merge_text_elements(&self, first_text_rc: &Rc<Text>, second_text_rc: &Rc<Text>) -> Rc<Text> {
354        first_text_rc
355            .set_text(&(first_text_rc.plain_text() + second_text_rc.plain_text().as_str()));
356        let element_manager = self.element_manager.upgrade().unwrap();
357        element_manager.remove(vec![second_text_rc.uuid()]);
358
359        first_text_rc.clone()
360    }
361
362    /// returns the plain text of this block
363    pub fn plain_text(&self) -> String {
364        let texts: Vec<String> = self
365            .list_all_children()
366            .iter()
367            .map(|fragment| match fragment {
368                TextElement(text_rc) => text_rc.plain_text(),
369                ImageElement(image_rc) => image_rc.plain_text(),
370                _ => unreachable!(),
371            })
372            .collect();
373        texts.join("")
374    }
375
376    pub(crate) fn plain_text_between_positions(
377        &self,
378        position_in_block: usize,
379        anchor_position_in_block: usize,
380    ) -> String {
381        let mut position_in_block = position_in_block;
382        let mut anchor_position_in_block = anchor_position_in_block;
383
384        let text_length = self.text_length();
385
386        if position_in_block > text_length {
387            position_in_block = text_length;
388        }
389        if anchor_position_in_block > text_length {
390            anchor_position_in_block = text_length;
391        }
392
393        self.plain_text()[position_in_block..anchor_position_in_block].to_string()
394    }
395
396    /// Remove text between two positions. Returns the position in the context of the document and the count of removed characters
397    pub(crate) fn remove_between_positions(
398        &self,
399        position_in_block: usize,
400        anchor_position_in_block: usize,
401    ) -> Result<(usize, usize), ModelError> {
402        let left_position = position_in_block.min(anchor_position_in_block);
403        let right_position = anchor_position_in_block.max(position_in_block);
404
405        let left_element = self
406            .find_element(left_position)
407            .ok_or_else(|| ModelError::ElementNotFound("left_element not found".to_string()))?;
408        let right_element = self
409            .find_element(right_position)
410            .ok_or_else(|| ModelError::ElementNotFound("right_element not found".to_string()))?;
411
412        // if same element targeted
413        if left_element == right_element {
414            match left_element {
415                TextElement(text) => {
416                    let left_position_in_child =
417                        self.convert_position_from_block_to_child(left_position);
418                    let right_position_in_child =
419                        self.convert_position_from_block_to_child(right_position);
420                    text.remove_text(left_position_in_child, right_position_in_child)?;
421                }
422                // nothing to remove since image length is 1
423                ImageElement(_) => return Ok((0, 0)),
424                _ => unreachable!(),
425            }
426        }
427        // if different elements
428        else {
429            let element_manager = self.element_manager.upgrade().unwrap();
430
431            // remove first part of last element
432            match &right_element {
433                TextElement(text) => {
434                    let left_position_in_child = 0;
435                    let right_position_in_child =
436                        self.convert_position_from_block_to_child(right_position);
437                    text.remove_text(left_position_in_child, right_position_in_child)?;
438                }
439                // remove completely  since image length is 1
440                ImageElement(image) => element_manager.remove(vec![image.uuid()]),
441                _ => unreachable!(),
442            }
443
444            // remove end part of first element
445            match &left_element {
446                TextElement(text) => {
447                    let left_position_in_child =
448                        self.convert_position_from_block_to_child(left_position);
449                    let right_position_in_child = text.text_length();
450                    text.remove_text(left_position_in_child, right_position_in_child)?;
451                }
452                // nothing to remove since image length is 1
453                ImageElement(_) => (),
454                _ => unreachable!(),
455            }
456
457            // remove all elements in between
458
459            element_manager.remove(
460                self.list_all_children()
461                    .iter()
462                    .skip_while(|element| element.uuid() != left_element.uuid())
463                    .skip(1)
464                    .take_while(|element| element.uuid() != right_element.uuid())
465                    .map(|element| element.uuid())
466                    .collect(),
467            )
468        }
469
470        self.analyze_for_merges();
471
472        let removed_characters_count = right_position - left_position;
473
474        let new_position_in_document = self.position() + left_position;
475
476        Ok((new_position_in_document, removed_characters_count))
477    }
478
479    /// Length of text in the block
480    pub fn text_length(&self) -> usize {
481        let all_children = self.list_all_children();
482        let mut counter: usize = 0;
483
484        for element in all_children {
485            counter += match element {
486                TextElement(text) => text.plain_text().len(),
487                ImageElement(_) => 1,
488                _ => 0,
489            };
490        }
491
492        counter
493    }
494    /// position of the start of the block in the context of the document
495    pub fn start(&self) -> usize {
496        self.position()
497    }
498
499    /// position of the end of the block in the context of the document
500    pub fn end(&self) -> usize {
501        self.start() + self.text_length()
502    }
503}
504
505impl ElementTrait for Block {
506    fn set_uuid(&self, uuid: usize) {
507        self.uuid.set(uuid);
508    }
509
510    fn verify_rule_with_parent(&self, parent_element: &Element) -> Result<(), ModelError> {
511        match parent_element {
512            Element::FrameElement(_) => Ok(()),
513            Element::BlockElement(_) => Err(ModelError::WrongParent),
514            Element::TextElement(_) => Err(ModelError::WrongParent),
515            Element::ImageElement(_) => Err(ModelError::WrongParent),
516        }
517    }
518}
519
520impl FormattedElement<BlockFormat> for Block {
521    fn format(&self) -> BlockFormat {
522        self.block_format.borrow().clone()
523    }
524
525    fn set_format(&self, format: &BlockFormat) -> FormatChangeResult {
526        if &*self.block_format.borrow() == format {
527            Ok(None)
528        } else {
529            self.block_format.replace(format.clone());
530            Ok(Some(()))
531        }
532    }
533
534    fn merge_format(&self, format: &BlockFormat) -> Result<Option<()>, ModelError> {
535        self.block_format.borrow_mut().merge_with(format)
536    }
537}
538
539pub struct BlockIter {
540    unvisited: Vec<Element>,
541}
542
543impl BlockIter {
544    fn new(block: &Block) -> Self {
545        let ordered_elements = block.list_all_children();
546
547        BlockIter {
548            unvisited: ordered_elements,
549        }
550    }
551}
552
553impl Iterator for BlockIter {
554    type Item = Element;
555
556    fn next(&mut self) -> Option<Self::Item> {
557        let element = self.unvisited.pop()?;
558
559        Some(element)
560    }
561}
562
563#[cfg(test)]
564mod tests {
565    use crate::text_document::InsertMode;
566
567    use super::*;
568
569    #[test]
570    fn list_all_children() {
571        let element_manager_rc = ElementManager::new_rc();
572        ElementManager::create_root_frame(element_manager_rc.clone());
573
574        let block = element_manager_rc
575            .insert_new_block(0, InsertMode::AsChild)
576            .unwrap();
577        let text = element_manager_rc
578            .insert_new_text(block.uuid(), InsertMode::AsChild)
579            .unwrap();
580        element_manager_rc.debug_elements();
581        assert_eq!(block.list_all_children(), vec![TextElement(text)]);
582    }
583
584    #[test]
585    fn set_plain_text() {
586        let element_manager_rc = ElementManager::new_rc();
587        ElementManager::create_root_frame(element_manager_rc.clone());
588
589        let block = element_manager_rc
590            .insert_new_block(0, InsertMode::AsChild)
591            .unwrap();
592        block.set_plain_text("plain_text");
593        element_manager_rc.debug_elements();
594        assert_eq!(block.plain_text(), "plain_text");
595    }
596
597    #[test]
598    fn remove_between_positions() {
599        let element_manager_rc = ElementManager::new_rc();
600        ElementManager::create_root_frame(element_manager_rc.clone());
601
602        let block = element_manager_rc
603            .insert_new_block(0, InsertMode::AsChild)
604            .unwrap();
605        block.set_plain_text("plain_text");
606
607        let (position, removed_count) = block.remove_between_positions(1, 6).unwrap();
608
609        assert_eq!(removed_count, 5);
610        assert_eq!(position, 2);
611        assert_eq!(block.plain_text(), "ptext");
612    }
613
614    #[test]
615    fn remove_between_positions_in_2_texts() {
616        let element_manager_rc = ElementManager::new_rc();
617        ElementManager::create_root_frame(element_manager_rc.clone());
618
619        let block = element_manager_rc
620            .insert_new_block(0, InsertMode::AsChild)
621            .unwrap();
622        block.set_plain_text("plain_text");
623
624        let new_text_rc = block.insert_new_text_element(block.text_length());
625        new_text_rc.set_text(" is life");
626        element_manager_rc.debug_elements();
627
628        assert_eq!(block.plain_text(), "plain_text is life");
629
630        let (position, removed_count) = block.remove_between_positions(1, 14).unwrap();
631
632        assert_eq!(removed_count, 13);
633        assert_eq!(position, 2);
634        assert_eq!(block.plain_text(), "plife");
635    }
636
637    #[test]
638    fn convert_position_from_block_to_child() {
639        let element_manager_rc = ElementManager::new_rc();
640        ElementManager::create_root_frame(element_manager_rc.clone());
641
642        let block = element_manager_rc
643            .insert_new_block(0, InsertMode::AsChild)
644            .unwrap();
645        block.set_plain_text("plain_text");
646
647        let new_text_rc = block.insert_new_text_element(block.text_length());
648        new_text_rc.set_text(" is life");
649        element_manager_rc.debug_elements();
650
651        assert_eq!(block.plain_text(), "plain_text is life");
652
653        assert_eq!(3, block.convert_position_from_block_to_child(3));
654        assert_eq!(4, block.convert_position_from_block_to_child(14));
655        assert_eq!(8, block.convert_position_from_block_to_child(18));
656    }
657    #[test]
658    fn plain_text_between_positions() {
659        let element_manager_rc = ElementManager::new_rc();
660        ElementManager::create_root_frame(element_manager_rc.clone());
661
662        let block = element_manager_rc
663            .insert_new_block(0, InsertMode::AsChild)
664            .unwrap();
665        block.set_plain_text("plain_text");
666
667        assert_eq!(block.plain_text_between_positions(0, 1), "p");
668        assert_eq!(block.plain_text_between_positions(2, 4), "ai");
669        assert_eq!(block.plain_text_between_positions(0, 10), "plain_text");
670    }
671
672    #[test]
673    fn split() {
674        let element_manager_rc = ElementManager::new_rc();
675        ElementManager::create_root_frame(element_manager_rc.clone());
676
677        let block = element_manager_rc
678            .insert_new_block(0, InsertMode::AsChild)
679            .unwrap();
680        block.set_plain_text("plain_text");
681
682        let new_block = block.split(2).unwrap();
683        element_manager_rc.debug_elements();
684        assert_eq!(block.plain_text(), "pl");
685        assert_eq!(new_block.plain_text(), "ain_text");
686
687        element_manager_rc.clear();
688        let block = element_manager_rc
689            .insert_new_block(0, InsertMode::AsChild)
690            .unwrap();
691        block.set_plain_text("plain_text");
692
693        let new_block = block.split(10).unwrap();
694        element_manager_rc.debug_elements();
695        assert_eq!(block.plain_text(), "plain_text");
696        assert_eq!(new_block.plain_text(), "");
697    }
698
699    #[test]
700    fn merge_text_elements() {
701        let element_manager_rc = ElementManager::new_rc();
702        ElementManager::create_root_frame(element_manager_rc.clone());
703
704        let block = element_manager_rc.first_block().unwrap();
705        block.set_plain_text("plain_text");
706
707        let first_text_rc = block.iter().next().unwrap().get_text().unwrap();
708
709        let new_text_rc = block.insert_new_text_element(block.text_length());
710        new_text_rc.set_text(" is life");
711        element_manager_rc.debug_elements();
712
713        assert_eq!(block.plain_text(), "plain_text is life");
714
715        //merge
716
717        block.merge_text_elements(&first_text_rc, &new_text_rc);
718        assert_eq!(first_text_rc.plain_text(), "plain_text is life");
719        assert_eq!(block.plain_text(), "plain_text is life");
720        element_manager_rc.debug_elements();
721
722        //let empty_text_rc = block.insert_new_text_element(block.text_length());
723    }
724    #[test]
725    fn analyze_for_merges_of_text_elements() {
726        let element_manager_rc = ElementManager::new_rc();
727        ElementManager::create_root_frame(element_manager_rc.clone());
728
729        let block = element_manager_rc.first_block().unwrap();
730        block.set_plain_text("plain_text");
731
732        let first_text_rc = block.iter().next().unwrap().get_text().unwrap();
733        block.insert_new_text_element(block.text_length());
734
735        let new_text_rc = block.insert_new_text_element(block.text_length());
736        new_text_rc.set_text(" is life");
737        element_manager_rc.debug_elements();
738
739        block.insert_new_text_element(block.text_length());
740        element_manager_rc.debug_elements();
741
742        assert_eq!(block.plain_text(), "plain_text is life");
743        assert_eq!(block.iter().count(), 4);
744
745        block.analyze_for_merges();
746        assert_eq!(block.iter().count(), 1);
747        assert_eq!(first_text_rc.plain_text(), "plain_text is life");
748        assert_eq!(block.plain_text(), "plain_text is life");
749
750        //let empty_text_rc = block.insert_new_text_element(block.text_length());
751    }
752
753    #[test]
754    fn insert_new_text_element() {
755        let element_manager_rc = ElementManager::new_rc();
756        ElementManager::create_root_frame(element_manager_rc.clone());
757
758        let block = element_manager_rc.first_block().unwrap();
759        block.set_plain_text("plain_text");
760
761        block.insert_new_text_element(block.text_length());
762        element_manager_rc.debug_elements();
763
764        let new_text_rc = block.insert_new_text_element(block.text_length());
765        new_text_rc.set_text(" is life");
766        element_manager_rc.debug_elements();
767
768        block.insert_new_text_element(block.text_length());
769        element_manager_rc.debug_elements();
770
771        assert_eq!(block.plain_text(), "plain_text is life");
772        assert_eq!(block.iter().count(), 4);
773    }
774
775    #[test]
776    fn block_text_format() {
777        let element_manager_rc = ElementManager::new_rc();
778        ElementManager::create_root_frame(element_manager_rc.clone());
779
780        let block = element_manager_rc.first_block().unwrap();
781        block.set_plain_text("bold plain_text");
782
783        block.insert_new_text_element(block.text_length());
784        element_manager_rc.debug_elements();
785
786        let new_text_rc = block.insert_new_text_element(block.text_length());
787        new_text_rc.set_text(" is life");
788        element_manager_rc.debug_elements();
789
790        block.insert_new_text_element(block.text_length());
791        element_manager_rc.debug_elements();
792
793        assert_eq!(block.plain_text(), "bold plain_text is life");
794        assert_eq!(block.iter().count(), 4);
795
796        // format all
797        let mut text_format = TextFormat::new();
798        text_format.set_bold(true);
799
800        block.set_text_format(&text_format);
801
802        block
803            .iter()
804            .filter_map(|element| element.get_text())
805            .for_each(|text: Rc<Text>| assert!(text.format().bold()));
806    }
807}