- id-based incremental (new_ids - prev_integrated_ids) with --full flag, kindle-id tag, deletions handling - Mappings tab with delete to return to Conflicts, sorted by updated_at newest first - Integrated tab with Added On / Integrated dates and Citekey - black over white iA Writer Duo theme, candidate-list per-row Use buttons, resizable/sortable tables - Settings editable + save, Artifacts Open/Reveal, Re-import bar with last file reuse - Fix override single-field validation and ignore cleanup |
||
|---|---|---|
| docs | ||
| maschine | ||
| plugin | ||
| scripts | ||
| src/kindle_zotero_importer | ||
| .gitignore | ||
| main.py | ||
| match-overrides.json | ||
| MEMORY.md | ||
| plugin_runner.py | ||
| pyproject.toml | ||
| README.md | ||
| zotero-writer.js | ||
Kindle Zotero Importer
Prototype importer for turning Kindle My Clippings.txt entries into a JSON import plan that Zotero can later write as native annotations.
The project intentionally keeps Zotero writes out of Python. Python parses, matches, and plans. Zotero JavaScript, and eventually a Zotero plugin, will perform annotation creation through Zotero's own APIs.
Current Milestone
Parse Kindle clippings and emit a stable JSON preview:
python -m kindle_zotero_importer parse "/path/to/My Clippings.txt" --output clippings.json
Index Zotero items and PDF/EPUB attachments read-only:
python -m kindle_zotero_importer index-zotero --output zotero-index.json
Match parsed Kindle titles to Zotero items:
python -m kindle_zotero_importer match clippings.json zotero-index.json --overrides match-overrides.json --output matches.json
Generate reusable manual overrides for ambiguous/unmatched titles:
python -m kindle_zotero_importer generate-overrides matches.json --output match-overrides.generated.json --pretty
Generated overrides are designed for batch editing: unresolved titles are sorted by clipping count, unmatched titles default to ignore: true, and already-entered overrides are kept at the end as an audit trail. Replace ignore with a confirmed citation_key, zotero_key, or zotero_item_id to import a title instead of discarding it.
Apply reviewed overrides:
python -m kindle_zotero_importer match clippings.json zotero-index.json --overrides match-overrides.json --output matches.json
Keep confirmed mappings in match-overrides.json. The match-overrides.generated.json file is only a disposable review skeleton and can be regenerated from the current matches.json at any time.
To permanently skip a Kindle title that should not be imported, add an ignore override:
{
"clipping_title": "Example Kindle Title",
"resolution": {
"ignore": true
}
}
If a matched Zotero item has multiple usable PDF/EPUB attachments, add the selected attachment to the same override entry:
{
"clipping_title": "Example Kindle Title",
"resolution": {
"citation_key": "example2024",
"attachment_key": "ABC12345"
}
}
Use either attachment_key or attachment_item_id. Attachment choices are listed in docs/mismatch-review.md when an item is ambiguous.
For cumulative Kindle exports, rerun the whole pipeline against the latest My Clippings.txt. Previously confirmed overrides in match-overrides.json will be applied automatically to old and new clippings.
Review unresolved cases in docs/mismatch-review.md after each run. Prioritize:
matched-title-no-attachment: add/link the missing PDF or EPUB in Zotero.unmatched-title: add a confirmed title mapping tomatch-overrides.json.- position failures: improve text/position matching or handle manually.
Regenerate the copy-friendly review report:
python -m kindle_zotero_importer review-mismatches import-plan.positioned.json matches.json --output docs/mismatch-review.md
Each reviewed title includes a YAML-style block with standalone keys such as clipping_title, citation_key, zotero_item_id, zotero_key, and override_entry for easy copying.
Generate a preliminary import plan for matched titles:
python -m kindle_zotero_importer plan clippings.json zotero-index.json matches.json --output import-plan.json --pretty
Position annotations and export the Zotero writer plan:
python -m kindle_zotero_importer position-epub import-plan.json --output import-plan.epub.json --pretty
python -m kindle_zotero_importer position-pdf import-plan.epub.json --output import-plan.positioned.json --pretty
python -m kindle_zotero_importer finalize import-plan.positioned.json --output import-plan.final.json --pretty
PDF positioning uses Poppler tools (pdftotext, pdftohtml, pdfinfo). If a PDF permits viewing but blocks text copying, the importer retries extraction through a temporary qpdf --decrypt copy. The Zotero attachment itself is not modified.
Safety Rule
Do not write directly to zotero.sqlite. Use read-only SQLite access for indexing and Zotero's JavaScript API for writes.
Zotero Plugin Wrapper
The plugin/ directory contains a hybrid Zotero plugin with one user-facing Tools action. It lets the user choose My Clippings.txt, runs the importer with visible progress, and writes positioned annotations through Zotero's native APIs. Unresolved cases are reported after the import; intermediate JSON artifacts are implementation details.
Build the plugin package:
python scripts/build_plugin.py
Install dist/kindle-zotero-importer.xpi in Zotero via Tools > Plugins. Open Tools > Kindle Zotero Importer..., choose My Clippings.txt, and keep the manager open to see the current stage, percentage, elapsed time, and final annotation counts.
The XPI manifest targets Zotero 6.999 through 10.0.*.