A web-based PDF editing application built with a Python/FastAPI backend and an Angular frontend.
This application allows you to upload PDFs, automatically detects existing text (using PyMuPDF for native text, and falling back to Tesseract OCR for scanned images), previews edits directly on the page, reuses embedded PDF fonts when possible, and enables in-place editing through a professional web interface.
The landing experience is a Stirling-inspired tool hub with 55 searchable surfaces, category navigation, favorites, recent tools, drag-and-drop workbenches, a direct OpenAPI link, and the original visual editor preserved as the main editing workbench. This project is independent from Stirling PDF; its public functionality catalog was used as the coverage baseline while the FastAPI + Angular architecture remains unchanged.
See the complete implementation/dependency matrix in Stirling Tool Parity.
- Provides a 55-surface catalog for page operations, conversions, content, security, OCR, compression, repair, comparison, automation, mobile scanning, and API access.
- Supports consolidated Split modes for ranges, page/document count, bookmarks, sections, size, QR divider sheets, and printable poster chunks.
- Converts PDF natively to text/data, images, SVG and CBZ; converts images, EML, CBZ, HTML/Markdown and public URL sources to PDF; and provides isolated adapters for Office, e-books, PDF/A, PDF/X and print formats.
- Adds/removes passwords, controls permissions, sanitizes, redacts, validates/removes signatures, signs with PKCS#12, and adds RFC 3161 timestamps.
- Detects individual photos in scanned pages and QR divider sheets through an injectable OpenCV boundary.
- Reuses the original embedded page font for replacement text before considering a system-font substitute.
- Opens password-protected PDFs after requesting the document password.
- Renders the main document at 200 DPI and retries difficult pages at safe lower resolutions.
- Uses lightweight 84 DPI page thumbnails to keep long documents responsive.
- Provides page navigation, 50%-200% zoom, font controls, text movement, and text-box resizing.
- Treats Add Text as a one-shot tool: it automatically turns off after one box is placed.
- Shows persistent, user-friendly errors without discarding pending edits.
- Offers light and dark themes, follows the operating-system preference initially, and remembers the user's choice.
- Uses accessible icon-only controls for frequent actions and independently collapsible page/tool sidebars.
- Provides undo/redo with browser autosave and interrupted-session recovery.
- Finds and replaces text across the document while preserving word spacing.
- Inserts or replaces images and adds highlights, comments, rectangles, and free-text annotations.
- Reorders, rotates, extracts, and deletes pages; fills text and checkbox AcroForms.
- Adds headers, footers, page numbering, and watermarks during preview/export.
- Compares document versions and runs a visual preflight for empty pages, low-resolution images, and font risks.
- Selects installed Tesseract languages for multilingual OCR.
- Applies standards-based CMS signatures from PKCS#12 (
.pfx/.p12) certificates through pyHanko. - Compresses the pending PDF in lossless, balanced (up to 200 DPI), or maximum (up to 144 DPI) modes.
Detailed behavior and API contracts are documented in Advanced Editing. The most recent verification is in Test Report.
Before you begin, ensure you have the following installed:
- Node.js/npm supported by the pinned Angular 17 toolchain; use an even-numbered LTS release and avoid odd-numbered development releases
- Standard CPython (3.10 or higher; recommended over MSYS2 Python for binary wheels)
- Tesseract OCR (Must be installed on your system to process scanned PDFs)
- OpenCV headless (installed by
backend/requirements.txt) for QR dividers and scanned-photo detection
Optional system runtimes expand conversion coverage:
- LibreOffice (
soffice) for Office/OpenDocument conversions. - Calibre (
ebook-convert) for e-book and CBR conversions. - Ghostscript (
gswin64c,gswin32c, orgs) for PDF/A, PDF/X, PostScript, EPS, PCL, and XPS.
This project consists of two separate applications that need to be run concurrently: the backend API and the frontend web server.
Install dependencies once:
pip install -r backend/requirements.txt
npm --prefix frontend installThen open two terminals from the repository root:
.\scripts\backend.ps1.\scripts\frontend.ps1Both scripts run in the foreground. Stop either server with Ctrl+C.
Security-sensitive runtime settings are explicit environment variables:
$env:PDF_EDITOR_MAX_UPLOAD_MIB = '512'
$env:PDF_EDITOR_CORS_ORIGINS = 'http://localhost:4200'
$env:PDF_EDITOR_ALLOWED_TSA_URLS = 'https://tsa.example.com/rfc3161'
$env:PDF_EDITOR_LIBREOFFICE_PATH = 'C:\Program Files\LibreOffice\program\soffice.exe'
$env:PDF_EDITOR_CALIBRE_PATH = 'C:\Program Files\Calibre2\ebook-convert.exe'
$env:PDF_EDITOR_GHOSTSCRIPT_PATH = 'C:\Tools\Ghostscript\bin\gswin64c.exe'The TSA allowlist is empty by default, so an arbitrary API caller cannot turn the
timestamp tool into a server-side network proxy. Use exact, administrator-approved
endpoints. In same-origin production/IIS deployments, set
PDF_EDITOR_CORS_ORIGINS to an empty string.
Run unit, regression, browser, and production-build checks with one command:
.\scripts\test.ps1The frontend test runner uses an isolated headless browser profile with sandbox-safe flags. Set CHROME_BIN first when Chrome or Edge is installed in a non-standard location.
The command covers Python unit/regression/smoke tests, Angular browser tests, Ahead-of-Time compilation, and the production bundle. Exact green/failure counts from the latest complete run are recorded in Test Report.
To create a local Windows package that does not require the end user to install Python, Node.js, or Tesseract, run this from the repository root on the build machine:
.\scripts\publish-windows.ps1The build machine still needs Python, Node.js, npm, and an installed Tesseract
runtime so the script can package them. The script installs PyInstaller if it is
missing, builds the Angular frontend, bundles Tesseract and tessdata, and
creates:
publish\PdfEditor\PdfEditor.exe
publish\PdfEditor-windows.zip
Send the publish\PdfEditor folder or the zip to users. They can run
PdfEditor.exe; the app starts a local server and opens the browser at
http://127.0.0.1:8000. Runtime upload scratch files are stored inside
publish\PdfEditor\data, keeping the app portable.
The backend handles PDF parsing, text extraction, OCR, and saving the final document.
- Open a terminal and navigate to the
backenddirectory:cd backend - Create a virtual environment (optional but recommended):
python -m venv venv
- Activate the virtual environment:
- On Windows:
venv\Scripts\activate - On macOS/Linux:
source venv/bin/activate
Note: If you are using MSYS2 on Windows (like in the original development environment), you might use system packages instead.
- On Windows:
- Install the required dependencies:
pip install -r requirements.txt
- Start the FastAPI server:
The backend will be running at
python -m uvicorn main:app --host 127.0.0.1 --port 8000
http://localhost:8000.
The frontend provides the user interface for viewing and editing the PDFs.
- Open a new, separate terminal and navigate to the
frontenddirectory:cd frontend - Install the Node.js dependencies:
npm install
- Start the Angular development server:
The frontend will compile and start running.
npm start
Once both servers are running:
- Open your web browser and navigate to
http://localhost:4200. - Search or choose a tool card, or open Editor de PDF for visual editing.
- Wait for the application to analyze the text and rasterize the pages.
- Click on any text block on the document image to edit it inline.
- Choose a font, size, bold, and italic style for new or focused text.
- Use "Add Text" to place new text anywhere on the current page.
- Use each text block's four-way SVG handle to reposition created or edited text.
- Drag the right, bottom, or corner handles to stretch a text box.
- Edit text and watch the page preview update without downloading.
- Click "Download PDF" when you are ready to export the modified file.
API-backed cards use one generic multipart contract:
POST /tools/{tool_id}
files=<zero or more uploads>
options=<JSON object>
Use these endpoints for discovery and monitoring:
GET /health— readiness probe.GET /tools— executable tool IDs, upload limit, and detected optional runtimes.GET /docs— interactive OpenAPI contract.
The URL converter can run without an upload by sending sourceUrl; /tools/api
is also fileless. Private, loopback, link-local, credential-bearing, binary, and
oversized destinations are rejected, and the connection is pinned to the public IP
that passed validation. Every document operation validates its required file shape.
automate and multi-tool accept pipelines of up to 20 steps. Intermediate steps
must return PDF; the final step may return PDF, JSON, ZIP, or another declared media
type, which is preserved in the download response.
- Native Text: The backend first tries to read text directly from the PDF structures.
- OCR Fallback: If a page contains very little or no native text (less than 50 characters), the backend assumes it's a scanned image, rasterizes it, cleans up the image for OCR, and groups confident Tesseract words into editable line blocks.
- Live Preview: While you edit, the frontend sends pending page edits to the backend, which renders a PNG preview using the same edit logic as the final PDF.
- Optimized Preview: A newer edit cancels the previous browser request, and the backend applies advanced operations only to the visible page. PDF-heavy work runs outside the API event loop.
- Cached Source Pages: Immutable source-page images use long-lived private browser caching, so reopening the page sidebar does not rerasterize thumbnails unnecessarily.
- Cached Application Bundles: Content-hashed JavaScript/CSS bundles receive a one-year immutable cache policy; the HTML shell remains revalidated.
- Bounded Raster Work: OCR, color transforms, QR detection, photo detection, and conversion rasterization enforce per-page pixel budgets.
- Session Cleanup: Replacing, closing, or failing an editor session releases its temporary backend PDF.
- Cached Tool Registry: The immutable tool-handler registry is built once and reused by pipelines.
- Self-Contained Runtime: The packaged Windows build serves the compiled Angular frontend directly from FastAPI and uses bundled Tesseract files for OCR.
- Font Matching: Replacement edits first reuse the matching font resource already embedded in the page. If that resource cannot be reused, the backend maps the detected family and style to the closest installed or built-in PDF font.
- Subset Font Safety: PDF subset fonts are not reused for newly written content because incomplete glyph metrics can collapse visible word spacing. Their family and style are mapped to a complete compatible font instead.
- Protected Documents: The upload flow validates PDFs immediately and can unlock password-protected documents for the current editing session.
- Resilient Rendering: Full-page previews use a larger pixel budget and retry at progressively safer resolutions when malformed or memory-heavy page content fails at the requested quality.
- New Text: Added text is inserted as text drawing only. The editor overlay is transparent and does not create a visible PDF rectangle.
- Moving Text: Replacement edits keep the original redaction area separate from the current placement, so moved text hides the old source text and renders at the new position.
- Saving: When you export, the backend locates the original coordinates of the text you edited, redacts the original area, and inserts your new text at the correct baseline.
- Digital Signatures: Exported bytes can be signed with a PKCS#12 certificate. The private key is read only for the request and is not persisted by the application.
- Compression: Structural cleanup, object-stream packing, font/image deflation, image deduplication, and optional DPI-aware JPEG recompression are applied without ever returning a file larger than the pending export.
IIS can expose the application through ARR + URL Rewrite while FastAPI remains a
localhost Windows service. The production topology, web.config, upload-limit
alignment, and health checks are documented in IIS Deployment.