Zirok05/NER_Russian_IT_Resumes
0
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('&', '&')75 .replace('<', '<')76 .replace('>', '>')77 .replace('"', '"')78 .replace("'", '''))79 