2021-09-25 02:13:06 +02:00
using System ;
2021-10-23 01:37:50 +02:00
using System.Collections.Generic ;
2021-09-25 02:13:06 +02:00
using System.Globalization ;
2021-09-23 09:29:19 +02:00
using System.Linq ;
2021-08-19 06:56:55 +02:00
using System.Text ;
using System.Web ;
namespace TL
2021-08-10 03:12:33 +02:00
{
2021-10-23 01:37:50 +02:00
public interface IPeerInfo
{
2021-10-22 15:26:46 +02:00
long ID { get ; }
bool IsActive { get ; }
InputPeer ToInputPeer ( ) ;
}
2021-10-23 01:37:50 +02:00
partial class InputPeer { public static InputPeerSelf Self = > new ( ) ; }
partial class InputUser { public static InputUserSelf Self = > new ( ) ; }
partial class InputFileBase
{
public abstract InputEncryptedFileBase ToInputEncryptedFile ( int key_fingerprint ) ;
public abstract InputSecureFileBase ToInputSecureFile ( byte [ ] file_hash , byte [ ] secret ) ;
}
partial class InputFile
{
public override InputEncryptedFileBase ToInputEncryptedFile ( int key_fingerprint ) = > new InputEncryptedFileUploaded { id = id , parts = parts , md5_checksum = md5_checksum , key_fingerprint = key_fingerprint } ;
public override InputSecureFileBase ToInputSecureFile ( byte [ ] file_hash , byte [ ] secret ) = > new InputSecureFileUploaded { id = id , parts = parts , md5_checksum = md5_checksum , file_hash = file_hash , secret = secret } ;
}
partial class InputFileBig
{
public override InputEncryptedFileBase ToInputEncryptedFile ( int key_fingerprint ) = > new InputEncryptedFileBigUploaded { id = id , parts = parts , key_fingerprint = key_fingerprint } ;
public override InputSecureFileBase ToInputSecureFile ( byte [ ] file_hash , byte [ ] secret ) = > new InputSecureFileUploaded { id = id , parts = parts , file_hash = file_hash , secret = secret } ;
}
partial class Peer
{
public abstract long ID { get ; }
abstract internal IPeerInfo UserOrChat ( Dictionary < long , UserBase > users , Dictionary < long , ChatBase > chats ) ;
}
partial class PeerUser
{
public override string ToString ( ) = > "user " + user_id ;
public override long ID = > user_id ;
internal override IPeerInfo UserOrChat ( Dictionary < long , UserBase > users , Dictionary < long , ChatBase > chats ) = > users [ user_id ] ;
}
partial class PeerChat
{
public override string ToString ( ) = > "chat " + chat_id ;
public override long ID = > chat_id ;
internal override IPeerInfo UserOrChat ( Dictionary < long , UserBase > users , Dictionary < long , ChatBase > chats ) = > chats [ chat_id ] ;
}
partial class PeerChannel
{
public override string ToString ( ) = > "channel " + channel_id ;
public override long ID = > channel_id ;
internal override IPeerInfo UserOrChat ( Dictionary < long , UserBase > users , Dictionary < long , ChatBase > chats ) = > chats [ channel_id ] ;
}
partial class UserBase : IPeerInfo
{
public abstract long ID { get ; }
public abstract bool IsActive { get ; }
public abstract InputPeer ToInputPeer ( ) ;
protected abstract InputUserBase ToInputUser ( ) ;
public static implicit operator InputPeer ( UserBase user ) = > user . ToInputPeer ( ) ;
public static implicit operator InputUserBase ( UserBase user ) = > user . ToInputUser ( ) ;
}
partial class UserEmpty
{
public override long ID = > id ;
public override bool IsActive = > false ;
public override string ToString ( ) = > null ;
public override InputPeer ToInputPeer ( ) = > null ;
protected override InputUserBase ToInputUser ( ) = > null ;
}
partial class User
{
public override long ID = > id ;
public override bool IsActive = > ( flags & Flags . deleted ) = = 0 ;
public override string ToString ( ) = > username ! = null ? '@' + username : last_name = = null ? first_name : $"{first_name} {last_name}" ;
public override InputPeer ToInputPeer ( ) = > new InputPeerUser { user_id = id , access_hash = access_hash } ;
protected override InputUserBase ToInputUser ( ) = > new InputUser { user_id = id , access_hash = access_hash } ;
}
2021-10-22 15:26:46 +02:00
partial class ChatBase : IPeerInfo
2021-08-10 03:12:33 +02:00
{
2021-10-22 15:26:46 +02:00
public abstract bool IsActive { get ; }
2021-08-14 15:15:41 +02:00
/// <summary>returns true if you're banned of any of these rights</summary>
2021-08-14 08:55:30 +02:00
public abstract bool IsBanned ( ChatBannedRights . Flags flags = 0 ) ;
2021-10-22 15:26:46 +02:00
public abstract InputPeer ToInputPeer ( ) ;
2021-08-10 03:12:33 +02:00
public static implicit operator InputPeer ( ChatBase chat ) = > chat . ToInputPeer ( ) ;
}
partial class ChatEmpty
{
2021-10-22 15:26:46 +02:00
public override bool IsActive = > false ;
2021-08-14 08:55:30 +02:00
public override bool IsBanned ( ChatBannedRights . Flags flags = 0 ) = > true ;
2021-10-22 15:26:46 +02:00
public override InputPeer ToInputPeer ( ) = > null ;
2021-10-01 02:22:26 +02:00
public override string ToString ( ) = > $"ChatEmpty {id}" ;
2021-08-10 03:12:33 +02:00
}
partial class Chat
{
2021-10-22 15:26:46 +02:00
public override bool IsActive = > ( flags & ( Flags . kicked | Flags . left | Flags . deactivated ) ) = = 0 ;
2021-08-14 08:55:30 +02:00
public override bool IsBanned ( ChatBannedRights . Flags flags = 0 ) = > ( ( default_banned_rights ? . flags ? ? 0 ) & flags ) ! = 0 ;
2021-10-22 15:26:46 +02:00
public override InputPeer ToInputPeer ( ) = > new InputPeerChat { chat_id = id } ;
2021-11-05 04:37:21 +01:00
public override string ToString ( ) = > $"Chat \" { title } \ "" + ( flags . HasFlag ( Flags . deactivated ) ? " [deactivated]" : null ) ;
2021-08-10 03:12:33 +02:00
}
partial class ChatForbidden
{
2021-10-22 15:26:46 +02:00
public override bool IsActive = > false ;
2021-08-14 08:55:30 +02:00
public override bool IsBanned ( ChatBannedRights . Flags flags = 0 ) = > true ;
2021-10-22 15:26:46 +02:00
public override InputPeer ToInputPeer ( ) = > new InputPeerChat { chat_id = id } ;
2021-10-01 02:22:26 +02:00
public override string ToString ( ) = > $"ChatForbidden {id} \" { title } \ "" ;
2021-08-10 03:12:33 +02:00
}
partial class Channel
{
2021-10-22 15:26:46 +02:00
public override bool IsActive = > ( flags & Flags . left ) = = 0 ;
2021-08-14 08:55:30 +02:00
public override bool IsBanned ( ChatBannedRights . Flags flags = 0 ) = > ( ( banned_rights ? . flags ? ? 0 ) & flags ) ! = 0 | | ( ( default_banned_rights ? . flags ? ? 0 ) & flags ) ! = 0 ;
2021-10-22 15:26:46 +02:00
public override InputPeer ToInputPeer ( ) = > new InputPeerChannel { channel_id = id , access_hash = access_hash } ;
2021-08-10 03:12:33 +02:00
public static implicit operator InputChannel ( Channel channel ) = > new ( ) { channel_id = channel . id , access_hash = channel . access_hash } ;
2021-10-01 02:22:26 +02:00
public override string ToString ( ) = >
( flags . HasFlag ( Flags . broadcast ) ? "Channel " : "Group " ) + ( username ! = null ? '@' + username : $"\" { title } \ "" ) ;
2021-08-10 03:12:33 +02:00
}
partial class ChannelForbidden
{
2021-10-22 15:26:46 +02:00
public override bool IsActive = > false ;
2021-08-14 08:55:30 +02:00
public override bool IsBanned ( ChatBannedRights . Flags flags = 0 ) = > true ;
2021-10-22 15:26:46 +02:00
public override InputPeer ToInputPeer ( ) = > new InputPeerChannel { channel_id = id , access_hash = access_hash } ;
2021-10-01 02:22:26 +02:00
public override string ToString ( ) = > $"ChannelForbidden {id} \" { title } \ "" ;
2021-08-10 03:12:33 +02:00
}
2021-08-16 05:56:39 +02:00
2021-10-23 03:36:46 +02:00
partial class ChatParticipantBase { public abstract bool IsAdmin { get ; } }
partial class ChatParticipant { public override bool IsAdmin = > false ; }
partial class ChatParticipantCreator { public override bool IsAdmin = > true ; }
partial class ChatParticipantAdmin { public override bool IsAdmin = > true ; }
2021-10-23 01:37:50 +02:00
2021-08-10 03:12:33 +02:00
partial class PhotoBase
{
public abstract long ID { get ; }
2021-09-30 03:40:08 +02:00
protected abstract InputPhoto ToInputPhoto ( ) ;
public static implicit operator InputPhoto ( PhotoBase photo ) = > photo . ToInputPhoto ( ) ;
2021-08-10 03:12:33 +02:00
}
partial class PhotoEmpty
{
public override long ID = > id ;
2021-09-30 03:40:08 +02:00
protected override InputPhoto ToInputPhoto ( ) = > null ;
2021-08-10 03:12:33 +02:00
}
partial class Photo
{
public override long ID = > id ;
2021-09-30 03:40:08 +02:00
protected override InputPhoto ToInputPhoto ( ) = > new ( ) { id = id , access_hash = access_hash , file_reference = file_reference } ;
2021-09-23 09:29:19 +02:00
public InputPhotoFileLocation ToFileLocation ( ) = > ToFileLocation ( LargestPhotoSize ) ;
2021-08-10 03:12:33 +02:00
public InputPhotoFileLocation ToFileLocation ( PhotoSizeBase photoSize ) = > new ( ) { id = id , access_hash = access_hash , file_reference = file_reference , thumb_size = photoSize . Type } ;
2021-09-23 09:29:19 +02:00
public PhotoSizeBase LargestPhotoSize = > sizes . Aggregate ( ( agg , next ) = > ( long ) next . Width * next . Height > ( long ) agg . Width * agg . Height ? next : agg ) ;
2021-08-10 03:12:33 +02:00
}
2021-09-23 09:29:19 +02:00
partial class PhotoSizeBase
{
public abstract int Width { get ; }
public abstract int Height { get ; }
public abstract int FileSize { get ; }
}
partial class PhotoSizeEmpty
{
public override int Width = > 0 ;
public override int Height = > 0 ;
public override int FileSize = > 0 ;
}
partial class PhotoSize
{
public override int Width = > w ;
public override int Height = > h ;
public override int FileSize = > size ;
}
partial class PhotoCachedSize
{
public override int Width = > w ;
public override int Height = > h ;
public override int FileSize = > bytes . Length ;
}
partial class PhotoStrippedSize
{
public override int Width = > bytes [ 2 ] ;
public override int Height = > bytes [ 1 ] ;
public override int FileSize = > bytes . Length ;
}
partial class PhotoSizeProgressive
{
public override int Width = > w ;
public override int Height = > h ;
public override int FileSize = > sizes . Last ( ) ;
}
partial class PhotoPathSize
{
public override int Width = > - 1 ;
public override int Height = > - 1 ;
public override int FileSize = > bytes . Length ;
}
2021-08-20 14:45:39 +02:00
namespace Layer23
{
2021-09-23 09:29:19 +02:00
partial class PhotoSize
{
public override int Width = > w ;
public override int Height = > h ;
public override int FileSize = > size ;
}
partial class PhotoCachedSize
{
public override int Width = > w ;
public override int Height = > h ;
public override int FileSize = > bytes . Length ;
}
2021-08-20 14:45:39 +02:00
}
2021-08-10 03:12:33 +02:00
2021-10-23 01:37:50 +02:00
partial class Contacts_Blocked { public IPeerInfo UserOrChat ( PeerBlocked peer ) = > peer . peer_id . UserOrChat ( users , chats ) ; }
2021-11-04 02:21:12 +01:00
partial class Messages_Dialogs { public IPeerInfo UserOrChat ( DialogBase dialog ) = > dialog . Peer . UserOrChat ( users , chats ) ; }
2021-10-23 01:37:50 +02:00
2021-10-23 03:36:46 +02:00
partial class Messages_MessagesBase { public abstract int Count { get ; } }
partial class Messages_Messages { public override int Count = > messages . Length ; }
partial class Messages_MessagesSlice { public override int Count = > count ; }
partial class Messages_ChannelMessages { public override int Count = > count ; }
partial class Messages_MessagesNotModified { public override int Count = > count ; }
2021-10-23 01:37:50 +02:00
2021-10-23 03:36:46 +02:00
partial class Updates_DifferenceBase { public abstract Updates_State State { get ; } }
partial class Updates_DifferenceEmpty { public override Updates_State State = > null ; }
partial class Updates_Difference { public override Updates_State State = > state ; }
partial class Updates_DifferenceSlice { public override Updates_State State = > intermediate_state ; }
partial class Updates_DifferenceTooLong { public override Updates_State State = > null ; }
2021-10-23 01:37:50 +02:00
partial class EncryptedFile
{
public static implicit operator InputEncryptedFile ( EncryptedFile file ) = > file = = null ? null : new InputEncryptedFile { id = file . id , access_hash = file . access_hash } ;
public InputEncryptedFileLocation ToFileLocation ( ) = > new ( ) { id = id , access_hash = access_hash } ;
}
2021-08-10 03:12:33 +02:00
partial class DocumentBase
{
public abstract long ID { get ; }
2021-09-30 03:40:08 +02:00
protected abstract InputDocument ToInputDocument ( ) ;
public static implicit operator InputDocument ( DocumentBase document ) = > document . ToInputDocument ( ) ;
2021-08-10 03:12:33 +02:00
}
partial class DocumentEmpty
{
public override long ID = > id ;
2021-09-30 03:40:08 +02:00
protected override InputDocument ToInputDocument ( ) = > null ;
2021-08-10 03:12:33 +02:00
}
partial class Document
{
public override long ID = > id ;
2021-09-30 03:40:08 +02:00
protected override InputDocument ToInputDocument ( ) = > new ( ) { id = id , access_hash = access_hash , file_reference = file_reference } ;
2021-09-23 09:29:19 +02:00
public InputDocumentFileLocation ToFileLocation ( PhotoSizeBase thumbSize = null ) = > new ( ) { id = id , access_hash = access_hash , file_reference = file_reference , thumb_size = thumbSize ? . Type } ;
2021-08-10 03:12:33 +02:00
}
2021-10-23 01:37:50 +02:00
partial class SendMessageAction
2021-08-10 03:12:33 +02:00
{
2021-10-23 01:37:50 +02:00
public override string ToString ( )
{
var type = GetType ( ) . Name [ 11. . ^ 6 ] ;
for ( int i = 1 ; i < type . Length ; i + + )
if ( char . IsUpper ( type [ i ] ) )
return type . ToLowerInvariant ( ) . Insert ( i , "ing " ) ;
return type . ToLowerInvariant ( ) ;
}
2021-08-10 03:12:33 +02:00
}
2021-10-23 03:36:46 +02:00
partial class SpeakingInGroupCallAction { public override string ToString ( ) = > "speaking in group call" ; }
partial class SendMessageTypingAction { public override string ToString ( ) = > "typing" ; }
partial class SendMessageCancelAction { public override string ToString ( ) = > "stopping" ; }
partial class SendMessageGeoLocationAction { public override string ToString ( ) = > "selecting a location" ; }
partial class SendMessageGamePlayAction { public override string ToString ( ) = > "playing a game" ; }
partial class SendMessageHistoryImportAction { public override string ToString ( ) = > "importing history" ; }
2021-08-10 03:12:33 +02:00
2021-10-23 01:37:50 +02:00
partial class StickerSet
2021-08-10 03:12:33 +02:00
{
2021-10-23 01:37:50 +02:00
public static implicit operator InputStickerSetID ( StickerSet stickerSet ) = > new ( ) { id = stickerSet . id , access_hash = stickerSet . access_hash } ;
2021-08-10 03:12:33 +02:00
}
2021-10-23 01:37:50 +02:00
partial class Contacts_ResolvedPeer
2021-08-10 03:12:33 +02:00
{
2021-10-23 01:37:50 +02:00
public static implicit operator InputPeer ( Contacts_ResolvedPeer resolved ) = > resolved . UserOrChat . ToInputPeer ( ) ;
public UserBase User = > peer is PeerUser pu ? users [ pu . user_id ] : null ;
public ChatBase Chat = > peer is PeerChat or PeerChannel ? chats [ peer . ID ] : null ;
2021-08-10 03:12:33 +02:00
}
2021-10-23 01:37:50 +02:00
partial class Updates_ChannelDifferenceBase
2021-08-10 03:12:33 +02:00
{
2021-10-23 01:37:50 +02:00
public abstract MessageBase [ ] NewMessages { get ; }
public abstract Update [ ] OtherUpdates { get ; }
public abstract bool Final { get ; }
public abstract int Timeout { get ; }
2021-08-10 03:12:33 +02:00
}
2021-10-23 01:37:50 +02:00
partial class Updates_ChannelDifferenceEmpty
2021-08-10 03:12:33 +02:00
{
2021-10-23 01:37:50 +02:00
public override MessageBase [ ] NewMessages = > Array . Empty < MessageBase > ( ) ;
public override Update [ ] OtherUpdates = > Array . Empty < Update > ( ) ;
public override bool Final = > flags . HasFlag ( Flags . final ) ;
public override int Timeout = > timeout ;
}
partial class Updates_ChannelDifference
{
public override MessageBase [ ] NewMessages = > new_messages ;
public override Update [ ] OtherUpdates = > other_updates ;
public override bool Final = > flags . HasFlag ( Flags . final ) ;
public override int Timeout = > timeout ;
}
partial class Updates_ChannelDifferenceTooLong
{
public override MessageBase [ ] NewMessages = > messages ;
public override Update [ ] OtherUpdates = > null ;
public override bool Final = > flags . HasFlag ( Flags . final ) ;
public override int Timeout = > timeout ;
2021-08-10 03:12:33 +02:00
}
2021-11-04 02:21:12 +01:00
partial class Messages_PeerDialogs { public IPeerInfo UserOrChat ( DialogBase dialog ) = > dialog . Peer . UserOrChat ( users , chats ) ; }
2021-10-23 01:37:50 +02:00
partial class SecureFile
{
public static implicit operator InputSecureFile ( SecureFile file ) = > new ( ) { id = file . id , access_hash = file . access_hash } ;
public InputSecureFileLocation ToFileLocation ( ) = > new ( ) { id = id , access_hash = access_hash } ;
2021-08-10 03:12:33 +02:00
}
2021-08-16 05:56:39 +02:00
2021-10-23 03:36:46 +02:00
partial class JsonObjectValue { public override string ToString ( ) = > $"{HttpUtility.JavaScriptStringEncode(key, true)}:{value}" ; }
partial class JsonNull { public override string ToString ( ) = > "null" ; }
partial class JsonBool { public override string ToString ( ) = > value ? "true" : "false" ; }
partial class JsonNumber { public override string ToString ( ) = > value . ToString ( CultureInfo . InvariantCulture ) ; }
partial class JsonString { public override string ToString ( ) = > HttpUtility . JavaScriptStringEncode ( value , true ) ; }
2021-08-19 06:56:55 +02:00
partial class JsonArray
{
public override string ToString ( )
{
var sb = new StringBuilder ( ) . Append ( '[' ) ;
for ( int i = 0 ; i < value . Length ; i + + )
sb . Append ( i = = 0 ? "" : "," ) . Append ( value [ i ] ) ;
return sb . Append ( ']' ) . ToString ( ) ;
}
}
partial class JsonObject
{
public override string ToString ( )
{
var sb = new StringBuilder ( ) . Append ( '{' ) ;
for ( int i = 0 ; i < value . Length ; i + + )
sb . Append ( i = = 0 ? "" : "," ) . Append ( value [ i ] ) ;
return sb . Append ( '}' ) . ToString ( ) ;
}
}
2021-10-31 02:40:10 +01:00
2021-10-31 18:28:25 +01:00
public static class Markdown
2021-10-31 02:40:10 +01:00
{
2021-11-06 05:22:33 +01:00
/// <summary>Converts a Markdown text into the (Entities + plain text) format used by Telegram messages</summary>
/// <param name="client">Client, used for getting access_hash for <c>tg://user?id=</c> URLs</param>
/// <param name="text">[in] The Markdown text<br/>[out] The same (plain) text, stripped of all Markdown notation</param>
/// <returns>The array of formatting entities that you can pass (along with the plain text) to <see cref="WTelegram.Client.SendMessageAsync">SendMessageAsync</see> or <see cref="WTelegram.Client.SendMediaAsync">SendMediaAsync</see></returns>
2021-10-31 02:40:10 +01:00
public static MessageEntity [ ] MarkdownToEntities ( this WTelegram . Client client , ref string text )
{
var entities = new List < MessageEntity > ( ) ;
var sb = new StringBuilder ( text ) ;
for ( int offset = 0 ; offset < sb . Length ; )
{
switch ( sb [ offset ] )
{
case '\\' : sb . Remove ( offset + + , 1 ) ; break ;
2021-10-31 18:28:25 +01:00
case '*' : ProcessEntity < MessageEntityBold > ( ) ; break ;
case '~' : ProcessEntity < MessageEntityStrike > ( ) ; break ;
2021-10-31 02:40:10 +01:00
case '_' :
if ( offset + 1 < sb . Length & & sb [ offset + 1 ] = = '_' )
{
sb . Remove ( offset , 1 ) ;
ProcessEntity < MessageEntityUnderline > ( ) ;
}
else
ProcessEntity < MessageEntityItalic > ( ) ;
break ;
case '`' :
if ( offset + 2 < sb . Length & & sb [ offset + 1 ] = = '`' & & sb [ offset + 2 ] = = '`' )
{
2021-10-31 18:28:25 +01:00
int len = 3 ;
if ( entities . FindLast ( e = > e . length = = - 1 ) is MessageEntityPre pre )
2021-10-31 02:40:10 +01:00
pre . length = offset - pre . offset ;
else
{
2021-10-31 18:28:25 +01:00
while ( offset + len < sb . Length & & ! char . IsWhiteSpace ( sb [ offset + len ] ) )
len + + ;
entities . Add ( new MessageEntityPre { offset = offset , length = - 1 , language = sb . ToString ( offset + 3 , len - 3 ) } ) ;
2021-10-31 02:40:10 +01:00
}
2021-10-31 18:28:25 +01:00
sb . Remove ( offset , len ) ;
2021-10-31 02:40:10 +01:00
}
else
ProcessEntity < MessageEntityCode > ( ) ;
break ;
case '[' :
2021-10-31 18:28:25 +01:00
entities . Add ( new MessageEntityTextUrl { offset = offset , length = - 1 } ) ;
2021-10-31 02:40:10 +01:00
sb . Remove ( offset , 1 ) ;
break ;
case ']' :
2021-10-31 18:28:25 +01:00
if ( offset + 2 < sb . Length & & sb [ offset + 1 ] = = '(' )
2021-10-31 02:40:10 +01:00
{
2021-10-31 18:28:25 +01:00
var lastIndex = entities . FindLastIndex ( e = > e . length = = - 1 ) ;
if ( lastIndex > = 0 & & entities [ lastIndex ] is MessageEntityTextUrl textUrl )
{
textUrl . length = offset - textUrl . offset ;
int offset2 = offset + 2 ;
while ( offset2 < sb . Length )
{
char c = sb [ offset2 + + ] ;
if ( c = = '\\' ) sb . Remove ( offset2 - 1 , 1 ) ;
else if ( c = = ')' ) break ;
}
textUrl . url = sb . ToString ( offset + 2 , offset2 - offset - 3 ) ;
if ( textUrl . url . StartsWith ( "tg://user?id=" ) & & long . TryParse ( textUrl . url [ 13. . ] , out var user_id ) & & client . GetAccessHashFor < User > ( user_id ) is long hash )
entities [ lastIndex ] = new InputMessageEntityMentionName { offset = textUrl . offset , length = textUrl . length , user_id = new InputUser { user_id = user_id , access_hash = hash } } ;
sb . Remove ( offset , offset2 - offset ) ;
break ;
}
2021-10-31 02:40:10 +01:00
}
2021-10-31 18:28:25 +01:00
offset + + ;
2021-10-31 02:40:10 +01:00
break ;
default : offset + + ; break ;
}
void ProcessEntity < T > ( ) where T : MessageEntity , new ( )
{
2021-10-31 18:28:25 +01:00
if ( entities . LastOrDefault ( e = > e . length = = - 1 ) is T prevEntity )
2021-10-31 02:40:10 +01:00
prevEntity . length = offset - prevEntity . offset ;
else
2021-10-31 18:28:25 +01:00
entities . Add ( new T { offset = offset , length = - 1 } ) ;
2021-10-31 02:40:10 +01:00
sb . Remove ( offset , 1 ) ;
}
}
text = sb . ToString ( ) ;
return entities . Count = = 0 ? null : entities . ToArray ( ) ;
}
2021-10-31 18:28:25 +01:00
2021-11-06 05:22:33 +01:00
/// <summary>Insert backslashes in front of Markdown reserved characters</summary>
/// <param name="text">The text to escape</param>
/// <returns>The escaped text, ready to be used in <see cref="MarkdownToEntities">MarkdownToEntities</see> without problems</returns>
2021-10-31 18:28:25 +01:00
public static string Escape ( string text )
{
StringBuilder sb = null ;
for ( int index = 0 , added = 0 ; index < text . Length ; index + + )
{
switch ( text [ index ] )
{
case '_' : case '*' : case '~' : case '`' : case '#' : case '+' : case '-' : case '=' : case '.' : case '!' :
case '[' : case ']' : case '(' : case ')' : case '{' : case '}' : case '>' : case '|' : case '\\' :
sb ? ? = new StringBuilder ( text , text . Length + 32 ) ;
sb . Insert ( index + added + + , '\\' ) ;
break ;
}
}
return sb ? . ToString ( ) ? ? text ;
}
2021-10-31 02:40:10 +01:00
}
2021-08-10 03:12:33 +02:00
}