mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2024-11-22 08:13:47 +00:00
add blockquote
This commit is contained in:
parent
a01a9910b5
commit
db2101d85c
@ -22,24 +22,25 @@ internal data class RawMessageEntity(
|
||||
val priority by lazy {
|
||||
when (type) {
|
||||
// Types with potential subsources should have priority
|
||||
"mention" -> 0
|
||||
"hashtag" -> 0
|
||||
"cashtag" -> 0
|
||||
"email" -> 0
|
||||
"phone_number" -> 0
|
||||
"bold" -> 0
|
||||
"italic" -> 0
|
||||
"text_mention" -> 0
|
||||
"strikethrough" -> 0
|
||||
"underline" -> 0
|
||||
"spoiler" -> 0
|
||||
"custom_emoji" -> 0
|
||||
"bot_command" -> 1
|
||||
"url" -> 1
|
||||
"code" -> 1
|
||||
"pre" -> 1
|
||||
"text_link" -> 1
|
||||
else -> 1
|
||||
"mention" -> 1
|
||||
"hashtag" -> 1
|
||||
"cashtag" -> 1
|
||||
"email" -> 1
|
||||
"phone_number" -> 1
|
||||
"bold" -> 1
|
||||
"blockquote" -> 0
|
||||
"italic" -> 1
|
||||
"text_mention" -> 1
|
||||
"strikethrough" -> 1
|
||||
"underline" -> 1
|
||||
"spoiler" -> 1
|
||||
"custom_emoji" -> 1
|
||||
"bot_command" -> 2
|
||||
"url" -> 2
|
||||
"code" -> 2
|
||||
"pre" -> 2
|
||||
"text_link" -> 2
|
||||
else -> 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -61,6 +62,7 @@ internal fun RawMessageEntity.asTextSource(
|
||||
"email" -> EMailTextSource(sourceSubstring, subPartsWithRegulars)
|
||||
"phone_number" -> PhoneNumberTextSource(sourceSubstring, subPartsWithRegulars)
|
||||
"bold" -> BoldTextSource(sourceSubstring, subPartsWithRegulars)
|
||||
"blockquote" -> BlockquoteTextSource(sourceSubstring, subPartsWithRegulars)
|
||||
"italic" -> ItalicTextSource(sourceSubstring, subPartsWithRegulars)
|
||||
"code" -> CodeTextSource(sourceSubstring)
|
||||
"pre" -> PreTextSource(sourceSubstring, language)
|
||||
@ -180,6 +182,7 @@ internal fun TextSource.toRawMessageEntities(offset: Int = 0): List<RawMessageEn
|
||||
is EMailTextSource -> RawMessageEntity("email", offset, length)
|
||||
is PhoneNumberTextSource -> RawMessageEntity("phone_number", offset, length)
|
||||
is BoldTextSource -> RawMessageEntity("bold", offset, length)
|
||||
is BlockquoteTextSource -> RawMessageEntity("blockquote", offset, length)
|
||||
is ItalicTextSource -> RawMessageEntity("italic", offset, length)
|
||||
is CodeTextSource -> RawMessageEntity("code", offset, length)
|
||||
is PreTextSource -> RawMessageEntity("pre", offset, length, language = language)
|
||||
|
@ -0,0 +1,26 @@
|
||||
package dev.inmo.tgbotapi.types.message.textsources
|
||||
|
||||
import dev.inmo.tgbotapi.utils.RiskFeature
|
||||
import dev.inmo.tgbotapi.utils.extensions.makeString
|
||||
import dev.inmo.tgbotapi.utils.internal.*
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* @see blockquote
|
||||
*/
|
||||
@Serializable
|
||||
data class BlockquoteTextSource @RiskFeature(DirectInvocationOfTextSourceConstructor) constructor (
|
||||
override val source: String,
|
||||
override val subsources: TextSourcesList
|
||||
) : MultilevelTextSource {
|
||||
override val markdown: String by lazy { source.blockquoteMarkdown() }
|
||||
override val markdownV2: String by lazy { blockquoteMarkdownV2() }
|
||||
override val html: String by lazy { blockquoteHTML() }
|
||||
}
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun blockquote(parts: TextSourcesList) = BlockquoteTextSource(parts.makeString(), parts)
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun blockquote(vararg parts: TextSource) = blockquote(parts.toList())
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun blockquote(text: String) = blockquote(regular(text))
|
@ -103,6 +103,43 @@ inline fun EntitiesBuilder.bold(text: String) = add(dev.inmo.tgbotapi.types.mess
|
||||
*/
|
||||
inline fun EntitiesBuilder.boldln(text: String) = bold(text) + newLine
|
||||
|
||||
/**
|
||||
* Add blockquote using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.blockquote]
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquote(parts: TextSourcesList) = add(dev.inmo.tgbotapi.types.message.textsources.blockquote(parts))
|
||||
/**
|
||||
* Version of [EntitiesBuilder.blockquote] with new line at the end
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquoteln(parts: TextSourcesList) = blockquote(parts) + newLine
|
||||
/**
|
||||
* Add blockquote using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.blockquote].
|
||||
* Will reuse separator config from [buildEntities]
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquote(noinline init: EntitiesBuilderBody) = add(dev.inmo.tgbotapi.types.message.textsources.blockquote(
|
||||
buildEntities(separator, init)
|
||||
))
|
||||
/**
|
||||
* Version of [EntitiesBuilder.blockquote] with new line at the end.
|
||||
* Will reuse separator config from [buildEntities]
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquoteln(noinline init: EntitiesBuilderBody) = blockquote(init) + newLine
|
||||
/**
|
||||
* Add blockquote using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.blockquote]
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquote(vararg parts: TextSource) = add(dev.inmo.tgbotapi.types.message.textsources.blockquote(*parts))
|
||||
/**
|
||||
* Version of [EntitiesBuilder.blockquote] with new line at the end
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquoteln(vararg parts: TextSource) = blockquote(*parts) + newLine
|
||||
/**
|
||||
* Add blockquote using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.blockquote]
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquote(text: String) = add(dev.inmo.tgbotapi.types.message.textsources.blockquote(text))
|
||||
/**
|
||||
* Version of [EntitiesBuilder.blockquote] with new line at the end
|
||||
*/
|
||||
inline fun EntitiesBuilder.blockquoteln(text: String) = blockquote(text) + newLine
|
||||
|
||||
/**
|
||||
* Add spoiler using [EntitiesBuilder.add] with [dev.inmo.tgbotapi.types.message.textsources.spoiler]
|
||||
*/
|
||||
|
@ -3,6 +3,8 @@ package dev.inmo.tgbotapi.utils.extensions
|
||||
import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
|
||||
import dev.inmo.tgbotapi.types.message.*
|
||||
|
||||
val eachLineRegex = Regex("^[^\n]")
|
||||
|
||||
inline fun TextSourcesList.makeString(
|
||||
parseMode: ParseMode? = null
|
||||
) = when (parseMode) {
|
||||
@ -21,8 +23,23 @@ inline fun TextSourcesList.makeHtmlString() = joinToString("") {
|
||||
it.html
|
||||
}
|
||||
|
||||
inline fun TextSourcesList.makeMarkdownV2String() = joinToString("") {
|
||||
inline fun TextSourcesList.makeMarkdownV2String(eachLineSeparator: String? = null) = joinToString("") {
|
||||
it.markdownV2
|
||||
}.let {
|
||||
if (eachLineSeparator == null) {
|
||||
it
|
||||
} else {
|
||||
it.let {
|
||||
if (it.startsWith("\n")) {
|
||||
it
|
||||
} else {
|
||||
"$eachLineSeparator$it"
|
||||
}
|
||||
}.replace(
|
||||
"\n",
|
||||
"\n$eachLineSeparator"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
inline fun TextSourcesList.makeMarkdownString() = joinToString("") {
|
||||
|
@ -6,8 +6,9 @@ import dev.inmo.tgbotapi.utils.extensions.*
|
||||
|
||||
internal fun MultilevelTextSource.markdownV2Default(
|
||||
openControlSymbol: String,
|
||||
closeControlSymbol: String = openControlSymbol
|
||||
) = "$openControlSymbol${subsources.makeMarkdownV2String()}$closeControlSymbol"
|
||||
closeControlSymbol: String = openControlSymbol,
|
||||
eachLineSeparator: String? = null
|
||||
) = "$openControlSymbol${subsources.makeMarkdownV2String(eachLineSeparator)}$closeControlSymbol"
|
||||
internal fun MultilevelTextSource.htmlDefault(
|
||||
openControlSymbol: String,
|
||||
closeControlSymbol: String = openControlSymbol
|
||||
@ -40,6 +41,10 @@ internal fun MultilevelTextSource.boldMarkdownV2(): String = markdownV2Default(m
|
||||
internal fun MultilevelTextSource.boldHTML(): String = htmlDefault(htmlBoldControl)
|
||||
|
||||
|
||||
internal fun MultilevelTextSource.blockquoteMarkdownV2(): String = markdownV2Default("", eachLineSeparator = markdownBlockquoteControl)
|
||||
internal fun MultilevelTextSource.blockquoteHTML(): String = htmlDefault(htmlBlockquoteControl)
|
||||
|
||||
|
||||
internal fun MultilevelTextSource.cashTagMarkdownV2(): String = subsources.makeMarkdownV2String()
|
||||
internal fun MultilevelTextSource.cashTagHTML(): String = subsources.makeHtmlString()
|
||||
|
||||
|
@ -5,6 +5,7 @@ import dev.inmo.tgbotapi.types.message.*
|
||||
import dev.inmo.tgbotapi.utils.extensions.*
|
||||
|
||||
const val markdownBoldControl = "*"
|
||||
const val markdownBlockquoteControl = ">"
|
||||
const val markdownItalicControl = "_"
|
||||
const val markdownSpoilerControl = "||"
|
||||
const val markdownCodeControl = "`"
|
||||
@ -17,6 +18,7 @@ const val markdownV2UnderlineEndControl = "$markdownV2UnderlineControl$markdownV
|
||||
const val markdownV2ItalicEndControl = "$markdownItalicControl$markdownV2ItalicUnderlineDelimiter"
|
||||
|
||||
const val htmlBoldControl = "b"
|
||||
const val htmlBlockquoteControl = "blockquote"
|
||||
const val htmlItalicControl = "i"
|
||||
const val htmlSpoilerControl = "span class=\"tg-spoiler\""
|
||||
const val htmlSpoilerClosingControl = "span"
|
||||
@ -47,6 +49,8 @@ internal fun String.linkHTML(link: String): String = "<a href=\"$link\">${toHtml
|
||||
|
||||
internal fun String.boldMarkdown(): String = markdownDefault(markdownBoldControl)
|
||||
|
||||
internal fun String.blockquoteMarkdown(): String = regularMarkdown()
|
||||
|
||||
internal fun String.italicMarkdown(): String = markdownDefault(markdownItalicControl)
|
||||
|
||||
internal fun String.spoilerMarkdown(): String = regularMarkdown()
|
||||
|
@ -4,9 +4,11 @@ import dev.inmo.tgbotapi.types.message.RawMessageEntity
|
||||
import dev.inmo.tgbotapi.types.message.textsources.*
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
const val testText = "It (is?) is simple hello world with #tag and @mention"
|
||||
const val formattedV2Text = "It \\(is?\\) *_is_ ~__simple__~* ||hello world|| with \\#tag and @mention"
|
||||
const val formattedHtmlText = "It (is?) <b><i>is</i> <s><u>simple</u></s></b> <span class=\"tg-spoiler\">hello world</span> with #tag and @mention"
|
||||
const val testText = "It (is?) is simple hello world with #tag and @mention. Start of blockquote: Block quotation started\n" +
|
||||
"Block quotation continued\n" +
|
||||
"The last line of the block quotation"
|
||||
const val formattedV2Text = "It \\(is?\\) *_is_ ~__simple__~* ||hello world|| with \\#tag and @mention\\. Start of blockquote: >Block quotation started\n>Block quotation continued\n>The last line of the block quotation"
|
||||
const val formattedHtmlText = "It (is?) <b><i>is</i> <s><u>simple</u></s></b> <span class=\"tg-spoiler\">hello world</span> with #tag and @mention. Start of blockquote: <blockquote>Block quotation started\nBlock quotation continued\nThe last line of the block quotation</blockquote>"
|
||||
internal val testTextEntities = listOf(
|
||||
RawMessageEntity(
|
||||
"bold",
|
||||
@ -42,6 +44,11 @@ internal val testTextEntities = listOf(
|
||||
"mention",
|
||||
45,
|
||||
8
|
||||
),
|
||||
RawMessageEntity(
|
||||
"blockquote",
|
||||
76,
|
||||
86
|
||||
)
|
||||
)
|
||||
|
||||
@ -54,10 +61,15 @@ fun TextSourcesList.testTextSources() {
|
||||
assertTrue (get(5) is HashTagTextSource)
|
||||
assertTrue (get(6) is RegularTextSource)
|
||||
assertTrue (get(7) is MentionTextSource)
|
||||
assertTrue (get(8) is RegularTextSource)
|
||||
assertTrue (get(9) is BlockquoteTextSource)
|
||||
|
||||
val boldSource = get(1) as BoldTextSource
|
||||
assertTrue (boldSource.subsources.first() is ItalicTextSource)
|
||||
assertTrue (boldSource.subsources[1] is RegularTextSource)
|
||||
assertTrue (boldSource.subsources[2] is StrikethroughTextSource)
|
||||
assertTrue ((boldSource.subsources[2] as StrikethroughTextSource).subsources.first() is UnderlineTextSource)
|
||||
|
||||
val blockquoteSource = get(9) as BlockquoteTextSource
|
||||
assertTrue (blockquoteSource.subsources.first() is RegularTextSource)
|
||||
}
|
||||
|
@ -48,7 +48,13 @@ class StringFormattingTests {
|
||||
" with " +
|
||||
hashtag("tag") +
|
||||
" and " +
|
||||
mention("mention")
|
||||
mention("mention") +
|
||||
". Start of blockquote: " +
|
||||
blockquote(
|
||||
"Block quotation started\n" +
|
||||
"Block quotation continued\n" +
|
||||
"The last line of the block quotation"
|
||||
)
|
||||
sources.testTextSources()
|
||||
|
||||
assertEquals(formattedV2Text, sources.toMarkdownV2Texts().first())
|
||||
|
Loading…
Reference in New Issue
Block a user