foundrytools-cli 1.1.22__tar.gz → 2.0.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.0.1/.gitignore +161 -0
- foundrytools_cli-2.0.1/PKG-INFO +115 -0
- foundrytools_cli-2.0.1/README.md +75 -0
- foundrytools_cli-2.0.1/pyproject.toml +86 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/__init__.py +3 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/__main__.py +40 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/cff.py +124 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/cmap.py +39 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/converter/__init__.py +3 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/converter/cli.py +404 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/converter/ttf_to_otf.py +189 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/fix/__init__.py +3 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/fix/cli.py +466 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/fix/legacy_accents.py +60 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/fix/vertical_metrics.py +22 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/font.py +276 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/gsub.py +50 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/hhea.py +75 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/name.py +386 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/os_2.py +638 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/otf.py +353 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/post.py +71 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/print/__init__.py +3 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/print/cli.py +49 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/print/font_info.py +201 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/print/font_names.py +147 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/ttf.py +72 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/utils/__init__.py +3 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/utils/cli.py +121 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/utils/font_organizer.py +118 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/utils/font_renamer.py +90 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/commands/utils/sync_timestamps.py +130 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/utils/__init__.py +245 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/utils/logger.py +21 -0
- foundrytools_cli-2.0.1/src/foundrytools_cli/utils/task_runner.py +199 -0
- {foundrytools_cli-1.1.22/foundryToolsCLI/Lib → foundrytools_cli-2.0.1/src/foundrytools_cli}/utils/timer.py +4 -2
- foundrytools_cli-1.1.22/MANIFEST.in +0 -2
- foundrytools_cli-1.1.22/PKG-INFO +0 -97
- foundrytools_cli-1.1.22/README.md +0 -72
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_assistant.py +0 -384
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_cff.py +0 -222
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_converter.py +0 -399
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_fix.py +0 -1087
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_hhea.py +0 -106
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_metrics.py +0 -281
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_name.py +0 -452
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_os2.py +0 -777
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_otf.py +0 -562
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_post.py +0 -117
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_print.py +0 -118
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_ttf.py +0 -399
- foundrytools_cli-1.1.22/foundryToolsCLI/CLI/ftcli_utils.py +0 -557
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/Font.py +0 -1159
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/VFont.py +0 -61
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/__init__.py +0 -0
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/assistant/UI.py +0 -591
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/assistant/__init__.py +0 -0
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/assistant/fonts_data.py +0 -647
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/assistant/styles_mapping.py +0 -78
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/constants.py +0 -650
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/__init__.py +0 -0
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/options.py +0 -48
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/otf_to_ttf.py +0 -128
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/sfnt_to_web.py +0 -70
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/ttc_to_sfnt.py +0 -39
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/ttf_to_otf.py +0 -235
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/variable_to_static.py +0 -74
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/converters/web_to_sfnt.py +0 -47
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/printer/UI.py +0 -366
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/printer/__init__.py +0 -0
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/CFF_.py +0 -99
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/OS_2.py +0 -422
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/__init__.py +0 -0
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/head.py +0 -42
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/hhea.py +0 -24
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/name.py +0 -192
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/tables/post.py +0 -18
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/__init__.py +0 -0
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/bits_tools.py +0 -39
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/cli_tools.py +0 -177
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/click_tools.py +0 -153
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/logger.py +0 -57
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/otf_tools.py +0 -59
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/ps_recalc_stems.py +0 -92
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/ps_recalc_zones.py +0 -246
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/skia_tools.py +0 -185
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/text_tools.py +0 -31
- foundrytools_cli-1.1.22/foundryToolsCLI/Lib/utils/ttf_tools.py +0 -134
- foundrytools_cli-1.1.22/foundryToolsCLI/__init__.py +0 -3
- foundrytools_cli-1.1.22/foundryToolsCLI/__main__.py +0 -35
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/PKG-INFO +0 -97
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/SOURCES.txt +0 -65
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/dependency_links.txt +0 -1
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/entry_points.txt +0 -2
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/not-zip-safe +0 -1
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/requires.txt +0 -12
- foundrytools_cli-1.1.22/foundrytools_cli.egg-info/top_level.txt +0 -2
- foundrytools_cli-1.1.22/requirements.txt +0 -13
- foundrytools_cli-1.1.22/setup.cfg +0 -4
- foundrytools_cli-1.1.22/setup.py +0 -38
- {foundrytools_cli-1.1.22 → foundrytools_cli-2.0.1}/LICENSE +0 -0
- {foundrytools_cli-1.1.22/foundryToolsCLI/CLI → foundrytools_cli-2.0.1/src/foundrytools_cli/commands}/__init__.py +0 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
foundryToolsCLI_2/lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
target/
|
|
77
|
+
|
|
78
|
+
# Jupyter Notebook
|
|
79
|
+
.ipynb_checkpoints
|
|
80
|
+
|
|
81
|
+
# IPython
|
|
82
|
+
profile_default/
|
|
83
|
+
ipython_config.py
|
|
84
|
+
|
|
85
|
+
# pyenv
|
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
88
|
+
# .python-version
|
|
89
|
+
|
|
90
|
+
# pipenv
|
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
94
|
+
# install all needed dependencies.
|
|
95
|
+
#Pipfile.lock
|
|
96
|
+
|
|
97
|
+
# poetry
|
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
100
|
+
# commonly ignored for libraries.
|
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
102
|
+
#poetry.lock
|
|
103
|
+
|
|
104
|
+
# pdm
|
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
106
|
+
#pdm.lock
|
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
108
|
+
# in version control.
|
|
109
|
+
# https://pdm.fming.dev/#use-with-ide
|
|
110
|
+
.pdm.toml
|
|
111
|
+
|
|
112
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
113
|
+
__pypackages__/
|
|
114
|
+
|
|
115
|
+
# Celery stuff
|
|
116
|
+
celerybeat-schedule
|
|
117
|
+
celerybeat.pid
|
|
118
|
+
|
|
119
|
+
# SageMath parsed files
|
|
120
|
+
*.sage.py
|
|
121
|
+
|
|
122
|
+
# Environments
|
|
123
|
+
.env
|
|
124
|
+
.venv
|
|
125
|
+
env/
|
|
126
|
+
venv/
|
|
127
|
+
ENV/
|
|
128
|
+
env.bak/
|
|
129
|
+
venv.bak/
|
|
130
|
+
|
|
131
|
+
# Spyder project settings
|
|
132
|
+
.spyderproject
|
|
133
|
+
.spyproject
|
|
134
|
+
|
|
135
|
+
# Rope project settings
|
|
136
|
+
.ropeproject
|
|
137
|
+
|
|
138
|
+
# mkdocs documentation
|
|
139
|
+
/site
|
|
140
|
+
|
|
141
|
+
# mypy
|
|
142
|
+
.mypy_cache/
|
|
143
|
+
.dmypy.json
|
|
144
|
+
dmypy.json
|
|
145
|
+
|
|
146
|
+
# Pyre type checker
|
|
147
|
+
.pyre/
|
|
148
|
+
|
|
149
|
+
# pytype static type analyzer
|
|
150
|
+
.pytype/
|
|
151
|
+
|
|
152
|
+
# Cython debug symbols
|
|
153
|
+
cython_debug/
|
|
154
|
+
|
|
155
|
+
# PyCharm
|
|
156
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
157
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
158
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
159
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
160
|
+
#.idea/
|
|
161
|
+
.qodo
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: foundrytools-cli
|
|
3
|
+
Version: 2.0.1
|
|
4
|
+
Summary: A set of command line tools to inspect, manipulate and convert font files
|
|
5
|
+
Project-URL: Homepage, https://github.com/ftCLI/FoundryTools-CLI
|
|
6
|
+
Author-email: Cesare Gilento <ftcli@proton.me>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Natural Language :: English
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Text Processing :: Fonts
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: afdko>=4.0.2
|
|
24
|
+
Requires-Dist: click>=8.1.8
|
|
25
|
+
Requires-Dist: foundrytools>=0.1.4
|
|
26
|
+
Requires-Dist: loguru>=0.7.3
|
|
27
|
+
Requires-Dist: pathvalidate>=3.2.3
|
|
28
|
+
Requires-Dist: rich>=14.0.0
|
|
29
|
+
Requires-Dist: win32-setctime>=1.2.0; sys_platform >= 'win32'
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: bump-my-version>=1.1.2; extra == 'dev'
|
|
32
|
+
Requires-Dist: hatch>=1.14.1; extra == 'dev'
|
|
33
|
+
Requires-Dist: mypy>=1.15.0; extra == 'dev'
|
|
34
|
+
Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pylint>=3.3.6; extra == 'dev'
|
|
36
|
+
Provides-Extra: docs
|
|
37
|
+
Requires-Dist: sphinx-click>=6.0.0; extra == 'docs'
|
|
38
|
+
Requires-Dist: sphinx-rtd-theme>=3.0.2; extra == 'docs'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# FoundryTools-CLI
|
|
42
|
+
|
|
43
|
+
FoundryTools-CLI is a command line interface for the
|
|
44
|
+
[FoundryTools](https://github.com/ftCLI/FoundryTools) library, which provides a set of tools for
|
|
45
|
+
working with font files. It is designed to be used from the command line, allowing users to perform
|
|
46
|
+
various operations on font files without the need for a graphical user interface.
|
|
47
|
+
|
|
48
|
+
The CLI provides a range of commands for manipulating font files, including converting between
|
|
49
|
+
different font formats, extracting and modifying font metadata, and performing various font-related
|
|
50
|
+
operations. It is built on top of the FoundryTools library, which provides a comprehensive set of
|
|
51
|
+
tools for working with font files in Python.
|
|
52
|
+
|
|
53
|
+
The CLI is designed to be easy to use and provides a consistent interface for working with different
|
|
54
|
+
font formats. It is suitable for both developers and font designers who need to perform various
|
|
55
|
+
operations on font files from the command line. The CLI is also extensible, allowing users to add
|
|
56
|
+
their own commands and functionality as needed.
|
|
57
|
+
|
|
58
|
+

|
|
59
|
+
|
|
60
|
+
The command line interface is built with [click](https://github.com/pallets/click/) and tables are
|
|
61
|
+
rendered by [rich](https://github.com/Textualize/rich).
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
FoundryTools-CLI requires Python 3.9 or later.
|
|
66
|
+
|
|
67
|
+
**IMPORTANT**: If you have Python 2.x installed in your system, you may have to use `python3`
|
|
68
|
+
(instead of `python`) in the commands below.
|
|
69
|
+
|
|
70
|
+
### pip
|
|
71
|
+
|
|
72
|
+
FoundryTools-CLI releases are available on the Python Package Index (PyPI), so it can be installed
|
|
73
|
+
with [pip](https://pip.pypa.io/):
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
python -m pip install foundrytools-cli
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### Editable mode
|
|
80
|
+
|
|
81
|
+
If you would like to contribute to the development, you can clone the repository from GitHub,
|
|
82
|
+
install the package in 'editable' mode and modify the source code in place. We strongly recommend
|
|
83
|
+
using a virtual environment.
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
# clone the repository:
|
|
87
|
+
git clone https://github.com/ftCLI/foundrytools-cli.git
|
|
88
|
+
cd foundrytools-cli
|
|
89
|
+
|
|
90
|
+
# create new virtual environment named e.g. ftcli-venv, or whatever you prefer:
|
|
91
|
+
python -m venv ftcli-venv
|
|
92
|
+
|
|
93
|
+
# to activate the virtual environmtnet in macOS and Linux, do:
|
|
94
|
+
. ftcli-venv/bin/activate
|
|
95
|
+
|
|
96
|
+
# to activate the virtual environment in Windows, do:
|
|
97
|
+
ftcli-venv\Scripts\activate.bat
|
|
98
|
+
|
|
99
|
+
# install in 'editable' mode
|
|
100
|
+
python -m pip install -e .
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Documentation
|
|
104
|
+
|
|
105
|
+
FoundryTools-CLI is a Terminal app where commands are logically organized into subcommands.
|
|
106
|
+
|
|
107
|
+
Please refer to the [user documentation](https://foundrytools-cli.readthedocs.io/).
|
|
108
|
+
|
|
109
|
+
## License
|
|
110
|
+
|
|
111
|
+
FoundryTools-CLI is available under the [MIT license](LICENSE)
|
|
112
|
+
|
|
113
|
+
## Credits
|
|
114
|
+
|
|
115
|
+
To Sergiev. May You rest in peace.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# FoundryTools-CLI
|
|
2
|
+
|
|
3
|
+
FoundryTools-CLI is a command line interface for the
|
|
4
|
+
[FoundryTools](https://github.com/ftCLI/FoundryTools) library, which provides a set of tools for
|
|
5
|
+
working with font files. It is designed to be used from the command line, allowing users to perform
|
|
6
|
+
various operations on font files without the need for a graphical user interface.
|
|
7
|
+
|
|
8
|
+
The CLI provides a range of commands for manipulating font files, including converting between
|
|
9
|
+
different font formats, extracting and modifying font metadata, and performing various font-related
|
|
10
|
+
operations. It is built on top of the FoundryTools library, which provides a comprehensive set of
|
|
11
|
+
tools for working with font files in Python.
|
|
12
|
+
|
|
13
|
+
The CLI is designed to be easy to use and provides a consistent interface for working with different
|
|
14
|
+
font formats. It is suitable for both developers and font designers who need to perform various
|
|
15
|
+
operations on font files from the command line. The CLI is also extensible, allowing users to add
|
|
16
|
+
their own commands and functionality as needed.
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+
The command line interface is built with [click](https://github.com/pallets/click/) and tables are
|
|
21
|
+
rendered by [rich](https://github.com/Textualize/rich).
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
FoundryTools-CLI requires Python 3.9 or later.
|
|
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.
|
|
29
|
+
|
|
30
|
+
### pip
|
|
31
|
+
|
|
32
|
+
FoundryTools-CLI releases are available on the Python Package Index (PyPI), so it can be installed
|
|
33
|
+
with [pip](https://pip.pypa.io/):
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
python -m pip install foundrytools-cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Editable mode
|
|
40
|
+
|
|
41
|
+
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. We strongly recommend
|
|
43
|
+
using a virtual environment.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
# clone the repository:
|
|
47
|
+
git clone https://github.com/ftCLI/foundrytools-cli.git
|
|
48
|
+
cd foundrytools-cli
|
|
49
|
+
|
|
50
|
+
# create new virtual environment named e.g. ftcli-venv, or whatever you prefer:
|
|
51
|
+
python -m venv ftcli-venv
|
|
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
|
|
58
|
+
|
|
59
|
+
# install in 'editable' mode
|
|
60
|
+
python -m pip install -e .
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Documentation
|
|
64
|
+
|
|
65
|
+
FoundryTools-CLI is a Terminal app where commands are logically organized into subcommands.
|
|
66
|
+
|
|
67
|
+
Please refer to the [user documentation](https://foundrytools-cli.readthedocs.io/).
|
|
68
|
+
|
|
69
|
+
## License
|
|
70
|
+
|
|
71
|
+
FoundryTools-CLI is available under the [MIT license](LICENSE)
|
|
72
|
+
|
|
73
|
+
## Credits
|
|
74
|
+
|
|
75
|
+
To Sergiev. May You rest in peace.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "foundrytools-cli"
|
|
7
|
+
dynamic = ["version"]
|
|
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.9"
|
|
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.9",
|
|
24
|
+
"Programming Language :: Python :: 3.10",
|
|
25
|
+
"Programming Language :: Python :: 3.11",
|
|
26
|
+
"Programming Language :: Python :: 3.12",
|
|
27
|
+
"Programming Language :: Python :: 3.13",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
"Topic :: Text Processing :: Fonts",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
dependencies = [
|
|
33
|
+
"afdko>=4.0.2",
|
|
34
|
+
"click>=8.1.8",
|
|
35
|
+
"foundrytools>=0.1.4",
|
|
36
|
+
"loguru>=0.7.3",
|
|
37
|
+
"pathvalidate>=3.2.3",
|
|
38
|
+
"rich>=14.0.0",
|
|
39
|
+
"win32-setctime>=1.2.0; sys_platform >= 'win32'",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
ftcli = "foundrytools_cli.__main__:cli"
|
|
44
|
+
|
|
45
|
+
[project.urls]
|
|
46
|
+
Homepage = "https://github.com/ftCLI/FoundryTools-CLI"
|
|
47
|
+
|
|
48
|
+
[project.optional-dependencies]
|
|
49
|
+
dev = [
|
|
50
|
+
"bump-my-version>=1.1.2",
|
|
51
|
+
"hatch>=1.14.1",
|
|
52
|
+
"mypy>=1.15.0",
|
|
53
|
+
"pre-commit>=4.2.0",
|
|
54
|
+
"pylint>=3.3.6",
|
|
55
|
+
]
|
|
56
|
+
docs = [
|
|
57
|
+
"sphinx-click>=6.0.0",
|
|
58
|
+
"sphinx-rtd-theme>=3.0.2",
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
[tool.hatch.version]
|
|
62
|
+
path = "src/foundrytools_cli/__init__.py"
|
|
63
|
+
pattern = 'VERSION = __version__ = "(?P<version>[^"]+)"'
|
|
64
|
+
|
|
65
|
+
[tool.hatch.build.targets.sdist]
|
|
66
|
+
include = [
|
|
67
|
+
"/src",
|
|
68
|
+
]
|
|
69
|
+
exclude = [
|
|
70
|
+
"/.gitignore",
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
[tool.bumpversion]
|
|
74
|
+
current_version = "2.0.1"
|
|
75
|
+
commit = true
|
|
76
|
+
tag = true
|
|
77
|
+
|
|
78
|
+
[[tool.bumpversion.files]]
|
|
79
|
+
filename = "src/foundrytools_cli/__init__.py"
|
|
80
|
+
search = '__version__ = "{current_version}"'
|
|
81
|
+
replace = '__version__ = "{new_version}"'
|
|
82
|
+
|
|
83
|
+
[[tool.bumpversion.files]]
|
|
84
|
+
filename = "docs/source/conf.py"
|
|
85
|
+
search = 'release = "{current_version}"'
|
|
86
|
+
replace = 'release = "{new_version}"'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from foundrytools_cli.commands.cff import cli as cff
|
|
4
|
+
from foundrytools_cli.commands.cmap import cli as cmap
|
|
5
|
+
from foundrytools_cli.commands.converter import cli as converter
|
|
6
|
+
from foundrytools_cli.commands.fix import cli as fix
|
|
7
|
+
from foundrytools_cli.commands.font import cli as font
|
|
8
|
+
from foundrytools_cli.commands.gsub import cli as gsub
|
|
9
|
+
from foundrytools_cli.commands.hhea import cli as hhea
|
|
10
|
+
from foundrytools_cli.commands.name import cli as name
|
|
11
|
+
from foundrytools_cli.commands.os_2 import cli as os_2
|
|
12
|
+
from foundrytools_cli.commands.otf import cli as otf
|
|
13
|
+
from foundrytools_cli.commands.post import cli as post
|
|
14
|
+
from foundrytools_cli.commands.print import cli as print_
|
|
15
|
+
from foundrytools_cli.commands.ttf import cli as ttf
|
|
16
|
+
from foundrytools_cli.commands.utils import cli as utils
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.group(
|
|
20
|
+
help="A collection of command line tools for working with font files.",
|
|
21
|
+
commands={
|
|
22
|
+
"cff": cff,
|
|
23
|
+
"cmap": cmap,
|
|
24
|
+
"converter": converter,
|
|
25
|
+
"fix": fix,
|
|
26
|
+
"font": font,
|
|
27
|
+
"gsub": gsub,
|
|
28
|
+
"hhea": hhea,
|
|
29
|
+
"name": name,
|
|
30
|
+
"os2": os_2,
|
|
31
|
+
"otf": otf,
|
|
32
|
+
"post": post,
|
|
33
|
+
"print": print_,
|
|
34
|
+
"ttf": ttf,
|
|
35
|
+
"utils": utils,
|
|
36
|
+
},
|
|
37
|
+
)
|
|
38
|
+
@click.version_option()
|
|
39
|
+
def cli() -> None: # pylint: disable=missing-function-docstring
|
|
40
|
+
pass
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any, Callable
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
from foundrytools import Font
|
|
6
|
+
from foundrytools.constants import TOP_DICT_NAMES
|
|
7
|
+
|
|
8
|
+
from foundrytools_cli.utils import BaseCommand, ensure_at_least_one_param, make_options
|
|
9
|
+
from foundrytools_cli.utils.task_runner import TaskRunner
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _top_dict_names_flags() -> Callable:
|
|
13
|
+
flags = [
|
|
14
|
+
click.option(
|
|
15
|
+
f"--{option_param}",
|
|
16
|
+
var_name,
|
|
17
|
+
is_flag=True,
|
|
18
|
+
default=None,
|
|
19
|
+
help=f"Deletes the ``{var_name}`` value",
|
|
20
|
+
)
|
|
21
|
+
for option_param, var_name in sorted(TOP_DICT_NAMES.items())
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
return make_options(flags)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _top_dict_names_options() -> Callable:
|
|
28
|
+
options = [
|
|
29
|
+
click.option(
|
|
30
|
+
f"--{option_param}",
|
|
31
|
+
var_name,
|
|
32
|
+
type=str,
|
|
33
|
+
help=f"Sets the ``cff.topDictIndex[0].{var_name}`` value",
|
|
34
|
+
)
|
|
35
|
+
for option_param, var_name in sorted(TOP_DICT_NAMES.items())
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
return make_options(options)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
cli = click.Group("cff", help="Utilities for editing the ``CFF`` table.")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@cli.command("set-names", cls=BaseCommand)
|
|
45
|
+
@click.option(
|
|
46
|
+
"--font-name",
|
|
47
|
+
"fontNames",
|
|
48
|
+
type=str,
|
|
49
|
+
help="Sets the ``cff.fontNames`` value",
|
|
50
|
+
)
|
|
51
|
+
@_top_dict_names_options()
|
|
52
|
+
def set_names(input_path: Path, **options: dict[str, Any]) -> None:
|
|
53
|
+
"""
|
|
54
|
+
Sets the ``cff.fontNames[0]`` and/or ``topDictIndex[0]`` values.
|
|
55
|
+
"""
|
|
56
|
+
ensure_at_least_one_param(click.get_current_context())
|
|
57
|
+
|
|
58
|
+
def task(font: Font, **kwargs: dict[str, str]) -> bool:
|
|
59
|
+
font.t_cff_.set_names(**kwargs)
|
|
60
|
+
return True
|
|
61
|
+
|
|
62
|
+
runner = TaskRunner(input_path=input_path, task=task, **options)
|
|
63
|
+
runner.filter.filter_out_tt = True
|
|
64
|
+
runner.run()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@cli.command("del-names", cls=BaseCommand)
|
|
68
|
+
@_top_dict_names_flags()
|
|
69
|
+
@click.option(
|
|
70
|
+
"--unique-id",
|
|
71
|
+
"UniqueID",
|
|
72
|
+
is_flag=True,
|
|
73
|
+
default=None,
|
|
74
|
+
help="Deletes the ``UniqueID`` value",
|
|
75
|
+
)
|
|
76
|
+
def del_names(input_path: Path, **options: dict[str, Any]) -> None:
|
|
77
|
+
"""
|
|
78
|
+
Deletes attributes from ``topDictIndex[0]`` using the provided keyword arguments.
|
|
79
|
+
"""
|
|
80
|
+
ensure_at_least_one_param(click.get_current_context())
|
|
81
|
+
|
|
82
|
+
def task(font: Font, **kwargs: dict[str, str]) -> bool:
|
|
83
|
+
font.t_cff_.del_names(**kwargs)
|
|
84
|
+
return True
|
|
85
|
+
|
|
86
|
+
runner = TaskRunner(input_path=input_path, task=task, **options)
|
|
87
|
+
runner.filter.filter_out_tt = True
|
|
88
|
+
runner.run()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
@cli.command("find-replace", cls=BaseCommand)
|
|
92
|
+
@click.option(
|
|
93
|
+
"-os",
|
|
94
|
+
"--old-string",
|
|
95
|
+
required=True,
|
|
96
|
+
help="The string to be replaced in th CFF TopDictIndex[0] fields.",
|
|
97
|
+
)
|
|
98
|
+
@click.option(
|
|
99
|
+
"-ns",
|
|
100
|
+
"--new-string",
|
|
101
|
+
required=True,
|
|
102
|
+
help="The string to replace the old string with in the CFF TopDictIndex[0] fields.",
|
|
103
|
+
)
|
|
104
|
+
def find_replace(input_path: Path, **options: dict[str, Any]) -> None:
|
|
105
|
+
"""
|
|
106
|
+
Finds and replaces a string in the ``CFF`` table. It performs the replacement in
|
|
107
|
+
``cff.fontNames[0]`` and in the following ``topDictIndex[0]`` fields:
|
|
108
|
+
|
|
109
|
+
\b
|
|
110
|
+
* version
|
|
111
|
+
* FullName
|
|
112
|
+
* FamilyName
|
|
113
|
+
* Weight
|
|
114
|
+
* Copyright
|
|
115
|
+
* Notice
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
def task(font: Font, old_string: str, new_string: str) -> bool:
|
|
119
|
+
font.t_cff_.find_replace(old_string, new_string)
|
|
120
|
+
return True
|
|
121
|
+
|
|
122
|
+
runner = TaskRunner(input_path=input_path, task=task, **options)
|
|
123
|
+
runner.filter.filter_out_tt = True
|
|
124
|
+
runner.run()
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
from foundrytools import Font
|
|
6
|
+
|
|
7
|
+
from foundrytools_cli.utils import BaseCommand
|
|
8
|
+
from foundrytools_cli.utils.logger import logger
|
|
9
|
+
from foundrytools_cli.utils.task_runner import TaskRunner
|
|
10
|
+
|
|
11
|
+
cli = click.Group(help="Utilities for editing the ``cmap`` table.")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@cli.command("rebuild", cls=BaseCommand)
|
|
15
|
+
@click.option(
|
|
16
|
+
"--remap-all",
|
|
17
|
+
is_flag=True,
|
|
18
|
+
help="Remap all glyphs, including the ones already in the cmap table.",
|
|
19
|
+
)
|
|
20
|
+
def rebuild_cmap(input_path: Path, **options: dict[str, Any]) -> None:
|
|
21
|
+
"""
|
|
22
|
+
Rebuild the cmap table of a font. Optionally remap all characters, including those already in
|
|
23
|
+
the cmap table.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def task(font: Font, remap_all: bool = False) -> bool:
|
|
27
|
+
remapped_glyphs, _ = font.t_cmap.rebuild_character_map(remap_all=remap_all)
|
|
28
|
+
if remapped_glyphs:
|
|
29
|
+
logger.info("Remapped glyphs:")
|
|
30
|
+
for r in remapped_glyphs:
|
|
31
|
+
logger.opt(colors=True).info(
|
|
32
|
+
f" {r[1]} -> <lc>{hex(r[0])[:2]}{hex(r[0])[2:].upper().zfill(6)}</lc>"
|
|
33
|
+
)
|
|
34
|
+
return True
|
|
35
|
+
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
runner = TaskRunner(input_path=input_path, task=task, **options)
|
|
39
|
+
runner.run()
|