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.
Files changed (33) hide show
  1. {flowmark-0.3.1 → flowmark-0.3.2}/.copier-answers.yml +2 -2
  2. {flowmark-0.3.1 → flowmark-0.3.2}/.github/workflows/publish.yml +3 -0
  3. {flowmark-0.3.1 → flowmark-0.3.2}/.gitignore +4 -1
  4. {flowmark-0.3.1 → flowmark-0.3.2}/Makefile +6 -3
  5. {flowmark-0.3.1 → flowmark-0.3.2}/PKG-INFO +12 -4
  6. {flowmark-0.3.1 → flowmark-0.3.2}/README.md +9 -2
  7. flowmark-0.3.2/development.md +89 -0
  8. {flowmark-0.3.1 → flowmark-0.3.2}/devtools/lint.py +13 -12
  9. flowmark-0.3.2/publishing.md +71 -0
  10. flowmark-0.3.2/pyproject.toml +138 -0
  11. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/__init__.py +3 -2
  12. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/cli.py +4 -5
  13. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/frontmatter.py +1 -4
  14. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/line_wrappers.py +6 -6
  15. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/markdown_filling.py +18 -11
  16. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/sentence_split_regex.py +4 -5
  17. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/text_filling.py +6 -6
  18. {flowmark-0.3.1 → flowmark-0.3.2}/src/flowmark/text_wrapping.py +14 -14
  19. {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_filling.py +2 -1
  20. {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_ref_docs.py +15 -9
  21. {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_wrapping.py +1 -1
  22. flowmark-0.3.2/uv.lock +356 -0
  23. flowmark-0.3.1/development.md +0 -64
  24. flowmark-0.3.1/pyproject.toml +0 -88
  25. flowmark-0.3.1/tests/__init__.py +0 -0
  26. flowmark-0.3.1/uv.lock +0 -579
  27. {flowmark-0.3.1 → flowmark-0.3.2}/.github/workflows/ci.yml +0 -0
  28. {flowmark-0.3.1 → flowmark-0.3.2}/LICENSE +0 -0
  29. {flowmark-0.3.1 → flowmark-0.3.2}/poetry.lock +0 -0
  30. {flowmark-0.3.1 → flowmark-0.3.2}/tests/test_frontmatter.py +0 -0
  31. {flowmark-0.3.1 → flowmark-0.3.2}/tests/testdocs/testdoc.orig.md +0 -0
  32. {flowmark-0.3.1 → flowmark-0.3.2}/tests/testdocs/testdoc.out.plain.md +0 -0
  33. {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: 1742e95
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
@@ -31,6 +31,9 @@ jobs:
31
31
  - name: Install all dependencies
32
32
  run: uv sync --all-extras --dev
33
33
 
34
+ - name: Run tests
35
+ run: uv run pytest
36
+
34
37
  - name: Build package
35
38
  run: uv build
36
39
 
@@ -1,7 +1,10 @@
1
1
  # Additions to standard GitHub .gitignore:
2
+ *.bak
3
+ *.orig
2
4
  tmp/
3
5
  trash/
4
- .kmd/
6
+ attic/
7
+ .kash/
5
8
 
6
9
  # Byte-compiled / optimized / DLL files
7
10
  __pycache__/
@@ -3,11 +3,11 @@
3
3
 
4
4
  .DEFAULT_GOAL := default
5
5
 
6
- .PHONY: default install_deps lint test build clean gen_test_docs
6
+ .PHONY: default install lint test upgrade build clean gen_test_docs
7
7
 
8
- default: install_deps lint test
8
+ default: install lint test
9
9
 
10
- install_deps:
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.1
3
+ Version: 0.3.2
4
4
  Summary: Better line wrapping and formatting for plaintext and Markdown
5
- Project-URL: Repository, https://github.com//flowmark
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 pip/poetry/uv to install
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 pip/poetry/uv to install
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 += _run(["codespell", "--write-changes", *SRC_PATHS, *DOC_PATHS])
15
- errcount += _run(["usort", "format", *SRC_PATHS])
16
- errcount += _run(["ruff", "check", "--fix", *SRC_PATHS])
17
- errcount += _run(["black", *SRC_PATHS])
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
- def _run(cmd: list[str]) -> int:
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 .markdown_filling import fill_markdown, line_wrap_by_sentence, line_wrap_to_width
13
- from .text_filling import fill_text, Wrap
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, Wrap
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: Optional[List[str]] = None) -> Options:
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: Optional[List[str]] = None) -> int:
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, "r") as f:
163
+ with open(options.file) as f:
165
164
  text = f.read()
166
165
 
167
166
  if options.plaintext:
@@ -1,7 +1,4 @@
1
- from typing import Tuple
2
-
3
-
4
- def split_frontmatter(text: str) -> Tuple[str, str]:
1
+ def split_frontmatter(text: str) -> tuple[str, str]:
5
2
  """
6
3
  Split a text document into frontmatter and content parts.
7
4
 
@@ -1,10 +1,10 @@
1
- from typing import Callable, List, Protocol
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) -> List[str]: ...
23
+ def __call__(self, text: str) -> list[str]: ...
24
24
 
25
25
 
26
- def split_sentences_no_min_length(text: str) -> List[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: List[str] = []
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 i, sentence in enumerate(sentences):
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])