Ignacio Ballesteros d319087c44 fix repo url
2026-02-17 22:37:16 +01:00
2026-02-17 22:37:16 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 22:37:16 +01:00
2026-02-17 21:25:46 +01:00
2026-02-17 21:25:46 +01:00

Zotero Org Export Annotations

Export PDF and EPUB annotations from Zotero to Org-mode files for use with Emacs, org-roam, and citar.

Features

  • Export annotations to individual Org files named by citation key
  • Automatic export after Zotero sync completes
  • Export when closing a PDF/EPUB reader tab
  • Configurable output directory
  • Optional attachment of Org files to Zotero items

Requirements

Installation

  1. Install the Better Notes plugin first (see its own instructions)
  2. Install Pandoc and ensure it is on your PATH (or note its full path)
  3. Download the latest .xpi file from Releases
  4. In Zotero, go to Tools → Add-ons
  5. Click the gear icon (top-right) and select Install Add-on From File...
  6. Select the downloaded .xpi file and restart Zotero if prompted

Configuration

After installation, open Tools → Org Export Preferences to configure:

Preference Default Description
Notes Directory (empty) Directory where Org files will be saved. Supports ~ for home.
Pandoc Path pandoc Full path to the pandoc binary if not on PATH
Attach Org file to item false Link exported Org files as Zotero attachments
Auto-export on sync true Export automatically after Zotero sync completes
Export on tab close true Export when closing a PDF/EPUB reader tab
Show notifications true Display a progress notification during export
Debug mode false Enable verbose logging to the Zotero error console

Usage

Manual Export

  • Export all items: Tools → Export All Annotations to Org
  • Export selected items: Right-click one or more items → Export Annotations to Org

Automatic Export

When enabled in preferences, exports happen automatically:

  • After a Zotero sync completes (only items with new/changed annotations are exported)
  • When you close a PDF or EPUB reader tab

Output Format

Files are written to the configured Notes Directory, named by citation key:

~/org/notes/smith2020.org
~/org/notes/doe2019.org

Each file contains:

#+title: The Full Title of the Referenced Work

* Annotation heading
  Converted annotation text...

Only items that have a citation key (via Better BibTeX or the citationKey field) will be exported.

For Maintainers

This section covers building, developing, and releasing the plugin.

Architecture

src/
├── index.ts          # Entry point: mounts addon to Zotero global
├── addon.ts          # Core addon class (logging, init, module wiring)
├── hooks.ts          # Lifecycle hooks (startup/shutdown, menu actions)
└── modules/
    ├── prefs.ts      # Typed read/write for all preferences
    ├── exporter.ts   # Attachment detection, sync checking, batch export
    ├── converter.ts  # Markdown → Org via pandoc, file I/O
    ├── notifier.ts   # Zotero event handlers (sync finish, tab close)
    └── menu.ts       # Menu registration (Zotero 7 + 8 compatible)

addon/                # Static plugin files copied verbatim into the XPI
├── manifest.json
├── bootstrap.js      # Zotero plugin lifecycle entry point
├── prefs.js          # Default preference values
└── content/
    ├── preferences.xhtml   # Preferences pane UI (XUL)
    ├── scripts/preferences.js
    ├── icons/
    └── locale/en-US/       # Fluent (.ftl) string bundles

The build system uses zotero-plugin-scaffold with esbuild, which bundles src/ into a single index.js and packages everything as an XPI.

Prerequisites

With Nix (recommended):

# Requires Nix with flakes enabled
nix develop

This provides Node.js 20, npm, TypeScript, ESLint, Prettier, and Pandoc.

Without Nix:

  • Node.js 20+
  • npm
  • Pandoc (for manual testing)
npm install

Environment Setup

Copy the environment template and fill in your local paths:

cp .env.example .env

Edit .env:

# Path to the Zotero binary (required for the dev server)
ZOTERO_PLUGIN_ZOTERO_BIN_PATH=/path/to/zotero

# Path to a Zotero development profile directory
ZOTERO_PLUGIN_PROFILE_PATH=/path/to/zotero-dev-profile

Create a dedicated Zotero profile for development to avoid affecting your main library.

Development Workflow

# Start the dev server — builds and hot-reloads the plugin into a running Zotero instance
npm start

# One-off build — outputs XPI to .scaffold/build/
npm run build

# Lint TypeScript source
npm run lint
npm run lint:fix    # auto-fix

# Format source files
npm run format
npm run format:check   # check without writing

The dev server (npm start) watches for changes in src/ and addon/, rebuilds, and reloads the plugin inside Zotero automatically. Zotero must already be running with the configured profile.

Testing

There are no automated tests. To test manually:

  1. npm run build to produce the XPI
  2. Install the XPI in a Zotero 7 instance via Tools → Add-ons → Install Add-on From File...
  3. Exercise the export functionality manually via the Tools menu and right-click context menu

Releasing

Releases are created by pushing a version tag. The CI/CD pipeline (Gitea Actions) will build the XPI and publish a release automatically.

To cut a release locally:

npm run release

This runs bumpp interactively to select the new version, then:

  1. Updates package.json version
  2. Commits and tags the version
  3. Pushes the commit and tag to the remote
  4. Builds the XPI

Once the tag is pushed, Gitea Actions takes over and creates the release with the XPI attached.

Code Style

  • Formatter: Prettier (config in .prettierrc) — double quotes, 2-space indent, semicolons
  • Linter: ESLint with TypeScript-ESLint (config in .eslintrc.js) — strict mode
  • Naming: PascalCase for classes/types, camelCase for functions/methods, UPPER_SNAKE_CASE for constants
  • Imports: relative paths, import type for type-only imports, no namespace imports
  • Error handling: always catch with a typed error as Error; use _error for non-critical ignores

See AGENTS.md for the full style guide used during AI-assisted development.

License

GPL-3.0-or-later

Credits

Based on the zotero-plugin-template by windingwind.

Description
No description provided
Readme 150 KiB
v1.0.1 Latest
2026-02-17 23:56:10 +01:00
Languages
TypeScript 68.7%
JavaScript 11.2%
HTML 8.1%
Nix 6.6%
Fluent 5.4%