# Linebreaker
I created this tool because I couldn't find a reliable line breaking utility that works with Quarto markdown without altering headers, lists, or other formatting. This tool is conservative - it preserves your document structure and only adds line breaks when both the preceding and following text segments are sufficiently long.
## Features
Intelligent line breaking for Markdown and text files, with support for:
- Citations in format `[@...]`
- Decimal numbers
- Common abbreviations (Dr., Prof., vs., et al., etc.)
- YAML headers
- Code blocks
- Soft breaks on conjunctions, commas, and/or
## Installation
Install from PyPI using pixi:
```bash
pip install linebreaker
```
```bash
pixi add --pypi linebreaker
```
Or install from source:
```bash
git clone https://github.com/silas/linebreaker.git
cd linebreaker
pixi install
```
## Usage
### As a command-line tool:
```bash
# Process a single file
linebreaker your_file.md
# Process a directory
linebreaker writing/
# For compatibility, you can still use the old script
python -m linebreaker.cli your_file.md
```
> **⚠️ Important**: Only use this tool on files that are tracked by a version control system like Git. Line breaking modifies your files, and having version control ensures you can review and revert changes if needed.
### As a module:
```python
from linebreaker import format_line, break_text
# Format a single line
result = format_line("Your text here...")
# Process entire text with YAML/code blocks
result = break_text(full_text)
```
## Running Tests
```bash
# Run all tests
pytest linebreaker/tests/
```
## Detailed Features
### Hard Breaks (Sentence Boundaries)
- Splits on `.`, `?`, `!` when both before and after have 20+ characters
- Avoids common abbreviations: vs., Dr., Prof., Mr., Mrs., Ms., Ph.D., M.D., Jr., Sr., etc., e.g., i.e., et al., vol., no., pp., fig.
### Medium Breaks (Colons/Semicolons)
- Splits sentences longer than 80 characters at `:` or `;`
- Only if both parts have 20+ characters
### Soft Breaks (Conjunctions)
- Applied when there are 3+ sentences or sentence is >60 characters
- Breaks on: `but`, `such as`, `for example`, `e.g.`, `i.e.` (after 20 chars)
- Breaks on commas (after 40 chars)
- Breaks on `and`, `or` (after 40 chars)
### Smart Masking
- Citations `[@...]` are masked to prevent dots inside from triggering breaks
- Decimal numbers like `0.85` are masked similarly
## Development
To add new abbreviations, edit the `abbreviations` pattern in `core.py`:
```python
abbreviations = r'(?!vs\.|dr\.|prof\.|...|your_abbrev\.)'
```
Raw data
{
"_id": null,
"home_page": null,
"name": "linebreaker",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "Silas Kieser <silas.kieser@gmail.com>",
"keywords": "markdown, text, line-breaking, formatting",
"author": null,
"author_email": "Silas Kieser <silas.kieser@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/f5/56/d41aaac60c3cbbe911779a67c2af0db17f5685184c6ccbcfc3be03ce4e45/linebreaker-0.0.0.tar.gz",
"platform": null,
"description": "\n\n# Linebreaker\n\nI created this tool because I couldn't find a reliable line breaking utility that works with Quarto markdown without altering headers, lists, or other formatting. This tool is conservative - it preserves your document structure and only adds line breaks when both the preceding and following text segments are sufficiently long.\n\n## Features\nIntelligent line breaking for Markdown and text files, with support for:\n- Citations in format `[@...]`\n- Decimal numbers\n- Common abbreviations (Dr., Prof., vs., et al., etc.)\n- YAML headers\n- Code blocks\n- Soft breaks on conjunctions, commas, and/or\n\n## Installation\n\nInstall from PyPI using pixi:\n\n\n```bash\npip install linebreaker\n```\n\n```bash\npixi add --pypi linebreaker\n```\n\nOr install from source:\n\n```bash\ngit clone https://github.com/silas/linebreaker.git\ncd linebreaker\npixi install\n```\n\n## Usage\n\n\n### As a command-line tool:\n\n```bash\n# Process a single file\nlinebreaker your_file.md\n\n# Process a directory\nlinebreaker writing/\n\n# For compatibility, you can still use the old script\npython -m linebreaker.cli your_file.md\n```\n> **\u26a0\ufe0f Important**: Only use this tool on files that are tracked by a version control system like Git. Line breaking modifies your files, and having version control ensures you can review and revert changes if needed.\n\n\n### As a module:\n\n```python\nfrom linebreaker import format_line, break_text\n\n# Format a single line\nresult = format_line(\"Your text here...\")\n\n# Process entire text with YAML/code blocks\nresult = break_text(full_text)\n```\n\n## Running Tests\n\n```bash\n# Run all tests\npytest linebreaker/tests/\n```\n\n\n\n## Detailed Features\n\n### Hard Breaks (Sentence Boundaries)\n- Splits on `.`, `?`, `!` when both before and after have 20+ characters\n- Avoids common abbreviations: vs., Dr., Prof., Mr., Mrs., Ms., Ph.D., M.D., Jr., Sr., etc., e.g., i.e., et al., vol., no., pp., fig.\n\n### Medium Breaks (Colons/Semicolons)\n- Splits sentences longer than 80 characters at `:` or `;`\n- Only if both parts have 20+ characters\n\n### Soft Breaks (Conjunctions)\n- Applied when there are 3+ sentences or sentence is >60 characters\n- Breaks on: `but`, `such as`, `for example`, `e.g.`, `i.e.` (after 20 chars)\n- Breaks on commas (after 40 chars)\n- Breaks on `and`, `or` (after 40 chars)\n\n### Smart Masking\n- Citations `[@...]` are masked to prevent dots inside from triggering breaks\n- Decimal numbers like `0.85` are masked similarly\n\n## Development\n\nTo add new abbreviations, edit the `abbreviations` pattern in `core.py`:\n\n```python\nabbreviations = r'(?!vs\\.|dr\\.|prof\\.|...|your_abbrev\\.)'\n```\n",
"bugtrack_url": null,
"license": null,
"summary": "Intelligent line breaking for Markdown and text files",
"version": "0.0.0",
"project_urls": {
"Changelog": "https://github.com/SilasK/linebreaker/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/SilasK/linebreaker",
"Issues": "https://github.com/SilasK/linebreaker/issues",
"Repository": "https://github.com/SilasK/linebreaker"
},
"split_keywords": [
"markdown",
" text",
" line-breaking",
" formatting"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "d3276c3fc3eb0d0ebdb0b7ed69b49440e88ea2a092a9274439270d66e4ef997e",
"md5": "cd744f1cda1cc77eb18d93866ab9489b",
"sha256": "7a764522a012a778a1f22c105ed41ce8a29221d38140dd8189cfa2c623106bd4"
},
"downloads": -1,
"filename": "linebreaker-0.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "cd744f1cda1cc77eb18d93866ab9489b",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 15640,
"upload_time": "2025-11-05T15:21:50",
"upload_time_iso_8601": "2025-11-05T15:21:50.844317Z",
"url": "https://files.pythonhosted.org/packages/d3/27/6c3fc3eb0d0ebdb0b7ed69b49440e88ea2a092a9274439270d66e4ef997e/linebreaker-0.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "f556d41aaac60c3cbbe911779a67c2af0db17f5685184c6ccbcfc3be03ce4e45",
"md5": "04a0f9c4e03ca7ed04c540f90784ed46",
"sha256": "fdee2bb84ac2e492f2e15853758a5f9f89d9a044e48d2526531c695cb679c650"
},
"downloads": -1,
"filename": "linebreaker-0.0.0.tar.gz",
"has_sig": false,
"md5_digest": "04a0f9c4e03ca7ed04c540f90784ed46",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 16469,
"upload_time": "2025-11-05T15:21:52",
"upload_time_iso_8601": "2025-11-05T15:21:52.326292Z",
"url": "https://files.pythonhosted.org/packages/f5/56/d41aaac60c3cbbe911779a67c2af0db17f5685184c6ccbcfc3be03ce4e45/linebreaker-0.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-11-05 15:21:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "SilasK",
"github_project": "linebreaker",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "linebreaker"
}