Skip to content

Commit d74586b

Browse files
committed
Add bullets support - stage 2
1 parent 781f865 commit d74586b

File tree

2 files changed

+190
-186
lines changed

2 files changed

+190
-186
lines changed

editor/src/main/java/com/canopas/editor/ui/data/QuillEditorState.kt

+80-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package com.canopas.editor.ui.data
22

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
37
import com.canopas.editor.ui.model.QuillSpan
8+
import com.canopas.editor.ui.model.QuillTextSpan
9+
import com.canopas.editor.ui.model.Span
410
import com.canopas.editor.ui.parser.QuillDefaultAdapter
511
import com.canopas.editor.ui.parser.QuillEditorAdapter
612
import com.canopas.editor.ui.utils.TextSpanStyle
@@ -21,7 +27,7 @@ class QuillEditorState internal constructor(
2127
}
2228

2329
fun output(): String {
24-
return adapter.decode(manager.richText)
30+
return adapter.decode(getRichText())
2531
}
2632

2733
fun reset() {
@@ -38,6 +44,79 @@ class QuillEditorState internal constructor(
3844
manager.setStyle(style)
3945
}
4046

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+
41120
class Builder {
42121
private var adapter: QuillEditorAdapter = QuillDefaultAdapter()
43122
private var input: String = ""

0 commit comments

Comments
 (0)