From 72127ce13397f6cacfb523a004a24cd997d57e1f Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Sun, 5 Jan 2020 19:24:17 +0600 Subject: [PATCH] rework in part of text message entities --- .../CommonAbstracts/Captioned.kt | 6 +- .../CommonAbstracts/TextSource.kt | 14 +- .../MessageEntity/BoldTextMessageEntity.kt | 12 -- .../MessageEntity/BotCommandMessageEntity.kt | 16 -- .../MessageEntity/CodeTextMessageEntity.kt | 12 -- .../types/MessageEntity/EMailMessageEntity.kt | 12 -- .../MessageEntity/HashTagMessageEntity.kt | 12 -- .../MessageEntity/ItalicTextMessageEntity.kt | 12 -- .../MessageEntity/MentionMessageEntity.kt | 12 -- .../types/MessageEntity/MessageEntity.kt | 11 -- .../MessageEntity/PhoneNumberMessageEntity.kt | 12 -- .../MessageEntity/PreTextMessageEntity.kt | 12 -- .../types/MessageEntity/RawMessageEntity.kt | 97 ++++++++---- .../MessageEntity/RegularTextMessageEntity.kt | 12 -- .../StrikethroughMessageEntity.kt | 10 -- .../MessageEntity/TextLinkMessageEntity.kt | 13 -- .../MessageEntity/TextMentionMessageEntity.kt | 15 -- .../types/MessageEntity/URLMessageEntity.kt | 15 -- .../MessageEntity/UnderlineMessageEntity.kt | 10 -- .../textsources/BoldTextSource.kt | 19 +-- .../textsources/BotCommandTextSource.kt | 27 ++-- .../textsources/CodeTextSource.kt | 13 +- .../textsources/EMailTextSource.kt | 18 +-- .../textsources/HashTagTextSource.kt | 27 ++-- .../textsources/ItalicTextSource.kt | 19 +-- .../textsources/MentionTextSource.kt | 29 ++-- .../textsources/PhoneNumberTextSource.kt | 18 +-- .../textsources/PreTextSource.kt | 13 +- .../textsources/RegularTextSource.kt | 12 +- .../textsources/StrikethroughTextSource.kt | 19 +-- .../textsources/TextLinkTextSource.kt | 10 +- .../textsources/TextMentionTextSource.kt | 19 +-- .../textsources/URLTextSource.kt | 14 +- .../textsources/UnderlineTextSource.kt | 19 +-- .../types/ParseMode/ParseMode.kt | 7 + .../TelegramBotAPI/types/games/Game.kt | 6 +- .../TelegramBotAPI/types/games/RawGame.kt | 3 +- .../types/message/RawMessage.kt | 7 +- .../types/message/content/TextContent.kt | 10 +- .../message/content/media/AnimationContent.kt | 4 +- .../message/content/media/AudioContent.kt | 4 +- .../message/content/media/DocumentContent.kt | 4 +- .../message/content/media/PhotoContent.kt | 4 +- .../message/content/media/VideoContent.kt | 4 +- .../message/content/media/VoiceContent.kt | 4 +- .../utils/CaptionAndTextSourcesToText.kt | 98 ++++++++++++ .../TelegramBotAPI/utils/Captions.kt | 77 ---------- .../utils/HtmlCaptionSourcer.kt | 24 --- .../utils/MarkdownCaptionSourcer.kt | 24 --- .../utils/MultilevelTextSourceFormatting.kt | 137 +++++++++++++++++ .../TelegramBotAPI/utils/StringFormatting.kt | 123 ++++++++++----- .../TelegramBotAPI/utils/extensions/String.kt | 27 ++++ .../MessageEntity/TextPartsCreatingTests.kt | 142 ++++++++++++++++++ 53 files changed, 760 insertions(+), 540 deletions(-) delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/StrikethroughMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/UnderlineMessageEntity.kt create mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt delete mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt create mode 100644 src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt create mode 100644 src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt index 7a80c885a1..b7755a370f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/Captioned.kt @@ -1,7 +1,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.ParseMode +import com.github.insanusmokrassar.TelegramBotAPI.utils.fullListOfSubSource interface Captioned { val caption: String? @@ -12,5 +12,7 @@ interface CaptionedOutput : Captioned { } interface CaptionedInput : Captioned { - val captionEntities: List + val captionEntities: List } + +fun CaptionedInput.fullEntitiesList() = caption ?.fullListOfSubSource(captionEntities) ?.map { it.source } ?: emptyList() diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt index 0369f0dbc8..be70f1032e 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/CommonAbstracts/TextSource.kt @@ -1,7 +1,17 @@ package com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts interface TextSource { - val rawSource: String val asMarkdownSource: String + val asMarkdownV2Source: String val asHtmlSource: String -} \ No newline at end of file +} + + +interface MultilevelTextSource : TextSource { + val textParts: List +} + +data class TextPart( + val range: IntRange, + val source: TextSource +) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt deleted file mode 100644 index ef5b0dbc96..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BoldTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.BoldTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldMarkdown - -data class BoldTextMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by BoldTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt deleted file mode 100644 index 8e755225db..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/BotCommandMessageEntity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.BotCommandTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandMarkdown - -data class BotCommandMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String, - private val botCommandTextSource: BotCommandTextSource = BotCommandTextSource(rawSource) -) : MessageEntity, TextSource by botCommandTextSource { - val command: String - get() = botCommandTextSource.command -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt deleted file mode 100644 index 6b65c2e0a7..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/CodeTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.CodeTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeMarkdown - -data class CodeTextMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by CodeTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt deleted file mode 100644 index 342bd7b5d4..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/EMailMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.EMailTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailMarkdown - -data class EMailMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by EMailTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt deleted file mode 100644 index 65dd2c2ac1..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/HashTagMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.HashTagTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagMarkdown - -data class HashTagMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by HashTagTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt deleted file mode 100644 index 38d9510bb3..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/ItalicTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.ItalicTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicMarkdown - -data class ItalicTextMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by ItalicTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt deleted file mode 100644 index de484c6925..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MentionMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.MentionTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown - -class MentionMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by MentionTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt deleted file mode 100644 index 0021ec72a1..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/MessageEntity.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource - -interface MessageEntity : TextSource { - val offset: Int - val length: Int - @Deprecated("Due to opportunity to get the same string from rawSource const", ReplaceWith("rawSource")) - val sourceString: String - get() = rawSource -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt deleted file mode 100644 index dfc3710bab..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PhoneNumberMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.PhoneNumberTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneMarkdown - -data class PhoneNumberMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by PhoneNumberTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt deleted file mode 100644 index b28c189c26..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/PreTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.PreTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.preHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.preMarkdown - -data class PreTextMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by PreTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt index 1d5ceac9a7..bdbfbb3f77 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RawMessageEntity.kt @@ -1,10 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.* import com.github.insanusmokrassar.TelegramBotAPI.types.User -import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat -import kotlinx.serialization.KSerializer +import com.github.insanusmokrassar.TelegramBotAPI.utils.shiftSourcesToTheLeft import kotlinx.serialization.Serializable -import kotlinx.serialization.internal.ArrayListSerializer @Serializable internal data class RawMessageEntity( @@ -13,32 +14,74 @@ internal data class RawMessageEntity( val length: Int, val url: String? = null, val user: User? = null -) { - fun asMessageEntity(source: String): MessageEntity { - val sourceSubstring = source.substring(offset, offset + length) - return when (type) { - "mention" -> MentionMessageEntity(offset, length, sourceSubstring) - "hashtag" -> HashTagMessageEntity(offset, length, sourceSubstring) - "cashtag" -> TODO() - "bot_command" -> BotCommandMessageEntity(offset, length, sourceSubstring) - "url" -> URLMessageEntity(offset, length, sourceSubstring) - "email" -> EMailMessageEntity(offset, length, sourceSubstring) - "phone_number" -> PhoneNumberMessageEntity(offset, length, sourceSubstring) - "bold" -> BoldTextMessageEntity(offset, length, sourceSubstring) - "italic" -> ItalicTextMessageEntity(offset, length, sourceSubstring) - "code" -> CodeTextMessageEntity(offset, length, sourceSubstring) - "pre" -> PreTextMessageEntity(offset, length, sourceSubstring) - "text_link" -> TextLinkMessageEntity(offset, length, sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link")) - "text_mention" -> TextMentionMessageEntity(offset, length, sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention")) - "underline" -> UnderlineMessageEntity(offset, length, sourceSubstring) - "strikethrough" -> StrikethroughMessageEntity(offset, length, sourceSubstring) - else -> RegularTextMessageEntity(offset, length, sourceSubstring) +) + +internal fun RawMessageEntity.asTextParts(source: String, subParts: List): List { + val sourceSubstring = source.substring(offset, offset + length) + val range = offset until (offset + length) + val shiftedSubParts = subParts.shiftSourcesToTheLeft(offset) + return when (type) { + "mention" -> MentionTextSource(sourceSubstring, shiftedSubParts) + "hashtag" -> HashTagTextSource(sourceSubstring, shiftedSubParts) + "cashtag" -> TODO() + "bot_command" -> BotCommandTextSource(sourceSubstring, shiftedSubParts) + "url" -> URLTextSource(sourceSubstring) + "email" -> EMailTextSource(sourceSubstring, shiftedSubParts) + "phone_number" -> PhoneNumberTextSource(sourceSubstring, shiftedSubParts) + "bold" -> BoldTextSource(sourceSubstring, shiftedSubParts) + "italic" -> ItalicTextSource(sourceSubstring, shiftedSubParts) + "code" -> CodeTextSource(sourceSubstring) + "pre" -> PreTextSource(sourceSubstring) + "text_link" -> TextLinkTextSource(sourceSubstring, url ?: throw IllegalStateException("URL must not be null for text link")) + "text_mention" -> TextMentionTextSource(sourceSubstring, user ?: throw IllegalStateException("User must not be null for text mention"), shiftedSubParts) + "underline" -> UnderlineTextSource(sourceSubstring, shiftedSubParts) + "strikethrough" -> StrikethroughTextSource(sourceSubstring, shiftedSubParts) + else -> RegularTextSource(sourceSubstring) + }.let { + val part = TextPart(range, it) + if (it !is MultilevelTextSource) { + (subParts + part).sortedBy { currentPart -> currentPart.range.first } + } else { + listOf(part) } } } -internal typealias RawMessageEntities = List +internal fun createTextPart(from: String, entities: RawMessageEntities): List { + val mutableEntities = entities.toMutableList() + mutableEntities.sortBy { it.offset } + val resultList = mutableListOf() -internal object RawMessageEntitiesSerializer : KSerializer> by ArrayListSerializer( - RawMessageEntity.serializer() -) + while (mutableEntities.isNotEmpty()) { + val currentFirst = mutableEntities.removeAt(0) + val subEntities = if (mutableEntities.isNotEmpty()) { + val lastIndex = currentFirst.offset + currentFirst.length + val subEntities = mutableListOf() + while (mutableEntities.isNotEmpty()) { + val currentPossibleSubEntity = mutableEntities.first() + if (currentPossibleSubEntity.offset < lastIndex) { + subEntities.add(currentPossibleSubEntity) + mutableEntities.removeAt(0) + } else { + break + } + } + subEntities + } else { + emptyList() + } + + resultList.addAll( + currentFirst.asTextParts( + from, + createTextPart(from, subEntities) + ) + ) + } + + return resultList +} + +internal fun RawMessageEntities.asTextParts(sourceString: String): List = createTextPart(sourceString, this) + +internal typealias RawMessageEntities = List diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt deleted file mode 100644 index b9834832d0..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/RegularTextMessageEntity.kt +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.RegularTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toHtml -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toMarkdown - -data class RegularTextMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by RegularTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/StrikethroughMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/StrikethroughMessageEntity.kt deleted file mode 100644 index 315abd4309..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/StrikethroughMessageEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.StrikethroughTextSource - -class StrikethroughMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by StrikethroughTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt deleted file mode 100644 index 4a8f704ded..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextLinkMessageEntity.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.TextLinkTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown - -data class TextLinkMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String, - val url: String -) : MessageEntity, TextSource by TextLinkTextSource(rawSource, url) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt deleted file mode 100644 index 7a4f8aaa89..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextMentionMessageEntity.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.TextMentionTextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.User -import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown - -class TextMentionMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String, - val privateChat: PrivateChat -) : MessageEntity, TextSource by TextMentionTextSource(rawSource, privateChat) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt deleted file mode 100644 index 61df04059b..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/URLMessageEntity.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.URLTextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown - -data class URLMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by URLTextSource(rawSource) { - val url: String - get() = rawSource -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/UnderlineMessageEntity.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/UnderlineMessageEntity.kt deleted file mode 100644 index 29519fdf64..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/UnderlineMessageEntity.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.UnderlineTextSource - -class UnderlineMessageEntity( - override val offset: Int, - override val length: Int, - override val rawSource: String -) : MessageEntity, TextSource by UnderlineTextSource(rawSource) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt index fda182dc83..45f308f77b 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BoldTextSource.kt @@ -1,14 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.boldMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class BoldTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.boldMarkdown() - override val asHtmlSource: String - get() = rawSource.boldHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List = source.fullListOfSubSource(textParts) + override val asMarkdownSource: String by lazy { source.boldMarkdown() } + override val asMarkdownV2Source: String by lazy { boldMarkdownV2() } + override val asHtmlSource: String by lazy { boldHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt index 0eb749548f..a8dfaa4c52 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/BotCommandTextSource.kt @@ -1,20 +1,25 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.commandMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* private val commandRegex = Regex("[/!][^@\\s]*") class BotCommandTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.commandMarkdown() - override val asHtmlSource: String - get() = rawSource.commandHTML() - + source: String, + textParts: List +) : MultilevelTextSource { val command: String by lazy { - commandRegex.find(rawSource) ?.value ?.substring(1) ?: rawSource.substring(1)// skip first symbol like "/" or "!" + commandRegex.find(source) ?.value ?.substring(1) ?: source.substring(1)// skip first symbol like "/" or "!" } + + override val textParts: List by lazy { + command.fullListOfSubSource( + textParts.shiftSourcesToTheLeft(1) + ) + } + override val asMarkdownSource: String by lazy { source.commandMarkdown() } + override val asMarkdownV2Source: String by lazy { commandMarkdownV2() } + override val asHtmlSource: String by lazy { commandHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt index 0ff5d3334a..fb74f58ae8 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/CodeTextSource.kt @@ -1,14 +1,13 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.codeMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* +import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.escapeMarkdownV2PreAndCode class CodeTextSource( - override val rawSource: String + source: String ) : TextSource { - override val asMarkdownSource: String - get() = rawSource.codeMarkdown() - override val asHtmlSource: String - get() = rawSource.codeHTML() + override val asMarkdownSource: String by lazy { source.codeMarkdown() } + override val asMarkdownV2Source: String by lazy { source.codeMarkdownV2() } + override val asHtmlSource: String by lazy { source.codeHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt index 135b31df98..8c89bc9774 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/EMailTextSource.kt @@ -1,14 +1,14 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.emailMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class EMailTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.emailMarkdown() - override val asHtmlSource: String - get() = rawSource.emailHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.emailMarkdown() } + override val asMarkdownV2Source: String by lazy { emailMarkdownV2(source) } + override val asHtmlSource: String by lazy { emailHTML(source) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt index fb5302d769..45a3eaf4a3 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/HashTagTextSource.kt @@ -1,14 +1,23 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.hashTagMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.utils.* + +private val String.withoutSharp + get() = if (startsWith("#")){ + substring(1) + } else { + this + } class HashTagTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.hashTagMarkdown() - override val asHtmlSource: String - get() = rawSource.hashTagHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List = source.withoutSharp.fullListOfSubSource( + textParts.shiftSourcesToTheLeft(1) + ) + override val asMarkdownSource: String by lazy { source.hashTagMarkdown() } + override val asMarkdownV2Source: String by lazy { hashTagMarkdownV2() } + override val asHtmlSource: String by lazy { hashTagHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt index 2027728f64..44e7b083a3 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/ItalicTextSource.kt @@ -1,14 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.italicMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class ItalicTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.italicMarkdown() - override val asHtmlSource: String - get() = rawSource.italicHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List = source.fullListOfSubSource(textParts) + override val asMarkdownSource: String by lazy { source.italicMarkdown() } + override val asMarkdownV2Source: String by lazy { italicMarkdownV2() } + override val asHtmlSource: String by lazy { italicHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt index a865ef6df4..9e171a0a14 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/MentionTextSource.kt @@ -1,14 +1,25 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.utils.* + +private val String.withoutCommercialAt + get() = if (startsWith("@")) { + substring(1) + } else { + this + } class MentionTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.mentionMarkdown() - override val asHtmlSource: String - get() = rawSource.mentionHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { + source.withoutCommercialAt.fullListOfSubSource( + textParts.shiftSourcesToTheLeft(1) + ) + } + override val asMarkdownSource: String by lazy { source.mentionMarkdown() } + override val asMarkdownV2Source: String by lazy { mentionMarkdownV2() } + override val asHtmlSource: String by lazy { mentionHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt index d9948a3ea2..72e584268a 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PhoneNumberTextSource.kt @@ -1,14 +1,14 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.phoneMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class PhoneNumberTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.phoneMarkdown() - override val asHtmlSource: String - get() = rawSource.phoneHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List = source.fullListOfSubSource(textParts) + override val asMarkdownSource: String by lazy { source.phoneMarkdown() } + override val asMarkdownV2Source: String by lazy { phoneMarkdownV2() } + override val asHtmlSource: String by lazy { phoneHTML() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt index dd8abe9637..d83896ba3f 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/PreTextSource.kt @@ -1,14 +1,13 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.preHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.preMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class PreTextSource( - override val rawSource: String + source: String, + val language: String? = null ) : TextSource { - override val asMarkdownSource: String - get() = rawSource.preMarkdown() - override val asHtmlSource: String - get() = rawSource.preHTML() + override val asMarkdownSource: String by lazy { source.preMarkdown(language) } + override val asMarkdownV2Source: String by lazy { source.preMarkdownV2(language) } + override val asHtmlSource: String by lazy { source.preHTML(language) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt index b8e236ea9d..dca8f5aedc 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/RegularTextSource.kt @@ -1,14 +1,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.regularHtml -import com.github.insanusmokrassar.TelegramBotAPI.utils.regularMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class RegularTextSource( - override val rawSource: String + source: String ) : TextSource { - override val asMarkdownSource: String - get() = rawSource.regularMarkdown() - override val asHtmlSource: String - get() = rawSource.regularHtml() + override val asMarkdownSource: String by lazy { source.regularMarkdown() } + override val asMarkdownV2Source: String by lazy { source.regularMarkdownV2() } + override val asHtmlSource: String by lazy { source.regularHtml() } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt index fa7d3b74cd..274e32f5c7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/StrikethroughTextSource.kt @@ -1,14 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.strikethroughHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.strikethroughMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class StrikethroughTextSource( - override val rawSource: String -) : TextSource { - override val asHtmlSource: String - get() = rawSource.strikethroughHTML() - override val asMarkdownSource: String - get() = rawSource.strikethroughMarkdown() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List = source.fullListOfSubSource(textParts) + override val asHtmlSource: String by lazy { strikethroughHTML() } + override val asMarkdownV2Source: String by lazy { strikethroughMarkdownV2() } + override val asMarkdownSource: String by lazy { source.strikethroughMarkdown() } } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt index 7356ac0b31..73d3ff8803 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextLinkTextSource.kt @@ -1,13 +1,13 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class TextLinkTextSource( - override val rawSource: String, + source: String, url: String ) : TextSource { - override val asMarkdownSource: String = rawSource.linkMarkdown(url) - override val asHtmlSource: String = rawSource.linkHTML(url) + override val asMarkdownSource: String by lazy { source.linkMarkdown(url) } + override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(url) } + override val asHtmlSource: String by lazy { source.linkHTML(url) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt index 3cc4643d55..d4c7f92403 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/TextMentionTextSource.kt @@ -1,15 +1,16 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.User +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.PrivateChat -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.mentionMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class TextMentionTextSource( - override val rawSource: String, - privateChat: PrivateChat -) : TextSource { - override val asMarkdownSource: String = rawSource.mentionMarkdown(privateChat.id) - override val asHtmlSource: String = rawSource.mentionHTML(privateChat.id) + source: String, + privateChat: PrivateChat, + textParts: List +) : MultilevelTextSource { + override val textParts: List by lazy { source.fullListOfSubSource(textParts) } + override val asMarkdownSource: String by lazy { source.textMentionMarkdown(privateChat.id) } + override val asMarkdownV2Source: String by lazy { textMentionMarkdownV2(privateChat.id) } + override val asHtmlSource: String by lazy { textMentionHTML(privateChat.id) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt index f96a169373..bd572b097b 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/URLTextSource.kt @@ -1,14 +1,12 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.linkMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class URLTextSource( - override val rawSource: String -) : TextSource{ - override val asMarkdownSource: String - get() = rawSource.linkMarkdown(rawSource) - override val asHtmlSource: String - get() = rawSource.linkHTML(rawSource) + source: String +) : TextSource { + override val asMarkdownSource: String by lazy { source.linkMarkdown(source) } + override val asMarkdownV2Source: String by lazy { source.linkMarkdownV2(source) } + override val asHtmlSource: String by lazy { source.linkHTML(source) } } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt index d7cef33cdc..92965f33d6 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/textsources/UnderlineTextSource.kt @@ -1,14 +1,15 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.utils.underlineHTML -import com.github.insanusmokrassar.TelegramBotAPI.utils.underlineMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.MultilevelTextSource +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart +import com.github.insanusmokrassar.TelegramBotAPI.utils.* class UnderlineTextSource( - override val rawSource: String -) : TextSource { - override val asMarkdownSource: String - get() = rawSource.underlineMarkdown() - override val asHtmlSource: String - get() = rawSource.underlineHTML() + source: String, + textParts: List +) : MultilevelTextSource { + override val textParts: List = source.fullListOfSubSource(textParts) + override val asMarkdownSource: String by lazy { source.underlineMarkdown() } + override val asMarkdownV2Source: String by lazy { underlineMarkdownV2() } + override val asHtmlSource: String by lazy { underlineHTML() } } \ No newline at end of file diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt index 7a94983458..e3558593d7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/ParseMode/ParseMode.kt @@ -16,6 +16,12 @@ object MarkdownParseMode : ParseMode() { override val parseModeName: String = "Markdown" } +@Serializable(ParseModeSerializerObject::class) +object MarkdownV2ParseMode : ParseMode() { + @Serializable + @SerialName(parseModeField) + override val parseModeName: String = "MarkdownV2" +} @Serializable(ParseModeSerializerObject::class) object HTMLParseMode : ParseMode() { @Serializable @@ -24,6 +30,7 @@ object HTMLParseMode : ParseMode() { } typealias Markdown = MarkdownParseMode +typealias MarkdownV2 = MarkdownV2ParseMode typealias HTML = HTMLParseMode @Serializer(ParseMode::class) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt index f35b549081..6fef99c5f6 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/Game.kt @@ -1,8 +1,6 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.games -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.Titled -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* import com.github.insanusmokrassar.TelegramBotAPI.types.files.AnimationFile import com.github.insanusmokrassar.TelegramBotAPI.types.files.Photo @@ -11,6 +9,6 @@ data class Game( val description: String, val photo: Photo, override val caption: String? = null, - override val captionEntities: List = emptyList(), + override val captionEntities: List = emptyList(), val animation: AnimationFile? = null ) : Titled, CaptionedInput diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt index 76054a81ea..5e740529d7 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/games/RawGame.kt @@ -2,6 +2,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.games import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.RawMessageEntities +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.asTextParts import com.github.insanusmokrassar.TelegramBotAPI.types.files.* import kotlinx.serialization.* @@ -27,7 +28,7 @@ internal data class RawGame( description, photo, caption, - caption ?.let { _ -> captionEntities.map { it.asMessageEntity(caption) } } ?: emptyList(), + caption ?.let { _ -> captionEntities.asTextParts(caption) } ?: emptyList(), animation ) } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt index 14edb09d08..1a48869f16 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/RawMessage.kt @@ -2,6 +2,7 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.RawMessageEntities +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.asTextParts import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.InlineKeyboardMarkup import com.github.insanusmokrassar.TelegramBotAPI.types.chat.abstracts.* import com.github.insanusmokrassar.TelegramBotAPI.types.files.* @@ -85,13 +86,11 @@ internal data class RawMessage( ) { private val content: MessageContent? by lazy { val adaptedCaptionEntities = caption ?.let { - caption_entities ?.map { - it.asMessageEntity(caption) - } + caption_entities ?.asTextParts(caption) } ?: emptyList() when { - text != null -> TextContent(text, entities ?.map { it.asMessageEntity(text) } ?: emptyList()) + text != null -> TextContent(text, entities ?.asTextParts(text) ?: emptyList()) audio != null -> AudioContent( audio, caption, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt index 0dfa2f56f4..0fe6e3296c 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/TextContent.kt @@ -1,20 +1,19 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.SendMessage import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup import com.github.insanusmokrassar.TelegramBotAPI.types.message.abstracts.Message import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.abstracts.MessageContent -import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlTexts -import com.github.insanusmokrassar.TelegramBotAPI.utils.toMarkdownTexts +import com.github.insanusmokrassar.TelegramBotAPI.utils.* data class TextContent( val text: String, - val entities: List = emptyList() + val entities: List = emptyList() ) : MessageContent { override fun createResend( chatId: ChatIdentifier, @@ -52,6 +51,7 @@ data class TextContent( parseMode: ParseMode = HTMLParseMode ): List> = when (parseMode) { is MarkdownParseMode -> toMarkdownTexts() + is MarkdownV2ParseMode -> toMarkdownV2Texts() is HTMLParseMode -> toHtmlTexts() }.map { SendMessage( @@ -65,3 +65,5 @@ data class TextContent( ) } } + +fun TextContent.fullEntitiesList() = text.fullListOfSubSource(entities).map { it.source } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt index a47d4d773e..04227b8c05 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AnimationContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendAnimation import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -18,7 +18,7 @@ data class AnimationContent( override val media: AnimationFile, val includedDocument: DocumentFile?, override val caption: String?, - override val captionEntities: List + override val captionEntities: List ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt index 346826b0b1..ff78e9c9a1 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/AudioContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendAudio import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -16,7 +16,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class AudioContent( override val media: AudioFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt index 2b6b31cb8b..219859ce03 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/DocumentContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendDocument import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -16,7 +16,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class DocumentContent( override val media: DocumentFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt index d358b88ebe..8a03bd47c0 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/PhotoContent.kt @@ -1,11 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendPhoto import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.InputMediaPhoto import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.MediaGroupMemberInputMedia -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -19,7 +19,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class PhotoContent( override val mediaCollection: List, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaCollectionContent, MediaGroupContent { override val media: PhotoSize = mediaCollection.biggest() ?: throw IllegalStateException("Can't locate any photo size for this content") diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt index 718845cafb..ff7210e201 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VideoContent.kt @@ -1,11 +1,11 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendVideo import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.InputMediaVideo import com.github.insanusmokrassar.TelegramBotAPI.types.InputMedia.MediaGroupMemberInputMedia -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -17,7 +17,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class VideoContent( override val media: VideoFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaGroupContent { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt index 63c07dbb5c..61ab4290b6 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/message/content/media/VoiceContent.kt @@ -1,10 +1,10 @@ package com.github.insanusmokrassar.TelegramBotAPI.types.message.content.media import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextPart import com.github.insanusmokrassar.TelegramBotAPI.requests.abstracts.Request import com.github.insanusmokrassar.TelegramBotAPI.requests.send.media.SendVoice import com.github.insanusmokrassar.TelegramBotAPI.types.ChatIdentifier -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity import com.github.insanusmokrassar.TelegramBotAPI.types.MessageIdentifier import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode import com.github.insanusmokrassar.TelegramBotAPI.types.buttons.KeyboardMarkup @@ -16,7 +16,7 @@ import com.github.insanusmokrassar.TelegramBotAPI.utils.toHtmlCaptions data class VoiceContent( override val media: VoiceFile, override val caption: String? = null, - override val captionEntities: List = emptyList() + override val captionEntities: List = emptyList() ) : MediaContent, CaptionedInput { override fun createResend( chatId: ChatIdentifier, diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt new file mode 100644 index 0000000000..7705a6c832 --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/CaptionAndTextSourcesToText.kt @@ -0,0 +1,98 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* +import com.github.insanusmokrassar.TelegramBotAPI.types.captionLength +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent +import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.fullEntitiesList +import com.github.insanusmokrassar.TelegramBotAPI.types.textLength + +fun createFormattedText( + entities: List, + partLength: Int = 4096, + mode: ParseMode = MarkdownParseMode +): List { + val texts = mutableListOf() + val textBuilder = StringBuilder(partLength) + for (entity in entities) { + val string = when (mode) { + is MarkdownParseMode -> entity.asMarkdownSource + is MarkdownV2ParseMode -> entity.asMarkdownV2Source + is HTMLParseMode -> entity.asHtmlSource + } + if (textBuilder.length + string.length > partLength) { + if (textBuilder.isNotEmpty()) { + texts.add(textBuilder.toString()) + textBuilder.clear() + } + val chunked = string.chunked(partLength) + val last = chunked.last() + textBuilder.append(last) + val listToAdd = if (chunked.size > 1) { + chunked.subList(0, chunked.size - 1) + } else { + emptyList() + } + listToAdd.forEach { + texts.add(it) + } + } else { + textBuilder.append(string) + } + } + if (textBuilder.isNotEmpty()) { + texts.add(textBuilder.toString()) + textBuilder.clear() + } + return texts +} + + +fun createMarkdownText( + entities: List, + partLength: Int = 4096 +): List = createFormattedText(entities, partLength, MarkdownParseMode) + +fun CaptionedInput.toMarkdownCaptions(): List = createMarkdownText( + fullEntitiesList(), + captionLength.last + 1 +) + +fun TextContent.toMarkdownTexts(): List = createMarkdownText( + fullEntitiesList(), + textLength.last + 1 +) + + +fun createMarkdownV2Text( + entities: List, + partLength: Int = 4096 +): List = createFormattedText(entities, partLength, MarkdownV2ParseMode) + +fun CaptionedInput.toMarkdownV2Captions(): List = createMarkdownV2Text( + fullEntitiesList(), + captionLength.last + 1 +) + +fun TextContent.toMarkdownV2Texts(): List = createMarkdownV2Text( + fullEntitiesList(), + textLength.last + 1 +) + + +fun createHtmlText( + entities: List, + partLength: Int = 4096 +): List = createFormattedText(entities, partLength, HTMLParseMode) + +fun CaptionedInput.toHtmlCaptions(): List = createHtmlText( + fullEntitiesList(), + captionLength.last + 1 +) + +fun TextContent.toHtmlTexts(): List = createHtmlText( + fullEntitiesList(), + textLength.last + 1 +) + + diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt deleted file mode 100644 index 5eca85548f..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/Captions.kt +++ /dev/null @@ -1,77 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.utils - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.RegularTextMessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* -import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent - -fun CaptionedInput.fullEntitiesList(): List = caption ?.let { - convertToFullMessageEntityList(it, captionEntities) -} ?: emptyList() - -fun TextContent.fullEntitiesList(): List = convertToFullMessageEntityList(text, entities) - -fun convertToFullMessageEntityList( - text: String, - messageEntities: List -): List { - val result = mutableListOf() - - var offset = 0 - for (entity in messageEntities) { - val newEntitySize = entity.offset - offset - if (newEntitySize > 0) { - val regularEntity = RegularTextMessageEntity(offset, newEntitySize, text.substring(offset, entity.offset)) - result.add(regularEntity) - offset += regularEntity.length - } - result.add(entity) - offset += entity.length - } - val newEntitySize = text.length - offset - if (newEntitySize > 0) { - result.add(RegularTextMessageEntity(offset, newEntitySize, text.substring(offset, text.length))) - } - return result -} - -fun createFormattedText( - entities: List, - partLength: Int = 4096, - mode: ParseMode = MarkdownParseMode -): List { - val texts = mutableListOf() - val textBuilder = StringBuilder(partLength) - for (entity in entities) { - val string = when (mode) { - is MarkdownParseMode -> entity.asMarkdownSource - is HTMLParseMode -> entity.asHtmlSource - } - if (textBuilder.length + string.length > partLength) { - if (textBuilder.isNotEmpty()) { - texts.add(textBuilder.toString()) - textBuilder.clear() - } - val chunked = string.chunked(partLength) - val last = chunked.last() - textBuilder.append(last) - val listToAdd = if (chunked.size > 1) { - chunked.subList(0, chunked.size - 1) - } else { - emptyList() - } - listToAdd.forEach { - texts.add(it) - } - } else { - textBuilder.append(string) - } - } - if (textBuilder.isNotEmpty()) { - texts.add(textBuilder.toString()) - textBuilder.clear() - } - return texts -} diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt deleted file mode 100644 index a36b52bee5..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/HtmlCaptionSourcer.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.utils - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.HTMLParseMode -import com.github.insanusmokrassar.TelegramBotAPI.types.captionLength -import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent -import com.github.insanusmokrassar.TelegramBotAPI.types.textLength - -fun createHtmlText( - entities: List, - partLength: Int = 4096 -): List = createFormattedText(entities, partLength, HTMLParseMode) - -fun CaptionedInput.toHtmlCaptions(): List = createHtmlText( - fullEntitiesList(), - captionLength.endInclusive + 1 -) - -fun TextContent.toHtmlTexts(): List = createHtmlText( - fullEntitiesList(), - textLength.endInclusive + 1 -) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt deleted file mode 100644 index c506670702..0000000000 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MarkdownCaptionSourcer.kt +++ /dev/null @@ -1,24 +0,0 @@ -package com.github.insanusmokrassar.TelegramBotAPI.utils - -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.CaptionedInput -import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.TextSource -import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.MessageEntity -import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownParseMode -import com.github.insanusmokrassar.TelegramBotAPI.types.captionLength -import com.github.insanusmokrassar.TelegramBotAPI.types.message.content.TextContent -import com.github.insanusmokrassar.TelegramBotAPI.types.textLength - -fun createMarkdownText( - entities: List, - partLength: Int = 4096 -): List = createFormattedText(entities, partLength, MarkdownParseMode) - -fun CaptionedInput.toMarkdownCaptions(): List = createMarkdownText( - fullEntitiesList(), - captionLength.endInclusive + 1 -) - -fun TextContent.toMarkdownTexts(): List = createMarkdownText( - fullEntitiesList(), - textLength.endInclusive + 1 -) diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt new file mode 100644 index 0000000000..15b0138bcb --- /dev/null +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/MultilevelTextSourceFormatting.kt @@ -0,0 +1,137 @@ +package com.github.insanusmokrassar.TelegramBotAPI.utils + +import com.github.insanusmokrassar.TelegramBotAPI.CommonAbstracts.* +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.* +import com.github.insanusmokrassar.TelegramBotAPI.types.UserId +import com.github.insanusmokrassar.TelegramBotAPI.types.link +import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.* + +internal fun String.fullListOfSubSource(sourceList: List): List { + val sortedSourceList = sourceList.sortedBy { it.range.first }.toMutableList() + + var previousLastIndex = 0 + + val newSubSources = mutableListOf() + + while (sortedSourceList.isNotEmpty()) { + val topSource = sortedSourceList.removeAt(0) + if (topSource.range.first - previousLastIndex > 0) { + val range = previousLastIndex until topSource.range.first + newSubSources.add( + TextPart( + range, + RegularTextSource( + substring(range) + ) + ) + ) + } + newSubSources.add(topSource) + previousLastIndex = topSource.range.last + 1 + } + + if (length > previousLastIndex) { + val range = previousLastIndex until length + newSubSources.add( + TextPart( + range, + RegularTextSource( + substring(range) + ) + ) + ) + } + + return newSubSources +} + +internal fun List.shiftSourcesToTheLeft(shiftCount: Int = 1): List { + return mapNotNull { + val first = (it.range.first - shiftCount).let { firstCalculated -> + if (firstCalculated < 0) { + 0 + } else { + firstCalculated + } + } + val last = (it.range.last - shiftCount).let { lastCalculated -> + if (lastCalculated < 0) { + 0 + } else { + lastCalculated + } + } + it.copy(range = first .. last).let { newSubSource -> + if (newSubSource.range.isEmpty()) { + null + } else { + newSubSource + } + } + } +} + +private fun List.joinSubSourcesMarkdownV2() = joinToString("") { + it.source.asMarkdownV2Source +} + +private fun List.joinSubSourcesHtml() = joinToString("") { + it.source.asHtmlSource +} + +internal fun MultilevelTextSource.markdownV2Default( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol +) = "$openControlSymbol${textParts.joinSubSourcesMarkdownV2()}$closeControlSymbol" +internal fun MultilevelTextSource.htmlDefault( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol +) = "<$openControlSymbol>${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.linkMarkdownV2( + link: String +) = "[${textParts.joinSubSourcesMarkdownV2()}](${link.escapeMarkdownV2Link()})" +internal fun MultilevelTextSource.linkHTML( + link: String +) = "${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.emailMarkdownV2(address: String): String = linkMarkdownV2("mailto://$address") +internal fun MultilevelTextSource.emailHTML(address: String): String = linkHTML("mailto://$address}") + + +internal fun MultilevelTextSource.boldMarkdownV2(): String = markdownV2Default(markdownBoldControl) +internal fun MultilevelTextSource.boldHTML(): String = htmlDefault(htmlBoldControl) + + +internal fun MultilevelTextSource.italicMarkdownV2(): String = markdownV2Default(markdownItalicControl) +internal fun MultilevelTextSource.italicHTML(): String = htmlDefault(htmlItalicControl) + + +internal fun MultilevelTextSource.strikethroughMarkdownV2(): String = markdownV2Default(markdownV2StrikethroughControl) +internal fun MultilevelTextSource.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl) + + +internal fun MultilevelTextSource.underlineMarkdownV2(): String = markdownV2Default(markdownV2UnderlineControl) +internal fun MultilevelTextSource.underlineHTML(): String = htmlDefault(htmlUnderlineControl) + + +internal fun MultilevelTextSource.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link) +internal fun MultilevelTextSource.textMentionHTML(userId: UserId): String = linkHTML(userId.link) + +internal fun MultilevelTextSource.mentionMarkdownV2(): String = "@${textParts.joinSubSourcesMarkdownV2()}" +internal fun MultilevelTextSource.mentionHTML(): String = "@${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.hashTagMarkdownV2(): String = "#${textParts.joinSubSourcesMarkdownV2()}" +internal fun MultilevelTextSource.hashTagHTML(): String = "#${textParts.joinSubSourcesHtml()}" + + +internal fun MultilevelTextSource.phoneMarkdownV2(): String = textParts.joinSubSourcesMarkdownV2() +internal fun MultilevelTextSource.phoneHTML(): String = textParts.joinSubSourcesHtml() + + +internal fun MultilevelTextSource.commandMarkdownV2(): String = "/${textParts.joinSubSourcesMarkdownV2()}" +internal fun MultilevelTextSource.commandHTML(): String = "/${textParts.joinSubSourcesHtml()}" + diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt index 175fcf0569..bf500dabf1 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/StringFormatting.kt @@ -2,14 +2,19 @@ package com.github.insanusmokrassar.TelegramBotAPI.utils import com.github.insanusmokrassar.TelegramBotAPI.types.* import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.* -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toHtml -import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.toMarkdown +import com.github.insanusmokrassar.TelegramBotAPI.utils.extensions.* const val markdownBoldControl = "*" const val markdownItalicControl = "_" const val markdownCodeControl = "`" const val markdownPreControl = "```" +const val markdownV2ItalicUnderlineDelimiter = "\u0013" +const val markdownV2StrikethroughControl = "~" +const val markdownV2UnderlineControl = "__" +const val markdownV2UnderlineEndControl = "$markdownV2UnderlineControl$markdownV2ItalicUnderlineDelimiter" +const val markdownV2ItalicEndControl = "$markdownItalicControl$markdownV2ItalicUnderlineDelimiter" + const val htmlBoldControl = "b" const val htmlItalicControl = "i" const val htmlCodeControl = "code" @@ -21,48 +26,35 @@ private fun String.markdownDefault( openControlSymbol: String, closeControlSymbol: String = openControlSymbol ) = "$openControlSymbol${toMarkdown()}$closeControlSymbol" +private fun String.markdownV2Default( + openControlSymbol: String, + closeControlSymbol: String = openControlSymbol, + escapeFun: String.() -> String = String::escapeMarkdownV2Common +) = "$openControlSymbol${escapeFun()}$closeControlSymbol" private fun String.htmlDefault( openControlSymbol: String, closeControlSymbol: String = openControlSymbol ) = "<$openControlSymbol>${toHtml()}" -fun String.linkMarkdown(link: String): String = "[${toMarkdown()}]($link)" +fun String.linkMarkdown(link: String): String = "[${toMarkdown()}](${link.toMarkdown()})" +fun String.linkMarkdownV2(link: String): String = "[${escapeMarkdownV2Common()}](${link.escapeMarkdownV2Link()})" fun String.linkHTML(link: String): String = "${toHtml()}" fun String.boldMarkdown(): String = markdownDefault(markdownBoldControl) +fun String.boldMarkdownV2(): String = markdownV2Default(markdownBoldControl) fun String.boldHTML(): String = htmlDefault(htmlBoldControl) fun String.italicMarkdown(): String = markdownDefault(markdownItalicControl) -fun String.italicHTML(): String =htmlDefault(htmlItalicControl) - - -fun String.codeMarkdown(): String = markdownDefault(markdownCodeControl) -fun String.codeHTML(): String = htmlDefault(htmlCodeControl) - - -fun String.preMarkdown(language: String? = null): String = markdownDefault( - "$markdownPreControl${language ?.let { "$it\n" } ?: "\n"}", - "\n$markdownPreControl" -) -fun String.preHTML(language: String? = null): String = htmlDefault( - language ?.let { _ -> - "$htmlPreControl><$htmlCodeControl class=\"language-$language\"" - } ?: htmlPreControl, - language ?.let { _ -> - "$htmlCodeControl><$htmlCodeControl class=\"language-$language\"" + } ?: htmlPreControl, + language ?.let { + "$htmlCodeControl> String): String = if (startsWith("@")) { adapt() } else { @@ -87,19 +109,23 @@ private inline fun String.hashTag(adapt: String.() -> String): String = if (star } -fun String.mentionMarkdown(userId: UserId): String = linkMarkdown(userId.link) -fun String.mentionHTML(userId: UserId): String = linkHTML(userId.link) +fun String.textMentionMarkdown(userId: UserId): String = linkMarkdown(userId.link) +fun String.textMentionMarkdownV2(userId: UserId): String = linkMarkdownV2(userId.link) +fun String.textMentionHTML(userId: UserId): String = linkHTML(userId.link) fun String.mentionMarkdown(): String = mention(String::toMarkdown) +fun String.mentionMarkdownV2(): String = mention(String::escapeMarkdownV2Common) fun String.mentionHTML(): String = mention(String::toHtml) fun String.hashTagMarkdown(): String = hashTag(String::toMarkdown) +fun String.hashTagMarkdownV2(): String = hashTag(String::escapeMarkdownV2Common) fun String.hashTagHTML(): String = hashTag(String::toHtml) fun String.phoneMarkdown(): String = toMarkdown() +fun String.phoneMarkdownV2(): String = escapeMarkdownV2Common() fun String.phoneHTML(): String = toHtml() @@ -110,70 +136,97 @@ fun String.command(adapt: String.() -> String): String = if (startsWith("/")) { } fun String.commandMarkdown(): String = command(String::toMarkdown) +fun String.commandMarkdownV2(): String = command(String::escapeMarkdownV2Common) fun String.commandHTML(): String = command(String::toHtml) fun String.regularMarkdown(): String = toMarkdown() +fun String.regularMarkdownV2(): String = escapeMarkdownV2Common() fun String.regularHtml(): String = toHtml() infix fun String.bold(parseMode: ParseMode): String = when (parseMode) { is HTML -> boldHTML() is Markdown -> boldMarkdown() + is MarkdownV2 -> boldMarkdownV2() } infix fun String.italic(parseMode: ParseMode): String = when (parseMode) { is HTML -> italicHTML() is Markdown -> italicMarkdown() + is MarkdownV2 -> italicMarkdownV2() } infix fun String.hashTag(parseMode: ParseMode): String = when (parseMode) { is HTML -> hashTagHTML() is Markdown -> hashTagMarkdown() + is MarkdownV2 -> hashTagMarkdownV2() } infix fun String.code(parseMode: ParseMode): String = when (parseMode) { is HTML -> codeHTML() is Markdown -> codeMarkdown() -} - -infix fun String.pre(parseMode: ParseMode): String = when (parseMode) { - is HTML -> preHTML() - is Markdown -> preMarkdown() + is MarkdownV2 -> codeMarkdownV2() } fun String.pre(parseMode: ParseMode, language: String? = null): String = when (parseMode) { is HTML -> preHTML(language) is Markdown -> preMarkdown(language) + is MarkdownV2 -> preMarkdownV2(language) } +infix fun String.pre(parseMode: ParseMode): String = pre(parseMode, null) infix fun String.email(parseMode: ParseMode): String = when (parseMode) { is HTML -> emailHTML() is Markdown -> emailMarkdown() + is MarkdownV2 -> emailMarkdownV2() } infix fun Pair.link(parseMode: ParseMode): String = when (parseMode) { is HTML -> first.linkHTML(second) is Markdown -> first.linkMarkdown(second) + is MarkdownV2 -> first.linkMarkdownV2(second) } infix fun String.mention(parseMode: ParseMode): String = when (parseMode) { is HTML -> mentionHTML() is Markdown -> mentionMarkdown() + is MarkdownV2 -> mentionMarkdownV2() } infix fun Pair.mention(parseMode: ParseMode): String = when (parseMode) { - is HTML -> first.mentionHTML(second) - is Markdown -> first.mentionMarkdown(second) + is HTML -> first.textMentionHTML(second) + is Markdown -> first.textMentionMarkdown(second) + is MarkdownV2 -> first.textMentionMarkdownV2(second) } infix fun String.phone(parseMode: ParseMode): String = when (parseMode) { is HTML -> phoneHTML() is Markdown -> phoneMarkdown() + is MarkdownV2 -> phoneMarkdownV2() } infix fun String.command(parseMode: ParseMode): String = when (parseMode) { is HTML -> commandHTML() is Markdown -> commandMarkdown() + is MarkdownV2 -> commandMarkdownV2() +} + +infix fun String.underline(parseMode: ParseMode): String = when (parseMode) { + is HTML -> underlineHTML() + is Markdown -> underlineMarkdown() + is MarkdownV2 -> underlineMarkdownV2() +} + +infix fun String.strikethrough(parseMode: ParseMode): String = when (parseMode) { + is HTML -> strikethroughHTML() + is Markdown -> strikethroughMarkdown() + is MarkdownV2 -> strikethroughMarkdownV2() +} + +infix fun String.regular(parseMode: ParseMode): String = when (parseMode) { + is HTML -> regularHtml() + is Markdown -> regularMarkdown() + is MarkdownV2 -> regularMarkdownV2() } diff --git a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt index 7d5457953c..349d644f83 100644 --- a/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt +++ b/src/commonMain/kotlin/com/github/insanusmokrassar/TelegramBotAPI/utils/extensions/String.kt @@ -16,6 +16,33 @@ fun String.toMarkdown(): String { ) } +private val markdownV2LinkEscapes = mutableSetOf(')', '\\') +private val markdownV2PreAndCodeEscapes = mutableSetOf('`', '\\') +private val markdownV2CommonEscapes = mutableSetOf( + '_', + '*', + '[', ']', + '(', ')', + '~', + '`', + '>', + '#', + '+', '-', '=', + '|', + '{', '}', + '.', '!' +) +private fun String.escapeMarkdownV2(escapeCharacters: Iterable): String = map { + if (it in escapeCharacters) { + "\\$it" + } else { + "$it" + } +}.joinToString("") +fun String.escapeMarkdownV2Link() = escapeMarkdownV2(markdownV2LinkEscapes) +fun String.escapeMarkdownV2PreAndCode() = escapeMarkdownV2(markdownV2PreAndCodeEscapes) +fun String.escapeMarkdownV2Common() = escapeMarkdownV2(markdownV2CommonEscapes) + fun String.toHtml(): String = replace( "<", "<" diff --git a/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt b/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt new file mode 100644 index 0000000000..7a2024523e --- /dev/null +++ b/src/commonTest/kotlin/com/github/insanusmokrassar/TelegramBotAPI/types/MessageEntity/TextPartsCreatingTests.kt @@ -0,0 +1,142 @@ +package com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity + +import com.github.insanusmokrassar.TelegramBotAPI.types.MessageEntity.textsources.* +import com.github.insanusmokrassar.TelegramBotAPI.types.ParseMode.MarkdownV2 +import com.github.insanusmokrassar.TelegramBotAPI.utils.* +import kotlin.test.* + +class TextPartsCreatingTests { + @Test + fun testThatTextWithMultilevelPartsCorrectlyCreating() { + val text = "It is simple hello world" + val formattedV2Text = "It *_is_ ~__simple__~* hello world" + val entities = listOf( + RawMessageEntity( + "bold", + 3, + 9 + ), + RawMessageEntity( + "italic", + 3, + 2 + ), + RawMessageEntity( + "strikethrough", + 6, + 6 + ), + RawMessageEntity( + "underline", + 6, + 6 + ) + ) + + val textParts = createTextPart(text, entities) + + + assertTrue ( + textParts.first().source is BoldTextSource + ) + + val boldSource = textParts.first().source as BoldTextSource + assertTrue ( + boldSource.textParts.first().source is ItalicTextSource + ) + assertTrue ( + boldSource.textParts[1].source is RegularTextSource + ) + assertTrue ( + boldSource.textParts[2].source is StrikethroughTextSource + ) + assertTrue ( + (boldSource.textParts[2].source as StrikethroughTextSource).textParts.first().source is UnderlineTextSource + ) + + + val fullTextParts = text.fullListOfSubSource(textParts) + + assertTrue( + fullTextParts.first().source is RegularTextSource + ) + assertTrue( + fullTextParts[1].source is BoldTextSource + ) + assertTrue( + fullTextParts[2].source is RegularTextSource + ) + + assertEquals( + formattedV2Text, + createMarkdownV2Text(fullTextParts.map { it.source }).first() + ) + } + + @Test + fun testThatTextWithMultilevelPartsCorrectlyCreatingInHtml() { + val text = "It is simple hello world" + val formattedHtmlText = "It is simple hello world" + val entities = listOf( + RawMessageEntity( + "bold", + 3, + 9 + ), + RawMessageEntity( + "italic", + 3, + 2 + ), + RawMessageEntity( + "strikethrough", + 6, + 6 + ), + RawMessageEntity( + "underline", + 6, + 6 + ) + ) + + val textParts = createTextPart(text, entities) + + + assertTrue ( + textParts.first().source is BoldTextSource + ) + + val boldSource = textParts.first().source as BoldTextSource + assertTrue ( + boldSource.textParts.first().source is ItalicTextSource + ) + assertTrue ( + boldSource.textParts[1].source is RegularTextSource + ) + assertTrue ( + boldSource.textParts[2].source is StrikethroughTextSource + ) + assertTrue ( + (boldSource.textParts[2].source as StrikethroughTextSource).textParts.first().source is UnderlineTextSource + ) + + + val fullTextParts = text.fullListOfSubSource(textParts) + + assertTrue( + fullTextParts.first().source is RegularTextSource + ) + assertTrue( + fullTextParts[1].source is BoldTextSource + ) + assertTrue( + fullTextParts[2].source is RegularTextSource + ) + + assertEquals( + formattedHtmlText, + createHtmlText(fullTextParts.map { it.source }).first() + ) + } +}