mirror of
https://github.com/InsanusMokrassar/TelegramBotAPI.git
synced 2026-03-04 18:02:24 +00:00
rework in part of text message entities
This commit is contained in:
@@ -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<TextSource>,
|
||||
partLength: Int = 4096,
|
||||
mode: ParseMode = MarkdownParseMode
|
||||
): List<String> {
|
||||
val texts = mutableListOf<String>()
|
||||
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<TextSource>,
|
||||
partLength: Int = 4096
|
||||
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
|
||||
|
||||
fun CaptionedInput.toMarkdownCaptions(): List<String> = createMarkdownText(
|
||||
fullEntitiesList(),
|
||||
captionLength.last + 1
|
||||
)
|
||||
|
||||
fun TextContent.toMarkdownTexts(): List<String> = createMarkdownText(
|
||||
fullEntitiesList(),
|
||||
textLength.last + 1
|
||||
)
|
||||
|
||||
|
||||
fun createMarkdownV2Text(
|
||||
entities: List<TextSource>,
|
||||
partLength: Int = 4096
|
||||
): List<String> = createFormattedText(entities, partLength, MarkdownV2ParseMode)
|
||||
|
||||
fun CaptionedInput.toMarkdownV2Captions(): List<String> = createMarkdownV2Text(
|
||||
fullEntitiesList(),
|
||||
captionLength.last + 1
|
||||
)
|
||||
|
||||
fun TextContent.toMarkdownV2Texts(): List<String> = createMarkdownV2Text(
|
||||
fullEntitiesList(),
|
||||
textLength.last + 1
|
||||
)
|
||||
|
||||
|
||||
fun createHtmlText(
|
||||
entities: List<TextSource>,
|
||||
partLength: Int = 4096
|
||||
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
|
||||
|
||||
fun CaptionedInput.toHtmlCaptions(): List<String> = createHtmlText(
|
||||
fullEntitiesList(),
|
||||
captionLength.last + 1
|
||||
)
|
||||
|
||||
fun TextContent.toHtmlTexts(): List<String> = createHtmlText(
|
||||
fullEntitiesList(),
|
||||
textLength.last + 1
|
||||
)
|
||||
|
||||
|
||||
@@ -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<MessageEntity> = caption ?.let {
|
||||
convertToFullMessageEntityList(it, captionEntities)
|
||||
} ?: emptyList()
|
||||
|
||||
fun TextContent.fullEntitiesList(): List<MessageEntity> = convertToFullMessageEntityList(text, entities)
|
||||
|
||||
fun convertToFullMessageEntityList(
|
||||
text: String,
|
||||
messageEntities: List<MessageEntity>
|
||||
): List<MessageEntity> {
|
||||
val result = mutableListOf<MessageEntity>()
|
||||
|
||||
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<TextSource>,
|
||||
partLength: Int = 4096,
|
||||
mode: ParseMode = MarkdownParseMode
|
||||
): List<String> {
|
||||
val texts = mutableListOf<String>()
|
||||
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
|
||||
}
|
||||
@@ -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<TextSource>,
|
||||
partLength: Int = 4096
|
||||
): List<String> = createFormattedText(entities, partLength, HTMLParseMode)
|
||||
|
||||
fun CaptionedInput.toHtmlCaptions(): List<String> = createHtmlText(
|
||||
fullEntitiesList(),
|
||||
captionLength.endInclusive + 1
|
||||
)
|
||||
|
||||
fun TextContent.toHtmlTexts(): List<String> = createHtmlText(
|
||||
fullEntitiesList(),
|
||||
textLength.endInclusive + 1
|
||||
)
|
||||
@@ -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<TextSource>,
|
||||
partLength: Int = 4096
|
||||
): List<String> = createFormattedText(entities, partLength, MarkdownParseMode)
|
||||
|
||||
fun CaptionedInput.toMarkdownCaptions(): List<String> = createMarkdownText(
|
||||
fullEntitiesList(),
|
||||
captionLength.endInclusive + 1
|
||||
)
|
||||
|
||||
fun TextContent.toMarkdownTexts(): List<String> = createMarkdownText(
|
||||
fullEntitiesList(),
|
||||
textLength.endInclusive + 1
|
||||
)
|
||||
@@ -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<TextPart>): List<TextPart> {
|
||||
val sortedSourceList = sourceList.sortedBy { it.range.first }.toMutableList()
|
||||
|
||||
var previousLastIndex = 0
|
||||
|
||||
val newSubSources = mutableListOf<TextPart>()
|
||||
|
||||
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<TextPart>.shiftSourcesToTheLeft(shiftCount: Int = 1): List<TextPart> {
|
||||
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<TextPart>.joinSubSourcesMarkdownV2() = joinToString("") {
|
||||
it.source.asMarkdownV2Source
|
||||
}
|
||||
|
||||
private fun List<TextPart>.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()}</$closeControlSymbol>"
|
||||
|
||||
|
||||
internal fun MultilevelTextSource.linkMarkdownV2(
|
||||
link: String
|
||||
) = "[${textParts.joinSubSourcesMarkdownV2()}](${link.escapeMarkdownV2Link()})"
|
||||
internal fun MultilevelTextSource.linkHTML(
|
||||
link: String
|
||||
) = "<a href=\"${link.toHtml()}\">${textParts.joinSubSourcesHtml()}</a>"
|
||||
|
||||
|
||||
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()}"
|
||||
|
||||
@@ -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()}</$closeControlSymbol>"
|
||||
|
||||
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 = "<a href=\"$link\">${toHtml()}</a>"
|
||||
|
||||
|
||||
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></$htmlPreControl"
|
||||
} ?: htmlPreControl
|
||||
)
|
||||
|
||||
|
||||
fun String.emailMarkdown(): String = linkMarkdown("mailto://$${toMarkdown()}")
|
||||
fun String.emailHTML(): String = linkHTML("mailto://$${toHtml()}")
|
||||
fun String.italicMarkdownV2(): String = markdownV2Default(markdownItalicControl, markdownV2ItalicEndControl)
|
||||
fun String.italicHTML(): String = htmlDefault(htmlItalicControl)
|
||||
|
||||
/**
|
||||
* Crutch for support of strikethrough in default markdown. Simply add modifier, but it will not look like correct
|
||||
*/
|
||||
fun String.strikethroughMarkdown(): String = map { it + "\u0336" }.joinToString("")
|
||||
fun String.strikethroughMarkdownV2(): String = markdownV2Default(markdownV2StrikethroughControl)
|
||||
fun String.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl)
|
||||
|
||||
|
||||
@@ -70,9 +62,39 @@ fun String.strikethroughHTML(): String = htmlDefault(htmlStrikethroughControl)
|
||||
* Crutch for support of underline in default markdown. Simply add modifier, but it will not look like correct
|
||||
*/
|
||||
fun String.underlineMarkdown(): String = map { it + "\u0347" }.joinToString("")
|
||||
fun String.underlineMarkdownV2(): String = markdownV2Default(markdownV2UnderlineControl, markdownV2UnderlineEndControl)
|
||||
fun String.underlineHTML(): String = htmlDefault(htmlUnderlineControl)
|
||||
|
||||
|
||||
fun String.codeMarkdown(): String = markdownDefault(markdownCodeControl)
|
||||
fun String.codeMarkdownV2(): String = markdownV2Default(markdownCodeControl, escapeFun = String::escapeMarkdownV2PreAndCode)
|
||||
fun String.codeHTML(): String = htmlDefault(htmlCodeControl)
|
||||
|
||||
|
||||
fun String.preMarkdown(language: String? = null): String = markdownDefault(
|
||||
"$markdownPreControl${language ?: ""}\n",
|
||||
"\n$markdownPreControl"
|
||||
)
|
||||
fun String.preMarkdownV2(language: String? = null): String = markdownV2Default(
|
||||
"$markdownPreControl${language ?: ""}\n",
|
||||
"\n$markdownPreControl",
|
||||
String::escapeMarkdownV2PreAndCode
|
||||
)
|
||||
fun String.preHTML(language: String? = null): String = htmlDefault(
|
||||
language ?.let {
|
||||
"$htmlPreControl><$htmlCodeControl class=\"language-$language\""
|
||||
} ?: htmlPreControl,
|
||||
language ?.let {
|
||||
"$htmlCodeControl></$htmlPreControl"
|
||||
} ?: htmlPreControl
|
||||
)
|
||||
|
||||
|
||||
fun String.emailMarkdown(): String = linkMarkdown("mailto://$${toMarkdown()}")
|
||||
fun String.emailMarkdownV2(): String = linkMarkdownV2("mailto://$${toMarkdown()}")
|
||||
fun String.emailHTML(): String = linkHTML("mailto://$${toHtml()}")
|
||||
|
||||
|
||||
private inline fun String.mention(adapt: String.() -> 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<String, String>.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<String, ChatId>.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()
|
||||
}
|
||||
|
||||
@@ -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<Char>): 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(
|
||||
"<",
|
||||
"<"
|
||||
|
||||
Reference in New Issue
Block a user