Doc Splitter
Split DOCX and PDF documents by headings while keeping their original format and styling.
Install the Python package to get the doc-splitter command.
Installation · Usage · API · Development
Doc Splitter turns structured DOCX and PDF documents into smaller files at their heading boundaries. Each output remains in the source format and is derived from a complete copy of the original document, preserving the formatting and styling of the retained content.
Installation
Requires Python 3.11 or newer:
python -m pip install doc-splitter
This provides the doc-splitter command:
doc-splitter --help
Usage
Inspect
Open a document and display its extracted heading hierarchy without calculating output paths or writing files:
doc-splitter inspect <input.docx|input.pdf> [--json]
doc-splitter inspect "manual.docx"
Plan
Calculate the exact output filenames and document ranges without creating them:
doc-splitter plan <input.docx|input.pdf> [split options] [--json]
doc-splitter plan "manual.docx" --level 2 --parent-headings folders
Split
Plan and create the output documents. The split workflow does not require a split command word:
doc-splitter <input.docx|input.pdf> [options]
Split a DOCX document at level 1:
doc-splitter "manual.docx" --level 1 --output ".\output"
Split a PDF document at level 2:
doc-splitter "book.pdf" --level 2 --output ".\chapters"
Paths containing spaces or Unicode characters can be quoted normally:
doc-splitter "C:\Documents\manual.pdf" --output "C:\Documents\Split Files"
Options
Split options apply to both plan and the default split workflow. --output, --subfolder, and --yes apply only when creating files.
| Option | Description |
|---|---|
--output <directory> |
Write the split documents to the selected directory. |
--subfolder |
Create a unique source-named directory inside the output directory. |
--level <number> |
Split at the selected heading level. |
--parent-headings <none|filename|folders> |
Omit parent headings, include them in filenames, or create parent folders. |
--index / --no-index |
Include or omit indexes in output filenames. |
--title-case / --no-title-case |
Transform or preserve heading-name casing. |
--original-name |
Prefix output filenames with the input filename. |
--multilevel-index |
Use hierarchical indexes in output filenames. |
--yes |
Create the planned files without asking for confirmation. |
--json |
Return a versioned JSON response. Splitting also requires --yes. |
--quiet |
Suppress progress and nonessential human-readable output. |
The input document is never modified. Existing output files are not overwritten.
API
The import name is doc_splitter. The API follows an inspect-plan-execute workflow:
from doc_splitter import (
DEFAULT_SPLIT_OPTIONS,
execute_split,
inspect_document,
plan_split,
)
inspection = inspect_document("manual.docx")
plan = plan_split(inspection, DEFAULT_SPLIT_OPTIONS)
result = execute_split(
inspection,
plan,
"./output",
output_directory_mode="direct",
)
print(f"Created {result.created_files} files.")
inspect_document reads and retains the input snapshot, plan_split calculates filenames and document ranges, and execute_split creates the planned outputs. The API raises DocSplitterError for document, planning, or output failures.
Behavior
Doc Splitter splits at heading boundaries without rebuilding the selected content in a blank document. This keeps each output in the original document format and preserves the formatting and styling of its retained content.
- Supported inputs are
.docxand.pdf, matched case-insensitively. - DOCX ranges use top-level Open XML body-element indexes.
- PDF ranges use zero-based page indexes.
- Split ranges include the start and exclude the end.
- Heading text is whitespace-normalized before use in filenames.
- Unsafe filename characters are removed or replaced.
- Windows reserved device names receive a trailing
_. - Outputs retain the source document format, formatting, and styling.
- Each output begins with a complete source-derived document and removes content outside its planned range.
When a document begins with exactly one level-1 heading followed by lower-level headings, Doc Splitter omits that single top heading from the returned hierarchy and promotes its descendants by one level. Content before the first returned heading can become a cover output.
Development
This package lives in the python/ directory of the Doc Splitter repository. Shared fixtures are in the repository test-data/ directory.
cd python
py -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e ".[dev]"
python -m compileall -q src
python -m pytest
Generated split documents belong in temporary directories or .artifacts/, not in test-data/. If a committed fixture changes intentionally, update its SHA-256 and affected expectations in the same change.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file doc_splitter-0.1.3.tar.gz.
File metadata
- Download URL: doc_splitter-0.1.3.tar.gz
- Upload date:
- Size: 22.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b981abe27a5edad9d5f964e217c0a1ab3620a56ace32e6ad4025b698634cb69
|
|
| MD5 |
20e326992ad4d4f0c582aab681a9436b
|
|
| BLAKE2b-256 |
437bba66956f6526d7ec58d82708124b933274d22983c4901dda3b0472235581
|
File details
Details for the file doc_splitter-0.1.3-py3-none-any.whl.
File metadata
- Download URL: doc_splitter-0.1.3-py3-none-any.whl
- Upload date:
- Size: 24.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4a695e4266934fa246a4aa0c9117f7a032bcc82b3956a6811f257e5506a57d9
|
|
| MD5 |
734d8c06d356408025e88a6e3a7629f2
|
|
| BLAKE2b-256 |
d7f6b2861333a94a672f0618178ac06a851b001ce3dda42108c64d5f03e1daff
|