1
0
mirror of https://github.com/InsanusMokrassar/TelegramBotAPI.git synced 2026-06-30 15:15:11 +00:00

Implement markdown and html for RichTextEntity inheritors

Add Rich Markdown style and Rich HTML style serialization for every
RichTextEntity subtype, following the Bot API rich formatting spec
(https://core.telegram.org/bots/api#rich-markdown-style and #rich-html-style).

New RichTextFormatting.kt provides:
* String.escapeRichMarkdown() escaping the rich-markdown special characters;
* RichText.source - plain unformatted text of any RichText;
* RichText.markdown / RichText.html - recursive dispatch over RichTextPlain,
  RichTextGroup and RichTextEntity so inner texts render correctly.

Each of the 25 entity types now overrides markdown and html. Auto-detected
entities (mention, hashtag, cashtag, bank card, bot command) emit their visible
text; the rest wrap inner text in the corresponding markers/tags.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 17:02:03 +06:00
parent 1091dbdb5e
commit 4cfc054526
4 changed files with 271 additions and 0 deletions

View File

@@ -35270,6 +35270,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextAnchor : dev/inmo/tgbota
public final fun copy (Ljava/lang/String;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchor;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextAnchor;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchor;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getName ()Ljava/lang/String;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35301,6 +35303,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextAnchorLink : dev/inmo/tg
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextAnchorLink;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextAnchorLink;
public fun equals (Ljava/lang/Object;)Z
public final fun getAnchorName ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35332,6 +35336,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextBankCardNumber : dev/inm
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextBankCardNumber;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextBankCardNumber;
public fun equals (Ljava/lang/Object;)Z
public final fun getBankCardNumber ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35361,6 +35367,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextBold : dev/inmo/tgbotapi
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextBold;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextBold;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextBold;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35392,6 +35400,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextBotCommand : dev/inmo/tg
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextBotCommand;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextBotCommand;
public fun equals (Ljava/lang/Object;)Z
public final fun getBotCommand ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35423,6 +35433,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextCashtag : dev/inmo/tgbot
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextCashtag;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextCashtag;
public fun equals (Ljava/lang/Object;)Z
public final fun getCashtag ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35452,6 +35464,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextCode : dev/inmo/tgbotapi
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextCode;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextCode;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextCode;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35484,6 +35498,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextCustomEmoji : dev/inmo/t
public fun equals (Ljava/lang/Object;)Z
public final fun getAlternativeText ()Ljava/lang/String;
public final fun getCustomEmojiId-dDnjveI ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
@@ -35515,6 +35531,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextDateTime : dev/inmo/tgbo
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextDateTime;Ldev/inmo/tgbotapi/types/rich/RichText;JLjava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextDateTime;
public fun equals (Ljava/lang/Object;)Z
public final fun getDateTimeFormat ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public final fun getUnixTime ()J
@@ -35547,6 +35565,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextEmailAddress : dev/inmo/
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextEmailAddress;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextEmailAddress;
public fun equals (Ljava/lang/Object;)Z
public final fun getEmailAddress ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35570,6 +35590,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextEmailAddress$Companion {
public abstract interface class dev/inmo/tgbotapi/types/rich/RichTextEntity : dev/inmo/tgbotapi/types/rich/RichText {
public static final field Companion Ldev/inmo/tgbotapi/types/rich/RichTextEntity$Companion;
public abstract fun getHtml ()Ljava/lang/String;
public abstract fun getMarkdown ()Ljava/lang/String;
public abstract fun getType ()Ljava/lang/String;
}
@@ -35581,6 +35603,13 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextEntitySerializer : kotli
public static final field INSTANCE Ldev/inmo/tgbotapi/types/rich/RichTextEntitySerializer;
}
public final class dev/inmo/tgbotapi/types/rich/RichTextFormattingKt {
public static final fun escapeRichMarkdown (Ljava/lang/String;)Ljava/lang/String;
public static final fun getHtml (Ldev/inmo/tgbotapi/types/rich/RichText;)Ljava/lang/String;
public static final fun getMarkdown (Ldev/inmo/tgbotapi/types/rich/RichText;)Ljava/lang/String;
public static final fun getSource (Ldev/inmo/tgbotapi/types/rich/RichText;)Ljava/lang/String;
}
public final class dev/inmo/tgbotapi/types/rich/RichTextGroup : dev/inmo/tgbotapi/types/rich/RichText {
public static final field Companion Ldev/inmo/tgbotapi/types/rich/RichTextGroup$Companion;
public fun <init> (Ljava/util/List;)V
@@ -35618,6 +35647,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextHashtag : dev/inmo/tgbot
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextHashtag;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextHashtag;
public fun equals (Ljava/lang/Object;)Z
public final fun getHashtag ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35677,6 +35708,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextItalic : dev/inmo/tgbota
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextItalic;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextItalic;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextItalic;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35706,6 +35739,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextMarked : dev/inmo/tgbota
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextMarked;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextMarked;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextMarked;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35736,6 +35771,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextMathematicalExpression :
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextMathematicalExpression;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextMathematicalExpression;
public fun equals (Ljava/lang/Object;)Z
public final fun getExpression ()Ljava/lang/String;
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
@@ -35765,6 +35802,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextMention : dev/inmo/tgbot
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;)Ldev/inmo/tgbotapi/types/rich/RichTextMention;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextMention;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextMention;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public final fun getUsername ()Ljava/lang/String;
@@ -35796,6 +35835,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextPhoneNumber : dev/inmo/t
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;)Ldev/inmo/tgbotapi/types/rich/RichTextPhoneNumber;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextPhoneNumber;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextPhoneNumber;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getPhoneNumber ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
@@ -35854,6 +35895,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextReference : dev/inmo/tgb
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;)Ldev/inmo/tgbotapi/types/rich/RichTextReference;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextReference;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextReference;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getName ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
@@ -35885,6 +35928,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextReferenceLink : dev/inmo
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;)Ldev/inmo/tgbotapi/types/rich/RichTextReferenceLink;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextReferenceLink;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextReferenceLink;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getReferenceName ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
@@ -35924,6 +35969,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextSpoiler : dev/inmo/tgbot
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSpoiler;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextSpoiler;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextSpoiler;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35953,6 +36000,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextStrikethrough : dev/inmo
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextStrikethrough;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextStrikethrough;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextStrikethrough;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -35982,6 +36031,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextSubscript : dev/inmo/tgb
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSubscript;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextSubscript;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextSubscript;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -36011,6 +36062,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextSuperscript : dev/inmo/t
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextSuperscript;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextSuperscript;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextSuperscript;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -36041,6 +36094,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextTextMention : dev/inmo/t
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;Ldev/inmo/tgbotapi/types/chat/User;)Ldev/inmo/tgbotapi/types/rich/RichTextTextMention;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextTextMention;Ldev/inmo/tgbotapi/types/rich/RichText;Ldev/inmo/tgbotapi/types/chat/User;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextTextMention;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public final fun getUser ()Ldev/inmo/tgbotapi/types/chat/User;
@@ -36071,6 +36126,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextUnderline : dev/inmo/tgb
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;)Ldev/inmo/tgbotapi/types/rich/RichTextUnderline;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextUnderline;Ldev/inmo/tgbotapi/types/rich/RichText;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextUnderline;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public fun hashCode ()I
@@ -36101,6 +36158,8 @@ public final class dev/inmo/tgbotapi/types/rich/RichTextUrl : dev/inmo/tgbotapi/
public final fun copy (Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;)Ldev/inmo/tgbotapi/types/rich/RichTextUrl;
public static synthetic fun copy$default (Ldev/inmo/tgbotapi/types/rich/RichTextUrl;Ldev/inmo/tgbotapi/types/rich/RichText;Ljava/lang/String;ILjava/lang/Object;)Ldev/inmo/tgbotapi/types/rich/RichTextUrl;
public fun equals (Ljava/lang/Object;)Z
public fun getHtml ()Ljava/lang/String;
public fun getMarkdown ()Ljava/lang/String;
public final fun getText ()Ldev/inmo/tgbotapi/types/rich/RichText;
public fun getType ()Ljava/lang/String;
public final fun getUrl ()Ljava/lang/String;

View File

@@ -42,6 +42,9 @@ data class RichTextGroup(
@Serializable(RichTextEntitySerializer::class)
sealed interface RichTextEntity : RichText {
val type: String
val markdown: String
val html: String
}
object RichTextSerializer : KSerializer<RichText> {

View File

@@ -12,6 +12,7 @@ import dev.inmo.tgbotapi.types.dateTimeFormatField
import dev.inmo.tgbotapi.types.emailAddressField
import dev.inmo.tgbotapi.types.expressionField
import dev.inmo.tgbotapi.types.hashtagField
import dev.inmo.tgbotapi.types.internalUserLinkBeginning
import dev.inmo.tgbotapi.types.nameField
import dev.inmo.tgbotapi.types.phoneNumberField
import dev.inmo.tgbotapi.types.referenceNameField
@@ -21,6 +22,7 @@ import dev.inmo.tgbotapi.types.unixTimeField
import dev.inmo.tgbotapi.types.urlField
import dev.inmo.tgbotapi.types.userField
import dev.inmo.tgbotapi.types.usernameField
import dev.inmo.tgbotapi.utils.extensions.toHtml
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -39,6 +41,11 @@ data class RichTextBold(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "**${text.markdown}**"
override val html: String
get() = "<b>${text.html}</b>"
companion object {
const val TYPE = "bold"
}
@@ -58,6 +65,11 @@ data class RichTextItalic(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "*${text.markdown}*"
override val html: String
get() = "<i>${text.html}</i>"
companion object {
const val TYPE = "italic"
}
@@ -77,6 +89,11 @@ data class RichTextUnderline(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "<u>${text.markdown}</u>"
override val html: String
get() = "<u>${text.html}</u>"
companion object {
const val TYPE = "underline"
}
@@ -96,6 +113,11 @@ data class RichTextStrikethrough(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "~~${text.markdown}~~"
override val html: String
get() = "<s>${text.html}</s>"
companion object {
const val TYPE = "strikethrough"
}
@@ -115,6 +137,11 @@ data class RichTextSpoiler(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "||${text.markdown}||"
override val html: String
get() = "<tg-spoiler>${text.html}</tg-spoiler>"
companion object {
const val TYPE = "spoiler"
}
@@ -134,6 +161,11 @@ data class RichTextSubscript(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "<sub>${text.markdown}</sub>"
override val html: String
get() = "<sub>${text.html}</sub>"
companion object {
const val TYPE = "subscript"
}
@@ -153,6 +185,11 @@ data class RichTextSuperscript(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "<sup>${text.markdown}</sup>"
override val html: String
get() = "<sup>${text.html}</sup>"
companion object {
const val TYPE = "superscript"
}
@@ -172,6 +209,11 @@ data class RichTextMarked(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "==${text.markdown}=="
override val html: String
get() = "<mark>${text.html}</mark>"
companion object {
const val TYPE = "marked"
}
@@ -191,6 +233,11 @@ data class RichTextCode(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "`${text.source}`"
override val html: String
get() = "<code>${text.html}</code>"
companion object {
const val TYPE = "code"
}
@@ -214,6 +261,11 @@ data class RichTextDateTime(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "![${text.markdown}](tg://time?unix=$unixTime&format=$dateTimeFormat)"
override val html: String
get() = "<tg-time unix=\"$unixTime\" format=\"$dateTimeFormat\">${text.html}</tg-time>"
companion object {
const val TYPE = "date_time"
}
@@ -235,6 +287,11 @@ data class RichTextTextMention(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "[${text.markdown}]($internalUserLinkBeginning${user.id.chatId.long})"
override val html: String
get() = "<a href=\"$internalUserLinkBeginning${user.id.chatId.long}\">${text.html}</a>"
companion object {
const val TYPE = "text_mention"
}
@@ -256,6 +313,11 @@ data class RichTextCustomEmoji(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "![${alternativeText.escapeRichMarkdown()}](tg://emoji?id=${customEmojiId.string})"
override val html: String
get() = "<tg-emoji emoji-id=\"${customEmojiId.string}\">${alternativeText.toHtml()}</tg-emoji>"
companion object {
const val TYPE = "custom_emoji"
}
@@ -275,6 +337,11 @@ data class RichTextMathematicalExpression(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "\$$expression\$"
override val html: String
get() = "<tg-math>$expression</tg-math>"
companion object {
const val TYPE = "mathematical_expression"
}
@@ -296,6 +363,11 @@ data class RichTextUrl(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "[${text.markdown}]($url)"
override val html: String
get() = "<a href=\"$url\">${text.html}</a>"
companion object {
const val TYPE = "url"
}
@@ -317,6 +389,11 @@ data class RichTextEmailAddress(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "[${text.markdown}](mailto:$emailAddress)"
override val html: String
get() = "<a href=\"mailto:$emailAddress\">${text.html}</a>"
companion object {
const val TYPE = "email_address"
}
@@ -338,6 +415,11 @@ data class RichTextPhoneNumber(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "[${text.markdown}](tel:$phoneNumber)"
override val html: String
get() = "<a href=\"tel:$phoneNumber\">${text.html}</a>"
companion object {
const val TYPE = "phone_number"
}
@@ -359,6 +441,11 @@ data class RichTextBankCardNumber(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = text.markdown
override val html: String
get() = text.html
companion object {
const val TYPE = "bank_card_number"
}
@@ -380,6 +467,11 @@ data class RichTextMention(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = text.markdown
override val html: String
get() = text.html
companion object {
const val TYPE = "mention"
}
@@ -401,6 +493,11 @@ data class RichTextHashtag(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = text.markdown
override val html: String
get() = text.html
companion object {
const val TYPE = "hashtag"
}
@@ -422,6 +519,11 @@ data class RichTextCashtag(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = text.markdown
override val html: String
get() = text.html
companion object {
const val TYPE = "cashtag"
}
@@ -443,6 +545,11 @@ data class RichTextBotCommand(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = text.markdown
override val html: String
get() = text.html
companion object {
const val TYPE = "bot_command"
}
@@ -462,6 +569,11 @@ data class RichTextAnchor(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "<a name=\"$name\"></a>"
override val html: String
get() = "<a name=\"$name\"></a>"
companion object {
const val TYPE = "anchor"
}
@@ -483,6 +595,11 @@ data class RichTextAnchorLink(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "[${text.markdown}](#$anchorName)"
override val html: String
get() = "<a href=\"#$anchorName\">${text.html}</a>"
companion object {
const val TYPE = "anchor_link"
}
@@ -504,6 +621,11 @@ data class RichTextReference(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "<tg-reference name=\"$name\">${text.markdown}</tg-reference>"
override val html: String
get() = "<tg-reference name=\"$name\">${text.html}</tg-reference>"
companion object {
const val TYPE = "reference"
}
@@ -525,6 +647,11 @@ data class RichTextReferenceLink(
@SerialName(typeField)
override val type: String = TYPE
override val markdown: String
get() = "[${text.markdown}](#$referenceName)"
override val html: String
get() = "<a href=\"#$referenceName\">${text.html}</a>"
companion object {
const val TYPE = "reference_link"
}

View File

@@ -0,0 +1,82 @@
package dev.inmo.tgbotapi.types.rich
import dev.inmo.tgbotapi.types.internalUserLinkBeginning
import dev.inmo.tgbotapi.utils.extensions.toHtml
/**
* Characters which have a special meaning in the
* [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) and must be escaped with a backslash
* to be represented literally.
*/
private val richMarkdownSpecialCharacters = setOf(
'\\', '`', '*', '_', '~', '|', '[', ']', '(', ')', '<', '>', '#', '=', '!', '$'
)
/**
* Escapes all the [richMarkdownSpecialCharacters] of the receiver with a backslash so that the resulting string is
* represented literally in the [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style).
*/
fun String.escapeRichMarkdown(): String = buildString {
for (character in this@escapeRichMarkdown) {
if (character in richMarkdownSpecialCharacters) {
append('\\')
}
append(character)
}
}
/**
* Plain (unformatted) text of this [RichText]. For [RichTextEntity]s without an inner [RichText] it falls back to the
* most meaningful textual representation: alternative text for custom emojis, the expression for mathematical
* expressions and an empty string for anchors.
*/
val RichText.source: String
get() = when (this) {
is RichTextPlain -> text
is RichTextGroup -> parts.joinToString(separator = "") { it.source }
is RichTextCustomEmoji -> alternativeText
is RichTextMathematicalExpression -> expression
is RichTextAnchor -> ""
is RichTextBold -> text.source
is RichTextItalic -> text.source
is RichTextUnderline -> text.source
is RichTextStrikethrough -> text.source
is RichTextSpoiler -> text.source
is RichTextSubscript -> text.source
is RichTextSuperscript -> text.source
is RichTextMarked -> text.source
is RichTextCode -> text.source
is RichTextDateTime -> text.source
is RichTextTextMention -> text.source
is RichTextUrl -> text.source
is RichTextEmailAddress -> text.source
is RichTextPhoneNumber -> text.source
is RichTextBankCardNumber -> text.source
is RichTextMention -> text.source
is RichTextHashtag -> text.source
is RichTextCashtag -> text.source
is RichTextBotCommand -> text.source
is RichTextAnchorLink -> text.source
is RichTextReference -> text.source
is RichTextReferenceLink -> text.source
}
/**
* [Rich Markdown style](https://core.telegram.org/bots/api#rich-markdown-style) representation of this [RichText].
*/
val RichText.markdown: String
get() = when (this) {
is RichTextPlain -> text.escapeRichMarkdown()
is RichTextGroup -> parts.joinToString(separator = "") { it.markdown }
is RichTextEntity -> markdown
}
/**
* [Rich HTML style](https://core.telegram.org/bots/api#rich-html-style) representation of this [RichText].
*/
val RichText.html: String
get() = when (this) {
is RichTextPlain -> text.toHtml()
is RichTextGroup -> parts.joinToString(separator = "") { it.html }
is RichTextEntity -> html
}