Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot]
58a5912246
Bump the all-non-major group with 7 updates
Bumps the all-non-major group with 7 updates:

| Package | From | To |
| --- | --- | --- |
| [zotero-plugin-toolkit](https://github.com/windingwind/zotero-plugin-toolkit) | `5.1.0-beta.13` | `5.1.2` |
| [@zotero-plugin/eslint-config](https://github.com/zotero-plugin-dev/eslint-config) | `0.6.7` | `0.6.9` |
| [chai](https://github.com/chaijs/chai) | `6.2.1` | `6.2.2` |
| [mocha](https://github.com/mochajs/mocha) | `11.7.5` | `11.7.6` |
| [prettier](https://github.com/prettier/prettier) | `3.7.4` | `3.8.4` |
| [zotero-plugin-scaffold](https://github.com/zotero-plugin-dev/zotero-plugin-scaffold) | `0.8.2` | `0.8.6` |
| [zotero-types](https://github.com/windingwind/zotero-types) | `4.1.0-beta.4` | `4.1.2` |


Updates `zotero-plugin-toolkit` from 5.1.0-beta.13 to 5.1.2
- [Release notes](https://github.com/windingwind/zotero-plugin-toolkit/releases)
- [Commits](https://github.com/windingwind/zotero-plugin-toolkit/compare/v5.1.0-beta.13...v5.1.2)

Updates `@zotero-plugin/eslint-config` from 0.6.7 to 0.6.9
- [Release notes](https://github.com/zotero-plugin-dev/eslint-config/releases)
- [Commits](https://github.com/zotero-plugin-dev/eslint-config/compare/v0.6.7...v0.6.9)

Updates `chai` from 6.2.1 to 6.2.2
- [Release notes](https://github.com/chaijs/chai/releases)
- [Changelog](https://github.com/chaijs/chai/blob/main/History.md)
- [Commits](https://github.com/chaijs/chai/compare/v6.2.1...v6.2.2)

Updates `mocha` from 11.7.5 to 11.7.6
- [Release notes](https://github.com/mochajs/mocha/releases)
- [Changelog](https://github.com/mochajs/mocha/blob/v11.7.6/CHANGELOG.md)
- [Commits](https://github.com/mochajs/mocha/compare/v11.7.5...v11.7.6)

Updates `prettier` from 3.7.4 to 3.8.4
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](https://github.com/prettier/prettier/compare/3.7.4...3.8.4)

Updates `zotero-plugin-scaffold` from 0.8.2 to 0.8.6
- [Release notes](https://github.com/zotero-plugin-dev/zotero-plugin-scaffold/releases)
- [Commits](https://github.com/zotero-plugin-dev/zotero-plugin-scaffold/compare/v0.8.2...v0.8.6)

Updates `zotero-types` from 4.1.0-beta.4 to 4.1.2
- [Release notes](https://github.com/windingwind/zotero-types/releases)
- [Commits](https://github.com/windingwind/zotero-types/compare/v4.1.0-beta.4...v4.1.2)

---
updated-dependencies:
- dependency-name: zotero-plugin-toolkit
  dependency-version: 5.1.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all-non-major
- dependency-name: "@zotero-plugin/eslint-config"
  dependency-version: 0.6.9
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-non-major
- dependency-name: chai
  dependency-version: 6.2.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-non-major
- dependency-name: mocha
  dependency-version: 11.7.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-non-major
- dependency-name: prettier
  dependency-version: 3.8.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: all-non-major
- dependency-name: zotero-plugin-scaffold
  dependency-version: 0.8.6
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-non-major
- dependency-name: zotero-types
  dependency-version: 4.1.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all-non-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-10 17:11:46 +00:00
12 changed files with 769 additions and 854 deletions

16
.github/dependabot.yml vendored Normal file
View File

@ -0,0 +1,16 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
groups:
all-non-major:
update-types:
- "minor"
- "patch"

4
.github/renovate.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["github>zotero-plugin-dev/renovate-config"]
}

44
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,44 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
jobs:
lint:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GitHub_TOKEN }}
steps:
- name: Setup JS
uses: zotero-plugin-dev/workflows/setup-js@main
- name: Run Lint
run: npm run lint:check
build:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GitHub_TOKEN }}
steps:
- name: Setup JS
uses: zotero-plugin-dev/workflows/setup-js@main
- name: Run Build
run: npm run build
- name: Upload build result
uses: actions/upload-artifact@v4
with:
name: build-result
path: .scaffold/build
test:
runs-on: ubuntu-latest
needs:
- build
steps:
- name: Setup JS
uses: zotero-plugin-dev/workflows/setup-js@main
- run: npm run test

20
.github/workflows/issue-bot.yml vendored Normal file
View File

@ -0,0 +1,20 @@
name: Issue Bot
on:
issues:
types:
- labeled
issue_comment:
types:
- created
schedule:
- cron: "30 1 * * *"
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
issue-bot:
uses: zotero-plugin-dev/workflows/.github/workflows/issue-bot.yml@main

21
.github/workflows/release.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: Release
on:
push:
tags:
- v**
permissions:
contents: write
issues: write
pull-requests: write
jobs:
create-release:
uses: zotero-plugin-dev/workflows/.github/workflows/release-plugin.yml@main
# You can customize any of the inputs here.
# If you omit an input, its default value will be used.
with:
build: "npm run build"
release: "npm run release"
secrets: inherit

View File

@ -1,68 +1,11 @@
# Zotero PDF Copier & Renamer
[![Download XPI](https://img.shields.io/badge/Download-zotero--pdf--copier--renamer.xpi-brightgreen?style=for-the-badge&logo=github)](https://github.com/iu-parvej/Zotero-PDF-Copier-Renamer/releases/download/v1.0.0/zotero-pdf-copier-renamer.xpi)
A powerful, lightweight, and restartless add-on for **Zotero 7, 8, and 9** that lets you copy attached PDF documents from selected bibliography references into any folder on your computer. Copied PDFs are automatically renamed based on the paper's title (sanitized for safe OS filenames) and index-deduplicated.
> [!IMPORTANT]
> **Instant Bulk Exporting**: This extension is built specifically to process **multiple references at once**. Select dozens or hundreds of papers, right-click, choose your folder, and all attached PDFs are renamed and saved in a split second. No manual clicks, no tedious per-file folder navigation, and no slow popup loops!
Developed and designed with custom branding and a native graphical interface.
---
## Screenshots & Preview
### 1. Seamless Context Menu Integration
Select your bibliography references, right-click, and select **Copy Attachments to Folder...** to begin the export:
<p align="center">
<img src="assets/context_menu.png" alt="Right-click Context Menu" width="80%">
</p>
### 2. Live Status & Copy Completion
A native popup notification tracks the copy operation and confirms when the files have been copied successfully:
<p align="center">
<img src="assets/copy_completed.png" alt="Copy Completed Toast" width="60%">
</p>
### 3. Clean Zotero Add-ons Listing
The extension is fully integrated with Zotero's Add-ons manager, showing the custom icon, updated author info, homepage, and version metadata:
<p align="center">
<img src="assets/addon_manager.png" alt="Add-ons Manager Listing" width="90%">
</p>
---
## Detailed Description
**Zotero PDF Copier & Renamer** is a professional-grade productivity extension built from the ground up for researchers, students, academics, and knowledge managers who utilize Zotero 7, 8, or 9 as their primary reference management system. While Zotero is incredibly powerful for cataloging reference metadata, fetching citation records, and organizing library items, extracting the actual PDF attachments for external use has always been a painful, friction-heavy process.
By default, Zotero abstracts files inside a local database storage system. Each PDF is hidden inside a separate, randomly generated alphanumeric directory (such as `Zotero/storage/3A8B9CDF/`). While this hashed architecture is crucial for Zotero's database integrity and synchronization stability, it makes the physical files completely inaccessible to users wishing to browse their papers locally. If you want to copy a set of papers to a USB drive, upload them to a shared cloud folder, email them to a colleague, or send them to an iPad/tablet for reading, you must open each folder manually or rely on clunky workarounds. Furthermore, Zotero's downloaded files are often named generically (like `fulltext.pdf`, `manuscript.pdf`, or abbreviated author names), stripping away the context of the research paper itself.
This addon solves these limitations elegantly by introducing a native right-click context menu option that allows users to instantly copy the PDF attachments of all selected items directly to any target folder on their computer. The files are not just copied; they are dynamically processed, sanitized, and renamed based on the actual paper titles stored in Zotero's database.
### Why It Is Essential
1. **Intelligent Metadata-Driven Renaming**:
Instead of keeping obscure or generic filenames, the extension reads the parent item's official title metadata dynamically. It reformats the file name to be clean, human-readable, and highly descriptive. For example, a file stored as `fulltext.pdf` inside `Zotero/storage/7J8KL9MN/` is copied and renamed to `A Deep Learning Approach to Climate Modeling.pdf`.
2. **Advanced Filename Sanitization**:
Different operating systems (Windows, macOS, and Linux) have different rules and reserved characters for filenames. To prevent errors and system crashes during copy operations, the addon features a robust sanitization engine. It automatically strips or replaces illegal characters—such as colons (`:`), question marks (`?`), backslashes (`\`), forward slashes (`/`), asterisks (`*`), vertical bars (`|`), quotation marks (`"`), and inequality brackets (`<`, `>`)—ensuring absolute file path compatibility across any filesystem (NTFS, APFS, ext4).
3. **Smart Collision & Multi-Attachment Resolution**:
In high-volume research, naming conflicts are inevitable. You might have multiple papers with identical titles, or a single bibliographic entry might have multiple associated PDF files (for instance, the main article, a supplemental figures document, and a pre-print version). The addon handles this seamlessly. If a file with the target name already exists in the destination folder, or if there are multiple PDFs attached to a single item, the plugin automatically appends a numeric suffix (e.g., `Deep Learning Approach_(1).pdf`, `Deep Learning Approach_(2).pdf`), preventing accidental data loss or file overwriting.
4. **Modern, Native UI & Smooth User Experience**:
Leveraging Zotero's native user interface libraries, the extension integrates seamlessly into the application window. When a copy operation begins, a clean, modern notification popup appears in the bottom-right corner of Zotero. It features a graphical, animated progress bar using Zotero's native `ItemProgress` layout. This displays the percentage of files copied, a detailed text indicator of the specific paper currently being processed, and a visual loader. Once the operation is complete, the modal stays open for 5 seconds to let you confirm success, and then closes itself automatically. Users can also dismiss it instantly by clicking a close button or clicking anywhere on the popup.
5. **Future-Proof Gecko Integration**:
Built on Zotero's bootstrapped architecture, the addon is fully compatible with Zotero 7, Zotero 8, and Zotero 9. It incorporates advanced API compatibility layers to handle changes in Mozilla's Gecko engine, specifically addressing Gecko 128+ file picker standards by using `window.browsingContext` fallback logic, ensuring a smooth, crash-free experience on all modern and future Zotero versions.
---
## Developer Details
- **Author**: Md. Parvej Hossain
@ -74,7 +17,6 @@ This addon solves these limitations elegantly by introducing a native right-clic
## Key Features
- **Fast Bulk Exporting**: Optimized for batch actions. Select multiple items (tens or hundreds of references) at once, and copy all their attached PDFs simultaneously in less than a second without clicking any manual folder pickers for each file or dealing with popup loops.
- **Direct Context Menu Access**: Right-click on any selected items in the main library grid pane to start copying instantly.
- **Visual Icon Registration**: Custom branded icon next to the context menu command and inside the Zotero Extensions listing for quick visual recognition.
- **Smart PDF Copying**: Filters all selected items to only copy actual PDF files (skips notes, web links, or citations that do not have attachments).
@ -119,13 +61,12 @@ To package the extension from source:
## Installation Guide
1. **Download the Extension**: Click [here to download the latest `zotero-pdf-copier-renamer.xpi` release](https://github.com/iu-parvej/Zotero-PDF-Copier-Renamer/releases/download/v1.0.0/zotero-pdf-copier-renamer.xpi).
2. Open **Zotero** on your computer.
3. Go to the top menu: **Tools -> Add-ons** (or **Extensions**).
4. Click the gear icon (`⚙️`) in the top-right corner of the Add-ons manager page.
5. Select **Install Add-on From File...**.
6. Select the downloaded **`zotero-pdf-copier-renamer.xpi`** file.
7. Click **Install** and restart Zotero when prompted.
1. Open **Zotero** on your computer.
2. Go to the top menu: **Tools -> Add-ons** (or **Extensions**).
3. Click the gear icon (`⚙️`) in the top-right corner of the Add-ons manager page.
4. Select **Install Add-on From File...**.
5. Select the generated **`zotero-pdf-copier-renamer.xpi`** file.
6. Click **Install** and restart Zotero when prompted.
---

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

1427
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,13 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/iu-parvej/Zotero-PDF-Copier-Renamer.git"
"url": "git+https://github.com/windingwind/zotero-plugin-template.git"
},
"author": "Md. Parvej Hossain <contact@parvej.me>",
"bugs": {
"url": "https://github.com/iu-parvej/Zotero-PDF-Copier-Renamer/issues"
"url": "https://github.com/windingwind/zotero-plugin-template/issues"
},
"homepage": "https://github.com/iu-parvej/Zotero-PDF-Copier-Renamer#readme",
"homepage": "https://github.com/windingwind/zotero-plugin-template#readme",
"license": "AGPL-3.0-or-later",
"scripts": {
"start": "zotero-plugin serve",
@ -30,20 +30,20 @@
"update-deps": "npm update --save"
},
"dependencies": {
"zotero-plugin-toolkit": "^5.1.0-beta.13"
"zotero-plugin-toolkit": "^5.1.2"
},
"devDependencies": {
"@types/chai": "^5.2.3",
"@types/mocha": "^10.0.10",
"@types/node": "^24.10.0",
"@zotero-plugin/eslint-config": "^0.6.7",
"chai": "^6.2.1",
"@zotero-plugin/eslint-config": "^0.6.9",
"chai": "^6.2.2",
"eslint": "^9.39.2",
"mocha": "^11.7.5",
"prettier": "^3.7.4",
"mocha": "^11.7.6",
"prettier": "^3.8.4",
"typescript": "^5.9.3",
"zotero-plugin-scaffold": "^0.8.2",
"zotero-types": "^4.1.0-beta.4"
"zotero-plugin-scaffold": "^0.8.6",
"zotero-types": "^4.1.2"
},
"prettier": {
"printWidth": 80,

Binary file not shown.