3 distinct bugs found and fixed:
1. TABLE in figure regex (_FIGURE_NUMBER_PATTERN)
Removed TABLE/Table from figure regex — caused table captions to be
extracted as figure numbers and roadmapped into figure inventory.
Added unit tests (table_numeric_caption_is_not_a_figure_number,
table_appendix_caption_marker_has_no_figure_number).
2. int block_id type mismatch in cross-page lookup
CrossPageSettlementPass and PrimarySamePagePass compared block_id
with === but deduped_legends use int keys while ResourceRef stores
str. Fixed by casting both to str. Table continuation lookup
missed page filter, picking wrong page's same block_id. Added
page filter + int_block_id tests.
3. Table appendix support gaps
- Table prefix regex only accepted digits/roman, not 'TABLE A1'.
Added [A-Z]\d+ token and strip-leading-alpha in parse.
- _is_validation_first_table_candidate didn't cover figure_title
raw_label blocks with table_caption_like style. Added second
gate.
- _is_weak_explicit_table_caption only checked table_caption roles.
Extended to include validation-first candidates.
- Same-page tie-break didn't apply for weak-explicit captions.
Ported _bare_table_tie_break into vnext pass.
- figure_caption_candidate not excluded from note attachment.
- Continuation merge stripped leading duplicate table marker.
M84CTEM9 vault verification: 6/6 figures matched (3 main + 3
appendix + assets), 4/4 tables (Table 1,2 + Table A1,A2 + assets),
0 false positives, 0 figure asset leakage.
|
||
|---|---|---|
| .agents/skills | ||
| .github | ||
| .husky | ||
| .omp | ||
| .opencode | ||
| .planning | ||
| .tmp/tail_pdf_samples | ||
| audit | ||
| docs | ||
| fixtures | ||
| node_modules | ||
| paperforge | ||
| project | ||
| scripts | ||
| tests | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| _master_funcs.txt | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CONTRIBUTING.md | ||
| INSTALLATION.md | ||
| LICENSE | ||
| manifest.json | ||
| OCR-V2-READINESS-SUMMARY.md | ||
| package-lock.json | ||
| package.json | ||
| paperforge.json | ||
| PROJECT-MANAGEMENT.md | ||
| pyproject.toml | ||
| README.en.md | ||
| README.md | ||
| README.zh-CN.md | ||
| README.zh.md | ||
| requirements.txt | ||
| REVIEW.md | ||
| skills-lock.json | ||
PaperForge
简体中文 · English
铸知识为器,启洞见之明。 — Forge Knowledge, Empower Insight.
PaperForge brings your Zotero library into Obsidian. Sync papers, run OCR, extract figures, and do AI-assisted deep reading — all inside a single vault.
0. What PaperForge Is
PaperForge is not just an Obsidian plugin. It has two parts:
| Part | What | Does | Where |
|---|---|---|---|
| Obsidian Plugin | main.js + manifest.json + styles.css |
Dashboard, buttons, settings UI | .obsidian/plugins/paperforge/ in your vault |
| Python Package | paperforge |
Sync, OCR, Doctor, repair | Your system Python (pip install) |
The plugin is the interface. The Python package is the engine. Every button you click in the plugin actually runs a Python command behind the scenes.
After installing the plugin, you MUST verify that the Python package is also installed and version-matched.
1. Install the Obsidian Plugin
Option A: BRAT (Recommended)
- Install BRAT from the Obsidian community plugin browser
- Open BRAT settings →
Add Beta Plugin - Enter:
https://github.com/LLLin000/PaperForge - BRAT downloads the latest
main.js,manifest.json, andstyles.cssand installs them - Settings → Community Plugins → enable PaperForge
BRAT auto-detects GitHub Release updates. No manual downloads needed.
Option B: Manual Download
- Go to Releases
- Download the three files:
main.js,manifest.json,styles.css - Create
.obsidian/plugins/paperforge/in your vault - Put the three files there
- Restart Obsidian → Settings → Community Plugins → enable PaperForge
Manual install does not auto-update. You'll need to re-download for each new version.
2. Install the Python Package
After enabling the plugin, open the PaperForge settings tab. You'll see a Runtime Status section:
Plugin v1.5.0 → Python Package v1.5.0 ✓ Matched
- If it says "Not installed" → click Open Wizard to re-run the setup process
- If it says "Mismatch" → the Python package auto-updates when the plugin updates. If it didn't succeed, click Update Runtime to manually trigger
3. Quickstart
# 1. Export from Zotero (Better BibTeX JSON, Keep updated) to exports/
# 2. Sync
paperforge sync
# 3. Mark a paper for OCR in its frontmatter: do_ocr: true
# 4. Run OCR
paperforge ocr
# 5. Mark for deep reading: analyze: true
# 6. In your Agent chat:
/pf-deep <zotero_key>
Documentation
| If you want to | Read |
|---|---|
| Full tutorial, from install to deep read | Getting Started |
| Troubleshooting | Troubleshooting |
| Command reference | Commands |
| How to update | Update Guide |
| Architecture / Maintenance / Release | Architecture |
| AI Agent collaboration | AGENTS.md |
License
CC BY-NC-SA 4.0. Non-commercial use only.
Acknowledgments
Built on PaddleOCR, Obsidian, Better BibTeX for Zotero, and other great open-source projects.