pdf-diff-viewer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/LICENSE +21 -0
- package/README.md +302 -0
- package/bin/cli.js +2 -0
- package/package.json +63 -0
- package/public/app.js +588 -0
- package/public/index.html +39 -0
- package/server.js +20 -0
- package/src/PDFDiffViewer.js +638 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.0] - 2026-01-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- Initial release
|
|
7
|
+
- Embeddable PDFDiffViewer class for programmatic use
|
|
8
|
+
- Framework-agnostic vanilla JavaScript library
|
|
9
|
+
- Support for File, ArrayBuffer, and Uint8Array inputs
|
|
10
|
+
- Comprehensive API with configurable options
|
|
11
|
+
- Smart alignment algorithm for handling layout shifts
|
|
12
|
+
- Word-level text detection and highlighting
|
|
13
|
+
- Crop and mask regions support
|
|
14
|
+
- Standalone web application mode
|
|
15
|
+
- CLI support via `npx pdf-diff-viewer`
|
|
16
|
+
- Example implementation in `example/index.html`
|
|
17
|
+
- Full API documentation in README
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
- Client-side PDF comparison using PDF.js
|
|
21
|
+
- Zero system dependencies
|
|
22
|
+
- Privacy-focused (no server uploads)
|
|
23
|
+
- Visual diff overlays with configurable transparency
|
|
24
|
+
- Auto-detection of word boundaries
|
|
25
|
+
- Customizable rendering scale and tolerances
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 pdf-diff-viewer
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# PDF Diff Viewer
|
|
2
|
+
|
|
3
|
+
A browser-based PDF comparison library with intelligent visual diff highlighting. Compare PDFs instantly without installation or system dependencies. Works as both a standalone app and an embeddable library.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
## ✨ Features
|
|
9
|
+
|
|
10
|
+
- **🌐 Browser-Based** - Runs entirely in the browser using PDF.js
|
|
11
|
+
- **📦 Embeddable Library** - Import and use in your own applications
|
|
12
|
+
- **🚀 Zero Setup** - No GraphicsMagick, ImageMagick, or GhostScript required
|
|
13
|
+
- **🔒 Privacy First** - PDFs never leave your machine, all processing is client-side
|
|
14
|
+
- **🎯 Smart Alignment** - Auto-alignment algorithm handles minor layout shifts
|
|
15
|
+
- **📝 Word-Level Detection** - Intelligent text extraction with word-level highlighting
|
|
16
|
+
- **⚡ Instant Feedback** - Real-time visual diff with color-coded differences
|
|
17
|
+
- **🎨 Visual Overlay** - Side-by-side comparison with highlighted changes
|
|
18
|
+
- **💻 Cross-Platform** - Works on any OS with a modern browser
|
|
19
|
+
- **🔧 Configurable** - Extensive options for customization
|
|
20
|
+
|
|
21
|
+
## 🚀 Quick Start
|
|
22
|
+
|
|
23
|
+
### Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install pdf-diff-viewer
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Programmatic Usage (Embed in Your App)
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
// Import the library
|
|
33
|
+
import PDFDiffViewer from 'pdf-diff-viewer';
|
|
34
|
+
|
|
35
|
+
// Or in browser (after including the script)
|
|
36
|
+
// <script src="node_modules/pdf-diff-viewer/src/PDFDiffViewer.js"></script>
|
|
37
|
+
|
|
38
|
+
// Create an instance
|
|
39
|
+
const viewer = new PDFDiffViewer('#results-container', {
|
|
40
|
+
scale: 3.0,
|
|
41
|
+
labelA: 'Original',
|
|
42
|
+
labelB: 'Modified',
|
|
43
|
+
highlightAlpha: 0.32
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// Compare PDFs (accepts File objects, ArrayBuffers, or Uint8Arrays)
|
|
47
|
+
const fileA = document.getElementById('fileA').files[0];
|
|
48
|
+
const fileB = document.getElementById('fileB').files[0];
|
|
49
|
+
|
|
50
|
+
viewer.compare(fileA, fileB)
|
|
51
|
+
.then(results => {
|
|
52
|
+
console.log('Comparison complete:', results);
|
|
53
|
+
console.log('Total pages:', results.totalPages);
|
|
54
|
+
console.log('Total diff pixels:', results.totalDiffPixels);
|
|
55
|
+
})
|
|
56
|
+
.catch(error => {
|
|
57
|
+
console.error('Comparison failed:', error);
|
|
58
|
+
});
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### HTML Setup
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<!DOCTYPE html>
|
|
65
|
+
<html>
|
|
66
|
+
<head>
|
|
67
|
+
<title>PDF Comparison</title>
|
|
68
|
+
<!-- Include PDF.js -->
|
|
69
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
|
|
70
|
+
</head>
|
|
71
|
+
<body>
|
|
72
|
+
<input type="file" id="fileA" accept="application/pdf">
|
|
73
|
+
<input type="file" id="fileB" accept="application/pdf">
|
|
74
|
+
<button onclick="comparePDFs()">Compare</button>
|
|
75
|
+
|
|
76
|
+
<div id="results"></div>
|
|
77
|
+
|
|
78
|
+
<!-- Include PDFDiffViewer -->
|
|
79
|
+
<script src="node_modules/pdf-diff-viewer/src/PDFDiffViewer.js"></script>
|
|
80
|
+
<script>
|
|
81
|
+
function comparePDFs() {
|
|
82
|
+
const viewer = new PDFDiffViewer('#results');
|
|
83
|
+
const fileA = document.getElementById('fileA').files[0];
|
|
84
|
+
const fileB = document.getElementById('fileB').files[0];
|
|
85
|
+
|
|
86
|
+
viewer.compare(fileA, fileB);
|
|
87
|
+
}
|
|
88
|
+
</script>
|
|
89
|
+
</body>
|
|
90
|
+
</html>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Standalone Server Mode
|
|
94
|
+
|
|
95
|
+
Run as a standalone web server:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
npx pdf-diff-viewer
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Then open your browser to `http://localhost:3000`
|
|
102
|
+
|
|
103
|
+
**Custom port:**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
PORT=8080 npx pdf-diff-viewer
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Direct Browser Use (No npm)
|
|
110
|
+
|
|
111
|
+
Simply open `public/index.html` directly in your browser - no server or npm required!
|
|
112
|
+
|
|
113
|
+
## 📖 How It Works
|
|
114
|
+
|
|
115
|
+
1. Select two PDF files using the file inputs (or pass them programmatically)
|
|
116
|
+
2. Click "Compare PDFs" (or call `viewer.compare(pdfA, pdfB)`)
|
|
117
|
+
3. View the visual diff with highlighted differences
|
|
118
|
+
4. Red highlights show changed or different content
|
|
119
|
+
5. Auto-alignment compensates for minor layout shifts
|
|
120
|
+
|
|
121
|
+
## 📚 API Reference
|
|
122
|
+
|
|
123
|
+
### Constructor
|
|
124
|
+
|
|
125
|
+
```javascript
|
|
126
|
+
new PDFDiffViewer(container, options)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Parameters:**
|
|
130
|
+
- `container` (string|HTMLElement) - CSS selector or DOM element to render results
|
|
131
|
+
- `options` (Object) - Configuration options
|
|
132
|
+
|
|
133
|
+
**Options:**
|
|
134
|
+
- `scale` (number) - PDF rendering scale, default: 3.0 (~300 DPI)
|
|
135
|
+
- `maxShift` (number) - Max pixel shift for alignment, default: 3
|
|
136
|
+
- `colorTolerance` (number) - Color difference threshold, default: 120
|
|
137
|
+
- `minHighlightArea` (number) - Min area to highlight in pixels, default: 60
|
|
138
|
+
- `minWordSize` (number) - Min word box size in pixels, default: 8
|
|
139
|
+
- `highlightAlpha` (number) - Highlight transparency, default: 0.32
|
|
140
|
+
- `labelA` (string) - Label for first document, default: 'Document A'
|
|
141
|
+
- `labelB` (string) - Label for second document, default: 'Document B'
|
|
142
|
+
- `showPageNumbers` (boolean) - Show page numbers, default: true
|
|
143
|
+
- `cropRegions` (Array) - Regions to crop: `[{ page: 1, x, y, width, height }]`
|
|
144
|
+
- `maskRegions` (Array) - Regions to mask/ignore: `[{ page: 1, x, y, width, height }]`
|
|
145
|
+
|
|
146
|
+
### Methods
|
|
147
|
+
|
|
148
|
+
#### `compare(pdfA, pdfB)`
|
|
149
|
+
|
|
150
|
+
Compare two PDFs and render results.
|
|
151
|
+
|
|
152
|
+
**Parameters:**
|
|
153
|
+
- `pdfA` (File|ArrayBuffer|Uint8Array) - First PDF
|
|
154
|
+
- `pdfB` (File|ArrayBuffer|Uint8Array) - Second PDF
|
|
155
|
+
|
|
156
|
+
**Returns:** Promise<Object> - Comparison results with:
|
|
157
|
+
- `totalPages` - Number of pages compared
|
|
158
|
+
- `totalDiffPixels` - Total different pixels across all pages
|
|
159
|
+
- `pageResults` - Array of per-page results
|
|
160
|
+
|
|
161
|
+
#### `getResults()`
|
|
162
|
+
|
|
163
|
+
Get the most recent comparison results.
|
|
164
|
+
|
|
165
|
+
**Returns:** Object|null - Last comparison results
|
|
166
|
+
|
|
167
|
+
#### `clear()`
|
|
168
|
+
|
|
169
|
+
Clear the viewer and remove all rendered content.
|
|
170
|
+
|
|
171
|
+
#### `destroy()`
|
|
172
|
+
|
|
173
|
+
Destroy the viewer instance and clean up resources.
|
|
174
|
+
|
|
175
|
+
## 🔧 Technical Details
|
|
176
|
+
|
|
177
|
+
### Architecture
|
|
178
|
+
|
|
179
|
+
- **Frontend**: AngularJS with PDF.js for rendering
|
|
180
|
+
- **PDF Rendering**: PDF.js at 3x scale (~300 DPI)
|
|
181
|
+
- **Comparison Engine**: Custom pixel-diff algorithm with alignment
|
|
182
|
+
- **Text Detection**: Word-level text box extraction
|
|
183
|
+
- **Highlighting**: Intelligent dilation and area filtering
|
|
184
|
+
|
|
185
|
+
### Configuration
|
|
186
|
+
|
|
187
|
+
Key parameters in `public/app.js`:
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
const SCALE = 3.0; // Rendering DPI (3x = ~300 DPI)
|
|
191
|
+
const MAX_SHIFT = 3; // Pixel search radius for alignment
|
|
192
|
+
const COLOR_TOLERANCE = 120; // Color difference threshold
|
|
193
|
+
const MIN_HIGHLIGHT_AREA = 60; // Minimum area to highlight (pixels)
|
|
194
|
+
const MIN_WORD_SIZE = 8; // Minimum word box size (pixels)
|
|
195
|
+
const HIGHLIGHT_ALPHA = 0.32; // Highlight transparency
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## 📦 Project Structure
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
pdf-diff-viewer/
|
|
202
|
+
├── src/
|
|
203
|
+
│ └── PDFDiffViewer.js # Main embeddable library
|
|
204
|
+
├── public/
|
|
205
|
+
│ ├── index.html # Standalone app interface
|
|
206
|
+
│ └── app.js # AngularJS standalone app
|
|
207
|
+
├── example/
|
|
208
|
+
│ └── index.html # Usage example
|
|
209
|
+
├── bin/
|
|
210
|
+
│ └── cli.js # CLI entry point
|
|
211
|
+
├── server.js # Express server (optional)
|
|
212
|
+
├── package.json
|
|
213
|
+
└── README.md
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## 💡 Usage Examples
|
|
217
|
+
|
|
218
|
+
### Basic Usage
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
const viewer = new PDFDiffViewer('#container');
|
|
222
|
+
await viewer.compare(pdfFileA, pdfFileB);
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### With Custom Options
|
|
226
|
+
|
|
227
|
+
```javascript
|
|
228
|
+
const viewer = new PDFDiffViewer('#container', {
|
|
229
|
+
scale: 2.5,
|
|
230
|
+
labelA: 'Version 1',
|
|
231
|
+
labelB: 'Version 2',
|
|
232
|
+
highlightAlpha: 0.4,
|
|
233
|
+
colorTolerance: 100
|
|
234
|
+
});
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### With Crop Regions (Compare Specific Areas)
|
|
238
|
+
|
|
239
|
+
```javascript
|
|
240
|
+
const viewer = new PDFDiffViewer('#container', {
|
|
241
|
+
cropRegions: [
|
|
242
|
+
{ page: 1, x: 100, y: 150, width: 400, height: 200 }
|
|
243
|
+
]
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### With Mask Regions (Ignore Dynamic Content)
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
const viewer = new PDFDiffViewer('#container', {
|
|
251
|
+
maskRegions: [
|
|
252
|
+
{ page: 1, x: 50, y: 30, width: 200, height: 60 } // Ignore date field
|
|
253
|
+
]
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Using ArrayBuffers
|
|
258
|
+
|
|
259
|
+
```javascript
|
|
260
|
+
const bufferA = await fetch('/path/to/doc-a.pdf').then(r => r.arrayBuffer());
|
|
261
|
+
const bufferB = await fetch('/path/to/doc-b.pdf').then(r => r.arrayBuffer());
|
|
262
|
+
|
|
263
|
+
await viewer.compare(bufferA, bufferB);
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
## � Key Highlights
|
|
267
|
+
|
|
268
|
+
- **Client-Side Processing** - All PDF comparison happens in your browser, no server uploads needed
|
|
269
|
+
- **Zero System Dependencies** - No need for GraphicsMagick, ImageMagick, or GhostScript
|
|
270
|
+
- **Instant Setup** - Just open the HTML file in a browser, or run `npx pdf-diff-viewer` for the server version
|
|
271
|
+
- **Visual Feedback** - Interactive overlay showing exactly what changed and where
|
|
272
|
+
- **Privacy-Focused** - Your PDFs never leave your local machine
|
|
273
|
+
- **Lightweight** - Pure JavaScript solution without heavy binary dependencies
|
|
274
|
+
|
|
275
|
+
## 🤝 Contributing
|
|
276
|
+
|
|
277
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
278
|
+
|
|
279
|
+
## 📄 License
|
|
280
|
+
|
|
281
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
282
|
+
|
|
283
|
+
## 🙏 Acknowledgments
|
|
284
|
+
|
|
285
|
+
- [PDF.js](https://mozilla.github.io/pdf.js/) (v3.11.174) by Mozilla for PDF rendering
|
|
286
|
+
- [AngularJS](https://angularjs.org/) (v1.6.0) for the frontend framework
|
|
287
|
+
- [Express.js](https://expressjs.com/) for the optional web server
|
|
288
|
+
|
|
289
|
+
## 📧 Support
|
|
290
|
+
|
|
291
|
+
For issues and questions, please open an issue on [GitHub](https://github.com/a-subhaneel/pdf-diff-viewer/issues).
|
|
292
|
+
|
|
293
|
+
## 🔗 Links
|
|
294
|
+
|
|
295
|
+
- [GitHub Repository](https://github.com/a-subhaneel/pdf-diff-viewer)
|
|
296
|
+
- [NPM Package](https://www.npmjs.com/package/pdf-diff-viewer)
|
|
297
|
+
- [Report Bug](https://github.com/a-subhaneel/pdf-diff-viewer/issues)
|
|
298
|
+
- [Request Feature](https://github.com/a-subhaneel/pdf-diff-viewer/issues)
|
|
299
|
+
|
|
300
|
+
---
|
|
301
|
+
|
|
302
|
+
Made with ❤️ for developers who need visual PDF comparison
|
package/bin/cli.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pdf-diff-viewer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Browser-based PDF comparison tool with visual diff highlighting. Zero system dependencies, pure JavaScript, client-side processing.",
|
|
5
|
+
"main": "src/PDFDiffViewer.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./src/PDFDiffViewer.js",
|
|
10
|
+
"require": "./src/PDFDiffViewer.js",
|
|
11
|
+
"default": "./src/PDFDiffViewer.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"bin": {
|
|
15
|
+
"pdf-diff-viewer": "./bin/cli.js"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"start": "node server.js"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"pdf",
|
|
22
|
+
"diff",
|
|
23
|
+
"compare",
|
|
24
|
+
"viewer",
|
|
25
|
+
"visual-diff",
|
|
26
|
+
"pdf-comparison",
|
|
27
|
+
"browser",
|
|
28
|
+
"client-side",
|
|
29
|
+
"pdf-diff",
|
|
30
|
+
"pdf-viewer",
|
|
31
|
+
"compare-pdf",
|
|
32
|
+
"visual-comparison",
|
|
33
|
+
"embeddable",
|
|
34
|
+
"library",
|
|
35
|
+
"javascript",
|
|
36
|
+
"framework-agnostic"
|
|
37
|
+
],
|
|
38
|
+
"author": "Subhaneel Agarwalla <a.subhaneel@gmail.com>",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/a-subhaneel/pdf-diff-viewer.git"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/a-subhaneel/pdf-diff-viewer/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/a-subhaneel/pdf-diff-viewer#readme",
|
|
48
|
+
"files": [
|
|
49
|
+
"src/",
|
|
50
|
+
"public/",
|
|
51
|
+
"bin/",
|
|
52
|
+
"server.js",
|
|
53
|
+
"README.md",
|
|
54
|
+
"LICENSE",
|
|
55
|
+
"CHANGELOG.md"
|
|
56
|
+
],
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=16.0.0"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"express": "^4.22.1"
|
|
62
|
+
}
|
|
63
|
+
}
|