LINUX.ORG.RU

История изменений

Исправление 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