fontforge-fontchecker 0.1.0__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.
- fontforge_fontchecker-0.1.0/LICENSE +21 -0
- fontforge_fontchecker-0.1.0/PKG-INFO +52 -0
- fontforge_fontchecker-0.1.0/README.md +33 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker/__init__.py +0 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker/__main__.py +18 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker/config.py +165 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker/run_check.py +158 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker.egg-info/PKG-INFO +52 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker.egg-info/SOURCES.txt +14 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker.egg-info/dependency_links.txt +1 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker.egg-info/entry_points.txt +2 -0
- fontforge_fontchecker-0.1.0/fontforge_fontchecker.egg-info/top_level.txt +1 -0
- fontforge_fontchecker-0.1.0/pyproject.toml +5 -0
- fontforge_fontchecker-0.1.0/setup.cfg +32 -0
- fontforge_fontchecker-0.1.0/test/test_dummy.py +2 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MihailJP
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fontforge_fontchecker
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: FontForge_plugin of font checker frontend
|
|
5
|
+
Home-page: https://github.com/MihailJP/fontforge-fontchecker
|
|
6
|
+
Author: MihailJP
|
|
7
|
+
Author-email: mihailjp@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Plugins
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Text Processing :: Fonts
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
Fontforge font checker plugin
|
|
21
|
+
=============================
|
|
22
|
+
|
|
23
|
+
Font checker wrapper for Fontforge
|
|
24
|
+
|
|
25
|
+
Install
|
|
26
|
+
-------
|
|
27
|
+
|
|
28
|
+
```shell
|
|
29
|
+
pip3 install fontforge_fontchecker
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Make sure Fontforge Python module is usable
|
|
33
|
+
|
|
34
|
+
In interactive mode of Python, run:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import fontforge
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If it raises ``ModuleNotFoundError`` exception, install Fontforge first. If
|
|
41
|
+
installed, make sure the build option set that the Python module gets also
|
|
42
|
+
installed. If already so, Python interpreter does not recognize the module
|
|
43
|
+
path where the required module.
|
|
44
|
+
|
|
45
|
+
```shell
|
|
46
|
+
export PYTHONPATH=/path/to/fontforge/python/module:$PYTHONPATH
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Usage
|
|
50
|
+
-----
|
|
51
|
+
|
|
52
|
+
Explanation here
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Fontforge font checker plugin
|
|
2
|
+
=============================
|
|
3
|
+
|
|
4
|
+
Font checker wrapper for Fontforge
|
|
5
|
+
|
|
6
|
+
Install
|
|
7
|
+
-------
|
|
8
|
+
|
|
9
|
+
```shell
|
|
10
|
+
pip3 install fontforge_fontchecker
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Make sure Fontforge Python module is usable
|
|
14
|
+
|
|
15
|
+
In interactive mode of Python, run:
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
import fontforge
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
If it raises ``ModuleNotFoundError`` exception, install Fontforge first. If
|
|
22
|
+
installed, make sure the build option set that the Python module gets also
|
|
23
|
+
installed. If already so, Python interpreter does not recognize the module
|
|
24
|
+
path where the required module.
|
|
25
|
+
|
|
26
|
+
```shell
|
|
27
|
+
export PYTHONPATH=/path/to/fontforge/python/module:$PYTHONPATH
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Usage
|
|
31
|
+
-----
|
|
32
|
+
|
|
33
|
+
Explanation here
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import fontforge
|
|
2
|
+
from . import config, run_check
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def fontforge_plugin_config(**_):
|
|
6
|
+
config.configInterface()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def fontforge_plugin_init(preferences_path=None, **_):
|
|
10
|
+
config.checkFontTools()
|
|
11
|
+
config.loadConf(preferences_path)
|
|
12
|
+
|
|
13
|
+
fontforge.registerMenuItem(
|
|
14
|
+
callback=run_check.run_check,
|
|
15
|
+
enable=run_check.enabled,
|
|
16
|
+
context="Font",
|
|
17
|
+
name="Check font"
|
|
18
|
+
)
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import fontforge
|
|
2
|
+
import shutil
|
|
3
|
+
import os
|
|
4
|
+
from tomlkit.toml_file import TOMLFile, TOMLDocument
|
|
5
|
+
from typing import Iterable, Optional
|
|
6
|
+
|
|
7
|
+
fontbakery_path = None
|
|
8
|
+
fontspector_path = None
|
|
9
|
+
fontbakery_config = TOMLDocument()
|
|
10
|
+
fontspector_config = TOMLDocument()
|
|
11
|
+
|
|
12
|
+
plugin_config = TOMLDocument()
|
|
13
|
+
_plugin_dir = ''
|
|
14
|
+
CONFIGFILE = 'config.toml'
|
|
15
|
+
FONTBAKERY_CONFIGFILE = 'fontbakery.toml'
|
|
16
|
+
FONTSPECTOR_CONFIGFILE = 'fontspector.toml'
|
|
17
|
+
|
|
18
|
+
profiles = {
|
|
19
|
+
'opentype': 'OpenType (standards compliance)',
|
|
20
|
+
'universal': 'Universal (community best practice)',
|
|
21
|
+
'googlefonts': 'Google Fonts',
|
|
22
|
+
'iso15008': 'ISO 15008 (in-car accessibility)',
|
|
23
|
+
'fontwerk': 'Fontwerk',
|
|
24
|
+
'adobefonts': 'Adobe Fonts',
|
|
25
|
+
'fontbureau': 'Font Bureau',
|
|
26
|
+
'microsoft': 'Microsoft',
|
|
27
|
+
'notofonts': 'Noto fonts',
|
|
28
|
+
'typenetwork': 'Type Network',
|
|
29
|
+
}
|
|
30
|
+
"""List of known Fontbakery/Fontspector check profile"""
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def checkFontTools():
|
|
34
|
+
global fontbakery_path, fontspector_path
|
|
35
|
+
fontbakery_path = shutil.which('fontbakery')
|
|
36
|
+
fontspector_path = shutil.which('fontspector')
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _validateConfItem(key: str, defaultVal, *, choice: Optional[Iterable] = None) -> bool:
|
|
40
|
+
loaded = True
|
|
41
|
+
if (key not in plugin_config) or (not isinstance(plugin_config[key], type(defaultVal))):
|
|
42
|
+
plugin_config[key] = defaultVal # load default
|
|
43
|
+
loaded = False
|
|
44
|
+
if choice:
|
|
45
|
+
if not any(plugin_config[key] == x for x in choice):
|
|
46
|
+
fontforge.logWarning("Invalid " + key + " '" + str(plugin_config[key]) + "' ignored")
|
|
47
|
+
plugin_config[key] = defaultVal
|
|
48
|
+
return loaded
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _validateConf():
|
|
52
|
+
global profiles
|
|
53
|
+
_validateConfItem('backend', 'auto', choice=['auto', 'fontbakery', 'fontspector'])
|
|
54
|
+
_validateConfItem('check_as', 'ttf', choice=['ttf', 'ufo'])
|
|
55
|
+
if _validateConfItem('profiles', profiles):
|
|
56
|
+
profiles |= plugin_config['profiles']
|
|
57
|
+
if _validateConfItem('profile', 'universal'):
|
|
58
|
+
if plugin_config['profile'] not in profiles:
|
|
59
|
+
profiles[plugin_config['profile']] = plugin_config['profile']
|
|
60
|
+
_validateConfItem('explicit_checks', [])
|
|
61
|
+
_validateConfItem('exclude_checks', [])
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def fontBakeryConfigFile() -> str:
|
|
65
|
+
return _plugin_dir + '/' + FONTBAKERY_CONFIGFILE
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def fontSpectorConfigFile() -> str:
|
|
69
|
+
return _plugin_dir + '/' + FONTSPECTOR_CONFIGFILE
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def loadConf(confdir: str):
|
|
73
|
+
global _plugin_dir, plugin_config, fontbakery_config, fontspector_config
|
|
74
|
+
_plugin_dir = confdir
|
|
75
|
+
try:
|
|
76
|
+
plugin_config = TOMLFile(_plugin_dir + '/' + CONFIGFILE).read()
|
|
77
|
+
except FileNotFoundError:
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
_validateConf()
|
|
81
|
+
|
|
82
|
+
try:
|
|
83
|
+
fontbakery_config = TOMLFile(fontBakeryConfigFile()).read()
|
|
84
|
+
except FileNotFoundError:
|
|
85
|
+
pass
|
|
86
|
+
try:
|
|
87
|
+
fontspector_config = TOMLFile(fontSpectorConfigFile()).read()
|
|
88
|
+
except FileNotFoundError:
|
|
89
|
+
pass
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def saveConf():
|
|
93
|
+
os.makedirs(_plugin_dir, exist_ok=True)
|
|
94
|
+
TOMLFile(_plugin_dir + '/' + CONFIGFILE).write(plugin_config)
|
|
95
|
+
TOMLFile(_plugin_dir + '/' + FONTBAKERY_CONFIGFILE).write(fontbakery_config)
|
|
96
|
+
TOMLFile(_plugin_dir + '/' + FONTSPECTOR_CONFIGFILE).write(fontspector_config)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _writeBackendConf():
|
|
100
|
+
fontspector_config['explicit_checks'] \
|
|
101
|
+
= fontbakery_config['explicit_checks'] \
|
|
102
|
+
= plugin_config['explicit_checks']
|
|
103
|
+
fontspector_config['exclude_checks'] \
|
|
104
|
+
= fontbakery_config['exclude_checks'] \
|
|
105
|
+
= plugin_config['exclude_checks']
|
|
106
|
+
for conf in (fontspector_config, fontbakery_config):
|
|
107
|
+
for i in [x[0] for x in conf.items() if not x[1]]:
|
|
108
|
+
conf.remove(i)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def configInterface():
|
|
112
|
+
ans = fontforge.askMulti(
|
|
113
|
+
'Configuration',
|
|
114
|
+
[
|
|
115
|
+
{
|
|
116
|
+
'type': 'choice',
|
|
117
|
+
'question': 'Backend',
|
|
118
|
+
'tag': 'backend',
|
|
119
|
+
'checks': True,
|
|
120
|
+
'answers': [
|
|
121
|
+
{'name': p.capitalize(), 'tag': p, 'default': plugin_config['backend'] == p}
|
|
122
|
+
for p in ['auto', 'fontbakery', 'fontspector']
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
'type': 'choice',
|
|
127
|
+
'question': 'Check as',
|
|
128
|
+
'tag': 'check_as',
|
|
129
|
+
'checks': True,
|
|
130
|
+
'answers': [
|
|
131
|
+
{'name': p, 'tag': p.lower(), 'default': plugin_config['check_as'] == p.lower()}
|
|
132
|
+
for p in ['TTF', 'UFO']
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
'type': 'choice',
|
|
137
|
+
'question': 'Profile',
|
|
138
|
+
'tag': 'profile',
|
|
139
|
+
'answers': [
|
|
140
|
+
{'name': p[1], 'tag': p[0], 'default': plugin_config['profile'] == p[0]}
|
|
141
|
+
for p in profiles.items()
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
'type': 'string',
|
|
146
|
+
'question': 'Explicit checks\n(comma-separated)',
|
|
147
|
+
'tag': 'explicit_checks',
|
|
148
|
+
'default': ','.join(plugin_config['explicit_checks']),
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
'type': 'string',
|
|
152
|
+
'question': 'Excluded checks\n(comma-separated)',
|
|
153
|
+
'tag': 'exclude_checks',
|
|
154
|
+
'default': ','.join(plugin_config['exclude_checks']),
|
|
155
|
+
},
|
|
156
|
+
]
|
|
157
|
+
)
|
|
158
|
+
if ans:
|
|
159
|
+
plugin_config['backend'] = ans['backend']
|
|
160
|
+
plugin_config['check_as'] = ans['check_as']
|
|
161
|
+
plugin_config['profile'] = ans['profile']
|
|
162
|
+
plugin_config['explicit_checks'] = [a for a in (ans['explicit_checks'] or '').split(',') if a]
|
|
163
|
+
plugin_config['exclude_checks'] = [a for a in (ans['exclude_checks'] or '').split(',') if a]
|
|
164
|
+
_writeBackendConf()
|
|
165
|
+
saveConf()
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
from . import config
|
|
2
|
+
import fontforge
|
|
3
|
+
import tempfile
|
|
4
|
+
from typing import Optional
|
|
5
|
+
from subprocess import run
|
|
6
|
+
import json
|
|
7
|
+
import webbrowser
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
RESULT_JSON = 'lastresult.json'
|
|
11
|
+
RESULT_HTML = 'lastresult.html'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _jsonFile() -> str:
|
|
15
|
+
return config._plugin_dir + '/' + RESULT_JSON
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _htmlFile() -> str:
|
|
19
|
+
return config._plugin_dir + '/' + RESULT_HTML
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _executable() -> Optional[str]:
|
|
23
|
+
if config.plugin_config['backend'] == 'auto':
|
|
24
|
+
return config.fontspector_path or config.fontbakery_path
|
|
25
|
+
elif config.plugin_config['backend'] == 'fontbakery':
|
|
26
|
+
return config.fontbakery_path
|
|
27
|
+
elif config.plugin_config['backend'] == 'fontspector':
|
|
28
|
+
return config.fontspector_path
|
|
29
|
+
else: # invalid!
|
|
30
|
+
return None
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def enabled(u, font) -> bool:
|
|
34
|
+
return bool(_executable())
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _cmdline(filename: str) -> list[str]:
|
|
38
|
+
if _executable():
|
|
39
|
+
isFontSpector = (_executable() == config.fontspector_path)
|
|
40
|
+
cmdline = [_executable()]
|
|
41
|
+
if isFontSpector:
|
|
42
|
+
cmdline.append('-p')
|
|
43
|
+
cmdline.append(config.plugin_config['profile'])
|
|
44
|
+
else:
|
|
45
|
+
cmdline.append('check-' + config.plugin_config['profile'])
|
|
46
|
+
cmdline.append('-q')
|
|
47
|
+
cmdline.append('--full-lists')
|
|
48
|
+
cmdline.append('-l')
|
|
49
|
+
cmdline.append('info' if isFontSpector else 'INFO')
|
|
50
|
+
cmdline.append('--configuration')
|
|
51
|
+
cmdline.append(config.fontSpectorConfigFile() if isFontSpector else config.fontBakeryConfigFile())
|
|
52
|
+
cmdline.append('--json')
|
|
53
|
+
cmdline.append(_jsonFile())
|
|
54
|
+
cmdline.append('--html')
|
|
55
|
+
cmdline.append(_htmlFile())
|
|
56
|
+
cmdline.append(filename)
|
|
57
|
+
return cmdline
|
|
58
|
+
else:
|
|
59
|
+
raise RuntimeError('neither Fontbakery nor Fontspector available')
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _outroTitle(summary: dict) -> str:
|
|
63
|
+
if 'ERROR' in summary and summary['ERROR'] > 0:
|
|
64
|
+
return 'Error'
|
|
65
|
+
elif 'FATAL' in summary and summary['FATAL'] > 0:
|
|
66
|
+
return 'Check failed'
|
|
67
|
+
elif 'FAIL' in summary and summary['FAIL'] > 0:
|
|
68
|
+
return 'Check failed'
|
|
69
|
+
else:
|
|
70
|
+
return 'Check passed'
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _outroMessage(summary: dict) -> str:
|
|
74
|
+
if 'ERROR' in summary and summary['ERROR'] > 0:
|
|
75
|
+
return 'There ' + ('are errors' if summary['ERROR'] > 1 else 'is an error') + 'during check.'
|
|
76
|
+
elif 'FATAL' in summary and summary['FATAL'] > 0:
|
|
77
|
+
return 'Check failed with ' + ('severe issues' if summary['FATAL'] > 1 else 'a severe issue') + '.'
|
|
78
|
+
elif 'FAIL' in summary and summary['FAIL'] > 0:
|
|
79
|
+
return 'Check failed with ' + ('some issues' if summary['FAIL'] > 1 else 'an issue') + '.'
|
|
80
|
+
elif 'WARN' in summary and summary['WARN'] > 0:
|
|
81
|
+
return 'Check passed, but with ' + ('warnings' if summary['WARN'] > 1 else 'a warning') + '.'
|
|
82
|
+
else:
|
|
83
|
+
return 'Check passed.'
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def _outroResultText(summary: dict) -> str:
|
|
87
|
+
def toString(key: str, label: str) -> str:
|
|
88
|
+
if key in summary and summary[key] > 0:
|
|
89
|
+
return label + ' ' + str(summary[key])
|
|
90
|
+
else:
|
|
91
|
+
return label + ' 0'
|
|
92
|
+
|
|
93
|
+
return ', '.join(
|
|
94
|
+
toString(x[0], x[1]) for x in [
|
|
95
|
+
('ERROR', '💥'),
|
|
96
|
+
('FATAL', '☠'),
|
|
97
|
+
('FAIL', '🔥'),
|
|
98
|
+
('WARN', '⚠️'),
|
|
99
|
+
('INFO', 'ℹ️'),
|
|
100
|
+
('SKIP', '⏩'),
|
|
101
|
+
('PASS', '✅'),
|
|
102
|
+
]
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _outro(filename: str):
|
|
107
|
+
isFontSpector = (_executable() == config.fontspector_path)
|
|
108
|
+
with open(_jsonFile(), 'r') as file:
|
|
109
|
+
jsonDoc = json.load(file)
|
|
110
|
+
summary = jsonDoc['summary'] if isFontSpector else jsonDoc['result']
|
|
111
|
+
fontforge.logWarning(filename + ': ' + _outroResultText(summary))
|
|
112
|
+
ans = fontforge.ask(
|
|
113
|
+
_outroTitle(summary),
|
|
114
|
+
_outroMessage(summary) + '\n'
|
|
115
|
+
'Would you like to open details with the browser?',
|
|
116
|
+
['_Yes', '_No'])
|
|
117
|
+
if ans == 0:
|
|
118
|
+
webbrowser.open('file://' + _htmlFile(), 1)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def _run_check_direct(font: fontforge.font):
|
|
122
|
+
run(_cmdline(font.path))
|
|
123
|
+
_outro(Path(font.path).name)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _run_check_tmpfile(font: fontforge.font):
|
|
127
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
128
|
+
changed = font.changed
|
|
129
|
+
basename = (
|
|
130
|
+
(font.default_base_filename or font.cidfontname or font.fontname) +
|
|
131
|
+
'.' + config.plugin_config['check_as']
|
|
132
|
+
)
|
|
133
|
+
testfile = tmpdir + '/' + basename
|
|
134
|
+
font.generate(testfile)
|
|
135
|
+
font.changed = changed
|
|
136
|
+
run(_cmdline(testfile))
|
|
137
|
+
_outro(basename)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def run_check(u, font: fontforge.font):
|
|
141
|
+
config.saveConf()
|
|
142
|
+
if any(font.path.endswith(x) for x in ['.ttf', '.otf', '.ufo', '.ufo2', '.ufo3']):
|
|
143
|
+
if font.changed:
|
|
144
|
+
ans = fontforge.ask(
|
|
145
|
+
'Font has been changed',
|
|
146
|
+
'The font\n' + font.path + '\n'
|
|
147
|
+
'has unsaved changes.\n'
|
|
148
|
+
'How would you like to check?',
|
|
149
|
+
['Expor_t a temporary file', 'Check _existing font'],
|
|
150
|
+
)
|
|
151
|
+
if ans == 0:
|
|
152
|
+
_run_check_tmpfile(font)
|
|
153
|
+
else:
|
|
154
|
+
_run_check_direct(font)
|
|
155
|
+
else:
|
|
156
|
+
_run_check_direct(font)
|
|
157
|
+
else:
|
|
158
|
+
_run_check_tmpfile(font)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fontforge_fontchecker
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: FontForge_plugin of font checker frontend
|
|
5
|
+
Home-page: https://github.com/MihailJP/fontforge-fontchecker
|
|
6
|
+
Author: MihailJP
|
|
7
|
+
Author-email: mihailjp@gmail.com
|
|
8
|
+
License: MIT
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Environment :: Plugins
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Text Processing :: Fonts
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
Fontforge font checker plugin
|
|
21
|
+
=============================
|
|
22
|
+
|
|
23
|
+
Font checker wrapper for Fontforge
|
|
24
|
+
|
|
25
|
+
Install
|
|
26
|
+
-------
|
|
27
|
+
|
|
28
|
+
```shell
|
|
29
|
+
pip3 install fontforge_fontchecker
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Make sure Fontforge Python module is usable
|
|
33
|
+
|
|
34
|
+
In interactive mode of Python, run:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
import fontforge
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
If it raises ``ModuleNotFoundError`` exception, install Fontforge first. If
|
|
41
|
+
installed, make sure the build option set that the Python module gets also
|
|
42
|
+
installed. If already so, Python interpreter does not recognize the module
|
|
43
|
+
path where the required module.
|
|
44
|
+
|
|
45
|
+
```shell
|
|
46
|
+
export PYTHONPATH=/path/to/fontforge/python/module:$PYTHONPATH
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Usage
|
|
50
|
+
-----
|
|
51
|
+
|
|
52
|
+
Explanation here
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
setup.cfg
|
|
5
|
+
fontforge_fontchecker/__init__.py
|
|
6
|
+
fontforge_fontchecker/__main__.py
|
|
7
|
+
fontforge_fontchecker/config.py
|
|
8
|
+
fontforge_fontchecker/run_check.py
|
|
9
|
+
fontforge_fontchecker.egg-info/PKG-INFO
|
|
10
|
+
fontforge_fontchecker.egg-info/SOURCES.txt
|
|
11
|
+
fontforge_fontchecker.egg-info/dependency_links.txt
|
|
12
|
+
fontforge_fontchecker.egg-info/entry_points.txt
|
|
13
|
+
fontforge_fontchecker.egg-info/top_level.txt
|
|
14
|
+
test/test_dummy.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
fontforge_fontchecker
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[metadata]
|
|
2
|
+
name = fontforge_fontchecker
|
|
3
|
+
version = 0.1.0
|
|
4
|
+
author = MihailJP
|
|
5
|
+
author_email = mihailjp@gmail.com
|
|
6
|
+
description = FontForge_plugin of font checker frontend
|
|
7
|
+
license = MIT
|
|
8
|
+
license_files =
|
|
9
|
+
LICENSE
|
|
10
|
+
long_description = file: README.md
|
|
11
|
+
long_description_content_type = text/markdown
|
|
12
|
+
url = https://github.com/MihailJP/fontforge-fontchecker
|
|
13
|
+
classifiers =
|
|
14
|
+
Development Status :: 3 - Alpha
|
|
15
|
+
Environment :: Plugins
|
|
16
|
+
Intended Audience :: Developers
|
|
17
|
+
Programming Language :: Python :: 3
|
|
18
|
+
Operating System :: OS Independent
|
|
19
|
+
Topic :: Text Processing :: Fonts
|
|
20
|
+
|
|
21
|
+
[options]
|
|
22
|
+
packages = fontforge_fontchecker
|
|
23
|
+
python_requires = >=3.8
|
|
24
|
+
|
|
25
|
+
[options.entry_points]
|
|
26
|
+
fontforge_plugin =
|
|
27
|
+
Font checker = fontforge_fontchecker.__main__
|
|
28
|
+
|
|
29
|
+
[egg_info]
|
|
30
|
+
tag_build =
|
|
31
|
+
tag_date = 0
|
|
32
|
+
|