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