flowmark 0.3.1__tar.gz → 0.3.3__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.3}/.copier-answers.yml +2 -2
- {flowmark-0.3.1 → flowmark-0.3.3}/.github/workflows/publish.yml +3 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/.gitignore +4 -1
- {flowmark-0.3.1 → flowmark-0.3.3}/Makefile +6 -3
- {flowmark-0.3.1 → flowmark-0.3.3}/PKG-INFO +24 -10
- {flowmark-0.3.1 → flowmark-0.3.3}/README.md +21 -8
- flowmark-0.3.3/development.md +89 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/devtools/lint.py +13 -12
- flowmark-0.3.3/publishing.md +71 -0
- flowmark-0.3.3/pyproject.toml +138 -0
- flowmark-0.3.3/src/flowmark/__init__.py +19 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/src/flowmark/cli.py +4 -5
- {flowmark-0.3.1 → flowmark-0.3.3}/src/flowmark/frontmatter.py +1 -4
- {flowmark-0.3.1 → flowmark-0.3.3}/src/flowmark/line_wrappers.py +6 -6
- {flowmark-0.3.1 → flowmark-0.3.3}/src/flowmark/markdown_filling.py +18 -11
- flowmark-0.3.3/src/flowmark/sentence_split_regex.py +86 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/src/flowmark/text_filling.py +6 -6
- {flowmark-0.3.1 → flowmark-0.3.3}/src/flowmark/text_wrapping.py +14 -14
- {flowmark-0.3.1 → flowmark-0.3.3}/tests/test_filling.py +2 -1
- {flowmark-0.3.1 → flowmark-0.3.3}/tests/test_ref_docs.py +15 -9
- flowmark-0.3.3/tests/test_sentences.py +30 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/tests/test_wrapping.py +1 -1
- flowmark-0.3.3/uv.lock +356 -0
- flowmark-0.3.1/development.md +0 -64
- flowmark-0.3.1/pyproject.toml +0 -88
- flowmark-0.3.1/src/flowmark/__init__.py +0 -14
- flowmark-0.3.1/src/flowmark/sentence_split_regex.py +0 -62
- flowmark-0.3.1/tests/__init__.py +0 -0
- flowmark-0.3.1/uv.lock +0 -579
- {flowmark-0.3.1 → flowmark-0.3.3}/.github/workflows/ci.yml +0 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/LICENSE +0 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/poetry.lock +0 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/tests/test_frontmatter.py +0 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/tests/testdocs/testdoc.orig.md +0 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/tests/testdocs/testdoc.out.plain.md +0 -0
- {flowmark-0.3.1 → flowmark-0.3.3}/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.3
|
|
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
|
|
@@ -18,15 +19,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.
|
|
20
21
|
|
|
21
|
-
In addition, it
|
|
22
|
-
|
|
22
|
+
In addition, it offers **Markdown auto-formatting and normalization** as a library or
|
|
23
|
+
from the command line.
|
|
23
24
|
This is much like [markdownfmt](https://github.com/shurcooL/markdownfmt) or
|
|
24
25
|
[prettier's Markdown support](https://prettier.io/blog/2017/11/07/1.8.0) but is pure
|
|
25
26
|
Python and has (in my humble opinion) better options and defaults.
|
|
26
27
|
|
|
27
28
|
## Installation
|
|
28
29
|
|
|
29
|
-
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv)
|
|
30
|
+
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv).
|
|
31
|
+
Then run `uvx flowmark --help`.
|
|
32
|
+
|
|
33
|
+
To install the command-line properly:
|
|
30
34
|
|
|
31
35
|
```shell
|
|
32
36
|
uv tool install flowmark
|
|
@@ -44,7 +48,7 @@ Then
|
|
|
44
48
|
flowmark --help
|
|
45
49
|
```
|
|
46
50
|
|
|
47
|
-
To use as a library, use
|
|
51
|
+
To use as a library, use uv/poetry/pip to install
|
|
48
52
|
[`flowmark`](https://pypi.org/project/flowmark/).
|
|
49
53
|
|
|
50
54
|
## Use in VSCode/Cursor
|
|
@@ -68,8 +72,7 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
68
72
|
|
|
69
73
|
## Use Cases
|
|
70
74
|
|
|
71
|
-
|
|
72
|
-
command.
|
|
75
|
+
The main ways to use Flowmark are:
|
|
73
76
|
|
|
74
77
|
- To **autoformat Markdown on save in VSCode/Cursor** or any other editor that supports
|
|
75
78
|
running a command on save.
|
|
@@ -78,6 +81,9 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
78
81
|
formatting styles). This can be especially useful for documentation and editing
|
|
79
82
|
workflows where clean diffs and minimal merge conflicts on GitHub are important.
|
|
80
83
|
|
|
84
|
+
- As a **command line formatter** to format text or Markdown files using the `flowmark`
|
|
85
|
+
command.
|
|
86
|
+
|
|
81
87
|
- As a **library to autoformat Markdown**. For example, it is great to normalize the
|
|
82
88
|
outputs from LLMs to be consistent, or to run on the inputs and outputs of LLM
|
|
83
89
|
transformations that edit text, so that the resulting diffs are clean.
|
|
@@ -90,6 +96,8 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
90
96
|
subsequent indentation** and **when to split words and lines**, e.g. using a word
|
|
91
97
|
splitter that won't break lines within HTML tags.
|
|
92
98
|
|
|
99
|
+
Other features:
|
|
100
|
+
|
|
93
101
|
- Flowmark has the option to to use **semantic line breaks** (using a heuristic to break
|
|
94
102
|
lines on sentences sentences when that is reasonable), which is an underrated feature
|
|
95
103
|
that can **make diffs on GitHub much more readable**. The the change may seem subtle
|
|
@@ -99,8 +107,11 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
99
107
|
[Markdown source](https://github.com/jlevy/flowmark/blob/main/README.md?plain=1) of
|
|
100
108
|
this readme file.)
|
|
101
109
|
|
|
102
|
-
- Very
|
|
103
|
-
|
|
110
|
+
- Very simple and fast **regex-based sentence splitting**. It's just based on letters
|
|
111
|
+
and punctuation so isn't perfect but works well for these purposes (and is much faster
|
|
112
|
+
and simpler than a proper sentence parser like SpaCy).
|
|
113
|
+
It should work fine for English and many other latin/Cyrillic languages but hasn't
|
|
114
|
+
been tested on CJK.
|
|
104
115
|
|
|
105
116
|
It aims to be small and simple and have only a few dependencies, currently only
|
|
106
117
|
[`marko`](https://github.com/frostming/marko),
|
|
@@ -158,6 +169,7 @@ Markdown content. It can:
|
|
|
158
169
|
|
|
159
170
|
- Optionally break lines at sentence boundaries for better diff readability
|
|
160
171
|
|
|
172
|
+
|
|
161
173
|
- Process plaintext with HTML-aware word splitting
|
|
162
174
|
|
|
163
175
|
It is both a library and a command-line tool.
|
|
@@ -183,6 +195,8 @@ Command-line usage examples:
|
|
|
183
195
|
For more details, see: https://github.com/jlevy/flowmark
|
|
184
196
|
```
|
|
185
197
|
|
|
198
|
+
For instructions on publishing to PyPI, see [publishing.md](publishing.md).
|
|
199
|
+
|
|
186
200
|
* * *
|
|
187
201
|
|
|
188
202
|
*This project was built from
|
|
@@ -4,15 +4,18 @@ 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
6
|
|
|
7
|
-
In addition, it
|
|
8
|
-
|
|
7
|
+
In addition, it offers **Markdown auto-formatting and normalization** as a library or
|
|
8
|
+
from the command line.
|
|
9
9
|
This is much like [markdownfmt](https://github.com/shurcooL/markdownfmt) or
|
|
10
10
|
[prettier's Markdown support](https://prettier.io/blog/2017/11/07/1.8.0) but is pure
|
|
11
11
|
Python and has (in my humble opinion) better options and defaults.
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
|
-
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv)
|
|
15
|
+
The simplest way to use the tool is to use [uv](https://github.com/astral-sh/uv).
|
|
16
|
+
Then run `uvx flowmark --help`.
|
|
17
|
+
|
|
18
|
+
To install the command-line properly:
|
|
16
19
|
|
|
17
20
|
```shell
|
|
18
21
|
uv tool install flowmark
|
|
@@ -30,7 +33,7 @@ Then
|
|
|
30
33
|
flowmark --help
|
|
31
34
|
```
|
|
32
35
|
|
|
33
|
-
To use as a library, use
|
|
36
|
+
To use as a library, use uv/poetry/pip to install
|
|
34
37
|
[`flowmark`](https://pypi.org/project/flowmark/).
|
|
35
38
|
|
|
36
39
|
## Use in VSCode/Cursor
|
|
@@ -54,8 +57,7 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
54
57
|
|
|
55
58
|
## Use Cases
|
|
56
59
|
|
|
57
|
-
|
|
58
|
-
command.
|
|
60
|
+
The main ways to use Flowmark are:
|
|
59
61
|
|
|
60
62
|
- To **autoformat Markdown on save in VSCode/Cursor** or any other editor that supports
|
|
61
63
|
running a command on save.
|
|
@@ -64,6 +66,9 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
64
66
|
formatting styles). This can be especially useful for documentation and editing
|
|
65
67
|
workflows where clean diffs and minimal merge conflicts on GitHub are important.
|
|
66
68
|
|
|
69
|
+
- As a **command line formatter** to format text or Markdown files using the `flowmark`
|
|
70
|
+
command.
|
|
71
|
+
|
|
67
72
|
- As a **library to autoformat Markdown**. For example, it is great to normalize the
|
|
68
73
|
outputs from LLMs to be consistent, or to run on the inputs and outputs of LLM
|
|
69
74
|
transformations that edit text, so that the resulting diffs are clean.
|
|
@@ -76,6 +81,8 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
76
81
|
subsequent indentation** and **when to split words and lines**, e.g. using a word
|
|
77
82
|
splitter that won't break lines within HTML tags.
|
|
78
83
|
|
|
84
|
+
Other features:
|
|
85
|
+
|
|
79
86
|
- Flowmark has the option to to use **semantic line breaks** (using a heuristic to break
|
|
80
87
|
lines on sentences sentences when that is reasonable), which is an underrated feature
|
|
81
88
|
that can **make diffs on GitHub much more readable**. The the change may seem subtle
|
|
@@ -85,8 +92,11 @@ The `--auto` option is just the same as `--inplace --nobackup --semantic`.
|
|
|
85
92
|
[Markdown source](https://github.com/jlevy/flowmark/blob/main/README.md?plain=1) of
|
|
86
93
|
this readme file.)
|
|
87
94
|
|
|
88
|
-
- Very
|
|
89
|
-
|
|
95
|
+
- Very simple and fast **regex-based sentence splitting**. It's just based on letters
|
|
96
|
+
and punctuation so isn't perfect but works well for these purposes (and is much faster
|
|
97
|
+
and simpler than a proper sentence parser like SpaCy).
|
|
98
|
+
It should work fine for English and many other latin/Cyrillic languages but hasn't
|
|
99
|
+
been tested on CJK.
|
|
90
100
|
|
|
91
101
|
It aims to be small and simple and have only a few dependencies, currently only
|
|
92
102
|
[`marko`](https://github.com/frostming/marko),
|
|
@@ -144,6 +154,7 @@ Markdown content. It can:
|
|
|
144
154
|
|
|
145
155
|
- Optionally break lines at sentence boundaries for better diff readability
|
|
146
156
|
|
|
157
|
+
|
|
147
158
|
- Process plaintext with HTML-aware word splitting
|
|
148
159
|
|
|
149
160
|
It is both a library and a command-line tool.
|
|
@@ -169,6 +180,8 @@ Command-line usage examples:
|
|
|
169
180
|
For more details, see: https://github.com/jlevy/flowmark
|
|
170
181
|
```
|
|
171
182
|
|
|
183
|
+
For instructions on publishing to PyPI, see [publishing.md](publishing.md).
|
|
184
|
+
|
|
172
185
|
* * *
|
|
173
186
|
|
|
174
187
|
*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 = []
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
__all__ = (
|
|
2
|
+
"fill_text",
|
|
3
|
+
"fill_markdown",
|
|
4
|
+
"first_sentence",
|
|
5
|
+
"first_sentences",
|
|
6
|
+
"html_md_word_splitter",
|
|
7
|
+
"line_wrap_by_sentence",
|
|
8
|
+
"line_wrap_to_width",
|
|
9
|
+
"split_sentences_regex",
|
|
10
|
+
"wrap_paragraph",
|
|
11
|
+
"wrap_paragraph_lines",
|
|
12
|
+
"Wrap",
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
from .line_wrappers import line_wrap_by_sentence, line_wrap_to_width
|
|
16
|
+
from .markdown_filling import fill_markdown
|
|
17
|
+
from .sentence_split_regex import first_sentence, first_sentences, split_sentences_regex
|
|
18
|
+
from .text_filling import Wrap, fill_text
|
|
19
|
+
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:
|