PDF Text editor (#4724)

## Summary
- add a `PdfJsonConversionService` that serializes PDF text, fonts, and
metadata to JSON and rebuilds a PDF from the same structure
- expose REST endpoints for `/pdf/json` and `/json/pdf` conversions
using the existing convert API infrastructure
- define JSON model classes capturing document metadata, font
information, and positioned text elements

## Testing
- `./gradlew spotlessApply` *(fails: plugin
org.springframework.boot:3.5.4 unavailable in build environment)*
- `./gradlew build` *(fails: plugin org.springframework.boot:3.5.4
unavailable in build environment)*

------
https://chatgpt.com/codex/tasks/task_b_68f8e98d94ac8328a0e499e541528b6f

---------

Co-authored-by: EthanHealy01 <[email protected]>
This commit is contained in:
Anthony Stirling
2025-11-24 14:15:02 +00:00
committed by GitHub
co-authored by EthanHealy01
parent d42065e338
commit b0397da19e
253 changed files with 26069 additions and 111 deletions
+130 -1
View File
@@ -28,7 +28,10 @@
"toggle": {
"fullscreen": "Switch to fullscreen mode",
"sidebar": "Switch to sidebar mode"
}
},
"alpha": "Alpha",
"premiumFeature": "Premium feature:",
"comingSoon": "Coming soon:"
},
"unsavedChanges": "You have unsaved changes to your PDF.",
"areYouSure": "Are you sure you want to leave?",
@@ -856,6 +859,10 @@
"desc": "Overlay one PDF on top of another",
"title": "Overlay PDFs"
},
"pdfTextEditor": {
"title": "PDF Text Editor",
"desc": "Review and edit Stirling PDF JSON exports with grouped text editing and PDF regeneration"
},
"addText": {
"tags": "text,annotation,label",
"title": "Add Text",
@@ -5789,6 +5796,128 @@
"noShortcut": "No shortcut set"
}
},
"pdfTextEditor": {
"title": "PDF JSON Editor",
"viewLabel": "PDF Editor",
"converting": "Converting PDF to editable format...",
"conversionFailed": "Failed to convert PDF. Please try again.",
"currentFile": "Current file: {{name}}",
"pageSummary": "Page {{number}} of {{total}}",
"pagePreviewAlt": "Page preview",
"imageLabel": "Placed image",
"noTextOnPage": "No editable text was detected on this page.",
"pageType": {
"paragraph": "Paragraph page",
"sparse": "Sparse text"
},
"groupingMode": {
"auto": "Auto",
"paragraph": "Paragraph",
"singleLine": "Single Line"
},
"badges": {
"unsaved": "Edited",
"modified": "Edited",
"earlyAccess": "Early Access"
},
"actions": {
"reset": "Reset Changes",
"downloadJson": "Download JSON",
"generatePdf": "Generate PDF"
},
"options": {
"autoScaleText": {
"title": "Auto-scale text to fit boxes",
"description": "Automatically scales text horizontally to fit within its original bounding box when font rendering differs from PDF."
},
"groupingMode": {
"title": "Text Grouping Mode",
"autoDescription": "Automatically detects page type and groups text appropriately.",
"paragraphDescription": "Groups aligned lines into multi-line paragraph text boxes.",
"singleLineDescription": "Keeps each PDF text line as a separate text box."
},
"manualGrouping": {
"descriptionInline": "Tip: Hold Ctrl (Cmd) or Shift to multi-select text boxes. A floating toolbar will appear above the selection so you can merge, ungroup, or adjust widths."
},
"forceSingleElement": {
"title": "Lock edited text to a single PDF element",
"description": "When enabled, the editor exports each edited text box as one PDF text element to avoid overlapping glyphs or mixed fonts."
}
},
"manual": {
"mergeTooltip": "Merge selected boxes",
"merge": "Merge selection",
"ungroupTooltip": "Split paragraph back into lines",
"ungroup": "Ungroup selection",
"widthMenu": "Width options",
"expandWidth": "Expand to page edge",
"resetWidth": "Reset width",
"resizeHandle": "Adjust text width"
},
"disclaimer": {
"heading": "Preview Limitations",
"textFocus": "This workspace focuses on editing text and repositioning embedded images. Complex page artwork, form widgets, and layered graphics are preserved for export but are not fully editable here.",
"previewVariance": "Some visuals (such as table borders, shapes, or annotation appearances) may not display exactly in the preview. The exported PDF keeps the original drawing commands whenever possible.",
"alpha": "This alpha viewer is still evolving—certain fonts, colours, transparency effects, and layout details may shift slightly. Please double-check the generated PDF before sharing."
},
"empty": {
"title": "No document loaded",
"subtitle": "Load a PDF or JSON file to begin editing text content."
},
"welcomeBanner": {
"title": "Welcome to PDF Text Editor (Early Access)",
"experimental": "This is an experimental feature in active development. Expect some instability and issues during use.",
"howItWorks": "This tool converts your PDF to an editable format where you can modify text content and reposition images. Changes are saved back as a new PDF.",
"bestFor": "Works Best With:",
"bestFor1": "Simple PDFs containing primarily text and images",
"bestFor2": "Documents with standard paragraph formatting",
"bestFor3": "Letters, essays, reports, and basic documents",
"notIdealFor": "Not Ideal For:",
"notIdealFor1": "PDFs with special formatting like bullet points, tables, or multi-column layouts",
"notIdealFor2": "Magazines, brochures, or heavily designed documents",
"notIdealFor3": "Instruction manuals with complex layouts",
"limitations": "Current Limitations:",
"limitation1": "Font rendering may differ slightly from the original PDF",
"limitation2": "Complex graphics, form fields, and annotations are preserved but not editable",
"limitation3": "Large files may take time to convert and process",
"knownIssues": "Known Issues (Being Fixed):",
"issue1": "Text colour is not currently preserved (will be added soon)",
"issue2": "Paragraph mode has more alignment and spacing issues - Single Line mode recommended",
"issue3": "The preview display differs from the exported PDF - exported PDFs are closer to the original",
"issue4": "Rotated text alignment may need manual adjustment",
"issue5": "Transparency and layering effects may vary from original",
"feedback": "This is an early access feature. Please report any issues you encounter to help us improve!",
"gotIt": "Got it",
"dontShowAgain": "Don't show again"
},
"modeChange": {
"title": "Confirm Mode Change",
"warning": "Changing the text grouping mode will reset all unsaved changes. Are you sure you want to continue?",
"cancel": "Cancel",
"confirm": "Reset and Change Mode"
},
"fontAnalysis": {
"details": "Font Details",
"embedded": "Embedded",
"type": "Type",
"webFormat": "Web Format",
"warnings": "Warnings",
"suggestions": "Notes",
"currentPageFonts": "Fonts on this page",
"allFonts": "All fonts",
"fallback": "fallback",
"missing": "missing",
"perfectMessage": "All fonts can be reproduced perfectly.",
"warningMessage": "Some fonts may not render correctly.",
"infoMessage": "Font reproduction information available.",
"perfect": "perfect",
"subset": "subset"
},
"errors": {
"invalidJson": "Unable to read the JSON file. Ensure it was generated by the PDF to JSON tool.",
"pdfConversion": "Unable to convert the edited JSON back into a PDF."
}
},
"auth": {
"sessionExpired": "Session Expired",
"pleaseLoginAgain": "Please login again.",