1
1
package com.canopas.editor.ui.data
2
2
3
+ import com.canopas.editor.ui.data.QuillTextManager.Companion.headerLevel
4
+ import com.canopas.editor.ui.data.QuillTextManager.Companion.isHeaderStyle
5
+ import com.canopas.editor.ui.model.Attributes
6
+ import com.canopas.editor.ui.model.ListType
3
7
import com.canopas.editor.ui.model.QuillSpan
8
+ import com.canopas.editor.ui.model.QuillTextSpan
9
+ import com.canopas.editor.ui.model.Span
4
10
import com.canopas.editor.ui.parser.QuillDefaultAdapter
5
11
import com.canopas.editor.ui.parser.QuillEditorAdapter
6
12
import com.canopas.editor.ui.utils.TextSpanStyle
@@ -21,7 +27,7 @@ class QuillEditorState internal constructor(
21
27
}
22
28
23
29
fun output (): String {
24
- return adapter.decode(manager.richText )
30
+ return adapter.decode(getRichText() )
25
31
}
26
32
27
33
fun reset () {
@@ -38,6 +44,79 @@ class QuillEditorState internal constructor(
38
44
manager.setStyle(style)
39
45
}
40
46
47
+ private fun getRichText () : QuillSpan {
48
+ val quillGroupedSpans = manager.quillTextSpans.groupBy { it.from to it.to }
49
+ val quillTextSpans =
50
+ quillGroupedSpans.map { (fromTo, spanList) ->
51
+ val (from, to) = fromTo
52
+ val uniqueStyles = spanList.map { it.style }.flatten().distinct()
53
+ QuillTextSpan (from, to, uniqueStyles)
54
+ }
55
+
56
+ val groupedSpans = mutableListOf<Span >()
57
+ quillTextSpans.forEachIndexed { index, span ->
58
+ var insert = manager.editableText.substring(span.from, span.to + 1 )
59
+ if (insert == " " || insert == " " ) {
60
+ return @forEachIndexed
61
+ }
62
+ val nextSpan = quillTextSpans.getOrNull(index + 1 )
63
+ val previousSpan = quillTextSpans.getOrNull(index - 1 )
64
+ val nextInsert =
65
+ nextSpan?.let { manager.editableText.substring(nextSpan.from, nextSpan.to + 1 ) }
66
+ if (nextInsert == " " || nextInsert == " " ) {
67
+ insert + = nextInsert
68
+ }
69
+ var attributes =
70
+ Attributes (
71
+ header =
72
+ if (span.style.any { it.isHeaderStyle() })
73
+ span.style.find { it.isHeaderStyle() }?.headerLevel()
74
+ else null ,
75
+ bold = if (span.style.contains(TextSpanStyle .BoldStyle )) true else null ,
76
+ italic = if (span.style.contains(TextSpanStyle .ItalicStyle )) true else null ,
77
+ underline =
78
+ if (span.style.contains(TextSpanStyle .UnderlineStyle )) true else null ,
79
+ list =
80
+ if (span.style.contains(TextSpanStyle .BulletStyle )) ListType .bullet
81
+ else null
82
+ )
83
+
84
+ if (insert == " \n " ) {
85
+ attributes = Attributes ()
86
+ }
87
+
88
+ if (
89
+ previousSpan?.style?.contains(TextSpanStyle .BulletStyle ) == true &&
90
+ nextInsert == " \n " &&
91
+ ! insert.contains(" \n " )
92
+ ) {
93
+ insert + = " \n "
94
+ }
95
+ if (
96
+ insert == " \n " &&
97
+ span.style.contains(TextSpanStyle .BulletStyle ) &&
98
+ previousSpan?.style?.contains(TextSpanStyle .BulletStyle ) == true &&
99
+ nextSpan?.style?.contains(TextSpanStyle .BulletStyle ) == true
100
+ ) {
101
+ return @forEachIndexed
102
+ }
103
+ insert = insert.replace(" \u200B " , " " )
104
+ // Merge consecutive spans with the same attributes into one
105
+ if (
106
+ groupedSpans.isNotEmpty() &&
107
+ groupedSpans.last().attributes == attributes &&
108
+ (attributes.list == null ||
109
+ (groupedSpans.last().insert?.contains(' \n ' ) == false ))
110
+ ) {
111
+ groupedSpans.last().insert + = insert
112
+ } else {
113
+ groupedSpans.add(Span (insert, attributes))
114
+ }
115
+ }
116
+
117
+ return QuillSpan (groupedSpans)
118
+ }
119
+
41
120
class Builder {
42
121
private var adapter: QuillEditorAdapter = QuillDefaultAdapter ()
43
122
private var input: String = " "
0 commit comments