CoolFace
Apppublic

Zirok05/NER_Russian_IT_Resumes

sourceHugging Faceupdated 7mo agoView on Hugging Face
0likes
visualization.py79 linesDownload Raw Back to modules
1def color_text(text, entities, entity_colors):2    """3    Реализует вложенную подсветку (как в Label Studio).4    Разбивает текст на сегменты по точкам начала и конца всех сущностей.5    """6    if not entities:7        return escape_html(text)8 9    # 1. Собираем все уникальные точки разреза текста10    stops = set([0, len(text)])11    for e in entities:12        stops.add(e['start'])13        stops.add(e['end'])14 15    sorted_stops = sorted(list(stops))16 17    # 2. Для каждого интервала между точками разреза ищем подходящие сущности18    html_segments = []19    for i in range(len(sorted_stops) - 1):20        start, end = sorted_stops[i], sorted_stops[i + 1]21        segment_text = text[start:end]22 23        if not segment_text:24            continue25 26        # Ищем все сущности, которые покрывают этот интервал27        matched_entities = [28            e for e in entities29            if e['start'] <= start and e['end'] >= end30        ]31 32        # Экранируем текст сегмента33        safe_text = escape_html(segment_text)34 35        if not matched_entities:36            html_segments.append(safe_text)37        else:38            # Сортируем сущности для стабильного порядка (например, по длине)39            # Чтобы вложенность была предсказуемой40            matched_entities.sort(key=lambda x: (x['end'] - x['start']), reverse=True)41 42            # Оборачиваем текст в слои span43            opening_tags = ""44            closing_tags = ""45            for e in matched_entities:46                color = entity_colors.get(e['label'], '#D3D3D3')47                rgba = hex_to_rgba(color, alpha=0.5)  # Используем прозрачность48                title = f"{e['label']} ({e['confidence']:.2f})"49 50                # Добавляем стиль для визуального разделения вложенных элементов51                opening_tags += f'<span style="background-color: {rgba}; border-bottom: 2px solid {color}; padding: 1px 0;" title="{title}">'52                closing_tags += '</span>'53 54            html_segments.append(f'{opening_tags}{safe_text}{closing_tags}')55 56    return "".join(html_segments)57 58def hex_to_rgba(hex_color, alpha=0.3):59    """Преобразует HEX в RGBA строку"""60    hex_color = hex_color.lstrip('#')61    r = int(hex_color[0:2], 16)62    g = int(hex_color[2:4], 16)63    b = int(hex_color[4:6], 16)64    return f'rgba({r}, {g}, {b}, {alpha})'65 66def escape_html(text):67    """Заменяет проблемные символы на безопасные аналоги"""68    text = text.replace('«', '"')69    text = text.replace('»', '"')70    text = text.replace('—', '-')71    text = text.replace('–', '-')72    text = text.replace('…', '...')73 74    return (text.replace('&', '&amp;')75            .replace('<', '&lt;')76            .replace('>', '&gt;')77            .replace('"', '&quot;')78            .replace("'", '&#39;'))79