'
)
def _render_node(self, node: dict, depth: int, collapsed_depth: int,
node_style: str, show_ids: bool, max_depth) -> str:
if not node or not isinstance(node, dict):
return ""
if max_depth is not None and depth > max_depth:
return '
[depth limit reached]
'
node_id = escape(str(node.get("id", f"node_{depth}")))
speaker = escape(str(node.get("speaker", "")))
text = escape(str(node.get("text", "")))
children = node.get("children", [])
is_collapsed = depth >= collapsed_depth and len(children) > 0
# Speaker color class based on name hash
speaker_class = f"conv-tree-speaker-{abs(hash(speaker)) % 6}"
parts = []
parts.append(
f'
'
)
# Node header
parts.append(f'
')
if children:
arrow = "▶" if is_collapsed else "▼"
parts.append(
f'{arrow}'
)
parts.append(f'{speaker}')
if show_ids:
parts.append(f'({node_id})')
if children:
parts.append(
f'{len(children)} '
f'{"branch" if len(children) == 1 else "branches"}'
)
parts.append('
')
# Node text
parts.append(f'
{text}
')
# Children
if children:
display = "none" if is_collapsed else "block"
parts.append(f'
')
for child in children:
parts.append(self._render_node(
child, depth + 1, collapsed_depth, node_style, show_ids, max_depth
))
parts.append('