flowmark 0.3.1__tar.gz → 0.3.2__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.
- {flowmark-0.3.1 → flowmark-0.3.2}/.copier-answers.yml +2 -2
- {flowmark-0.3.1 → flowmark-0.3.2}/.github/workflows/publish.yml +3 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/.gitignore +4 -1
- {flowmark-0.3.1 → flowmark-0.3.2}/Makefile +6 -3
- {flowmark-0.3.1 → flowmark-0.3.2}/PKG-INFO +12 -4
- {flowmark-0.3.1 → flowmark-0.3.2}/README.md +9 -2
- flowmark-0.3.2/development.md +89 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/devtools/lint.py +13 -12
- flowmark-0.3.2/publishing.md +71 -0
- flowmark-0.3.2/pyproject.toml +138 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/__init__.py +3 -2
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/cli.py +4 -5
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/frontmatter.py +1 -4
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/line_wrappers.py +6 -6
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/markdown_filling.py +18 -11
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/sentence_split_regex.py +4 -5
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/text_filling.py +6 -6
- {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/text_wrapping.py +14 -14
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_filling.py +2 -1
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_ref_docs.py +15 -9
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_wrapping.py +1 -1
- flowmark-0.3.2/uv.lock +356 -0
- flowmark-0.3.1/development.md +0 -64
- flowmark-0.3.1/pyproject.toml +0 -88
- flowmark-0.3.1/tests/__init__.py +0 -0
- flowmark-0.3.1/uv.lock +0 -579
- {flowmark-0.3.1 → flowmark-0.3.2}/.github/workflows/ci.yml +0 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/LICENSE +0 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/poetry.lock +0 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_frontmatter.py +0 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/testdocs/testdoc.orig.md +0 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/testdocs/testdoc.out.plain.md +0 -0
- {flowmark-0.3.1 → flowmark-0.3.2}/tests/testdocs/testdoc.out.semantic.md +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Changes here will be overwritten by Copier. Do not edit manually.
|
|
2
|
-
_commit:
|
|
2
|
+
_commit: v0.2.0
|
|
3
3
|
_src_path: gh:jlevy/simple-modern-uv
|
|
4
4
|
package_author_email: joshua@cal.berkeley.edu
|
|
5
5
|
package_author_name: Joshua Levy
|
|
6
6
|
package_description: Better line wrapping and formatting for plaintext and Markdown
|
|
7
7
|
package_github_org: jlevy
|
|
8
|
+
package_module: flowmark
|
|
8
9
|
package_name: flowmark
|
|
9
|
-
package_slug: flowmark
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
.DEFAULT_GOAL := default
|
|
5
5
|
|
|
6
|
-
.PHONY: default
|
|
6
|
+
.PHONY: default install lint test upgrade build clean gen_test_docs
|
|
7
7
|
|
|
8
|
-
default:
|
|
8
|
+
default: install lint test
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
install:
|
|
11
11
|
uv sync --all-extras --dev
|
|
12
12
|
|
|
13
13
|
lint:
|
|
@@ -16,6 +16,9 @@ lint:
|
|
|
16
16
|
test:
|
|
17
17
|
uv run pytest
|
|
18
18
|
|
|
19
|
+
upgrade:
|
|
20
|
+
uv sync --upgrade
|
|
21
|
+
|
|
19
22
|
build:
|
|
20
23
|
uv build
|
|
21
24
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flowmark
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Better line wrapping and formatting for plaintext and Markdown
|
|
5
|
-
Project-URL: Repository, https://github.com
|
|
5
|
+
Project-URL: Repository, https://github.com/jlevy/flowmark
|
|
6
6
|
Author-email: Joshua Levy <joshua@cal.berkeley.edu>
|
|
7
7
|
License-Expression: MIT
|
|
8
8
|
License-File: LICENSE
|
|
@@ -10,6 +10,7 @@ Requires-Python: <4.0,>=3.10
|
|
|
10
10
|
Requires-Dist: marko>=2.1.2
|
|
11
11
|
Requires-Dist: regex>=2024.11.6
|
|
12
12
|
Requires-Dist: strif>=2.0.0
|
|
13
|
+
Requires-Dist: typing-extensions>=4.12.2
|
|
13
14
|
Description-Content-Type: text/markdown
|
|
14
15
|
|
|
15
16
|
# flowmark
|
|
@@ -17,6 +18,7 @@ Description-Content-Type: text/markdown
|
|
|
17
18
|
Flowmark is a new Python implementation of **text and Markdown line wrapping and
|
|
18
19
|
filling**, with an emphasis on making **git diffs** and **LLM edits** to text documents
|
|
19
20
|
easier to diff and review.
|
|
21
|
+
after updating
|
|
20
22
|
|
|
21
23
|
In addition, it adds **support for Markdown** and offers **Markdown auto-formatting and
|
|
22
24
|
normalization** as a library or from the command line.
|
|
@@ -26,7 +28,10 @@ Python and has (in my humble opinion) better options and defaults.
|
|
|
26
28
|
|
|
27
29
|
## Installation
|
|
28
30
|
|
|
29
|
-
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv)
|
|
31
|
+
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv).
|
|
32
|
+
Then run `uvx flowmark --help`.
|
|
33
|
+
|
|
34
|
+
To install the command-line properly:
|
|
30
35
|
|
|
31
36
|
```shell
|
|
32
37
|
uv tool install flowmark
|
|
@@ -44,7 +49,7 @@ Then
|
|
|
44
49
|
flowmark --help
|
|
45
50
|
```
|
|
46
51
|
|
|
47
|
-
To use as a library, use
|
|
52
|
+
To use as a library, use uv/poetry/pip to install
|
|
48
53
|
[`flowmark`](https://pypi.org/project/flowmark/).
|
|
49
54
|
|
|
50
55
|
## Use in VSCode/Cursor
|
|
@@ -158,6 +163,7 @@ Markdown content. It can:
|
|
|
158
163
|
|
|
159
164
|
- Optionally break lines at sentence boundaries for better diff readability
|
|
160
165
|
|
|
166
|
+
|
|
161
167
|
- Process plaintext with HTML-aware word splitting
|
|
162
168
|
|
|
163
169
|
It is both a library and a command-line tool.
|
|
@@ -183,6 +189,8 @@ Command-line usage examples:
|
|
|
183
189
|
For more details, see: https://github.com/jlevy/flowmark
|
|
184
190
|
```
|
|
185
191
|
|
|
192
|
+
For instructions on publishing to PyPI, see [publishing.md](publishing.md).
|
|
193
|
+
|
|
186
194
|
* * *
|
|
187
195
|
|
|
188
196
|
*This project was built from
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
Flowmark is a new Python implementation of **text and Markdown line wrapping and
|
|
4
4
|
filling**, with an emphasis on making **git diffs** and **LLM edits** to text documents
|
|
5
5
|
easier to diff and review.
|
|
6
|
+
after updating
|
|
6
7
|
|
|
7
8
|
In addition, it adds **support for Markdown** and offers **Markdown auto-formatting and
|
|
8
9
|
normalization** as a library or from the command line.
|
|
@@ -12,7 +13,10 @@ Python and has (in my humble opinion) better options and defaults.
|
|
|
12
13
|
|
|
13
14
|
## Installation
|
|
14
15
|
|
|
15
|
-
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv)
|
|
16
|
+
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv).
|
|
17
|
+
Then run `uvx flowmark --help`.
|
|
18
|
+
|
|
19
|
+
To install the command-line properly:
|
|
16
20
|
|
|
17
21
|
```shell
|
|
18
22
|
uv tool install flowmark
|
|
@@ -30,7 +34,7 @@ Then
|
|
|
30
34
|
flowmark --help
|
|
31
35
|
```
|
|
32
36
|
|
|
33
|
-
To use as a library, use
|
|
37
|
+
To use as a library, use uv/poetry/pip to install
|
|
34
38
|
[`flowmark`](https://pypi.org/project/flowmark/).
|
|
35
39
|
|
|
36
40
|
## Use in VSCode/Cursor
|
|
@@ -144,6 +148,7 @@ Markdown content. It can:
|
|
|
144
148
|
|
|
145
149
|
- Optionally break lines at sentence boundaries for better diff readability
|
|
146
150
|
|
|
151
|
+
|
|
147
152
|
- Process plaintext with HTML-aware word splitting
|
|
148
153
|
|
|
149
154
|
It is both a library and a command-line tool.
|
|
@@ -169,6 +174,8 @@ Command-line usage examples:
|
|
|
169
174
|
For more details, see: https://github.com/jlevy/flowmark
|
|
170
175
|
```
|
|
171
176
|
|
|
177
|
+
For instructions on publishing to PyPI, see [publishing.md](publishing.md).
|
|
178
|
+
|
|
172
179
|
* * *
|
|
173
180
|
|
|
174
181
|
*This project was built from
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# Development
|
|
2
|
+
|
|
3
|
+
## Setting Up uv
|
|
4
|
+
|
|
5
|
+
This project is set up to use [uv](https://docs.astral.sh/uv/) to manage Python and
|
|
6
|
+
dependencies. First, be sure you
|
|
7
|
+
[have uv installed](https://docs.astral.sh/uv/getting-started/installation/).
|
|
8
|
+
|
|
9
|
+
Then [fork the jlevy/flowmark repo](https://github.com/jlevy/flowmark/fork) (having your
|
|
10
|
+
own fork will make it easier to contribute) and
|
|
11
|
+
[clone it](https://docs.github.com/en/repositories/creating-and-managing-repositories/cloning-a-repository).
|
|
12
|
+
|
|
13
|
+
## Basic Developer Workflows
|
|
14
|
+
|
|
15
|
+
The `Makefile` simply offers shortcuts to `uv` commands for developer convenience.
|
|
16
|
+
(For clarity, GitHub Actions don't use the Makefile and just call `uv` directly.)
|
|
17
|
+
|
|
18
|
+
```shell
|
|
19
|
+
# First, install all dependencies and set up your virtual environment.
|
|
20
|
+
# This simply runs `uv sync --all-extras --dev` to install all packages,
|
|
21
|
+
# including dev dependencies and optional dependencies.
|
|
22
|
+
make install
|
|
23
|
+
|
|
24
|
+
# Run uv sync, lint, and test:
|
|
25
|
+
make
|
|
26
|
+
|
|
27
|
+
# Build wheel:
|
|
28
|
+
make build
|
|
29
|
+
|
|
30
|
+
# Linting:
|
|
31
|
+
make lint
|
|
32
|
+
|
|
33
|
+
# Run tests:
|
|
34
|
+
make test
|
|
35
|
+
|
|
36
|
+
# Delete all the build artifacts:
|
|
37
|
+
make clean
|
|
38
|
+
|
|
39
|
+
# Upgrade dependencies to compatible versions:
|
|
40
|
+
make upgrade
|
|
41
|
+
|
|
42
|
+
# To run tests by hand:
|
|
43
|
+
uv run pytest # all tests
|
|
44
|
+
uv run pytest -s src/module/some_file.py # one test, showing outputs
|
|
45
|
+
|
|
46
|
+
# Build and install current dev executables, to let you use your dev copies
|
|
47
|
+
# as local tools:
|
|
48
|
+
uv tool install --editable .
|
|
49
|
+
|
|
50
|
+
# Dependency management directly with uv:
|
|
51
|
+
# Add a new dependency:
|
|
52
|
+
uv add package_name
|
|
53
|
+
# Add a development dependency:
|
|
54
|
+
uv add --dev package_name
|
|
55
|
+
# Update to latest compatible versions (including dependencies on git repos):
|
|
56
|
+
uv sync --upgrade
|
|
57
|
+
# Update a specific package:
|
|
58
|
+
uv lock --upgrade-package package_name
|
|
59
|
+
# Update dependencies on a package:
|
|
60
|
+
uv add package_name@latest
|
|
61
|
+
|
|
62
|
+
# Run a shell within the Python environment:
|
|
63
|
+
uv venv
|
|
64
|
+
source .venv/bin/activate
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
See [uv docs](https://docs.astral.sh/uv/) for details.
|
|
68
|
+
|
|
69
|
+
## IDE setup
|
|
70
|
+
|
|
71
|
+
If you use VSCode or a fork like Cursor or Windsurf, you can install the following
|
|
72
|
+
extensions:
|
|
73
|
+
|
|
74
|
+
- [Python](https://marketplace.visualstudio.com/items?itemName=ms-python.python)
|
|
75
|
+
|
|
76
|
+
- [Based Pyright](https://marketplace.visualstudio.com/items?itemName=detachhead.basedpyright)
|
|
77
|
+
for type checking. Note that this extension works with non-Microsoft VSCode forks like
|
|
78
|
+
Cursor.
|
|
79
|
+
|
|
80
|
+
## Documentation
|
|
81
|
+
|
|
82
|
+
- [uv docs](https://docs.astral.sh/uv/)
|
|
83
|
+
|
|
84
|
+
- [basedpyright docs](https://docs.basedpyright.com/latest/)
|
|
85
|
+
|
|
86
|
+
* * *
|
|
87
|
+
|
|
88
|
+
*This file was built with
|
|
89
|
+
[simple-modern-uv](https://github.com/jlevy/simple-modern-uv).*
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# Update as needed.
|
|
2
|
-
SRC_PATHS = ["src", "tests"]
|
|
3
|
-
DOC_PATHS = ["README.md"]
|
|
4
|
-
|
|
5
|
-
|
|
6
1
|
import subprocess
|
|
2
|
+
|
|
3
|
+
from funlog import log_calls
|
|
7
4
|
from rich import print as rprint
|
|
8
5
|
|
|
6
|
+
# Update as needed.
|
|
7
|
+
SRC_PATHS = ["src", "tests", "devtools"]
|
|
8
|
+
DOC_PATHS = ["README.md"]
|
|
9
|
+
|
|
9
10
|
|
|
10
11
|
def main():
|
|
11
12
|
rprint()
|
|
12
13
|
|
|
13
14
|
errcount = 0
|
|
14
|
-
errcount +=
|
|
15
|
-
errcount +=
|
|
16
|
-
errcount +=
|
|
17
|
-
errcount +=
|
|
18
|
-
errcount += _run(["mypy", *SRC_PATHS])
|
|
15
|
+
errcount += run(["codespell", "--write-changes", *SRC_PATHS, *DOC_PATHS])
|
|
16
|
+
errcount += run(["ruff", "check", "--fix", *SRC_PATHS])
|
|
17
|
+
errcount += run(["ruff", "format", *SRC_PATHS])
|
|
18
|
+
errcount += run(["basedpyright", *SRC_PATHS])
|
|
19
19
|
|
|
20
20
|
rprint()
|
|
21
21
|
|
|
@@ -28,7 +28,9 @@ def main():
|
|
|
28
28
|
return errcount
|
|
29
29
|
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
@log_calls(level="warning", show_timing_only=True)
|
|
32
|
+
def run(cmd: list[str]) -> int:
|
|
33
|
+
rprint()
|
|
32
34
|
rprint(f"[bold green]❯ {' '.join(cmd)}[/bold green]")
|
|
33
35
|
errcount = 0
|
|
34
36
|
try:
|
|
@@ -36,7 +38,6 @@ def _run(cmd: list[str]) -> int:
|
|
|
36
38
|
except subprocess.CalledProcessError as e:
|
|
37
39
|
rprint(f"[bold red]Error: {e}[/bold red]")
|
|
38
40
|
errcount = 1
|
|
39
|
-
rprint()
|
|
40
41
|
|
|
41
42
|
return errcount
|
|
42
43
|
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
## Publishing Releases
|
|
2
|
+
|
|
3
|
+
This is how to publish a Python package to [**PyPI**](https://pypi.org/) from GitHub
|
|
4
|
+
Actions, when using the
|
|
5
|
+
[**simple-modern-uv**](https://github.com/jlevy/simple-modern-uv) template.
|
|
6
|
+
|
|
7
|
+
Thanks to [the dynamic versioning
|
|
8
|
+
plugin](https://github.com/ninoseki/uv-dynamic-versioning/) and the
|
|
9
|
+
[`publish.yml` workflow](https://github.com/jlevy/simple-modern-uv/blob/main/template/.github/workflows/publish.yml),
|
|
10
|
+
you can simply create tagged releases (using standard format for the tag name, e.g.
|
|
11
|
+
`v0.1.0`) on GitHub and the tag will trigger a release build, which then uploads it to
|
|
12
|
+
PyPI.
|
|
13
|
+
|
|
14
|
+
### How to Publish the First Time
|
|
15
|
+
|
|
16
|
+
This part is a little confusing the first time.
|
|
17
|
+
Here is the simplest way to do it.
|
|
18
|
+
For the purposes of this example replace OWNER and PROJECT with the right values.
|
|
19
|
+
|
|
20
|
+
1. **Get a PyPI account** at [pypi.org](https://pypi.org/) and sign in.
|
|
21
|
+
|
|
22
|
+
2. **Pick a name for the project** that isn't already taken.
|
|
23
|
+
|
|
24
|
+
- Go to `https://pypi.org/project/PROJECT` to see if another project with that name
|
|
25
|
+
already exits.
|
|
26
|
+
|
|
27
|
+
- If needed, update your `pyproject.yml` with the correct name.
|
|
28
|
+
|
|
29
|
+
3. **Authorize** your repository to publish to PyPI:
|
|
30
|
+
|
|
31
|
+
- Go to [the publishing settings page](https://pypi.org/manage/account/publishing/).
|
|
32
|
+
|
|
33
|
+
- Find "Trusted Publisher Management" and register your GitHub repo as a new
|
|
34
|
+
"pending" trusted publisher
|
|
35
|
+
|
|
36
|
+
- Enter the project name, repo owner, repo name, and `publish.yml` as the workflow
|
|
37
|
+
name. (You can leave the "environment name" field blank.)
|
|
38
|
+
|
|
39
|
+
4. **Create a release** on GitHub:
|
|
40
|
+
|
|
41
|
+
- Commit code and make sure it's running correctly.
|
|
42
|
+
|
|
43
|
+
- Go to your GitHub project page, then click on Actions tab.
|
|
44
|
+
|
|
45
|
+
- Confirm all tests are passing in the last CI workflow.
|
|
46
|
+
(If you want, you can even publish this template when it's empty as just a stub
|
|
47
|
+
project, to try all this out.)
|
|
48
|
+
|
|
49
|
+
- Go to your GitHub project page, click on Releases.
|
|
50
|
+
|
|
51
|
+
- Fill in the tag and the release name.
|
|
52
|
+
Select to create a new tag, and pick a version.
|
|
53
|
+
A good option is `v0.1.0`. (It's wise to have it start with a `v`.)
|
|
54
|
+
|
|
55
|
+
- Submit to create the release.
|
|
56
|
+
|
|
57
|
+
5. **Confirm it publishes to PyPI**
|
|
58
|
+
|
|
59
|
+
- Watch for the release workflow in the GitHub Actions tab.
|
|
60
|
+
|
|
61
|
+
- If it succeeds, you should see it appear at `https://pypi.org/project/PROJECT`.
|
|
62
|
+
|
|
63
|
+
### How to Publish Subsequent Releases
|
|
64
|
+
|
|
65
|
+
Just create a new release!
|
|
66
|
+
Everything is the same as the last two steps above.
|
|
67
|
+
|
|
68
|
+
* * *
|
|
69
|
+
|
|
70
|
+
*This file was built with
|
|
71
|
+
[simple-modern-uv](https://github.com/jlevy/simple-modern-uv).*
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# ---- Project Info and Dependencies ----
|
|
2
|
+
|
|
3
|
+
[project.urls]
|
|
4
|
+
Repository = "https://github.com/jlevy/flowmark"
|
|
5
|
+
# Homepage = "https://..."
|
|
6
|
+
|
|
7
|
+
[project]
|
|
8
|
+
name = "flowmark"
|
|
9
|
+
description = "Better line wrapping and formatting for plaintext and Markdown"
|
|
10
|
+
authors = [
|
|
11
|
+
{ name="Joshua Levy", email="joshua@cal.berkeley.edu" },
|
|
12
|
+
]
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
license = "MIT"
|
|
15
|
+
requires-python = ">=3.10,<4.0"
|
|
16
|
+
dynamic = ["version"]
|
|
17
|
+
|
|
18
|
+
dependencies = [
|
|
19
|
+
"marko>=2.1.2",
|
|
20
|
+
"regex>=2024.11.6",
|
|
21
|
+
"strif>=2.0.0",
|
|
22
|
+
"typing-extensions>=4.12.2",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[dependency-groups]
|
|
26
|
+
dev = [
|
|
27
|
+
"pytest>=8.3.5",
|
|
28
|
+
"ruff>=0.11.0",
|
|
29
|
+
"codespell>=2.4.1",
|
|
30
|
+
"rich>=13.9.4",
|
|
31
|
+
"basedpyright>=1.28.2",
|
|
32
|
+
"funlog>=0.2.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
# Add script entry points here.
|
|
38
|
+
flowmark = "flowmark.cli:main"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# ---- Build system ----
|
|
42
|
+
|
|
43
|
+
# Dynamic versioning from:
|
|
44
|
+
# https://github.com/ninoseki/uv-dynamic-versioning/
|
|
45
|
+
|
|
46
|
+
[build-system]
|
|
47
|
+
requires = ["hatchling", "uv-dynamic-versioning"]
|
|
48
|
+
build-backend = "hatchling.build"
|
|
49
|
+
|
|
50
|
+
[tool.hatch.version]
|
|
51
|
+
source = "uv-dynamic-versioning"
|
|
52
|
+
# Note JSON schemas don't seem to be right for tool.hatch.version.source so
|
|
53
|
+
# this may cause false warnings in IDEs.
|
|
54
|
+
# https://github.com/ninoseki/uv-dynamic-versioning/issues/21
|
|
55
|
+
|
|
56
|
+
[tool.uv-dynamic-versioning]
|
|
57
|
+
vcs = "git"
|
|
58
|
+
style = "pep440"
|
|
59
|
+
bump = "true"
|
|
60
|
+
|
|
61
|
+
# ---- Settings ----
|
|
62
|
+
|
|
63
|
+
[tool.ruff]
|
|
64
|
+
# Set as desired, typically 88 (black standard) or 100 (wide).
|
|
65
|
+
line-length = 100
|
|
66
|
+
|
|
67
|
+
[tool.ruff.lint]
|
|
68
|
+
# See: https://docs.astral.sh/ruff/rules/
|
|
69
|
+
select = [
|
|
70
|
+
# Basic list from: https://docs.astral.sh/ruff/linter/#rule-selection
|
|
71
|
+
"E", # https://docs.astral.sh/ruff/rules/#error-e
|
|
72
|
+
"F", # https://docs.astral.sh/ruff/rules/#pyflakes-f
|
|
73
|
+
"UP", # https://docs.astral.sh/ruff/rules/#pyupgrade-up
|
|
74
|
+
"B", # https://docs.astral.sh/ruff/rules/#flake8-bugbear-b
|
|
75
|
+
"I", # https://docs.astral.sh/ruff/rules/#isort-i
|
|
76
|
+
# Other possibilities:
|
|
77
|
+
# "D" # https://docs.astral.sh/ruff/rules/#pydocstyle-d
|
|
78
|
+
# "Q" # https://docs.astral.sh/ruff/rules/#flake8-quotes-q
|
|
79
|
+
# "COM" # https://docs.astral.sh/ruff/rules/#flake8-commas-com
|
|
80
|
+
# "SIM", # https://docs.astral.sh/ruff/rules/#flake8-simplify-sim
|
|
81
|
+
|
|
82
|
+
]
|
|
83
|
+
ignore = [
|
|
84
|
+
"E501", # https://docs.astral.sh/ruff/rules/line-too-long/
|
|
85
|
+
"E402", # https://docs.astral.sh/ruff/rules/module-import-not-at-top-of-file/
|
|
86
|
+
"E731", # https://docs.astral.sh/ruff/rules/lambda-assignment/
|
|
87
|
+
# We use both ruff formatter and linter so some rules should always be disabled.
|
|
88
|
+
# See: https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules
|
|
89
|
+
"W191", # https://docs.astral.sh/ruff/rules/tab-indentation/
|
|
90
|
+
"E111", # https://docs.astral.sh/ruff/rules/indentation-with-invalid-multiple/
|
|
91
|
+
"E114", # https://docs.astral.sh/ruff/rules/indentation-with-invalid-multiple-comment/
|
|
92
|
+
"E117", # https://docs.astral.sh/ruff/rules/over-indented/
|
|
93
|
+
"D206", # https://docs.astral.sh/ruff/rules/docstring-tab-indentation/
|
|
94
|
+
"D300", # https://docs.astral.sh/ruff/rules/triple-single-quotes/
|
|
95
|
+
"Q000", # https://docs.astral.sh/ruff/rules/bad-quotes-inline-string/
|
|
96
|
+
"Q001", # https://docs.astral.sh/ruff/rules/bad-quotes-multiline-string/
|
|
97
|
+
"Q002", # https://docs.astral.sh/ruff/rules/bad-quotes-docstring/
|
|
98
|
+
"Q003", # https://docs.astral.sh/ruff/rules/avoidable-escaped-quote/
|
|
99
|
+
"COM812", # https://docs.astral.sh/ruff/rules/missing-trailing-comma/
|
|
100
|
+
"COM819", # https://docs.astral.sh/ruff/rules/prohibited-trailing-comma/
|
|
101
|
+
"ISC002", # https://docs.astral.sh/ruff/rules/multi-line-implicit-string-concatenation/
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
# BasedPyright currently seems like the best type checker option, much faster
|
|
105
|
+
# than mypy and with a good extension for VSCode/Cursor.
|
|
106
|
+
# https://marketplace.visualstudio.com/items?itemName=detachhead.basedpyright
|
|
107
|
+
# https://docs.basedpyright.com/latest/configuration/config-files/#sample-pyprojecttoml-file
|
|
108
|
+
[tool.basedpyright]
|
|
109
|
+
include = ["src", "tests", "devtools"]
|
|
110
|
+
# Make ignoring easier:
|
|
111
|
+
reportIgnoreCommentWithoutRule = false
|
|
112
|
+
reportUnnecessaryTypeIgnoreComment = false
|
|
113
|
+
# Typically noisy warnings, comment/uncomment as desired:
|
|
114
|
+
reportMissingTypeStubs = false
|
|
115
|
+
reportUnusedCallResult = false
|
|
116
|
+
# reportMissingImports = false
|
|
117
|
+
# reportUnnecessaryIsInstance = false
|
|
118
|
+
# reportUnreachable = false
|
|
119
|
+
reportAny = false
|
|
120
|
+
reportExplicitAny = false
|
|
121
|
+
reportUnusedParameter = false
|
|
122
|
+
# reportUnknownVariableType = false
|
|
123
|
+
# reportUnknownArgumentType = false
|
|
124
|
+
|
|
125
|
+
[tool.codespell]
|
|
126
|
+
# ignore-words-list = "foo,bar"
|
|
127
|
+
skip = "tests/testdocs/*.md"
|
|
128
|
+
|
|
129
|
+
[tool.pytest.ini_options]
|
|
130
|
+
python_files = ["*.py"]
|
|
131
|
+
python_classes = ["Test*"]
|
|
132
|
+
python_functions = ["test_*"]
|
|
133
|
+
testpaths = [
|
|
134
|
+
"src",
|
|
135
|
+
"tests",
|
|
136
|
+
]
|
|
137
|
+
norecursedirs = []
|
|
138
|
+
filterwarnings = []
|
|
@@ -9,6 +9,7 @@ __all__ = (
|
|
|
9
9
|
"Wrap",
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
12
|
+
from .line_wrappers import line_wrap_by_sentence, line_wrap_to_width
|
|
13
|
+
from .markdown_filling import fill_markdown
|
|
14
|
+
from .text_filling import Wrap, fill_text
|
|
14
15
|
from .text_wrapping import html_md_word_splitter, wrap_paragraph, wrap_paragraph_lines
|
|
@@ -40,11 +40,10 @@ import argparse
|
|
|
40
40
|
import importlib.metadata
|
|
41
41
|
import sys
|
|
42
42
|
from dataclasses import dataclass
|
|
43
|
-
from typing import List, Optional
|
|
44
43
|
|
|
45
44
|
from strif import atomic_output_file
|
|
46
45
|
|
|
47
|
-
from flowmark import fill_markdown, fill_text, html_md_word_splitter
|
|
46
|
+
from flowmark import Wrap, fill_markdown, fill_text, html_md_word_splitter
|
|
48
47
|
|
|
49
48
|
|
|
50
49
|
@dataclass
|
|
@@ -61,7 +60,7 @@ class Options:
|
|
|
61
60
|
version: bool
|
|
62
61
|
|
|
63
62
|
|
|
64
|
-
def _parse_args(args:
|
|
63
|
+
def _parse_args(args: list[str] | None = None) -> Options:
|
|
65
64
|
"""Parse command-line arguments for the flowmark tool."""
|
|
66
65
|
# Use the module's docstring as the description
|
|
67
66
|
module_doc = __doc__ or ""
|
|
@@ -136,7 +135,7 @@ def _parse_args(args: Optional[List[str]] = None) -> Options:
|
|
|
136
135
|
)
|
|
137
136
|
|
|
138
137
|
|
|
139
|
-
def main(args:
|
|
138
|
+
def main(args: list[str] | None = None) -> int:
|
|
140
139
|
"""
|
|
141
140
|
Main entry point for the flowmark CLI.
|
|
142
141
|
|
|
@@ -161,7 +160,7 @@ def main(args: Optional[List[str]] = None) -> int:
|
|
|
161
160
|
if options.file == "-":
|
|
162
161
|
text = sys.stdin.read()
|
|
163
162
|
else:
|
|
164
|
-
with open(options.file
|
|
163
|
+
with open(options.file) as f:
|
|
165
164
|
text = f.read()
|
|
166
165
|
|
|
167
166
|
if options.plaintext:
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Callable
|
|
2
|
+
from typing import Protocol
|
|
2
3
|
|
|
3
4
|
from flowmark.sentence_split_regex import split_sentences_regex
|
|
4
5
|
from flowmark.text_filling import DEFAULT_WRAP_WIDTH
|
|
5
6
|
from flowmark.text_wrapping import DEFAULT_LEN_FUNCTION, wrap_paragraph, wrap_paragraph_lines
|
|
6
7
|
|
|
7
|
-
|
|
8
8
|
DEFAULT_MIN_LINE_LEN = 20
|
|
9
9
|
"""Default minimum line length for sentence breaking."""
|
|
10
10
|
|
|
@@ -20,10 +20,10 @@ class LineWrapper(Protocol):
|
|
|
20
20
|
class SentenceSplitter(Protocol):
|
|
21
21
|
"""Takes a text string and returns a list of sentences."""
|
|
22
22
|
|
|
23
|
-
def __call__(self, text: str) ->
|
|
23
|
+
def __call__(self, text: str) -> list[str]: ...
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def split_sentences_no_min_length(text: str) ->
|
|
26
|
+
def split_sentences_no_min_length(text: str) -> list[str]:
|
|
27
27
|
return split_sentences_regex(text, min_length=0)
|
|
28
28
|
|
|
29
29
|
|
|
@@ -61,7 +61,7 @@ def line_wrap_by_sentence(
|
|
|
61
61
|
|
|
62
62
|
def line_wrapper(text: str, initial_indent: str, subsequent_indent: str) -> str:
|
|
63
63
|
text = text.replace("\n", " ")
|
|
64
|
-
lines:
|
|
64
|
+
lines: list[str] = []
|
|
65
65
|
first_line = True
|
|
66
66
|
length = len_fn
|
|
67
67
|
initial_indent_len = len_fn(initial_indent)
|
|
@@ -69,7 +69,7 @@ def line_wrap_by_sentence(
|
|
|
69
69
|
|
|
70
70
|
sentences = split_sentences(text)
|
|
71
71
|
|
|
72
|
-
for
|
|
72
|
+
for sentence in sentences:
|
|
73
73
|
current_column = initial_indent_len if first_line else subsequent_indent_len
|
|
74
74
|
if len(lines) > 0 and length(lines[-1]) < min_line_len:
|
|
75
75
|
current_column += length(lines[-1])
|