# Research: Zotero Attachment Paths & BBT Export Format

> **Purpose:** Document real-world Zotero/Better BibTeX export structure for v1.3 path normalization.
> **Date:** 2026-04-24
> **Source:** Real Zotero library at `D:\L\Med\Research\99_System\Zotero`
> **Analyst:** VT-OS/OPENCODE Terminal

---

## 1. Zotero Data Directory Structure

```
D:\L\Med\Research\99_System\Zotero\
├── storage\                    # PDF 附件存储（1141 个目录）
│   ├── 25AQPG4N\              # Zotero 8位 item key
│   │   └── He - 2024 - Gel microspheres... .pdf
│   ├── 26EUQKI8\
│   │   └── Imler - 2024 - Evolutionary immunology... .pdf
│   └── ... (1141 total)
├── zotero.sqlite               # 主数据库
└── ...
```

**Key observation:** Each attachment gets a unique 8-character directory under `storage/`. The directory name is the Zotero item key (e.g., `RU33UHK8`).

---

## 2. Better BibTeX Export Format (JSON)

**File:** `D:\L\Med\Research\99_System\LiteraturePipeline\exports\运动医学.json`

### Top-level structure

```json
{
  "config": { ... },
  "version": { ... },
  "collections": [ ... ],
  "items": [ ... ]
}
```

### Journal Article entry structure

```json
{
  "itemType": "journalArticle",
  "title": "Platelet-rich plasma for rotator cuff tendinopathy...",
  "citationKey": "a.hamidPlateletrichPlasmaRotator2021",
  "itemKey": "ME6BJZVS",
  "itemID": 12345,
  "attachments": [
    {
      "itemType": "attachment",
      "title": "PDF",
      "uri": "http://zotero.org/users/13781256/items/RU33UHK8",
      "path": "D:\\L\\Med\\Research\\99_System\\Zotero\\storage\\RU33UHK8\\A. Hamid... .pdf",
      "select": "zotero://select/library/items/RU33UHK8"
    }
  ]
}
```

### Attachment entry structure (standalone)

```json
{
  "itemType": "attachment",
  "title": "Seymour - 1977 - Osteolysis...",
  "path": "D:\\L\\Med\\Research\\99_System\\Zotero\\storage\\JY4AYIWW\\Seymour - 1977... .pdf",
  "uri": "http://zotero.org/users/13781256/items/JY4AYIWW",
  "select": "zotero://select/library/items/JY4AYIWW"
}
```

---

## 3. Path Format Analysis

### Real path format from BBT export

```
D:\L\Med\Research\99_System\Zotero\storage\<8位代码>\<原始文件名>.pdf
```

**Components:**
- `D:\L\Med\Research\99_System\Zotero\storage\` — Zotero 数据目录 + storage
- `<8位代码>` — Zotero item key (如 `RU33UHK8`, `JY4AYIWW`)
- `<原始文件名>` — 导入时的原始 PDF 文件名（可能含中文、特殊字符）

### Current code expectations (v1.2)

| 格式类型      | 示例                              | 来源         |
| ------------ | ---------------------------------- | ----------- |
| `storage:`前缀 | `storage:KEY/KEY.pdf`              | BBT 配置输出 |
| 裸相对路径    | `KEY/KEY.pdf`                      | BBT 默认输出 |
| 绝对路径      | `D:\...\Zotero\storage\KEY\...pdf` | **真实导出** |

**发现：当前代码主要处理 `storage:` 前缀和裸路径，但真实 BBT JSON 导出使用的是绝对 Windows 路径。**

---

## 4. Key Fields for Path Resolution

| 字段           | 示例值                                        | 用途                   |
| ------------- | --------------------------------------------- | ---------------------- |
| `citationKey`   | `a.hamidPlateletrichPlasmaRotator2021`        | 引用键，用于笔记文件名  |
| `itemKey`       | `ME6BJZVS`                                    | 主条目 Zotero key       |
| `attachments[0].path` | `D:\...\storage\RU33UHK8\...pdf`      | **PDF 绝对路径**        |
| `attachments[0].uri` | `http://zotero.org/users/.../RU33UHK8` | 附件 Zotero key         |
| `attachments[0].select` | `zotero://select/library/items/RU33UHK8` | Zotero 选择链接       |

**重要：**
- `itemKey` (主条目) ≠ attachments 中的 key (附件条目)
- 附件有自己的 Zotero key（在 `uri` 和 `select` 中）
- 附件 key 与 storage 目录名一致（`RU33UHK8`）

---

## 5. Multi-Attachment Scenario

**观察：** 一个文献可能有多个附件。

```json
"attachments": [
  { "title": "PDF", "path": "..." },           // 主 PDF
  { "title": "Supplementary", "path": "..." }  // 补充材料
]
```

**决策需求：**
- 哪个附件是"主 PDF"？（通常 `title == "PDF"`）
- 多个 PDF 时如何处理？（主 PDF + 辅助材料列表）

---

## 6. Path Normalization Requirements for v1.3

### Input formats to support

1. **绝对路径**（当前真实格式）
   ```
   D:\L\Med\Research\99_System\Zotero\storage\RU33UHK8\文件名.pdf
   ```

2. **`storage:` 相对路径**（BBT 配置可输出）
   ```
   storage:RU33UHK8/文件名.pdf
   ```

3. **裸相对路径**（BBT 默认）
   ```
   RU33UHK8/文件名.pdf
   ```

4. **URI 格式**（从 `uri` 字段组装）
   ```
   zotero://select/library/items/RU33UHK8
   ```

### Output requirements

1. **Vault 相对路径**（用于 Wikilink）
   ```
   system/Zotero/storage/RU33UHK8/文件名.pdf
   ```

2. **Obsidian Wikilink**
   ```markdown
   [[system/Zotero/storage/RU33UHK8/文件名.pdf]]
   ```

3. **Windows 路径**（用于本地文件操作）
   ```
   D:\L\Med\Research\99_System\Zotero\storage\RU33UHK8\文件名.pdf
   ```

---

## 7. Wikilink Standard (监工指定)

**格式：** `[[相对路径]]`

**要求：**
- 不使用 Markdown 标准链接 — 使用 `[[wikilink]]` 而非 `label → url` 格式
- 使用 Obsidian wikilink 语法
- 路径相对于 Vault 根目录
- 支持双链图谱和反向链接

**示例：**
```markdown
PDF链接：[[system/Zotero/storage/RU33UHK8/文件名.pdf]]
笔记链接：[[Literature/骨科/ME6BJZVS - 论文标题]]
```

**路径分隔符：**
- Vault 内使用 `/`（即使 Windows 系统）
- Obsidian 会自动处理跨平台路径

---

## 8. Implementation Strategy for v1.3

### New component: `paperforge/paths.py`

**Responsibilities:**
1. Parse BBT export JSON → 提取附件信息
2. 路径格式识别（绝对/相对/storage/URI）
3. 路径转换：
   - 绝对路径 ↔ Vault 相对路径
   - Windows `\` → Markdown `/`
4. Wikilink 生成
5. 多附件处理（主 PDF 识别）

**Function signatures (draft):**

```python
class ZoteroPathResolver:
    def __init__(self, zotero_data_dir: Path, vault_dir: Path):
        ...

    def resolve_attachment(self, item: dict) -> AttachmentInfo:
        """从 BBT item 解析附件路径"""
        ...

    def to_vault_relative(self, abs_path: Path) -> str:
        """绝对路径 → Vault 相对路径"""
        ...

    def to_wikilink(self, rel_path: str) -> str:
        """相对路径 → [[wikilink]]"""
        return f"[[{rel_path}]]"

    def get_storage_key(self, item: dict) -> str:
        """从 uri/select/path 提取 8位 Zotero key"""
        ...
```

### Test fixtures needed

- 单附件文献（标准情况）
- 多附件文献（主 PDF + 补充材料）
- 中文文件名
- 特殊字符文件名
- 绝对路径格式
- storage: 前缀格式
- 裸相对路径格式

---

## 9. Open Questions for v1.3 Planning

1. **BBT 配置：** 是否配置 BBT 输出相对路径而非绝对路径？（可减少解析复杂度）
2. **多附件策略：** 如何处理补充材料？（单独列出？忽略？）
3. **文件名冲突：** 同一 storage key 下多个 PDF 文件如何处理？
4. **软链接/junction：** Vault 中 `system/Zotero/` 是 junction 到真实 Zotero 目录，路径解析需考虑
5. **跨平台：** macOS/Linux 用户的 Zotero 路径格式是否一致？

---

## 10. Reference Data

### 示例文献（运动医学.json 第一条）

```yaml
Title: Platelet-rich plasma for rotator cuff tendinopathy: A systematic review and meta-analysis
CitationKey: a.hamidPlateletrichPlasmaRotator2021
ItemKey: ME6BJZVS
Attachment:
  - ZoteroKey: RU33UHK8
  - Path: D:\L\Med\Research\99_System\Zotero\storage\RU33UHK8\A. Hamid... .pdf
  - Type: PDF
```

### Zotero 存储统计

- **总目录数：** 1141
- **存储位置：** `D:\L\Med\Research\99_System\Zotero\storage\`
- **命名规则：** 8位随机字符（与 attachment uri 中的 item key 一致）

---

*Research archive created: 2026-04-24*
*For v1.3 path normalization phase planning*
