pdfconcat

module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 16, 2026 License: MPL-2.0

README

PDFConcat

Build a PDF packet with selected source pages, sections, title dividers, linked contents and physical page numbers. Save the order and page settings in one JSON plan, check it, then build the PDF. An optional report maps included source pages to their places in the packet.

PDFConcat includes Noto Sans for Latin, Greek and Cyrillic generated text and uses pdfcpu as its PDF engine. You need only the PDFConcat executable to use the built-in font. It is intended for trusted local documents.

Use a published release

This documentation describes the current source tree: plan v3 and result v4. For a published binary, use the matching documentation supplied with its archive. A source build follows the contracts documented here.

Download the archive matching your operating system and CPU from published releases, verify its checksum against checksums.txt, and extract it. The executable is at the archive root. From that directory, run ./pdfconcat version on macOS/Linux or .\pdfconcat.exe version in Windows PowerShell. version reports the release version and build identity.

With Go at the version declared in go.mod, install the latest published module tag into your Go binary directory:

go install github.com/resoltico/pdfconcat/cmd/pdfconcat@latest
pdfconcat version

Add that directory (go env GOBIN, or bin under go env GOPATH when GOBIN is empty) to PATH if needed. The examples below use pdfconcat on PATH; you can also use the extracted executable path.

First packet

pdfconcat check --format text cover.pdf --blank appendix.pdf
pdfconcat build --format text -o packet.pdf cover.pdf --blank appendix.pdf --report packet.report.json

--blank inserts one plain page that inherits the neighboring source's displayed size. Options may interleave with operands; -- makes all following arguments literal paths. Use --overwrite to replace an existing regular output/report file. Known input, output and report collisions are refused.

For a divider with text, save this as packet.json next to the source PDFs:

{
  "version": 3,
  "output": "packet-with-divider.pdf",
  "page": {
    "text": {
      "value": "Pielikums Ā ļ ķ — Ελληνικά",
      "size": 18
    }
  },
  "items": [
    {
      "source": "cover.pdf"
    },
    {
      "page": {}
    },
    {
      "source": "appendix.pdf"
    }
  ]
}
pdfconcat check --format text --plan packet.json
pdfconcat build --format text --plan packet.json --report packet-with-divider.report.json

Results are JSON by default. Use --format text for a human-readable result. --report saves all diagnostics and per-part ranges, hashes, layout and actual form-name mappings. check writes no PDF; it can write its requested report. Passing check does not guarantee that a later build will succeed.

Sections, selected pages and physical numbering

A source object can select ascending disjoint ranges, for example {"source":"report.pdf","pages":[[2,4],[7,7]]}. A titled container creates a bookmark and contents entry; its optional divider paints the same title. Nested sections retain the original source bookmarks beneath them.

Put one contents item where you want the linked contents pages. Set start_on: "odd" on a container for automatic blank backs, and add page_numbers: {} at the root to print physical page numbers. All features use the same final page positions. Padding counts but stays visually blank; authored blank pages receive numbers. Footers may cover existing content; overlap is not detected. Selection is packet composition, not redaction, and partial sources with forms/widgets are refused.

See the complete composition plan and syntax, layout and limits.

PDFConcat or the pdfcpu CLI?

For a simple merge, pdfcpu merge already covers the task. PDFConcat adds a packet workflow on top of the same engine: one recipe coordinates selected pages, sections, dividers, linked contents, odd-page starts and numbering. You can check the complete recipe before building and keep a report of the final page ranges and source identities.

pdfcpu can also create pages, insert blanks, manage bookmarks and resize PDFs. PDFConcat's purpose is to coordinate those packet decisions in one plan.

What you want to do pdfcpu CLI PDFConcat
Join existing PDFs in order pdfcpu merge packet.pdf first.pdf second.pdf pdfconcat build -o packet.pdf first.pdf second.pdf
Rebuild a packet with excerpts, sections, dividers and numbering Coordinate the PDF operations and generated pages in your script Keep the packet choices together in one JSON plan
Use Latvian, Greek or Cyrillic divider text Create pages with an installed font covering the text Use the included Noto Sans without font installation
Check layout and track where packet pages came from Validate the PDFs and track your script's assembly decisions check predicts ranges and generated-text layout; --report records source hashes and page mappings
Split, extract, watermark, encrypt or fill forms Use the corresponding pdfcpu tools Use pdfcpu for these editing tasks

PDFConcat applies a defined input policy. For example, it refuses encrypted PDFs and PDFs containing signature values. It handles repeated internal named links so each copy's supported links point into that copy. Forms must meet the supported form rules. Fitting refuses interactive form fields and internal page destinations with explicit numeric position coordinates, including destinations used by links and bookmarks. See PDF behavior and limits.

The optional same-input comparison uses the pdfcpu CLI version pinned in this project.

Build from source

With Go at the version declared in go.mod, build the current code from main:

git clone --branch main https://github.com/resoltico/pdfconcat.git
cd pdfconcat
go build -o bin/pdfconcat ./cmd/pdfconcat
bin/pdfconcat version

The source build needs no PDF CLI, system font installation or runtime configuration directory. Windows builds use bin/pdfconcat.exe.

The release workflow publishes macOS, Linux and Windows archives for amd64/arm64, with checksums and provenance, when a release is tagged. Check published releases for available artifacts and use the documentation supplied with the selected version. Building main uses the code and contracts documented here; @latest selects the latest published module tag.

Limits and behavior

  • Plan v3 declares version: 3 and generated items with page; output uses result v4.
  • At most 64 MiB of plan JSON, 64 container levels, 100,000 entries and 100,000 generated pages. Each text value holds at most 10,000 characters.
  • Generated text supports left-to-right Latin, Greek and Cyrillic with a static TrueType font. Missing glyphs and unsupported characters are errors. Overflow is refused by default; overflow: allow places measured overflow with a warning.
  • Source policy refuses encryption, signature values, dynamic forms, optional content, damaged page trees and specific unsafe/unsupported shapes. Upstream relaxed parsing may accept other malformed syntax or repairs.
  • Fitting refuses interactive form fields and internal page destinations with explicit numeric position coordinates. Use the original page sizes for those sources. Whole-page destinations and valid destinations without numeric position coordinates are supported.
  • Static forms require compatible defaults/resources. Some form and annotation combinations are incompatible with PDF 2.0 output. Check reports the known appearance conflict; build can still fail for other assembly or writing reasons.
  • Tags, some document settings and catalog information are removed. The output is not promised to retain PDF/A, PDF/X or accessibility conformance. See the full PDF behavior and limits.
  • Assembly is in memory. PDF object graphs and generated pages can cost much more RAM than compressed input bytes. There is no universal memory or time bound.
  • This is not a sanitizer: retained page/annotation actions can contain active content. No hostile-input memory/CPU sandbox is provided.

Exit codes: 0 ok, 2 invalid request/refusal, 1 environment/backend failure, 130 interrupted. A PDF may already be published when a later report/durability failure occurs; inspect output.published before retrying.

Reference

Plan and text · CLI, result and recipes · Design and PDF policy · Contributing · Security · Changelog · Third-party notices

In-repository frontends share the application core. Contributor setup and the whole-source architecture check are in CONTRIBUTING.

Directories

Path Synopsis
cmd
pdfconcat command
Command pdfconcat supplies process lifetime and standard streams to the CLI.
Command pdfconcat supplies process lifetime and standard streams to the CLI.
internal
cli
Package cli adapts argument grammar, process input and presentation to core.
Package cli adapts argument grammar, process input and presentation to core.
core
Package core is the transport-neutral PDF packet application boundary.
Package core is the transport-neutral PDF packet application boundary.
diag
Package diag defines product diagnostics and outcome classes.
Package diag defines product diagnostics and outcome classes.
inputfile
Package inputfile reads named regular inputs without opening known streams/devices.
Package inputfile reads named regular inputs without opening known streams/devices.
job
Package job defines the assembly domain without PDF or filesystem I/O.
Package job defines the assembly domain without PDF or filesystem I/O.
oracle
Package oracle judges PDF output with programs that share no code with the PDF library under test: qpdf's JSON dump and checker for structure, Poppler's pdftotext for page text, and pdfinfo and pdftoppm for geometry.
Package oracle judges PDF output with programs that share no code with the PDF library under test: qpdf's JSON dump and checker for structure, Poppler's pdftotext for page text, and pdfinfo and pdftoppm for geometry.
pdf
Package pdf owns upstream PDF inspection, policy, fitting, destination handling, assembly and verification.
Package pdf owns upstream PDF inspection, policy, fitting, destination handling, assembly and verification.
pdffixture
Package pdffixture writes small, deterministic PDF files for tests and benchmarks.
Package pdffixture writes small, deterministic PDF files for tests and benchmarks.
plan
Package plan decodes strict, located version 3 assembly plans.
Package plan decodes strict, located version 3 assembly plans.
publication
Package publication publishes a sibling temporary file without exposing partial bytes.
Package publication publishes a sibling temporary file without exposing partial bytes.
result
Package result defines result v4 and its complete factual outcomes.
Package result defines result v4 and its complete factual outcomes.
typeset
Package typeset loads TrueType fonts, shapes and wraps text, and places one text block on a page.
Package typeset loads TrueType fonts, shapes and wraps text, and places one text block on a page.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL