Metadata-Version: 2.4
Name: doc-splitter
Version: 0.1.3
Summary: Split DOCX and PDF documents by headings while preserving their original format and styling.
Author: PolishedApps LLC
License-Expression: MIT
Project-URL: Homepage, https://polishedapps.com/en/apps/doc-splitter
Project-URL: Repository, https://github.com/PolishedApps/doc-splitter
Project-URL: Issues, https://github.com/PolishedApps/doc-splitter/issues
Keywords: cli,document,docx,pdf,split
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: python-docx==1.2.0
Requires-Dist: pypdf==6.14.2
Provides-Extra: dev
Requires-Dist: pytest==9.1.1; extra == "dev"
Dynamic: license-file

<h1 align="center">
  Doc Splitter
</h1>

---

<p align="center">Split DOCX and PDF documents by headings while keeping their original format and styling.</p>

<p align="center">
  <a href="https://github.com/PolishedApps/doc-splitter/blob/main/LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-f5c400"></a>
  <a href="https://pypi.org/project/doc-splitter/"><img alt="PyPI: doc-splitter" src="https://img.shields.io/badge/PyPI-doc--splitter-3775A9?logo=pypi&logoColor=white"></a>
  <img alt="Python 3.11 or newer" src="https://img.shields.io/badge/Python-3.11%2B-3776AB?logo=python&logoColor=white">
  <img alt="Tests: pytest" src="https://img.shields.io/badge/tests-pytest-2EA44F">
</p>

<p align="center">Install the Python package to get the <code>doc-splitter</code> command.</p>

<p align="center">
  <a href="#installation">Installation</a> ·
  <a href="#usage">Usage</a> ·
  <a href="#api">API</a> ·
  <a href="#development">Development</a>
</p>

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:

```powershell
python -m pip install doc-splitter
```

This provides the `doc-splitter` command:

```powershell
doc-splitter --help
```

## Usage

### Inspect

Open a document and display its extracted heading hierarchy without calculating output paths or writing files:

```text
doc-splitter inspect <input.docx|input.pdf> [--json]
```

```powershell
doc-splitter inspect "manual.docx"
```

### Plan

Calculate the exact output filenames and document ranges without creating them:

```text
doc-splitter plan <input.docx|input.pdf> [split options] [--json]
```

```powershell
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:

```text
doc-splitter <input.docx|input.pdf> [options]
```

Split a DOCX document at level 1:

```powershell
doc-splitter "manual.docx" --level 1 --output ".\output"
```

Split a PDF document at level 2:

```powershell
doc-splitter "book.pdf" --level 2 --output ".\chapters"
```

Paths containing spaces or Unicode characters can be quoted normally:

```powershell
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:

```python
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 `.docx` and `.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](https://github.com/PolishedApps/doc-splitter). Shared fixtures are in the repository `test-data/` directory.

```powershell
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

[MIT](https://github.com/PolishedApps/doc-splitter/blob/main/LICENSE)
