Skill: ziyi-z-z/academic-ppt-generator (version 1.0.0)

--- name: academic-ppt-generator description: | 从学术文献PDF自动生成学术汇报PPT的完整工具链。 **使用场景**: (1) 需要根据文献快速生成学术汇报PPT (2) 文献阅读后的内容整理与可视化呈现 (3) 组会汇报、文献分享、学术报告准备 (4) 需要结构化展示研究问题、方法、结论、局限 **触发关键词**: "文献PPT", "汇报PPT", "学术汇报", "文献整理", "自动生成PPT", "presentation", "组会汇报", "文献分享" **工作流程**: 分析PDF → 提取关键信息 → 生成PPT结构 → 导出PowerPoint文件 --- # 学术汇报PPT生成器 从学术文献PDF自动生成结构化的学术汇报PPT，遵循学术汇报的标准框架。 ## 功能特点 - **结构化输出**: 按照学术汇报的标准四部分组织内容 - **智能分析**: 自动提取文献的关键信息 - **专业排版**: 学术风格的配色和版式设计 - **演讲者备注**: 每页附带演讲提示 ## 标准PPT结构 ### Part 1: 科学问题与背景 (1-2页) - 核心研究问题 - 研究背景 - 前人工作 - 研究空白 - 理论假设 ### Part 2: 研究方法 (2-3页) - 实验设计概述 - 被试/样本信息 - 实验流程 - 控制变量 - 方法-理论对应 ### Part 3: 结论与验证 (多页) - 主要发现（每页一个） - 支持证据 - 假设验证结果 - 结论逻辑链 ### Part 4: 研究局限 (1页) - 方法局限 - 结果局限 - 未来研究方向 ### 总结页 - 核心贡献 ## 使用方法 ### 完整工作流程 ``` 文献PDF → 分析提取 → JSON结构 → PPT文件 ``` #### 步骤1: 分析文献PDF 阅读文献，提取关键信息，整理为JSON格式。参考 `references/analysis_guide.md` 了解提取要点。 #### 步骤2: 生成PPT结构 ```bash python scripts/generate_ppt_structure.py analysis.json > structure.json ``` #### 步骤3: 导出PowerPoint ```bash python scripts/export_ppt.py structure.json output.pptx ``` ### 依赖安装 ```bash pip install python-pptx ``` ## 输入格式 分析结果应为JSON格式，包含以下字段： ```json { "title": "论文标题", "authors": "作者", "venue": "期刊/会议", "year": "2024", "research_question": "核心问题", "background": ["背景要点1", "背景要点2"], "previous_work": ["前人工作1", "前人工作2"], "research_gap": ["研究空白1", "研究空白2"], "hypothesis": ["假设1", "假设2"], "experimental_design": ["设计要点"], "participants": "被试信息", "independent_variables": "自变量", "dependent_variables": "因变量", "procedure": ["步骤1", "步骤2"], "control_variables": ["控制变量1"], "method_theory_mapping": ["方法-理论对应"], "main_findings": ["发现1", "发现2"], "hypothesis_validation": ["验证结果"], "conclusion_logic": ["逻辑链"], "limitations": ["局限1", "局限2"], "contributions": ["贡献1", "贡献2"] } ``` 完整示例见 `references/example_analysis.json`。 ## 注意事项 1. **内容简洁**: 每页PPT控制在6个要点以内 2. **逻辑清晰**: 按"问题-方法-结论-局限"的顺序组织 3. **重点突出**: 强调核心发现和理论贡献 4. **建议配图**: 导出后可手动添加关键图表 ## 自定义选项 如需调整PPT样式，可修改 `scripts/export_ppt.py`: - `COLORS` 字典: 修改配色方案 - 字体大小参数: 调整文字尺寸 - 布局常量: 修改页面元素位置

path: scripts/export_ppt.py
content: #!/usr/bin/env python3
"""
学术汇报PPT导出器 - 将PPT结构导出为PowerPoint文件
"""

import json
import sys
from typing import Dict, List, Any
from pathlib import Path

try:
    from pptx import Presentation
    from pptx.util import Inches, Pt
    from pptx.dml.color import RgbColor
    from pptx.enum.text import PP_ALIGN, MSO_ANCHOR
    from pptx.enum.shapes import MSO_SHAPE
except ImportError:
    print("Error: python-pptx is required. Install with: pip install python-pptx")
    sys.exit(1)


class AcademicPPTExporter:
    """学术PPT导出器"""
    
    # 配色方案 - 学术风格
    COLORS = {
        'primary': RgbColor(0x1a, 0x5f, 0x7a),      # 深蓝绿色 - 主色
        'secondary': RgbColor(0x57, 0xa0, 0xd3),    # 浅蓝色 - 辅助
        'accent': RgbColor(0xf4, 0xa2, 0x61),       # 橙色 - 强调
        'dark': RgbColor(0x2c, 0x3e, 0x50),         # 深色 - 文字
        'light': RgbColor(0xec, 0xf0, 0xf1),        # 浅色 - 背景
        'white': RgbColor(0xff, 0xff, 0xff),
    }
    
    def __init__(self):
        self.prs = Presentation()
        self.prs.slide_width = Inches(13.333)  # 16:9 比例
        self.prs.slide_height = Inches(7.5)
    
    def _add_title_slide(self, title: str, authors: str, venue: str, year: str):
        """添加标题页"""
        slide_layout = self.prs.slide_layouts[6]  # 空白布局
        slide = self.prs.slides.add_slide(slide_layout)
        
        # 背景色块
        shape = slide.shapes.add_shape(
            MSO_SHAPE.RECTANGLE, Inches(0), Inches(0), 
            self.prs.slide_width, self.prs.slide_height
        )
        shape.fill.solid()
        shape.fill.fore_color.rgb = self.COLORS['primary']
        shape.line.fill.background()
        
        # 标题
        title_box = slide.shapes.add_textbox(
            Inches(0.5), Inches(2.5), Inches(12.333), Inches(1.5)
        )
        tf = title_box.text_frame
        p = tf.paragraphs[0]
        p.text = title
        p.font.size = Pt(40)
        p.font.bold = True
        p.font.color.rgb = self.COLORS['white']
        p.alignment = PP_ALIGN.CENTER
        
        # 作者
        author_box = slide.shapes.add_textbox(
            Inches(0.5), Inches(4.2), Inches(12.333), Inches(0.8)
        )
        tf = author_box.text_frame
        p = tf.paragraphs[0]
        p.text = authors
        p.font.size = Pt(24)
        p.font.color.rgb = self.COLORS['light']
        p.alignment = PP_ALIGN.CENTER
        
        # 期刊/年份
        venue_box = slide.shapes.add_textbox(
            Inches(0.5), Inches(5.2), Inches(12.333), Inches(0.6)
        )
        tf = venue_box.text_frame
        p = tf.paragraphs[0]
        p.text = f"{venue}, {year}"
        p.font.size = Pt(18)
        p.font.color.rgb = self.COLORS['secondary']
        p.alignment = PP_ALIGN.CENTER
    
    def _add_section_divider(self, section_title: str, section_num: str):
        """添加章节分隔页"""
        slide_layout = self.prs.slide_layouts[6]
        slide = self.prs.slides.add_slide(slide_layout)
        
        # 左侧色块
        shape = slide.shapes.add_shape(
            MSO_SHAPE.RECTANGLE, Inches(0), Inches(0),
            Inches(4), self.prs.slide_height
        )
        shape.fill.solid()
        shape.fill.fore_color.rgb = self.COLORS['primary']
        shape.line.fill.background()
        
        # 章节编号
        num_box = slide.shapes.add_textbox(
            Inches(0.5), Inches(2.8), Inches(3), Inches(1.5)
        )
        tf = num_box.text_frame
        p = tf.paragraphs[0]
        p.text = section_num
        p.font.size = Pt(72)
        p.font.bold = True
        p.font.color.rgb = self.COLORS['white']
        
        # 章节标题
        title_box = slide.shapes.add_textbox(
            Inches(4.5), Inches(3), Inches(8), Inches(1.5)
        )
        tf = title_box.text_frame
        p = tf.paragraphs[0]
        p.text = section_title
        p.font.size = Pt(44)
        p.font.bold = True
        p.font.color.rgb = self.COLORS['primary']
    
    def _add_content_slide(self, title: str, bullets: List[str], notes: str = ""):
        """添加内容页"""
        slide_layout = self.prs.slide_layouts[6]
        slide = self.prs.slides.add_slide(slide_layout)
        
        # 顶部装饰条
        bar = slide.shapes.add_shape(
            MSO_SHAPE.RECTANGLE, Inches(0), Inches(0),
            self.prs.slide_width, Inches(0.15)
        )
        bar.fill.solid()
        bar.fill.fore_color.rgb = self.COLORS['primary']
        bar.line.fill.background()
        
        # 标题
        title_box = slide.shapes.add_textbox(
            Inches(0.5), Inches(0.4), Inches(12.333), Inches(0.8)
        )
        tf = title_box.text_frame
        p = tf.paragraphs[0]
        p.text = title
        p.font.size = Pt(32)
        p.font.bold = True
        p.font.color.rgb = self.COLORS['primary']
        
        # 内容
        content_box = slide.shapes.add_textbox(
            Inches(0.5), Inches(1.4), Inches(12.333), Inches(5.8)
        )
        tf = content_box.text_frame
        tf.word_wrap = True
        
        for i, bullet in enumerate(bullets):
            if i == 0:
                p = tf.paragraphs[0]
            else:
                p = tf.add_paragraph()
            
            # 处理加粗标记 **text**
            if bullet.startswith('**') and bullet.endswith('**'):
                p.text = bullet[2:-2]
                p.font.bold = True
            elif '**' in bullet:
                # 简单处理行内加粗
                parts = bullet.split('**')
                p.text = ''.join(parts)
                p.font.bold = False
            else:
                p.text = bullet
            
            p.font.size = Pt(20) if bullet.startswith('•') or bullet.startswith(('1.', '2.', '3.', '4.', '5.', '→')) else Pt(22)
            p.font.color.rgb = self.COLORS['dark']
            p.space_before = Pt(12) if bullet == "" else Pt(6)
            p.line_spacing = 1.3
        
        # 演讲者备注
        if notes:
            slide.notes_slide.notes_text_frame.text = notes
    
    def export(self, structure: Dict[str, Any], output_path: str):
        """导出PPT"""
        # 标题页
        self._add_title_slide(
            structure['title'],
            structure['authors'],
            structure['venue'],
            structure['year']
        )
        
        slides_data = structure['slides']
        
        # 第一部分：科学问题
        if slides_data['part1_problem']:
            self._add_section_divider("科学问题与背景", "01")
            for slide_data in slides_data['part1_problem']:
                self._add_content_slide(
                    slide_data['title'],
                    slide_data['bullets'],
                    slide_data.get('notes', '')
                )
        
        # 第二部分：方法
        if slides_data['part2_method']:
            self._add_section_divider("研究方法", "02")
            for slide_data in slides_data['part2_method']:
                self._add_content_slide(
                    slide_data['title'],
                    slide_data['bullets'],
                    slide_data.get('notes', '')
                )
        
        # 第三部分：结论
        if slides_data['part3_results']:
            self._add_section_divider("结论与验证", "03")
            for slide_data in slides_data['part3_results']:
                self._add_content_slide(
                    slide_data['title'],
                    slide_data['bullets'],
                    slide_data.get('notes', '')
                )
        
        # 第四部分：局限
        if slides_data['part4_limitations']:
            self._add_section_divider("局限与展望", "04")
            limitation = slides_data['part4_limitations']
            self._add_content_slide(
                limitation['title'],
                limitation['bullets'],
                limitation.get('notes', '')
            )
        
        # 总结页
        if slides_data['summary']:
            summary = slides_data['summary']
            self._add_content_slide(
                summary['title'],
                summary['bullets'],
                summary.get('notes', '')
            )
        
        # 保存
        self.prs.save(output_path)
        print(f"PPT已保存至: {output_path}")
        print(f"总页数: {len(self.prs.slides)}")


def main():
    """主函数"""
    if len(sys.argv) < 3:
        print("Usage: python export_ppt.py <structure_json_file> <output_pptx_file>")
        sys.exit(1)
    
    structure_file = sys.argv[1]
    output_file = sys.argv[2]
    
    # 读取结构
    with open(structure_file, 'r', encoding='utf-8') as f:
        structure = json.load(f)
    
    # 导出
    exporter = AcademicPPTExporter()
    exporter.export(structure, output_file)


if __name__ == "__main__":
    main()


path: scripts/generate_ppt_structure.py
content: #!/usr/bin/env python3
"""
学术汇报PPT生成器 - 从文献PDF自动生成学术汇报PPT
"""

import json
import sys
from typing import Dict, List, Any, Optional
from dataclasses import dataclass, asdict
from datetime import datetime


@dataclass
class SlideContent:
    """单页PPT内容"""
    title: str
    bullets: List[str]
    notes: str = ""
    layout: str = "content"  # title, content, two-column, comparison


@dataclass
class PresentationStructure:
    """PPT整体结构"""
    title: str
    authors: str
    venue: str
    year: str
    
    # 第一部分：科学问题与背景 (1-2页)
    problem_slides: List[SlideContent]
    
    # 第二部分：方法 (2-3页)
    method_slides: List[SlideContent]
    
    # 第三部分：结论与验证 (多页)
    result_slides: List[SlideContent]
    
    # 第四部分：局限 (1页)
    limitation_slide: SlideContent
    
    # 总结页
    summary_slide: SlideContent


def create_ppt_structure(analysis_result: Dict[str, Any]) -> PresentationStructure:
    """
    根据文献分析结果创建PPT结构
    
    Args:
        analysis_result: 包含文献各部分分析结果的字典
        
    Returns:
        PresentationStructure: PPT结构对象
    """
    
    # 提取基本信息
    title = analysis_result.get("title", "研究标题")
    authors = analysis_result.get("authors", "作者")
    venue = analysis_result.get("venue", "发表期刊/会议")
    year = analysis_result.get("year", str(datetime.now().year))
    
    # ========== 第一部分：科学问题与背景 ==========
    problem_slides = []
    
    # 第1页：科学问题与背景
    problem_slide1 = SlideContent(
        title="研究背景与科学问题",
        bullets=[
            f"**核心问题**: {analysis_result.get('research_question', '待提取')}",
            "",
            "**研究背景**:",
            *[f"• {bg}" for bg in analysis_result.get('background', ['背景信息待提取'])],
            "",
            "**前人工作**:",
            *[f"• {work}" for work in analysis_result.get('previous_work', ['前人工作待提取'])]
        ],
        notes="这一页要快速让观众理解研究的大背景和核心问题",
        layout="content"
    )
    problem_slides.append(problem_slide1)
    
    # 第2页：研究空白与假设（如果需要）
    if analysis_result.get('research_gap') or analysis_result.get('hypothesis'):
        problem_slide2 = SlideContent(
            title="研究空白与理论假设",
            bullets=[
                "**现有研究的不足**:",
                *[f"• {gap}" for gap in analysis_result.get('research_gap', ['研究空白待提取'])],
                "",
                "**本研究的理论假设**:",
                *[f"• {hypo}" for hypo in analysis_result.get('hypothesis', ['假设待提取'])]
            ],
            notes="明确指出现有研究的gap，以及本研究如何解决",
            layout="content"
        )
        problem_slides.append(problem_slide2)
    
    # ========== 第二部分：方法 (2-3页) ==========
    method_slides = []
    
    # 方法第1页：总体设计
    method_slide1 = SlideContent(
        title="研究方法概述",
        bullets=[
            "**实验设计**:",
            *[f"• {design}" for design in analysis_result.get('experimental_design', ['实验设计待提取'])],
            "",
            "**被试/样本**:",
            f"• {analysis_result.get('participants', '被试信息待提取')}",
            "",
            "**核心变量**:",
            f"• 自变量: {analysis_result.get('independent_variables', '待提取')}",
            f"• 因变量: {analysis_result.get('dependent_variables', '待提取')}"
        ],
        notes="介绍实验的整体设计框架",
        layout="content"
    )
    method_slides.append(method_slide1)
    
    # 方法第2页：实验流程
    method_slide2 = SlideContent(
        title="实验流程",
        bullets=[
            "**实验步骤**:",
            *[f"{i+1}. {step}" for i, step in enumerate(analysis_result.get('procedure', ['步骤待提取']))],
            "",
            "**控制变量**:",
            *[f"• {control}" for control in analysis_result.get('control_variables', ['控制变量待提取'])]
        ],
        notes="详细说明实验如何进行，以及如何控制混淆变量",
        layout="content"
    )
    method_slides.append(method_slide2)
    
    # 方法第3页：方法-理论对应（如果需要）
    if analysis_result.get('method_theory_mapping'):
        method_slide3 = SlideContent(
            title="实验设计的理论依据",
            bullets=[
                "**实验设计如何验证假设**:",
                *[f"• {mapping}" for mapping in analysis_result.get('method_theory_mapping', [])],
                "",
                "**关键操作的理论意义**:",
                *[f"• {significance}" for significance in analysis_result.get('operational_significance', [])]
            ],
            notes="解释为什么这样设计实验，如何对应理论假设",
            layout="content"
        )
        method_slides.append(method_slide3)
    
    # ========== 第三部分：结论与验证 (多页) ==========
    result_slides = []
    
    # 主要发现（每页一个主要发现）
    main_findings = analysis_result.get('main_findings', ['主要发现待提取'])
    for i, finding in enumerate(main_findings):
        finding_slide = SlideContent(
            title=f"主要发现 {i+1}" if len(main_findings) > 1 else "主要发现",
            bullets=[
                f"**{finding}**",
                "",
                "**支持证据**:",
                *[f"• {evidence}" for evidence in analysis_result.get(f'evidence_{i}', ['证据待提取'])]
            ],
            notes=f"详细阐述第{i+1}个主要发现及其证据",
            layout="content"
        )
        result_slides.append(finding_slide)
    
    # 假设验证页
    hypothesis_validation = analysis_result.get('hypothesis_validation', [])
    if hypothesis_validation:
        validation_slide = SlideContent(
            title="假设验证结果",
            bullets=[
                "**假设检验**:",
                *[f"• {validation}" for validation in hypothesis_validation],
                "",
                "**结论逻辑链**:",
                *[f"→ {logic}" for logic in analysis_result.get('conclusion_logic', ['逻辑链待提取'])]
            ],
            notes="清晰展示每个假设是否被验证，以及验证的逻辑链条",
            layout="content"
        )
        result_slides.append(validation_slide)
    
    # ========== 第四部分：局限 (1页) ==========
    limitation_slide = SlideContent(
        title="研究局限与未来方向",
        bullets=[
            "**本研究的局限**:",
            *[f"• {limit}" for limit in analysis_result.get('limitations', ['局限待提取'])],
            "",
            "**未来研究方向**:",
            *[f"• {future}" for future in analysis_result.get('future_directions', ['未来方向待提取'])]
        ],
        notes="诚实说明研究局限，同时指出未来可以改进的方向",
        layout="content"
    )
    
    # ========== 总结页 ==========
    summary_slide = SlideContent(
        title="总结",
        bullets=[
            f"**{title}**",
            "",
            "**核心贡献**:",
            *[f"• {contrib}" for contrib in analysis_result.get('contributions', ['贡献待提取'])]
        ],
        notes="简洁总结研究的核心贡献",
        layout="content"
    )
    
    return PresentationStructure(
        title=title,
        authors=authors,
        venue=venue,
        year=year,
        problem_slides=problem_slides,
        method_slides=method_slides,
        result_slides=result_slides,
        limitation_slide=limitation_slide,
        summary_slide=summary_slide
    )


def structure_to_json(structure: PresentationStructure) -> Dict[str, Any]:
    """将PPT结构转换为JSON格式"""
    return {
        "title": structure.title,
        "authors": structure.authors,
        "venue": structure.venue,
        "year": structure.year,
        "slides": {
            "part1_problem": [asdict(slide) for slide in structure.problem_slides],
            "part2_method": [asdict(slide) for slide in structure.method_slides],
            "part3_results": [asdict(slide) for slide in structure.result_slides],
            "part4_limitations": asdict(structure.limitation_slide),
            "summary": asdict(structure.summary_slide)
        },
        "total_slides": (
            len(structure.problem_slides) +
            len(structure.method_slides) +
            len(structure.result_slides) +
            2  # limitations + summary
        )
    }


def main():
    """主函数 - 从JSON输入生成PPT结构"""
    if len(sys.argv) < 2:
        print("Usage: python generate_ppt_structure.py <analysis_json_file>")
        sys.exit(1)
    
    # 读取分析结果
    with open(sys.argv[1], 'r', encoding='utf-8') as f:
        analysis_result = json.load(f)
    
    # 生成PPT结构
    structure = create_ppt_structure(analysis_result)
    
    # 输出JSON
    output = structure_to_json(structure)
    
    # 处理Windows控制台编码问题
    import io
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
    print(json.dumps(output, ensure_ascii=False, indent=2))


if __name__ == "__main__":
    main()


path: references/analysis_guide.md
content: # 文献分析指南

本文档指导如何从学术文献中提取关键信息用于PPT生成。

## 分析框架

### 1. 基本信息提取

```json
{
  "title": "论文标题",
  "authors": "作者列表",
  "venue": "期刊或会议名称",
  "year": "发表年份"
}
```

### 2. 科学问题与背景 (Part 1)

#### 研究问题识别
- 论文试图回答什么核心问题？
- 这个问题为什么重要？
- 问题属于哪个研究领域？

#### 背景信息提取
- 该领域的基本概念是什么？
- 相关的理论基础有哪些？
- 当前领域的发展状况？

#### 前人工作梳理
- 已有研究解决了什么？
- 使用了什么方法？
- 得出了什么结论？

#### 研究空白识别
- 前人工作有什么不足？
- 哪些问题还没有被回答？
- 现有理论的缺陷是什么？

#### 理论假设
- 本研究提出了什么假设？
- 假设基于什么理论？
- 假设如何可以被验证？

### 3. 研究方法 (Part 2)

#### 实验设计
- 采用什么研究设计？（实验/准实验/相关/纵向等）
- 自变量是什么？如何操纵？
- 因变量是什么？如何测量？
- 是否有控制组？

#### 被试/样本
- 样本量是多少？
- 被试的人口学特征？
- 如何招募和筛选？

#### 实验流程
- 实验的具体步骤？
- 每个阶段做什么？
- 时间线是怎样的？

#### 控制变量
- 控制了哪些混淆变量？
- 如何控制的？
- 为什么控制这些变量？

#### 方法-理论对应
- 实验设计如何验证假设？
- 每个操作的理论意义？
- 测量指标如何反映构念？

### 4. 结论与验证 (Part 3)

#### 主要发现
- 发现了什么？
- 统计结果是什么？
- 效应量有多大？

#### 证据支持
- 什么数据支持这个发现？
- 图表显示了什么？
- 统计检验结果？

#### 假设验证
- 每个假设是否被支持？
- 支持/不支持的证据？
- 部分支持的情况？

#### 结论逻辑
- 从数据到结论的逻辑链？
- 排除了哪些替代解释？
- 结论的可靠性如何？

### 5. 研究局限 (Part 4)

#### 方法局限
- 样本是否有代表性？
- 测量是否有局限？
- 实验设计是否有缺陷？

#### 结果局限
- 结果能否推广？
- 效应是否稳定？
- 是否有未控制的变量？

#### 未来方向
- 如何改进研究？
- 下一步研究建议？
- 可以扩展的方向？

## 提取技巧

### 阅读顺序
1. 先读摘要，了解整体框架
2. 读引言，理解问题和背景
3. 读方法，了解实验设计
4. 读结果，提取主要发现
5. 读讨论，理解结论和局限

### 关键句识别
- 问题陈述："本文旨在..." "本研究探讨..."
- 假设陈述："我们假设..." "基于...理论，我们预测..."
- 方法描述："采用...设计" "被试为..."
- 结果陈述："结果显示..." "发现..."
- 结论陈述："这些结果表明..." "本研究证实..."

### 信息组织原则
- 简洁优先：每页PPT不超过6个要点
- 逻辑清晰：按时间或逻辑顺序组织
- 重点突出：强调核心发现和贡献
- 图文配合：建议添加关键图表

## 输出格式

分析结果应为JSON格式，包含上述所有字段。详见示例文件。


path: references/example_analysis.json
content: {
  "title": "示例研究：社交媒体使用对青少年心理健康的影响",
  "authors": "张三, 李四, 王五",
  "venue": "Journal of Adolescent Psychology",
  "year": "2024",
  
  "research_question": "社交媒体使用时长和方式如何影响青少年的抑郁和焦虑症状？",
  
  "background": [
    "青少年是社交媒体的主要用户群体，日均使用时长超过3小时",
    "已有研究表明社交媒体使用与心理健康问题存在关联",
    "但因果关系尚不明确，机制有待探索"
  ],
  
  "previous_work": [
    "横断面研究发现社交媒体使用与抑郁症状正相关 (Smith et al., 2020)",
    "实验研究显示限制社交媒体使用可改善幸福感 (Jones et al., 2021)",
    "纵向研究揭示了使用时长与心理健康问题的双向关系 (Brown et al., 2022)"
  ],
  
  "research_gap": [
    "前人研究多关注使用时长，忽视了使用方式（主动vs被动）的影响",
    "缺乏对中介机制（如社会比较、睡眠）的系统检验",
    "样本多来自西方国家，中国文化背景下的证据不足"
  ],
  
  "hypothesis": [
    "H1: 被动性社交媒体使用（浏览他人动态）比主动性使用（发布内容）更 negatively 预测心理健康",
    "H2: 社会比较在社交媒体使用与心理健康之间起中介作用",
    "H3: 睡眠质量调节社交媒体使用对心理健康的影响"
  ],
  
  "experimental_design": [
    "采用纵向追踪设计，测量3个时间点（T1, T2, T3，间隔6个月）",
    "结合经验抽样法（ESM），连续14天每日多次测量",
    "使用交叉滞后面板模型分析因果关系"
  ],
  
  "participants": "N = 800名初中生（年龄12-15岁，M = 13.4, SD = 0.9），来自5所城市中学",
  
  "independent_variables": "社交媒体使用时长、主动/被动使用比例、使用情境",
  
  "dependent_variables": "抑郁症状（CES-D量表）、焦虑症状（GAD-7量表）、主观幸福感",
  
  "procedure": [
    "T1基线测量：问卷调查人口学变量、社交媒体使用习惯、心理健康基线",
    "ESM阶段：连续14天，每天3次随机推送问卷，测量当下社交媒体使用和情绪",
    "T2和T3随访：重复心理健康测量，追踪变化轨迹",
    "数据整合：将ESM数据与问卷数据匹配，进行多层次分析"
  ],
  
  "control_variables": [
    "基线心理健康水平：控制T1时的抑郁/焦虑分数",
    "人口学变量：性别、年龄、家庭经济状况",
    "其他媒体使用：电视观看时间、电子游戏时间",
    "社会支持：感知到的家庭和朋友支持"
  ],
  
  "method_theory_mapping": [
    "纵向设计验证因果关系：通过交叉滞后分析，检验社交媒体使用是否先于心理健康变化",
    "ESM方法捕捉真实使用情境：避免回顾性报告的偏差，获得生态效度更高的数据",
    "主动/被动使用区分：基于使用-满足理论，检验不同使用动机的差异化影响"
  ],
  
  "operational_significance": [
    "社会比较测量：采用向上/向下社会比较量表，对应社会比较理论",
    "睡眠质量评估：使用匹兹堡睡眠质量指数（PSQI），捕捉睡眠的多维特征",
    "情绪测量：PANAS量表测量正负性情绪，对应情绪调节理论"
  ],
  
  "main_findings": [
    "被动性社交媒体使用显著预测6个月后的抑郁症状增加（β = 0.32, p < .001）",
    "社会比较中介了被动使用与抑郁的关系（间接效应 = 0.15, 95% CI [0.08, 0.23]）",
    "睡眠质量调节了社交媒体使用的影响（低睡眠质量组效应更强）"
  ],
  
  "evidence_0": [
    "交叉滞后面板模型显示，T1的被动使用预测T2的抑郁（β = 0.28），但反向路径不显著",
    "效应在控制基线抑郁后仍然显著",
    "敏感性分析排除了第三方变量解释"
  ],
  
  "evidence_1": [
    "Bootstrap检验显示中介效应显著",
    "向上社会比较的效应（β = 0.18）大于向下社会比较（β = -0.05）",
    "中介效应占总效应的47%"
  ],
  
  "evidence_2": [
    "多层次模型显示使用×睡眠质量的交互项显著（β = -0.22, p < .01）",
    "简单斜率分析：低睡眠质量组斜率 = 0.41，高睡眠质量组斜率 = 0.12",
    "Johnson-Neyman法确定了调节作用的显著区域"
  ],
  
  "hypothesis_validation": [
    "H1得到支持：被动使用比主动使用对心理健康的负面影响更大",
    "H2得到支持：社会比较的中介作用得到验证",
    "H3得到支持：睡眠质量显著调节主效应"
  ],
  
  "conclusion_logic": [
    "被动使用导致频繁的社会比较",
    "向上社会比较引发负面情绪和自我贬低",
    "长期积累导致抑郁症状增加",
    "良好的睡眠质量可以缓冲这种负面影响"
  ],
  
  "limitations": [
    "样本仅来自城市地区，农村青少年的情况可能不同",
    "ESM依从率为78%，可能存在选择性偏差",
    "未能完全排除基因和家庭环境的混淆",
    "社交媒体平台快速迭代，结果的时效性有限"
  ],
  
  "future_directions": [
    "扩展样本范围，纳入更多样化的青少年群体",
    "开发针对性的干预方案，减少被动使用和社会比较",
    "探索其他可能的保护性因素（如媒体素养）",
    "开展实验研究进一步验证因果关系"
  ],
  
  "contributions": [
    "首次在中国青少年群体中系统检验社交媒体使用的心理健康效应",
    "揭示了使用方式（主动vs被动）的差异化影响机制",
    "识别了社会比较和睡眠质量作为关键的中介和调节变量",
    "为青少年心理健康干预提供了实证依据"
  ]
}


path: assets/template_readme.md
content: # PPT模板说明

本Skill使用代码自动生成PPT，不需要预定义模板文件。

## 生成的PPT特点

### 视觉设计
- **配色方案**: 学术蓝绿色系 (#1a5f7a, #57a0d3, #f4a261)
- **版式**: 16:9 宽屏比例
- **字体**: 使用系统默认字体，确保兼容性

### 页面结构
1. **标题页** - 论文标题、作者、期刊、年份
2. **章节分隔页** - 四大部分清晰分隔
3. **内容页** - 要点式布局，支持演讲者备注

### 章节安排
- **Part 1**: 科学问题与背景 (1-2页)
- **Part 2**: 研究方法 (2-3页)
- **Part 3**: 结论与验证 (多页)
- **Part 4**: 局限与展望 (1页)
- **总结页**: 核心贡献

## 自定义建议

如需调整样式，可修改 `scripts/export_ppt.py` 中的:
- `COLORS` 字典 - 修改配色
- 字体大小参数 - 调整文字尺寸
- 布局尺寸 - 修改页面元素位置


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)