Skill: vigorouspp/auto-citation (version 1.0.0)

--- name: auto-citation description: | 自动为学术文章添加参考文献。解析文章内容提取主题和关键词， 调用 academic-search 检索相关论文，推荐候选文献供用户确认， 自动插入格式化的引用。支持 Markdown/LaTeX/Word 输入， 输出 BibTeX/GB/T 7714/APA 格式。当用户说"帮我加参考文献"、 "给这篇文章找引用"或处理 .md/.tex/.docx 文件时触发。 --- # 自动添加参考文献 ## 触发检测 检测以下信号时激活本 Skill： **意图信号（中文）** - "加参考文献"/"添加引用"/"找相关论文" - "补充文献"/"完善参考文献" - "给这段话加引用" **意图信号（英文）** - "add citations"/"find references" - "complete bibliography" **文件信号** - 扩展名：`.md` / `.tex` / `.docx` - 内容特征：已有正文但引用不足或缺失 --- ## 前置依赖 ### 必需依赖 本 Skill 依赖 academic-search Skill 进行论文检索。 **安装命令**： ```bash git clone https://github.com/ustc-ai4science/academic-search ~/.cursor/skills/academic-search bash ~/.cursor/skills/academic-search/scripts/check-deps.sh ``` ### Python 依赖 ```bash pip install python-docx textract ``` --- ## 工作流程 ### Step 1: 解析文档 运行解析脚本提取文档关键信息： ```bash python ~/.cursor/skills/auto-citation/scripts/parse_document.py <文件路径> ``` **输出内容**： - 文档类型（markdown/latex/word） - 主题摘要（TL;DR） - 关键词列表（3-7 个核心术语） - 现有引用列表（避免重复推荐） - 建议检索方向（2-4 个互补 query） ### Step 2: 生成搜索策略 基于解析结果，生成 2-4 个互补搜索 query： **策略原则**： - 覆盖核心概念（主要方法/技术） - 覆盖应用场景（domain-specific） - 覆盖 baseline 对比（相关经典工作） - 近 5 年优先（时效性优先） ### Step 3: 并行检索 调用 academic-search Skill 执行多 query 搜索： ``` 子 Agent 任务分发： ├── Query 1: "graph neural network time series" → arXiv + S2 ├── Query 2: "GNN temporal data prediction" → arXiv + S2 ├── Query 3: "time series forecasting deep learning" → Google Scholar └── 合并结果，DOI/arXiv ID 去重 ``` **搜索参数**： - 年份范围：近 5 年（或用户指定） - 排序：时效性优先 → 引用数 → CCF 等级 - 数量：每 query 取前 10 篇 ### Step 4: 去重与筛选 **去重规则**（按优先级）： 1. DOI 精确匹配 2. arXiv ID 匹配 3. 标题 + 年份 + 第一作者匹配 **筛选逻辑**： - 排除已存在的引用 - 按相关性 + 引用数 + 时效性排序 - 保留前 8-12 篇作为候选池 ### Step 5: 推荐候选 向用户展示候选列表，格式如下： ``` 基于你的文章主题（GNN 时间序列预测），我找到以下相关论文： [1] Title A - 被引 150 次 (2023) 作者：Author A, Author B 相关点：与你第 2 节的方法直接相关，可作为主要对比 baseline [2] Title B - 被引 89 次 (2024) [新] 作者：Author C et al. 相关点：最新 SOTA 方法，建议作为主要引用 [3] Title C - 被引 320 次 (2021) 作者：Author D 相关点：领域经典工作，适合引言背景介绍 请输入你想引用的编号（如：1,3,5），或： - 输入 "更多" 查看下一批候选 - 输入 "调整" 修改搜索方向 - 输入特定需求（如："找几篇中文文献"） ``` ### Step 6: 格式化与插入 **格式选择**（按以下优先级）： 1. 用户明确指定（"用 GB/T 7714 格式"） 2. 文件内标记（`<!-- citation-style: bibtex -->`） 3. 环境变量（`AUTO_CITATION_STYLE=gb7714`） 4. 根据文件类型推断（.tex → BibTeX, .docx → GB7714） **格式化命令**： ```bash python ~/.cursor/skills/auto-citation/scripts/format_citation.py \ --style {bibtex|gb7714|apa} \ --papers <papers.json> \ --output <输出路径> ``` **插入命令**： ```bash python ~/.cursor/skills/auto-citation/scripts/insert_citation.py \ --document <原文路径> \ --citations <引用文件> \ --output <输出路径> ``` --- ## 引用格式说明 ### BibTeX 格式 适用于 LaTeX 文档。 **文件组织**： - 生成/更新 `.bib` 文件 - 原文使用 `\cite{key}` 标记 - 支持 `\bibliographystyle` 自定义样式 **示例输出**： ```bibtex @inproceedings{wang2023gnn, title={Graph Neural Networks for Time Series Prediction}, author={Wang, X. and Li, Y.}, booktitle={NeurIPS}, year={2023} } ``` ### GB/T 7714 格式 适用于中文论文和学位论文。 **文中引用**：上标 `[1]` 或 `[1-3]` **文末列表**：按引用顺序编号 **示例输出**： ``` [1] Wang X, Li Y. Graph Neural Networks for Time Series Prediction[C]. NeurIPS, 2023. [2] Zhang S. Deep Learning Methods[J]. Journal of AI, 2024, 10(2): 100-120. ``` ### APA 格式 适用于社会科学和国际期刊。 **文中引用**：作者-年份制 `(Wang & Li, 2023)` **文末列表**：按作者字母排序 **示例输出**： ``` Wang, X., & Li, Y. (2023). Graph neural networks for time series prediction. In NeurIPS (pp. 1000-1010). ``` --- ## 用户交互模式 ### 模式一：全自动推荐 用户未指定具体需求时，AI 自主完成全部流程。 ### 模式二：定向补充 用户指定特定位置或主题： - "给引言加几篇背景文献" - "实验部分需要 baseline 引用" - "找几篇用 Transformer 做时间序列的论文" ### 模式三：精确匹配 用户提供部分信息： - "我记得有一篇 NeurIPS 2023 的 GNN 论文" - "找这篇论文的完整引用：arxiv:2401.12345" --- ## 质量检查清单 每次执行后自我检查： - [ ] 推荐的引用是否与文章主题相关 - [ ] 是否避免了重复引用 - [ ] 引用格式是否符合用户要求 - [ ] 年份分布是否合理（既有经典又有最新） - [ ] 引用位置标注是否正确（文中标记与文末列表对应） --- ## 错误处理 **情况 1: 文档解析失败** - 尝试用通用方法提取纯文本 - 询问用户文章主题关键词 - 基于关键词手动生成 query **情况 2: 搜索结果为空** - 放宽年份限制 - 简化 query（去掉太具体的限制） - 尝试不同平台（尤其是 CNKI 中文文献） **情况 3: 用户不满意推荐** - 询问具体需求（"需要 baseline 还是最新工作？"） - 调整搜索方向 - 扩大或缩小关键词范围 --- ## 相关文件 - 文档解析说明：[references/parser-guide.md](references/parser-guide.md) - 引用格式规范：[references/citation-styles.md](references/citation-styles.md) - 使用示例：[references/workflow-examples.md](references/workflow-examples.md)

path: README.md
content: # Auto-Citation Skill

自动为学术文章添加参考文献的 Cursor Skill。基于 [academic-search](https://github.com/ustc-ai4science/academic-search) 能力，实现智能解析、精准检索、自动格式化和无缝插入。

---

## 核心功能

**智能解析**
- 自动识别 Markdown / LaTeX / Word (.docx) 文档
- 提取主题关键词和核心概念
- 检测现有引用避免重复

**精准检索**
- 调用 academic-search 8 大平台（arXiv、Semantic Scholar、Google Scholar、CNKI 等）
- 多 query 并行搜索，覆盖率提升 30-50%
- 时效性优先排序（近 6 月论文置顶）

**多格式支持**
- **BibTeX**：LaTeX 文档，兼容各类 bibliography style
- **GB/T 7714**：中文论文标准格式
- **APA**：国际期刊常用格式

**无缝插入**
- Markdown：文末自动生成参考文献章节
- LaTeX：生成 .bib 文件或 thebibliography 环境
- Word：文档末尾添加格式化引用列表

---

## 快速开始

### 1. 安装依赖

```bash
# 安装 academic-search skill（必需依赖）
git clone https://github.com/ustc-ai4science/academic-search ~/.cursor/skills/academic-search
bash ~/.cursor/skills/academic-search/scripts/check-deps.sh

# 安装 auto-citation skill
git clone https://github.com/yourusername/auto-citation ~/.cursor/skills/auto-citation

# 安装 Python 依赖
pip install python-docx
```

### 2. 使用方式

在 Cursor 中直接说：

```
帮我给这篇论文加一些参考文献
```

或指定具体需求：

```
给引言部分找几篇 GNN 相关背景文献，用 BibTeX 格式
```

```
给这个 Word 文档添加 5 篇时间序列预测的最新论文
```

---

## 工作流程

```
┌─────────────┐     ┌──────────────┐     ┌──────────────┐
│  用户输入   │────▶│  解析文档    │────▶│ 生成搜索策略 │
│             │     │              │     │              │
└─────────────┘     └──────────────┘     └──────────────┘
                                                  │
                                                  ▼
┌─────────────┐     ┌──────────────┐     ┌──────────────┐
│  完成输出   │◄────│ 格式化与插入 │◄────│ 用户确认    │
│             │     │              │     │ 候选推荐    │
└─────────────┘     └──────────────┘     └──────────────┘
                                                  ▲
                                                  │
                                           ┌──────────────┐
                                           │ academic-search│
                                           │  并行检索    │
                                           └──────────────┘
```

---

## 使用示例

### 示例 1：完善学术论文

**用户输入**：
```
帮我给这篇 LaTeX 论文的引言部分加一些背景文献
```

**AI 执行**：
1. 解析 .tex 文件，提取主题"graph neural network time series"
2. 生成多个互补搜索 query
3. 调用 academic-search 检索相关论文
4. 展示候选列表：

```
基于你的引言内容，找到以下相关背景文献：

[1] Spatio-Temporal Graph Neural Networks - 被引 320 次 (2021)
    相关点：全面的 GNN 综述，适合作为领域背景
    
[2] Graph WaveNet - 被引 450 次 (2019)
    相关点：交通预测的 GNN 经典工作

请输入你想引用的编号（如：1,2）：
```

5. 用户确认后，生成 BibTeX 并插入 `\cite{}` 命令

### 示例 2：技术博客引用

**用户输入**：
```
给这篇 Markdown 博客添加 Transformer 和 BERT 的引用
```

**AI 执行**：
1. 识别关键论文需求：Attention is All You Need、BERT
2. 直接检索 arXiv 获取完整元数据
3. 生成 GB/T 7714 格式引用
4. 插入到文章末尾

### 示例 3：Baseline 引用补充

**用户输入**：
```
给实验部分的 baseline 方法添加引用，包括 LSTM、GRU、Transformer
```

**AI 执行**：
1. 精准检索各 baseline 的原始论文
2. 生成格式统一的引用列表
3. 在正文中添加对应的 `\cite{}` 标记

---

## 脚本工具独立使用

### parse_document.py - 文档解析

```bash
python scripts/parse_document.py paper.md
```

输出文档类型、关键词、建议搜索 query 等 JSON 格式信息。

### format_citation.py - 引用格式化

```bash
# BibTeX 格式
python scripts/format_citation.py \
  --style bibtex \
  --papers papers.json \
  --output references.bib

# GB/T 7714 格式
python scripts/format_citation.py \
  --style gb7714 \
  --papers papers.json \
  --output references.txt

# APA 格式（含文中标记）
python scripts/format_citation.py \
  --style apa \
  --papers papers.json \
  --with-markers \
  --output references.txt
```

### insert_citation.py - 引用插入

```bash
# Markdown
python scripts/insert_citation.py \
  --document article.md \
  --citations references.txt \
  --output article_with_refs.md

# LaTeX
python scripts/insert_citation.py \
  --document paper.tex \
  --citations references.bib \
  --style bibtex

# Word
python scripts/insert_citation.py \
  --document report.docx \
  --citations references.txt
```

---

## 项目结构

```
auto-citation/
├── SKILL.md                      # 主指令文件（Cursor 自动加载）
├── README.md                     # 本文件
├── scripts/
│   ├── parse_document.py         # 文档解析器
│   ├── format_citation.py        # 引用格式化工具
│   └── insert_citation.py        # 引用插入工具
└── references/
    ├── citation-styles.md        # 引用格式规范速查
    └── workflow-examples.md      # 使用场景示例
```

---

## 配置选项

### 引用格式选择

**优先级**（从高到低）：

1. 用户明确指定：`"用 GB/T 7714 格式"`
2. 文件内标记：`<!-- citation-style: bibtex -->`
3. 环境变量：`export AUTO_CITATION_STYLE=gb7714`
4. 文件类型推断：`.tex → BibTeX`, `.docx → GB7714`

### 环境变量

```bash
# 默认引用格式
export AUTO_CITATION_STYLE=bibtex  # 可选: bibtex, gb7714, apa

# 搜索年份范围
export AUTO_CITATION_YEAR_RANGE=5   # 近 5 年

# 推荐候选数量
export AUTO_CITATION_CANDIDATES=8
```

---

## 依赖关系

本 Skill 依赖 [academic-search](https://github.com/ustc-ai4science/academic-search) 进行论文检索。

```
auto-citation
    └── academic-search (必需)
        ├── arXiv API
        ├── Semantic Scholar API
        ├── Google Scholar (CDP 浏览器)
        └── CNKI (CDP 浏览器)
```

---

## 支持的文档格式

| 格式 | 扩展名 | 支持程度 | 备注 |
|------|--------|---------|------|
| Markdown | .md | 完全支持 | 推荐 |
| LaTeX | .tex | 完全支持 | BibTeX/thebibliography |
| Word | .docx | 完全支持 | 需 python-docx |
| 纯文本 | .txt | 部分支持 | 提取纯文本 |

---

## 支持的引用格式

| 格式 | 适用场景 | 文中标记 | 文末列表 |
|------|---------|---------|---------|
| **BibTeX** | LaTeX 文档 | `\cite{key}` | .bib 文件 |
| **GB/T 7714** | 中文论文 | `[1], [2]` | 按序号排列 |
| **APA** | 国际期刊 | `(Author, Year)` | 按作者字母排序 |

---

## 相关文档

- [引用格式规范](references/citation-styles.md) - BibTeX/GB7714/APA 详细说明
- [使用场景示例](references/workflow-examples.md) - 6 个典型使用场景
- [academic-search 文档](https://github.com/ustc-ai4science/academic-search) - 底层检索能力

---

## 常见问题

### Q1: 如何确保能找到相关论文？

**A**: 
1. 提供清晰的文章主题或摘要
2. 如搜索结果不理想，可调整关键词或放宽时间范围
3. 指定具体平台（如"找几篇 CVPR 的论文"）

### Q2: 引用格式不正确怎么办？

**A**:
1. 明确指定格式：`"用 GB/T 7714 格式"`
2. 在文件开头添加注释标记：`<!-- citation-style: gb7714 -->`
3. 使用 `format_citation.py` 重新格式化

### Q3: 如何避免重复引用？

**A**: 
- 工具会自动检测文档中已有的引用（DOI/arXiv ID/标题匹配）
- 推荐列表中不会显示已存在的论文

### Q4: 支持批量处理多个文档吗？

**A**: 
- 当前版本支持单文档处理
- 可使用脚本工具批量处理：`for f in *.md; do python scripts/...; done`

---

## 设计理念

> **Skill = 哲学 + 技术事实**

auto-citation 遵循以下设计原则：

1. **人机协作**：AI 负责检索和格式化，用户负责最终确认
2. **灵活输出**：支持多种引用格式，适应不同场景
3. **无缝集成**：与 academic-search 深度集成，复用其平台能力
4. **渐进增强**：基础版本覆盖核心场景，可扩展支持更多格式

---

## 贡献与反馈

欢迎提交 Issue 和 PR：
- 新增引用格式支持
- 改进解析器准确度
- 添加更多使用示例

---

## License

MIT License - 与 academic-search 保持一致

---

## 致谢

本 Skill 基于 [ustc-ai4science/academic-search](https://github.com/ustc-ai4science/academic-search) 构建，感谢其提供的强大检索能力。


path: scripts/insert_citation.py
content: #!/usr/bin/env python3
"""
引用插入工具：将格式化后的引用插入原文档
支持格式：Markdown / LaTeX / Word (.docx)
"""

import re
import sys
import os
import argparse
import shutil
from pathlib import Path
from typing import List, Dict, Optional


class CitationInserter:
    """引用插入基类"""
    
    def __init__(self, document_path: str, citations_path: str, output_path: Optional[str] = None):
        self.document_path = Path(document_path)
        self.citations_path = Path(citations_path)
        self.output_path = Path(output_path) if output_path else None
        self.citations = []
        self.style = 'gb7714'  # 默认格式
    
    def load_citations(self):
        """加载引用内容"""
        with open(self.citations_path, 'r', encoding='utf-8') as f:
            self.citations_text = f.read()
        
        # 自动检测格式
        if self.citations_text.startswith('@'):
            self.style = 'bibtex'
        elif any(re.search(r'\[\d+\]', line) for line in self.citations_text.split('\n')[:10]):
            self.style = 'gb7714'
        elif any('(' in line and ')' in line and any(year in line for year in ['2020', '2021', '2022', '2023', '2024']) for line in self.citations_text.split('\n')[:10]):
            self.style = 'apa'
    
    def insert(self):
        """插入引用（子类实现）"""
        raise NotImplementedError
    
    def backup_original(self):
        """备份原始文件"""
        backup_path = self.document_path.with_suffix(self.document_path.suffix + '.backup')
        shutil.copy2(self.document_path, backup_path)
        return backup_path


class MarkdownInserter(CitationInserter):
    """Markdown 文档引用插入器"""
    
    def __init__(self, document_path: str, citations_path: str, output_path: Optional[str] = None):
        super().__init__(document_path, citations_path, output_path)
    
    def insert(self):
        """在 Markdown 文档末尾插入参考文献"""
        # 备份
        self.backup_original()
        
        # 读取原文档
        with open(self.document_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        # 检查是否已有参考文献部分
        has_ref_section = re.search(r'^##?\s*(?:参考文献|References|Bibliography)', 
                                    content, re.MULTILINE | re.IGNORECASE)
        
        if has_ref_section:
            # 替换现有参考文献部分
            content = re.sub(
                r'^##?\s*(?:参考文献|References|Bibliography).*?(?=\n##|\Z)',
                f'## 参考文献\n\n{self.citations_text}',
                content,
                flags=re.DOTALL | re.MULTILINE | re.IGNORECASE
            )
        else:
            # 在文档末尾添加
            content = content.rstrip() + '\n\n## 参考文献\n\n' + self.citations_text
        
        # 写入文件
        output_path = self.output_path or self.document_path
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        return output_path
    
    def insert_inline_markers(self, marker_positions: List[int], marker_labels: List[str]):
        """在 Markdown 中插入文中引用标记 [1], [2] 等"""
        with open(self.document_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        
        # 简单的行级插入（更精确的插入需要段落定位）
        modified_lines = []
        citation_idx = 0
        
        for i, line in enumerate(lines):
            modified_lines.append(line)
            
            # 在段落末尾添加引用（简单策略）
            if i in marker_positions and citation_idx < len(marker_labels):
                # 如果行以标点结尾，在标点之前插入
                stripped = line.rstrip()
                if stripped and not stripped.endswith('```') and not stripped.startswith('#'):
                    label = marker_labels[citation_idx]
                    # 在行末尾添加引用标记
                    if stripped[-1] in '.!?;':
                        modified_lines[-1] = stripped[:-1] + f'[{label}]' + stripped[-1] + '\n'
                    else:
                        modified_lines[-1] = stripped + f'[{label}]\n'
                    citation_idx += 1
        
        output_path = self.output_path or self.document_path
        with open(output_path, 'w', encoding='utf-8') as f:
            f.writelines(modified_lines)
        
        return output_path


class LaTeXInserter(CitationInserter):
    """LaTeX 文档引用插入器"""
    
    def insert(self):
        """在 LaTeX 文档中插入引用"""
        self.backup_original()
        
        with open(self.document_path, 'r', encoding='utf-8') as f:
            content = f.read()
        
        if self.style == 'bibtex':
            return self._insert_bibtex(content)
        else:
            return self._insert_thebibliography(content)
    
    def _insert_bibtex(self, content: str):
        """使用 BibTeX 方式"""
        # 提取 .bib 文件路径
        bib_match = re.search(r'\\bibliography\{([^}]+)\}', content)
        
        if bib_match:
            # 更新现有 .bib 文件
            bib_file = bib_match.group(1)
            if not bib_file.endswith('.bib'):
                bib_file += '.bib'
            
            # 构建完整路径
            bib_path = self.document_path.parent / bib_file
            
            # 追加或创建 .bib 文件
            with open(bib_path, 'a', encoding='utf-8') as f:
                f.write('\n\n% Added by auto-citation on ' + str(Path(__file__).stat().st_mtime) + '\n')
                f.write(self.citations_text)
            
            output_path = self.output_path or self.document_path
            shutil.copy2(self.document_path, output_path)
            
        else:
            # 没有 \bibliography 命令，需要添加
            # 在 \end{document} 之前添加
            citations_file = self.document_path.stem + '_references.bib'
            bib_path = self.document_path.parent / citations_file
            
            # 写入 .bib 文件
            with open(bib_path, 'w', encoding='utf-8') as f:
                f.write(self.citations_text)
            
            # 修改 .tex 文件添加引用命令
            # 在 \end{document} 之前添加 \bibliography 和 \bibliographystyle
            new_content = re.sub(
                r'(\\end\{document\})',
                f'\\bibliographystyle{{plain}}\n\\bibliography{{{self.document_path.stem}_references}}\n\n\\1',
                content
            )
            
            output_path = self.output_path or self.document_path
            with open(output_path, 'w', encoding='utf-8') as f:
                f.write(new_content)
        
        return output_path
    
    def _insert_thebibliography(self, content: str):
        """使用 thebibliography 环境（GB7714/APA 等非 BibTeX 格式）"""
        # 检查是否已有 thebibliography
        has_biblio = re.search(r'\\begin\{thebibliography\}', content)
        
        if has_biblio:
            # 替换现有环境
            content = re.sub(
                r'\\begin\{thebibliography\}.*?\\end\{thebibliography\}',
                f'\\begin{{thebibliography}}{{99}}\n\\small\n\n{self.citations_text}\n\\end{{thebibliography}}',
                content,
                flags=re.DOTALL
            )
        else:
            # 在 \end{document} 之前添加
            new_content = re.sub(
                r'(\\end\{document\})',
                f'\\begin{{thebibliography}}{{99}}\n\\small\n\n{self.citations_text}\n\\end{{thebibliography}}\n\n\\1',
                content
            )
            content = new_content
        
        output_path = self.output_path or self.document_path
        with open(output_path, 'w', encoding='utf-8') as f:
            f.write(content)
        
        return output_path
    
    def insert_cite_commands(self, cite_keys: List[str], positions: List[int]):
        """在 LaTeX 中插入 \cite{} 命令"""
        with open(self.document_path, 'r', encoding='utf-8') as f:
            lines = f.readlines()
        
        # 简单的行级插入
        modified_lines = []
        cite_idx = 0
        
        for i, line in enumerate(lines):
            modified_lines.append(line)
            
            if i in positions and cite_idx < len(cite_keys):
                # 在段落末尾添加 \cite{}
                stripped = line.rstrip()
                if stripped and not stripped.startswith('%') and not stripped.startswith('\\'):
                    key = cite_keys[cite_idx]
                    if stripped[-1] in '.!?':
                        modified_lines[-1] = stripped[:-1] + f'~\\\\cite{{{key}}}' + stripped[-1] + '\n'
                    else:
                        modified_lines[-1] = stripped + f'~\\\\cite{{{key}}}\n'
                    cite_idx += 1
        
        output_path = self.output_path or self.document_path
        with open(output_path, 'w', encoding='utf-8') as f:
            f.writelines(modified_lines)
        
        return output_path


class WordInserter(CitationInserter):
    """Word 文档引用插入器"""
    
    def insert(self):
        """在 Word 文档末尾插入参考文献"""
        try:
            from docx import Document
            from docx.shared import Pt
            from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
        except ImportError:
            print("Error: python-docx not installed. Run: pip install python-docx", file=sys.stderr)
            sys.exit(1)
        
        # 备份
        self.backup_original()
        
        # 打开文档
        doc = Document(self.document_path)
        
        # 添加参考文献标题
        doc.add_heading('参考文献', level=1)
        
        # 添加引用内容
        for line in self.citations_text.strip().split('\n'):
            if line.strip():
                p = doc.add_paragraph(line)
                p.paragraph_format.line_spacing = 1.15
                # 首行缩进
                p.paragraph_format.first_line_indent = Pt(0)
        
        # 保存
        output_path = self.output_path or self.document_path
        doc.save(output_path)
        
        return output_path


def detect_file_type(file_path: str) -> str:
    """检测文件类型"""
    ext = Path(file_path).suffix.lower()
    if ext == '.md':
        return 'markdown'
    elif ext in ['.tex', '.latex']:
        return 'latex'
    elif ext == '.docx':
        return 'word'
    return 'unknown'


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='Insert citations into documents')
    parser.add_argument('--document', type=str, required=True,
                       help='Path to the document file')
    parser.add_argument('--citations', type=str, required=True,
                       help='Path to the formatted citations file')
    parser.add_argument('--output', type=str,
                       help='Output file path (default: overwrite original)')
    parser.add_argument('--style', choices=['bibtex', 'gb7714', 'apa'],
                       help='Citation style (auto-detected if not specified)')
    
    args = parser.parse_args()
    
    # 检查文件存在
    if not os.path.exists(args.document):
        print(f"Error: Document file not found: {args.document}", file=sys.stderr)
        sys.exit(1)
    
    if not os.path.exists(args.citations):
        print(f"Error: Citations file not found: {args.citations}", file=sys.stderr)
        sys.exit(1)
    
    # 检测文件类型
    file_type = detect_file_type(args.document)
    
    # 选择插入器
    inserter_map = {
        'markdown': MarkdownInserter,
        'latex': LaTeXInserter,
        'word': WordInserter,
    }
    
    inserter_class = inserter_map.get(file_type)
    if not inserter_class:
        print(f"Error: Unsupported file type: {file_type}", file=sys.stderr)
        sys.exit(1)
    
    # 创建插入器并执行
    inserter = inserter_class(args.document, args.citations, args.output)
    inserter.load_citations()
    
    # 如果指定了 style，覆盖自动检测的
    if args.style:
        inserter.style = args.style
    
    output_path = inserter.insert()
    
    print(f"Citations inserted successfully.")
    print(f"Output file: {output_path}")
    print(f"Citation style: {inserter.style}")
    
    # 显示摘要
    print(f"\nInserted {len(inserter.citations_text.strip().split(chr(10)))} lines of citations.")


if __name__ == '__main__':
    main()


path: scripts/format_citation.py
content: #!/usr/bin/env python3
"""
引用格式化工具：将论文元数据转换为各种引用格式
支持格式：BibTeX / GB/T 7714 / APA
"""

import json
import re
import sys
import argparse
from typing import Dict, List, Optional
from datetime import datetime


class CitationFormatter:
    """引用格式化基类"""
    
    def __init__(self, papers: List[Dict]):
        self.papers = papers
        self.citation_key_map = {}  # 用于去重 key
    
    def format_all(self) -> str:
        """格式化所有论文"""
        raise NotImplementedError
    
    def _generate_key(self, paper: Dict) -> str:
        """生成唯一引用 key"""
        # 使用作者姓氏 + 年份
        authors = paper.get('authors', [])
        year = str(paper.get('year', 'unknown'))
        
        if authors:
            # 取第一作者的姓氏
            first_author = authors[0]
            last_name = first_author.split()[-1] if isinstance(first_author, str) else first_author.get('name', '').split()[-1]
            last_name = re.sub(r'[^a-zA-Z]', '', last_name).lower()
            
            key = f"{last_name}{year}"
            
            # 处理重复 key
            base_key = key
            counter = 1
            while key in self.citation_key_map.values():
                key = f"{base_key}{counter}"
                counter += 1
            
            self.citation_key_map[paper.get('doi') or paper.get('arxiv_id')] = key
            return key
        
        return f"paper{year}"
    
    def _format_authors(self, authors: List, style: str = 'full') -> str:
        """格式化作者列表"""
        if not authors:
            return "Unknown"
        
        if style == 'bibtex':
            # BibTeX: Author1 and Author2 and Author3
            formatted = []
            for author in authors:
                if isinstance(author, dict):
                    name = author.get('name', '')
                else:
                    name = str(author)
                formatted.append(name)
            return ' and '.join(formatted)
        
        elif style == 'gb7714':
            # GB/T 7714: Author A, Author B, Author C
            formatted = []
            for author in authors[:3]:  # 最多显示3个作者
                if isinstance(author, dict):
                    name = author.get('name', '')
                else:
                    name = str(author)
                # 简化为 A. Author 格式
                parts = name.split()
                if len(parts) >= 2:
                    last = parts[-1]
                    initials = ''.join([p[0] for p in parts[:-1]])
                    formatted.append(f"{initials}. {last}")
                else:
                    formatted.append(name)
            
            if len(authors) > 3:
                formatted.append("et al.")
            
            return ', '.join(formatted)
        
        elif style == 'apa':
            # APA: Author, A. A., Author, B. B., & Author, C. C.
            formatted = []
            for i, author in enumerate(authors[:20]):  # APA最多20个作者
                if isinstance(author, dict):
                    name = author.get('name', '')
                else:
                    name = str(author)
                
                parts = name.split()
                if len(parts) >= 2:
                    last = parts[-1]
                    initials = ' '.join([f"{p[0]}." for p in parts[:-1]])
                    formatted.append(f"{last}, {initials}")
                else:
                    formatted.append(name)
            
            if len(authors) == 1:
                return formatted[0]
            elif len(authors) <= 20:
                return ', '.join(formatted[:-1]) + ', & ' + formatted[-1]
            else:
                return ', '.join(formatted) + ', et al.'
        
        return ', '.join([str(a) for a in authors])


class BibTeXFormatter(CitationFormatter):
    """BibTeX 格式生成器"""
    
    def format_all(self) -> str:
        """生成 BibTeX 格式的引用列表"""
        entries = []
        
        for paper in self.papers:
            entry = self._format_single(paper)
            entries.append(entry)
        
        return '\n\n'.join(entries)
    
    def _format_single(self, paper: Dict) -> str:
        """格式化单篇论文为 BibTeX 条目"""
        key = self._generate_key(paper)
        
        # 确定条目类型
        venue = paper.get('venue', '')
        if paper.get('arxiv_id'):
            entry_type = 'misc'
        elif any(conf in venue.lower() for conf in ['conference', 'proceedings', 'cvpr', 'icml', 'neurips', 'iclr', 'acl', 'emnlp', 'aaai', 'ijcai', 'kdd']):
            entry_type = 'inproceedings'
        elif any(journal in venue.lower() for journal in ['journal', 'transactions', 'review', 'letters', 'arxiv']):
            entry_type = 'article'
        else:
            entry_type = 'misc'
        
        # 构建字段
        fields = []
        
        # title
        title = paper.get('title', '').replace('{', '').replace('}', '')
        fields.append(f'  title = {{{title}}}')
        
        # author
        authors = self._format_authors(paper.get('authors', []), 'bibtex')
        if authors and authors != "Unknown":
            fields.append(f'  author = {{{authors}}}')
        
        # year
        year = paper.get('year', '')
        if year:
            fields.append(f'  year = {{{year}}}')
        
        # venue/booktitle/journal
        if entry_type == 'inproceedings':
            fields.append(f'  booktitle = {{{venue}}}')
        elif entry_type == 'article':
            fields.append(f'  journal = {{{venue}}}')
        
        # pages
        pages = paper.get('pages', '')
        if pages:
            fields.append(f'  pages = {{{pages}}}')
        
        # doi
        doi = paper.get('doi', '')
        if doi:
            fields.append(f'  doi = {{{doi}}}')
        
        # arXiv
        arxiv_id = paper.get('arxiv_id', '')
        if arxiv_id:
            fields.append(f'  eprint = {{{arxiv_id}}}')
            fields.append(f'  eprinttype = {{arXiv}}')
        
        # url
        pdf_url = paper.get('pdf_url', '')
        if pdf_url:
            fields.append(f'  url = {{{pdf_url}}}')
        
        # abstract (可选)
        abstract = paper.get('abstract', '')
        if abstract:
            fields.append(f'  abstract = {{{abstract[:200]}...}}')
        
        # 组装条目
        entry_lines = [f'@{entry_type}{{{key},'] + [f + ',' for f in fields] + ['}']
        return '\n'.join(entry_lines)


class GB7714Formatter(CitationFormatter):
    """GB/T 7714 格式生成器（中文论文标准）"""
    
    def format_all(self) -> str:
        """生成 GB/T 7714 格式的引用列表"""
        entries = []
        
        for i, paper in enumerate(self.papers, 1):
            entry = self._format_single(paper, i)
            entries.append(entry)
        
        return '\n'.join(entries)
    
    def _format_single(self, paper: Dict, index: int) -> str:
        """格式化单篇论文为 GB/T 7714 格式"""
        authors = self._format_authors_gb7714(paper.get('authors', []))
        title = paper.get('title', '')
        venue = paper.get('venue', '')
        year = paper.get('year', '')
        doi = paper.get('doi', '')
        arxiv_id = paper.get('arxiv_id', '')
        
        # 判断文献类型
        if arxiv_id and not venue:
            # 预印本
            entry = f"[{index}] {authors}. {title}[EB/OL]. arXiv preprint arXiv:{arxiv_id}, {year}."
            if doi:
                entry += f" https://doi.org/{doi}"
        
        elif any(conf in venue.lower() for conf in ['conference', 'proceedings', 'cvpr', 'icml', 'neurips', 'iclr']):
            # 会议论文
            entry = f"[{index}] {authors}. {title}[C]. {venue}, {year}."
            if doi:
                entry += f" https://doi.org/{doi}"
            entry += "."
        
        elif venue:
            # 期刊论文
            volume = paper.get('volume', '')
            issue = paper.get('issue', '')
            pages = paper.get('pages', '')
            
            entry = f"[{index}] {authors}. {title}[J]. {venue}"
            if year:
                entry += f", {year}"
            if volume:
                entry += f", {volume}"
            if issue:
                entry += f"({issue})"
            if pages:
                entry += f": {pages}"
            entry += "."
            if doi:
                entry += f" https://doi.org/{doi}."
        
        else:
            # 其他类型
            entry = f"[{index}] {authors}. {title}[M]. {year}."
        
        return entry
    
    def _format_authors_gb7714(self, authors: List) -> str:
        """GB/T 7714 作者格式：姓前名后，逗号分隔，最多3人"""
        if not authors:
            return "佚名"
        
        formatted = []
        for author in authors[:3]:
            if isinstance(author, dict):
                name = author.get('name', '')
            else:
                name = str(author)
            
            # 简化为 姓,名首字母 格式
            parts = name.split()
            if len(parts) >= 2:
                # 假设最后一个是姓
                last = parts[-1]
                initials = ''.join([p[0] for p in parts[:-1]])
                formatted.append(f"{last} {initials}")
            else:
                formatted.append(name)
        
        if len(authors) > 3:
            formatted.append("等")
        
        return ', '.join(formatted)


class APAFormatter(CitationFormatter):
    """APA 格式生成器（第 7 版）"""
    
    def format_all(self) -> str:
        """生成 APA 格式的引用列表"""
        entries = []
        
        for paper in self.papers:
            entry = self._format_single(paper)
            entries.append(entry)
        
        return '\n\n'.join(entries)
    
    def _format_single(self, paper: Dict) -> str:
        """格式化单篇论文为 APA 格式"""
        authors = self._format_authors(paper.get('authors', []), 'apa')
        year = paper.get('year', 'n.d.')
        title = paper.get('title', '')
        venue = paper.get('venue', '')
        doi = paper.get('doi', '')
        arxiv_id = paper.get('arxiv_id', '')
        
        # 判断文献类型
        if arxiv_id and not venue:
            # 预印本
            entry = f"{authors} ({year}). {title}. *arXiv preprint arXiv:{arxiv_id}*."
            if doi:
                entry += f" https://doi.org/{doi}"
        
        elif any(conf in venue.lower() for conf in ['conference', 'proceedings', 'cvpr', 'icml', 'neurips', 'iclr']):
            # 会议论文
            entry = f"{authors} ({year}). {title}. In *{venue}* (pp. XX-XX)."
            if doi:
                entry += f" https://doi.org/{doi}"
            entry += "."
        
        elif venue:
            # 期刊论文
            volume = paper.get('volume', '')
            issue = paper.get('issue', '')
            pages = paper.get('pages', '')
            
            entry = f"{authors} ({year}). {title}. *{venue}*"
            if volume:
                entry += f", *{volume}*"
            if issue:
                entry += f"({issue})"
            if pages:
                entry += f", {pages}"
            entry += "."
            if doi:
                entry += f" https://doi.org/{doi}"
        
        else:
            # 其他类型
            entry = f"{authors} ({year}). {title}."
        
        return entry
    
    def format_citations_inline(self) -> List[str]:
        """生成文中引用标记 (Author, Year)"""
        markers = []
        for paper in self.papers:
            authors = paper.get('authors', [])
            year = paper.get('year', 'n.d.')
            
            if authors:
                if isinstance(authors[0], dict):
                    first_author = authors[0].get('name', '')
                else:
                    first_author = str(authors[0])
                
                last_name = first_author.split()[-1]
                
                if len(authors) == 1:
                    marker = f"({last_name}, {year})"
                elif len(authors) == 2:
                    second = str(authors[1]).split()[-1] if not isinstance(authors[1], dict) else authors[1].get('name', '').split()[-1]
                    marker = f"({last_name} & {second}, {year})"
                else:
                    marker = f"({last_name} et al., {year})"
            else:
                marker = f"(Anonymous, {year})"
            
            markers.append(marker)
        
        return markers


def main():
    """主函数"""
    parser = argparse.ArgumentParser(description='Format citations in various styles')
    parser.add_argument('--style', choices=['bibtex', 'gb7714', 'apa'], required=True,
                       help='Citation style to use')
    parser.add_argument('--papers', type=str, required=True,
                       help='JSON file containing paper metadata or JSON string')
    parser.add_argument('--output', type=str, help='Output file path (default: stdout)')
    parser.add_argument('--with-markers', action='store_true',
                       help='Also generate inline citation markers (APA only)')
    
    args = parser.parse_args()
    
    # 读取论文数据
    papers_data = args.papers
    if papers_data.endswith('.json') and os.path.exists(papers_data):
        with open(papers_data, 'r', encoding='utf-8') as f:
            papers = json.load(f)
    else:
        # 尝试解析为 JSON 字符串
        try:
            papers = json.loads(papers_data)
        except json.JSONDecodeError:
            print(f"Error: Cannot parse papers data: {papers_data[:100]}...", file=sys.stderr)
            sys.exit(1)
    
    # 确保是列表
    if not isinstance(papers, list):
        papers = [papers]
    
    # 选择格式化器
    formatter_map = {
        'bibtex': BibTeXFormatter,
        'gb7714': GB7714Formatter,
        'apa': APAFormatter,
    }
    
    formatter_class = formatter_map.get(args.style)
    if not formatter_class:
        print(f"Error: Unknown style {args.style}", file=sys.stderr)
        sys.exit(1)
    
    formatter = formatter_class(papers)
    output = formatter.format_all()
    
    # 如果需要文中引用标记（APA 格式）
    if args.with_markers and args.style == 'apa':
        markers = formatter.format_citations_inline()
        output += "\n\n---\n\nInline citation markers:\n"
        for i, marker in enumerate(markers, 1):
            output += f"[{i}] {marker}\n"
    
    # 输出结果
    if args.output:
        with open(args.output, 'w', encoding='utf-8') as f:
            f.write(output)
        print(f"Formatted citations written to: {args.output}")
    else:
        print(output)


if __name__ == '__main__':
    import os
    main()


path: scripts/parse_document.py
content: #!/usr/bin/env python3
"""
文档解析器：提取文章主题、关键词、现有引用和搜索建议
支持格式：Markdown / LaTeX / Word (.docx)
"""

import re
import json
import sys
import os
from pathlib import Path
from typing import Dict, List, Set, Optional


class DocumentParser:
    """通用文档解析基类"""
    
    def __init__(self, file_path: str):
        self.file_path = Path(file_path)
        self.content = ""
        self.file_type = ""
        
    def parse(self) -> Dict:
        """解析文档并返回结构化信息"""
        raise NotImplementedError
    
    def extract_keywords(self, text: str, top_k: int = 7) -> List[str]:
        """提取关键词（基于学术术语模式）"""
        # 学术术语模式：驼峰命名、连字符连接、特定后缀
        patterns = [
            # 驼峰命名（如 GraphNeuralNetwork）
            r'\b[A-Z][a-z]+(?:[A-Z][a-z]+)+\b',
            # 连字符连接（如 graph-neural-network）
            r'\b[a-z]+(?:-[a-z]+){1,3}\b',
            # 常见学术术语
            r'\b(?:neural|network|learning|model|algorithm|optimization|prediction|forecasting|classification|regression|clustering|embedding|attention|transformer|bert|gpt|cnn|rnn|lstm|gru|gan|vae|gnn|gnn|graph|temporal|spatial|multivariate|univariate|series|time)\b',
            # 大写缩写（2-5个字母）
            r'\b[A-Z]{2,5}\b',
        ]
        
        keywords = []
        for pattern in patterns:
            matches = re.findall(pattern, text, re.IGNORECASE)
            keywords.extend([m.lower() if m.isupper() else m for m in matches])
        
        # 统计频率并去重
        from collections import Counter
        keyword_counts = Counter(keywords)
        
        # 过滤停用词
        stopwords = {'the', 'and', 'for', 'with', 'via', 'using', 'based', 'from', 
                     'this', 'that', 'such', 'also', 'more', 'than', 'only', 
                     'even', 'both', 'each', 'all', 'any', 'can', 'may', 'use',
                     'one', 'two', 'new', 'first', 'second', 'third', 'et', 'al'}
        
        filtered = [(k, v) for k, v in keyword_counts.items() 
                   if k.lower() not in stopwords and len(k) > 2]
        
        # 返回 top_k 个关键词
        return [k for k, _ in sorted(filtered, key=lambda x: x[1], reverse=True)[:top_k]]
    
    def generate_search_queries(self, keywords: List[str], context: str) -> List[str]:
        """基于关键词和上下文生成搜索 query"""
        queries = []
        
        if len(keywords) >= 2:
            # Query 1: 主要方法
            queries.append(f"{keywords[0]} {keywords[1]}")
            
            # Query 2: 方法 + 应用场景
            if len(keywords) >= 3:
                queries.append(f"{keywords[0]} {keywords[2]} prediction")
            
            # Query 3: 扩展同义词
            synonyms = self._expand_synonyms(keywords[:2])
            if synonyms:
                queries.append(f"{synonyms[0]} {synonyms[1] if len(synonyms) > 1 else keywords[1]}")
        
        # 确保至少有 2 个 query
        if len(queries) < 2:
            queries.append(" ".join(keywords[:3]) if len(keywords) >= 3 else " ".join(keywords))
        
        return queries[:4]
    
    def _expand_synonyms(self, terms: List[str]) -> List[str]:
        """扩展学术术语同义词"""
        synonym_map = {
            'gnn': ['graph neural network', 'graph convolutional network', 'gcn'],
            'graphneuralnetwork': ['gnn', 'graph convolutional network'],
            'graph-neural-network': ['gnn', 'gcn'],
            'transformer': ['attention mechanism', 'self-attention', 'bert', 'gpt'],
            'deep-learning': ['neural network', 'deep neural network', 'dnn'],
            'deeplearning': ['deep learning', 'neural network'],
            'time-series': ['temporal data', 'sequential data', 'time series forecasting'],
            'timeseries': ['time series', 'temporal prediction'],
            'multivariate': ['multi-variable', 'multi-variate'],
        }
        
        expanded = []
        for term in terms:
            term_lower = term.lower()
            if term_lower in synonym_map:
                expanded.extend(synonym_map[term_lower][:1])
            else:
                expanded.append(term)
        
        return expanded


class MarkdownParser(DocumentParser):
    """Markdown 文档解析器"""
    
    def __init__(self, file_path: str):
        super().__init__(file_path)
        self.file_type = "markdown"
    
    def parse(self) -> Dict:
        """解析 Markdown 文档"""
        with open(self.file_path, 'r', encoding='utf-8') as f:
            self.content = f.read()
        
        return {
            "file_type": self.file_type,
            "title": self._extract_title(),
            "abstract": self._extract_abstract(),
            "sections": self._extract_sections(),
            "keywords": self.extract_keywords(self.content),
            "existing_citations": self._extract_citations(),
            "content_preview": self._get_preview(),
            "suggested_queries": self.generate_search_queries(
                self.extract_keywords(self.content), 
                self.content
            )
        }
    
    def _extract_title(self) -> str:
        """提取标题（第一个 # 标题）"""
        match = re.search(r'^#\s+(.+)$', self.content, re.MULTILINE)
        return match.group(1).strip() if match else ""
    
    def _extract_abstract(self) -> str:
        """提取摘要"""
        # 寻找 Abstract 或 摘要 部分
        patterns = [
            r'##?\s*(?:Abstract|摘要)\s*\n\n?(.+?)(?=\n##|\Z)',
            r'(?:^|\n)([^#\n].{100,500}?)(?=\n##|\n\n##|\Z)',
        ]
        for pattern in patterns:
            match = re.search(pattern, self.content, re.DOTALL | re.IGNORECASE)
            if match:
                return match.group(1).strip()[:500]
        return ""
    
    def _extract_sections(self) -> List[str]:
        """提取章节标题"""
        sections = re.findall(r'^##?\s+(.+)$', self.content, re.MULTILINE)
        return [s.strip() for s in sections[:10]]
    
    def _extract_citations(self) -> List[str]:
        """提取已有引用"""
        citations = []
        
        # arXiv ID 模式
        arxiv_matches = re.findall(r'arxiv[:/](\d{4}\.\d{4,5})', self.content, re.IGNORECASE)
        citations.extend([f"arxiv:{m}" for m in arxiv_matches])
        
        # DOI 模式
        doi_matches = re.findall(r'10\.\d{4,}/[^\s\]]+', self.content)
        citations.extend([f"doi:{m}" for m in doi_matches])
        
        # 引用标记模式 [1], [2], etc.
        ref_matches = re.findall(r'\[(\d+)\]', self.content)
        
        return list(set(citations))
    
    def _get_preview(self) -> str:
        """获取内容预览"""
        # 移除 markdown 标记，保留纯文本
        text = re.sub(r'!?\[([^\]]*)\]\([^\)]+\)', r'\1', self.content)  # 移除链接和图片
        text = re.sub(r'[#*_`]', '', text)  # 移除格式标记
        text = re.sub(r'\n+', ' ', text)  # 合并换行
        return text[:800]


class LaTeXParser(DocumentParser):
    """LaTeX 文档解析器"""
    
    def __init__(self, file_path: str):
        super().__init__(file_path)
        self.file_type = "latex"
    
    def parse(self) -> Dict:
        """解析 LaTeX 文档"""
        with open(self.file_path, 'r', encoding='utf-8') as f:
            self.content = f.read()
        
        return {
            "file_type": self.file_type,
            "title": self._extract_title(),
            "abstract": self._extract_abstract(),
            "sections": self._extract_sections(),
            "keywords": self._extract_keywords_latex() or self.extract_keywords(self.content),
            "existing_citations": self._extract_citations(),
            "bibliography_files": self._extract_bib_files(),
            "content_preview": self._get_preview(),
            "suggested_queries": self.generate_search_queries(
                self.extract_keywords(self.content),
                self.content
            )
        }
    
    def _extract_title(self) -> str:
        """提取标题"""
        match = re.search(r'\\title\{([^}]+)\}', self.content)
        return match.group(1).strip() if match else ""
    
    def _extract_abstract(self) -> str:
        """提取摘要"""
        match = re.search(r'\\begin\{abstract\}(.+?)\\end\{abstract\}', 
                         self.content, re.DOTALL | re.IGNORECASE)
        return match.group(1).strip()[:500] if match else ""
    
    def _extract_sections(self) -> List[str]:
        """提取章节"""
        sections = re.findall(r'\\section\{([^}]+)\}', self.content)
        return sections[:10]
    
    def _extract_keywords_latex(self) -> List[str]:
        """提取 LaTeX 关键词"""
        match = re.search(r'\\keywords\{([^}]+)\}', self.content, re.IGNORECASE)
        if match:
            return [k.strip() for k in match.group(1).split(',')]
        return []
    
    def _extract_citations(self) -> List[str]:
        """提取引用标记"""
        # \cite{key1,key2}
        cites = re.findall(r'\\cite[pt]?\{([^}]+)\}', self.content)
        all_cites = []
        for cite_group in cites:
            all_cites.extend([c.strip() for c in cite_group.split(',')])
        return list(set(all_cites))
    
    def _extract_bib_files(self) -> List[str]:
        """提取引用的 .bib 文件"""
        matches = re.findall(r'\\bibliography\{([^}]+)\}', self.content)
        return [m.strip() for m in matches]
    
    def _get_preview(self) -> str:
        """获取纯文本预览"""
        # 移除 LaTeX 命令
        text = re.sub(r'\\[a-zA-Z]+\*?(?:\[[^\]]*\])?(?:\{[^}]*\})?', ' ', self.content)
        text = re.sub(r'%.*?\n', ' ', text)  # 移除注释
        text = re.sub(r'\s+', ' ', text)  # 合并空白
        return text[:800]


class WordParser(DocumentParser):
    """Word 文档解析器（.docx）"""
    
    def __init__(self, file_path: str):
        super().__init__(file_path)
        self.file_type = "word"
    
    def parse(self) -> Dict:
        """解析 Word 文档"""
        try:
            from docx import Document
        except ImportError:
            return {
                "file_type": self.file_type,
                "error": "python-docx not installed. Run: pip install python-docx",
                "content_preview": ""
            }
        
        doc = Document(self.file_path)
        full_text = []
        sections = []
        
        for para in doc.paragraphs:
            text = para.text.strip()
            if text:
                full_text.append(text)
                # 检测标题（简单启发式：短段落且以大写字母开头）
                if len(text) < 100 and text[0].isupper() and not text[-1] in '.!?':
                    sections.append(text)
        
        content = '\n'.join(full_text)
        
        return {
            "file_type": self.file_type,
            "title": full_text[0] if full_text else "",
            "abstract": self._extract_abstract_word(full_text),
            "sections": sections[:10],
            "keywords": self.extract_keywords(content),
            "existing_citations": [],  # Word 中难以自动提取
            "content_preview": content[:800],
            "suggested_queries": self.generate_search_queries(
                self.extract_keywords(content),
                content
            )
        }
    
    def _extract_abstract_word(self, paragraphs: List[str]) -> str:
        """从 Word 段落中提取摘要"""
        # 寻找 "Abstract" 或 "摘要" 后面的段落
        for i, para in enumerate(paragraphs):
            if re.match(r'^(Abstract|摘要)\s*$', para, re.IGNORECASE):
                if i + 1 < len(paragraphs):
                    return paragraphs[i + 1][:500]
        
        # 如果没有明确标记，返回前几个段落中较长的一个
        for para in paragraphs[1:5]:
            if 100 < len(para) < 500:
                return para
        return ""


def detect_file_type(file_path: str) -> str:
    """检测文件类型"""
    ext = Path(file_path).suffix.lower()
    if ext == '.md':
        return 'markdown'
    elif ext in ['.tex', '.latex']:
        return 'latex'
    elif ext == '.docx':
        return 'word'
    else:
        # 尝试根据内容检测
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            content = f.read(1000)
            if content.startswith('%') or '\\documentclass' in content:
                return 'latex'
            elif '# ' in content or content.startswith('#'):
                return 'markdown'
        return 'unknown'


def main():
    """主函数"""
    if len(sys.argv) < 2:
        print("Usage: python parse_document.py <file_path>", file=sys.stderr)
        sys.exit(1)
    
    file_path = sys.argv[1]
    
    if not os.path.exists(file_path):
        print(json.dumps({"error": f"File not found: {file_path}"}))
        sys.exit(1)
    
    # 检测文件类型并选择解析器
    file_type = detect_file_type(file_path)
    
    parser_map = {
        'markdown': MarkdownParser,
        'latex': LaTeXParser,
        'word': WordParser,
    }
    
    parser_class = parser_map.get(file_type)
    if not parser_class:
        print(json.dumps({"error": f"Unsupported file type: {file_type}"}))
        sys.exit(1)
    
    # 解析文档
    parser = parser_class(file_path)
    result = parser.parse()
    
    # 添加文件路径
    result["file_path"] = file_path
    
    # 输出 JSON
    print(json.dumps(result, ensure_ascii=False, indent=2))


if __name__ == '__main__':
    main()


path: references/citation-styles.md
content: # 引用格式规范速查

本文档详细说明支持的三种引用格式及其使用场景。

---

## BibTeX 格式

### 适用场景
- LaTeX 文档
- 需要灵活切换引用样式（plain/unsrt/alpha/ieee/acl）
- 与 Zotero/JabRef 等文献管理工具集成

### 条目类型

| 类型 | 使用场景 | 必需字段 |
|------|---------|---------|
| `@article` | 期刊论文 | title, author, journal, year |
| `@inproceedings` | 会议论文 | title, author, booktitle, year |
| `@misc` | 预印本/技术报告 | title, author, year, eprint |
| `@book` | 书籍 | title, author, publisher, year |
| `@phdthesis` | 学位论文 | title, author, school, year |

### 示例输出

```bibtex
@inproceedings{wang2023gnn,
  title = {Graph Neural Networks for Time Series Prediction},
  author = {Wang, X. and Li, Y.},
  booktitle = {NeurIPS},
  year = {2023},
  pages = {1000--1010},
  doi = {10.5555/1234567}
}

@misc{zhang2024transformer,
  title = {Transformer-based Methods for Long-term Forecasting},
  author = {Zhang, S. and Liu, J.},
  year = {2024},
  eprint = {2401.12345},
  eprinttype = {arXiv}
}
```

### 文中引用

```latex
% 单篇引用
\cite{wang2023gnn}

% 多篇引用
\cite{wang2023gnn,zhang2024transformer}

% 引用并显示页码
\cite[pp. 100]{wang2023gnn}

% 作者 (年份) 格式（需 natbib 宏包）
\citet{wang2023gnn}  % Wang et al. (2023)
\citep{wang2023gnn}  % (Wang et al., 2023)
```

### 完整 LaTeX 示例

```latex
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{natbib}  % 或 \usepackage[numbers]{natbib}

\begin{document}

% 正文中的引用
Recent work has explored graph neural networks for time series forecasting \cite{wang2023gnn,zhang2024transformer}.

% 参考文献列表（在 document 末尾）
\bibliographystyle{plain}  % 可选: plain, unsrt, alpha, ieee, acl
\bibliography{references}

\end{document}
```

---

## GB/T 7714 格式（中国国家标准）

### 适用场景
- 中文学位论文（硕士/博士）
- 中文期刊投稿
- 国内学术会议
- 符合中国高校毕业论文规范

### 基本格式

**文中引用**：上标 `[1]`、`[2-4]`、`[1,3,5]`

**文末列表**：按文中出现顺序编号

### 各类文献格式

#### 期刊论文 [J]

```
[1] 作者. 标题[J]. 期刊名, 年份, 卷(期): 页码.
```

示例：
```
[1] 张三, 李四. 基于图神经网络的时间序列预测方法[J]. 计算机学报, 2023, 46(5): 100-120.
```

#### 会议论文 [C]

```
[2] 作者. 标题[C]. 会议名称, 地点, 年份: 页码.
```

示例：
```
[2] Wang X, Li Y. Graph Neural Networks for Time Series Prediction[C]. NeurIPS, 2023: 1000-1010.
```

#### 学位论文 [D]

```
[3] 作者. 标题[D]. 保存地点: 保存单位, 年份.
```

示例：
```
[3] 王五. 深度学习在时间序列分析中的应用研究[D]. 北京: 清华大学, 2022.
```

#### 预印本/电子文献 [EB/OL]

```
[4] 作者. 标题[EB/OL]. arXiv:编号, 年份. https://arxiv.org/abs/编号
```

示例：
```
[4] Zhang S, Liu J. Transformer-based Methods for Long-term Forecasting[EB/OL]. arXiv:2401.12345, 2024. https://arxiv.org/abs/2401.12345
```

### 作者格式规则

| 作者数量 | 格式 | 示例 |
|---------|------|------|
| 1 人 | 全名 | 张三 |
| 2 人 | 全名, 全名 | 张三, 李四 |
| 3 人 | 全名, 全名, 全名 | 张三, 李四, 王五 |
| 4+ 人 | 前 3 人 + "等" | 张三, 李四, 王五, 等 |

### 西文作者格式

- 名在前，姓在后
- 名缩写，姓完整
- 示例：`J. Smith`, `A. B. Johnson`

---

## APA 格式（第 7 版）

### 适用场景
- 国际期刊投稿（心理学、社会科学）
- 英文毕业论文
- APA 风格的学术写作

### 基本格式

**文中引用**：作者-年份制
- 单作者：`(Smith, 2023)`
- 双作者：`(Smith & Jones, 2023)`
- 三作者及以上：`(Smith et al., 2023)`

**文末列表**：按作者姓氏字母顺序排列

### 各类文献格式

#### 期刊论文

```
Author, A. A., & Author, B. B. (Year). Title of article. *Title of Journal*, *volume*(issue), page range. https://doi.org/xx.xxx/xxxx
```

示例：
```
Wang, X., & Li, Y. (2023). Graph neural networks for time series prediction. *Journal of Machine Learning*, *45*(3), 100-120. https://doi.org/10.1037/jml0000123
```

#### 会议论文

```
Author, A. A. (Year). Title of paper. In *Proceedings of Conference* (pp. XX-XX). Publisher. https://doi.org/xx.xxx/xxxx
```

示例：
```
Wang, X., & Li, Y. (2023). Graph neural networks for time series prediction. In *Proceedings of NeurIPS 2023* (pp. 1000-1010). Curran Associates. https://doi.org/10.5555/1234567
```

#### 预印本（arXiv）

```
Author, A. A. (Year). Title of preprint. *arXiv*. https://arxiv.org/abs/XXXX.XXXXX
```

示例：
```
Zhang, S., & Liu, J. (2024). Transformer-based methods for long-term forecasting. *arXiv*. https://arxiv.org/abs/2401.12345
```

### 文中引用详细规则

| 情况 | 首次引用 | 后续引用 |
|------|---------|---------|
| 1 作者 | (Smith, 2023) | (Smith, 2023) |
| 2 作者 | (Smith & Jones, 2023) | (Smith & Jones, 2023) |
| 3 作者 | (Smith, Jones, & Lee, 2023) | (Smith et al., 2023) |
| 4+ 作者 | (Smith et al., 2023) | (Smith et al., 2023) |
| 机构 | (National Institute, 2023) | (NIA, 2023) |

### 特殊规则

1. **同作者同年多篇**：在年份后加小写字母 `(Smith, 2023a)`, `(Smith, 2023b)`
2. **多引用排序**：按作者字母顺序 `(Jones, 2022; Smith, 2023; Wang, 2021)`
3. **引用在句中**：`Smith (2023) found that...`
4. **引用在句末**：`...found significant results (Smith, 2023).`

---

## 格式选择指南

### 按文档类型选择

| 文档类型 | 推荐格式 | 理由 |
|---------|---------|------|
| LaTeX 论文 | BibTeX | 与 LaTeX 原生集成 |
| 中文毕业论文 | GB/T 7714 | 符合国家标准 |
| 英文期刊投稿 | APA / 期刊指定 | 国际通用 |
| 技术博客 | GB/T 7714 / APA | 简洁清晰 |
| 学位论文（国内）| GB/T 7714 | 学校要求 |
| 学位论文（国外）| APA | 学校要求 |

### 按学科选择

| 学科领域 | 推荐格式 |
|---------|---------|
| 计算机科学 | BibTeX / GB/T 7714 |
| 心理学 | APA |
| 社会科学 | APA |
| 工程技术 | GB/T 7714 / IEEE |
| 医学 | Vancouver / APA |
| 自然科学 | GB/T 7714 / Nature/Science 格式 |

---

## 常见问题 (FAQ)

### Q1: 如何切换引用格式？

**A**: 
- **BibTeX**: 修改 `\bibliographystyle{...}` 行
- **其他格式**: 需重新生成引用文本

### Q2: 同一文档可以使用多种格式吗？

**A**: 不建议。全文应保持一致格式。如需转换，使用 `format_citation.py` 重新格式化。

### Q3: 中文作者姓名在 GB/T 7714 中如何排列？

**A**: 中文作者保持原顺序，西文作者姓在前名在后。
示例：`张三, 李四, Smith J A`

### Q4: 如何引用没有 DOI 的论文？

**A**: 
- **BibTeX**: 省略 doi 字段或使用 url 字段
- **GB/T 7714**: 省略 DOI 链接或使用 URL
- **APA**: 使用 URL 或数据库名称

### Q5: arXiv 论文如何引用？

**A**:
- **BibTeX**: 使用 `@misc` 类型，包含 `eprint` 和 `eprinttype`
- **GB/T 7714**: 使用 `[EB/OL]` 类型，标注 arXiv 编号
- **APA**: 标注为预印本，包含 arXiv URL

---

## 工具使用示例

### 生成 BibTeX 格式

```bash
python scripts/format_citation.py \
  --style bibtex \
  --papers papers.json \
  --output references.bib
```

### 生成 GB/T 7714 格式

```bash
python scripts/format_citation.py \
  --style gb7714 \
  --papers papers.json \
  --output references.txt
```

### 生成 APA 格式（含文中标记）

```bash
python scripts/format_citation.py \
  --style apa \
  --papers papers.json \
  --with-markers \
  --output references.txt
```

---

## 参考资源

- [GB/T 7714-2015 官方标准](https://www.tsinghua.edu.cn/)
- [APA Style 第7版官网](https://apastyle.apa.org/)
- [BibTeX 格式说明](http://www.bibtex.org/Format/)


path: references/workflow-examples.md
content: # 使用场景示例

本文档展示 auto-citation skill 在不同场景下的典型使用流程。

---

## 场景一：完善学术论文引言

### 背景
你正在撰写一篇关于"图神经网络在时间序列预测中的应用"的论文，引言部分需要补充相关工作引用。

### 原文（LaTeX）

```latex
\section{Introduction}

Time series forecasting is a fundamental problem in machine learning with 
applications in finance, weather prediction, and traffic management. 
Recent years have witnessed the rapid development of deep learning methods 
for this task. However, capturing complex temporal dependencies remains 
a challenging problem.

In this paper, we propose a novel graph neural network approach...
```

### 用户指令

```
给引言部分加一些背景文献，主要是时间序列预测和GNN方面的
```

### AI 执行流程

1. **解析文档**
   - 主题：GNN + 时间序列预测
   - 关键词：`graph neural network`, `time series forecasting`, `temporal dependencies`
   - 现有引用：无
   - 建议 query：`graph neural network time series`, `deep learning time series forecasting`

2. **搜索论文**
   - arXiv: 近 5 年相关论文
   - Semantic Scholar: 高引用相关工作
   - 筛选出 8 篇候选

3. **推荐候选**

```
基于你的引言内容，我找到以下相关背景文献：

[1] **Spatio-Temporal Graph Neural Networks** - 被引 320 次 (2021)
    作者：Yu et al.
    相关点：全面的时空 GNN 综述，适合作为领域背景
    
[2] **Long-term Time Series Forecasting with Transformers** - 被引 280 次 (2022)
    作者：Zhou et al.
    相关点：时间序列预测的深度学习方法综述
    
[3] **Graph WaveNet** - 被引 450 次 (2019)
    作者：Wu et al.
    相关点：交通预测的 GNN 经典工作，可作为 baseline 引用
    
[4] **STGNN for Multi-step Prediction** - 被引 180 次 (2023) [新]
    作者：Li et al.
    相关点：最新的多步预测方法，展示领域进展

请选择你想引用的论文编号（如：1,2,3）
```

4. **用户选择**

```
用户：选 1, 2, 3，用 BibTeX 格式
```

5. **生成并插入引用**

AI 生成 BibTeX 条目并插入到 .bib 文件，同时在引言中添加 `\cite{}` 命令。

### 最终输出

**引言更新为：**

```latex
\section{Introduction}

Time series forecasting is a fundamental problem in machine learning with 
applications in finance, weather prediction, and traffic management. 
Recent years have witnessed the rapid development of deep learning methods 
for this task \cite{zhou2022transformers}, including various neural network 
architectures \cite{wu2019graphwavenet}. However, capturing complex temporal 
dependencies remains a challenging problem.

Graph neural networks (GNNs) have emerged as a powerful tool for modeling 
spatial-temporal data \cite{yu2021stgnn}. In this paper, we propose a novel 
graph neural network approach...
```

**references.bib 新增：**

```bibtex
@article{yu2021stgnn,
  title = {Spatio-Temporal Graph Neural Networks},
  author = {Yu, B. and Yin, H. and Zhu, Z.},
  journal = {IEEE Transactions on Knowledge and Data Engineering},
  year = {2021},
  doi = {10.1109/TKDE.2021.1234567}
}

@inproceedings{zhou2022transformers,
  title = {Long-term Time Series Forecasting with Transformers},
  author = {Zhou, H. and Zhang, S. and Peng, J.},
  booktitle = {ICLR},
  year = {2022}
}

@inproceedings{wu2019graphwavenet,
  title = {Graph WaveNet for Deep Spatial-Temporal Graph Modeling},
  author = {Wu, Z. and Pan, S. and Long, G. and others},
  booktitle = {IJCAI},
  year = {2019}
}
```

---

## 场景二：技术博客补充引用

### 背景
你写了一篇关于 Transformer 的博客文章，想为关键观点添加学术引用。

### 原文（Markdown）

```markdown
# Transformer 详解：从 Attention 到 BERT

Transformer 架构自 2017 年提出以来，彻底改变了 NLP 领域。
它完全基于注意力机制，摒弃了传统的 RNN 和 CNN 结构。

BERT 进一步扩展了 Transformer 的应用...
```

### 用户指令

```
给这篇文章加一些关键论文引用，用 GB/T 7714 格式
```

### AI 执行流程

1. **解析文档**
   - 主题：Transformer, Attention, BERT
   - 关键词：`transformer`, `attention`, `bert`
   - 识别关键论文需求：原始 Transformer 论文、BERT 论文

2. **精确检索**
   - `arxiv:1706.03762` (Attention is All You Need)
   - `arxiv:1810.04805` (BERT)

3. **推荐候选**

```
找到以下核心论文：

[1] **Attention Is All You Need** - 被引 52000+ 次 (2017)
    作者：Vaswani et al.
    相关点：Transformer 原始论文，适合介绍架构起源
    
[2] **BERT: Pre-training of Deep Transformers** - 被引 38000+ 次 (2019)
    作者：Devlin et al.
    相关点：BERT 论文，适合介绍预训练概念

确认添加这 2 篇？（是/否/更多）
```

4. **用户确认**

```
用户：确认，添加到文末
```

5. **生成并插入**

### 最终输出

**文章末尾新增：**

```markdown
## 参考文献

[1] Vaswani A, Shazeer N, Parmar N, 等. Attention is All You Need[C]. NeurIPS, 2017.

[2] Devlin J, Chang M W, Lee K, 等. BERT: Pre-training of Deep Bidirectional Transformers[J]. 
    NAACL, 2019.
```

---

## 场景三：实验部分补充 baseline

### 背景
你的论文实验部分需要引用对比方法的相关论文。

### 原文片段

```latex
\section{Experiments}

\subsection{Baselines}

We compare our proposed method against the following baselines:
\begin{itemize}
    \item LSTM: A classic RNN-based method
    \item GRU: A gated recurrent unit variant
    \item Transformer: The standard transformer architecture
    \item Informer: An efficient transformer variant
\end{itemize}
```

### 用户指令

```
给这些 baseline 方法加具体引用，每个都要有出处
```

### AI 执行流程

1. **解析需求**
   - 需要 4 篇特定论文的引用
   - 格式：BibTeX

2. **精准检索**

针对每个 baseline 搜索：
- `LSTM Hochreiter Schmidhuber 1997`
- `GRU Cho 2014`
- `Transformer Vaswani 2017`
- `Informer Zhou 2021 AAAI`

3. **推荐确认**

```
找到以下 baseline 论文：

LSTM:
[1] Hochreiter S, Schmidhuber J. Long Short-Term Memory[J]. Neural Computation, 1997.

GRU:
[2] Cho K, van Merriënboer B, Gulcehre C, 等. Learning Phrase Representations 
    using RNN Encoder–Decoder for Statistical Machine Translation[C]. EMNLP, 2014.

Transformer:
[3] Vaswani A, 等. Attention is All You Need[C]. NeurIPS, 2017.

Informer:
[4] Zhou H, Zhang S, Peng J, 等. Informer: Beyond Efficient Transformer for 
    Long Sequence Time-Series Forecasting[C]. AAAI, 2021.

全部确认？
```

4. **插入引用**

AI 生成 BibTeX 并更新正文中的 baseline 列表。

### 最终输出

```latex
\subsection{Baselines}

We compare our proposed method against the following baselines:
\begin{itemize}
    \item LSTM \cite{hochreiter1997lstm}: A classic RNN-based method
    \item GRU \cite{cho2014gru}: A gated recurrent unit variant
    \item Transformer \cite{vaswani2017attention}: The standard transformer architecture
    \item Informer \cite{zhou2021informer}: An efficient transformer variant
\end{itemize}
```

---

## 场景四：中文毕业论文格式转换

### 背景
你有一篇英文论文需要改成中文毕业论文格式（GB/T 7714）。

### 原始引用（APA 格式）

```
Wang, X., & Li, Y. (2023). Graph neural networks for time series prediction. 
    Journal of ML, 45(3), 100-120.
```

### 用户指令

```
把这些引用转成 GB/T 7714 格式
```

### AI 执行流程

1. **格式识别**
   - 当前：APA 格式
   - 目标：GB/T 7714

2. **逐条转换**

**转换结果：**

```
[1] Wang X, Li Y. Graph neural networks for time series prediction[J]. 
    Journal of ML, 2023, 45(3): 100-120.
```

### 中文论文特殊处理

如果涉及中文文献：

```
[2] 张三, 李四. 深度学习在时间序列预测中的应用[J]. 计算机学报, 2022, 45(8): 2000-2015.
```

---

## 场景五：快速引用单篇论文

### 背景
你知道某篇论文的信息，需要快速添加完整引用。

### 用户指令

```
帮我引用这篇论文：arxiv 2401.12345，用 GB/T 7714 格式
```

### AI 执行流程

1. **直接查询 arXiv**
   - 调用 academic-search 获取 arxiv:2401.12345 元数据

2. **生成引用**

```
生成引用：

[1] Zhang S, Liu J, Wang W. Transformer-based Methods for Long-term Forecasting[EB/OL]. 
    arXiv:2401.12345, 2024. https://arxiv.org/abs/2401.12345
```

3. **询问插入位置**

```
是否要插入到当前文档？如果是，请提供文件路径。
```

---

## 场景六：Word 文档引用

### 背景
你在写 Word 格式的综述报告。

### 用户指令

```
给这个 Word 文档加 5 篇 GNN 相关引用
文档路径：report.docx
```

### AI 执行流程

1. **解析 Word 文档**
   - 使用 python-docx 提取内容
   - 主题：图神经网络综述

2. **搜索并推荐**

3. **生成引用**
   - 格式：GB/T 7714（Word 默认推荐）

4. **插入文档**
   - 在文档末尾添加"参考文献"章节
   - 使用 Word 样式格式化

### 最终效果

Word 文档末尾：

```
参考文献

[1] Kipf T N, Welling M. Semi-supervised Classification with Graph Convolutional Networks[C]. 
    ICLR, 2017.
[2] Veličković P, Cucurull G, Casanova A, 等. Graph Attention Networks[C]. ICLR, 2018.
...
```

---

## 使用建议

### 选择合适的工作模式

| 场景 | 推荐模式 | 理由 |
|------|---------|------|
| 完善引言 | 全自动推荐 | 需要探索相关领域 |
| 补充 baseline | 定向补充 | 目标明确 |
| 已知论文信息 | 精确匹配 | 快速定位 |
| 格式转换 | 全自动 | 纯格式操作 |

### 优化搜索结果

如果推荐不精准：
1. 提供更具体的主题描述
2. 指定年份范围（如"近 3 年"）
3. 指定具体平台（如"找几篇 CVPR 的论文"）
4. 排除某些关键词（如"不要 survey"）

### 引用数量建议

| 文档类型 | 建议引用数 | 分布 |
|---------|-----------|------|
| 技术博客 | 3-5 篇 | 核心论文 |
| 会议论文 | 15-25 篇 | 背景 + 方法 + baseline |
| 期刊论文 | 30-50 篇 | 全面覆盖 |
| 学位论文 | 50-100 篇 | 系统性综述 |

---

## 故障排除

### 搜索结果为空

**可能原因**：
- 关键词太具体
- 时间范围限制太严格
- 平台限制（如只用 arXiv 搜医学论文）

**解决方案**：
```
"放宽时间范围到 10 年"
"也搜索一下 Google Scholar"
"用同义词再搜一遍"
```

### 推荐不够相关

**解决方案**：
```
"侧重找方法类的论文，不要综述"
"找交通预测方向的，不是通用 GNN"
"需要中文文献"
```

### 格式不正确

**解决方案**：
```
"用 GB/T 7714 的会议论文格式重新生成"
"作者名需要全大写"
"加上 DOI 链接"
```


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