diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.kt b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.kt index 5b1df2acd..58243a6a8 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.kt +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.kt @@ -77,7 +77,7 @@ import com.hippo.ehviewer.dao.Filter import com.hippo.ehviewer.ui.MainActivity import com.hippo.ehviewer.ui.scene.GalleryListScene.Companion.toStartArgs import com.hippo.text.URLImageGetter -import com.hippo.util.BBCode.toBBCode +import com.hippo.util.toBBCode import com.hippo.util.ExceptionUtils import com.hippo.util.ReadableTime import com.hippo.util.TextUrl diff --git a/app/src/main/java/com/hippo/util/BBCode.kt b/app/src/main/java/com/hippo/util/BBCode.kt index 706ee7735..506b86d2a 100644 --- a/app/src/main/java/com/hippo/util/BBCode.kt +++ b/app/src/main/java/com/hippo/util/BBCode.kt @@ -2,70 +2,65 @@ package com.hippo.util import android.graphics.Typeface import android.text.Spanned -import android.text.style.* +import android.text.style.CharacterStyle +import android.text.style.ImageSpan +import android.text.style.StrikethroughSpan +import android.text.style.StyleSpan +import android.text.style.URLSpan +import android.text.style.UnderlineSpan -object BBCode { - fun Spanned.toBBCode(): String { - val out = StringBuilder() - withinParagraph(out, this, this.length) - return out.toString() - } - - private fun withinParagraph(out: StringBuilder, text: Spanned, end: Int) { - var next: Int - var i = 0 - while (i < text.length) { - next = text.nextSpanTransition(i, end, CharacterStyle::class.java) - val style = text.getSpans(i, next, CharacterStyle::class.java) - for (j in style.indices) { - if (style[j] is StyleSpan) { - val s = (style[j] as StyleSpan).style +fun Spanned.toBBCode(): String { + val text = this + tailrec fun StringBuilder.processOneSpanTransition(cur: Int = 0) { + val next = nextSpanTransition(cur, text.length, CharacterStyle::class.java) + getSpans(cur, next, CharacterStyle::class.java).forEach { + when (it) { + is StyleSpan -> { + val s = it.style if (s and Typeface.BOLD != 0) { - out.append("[b]") + append("[b]") } if (s and Typeface.ITALIC != 0) { - out.append("[i]") + append("[i]") } } - if (style[j] is UnderlineSpan) { - out.append("[u]") + + is UnderlineSpan -> append("[u]") + is StrikethroughSpan -> append("[s]") + is URLSpan -> { + append("[url=") + append(it.url) + append("]") } - if (style[j] is StrikethroughSpan) { - out.append("[s]") - } - if (style[j] is URLSpan) { - out.append("[url=") - out.append((style[j] as URLSpan).url) - out.append("]") - } - if (style[j] is ImageSpan) { - out.append("[img]") - out.append((style[j] as ImageSpan).source) - out.append("[/img]") + + is ImageSpan -> { + append("[img]") + append(it.source) + append("[/img]") } } - out.append(text.subSequence(i, next)) - for (j in style.indices.reversed()) { - if (style[j] is URLSpan) { - out.append("[/url]") - } - if (style[j] is StrikethroughSpan) { - out.append("[/s]") - } - if (style[j] is UnderlineSpan) { - out.append("[/u]") - } - if (style[j] is StyleSpan) { - val s = (style[j] as StyleSpan).style - if (s and Typeface.BOLD != 0) { - out.append("[/b]") - } - if (s and Typeface.ITALIC != 0) { - out.append("[/i]") - } - } - } - i = next } + append(text.subSequence(cur, next)) + getSpans(cur, next, CharacterStyle::class.java).reversed().forEach { + when (it) { + is StyleSpan -> { + val s = it.style + if (s and Typeface.BOLD != 0) { + append("[/b]") + } + if (s and Typeface.ITALIC != 0) { + append("[/i]") + } + } + + is UnderlineSpan -> append("[/u]") + is StrikethroughSpan -> append("[/s]") + is URLSpan -> append("[/url]") + } + } + if (next < text.length) processOneSpanTransition(next) } -} \ No newline at end of file + return StringBuilder().apply { + processOneSpanTransition() + }.toString() +}