История изменений
Исправление theurs, (текущая версия) :
Ссылка длиннее 4к символов?
если попадется такая ссылка то её в телеграм никак не протолкнешь, даже без форматирования Ж(
сделал так. вроде даже работает
# найти и заменить все ссылки (тэг <a>) на рандомные слова с такой же длиной
# разбить текст на части стараясь делать разрез по абзацу, строке или пробелу в таком порядке
# в каждом куске проверить совпадение количества открывающих и закрывающих
# тэгов <b> <code> и заменить рандомные слова обратно на ссылки
def split_html(text: str, max_length: int = 1500) -> list:
"""
Split the given HTML text into chunks of maximum length, while preserving the integrity
of HTML tags. The function takes two arguments:
Parameters:
- text (str): The HTML text to be split.
- max_length (int): The maximum length of each chunk. Default is 1500.
Returns:
- list: A list of chunks, where each chunk is a part of the original text.
Raises:
- AssertionError: If the length of the text is less than or equal to 299.
"""
assert len(text) > 299, 'Длина текста должна быть больше 299'
#найти и заменить все ссылки (тэг <a>) на рандомные слова с такой же длиной
links = []
soup = BeautifulSoup(text, 'html.parser')
a_tags = soup.find_all('a')
for tag in a_tags:
tag = str(tag)
random_string = ''.join(random.choice(string.ascii_uppercase+string.ascii_lowercase) for _ in range(len(tag)))
links.append((random_string, tag))
text = text.replace(tag, random_string)
# разбить текст на части
chunks = telebot.util.smart_split(text, max_length)
chunks2 = []
next_chunk_is_b = False
next_chunk_is_code = False
# в каждом куске проверить совпадение количества открывающих и закрывающих
# тэгов <b> <code> и заменить рандомные слова обратно на ссылки
for chunk in chunks:
for random_string, tag in links:
chunk = chunk.replace(random_string, tag)
b_tags = chunk.count('<b>')
b_close_tags = chunk.count('</b>')
code_tags = chunk.count('<code>')
code_close_tags = chunk.count('</code>')
if b_tags > b_close_tags:
chunk += '</b>'
next_chunk_is_b = True
elif b_tags < b_close_tags:
chunk = '<b>' + chunk
next_chunk_is_b = False
if code_tags > code_close_tags:
chunk += '</code>'
next_chunk_is_code = True
elif code_tags < code_close_tags:
chunk = '<code>' + chunk
next_chunk_is_code = False
# если нет открывающих и закрывающих тегов <code> а в предыдущем чанке
# был добавлен закрывающий тег значит этот чанк целиком - код
if code_close_tags == 0 and code_tags == 0 and next_chunk_is_code:
chunk = '<code>' + chunk
chunk += '</code>'
# если нет открывающих и закрывающих тегов <b> а в предыдущем чанке
# был добавлен закрывающий тег значит этот чанк целиком - <b>
if b_close_tags == 0 and b_tags == 0 and next_chunk_is_b:
chunk = '<b>' + chunk
chunk += '</b>'
chunks2.append(chunk)
return chunks2
Исходная версия theurs, :
Ссылка длиннее 4к символов?
если попадется такая ссылка то её в телеграм никак не протолкнешь, даже без форматирования Ж(
сделал так. вроде даже работает
# найти и заменить все ссылки (тэг <a>) на рандомные слова с такой же длинной
# разбить текст на части стараясь делать разрез по абзацу, строке или пробелу в таком порядке
# в каждом куске проверить совпадение количества открывающих и закрывающих
# тэгов <b> <code> и заменить рандомные слова обратно на ссылки
def split_html(text: str, max_length: int = 1500) -> list:
"""
Split the given HTML text into chunks of maximum length, while preserving the integrity
of HTML tags. The function takes two arguments:
Parameters:
- text (str): The HTML text to be split.
- max_length (int): The maximum length of each chunk. Default is 1500.
Returns:
- list: A list of chunks, where each chunk is a part of the original text.
Raises:
- AssertionError: If the length of the text is less than or equal to 299.
"""
assert len(text) > 299, 'Длина текста должна быть больше 299'
#найти и заменить все ссылки (тэг <a>) на рандомные слова с такой же длинной
links = []
soup = BeautifulSoup(text, 'html.parser')
a_tags = soup.find_all('a')
for tag in a_tags:
tag = str(tag)
random_string = ''.join(random.choice(string.ascii_uppercase+string.ascii_lowercase) for _ in range(len(tag)))
links.append((random_string, tag))
text = text.replace(tag, random_string)
# разбить текст на части
chunks = telebot.util.smart_split(text, max_length)
chunks2 = []
next_chunk_is_b = False
next_chunk_is_code = False
# в каждом куске проверить совпадение количества открывающих и закрывающих
# тэгов <b> <code> и заменить рандомные слова обратно на ссылки
for chunk in chunks:
for random_string, tag in links:
chunk = chunk.replace(random_string, tag)
b_tags = chunk.count('<b>')
b_close_tags = chunk.count('</b>')
code_tags = chunk.count('<code>')
code_close_tags = chunk.count('</code>')
if b_tags > b_close_tags:
chunk += '</b>'
next_chunk_is_b = True
elif b_tags < b_close_tags:
chunk = '<b>' + chunk
next_chunk_is_b = False
if code_tags > code_close_tags:
chunk += '</code>'
next_chunk_is_code = True
elif code_tags < code_close_tags:
chunk = '<code>' + chunk
next_chunk_is_code = False
# если нет открывающих и закрывающих тегов <code> а в предыдущем чанке
# был добавлен закрывающий тег значит этот чанк целиком - код
if code_close_tags == 0 and code_tags == 0 and next_chunk_is_code:
chunk = '<code>' + chunk
chunk += '</code>'
# если нет открывающих и закрывающих тегов <b> а в предыдущем чанке
# был добавлен закрывающий тег значит этот чанк целиком - <b>
if b_close_tags == 0 and b_tags == 0 and next_chunk_is_b:
chunk = '<b>' + chunk
chunk += '</b>'
chunks2.append(chunk)
return chunks2