| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- #!/usr/bin/env python3
- """
- Tab2内容生成器 - 段落结构
- """
- import html as html_module
- import re
- from typing import Dict, Any, List
- def extract_image_numbers(text: str) -> List[int]:
- """
- 从文本中提取图片编号
- Args:
- text: 包含图片编号的文本(如"图1"、"图片1"、"图2"或列表)
- Returns:
- 图片编号列表(从1开始)
- """
- if not text:
- return []
- # 使用正则表达式提取所有"图X"或"图片X"格式的编号
- matches = re.findall(r'图片?(\d+)', str(text))
- return [int(num) for num in matches]
- def render_images(text: str, images: List[str]) -> str:
- """
- 根据文本中的图片编号渲染图片HTML
- Args:
- text: 包含图片编号的文本
- images: 原始图片URL列表
- Returns:
- 图片HTML字符串
- """
- image_numbers = extract_image_numbers(text)
- if not image_numbers or not images:
- return ""
- html = '<div class="related-images">\n'
- for num in image_numbers:
- # 图片编号从1开始,数组索引从0开始
- idx = num - 1
- if 0 <= idx < len(images):
- html += f'<div class="image-item">\n'
- html += f'<img src="{images[idx]}" alt="图{num}" loading="lazy">\n'
- html += f'<div class="image-label">图{num}</div>\n'
- html += f'</div>\n'
- html += '</div>\n'
- return html
- def render_paragraph_tree(paragraphs: List[Dict[str, Any]], level: int = 0, images: List[str] = None) -> str:
- """
- 递归渲染段落树(支持展开/收起)
- Args:
- paragraphs: 段落列表
- level: 层级深度
- images: 原始图片URL列表
- Returns:
- HTML字符串
- """
- if not paragraphs:
- return ""
- if images is None:
- images = []
- html = f'<ul class="paragraph-list level-{level}">\n'
- for para in paragraphs:
- para_id = para.get('id', '')
- desc = para.get('描述', '')
- content_range = para.get('内容范围', '')
- reason = para.get('推理依据', '')
- children = para.get('子项', [])
- has_children = bool(children)
- collapsible_class = 'collapsible' if has_children else ''
- html += f'<li class="paragraph-item {collapsible_class}" data-para-id="{html_module.escape(para_id)}">\n'
- # 检查是否有详细信息
- has_details = bool(content_range or reason)
- html += f'<div class="paragraph-header" onclick="toggleCollapse(this)">\n'
- # 添加展开/收起图标
- if has_children:
- html += f'<span class="toggle-icon">▼</span>\n'
- # 将段落索引和描述包裹在一个容器中
- html += f'<div class="paragraph-header-content">\n'
- html += f'<span class="paragraph-index">{html_module.escape(para_id)}</span>\n'
- if desc:
- html += f'<span class="paragraph-desc">{html_module.escape(desc)}</span>\n'
- html += f'</div>\n'
- # 添加详细信息按钮(在标题右侧)
- if has_details:
- html += f'<div class="details-toggle-btn" onclick="event.stopPropagation(); toggleDetails(this)"><span class="details-icon">▶</span> 查看详细内容</div>\n'
- html += f'</div>\n'
- # 将内容包裹在可折叠的容器中
- html += f'<div class="collapsible-content">\n'
- # 添加详细信息区域(可独立收起展开)
- if has_details:
- html += f'<div class="paragraph-details collapsed">\n'
- html += f'<div class="details-content">\n'
- # 添加内容范围(处理列表或字符串类型)
- if content_range:
- if isinstance(content_range, list):
- # 如果是列表,格式化为带标签的列表
- range_html = '<ul class="content-range-list">'
- for item in content_range:
- range_html += f'<li>{html_module.escape(str(item))}</li>'
- range_html += '</ul>'
- html += f'<div class="paragraph-content"><strong>内容范围:</strong>{range_html}</div>\n'
- # 显示相关图片
- if images:
- html += render_images(str(content_range), images)
- else:
- # 如果是字符串,保持原有格式
- html += f'<div class="paragraph-content"><strong>内容范围:</strong>{html_module.escape(str(content_range))}</div>\n'
- # 显示相关图片
- if images:
- html += render_images(str(content_range), images)
- # 添加推理依据
- if reason:
- html += f'<div class="paragraph-reason"><strong>推理依据:</strong>{html_module.escape(reason)}</div>\n'
- html += f'</div>\n'
- html += f'</div>\n'
- if children:
- html += render_paragraph_tree(children, level + 1, images)
- html += '</div>\n'
- html += '</li>\n'
- html += '</ul>\n'
- return html
- def generate_tab2_content(data: Dict[str, Any]) -> str:
- """生成Tab2内容:段落"""
- html = '<div class="tab-content" id="tab2" style="display:none;">\n'
- if '脚本理解' in data:
- script = data['脚本理解']
- script_images = script.get('图片列表', [])
- html += '<div class="section">\n'
- html += '<h3>脚本理解</h3>\n'
- html += f'<div class="script-category"><strong>内容品类:</strong> {script.get("内容品类", "无")}</div>\n'
- # 段落列表
- if '段落列表' in script and script['段落列表']:
- html += '<div class="section-header">\n'
- html += '<h4>段落结构</h4>\n'
- html += '</div>\n'
- html += render_paragraph_tree(script['段落列表'], images=script_images)
- html += '</div>\n'
- html += '</div>\n'
- return html
|