foundrytools-cli 2.1.1__tar.gz → 2.2.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.
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/PKG-INFO +20 -26
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/README.md +8 -16
- foundrytools_cli-2.2.1/pyproject.toml +131 -0
- foundrytools_cli-2.2.1/pyproject.toml.orig +112 -0
- foundrytools_cli-2.2.1/src/foundrytools_cli/__init__.py +3 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/__main__.py +1 -1
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/fix/cli.py +0 -1
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/font.py +40 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/otf.py +71 -16
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/utils/cli.py +0 -1
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/utils/font_renamer.py +1 -1
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/utils/sync_timestamps.py +3 -4
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/utils/task_runner.py +4 -4
- foundrytools_cli-2.1.1/pyproject.toml +0 -74
- foundrytools_cli-2.1.1/src/foundrytools_cli/__init__.py +0 -3
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/__init__.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/cff.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/cmap.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/converter/__init__.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/converter/cli.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/converter/ttf_to_otf.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/fix/__init__.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/fix/legacy_accents.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/fix/vertical_metrics.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/gsub.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/hhea.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/name.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/os_2.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/post.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/__init__.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/cli.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/font_info.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/font_names.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/vf_instances.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/ttf.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/utils/__init__.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/utils/font_organizer.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/utils/__init__.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/utils/logger.py +0 -0
- {foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/utils/timer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: foundrytools-cli
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.1
|
|
4
4
|
Summary: A set of command line tools to inspect, manipulate and convert font files
|
|
5
5
|
Author: Cesare Gilento
|
|
6
6
|
Author-email: Cesare Gilento <ftcli@proton.me>
|
|
@@ -11,23 +11,25 @@ Classifier: Intended Audience :: End Users/Desktop
|
|
|
11
11
|
Classifier: Natural Language :: English
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.11
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
16
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
-
Classifier:
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
20
19
|
Classifier: Topic :: Text Processing :: Fonts
|
|
21
|
-
Requires-Dist: afdko
|
|
22
|
-
Requires-Dist: click>=8.
|
|
23
|
-
Requires-Dist: foundrytools>=0.1.
|
|
20
|
+
Requires-Dist: afdko==4.0.3
|
|
21
|
+
Requires-Dist: click>=8.5.0
|
|
22
|
+
Requires-Dist: foundrytools>=0.1.8
|
|
24
23
|
Requires-Dist: loguru>=0.7.3
|
|
25
24
|
Requires-Dist: pathvalidate>=3.3.1
|
|
26
|
-
Requires-Dist: rich>=
|
|
27
|
-
Requires-Dist: ufolib2>=0.
|
|
28
|
-
Requires-Dist: win32-setctime>=1.2.0 ; sys_platform
|
|
29
|
-
Requires-
|
|
25
|
+
Requires-Dist: rich>=15.0.0
|
|
26
|
+
Requires-Dist: ufolib2>=0.19.0
|
|
27
|
+
Requires-Dist: win32-setctime>=1.2.0 ; sys_platform == 'win32'
|
|
28
|
+
Requires-Dist: sphinx-click>=6.2.0 ; extra == 'docs'
|
|
29
|
+
Requires-Dist: sphinx-rtd-theme>=3.0.2 ; extra == 'docs'
|
|
30
|
+
Requires-Python: >=3.11
|
|
30
31
|
Project-URL: Homepage, https://github.com/ftCLI/FoundryTools-CLI
|
|
32
|
+
Provides-Extra: docs
|
|
31
33
|
Description-Content-Type: text/markdown
|
|
32
34
|
|
|
33
35
|
# FoundryTools-CLI
|
|
@@ -54,10 +56,7 @@ rendered by [rich](https://github.com/Textualize/rich).
|
|
|
54
56
|
|
|
55
57
|
## Installation
|
|
56
58
|
|
|
57
|
-
FoundryTools-CLI requires Python 3.
|
|
58
|
-
|
|
59
|
-
**IMPORTANT**: If you have Python 2.x installed in your system, you may have to use `python3`
|
|
60
|
-
(instead of `python`) in the commands below.
|
|
59
|
+
FoundryTools-CLI requires Python 3.11 or later.
|
|
61
60
|
|
|
62
61
|
### pip
|
|
63
62
|
|
|
@@ -71,25 +70,20 @@ python -m pip install foundrytools-cli
|
|
|
71
70
|
### Editable mode
|
|
72
71
|
|
|
73
72
|
If you would like to contribute to the development, you can clone the repository from GitHub,
|
|
74
|
-
install the package in 'editable' mode and modify the source code in place.
|
|
75
|
-
|
|
73
|
+
install the package in 'editable' mode and modify the source code in place. Install
|
|
74
|
+
[uv](https://docs.astral.sh/uv/getting-started/installation/) first to create the project
|
|
75
|
+
environment.
|
|
76
76
|
|
|
77
77
|
```
|
|
78
78
|
# clone the repository:
|
|
79
79
|
git clone https://github.com/ftCLI/foundrytools-cli.git
|
|
80
80
|
cd foundrytools-cli
|
|
81
81
|
|
|
82
|
-
#
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
# to activate the virtual environmtnet in macOS and Linux, do:
|
|
86
|
-
. ftcli-venv/bin/activate
|
|
87
|
-
|
|
88
|
-
# to activate the virtual environment in Windows, do:
|
|
89
|
-
ftcli-venv\Scripts\activate.bat
|
|
82
|
+
# install the project and development tools in a managed environment:
|
|
83
|
+
uv sync --locked --group dev
|
|
90
84
|
|
|
91
|
-
#
|
|
92
|
-
|
|
85
|
+
# run the CLI:
|
|
86
|
+
uv run ftcli --help
|
|
93
87
|
```
|
|
94
88
|
|
|
95
89
|
## Documentation
|
|
@@ -22,10 +22,7 @@ rendered by [rich](https://github.com/Textualize/rich).
|
|
|
22
22
|
|
|
23
23
|
## Installation
|
|
24
24
|
|
|
25
|
-
FoundryTools-CLI requires Python 3.
|
|
26
|
-
|
|
27
|
-
**IMPORTANT**: If you have Python 2.x installed in your system, you may have to use `python3`
|
|
28
|
-
(instead of `python`) in the commands below.
|
|
25
|
+
FoundryTools-CLI requires Python 3.11 or later.
|
|
29
26
|
|
|
30
27
|
### pip
|
|
31
28
|
|
|
@@ -39,25 +36,20 @@ python -m pip install foundrytools-cli
|
|
|
39
36
|
### Editable mode
|
|
40
37
|
|
|
41
38
|
If you would like to contribute to the development, you can clone the repository from GitHub,
|
|
42
|
-
install the package in 'editable' mode and modify the source code in place.
|
|
43
|
-
|
|
39
|
+
install the package in 'editable' mode and modify the source code in place. Install
|
|
40
|
+
[uv](https://docs.astral.sh/uv/getting-started/installation/) first to create the project
|
|
41
|
+
environment.
|
|
44
42
|
|
|
45
43
|
```
|
|
46
44
|
# clone the repository:
|
|
47
45
|
git clone https://github.com/ftCLI/foundrytools-cli.git
|
|
48
46
|
cd foundrytools-cli
|
|
49
47
|
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# to activate the virtual environmtnet in macOS and Linux, do:
|
|
54
|
-
. ftcli-venv/bin/activate
|
|
55
|
-
|
|
56
|
-
# to activate the virtual environment in Windows, do:
|
|
57
|
-
ftcli-venv\Scripts\activate.bat
|
|
48
|
+
# install the project and development tools in a managed environment:
|
|
49
|
+
uv sync --locked --group dev
|
|
58
50
|
|
|
59
|
-
#
|
|
60
|
-
|
|
51
|
+
# run the CLI:
|
|
52
|
+
uv run ftcli --help
|
|
61
53
|
```
|
|
62
54
|
|
|
63
55
|
## Documentation
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.13.1,<0.14"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "foundrytools-cli"
|
|
7
|
+
version = "2.2.1"
|
|
8
|
+
description = "A set of command line tools to inspect, manipulate and convert font files"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
dependencies = [
|
|
13
|
+
"afdko==4.0.3",
|
|
14
|
+
"click>=8.5.0",
|
|
15
|
+
"foundrytools>=0.1.8",
|
|
16
|
+
"loguru>=0.7.3",
|
|
17
|
+
"pathvalidate>=3.3.1",
|
|
18
|
+
"rich>=15.0.0",
|
|
19
|
+
"ufolib2>=0.19.0",
|
|
20
|
+
"win32-setctime>=1.2.0; sys_platform == 'win32'",
|
|
21
|
+
]
|
|
22
|
+
classifiers = [
|
|
23
|
+
"Development Status :: 5 - Production/Stable",
|
|
24
|
+
"Intended Audience :: Developers",
|
|
25
|
+
"Intended Audience :: End Users/Desktop",
|
|
26
|
+
"Natural Language :: English",
|
|
27
|
+
"Operating System :: OS Independent",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.11",
|
|
30
|
+
"Programming Language :: Python :: 3.12",
|
|
31
|
+
"Programming Language :: Python :: 3.13",
|
|
32
|
+
"Programming Language :: Python :: 3.14",
|
|
33
|
+
"Programming Language :: Python :: 3.15",
|
|
34
|
+
"Topic :: Text Processing :: Fonts",
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
[[project.authors]]
|
|
38
|
+
name = "Cesare Gilento"
|
|
39
|
+
email = "ftcli@proton.me"
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
docs = [
|
|
43
|
+
"sphinx-click>=6.2.0",
|
|
44
|
+
"sphinx-rtd-theme>=3.0.2",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
[project.scripts]
|
|
48
|
+
ftcli = "foundrytools_cli.__main__:cli"
|
|
49
|
+
|
|
50
|
+
[project.urls]
|
|
51
|
+
Homepage = "https://github.com/ftCLI/FoundryTools-CLI"
|
|
52
|
+
|
|
53
|
+
[dependency-groups]
|
|
54
|
+
dev = [
|
|
55
|
+
"bump-my-version>=1.6.0",
|
|
56
|
+
"mypy>=2.4.0",
|
|
57
|
+
"pre-commit>=4.6.2",
|
|
58
|
+
"ruff>=0.11.0",
|
|
59
|
+
]
|
|
60
|
+
security = [
|
|
61
|
+
"bandit>=1.8.6",
|
|
62
|
+
"pip-audit>=2.9.0",
|
|
63
|
+
]
|
|
64
|
+
|
|
65
|
+
[tool.uv.build-backend]
|
|
66
|
+
module-name = "foundrytools_cli"
|
|
67
|
+
module-root = "src"
|
|
68
|
+
|
|
69
|
+
[tool.mypy]
|
|
70
|
+
warn_unused_configs = true
|
|
71
|
+
disallow_untyped_defs = true
|
|
72
|
+
|
|
73
|
+
[[tool.mypy.overrides]]
|
|
74
|
+
module = [
|
|
75
|
+
"afdko.*",
|
|
76
|
+
"fontTools.*",
|
|
77
|
+
"win32_setctime.*",
|
|
78
|
+
]
|
|
79
|
+
ignore_missing_imports = true
|
|
80
|
+
|
|
81
|
+
[tool.ruff]
|
|
82
|
+
line-length = 100
|
|
83
|
+
indent-width = 4
|
|
84
|
+
target-version = "py311"
|
|
85
|
+
|
|
86
|
+
[tool.ruff.lint]
|
|
87
|
+
select = [
|
|
88
|
+
"C",
|
|
89
|
+
"E",
|
|
90
|
+
"F",
|
|
91
|
+
"UP",
|
|
92
|
+
"B",
|
|
93
|
+
"SIM",
|
|
94
|
+
"I",
|
|
95
|
+
]
|
|
96
|
+
ignore = []
|
|
97
|
+
fixable = ["ALL"]
|
|
98
|
+
unfixable = []
|
|
99
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
100
|
+
|
|
101
|
+
[tool.ruff.format]
|
|
102
|
+
quote-style = "double"
|
|
103
|
+
indent-style = "space"
|
|
104
|
+
skip-magic-trailing-comma = false
|
|
105
|
+
line-ending = "auto"
|
|
106
|
+
docstring-code-format = true
|
|
107
|
+
docstring-code-line-length = "dynamic"
|
|
108
|
+
|
|
109
|
+
[tool.bumpversion]
|
|
110
|
+
current_version = "2.2.1"
|
|
111
|
+
commit = true
|
|
112
|
+
tag = true
|
|
113
|
+
|
|
114
|
+
[[tool.bumpversion.files]]
|
|
115
|
+
filename = "src/foundrytools_cli/__init__.py"
|
|
116
|
+
search = '__version__ = "{current_version}"'
|
|
117
|
+
replace = '__version__ = "{new_version}"'
|
|
118
|
+
|
|
119
|
+
[[tool.bumpversion.files]]
|
|
120
|
+
filename = "docs/source/conf.py"
|
|
121
|
+
search = 'release = "{current_version}"'
|
|
122
|
+
replace = 'release = "{new_version}"'
|
|
123
|
+
|
|
124
|
+
[[tool.bumpversion.files]]
|
|
125
|
+
filename = "pyproject.toml"
|
|
126
|
+
search = """
|
|
127
|
+
name = "foundrytools-cli"
|
|
128
|
+
version = "{current_version}""""
|
|
129
|
+
replace = """
|
|
130
|
+
name = "foundrytools-cli"
|
|
131
|
+
version = "{new_version}""""
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["uv_build>=0.13.1,<0.14"]
|
|
3
|
+
build-backend = "uv_build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "foundrytools-cli"
|
|
7
|
+
version = "2.2.1"
|
|
8
|
+
description = "A set of command line tools to inspect, manipulate and convert font files"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [{ name = "Cesare Gilento", email = "ftcli@proton.me" }]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"afdko==4.0.3",
|
|
15
|
+
"click>=8.5.0",
|
|
16
|
+
"foundrytools>=0.1.8",
|
|
17
|
+
"loguru>=0.7.3",
|
|
18
|
+
"pathvalidate>=3.3.1",
|
|
19
|
+
"rich>=15.0.0",
|
|
20
|
+
"ufolib2>=0.19.0",
|
|
21
|
+
"win32-setctime>=1.2.0; sys_platform == 'win32'",
|
|
22
|
+
]
|
|
23
|
+
classifiers = [
|
|
24
|
+
"Development Status :: 5 - Production/Stable",
|
|
25
|
+
"Intended Audience :: Developers",
|
|
26
|
+
"Intended Audience :: End Users/Desktop",
|
|
27
|
+
"Natural Language :: English",
|
|
28
|
+
"Operating System :: OS Independent",
|
|
29
|
+
"Programming Language :: Python :: 3",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Programming Language :: Python :: 3.13",
|
|
33
|
+
"Programming Language :: Python :: 3.14",
|
|
34
|
+
"Programming Language :: Python :: 3.15",
|
|
35
|
+
"Topic :: Text Processing :: Fonts",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"bump-my-version>=1.6.0",
|
|
41
|
+
"mypy>=2.4.0",
|
|
42
|
+
"pre-commit>=4.6.2",
|
|
43
|
+
"ruff>=0.11.0",
|
|
44
|
+
]
|
|
45
|
+
security = [
|
|
46
|
+
"bandit>=1.8.6",
|
|
47
|
+
"pip-audit>=2.9.0",
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
[project.optional-dependencies]
|
|
51
|
+
docs = [
|
|
52
|
+
"sphinx-click>=6.2.0",
|
|
53
|
+
"sphinx-rtd-theme>=3.0.2",
|
|
54
|
+
]
|
|
55
|
+
|
|
56
|
+
[project.scripts]
|
|
57
|
+
ftcli = "foundrytools_cli.__main__:cli"
|
|
58
|
+
|
|
59
|
+
[project.urls]
|
|
60
|
+
Homepage = "https://github.com/ftCLI/FoundryTools-CLI"
|
|
61
|
+
|
|
62
|
+
[tool.uv.build-backend]
|
|
63
|
+
module-name = "foundrytools_cli"
|
|
64
|
+
module-root = "src"
|
|
65
|
+
|
|
66
|
+
[tool.mypy]
|
|
67
|
+
warn_unused_configs = true
|
|
68
|
+
disallow_untyped_defs = true
|
|
69
|
+
|
|
70
|
+
[[tool.mypy.overrides]]
|
|
71
|
+
module = ["afdko.*", "fontTools.*", "win32_setctime.*"]
|
|
72
|
+
ignore_missing_imports = true
|
|
73
|
+
|
|
74
|
+
[tool.ruff]
|
|
75
|
+
line-length = 100
|
|
76
|
+
indent-width = 4
|
|
77
|
+
target-version = "py311"
|
|
78
|
+
|
|
79
|
+
[tool.ruff.lint]
|
|
80
|
+
select = ["C", "E", "F", "UP", "B", "SIM", "I"]
|
|
81
|
+
ignore = []
|
|
82
|
+
fixable = ["ALL"]
|
|
83
|
+
unfixable = []
|
|
84
|
+
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
|
85
|
+
|
|
86
|
+
[tool.ruff.format]
|
|
87
|
+
quote-style = "double"
|
|
88
|
+
indent-style = "space"
|
|
89
|
+
skip-magic-trailing-comma = false
|
|
90
|
+
line-ending = "auto"
|
|
91
|
+
docstring-code-format = true
|
|
92
|
+
docstring-code-line-length = "dynamic"
|
|
93
|
+
|
|
94
|
+
[tool.bumpversion]
|
|
95
|
+
current_version = "2.2.1"
|
|
96
|
+
commit = true
|
|
97
|
+
tag = true
|
|
98
|
+
|
|
99
|
+
[[tool.bumpversion.files]]
|
|
100
|
+
filename = "src/foundrytools_cli/__init__.py"
|
|
101
|
+
search = '__version__ = "{current_version}"'
|
|
102
|
+
replace = '__version__ = "{new_version}"'
|
|
103
|
+
|
|
104
|
+
[[tool.bumpversion.files]]
|
|
105
|
+
filename = "docs/source/conf.py"
|
|
106
|
+
search = 'release = "{current_version}"'
|
|
107
|
+
replace = 'release = "{new_version}"'
|
|
108
|
+
|
|
109
|
+
[[tool.bumpversion.files]]
|
|
110
|
+
filename = "pyproject.toml"
|
|
111
|
+
search = "name = \"foundrytools-cli\"\nversion = \"{current_version}\""
|
|
112
|
+
replace = "name = \"foundrytools-cli\"\nversion = \"{new_version}\""
|
|
@@ -11,6 +11,46 @@ from foundrytools_cli.utils.task_runner import TaskRunner
|
|
|
11
11
|
cli = click.Group(help="Font level utilities.")
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
@cli.command("add-extremes", cls=BaseCommand)
|
|
15
|
+
@click.option(
|
|
16
|
+
"--keep-hinting",
|
|
17
|
+
is_flag=True,
|
|
18
|
+
help="Preserve hinting when adding extrema points.",
|
|
19
|
+
)
|
|
20
|
+
@click.option(
|
|
21
|
+
"--tolerance",
|
|
22
|
+
type=click.FloatRange(min=0),
|
|
23
|
+
default=1.0,
|
|
24
|
+
show_default=True,
|
|
25
|
+
help="Do not add extrema points within this distance (font units) of existing points.",
|
|
26
|
+
)
|
|
27
|
+
def add_extremes(input_path: Path, **options: dict[str, Any]) -> None:
|
|
28
|
+
"""
|
|
29
|
+
Add points at the horizontal and vertical extrema of glyph curves.
|
|
30
|
+
|
|
31
|
+
Composite glyphs in TrueType fonts and variable fonts are not modified.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
def task(font: Font, keep_hinting: bool = False, tolerance: float = 1.0) -> bool:
|
|
35
|
+
modified_glyphs = font.add_extremes(
|
|
36
|
+
remove_hinting=not keep_hinting,
|
|
37
|
+
tolerance=tolerance,
|
|
38
|
+
)
|
|
39
|
+
if not modified_glyphs:
|
|
40
|
+
logger.info("No glyphs were modified")
|
|
41
|
+
return False
|
|
42
|
+
|
|
43
|
+
logger.opt(colors=True).info(
|
|
44
|
+
f"{len(modified_glyphs)} glyphs were modified: "
|
|
45
|
+
f"<lc>{', '.join(sorted(modified_glyphs))}</lc>"
|
|
46
|
+
)
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
runner = TaskRunner(input_path=input_path, task=task, **options)
|
|
50
|
+
runner.filter.filter_out_variable = True
|
|
51
|
+
runner.run()
|
|
52
|
+
|
|
53
|
+
|
|
14
54
|
@cli.command("correct-contours", cls=BaseCommand)
|
|
15
55
|
@click.option(
|
|
16
56
|
"-ma",
|
|
@@ -258,12 +258,53 @@ def round_coordinates(input_path: Path, **options: dict[str, Any]) -> None:
|
|
|
258
258
|
The number of vertical stem values to extract.
|
|
259
259
|
""",
|
|
260
260
|
)
|
|
261
|
+
@click.option(
|
|
262
|
+
"--use-samples/--all-glyphs",
|
|
263
|
+
default=True,
|
|
264
|
+
show_default=True,
|
|
265
|
+
help="Calculate each value from its default or custom glyph sample, or from the whole font.",
|
|
266
|
+
)
|
|
267
|
+
@click.option(
|
|
268
|
+
"--std-h-sample",
|
|
269
|
+
multiple=True,
|
|
270
|
+
help="Characters to sample for StdHW; may be repeated. Defaults to the built-in sample.",
|
|
271
|
+
)
|
|
272
|
+
@click.option(
|
|
273
|
+
"--std-v-sample",
|
|
274
|
+
multiple=True,
|
|
275
|
+
help="Characters to sample for StdVW; may be repeated. Defaults to the built-in sample.",
|
|
276
|
+
)
|
|
277
|
+
@click.option(
|
|
278
|
+
"--snap-h-sample",
|
|
279
|
+
multiple=True,
|
|
280
|
+
help="Characters to sample for StemSnapH; may be repeated. Defaults to the built-in sample.",
|
|
281
|
+
)
|
|
282
|
+
@click.option(
|
|
283
|
+
"--snap-v-sample",
|
|
284
|
+
multiple=True,
|
|
285
|
+
help="Characters to sample for StemSnapV; may be repeated. Defaults to the built-in sample.",
|
|
286
|
+
)
|
|
261
287
|
def recalc_stems(input_path: Path, **options: dict[str, Any]) -> None:
|
|
262
288
|
"""
|
|
263
289
|
Recalculate the hinting stems of OpenType-PS fonts.
|
|
264
290
|
"""
|
|
265
291
|
|
|
266
|
-
|
|
292
|
+
sample_options = ("std_h_sample", "std_v_sample", "snap_h_sample", "snap_v_sample")
|
|
293
|
+
if not options["use_samples"] and any(options[name] for name in sample_options):
|
|
294
|
+
raise click.UsageError("Custom glyph samples cannot be used with --all-glyphs.")
|
|
295
|
+
|
|
296
|
+
def task(
|
|
297
|
+
font: Font,
|
|
298
|
+
report_all_stems: bool = False,
|
|
299
|
+
max_distance: int = 1,
|
|
300
|
+
max_h_stems: int = 2,
|
|
301
|
+
max_v_stems: int = 2,
|
|
302
|
+
use_samples: bool = True,
|
|
303
|
+
std_h_sample: tuple[str, ...] = (),
|
|
304
|
+
std_v_sample: tuple[str, ...] = (),
|
|
305
|
+
snap_h_sample: tuple[str, ...] = (),
|
|
306
|
+
snap_v_sample: tuple[str, ...] = (),
|
|
307
|
+
) -> bool:
|
|
267
308
|
if not font.is_ps:
|
|
268
309
|
logger.error("Font is not a PostScript font")
|
|
269
310
|
return False
|
|
@@ -273,11 +314,17 @@ def recalc_stems(input_path: Path, **options: dict[str, Any]) -> None:
|
|
|
273
314
|
return False
|
|
274
315
|
|
|
275
316
|
flavor = font.ttfont.flavor
|
|
276
|
-
temp_file =
|
|
317
|
+
temp_file: Path | None = None
|
|
277
318
|
if flavor is not None:
|
|
278
319
|
font.ttfont.flavor = None
|
|
279
320
|
temp_file = get_temp_file_path()
|
|
280
|
-
|
|
321
|
+
try:
|
|
322
|
+
font.save(temp_file)
|
|
323
|
+
except Exception:
|
|
324
|
+
temp_file.unlink(missing_ok=True)
|
|
325
|
+
raise
|
|
326
|
+
finally:
|
|
327
|
+
font.ttfont.flavor = flavor
|
|
281
328
|
input_file = temp_file
|
|
282
329
|
else:
|
|
283
330
|
input_file = font.file
|
|
@@ -289,22 +336,31 @@ def recalc_stems(input_path: Path, **options: dict[str, Any]) -> None:
|
|
|
289
336
|
current_stem_snap_h = font.t_cff_.get_hinting_data().get("StemSnapH", None)
|
|
290
337
|
current_stem_snap_v = font.t_cff_.get_hinting_data().get("StemSnapV", None)
|
|
291
338
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
339
|
+
def to_codepoints(sample: tuple[str, ...]) -> set[int] | None:
|
|
340
|
+
codepoints = {ord(char) for text in sample for char in text}
|
|
341
|
+
return codepoints or None
|
|
342
|
+
|
|
343
|
+
try:
|
|
344
|
+
std_h_w, std_v_w, stem_snap_h, stem_snap_v = get_stems(
|
|
345
|
+
input_file,
|
|
346
|
+
report_all_stems=report_all_stems,
|
|
347
|
+
max_distance=max_distance,
|
|
348
|
+
max_h_stems=max_h_stems,
|
|
349
|
+
max_v_stems=max_v_stems,
|
|
350
|
+
use_samples=use_samples,
|
|
351
|
+
std_h_codepoints=to_codepoints(std_h_sample),
|
|
352
|
+
std_v_codepoints=to_codepoints(std_v_sample),
|
|
353
|
+
snap_h_codepoints=to_codepoints(snap_h_sample),
|
|
354
|
+
snap_v_codepoints=to_codepoints(snap_v_sample),
|
|
355
|
+
)
|
|
356
|
+
finally:
|
|
357
|
+
if temp_file is not None:
|
|
358
|
+
temp_file.unlink(missing_ok=True)
|
|
359
|
+
|
|
303
360
|
logger.info(f"StdHW: {current_std_h_w} -> {std_h_w}")
|
|
304
361
|
logger.info(f"StdVW: {current_std_v_w} -> {std_v_w}")
|
|
305
362
|
logger.info(f"StemSnapH: {current_stem_snap_h} -> {stem_snap_h}")
|
|
306
363
|
logger.info(f"StemSnapV: {current_stem_snap_v} -> {stem_snap_v}")
|
|
307
|
-
temp_file.unlink(missing_ok=True)
|
|
308
364
|
|
|
309
365
|
if (current_std_h_w, current_std_v_w, current_stem_snap_h, current_stem_snap_v) == (
|
|
310
366
|
std_h_w,
|
|
@@ -321,7 +377,6 @@ def recalc_stems(input_path: Path, **options: dict[str, Any]) -> None:
|
|
|
321
377
|
"StemSnapV": stem_snap_v,
|
|
322
378
|
}
|
|
323
379
|
font.t_cff_.set_hinting_data(**hinting_data)
|
|
324
|
-
font.ttfont.flavor = flavor
|
|
325
380
|
return True
|
|
326
381
|
|
|
327
382
|
runner = TaskRunner(input_path=input_path, task=task, **options)
|
|
@@ -150,6 +150,6 @@ def main(font: Font, source: int = 1) -> None:
|
|
|
150
150
|
logger.opt(colors=True).info(
|
|
151
151
|
f"<light-black>{old_file.name}</> --> <bold><magenta>{new_file.name}</></>"
|
|
152
152
|
)
|
|
153
|
-
except Exception as e:
|
|
153
|
+
except Exception as e:
|
|
154
154
|
logger.error(f"Error renaming {old_file.name}: {e}")
|
|
155
155
|
return
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# pylint: disable=import-outside-toplevel
|
|
2
1
|
import os
|
|
3
2
|
import platform
|
|
4
3
|
from pathlib import Path
|
|
@@ -19,7 +18,7 @@ if platform.system() == "Windows":
|
|
|
19
18
|
from win32_setctime import setctime
|
|
20
19
|
|
|
21
20
|
SETCTIME = setctime
|
|
22
|
-
except (ImportError, Exception) as exc:
|
|
21
|
+
except (ImportError, Exception) as exc:
|
|
23
22
|
SETCTIME = None
|
|
24
23
|
IMPORT_ERROR = exc
|
|
25
24
|
|
|
@@ -98,7 +97,7 @@ def _set_windows_ctime(path: Path, timestamp: int) -> None:
|
|
|
98
97
|
try:
|
|
99
98
|
SETCTIME(path, timestamp + epoch_diff)
|
|
100
99
|
logger.info(f"created timestamp : {timestampToString(timestamp)}")
|
|
101
|
-
except Exception as e:
|
|
100
|
+
except Exception as e:
|
|
102
101
|
logger.error(f"Error setting file creation time: {e}")
|
|
103
102
|
|
|
104
103
|
|
|
@@ -107,7 +106,7 @@ def _set_mtime_and_atime(path: Path, timestamp: int) -> None:
|
|
|
107
106
|
os.utime(path, (timestamp + epoch_diff, timestamp + epoch_diff))
|
|
108
107
|
logger.info(f"modified timestamp : {timestampToString(timestamp)}")
|
|
109
108
|
logger.info(f"access timestamp : {timestampToString(timestamp)}")
|
|
110
|
-
except Exception as e:
|
|
109
|
+
except Exception as e:
|
|
111
110
|
logger.error(f"Error setting file timestamps: {e}")
|
|
112
111
|
|
|
113
112
|
|
|
@@ -35,7 +35,7 @@ class SaveOptions:
|
|
|
35
35
|
overwrite: bool = False
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
class TaskRunnerConfig:
|
|
38
|
+
class TaskRunnerConfig:
|
|
39
39
|
"""
|
|
40
40
|
Handle options for TaskRunner.
|
|
41
41
|
"""
|
|
@@ -85,7 +85,7 @@ class TaskRunnerConfig: # pylint: disable=too-few-public-methods
|
|
|
85
85
|
setattr(options_group, key, value)
|
|
86
86
|
|
|
87
87
|
|
|
88
|
-
class TaskRunner:
|
|
88
|
+
class TaskRunner:
|
|
89
89
|
"""
|
|
90
90
|
A class for running tasks on multiple fonts.
|
|
91
91
|
|
|
@@ -162,7 +162,7 @@ class TaskRunner: # pylint: disable=too-few-public-methods
|
|
|
162
162
|
def _execute_task(self, font: Font) -> bool:
|
|
163
163
|
try:
|
|
164
164
|
return bool(self.task(font, **self.config.task_options))
|
|
165
|
-
except Exception as e:
|
|
165
|
+
except Exception as e:
|
|
166
166
|
self._log_error(e)
|
|
167
167
|
return False
|
|
168
168
|
|
|
@@ -181,7 +181,7 @@ class TaskRunner: # pylint: disable=too-few-public-methods
|
|
|
181
181
|
out_file = self._get_out_file_name(font)
|
|
182
182
|
font.save(out_file, reorder_tables=self.config.save_options.reorder_tables)
|
|
183
183
|
logger.success(f"File saved to {out_file}")
|
|
184
|
-
except Exception as e:
|
|
184
|
+
except Exception as e:
|
|
185
185
|
self._log_error(e)
|
|
186
186
|
|
|
187
187
|
def _get_out_file_name(self, font: Font) -> Path:
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["uv_build>=0.9.17"]
|
|
3
|
-
build-backend = "uv_build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "foundrytools-cli"
|
|
7
|
-
version = "2.1.1"
|
|
8
|
-
description = "A set of command line tools to inspect, manipulate and convert font files"
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
license = "MIT"
|
|
11
|
-
requires-python = ">=3.10"
|
|
12
|
-
authors = [
|
|
13
|
-
{ name = "Cesare Gilento", email = "ftcli@proton.me" },
|
|
14
|
-
]
|
|
15
|
-
|
|
16
|
-
classifiers = [
|
|
17
|
-
"Development Status :: 5 - Production/Stable",
|
|
18
|
-
"Intended Audience :: Developers",
|
|
19
|
-
"Intended Audience :: End Users/Desktop",
|
|
20
|
-
"Natural Language :: English",
|
|
21
|
-
"Operating System :: OS Independent",
|
|
22
|
-
"Programming Language :: Python :: 3",
|
|
23
|
-
"Programming Language :: Python :: 3.10",
|
|
24
|
-
"Programming Language :: Python :: 3.11",
|
|
25
|
-
"Programming Language :: Python :: 3.12",
|
|
26
|
-
"Programming Language :: Python :: 3.13",
|
|
27
|
-
"Programming Language :: Python :: 3.14",
|
|
28
|
-
"License :: OSI Approved :: MIT License",
|
|
29
|
-
"Topic :: Text Processing :: Fonts",
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
dependencies = [
|
|
33
|
-
"afdko>=4.0.3",
|
|
34
|
-
"click>=8.3.1",
|
|
35
|
-
"foundrytools>=0.1.6",
|
|
36
|
-
"loguru>=0.7.3",
|
|
37
|
-
"pathvalidate>=3.3.1",
|
|
38
|
-
"rich>=14.3.1",
|
|
39
|
-
"ufolib2>=0.18.1",
|
|
40
|
-
"win32-setctime>=1.2.0; sys_platform >= 'win32'",
|
|
41
|
-
]
|
|
42
|
-
|
|
43
|
-
[dependency-groups]
|
|
44
|
-
dev = [
|
|
45
|
-
"bump-my-version>=1.2.6",
|
|
46
|
-
"mypy>=1.19.1",
|
|
47
|
-
"pre-commit>=4.5.1",
|
|
48
|
-
"pylint>=4.0.4",
|
|
49
|
-
]
|
|
50
|
-
docs = [
|
|
51
|
-
"sphinx-click>=6.2.0",
|
|
52
|
-
"sphinx-rtd-theme>=3.1.0",
|
|
53
|
-
]
|
|
54
|
-
|
|
55
|
-
[project.scripts]
|
|
56
|
-
ftcli = "foundrytools_cli.__main__:cli"
|
|
57
|
-
|
|
58
|
-
[project.urls]
|
|
59
|
-
Homepage = "https://github.com/ftCLI/FoundryTools-CLI"
|
|
60
|
-
|
|
61
|
-
[tool.bumpversion]
|
|
62
|
-
current_version = "2.1.1"
|
|
63
|
-
commit = false
|
|
64
|
-
tag = false
|
|
65
|
-
|
|
66
|
-
[[tool.bumpversion.files]]
|
|
67
|
-
filename = "src/foundrytools_cli/__init__.py"
|
|
68
|
-
search = '__version__ = "{current_version}"'
|
|
69
|
-
replace = '__version__ = "{new_version}"'
|
|
70
|
-
|
|
71
|
-
[[tool.bumpversion.files]]
|
|
72
|
-
filename = "docs/source/conf.py"
|
|
73
|
-
search = 'release = "{current_version}"'
|
|
74
|
-
replace = 'release = "{new_version}"'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/converter/cli.py
RENAMED
|
File without changes
|
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/fix/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/__init__.py
RENAMED
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/cli.py
RENAMED
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/font_info.py
RENAMED
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/print/font_names.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{foundrytools_cli-2.1.1 → foundrytools_cli-2.2.1}/src/foundrytools_cli/commands/utils/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|