@@ -55,6 +55,15 @@ def lazy_replace(text, key, value_function):
5555 return text
5656
5757
58+ def lazy_replace_args (text , key , value_function ):
59+ """Replace key in text with result from value_function, but run it only if key is found"""
60+ extra_arg = None
61+ if key in text :
62+ replacement , extra_arg = value_function ()
63+ text = text .replace (key , replacement )
64+ return text , extra_arg
65+
66+
5867def trim_string (input_string , max_length ):
5968 """If string is too long, trim it and append '...' so returned string is not longer than max_length"""
6069 if len (input_string ) > max_length :
@@ -308,7 +317,7 @@ def normalize_string_count(input_string, max_length, dots=False, fill=True):
308317 """
309318 Normalize length of string, by cropping it or appending spaces.
310319 Set max_length to None to disable.
311- Also return count of wide characters.
320+ Also return count of wide characters in normalized string .
312321 """
313322 input_string = str (input_string )
314323 if not max_length :
@@ -353,6 +362,8 @@ def normalize_string_with_suffix(input_string, suffix, max_length, emoji_safe=Fa
353362
354363def shift_ranges (ranges_lists , index , diff ):
355364 """Range shifter for chained replace_ functions"""
365+ if not diff :
366+ return
356367 for ranges in ranges_lists :
357368 for format_range in ranges :
358369 if format_range [0 ] >= index :
@@ -362,6 +373,8 @@ def shift_ranges(ranges_lists, index, diff):
362373
363374def shift_ranges_all (diff , * ranges_lists ):
364375 """Shifter for chat format ranges"""
376+ if not diff :
377+ return
365378 for ranges in ranges_lists :
366379 for format_range in ranges :
367380 format_range [0 ] += diff
@@ -385,6 +398,20 @@ def delete_ranges(outer_ranges, *ranges_lists):
385398 break
386399
387400
401+ def shift_formats (formats , index , diff , skip = 1 ):
402+ """Shift formats for one chat element after specified index, creates copy of initial formats if there is diff"""
403+ if not diff :
404+ return formats
405+ new_formats = []
406+ for num , chat_format in enumerate (formats ):
407+ new_chat_format = chat_format [:]
408+ if num >= skip and new_chat_format [1 ] >= index :
409+ new_chat_format [1 ] += diff
410+ new_chat_format [2 ] += diff
411+ new_formats .append (new_chat_format )
412+ return new_formats
413+
414+
388415def replace_discord_emoji (text , * ranges_lists ):
389416 """
390417 Transform emoji strings into nicer looking ones:
@@ -1219,33 +1246,37 @@ def generate_chat(messages, roles, channels, max_length, my_id, my_roles, member
12191246 if trim_embed_url_size :
12201247 embed_url = trim_string (embed_url , trim_embed_url_size )
12211248 content += f"[{ clean_type (embed ["type" ])} embed]: { embed_url } "
1222- reply_line = lazy_replace (format_reply , "%username" , lambda : normalize_string (ref_message ["username" ], limit_username , emoji_safe = True ))
1223- reply_line = lazy_replace (reply_line , "%global_name" , lambda : normalize_string (global_name , limit_username , emoji_safe = True ))
1249+ reply_line = lazy_replace (format_reply , "%username" , lambda : normalize_string (ref_message ["username" ], limit_username , emoji_safe = False ))
1250+ reply_line , wide_shift = lazy_replace_args (reply_line , "%global_name" , lambda : normalize_string_count (global_name , limit_username ))
12241251 reply_line = lazy_replace (reply_line , "%timestamp" , lambda : generate_timestamp (ref_message ["timestamp" ], format_timestamp , convert_timezone ))
12251252 reply_line = lazy_replace (reply_line , "%content" , lambda : content .replace ("\r " , " " ).replace ("\n " , " " ))
1253+ wide_shift = - wide_shift
12261254 else :
12271255 reply_line = lazy_replace (format_reply , "%username" , lambda : normalize_string ("Unknown" , limit_username ))
12281256 reply_line = lazy_replace (reply_line , "%global_name" , lambda : normalize_string ("Unknown" , limit_username ))
12291257 reply_line = reply_line .replace ("%timestamp" , placeholder_timestamp )
12301258 reply_line = lazy_replace (reply_line , "%content" , lambda : ref_message ["content" ].replace ("\r " , "" ).replace ("\n " , "" ))
1259+ wide_shift = 0
12311260 reply_line , wide = normalize_string_count (reply_line , max_length , dots = True )
12321261 if wide :
12331262 temp_wide_map .append (len (temp_chat ))
12341263 temp_chat .append (reply_line )
12351264 if disable_formatting or reply_color_format == color_blocked :
12361265 temp_format .append ([color_base ])
12371266 elif mentioned :
1238- temp_format .append (color_mention_reply )
1267+ temp_format .append (shift_formats ( color_mention_reply , pre_name_len , wide_shift ) )
12391268 else :
1240- temp_format .append (color_reply )
1269+ temp_format .append (shift_formats ( color_reply , pre_name_len , wide_shift ) )
12411270 temp_chat_map .append ((num , None , True , None , None , None ))
12421271
12431272 # bot interaction
12441273 elif message ["interaction" ]:
1274+ global_name , wide_shift = normalize_string_count (get_global_name (message ["interaction" ], use_nick ), limit_username )
1275+ wide_shift = - wide_shift
12451276 interaction_line = (
12461277 format_interaction
12471278 .replace ("%username" , message ["interaction" ]["username" ][:limit_username ])
1248- .replace ("%global_name" , get_global_name ( message [ "interaction" ], use_nick )[: limit_username ] )
1279+ .replace ("%global_name" , global_name )
12491280 .replace ("%command" , message ["interaction" ]["command" ])
12501281 )
12511282 interaction_line , wide = normalize_string_count (interaction_line , max_length , dots = True )
@@ -1255,9 +1286,9 @@ def generate_chat(messages, roles, channels, max_length, my_id, my_roles, member
12551286 if disable_formatting or reply_color_format == color_blocked :
12561287 temp_format .append ([color_base ])
12571288 elif mentioned :
1258- temp_format .append (color_mention_reply )
1289+ temp_format .append (shift_formats ( color_mention_reply , pre_name_len , wide_shift ) )
12591290 else :
1260- temp_format .append (color_reply )
1291+ temp_format .append (shift_formats ( color_reply , pre_name_len , wide_shift ) )
12611292 temp_chat_map .append ((num , None , 2 , None , None , None ))
12621293
12631294 # main message
@@ -1320,11 +1351,12 @@ def generate_chat(messages, roles, channels, max_length, my_id, my_roles, member
13201351 else :
13211352 content += f"[gif sticker] (can be opened): { sticker ["name" ]} "
13221353
1323- message_line = lazy_replace (format_message , "%username" , lambda : normalize_string (message ["username" ], limit_username , emoji_safe = True ))
1324- message_line = lazy_replace (message_line , "%global_name" , lambda : normalize_string (global_name , limit_username , emoji_safe = True ))
1354+ message_line = lazy_replace (format_message , "%username" , lambda : normalize_string (message ["username" ], limit_username , emoji_safe = False ))
1355+ message_line , wide_shift = lazy_replace_args (message_line , "%global_name" , lambda : normalize_string_count (global_name , limit_username ))
13251356 message_line = lazy_replace (message_line , "%timestamp" , lambda : generate_timestamp (message ["timestamp" ], format_timestamp , convert_timezone ))
13261357 message_line = message_line .replace ("%edited" , edited_string if edited else "" )
13271358 message_line = message_line .replace ("%content" , content )
1359+ wide_shift = - wide_shift
13281360
13291361 # find all code snippets and blocks
13301362 code_snippets = []
@@ -1357,6 +1389,19 @@ def generate_chat(messages, roles, channels, max_length, my_id, my_roles, member
13571389 if spoiled :
13581390 spoilers = [value for i , value in enumerate (spoilers ) if i not in spoiled ] # exclude spoiled messages
13591391
1392+ # fix for wide in global_name (assuming global_name is always on left side of content)
1393+ shift_ranges_all (
1394+ wide_shift ,
1395+ urls ,
1396+ # spoilers, # not spoilers?
1397+ code_snippets ,
1398+ code_blocks ,
1399+ emoji_ranges ,
1400+ mention_ranges ,
1401+ channel_ranges ,
1402+ timestamp_ranges ,
1403+ )
1404+
13601405 # find all markdown and correct format indexes
13611406 message_line , md_format , md_indexes = format_md_all (message_line , pre_content_len , chain (code_snippets , code_blocks , urls ))
13621407 if md_indexes :
@@ -1475,27 +1520,29 @@ def generate_chat(messages, roles, channels, max_length, my_id, my_roles, member
14751520 temp_format .append ([color_base ])
14761521 elif mentioned :
14771522 format_line = color_mention_message [:]
1523+ format_line = shift_formats (format_line , pre_name_len + 1 , wide_shift )
14781524 format_line += format_multiline_one_line_format (md_format , newline_index + 1 , 0 , quote )
14791525 format_line += format_multiline_one_line (urls , newline_index + 1 , 0 , color_mention_chat_url , quote )
14801526 format_line += format_multiline_one_line (code_snippets , newline_index + 1 , 0 , color_code , quote )
14811527 format_line += format_multiline_one_line (standout_ranges , newline_index + 1 , 0 , color_standout , quote )
14821528 format_line += code_block_format
14831529 format_line += format_spoilers
14841530 if alt_role_color :
1485- format_line .append ([alt_role_color , pre_name_len , end_name ])
1531+ format_line .append ([alt_role_color , pre_name_len + bool ( wide_shift ) , end_name ])
14861532 if edited and not next_line :
14871533 format_line .append (color_mention_chat_edited + [len_message_line - len_edited , len_message_line ])
14881534 temp_format .append (format_line )
14891535 else :
14901536 format_line = color_message [:]
1537+ format_line = shift_formats (format_line , pre_name_len + 1 , wide_shift )
14911538 format_line += format_multiline_one_line_format (md_format , newline_index + 1 , 0 , quote )
14921539 format_line += format_multiline_one_line (urls , newline_index + 1 , 0 , color_chat_url , quote )
14931540 format_line += format_multiline_one_line (code_snippets , newline_index + 1 , 0 , color_code , quote )
14941541 format_line += format_multiline_one_line (standout_ranges , newline_index + 1 , 0 , color_standout , quote )
14951542 format_line += code_block_format
14961543 format_line += format_spoilers
14971544 if role_color :
1498- format_line .append ([role_color , pre_name_len , end_name ])
1545+ format_line .append ([role_color , pre_name_len + bool ( wide_shift ) , end_name ])
14991546 if edited and not next_line :
15001547 format_line .append ([* color_chat_edited , len_message_line - len_edited , len_message_line ])
15011548 temp_format .append (format_line )
0 commit comments