flowmark 0.2.1__tar.gz → 0.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. flowmark-0.3.1/.copier-answers.yml +9 -0
  2. flowmark-0.3.1/.github/workflows/ci.yml +63 -0
  3. flowmark-0.3.1/.github/workflows/publish.yml +38 -0
  4. flowmark-0.3.1/.gitignore +176 -0
  5. flowmark-0.3.1/Makefile +32 -0
  6. flowmark-0.3.1/PKG-INFO +189 -0
  7. flowmark-0.3.1/README.md +175 -0
  8. flowmark-0.3.1/development.md +64 -0
  9. flowmark-0.3.1/devtools/lint.py +45 -0
  10. flowmark-0.3.1/poetry.lock +778 -0
  11. flowmark-0.3.1/pyproject.toml +88 -0
  12. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/cli.py +27 -9
  13. flowmark-0.3.1/src/flowmark/frontmatter.py +44 -0
  14. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/markdown_filling.py +47 -10
  15. flowmark-0.3.1/tests/__init__.py +0 -0
  16. flowmark-0.3.1/tests/test_filling.py +286 -0
  17. flowmark-0.3.1/tests/test_frontmatter.py +72 -0
  18. flowmark-0.3.1/tests/test_ref_docs.py +41 -0
  19. flowmark-0.3.1/tests/test_wrapping.py +130 -0
  20. flowmark-0.3.1/tests/testdocs/testdoc.orig.md +593 -0
  21. flowmark-0.3.1/tests/testdocs/testdoc.out.plain.md +877 -0
  22. flowmark-0.3.1/tests/testdocs/testdoc.out.semantic.md +918 -0
  23. flowmark-0.3.1/uv.lock +579 -0
  24. flowmark-0.2.1/PKG-INFO +0 -142
  25. flowmark-0.2.1/README.md +0 -122
  26. flowmark-0.2.1/pyproject.toml +0 -102
  27. {flowmark-0.2.1 → flowmark-0.3.1}/LICENSE +0 -0
  28. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/__init__.py +0 -0
  29. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/line_wrappers.py +0 -0
  30. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/sentence_split_regex.py +0 -0
  31. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/text_filling.py +0 -0
  32. {flowmark-0.2.1 → flowmark-0.3.1}/src/flowmark/text_wrapping.py +0 -0
@@ -0,0 +1,9 @@
1
+ # Changes here will be overwritten by Copier. Do not edit manually.
2
+ _commit: 1742e95
3
+ _src_path: gh:jlevy/simple-modern-uv
4
+ package_author_email: joshua@cal.berkeley.edu
5
+ package_author_name: Joshua Levy
6
+ package_description: Better line wrapping and formatting for plaintext and Markdown
7
+ package_github_org: jlevy
8
+ package_name: flowmark
9
+ package_slug: flowmark
@@ -0,0 +1,63 @@
1
+ # This workflow will install Python dependencies, run tests and lint with a single version of Python
2
+ # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3
+
4
+ name: CI
5
+
6
+ on:
7
+ push:
8
+ # Use ["main", "master"] for CI only on the default branch.
9
+ # Use ["**"] for CI on all branches.
10
+ branches: ["main", "master"]
11
+ pull_request:
12
+ branches: ["main", "master"]
13
+
14
+ permissions:
15
+ contents: read
16
+
17
+ jobs:
18
+ build:
19
+ strategy:
20
+ matrix:
21
+ # Update this as needed:
22
+
23
+ # Common platforms: ["ubuntu-latest", "macos-latest", "windows-latest"]
24
+ os: ["ubuntu-latest"]
25
+ python-version: ["3.10","3.11", "3.12", "3.13"]
26
+
27
+ # Linux only by default. Use ${{ matrix.os }} for other OSes.
28
+ runs-on: ${{ matrix.os }}
29
+
30
+ steps:
31
+ # Generally following uv docs:
32
+ # https://docs.astral.sh/uv/guides/integration/github/
33
+
34
+ - name: Checkout (official GitHub action)
35
+ uses: actions/checkout@v4
36
+ with:
37
+ # Important for versioning plugins:
38
+ fetch-depth: 0
39
+
40
+ - name: Install uv (official Astral action)
41
+ uses: astral-sh/setup-uv@v5
42
+ with:
43
+ version: "0.6.5"
44
+ enable-cache: true
45
+ python-version: ${{ matrix.python-version }}
46
+
47
+ - name: Set up Python (using uv)
48
+ run: uv python install
49
+
50
+ # Alternately can use the official Python action:
51
+ # - name: Set up Python (using actions/setup-python)
52
+ # uses: actions/setup-python@v5
53
+ # with:
54
+ # python-version: ${{ matrix.python-version }}
55
+
56
+ - name: Install all dependencies
57
+ run: uv sync --all-extras --dev
58
+
59
+ - name: Run linting
60
+ run: uv run python devtools/lint.py
61
+
62
+ - name: Run tests
63
+ run: uv run pytest
@@ -0,0 +1,38 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch: # Enable manual trigger.
7
+
8
+ jobs:
9
+ build-and-publish:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ id-token: write # Mandatory for OIDC.
13
+ contents: read
14
+ steps:
15
+ - name: Checkout (official GitHub action)
16
+ uses: actions/checkout@v4
17
+ with:
18
+ # Important for versioning plugins:
19
+ fetch-depth: 0
20
+
21
+ - name: Install uv (official Astral action)
22
+ uses: astral-sh/setup-uv@v5
23
+ with:
24
+ version: "0.6.5"
25
+ enable-cache: true
26
+ python-version: "3.12"
27
+
28
+ - name: Set up Python (using uv)
29
+ run: uv python install
30
+
31
+ - name: Install all dependencies
32
+ run: uv sync --all-extras --dev
33
+
34
+ - name: Build package
35
+ run: uv build
36
+
37
+ - name: Publish to PyPI (using uv)
38
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,176 @@
1
+ # Additions to standard GitHub .gitignore:
2
+ tmp/
3
+ trash/
4
+ .kmd/
5
+
6
+ # Byte-compiled / optimized / DLL files
7
+ __pycache__/
8
+ *.py[cod]
9
+ *$py.class
10
+
11
+ # C extensions
12
+ *.so
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
33
+
34
+ # PyInstaller
35
+ # Usually these files are written by a python script from a template
36
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py,cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Translations
60
+ *.mo
61
+ *.pot
62
+
63
+ # Django stuff:
64
+ *.log
65
+ local_settings.py
66
+ db.sqlite3
67
+ db.sqlite3-journal
68
+
69
+ # Flask stuff:
70
+ instance/
71
+ .webassets-cache
72
+
73
+ # Scrapy stuff:
74
+ .scrapy
75
+
76
+ # Sphinx documentation
77
+ docs/_build/
78
+
79
+ # PyBuilder
80
+ .pybuilder/
81
+ target/
82
+
83
+ # Jupyter Notebook
84
+ .ipynb_checkpoints
85
+
86
+ # IPython
87
+ profile_default/
88
+ ipython_config.py
89
+
90
+ # pyenv
91
+ # For a library or package, you might want to ignore these files since the code is
92
+ # intended to run in multiple environments; otherwise, check them in:
93
+ # .python-version
94
+
95
+ # pipenv
96
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
97
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
98
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
99
+ # install all needed dependencies.
100
+ #Pipfile.lock
101
+
102
+ # UV
103
+ # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
104
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
105
+ # commonly ignored for libraries.
106
+ #uv.lock
107
+
108
+ # poetry
109
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
110
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
111
+ # commonly ignored for libraries.
112
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
113
+ #poetry.lock
114
+
115
+ # pdm
116
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
117
+ #pdm.lock
118
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
119
+ # in version control.
120
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
121
+ .pdm.toml
122
+ .pdm-python
123
+ .pdm-build/
124
+
125
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
126
+ __pypackages__/
127
+
128
+ # Celery stuff
129
+ celerybeat-schedule
130
+ celerybeat.pid
131
+
132
+ # SageMath parsed files
133
+ *.sage.py
134
+
135
+ # Environments
136
+ .env
137
+ .venv
138
+ env/
139
+ venv/
140
+ ENV/
141
+ env.bak/
142
+ venv.bak/
143
+
144
+ # Spyder project settings
145
+ .spyderproject
146
+ .spyproject
147
+
148
+ # Rope project settings
149
+ .ropeproject
150
+
151
+ # mkdocs documentation
152
+ /site
153
+
154
+ # mypy
155
+ .mypy_cache/
156
+ .dmypy.json
157
+ dmypy.json
158
+
159
+ # Pyre type checker
160
+ .pyre/
161
+
162
+ # pytype static type analyzer
163
+ .pytype/
164
+
165
+ # Cython debug symbols
166
+ cython_debug/
167
+
168
+ # PyCharm
169
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
170
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
171
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
172
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
173
+ #.idea/
174
+
175
+ # PyPI configuration file
176
+ .pypirc
@@ -0,0 +1,32 @@
1
+ # Makefile for easy development workflows.
2
+ # GitHub Actions call uv directly.
3
+
4
+ .DEFAULT_GOAL := default
5
+
6
+ .PHONY: default install_deps lint test build clean gen_test_docs
7
+
8
+ default: install_deps lint test
9
+
10
+ install_deps:
11
+ uv sync --all-extras --dev
12
+
13
+ lint:
14
+ uv run python devtools/lint.py
15
+
16
+ test:
17
+ uv run pytest
18
+
19
+ build:
20
+ uv build
21
+
22
+ clean:
23
+ -rm -rf dist/
24
+ -rm -rf *.egg-info/
25
+ -rm -rf .pytest_cache/
26
+ -rm -rf .mypy_cache/
27
+ -rm -rf .venv/
28
+ -find . -type d -name "__pycache__" -exec rm -rf {} +
29
+
30
+ gen_test_docs:
31
+ poetry run flowmark tests/testdocs/testdoc.orig.md -o tests/testdocs/testdoc.out.plain.md
32
+ poetry run flowmark --semantic tests/testdocs/testdoc.orig.md -o tests/testdocs/testdoc.out.semantic.md
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: flowmark
3
+ Version: 0.3.1
4
+ Summary: Better line wrapping and formatting for plaintext and Markdown
5
+ Project-URL: Repository, https://github.com//flowmark
6
+ Author-email: Joshua Levy <joshua@cal.berkeley.edu>
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Requires-Python: <4.0,>=3.10
10
+ Requires-Dist: marko>=2.1.2
11
+ Requires-Dist: regex>=2024.11.6
12
+ Requires-Dist: strif>=2.0.0
13
+ Description-Content-Type: text/markdown
14
+
15
+ # flowmark
16
+
17
+ Flowmark is a new Python implementation of **text and Markdown line wrapping and
18
+ filling**, with an emphasis on making **git diffs** and **LLM edits** to text documents
19
+ easier to diff and review.
20
+
21
+ In addition, it adds **support for Markdown** and offers **Markdown auto-formatting and
22
+ normalization** as a library or from the command line.
23
+ This is much like [markdownfmt](https://github.com/shurcooL/markdownfmt) or
24
+ [prettier's Markdown support](https://prettier.io/blog/2017/11/07/1.8.0) but is pure
25
+ Python and has (in my humble opinion) better options and defaults.
26
+
27
+ ## Installation
28
+
29
+ The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv):
30
+
31
+ ```shell
32
+ uv tool install flowmark
33
+ ```
34
+
35
+ Or [pipx](https://github.com/pypa/pipx):
36
+
37
+ ```shell
38
+ pipx install flowmark
39
+ ```
40
+
41
+ Then
42
+
43
+ ```
44
+ flowmark --help
45
+ ```
46
+
47
+ To use as a library, use pip/poetry/uv to install
48
+ [`flowmark`](https://pypi.org/project/flowmark/).
49
+
50
+ ## Use in VSCode/Cursor
51
+
52
+ You can use Flowmark to auto-format Markdown on save in VSCode or Cursor.
53
+ Install the "Run on Save" (`emeraldwalk.runonsave`) extension.
54
+ Then add to your `settings.json`:
55
+
56
+ ```json
57
+ "emeraldwalk.runonsave": {
58
+ "commands": [
59
+ {
60
+ "match": "\\.md$",
61
+ "cmd": "flowmark --auto ${file}"
62
+ }
63
+ ]
64
+ }
65
+ ```
66
+
67
+ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
68
+
69
+ ## Use Cases
70
+
71
+ - As a **command line formatter** to format text or Markdown files using the `flowmark`
72
+ command.
73
+
74
+ - To **autoformat Markdown on save in VSCode/Cursor** or any other editor that supports
75
+ running a command on save.
76
+ Flowmark uses a readable format that makes diffs easy to read and use on GitHub.
77
+ It also normalizes all Markdown syntax variations (such as different header or
78
+ formatting styles). This can be especially useful for documentation and editing
79
+ workflows where clean diffs and minimal merge conflicts on GitHub are important.
80
+
81
+ - As a **library to autoformat Markdown**. For example, it is great to normalize the
82
+ outputs from LLMs to be consistent, or to run on the inputs and outputs of LLM
83
+ transformations that edit text, so that the resulting diffs are clean.
84
+ Having this as a simple Python library makes this easy in AI-related document
85
+ pipelines.
86
+
87
+ - As a **drop-in replacement library for Python's default
88
+ [`textwrap`](https://docs.python.org/3/library/textwrap.html)** but with more options.
89
+ It simplifies and generalizes that library, offering better control over **initial and
90
+ subsequent indentation** and **when to split words and lines**, e.g. using a word
91
+ splitter that won't break lines within HTML tags.
92
+
93
+ - Flowmark has the option to to use **semantic line breaks** (using a heuristic to break
94
+ lines on sentences sentences when that is reasonable), which is an underrated feature
95
+ that can **make diffs on GitHub much more readable**. The the change may seem subtle
96
+ but avoids having paragraphs reflow for very small edits, which does a lot to
97
+ **minimize merge conflicts**. An example of what sentence-guided wrapping looks like,
98
+ see the
99
+ [Markdown source](https://github.com/jlevy/flowmark/blob/main/README.md?plain=1) of
100
+ this readme file.)
101
+
102
+ - Very, very simple and fast **regex-based sentence splitting**. This should work fine
103
+ for English and many other latin/Cyrillic languages but it hasn't been tested on CJK.
104
+
105
+ It aims to be small and simple and have only a few dependencies, currently only
106
+ [`marko`](https://github.com/frostming/marko),
107
+ [`regex`](https://pypi.org/project/regex/), and
108
+ [`strif`](https://github.com/jlevy/strif).
109
+
110
+ Because **YAML frontmatter** is common on Markdown files, the Markdown autoformat
111
+ preserves all frontmatter (content between `---` delimiters at the front of a file).
112
+
113
+ ## Why a New Markdown Formatter?
114
+
115
+ Previously I'd implemented something very similar with
116
+ [for Atom](https://github.com/jlevy/atom-flowmark).
117
+ I found the Markdown formatting conventions enforced by the that plugin worked really
118
+ well for editing and publishing large or collaboratively edited documents.
119
+
120
+ This is new, pure Python implementation.
121
+ There are numerous needs for a tool like this on the command line and in Python.
122
+
123
+ With LLM tools now using Markdown everywhere, there are enormous advantages to having
124
+ very clean and well-formatted Markdown documents, since you can then cleanly see diffs
125
+ or edits made by LLMs.
126
+
127
+ If you are in a workspace where you are editing lots of text, having them all be
128
+ Markdown with frontmatter, auto-formatted for every git commit makes for a *much* better
129
+ experience.
130
+
131
+ ## Usage
132
+
133
+ Flowmark can be used as a library or as a CLI.
134
+
135
+ ```
136
+ $ flowmark --help
137
+ usage: flowmark [-h] [-o OUTPUT] [-w WIDTH] [-p] [-s] [-i] [--nobackup] [file]
138
+
139
+ Flowmark: Better line wrapping and formatting for plaintext and Markdown
140
+
141
+ positional arguments:
142
+ file Input file (use '-' for stdin)
143
+
144
+ options:
145
+ -h, --help show this help message and exit
146
+ -o, --output OUTPUT Output file (use '-' for stdout)
147
+ -w, --width WIDTH Line width to wrap to
148
+ -p, --plaintext Process as plaintext (no Markdown parsing)
149
+ -s, --semantic Enable sentence-based line breaks (only applies to Markdown mode)
150
+ -i, --inplace Edit the file in place (ignores --output)
151
+ --nobackup Do not make a backup of the original file when using --inplace
152
+
153
+ Flowmark provides enhanced text wrapping capabilities with special handling for
154
+ Markdown content. It can:
155
+
156
+ - Format Markdown with proper line wrapping while preserving structure
157
+ and normalizing Markdown formatting
158
+
159
+ - Optionally break lines at sentence boundaries for better diff readability
160
+
161
+ - Process plaintext with HTML-aware word splitting
162
+
163
+ It is both a library and a command-line tool.
164
+
165
+ Command-line usage examples:
166
+
167
+ # Format a Markdown file to stdout
168
+ flowmark README.md
169
+
170
+ # Format a Markdown file and save to a new file
171
+ flowmark README.md -o README_formatted.md
172
+
173
+ # Edit a file in-place (with or without making a backup)
174
+ flowmark --inplace README.md
175
+ flowmark --inplace --nobackup README.md
176
+
177
+ # Process plaintext instead of Markdown
178
+ flowmark --plaintext text.txt
179
+
180
+ # Use sentences to guide line breaks (good for many purposes git history and diffs)
181
+ flowmark --semantic README.md
182
+
183
+ For more details, see: https://github.com/jlevy/flowmark
184
+ ```
185
+
186
+ * * *
187
+
188
+ *This project was built from
189
+ [simple-modern-uv](https://github.com/jlevy/simple-modern-uv).*
@@ -0,0 +1,175 @@
1
+ # flowmark
2
+
3
+ Flowmark is a new Python implementation of **text and Markdown line wrapping and
4
+ filling**, with an emphasis on making **git diffs** and **LLM edits** to text documents
5
+ easier to diff and review.
6
+
7
+ In addition, it adds **support for Markdown** and offers **Markdown auto-formatting and
8
+ normalization** as a library or from the command line.
9
+ This is much like [markdownfmt](https://github.com/shurcooL/markdownfmt) or
10
+ [prettier's Markdown support](https://prettier.io/blog/2017/11/07/1.8.0) but is pure
11
+ Python and has (in my humble opinion) better options and defaults.
12
+
13
+ ## Installation
14
+
15
+ The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv):
16
+
17
+ ```shell
18
+ uv tool install flowmark
19
+ ```
20
+
21
+ Or [pipx](https://github.com/pypa/pipx):
22
+
23
+ ```shell
24
+ pipx install flowmark
25
+ ```
26
+
27
+ Then
28
+
29
+ ```
30
+ flowmark --help
31
+ ```
32
+
33
+ To use as a library, use pip/poetry/uv to install
34
+ [`flowmark`](https://pypi.org/project/flowmark/).
35
+
36
+ ## Use in VSCode/Cursor
37
+
38
+ You can use Flowmark to auto-format Markdown on save in VSCode or Cursor.
39
+ Install the "Run on Save" (`emeraldwalk.runonsave`) extension.
40
+ Then add to your `settings.json`:
41
+
42
+ ```json
43
+ "emeraldwalk.runonsave": {
44
+ "commands": [
45
+ {
46
+ "match": "\\.md$",
47
+ "cmd": "flowmark --auto ${file}"
48
+ }
49
+ ]
50
+ }
51
+ ```
52
+
53
+ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
54
+
55
+ ## Use Cases
56
+
57
+ - As a **command line formatter** to format text or Markdown files using the `flowmark`
58
+ command.
59
+
60
+ - To **autoformat Markdown on save in VSCode/Cursor** or any other editor that supports
61
+ running a command on save.
62
+ Flowmark uses a readable format that makes diffs easy to read and use on GitHub.
63
+ It also normalizes all Markdown syntax variations (such as different header or
64
+ formatting styles). This can be especially useful for documentation and editing
65
+ workflows where clean diffs and minimal merge conflicts on GitHub are important.
66
+
67
+ - As a **library to autoformat Markdown**. For example, it is great to normalize the
68
+ outputs from LLMs to be consistent, or to run on the inputs and outputs of LLM
69
+ transformations that edit text, so that the resulting diffs are clean.
70
+ Having this as a simple Python library makes this easy in AI-related document
71
+ pipelines.
72
+
73
+ - As a **drop-in replacement library for Python's default
74
+ [`textwrap`](https://docs.python.org/3/library/textwrap.html)** but with more options.
75
+ It simplifies and generalizes that library, offering better control over **initial and
76
+ subsequent indentation** and **when to split words and lines**, e.g. using a word
77
+ splitter that won't break lines within HTML tags.
78
+
79
+ - Flowmark has the option to to use **semantic line breaks** (using a heuristic to break
80
+ lines on sentences sentences when that is reasonable), which is an underrated feature
81
+ that can **make diffs on GitHub much more readable**. The the change may seem subtle
82
+ but avoids having paragraphs reflow for very small edits, which does a lot to
83
+ **minimize merge conflicts**. An example of what sentence-guided wrapping looks like,
84
+ see the
85
+ [Markdown source](https://github.com/jlevy/flowmark/blob/main/README.md?plain=1) of
86
+ this readme file.)
87
+
88
+ - Very, very simple and fast **regex-based sentence splitting**. This should work fine
89
+ for English and many other latin/Cyrillic languages but it hasn't been tested on CJK.
90
+
91
+ It aims to be small and simple and have only a few dependencies, currently only
92
+ [`marko`](https://github.com/frostming/marko),
93
+ [`regex`](https://pypi.org/project/regex/), and
94
+ [`strif`](https://github.com/jlevy/strif).
95
+
96
+ Because **YAML frontmatter** is common on Markdown files, the Markdown autoformat
97
+ preserves all frontmatter (content between `---` delimiters at the front of a file).
98
+
99
+ ## Why a New Markdown Formatter?
100
+
101
+ Previously I'd implemented something very similar with
102
+ [for Atom](https://github.com/jlevy/atom-flowmark).
103
+ I found the Markdown formatting conventions enforced by the that plugin worked really
104
+ well for editing and publishing large or collaboratively edited documents.
105
+
106
+ This is new, pure Python implementation.
107
+ There are numerous needs for a tool like this on the command line and in Python.
108
+
109
+ With LLM tools now using Markdown everywhere, there are enormous advantages to having
110
+ very clean and well-formatted Markdown documents, since you can then cleanly see diffs
111
+ or edits made by LLMs.
112
+
113
+ If you are in a workspace where you are editing lots of text, having them all be
114
+ Markdown with frontmatter, auto-formatted for every git commit makes for a *much* better
115
+ experience.
116
+
117
+ ## Usage
118
+
119
+ Flowmark can be used as a library or as a CLI.
120
+
121
+ ```
122
+ $ flowmark --help
123
+ usage: flowmark [-h] [-o OUTPUT] [-w WIDTH] [-p] [-s] [-i] [--nobackup] [file]
124
+
125
+ Flowmark: Better line wrapping and formatting for plaintext and Markdown
126
+
127
+ positional arguments:
128
+ file Input file (use '-' for stdin)
129
+
130
+ options:
131
+ -h, --help show this help message and exit
132
+ -o, --output OUTPUT Output file (use '-' for stdout)
133
+ -w, --width WIDTH Line width to wrap to
134
+ -p, --plaintext Process as plaintext (no Markdown parsing)
135
+ -s, --semantic Enable sentence-based line breaks (only applies to Markdown mode)
136
+ -i, --inplace Edit the file in place (ignores --output)
137
+ --nobackup Do not make a backup of the original file when using --inplace
138
+
139
+ Flowmark provides enhanced text wrapping capabilities with special handling for
140
+ Markdown content. It can:
141
+
142
+ - Format Markdown with proper line wrapping while preserving structure
143
+ and normalizing Markdown formatting
144
+
145
+ - Optionally break lines at sentence boundaries for better diff readability
146
+
147
+ - Process plaintext with HTML-aware word splitting
148
+
149
+ It is both a library and a command-line tool.
150
+
151
+ Command-line usage examples:
152
+
153
+ # Format a Markdown file to stdout
154
+ flowmark README.md
155
+
156
+ # Format a Markdown file and save to a new file
157
+ flowmark README.md -o README_formatted.md
158
+
159
+ # Edit a file in-place (with or without making a backup)
160
+ flowmark --inplace README.md
161
+ flowmark --inplace --nobackup README.md
162
+
163
+ # Process plaintext instead of Markdown
164
+ flowmark --plaintext text.txt
165
+
166
+ # Use sentences to guide line breaks (good for many purposes git history and diffs)
167
+ flowmark --semantic README.md
168
+
169
+ For more details, see: https://github.com/jlevy/flowmark
170
+ ```
171
+
172
+ * * *
173
+
174
+ *This project was built from
175
+ [simple-modern-uv](https://github.com/jlevy/simple-modern-uv).*