fontist 1.19.0 → 1.21.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/deploy-pages.yml +48 -0
- data/.github/workflows/tebako-pack.yml +61 -0
- data/.github/workflows/test-and-release.yml +2 -1
- data/LICENSE.txt +1 -2
- data/README.adoc +24 -2
- data/docs/.gitignore +136 -0
- data/docs/.vitepress/config.ts +83 -0
- data/docs/guide/api-ruby.md +190 -0
- data/docs/guide/ci.md +29 -0
- data/docs/guide/fontconfig.md +23 -0
- data/docs/guide/index.md +67 -0
- data/docs/guide/proxy.md +47 -0
- data/docs/guide/why.md +7 -0
- data/docs/index.md +40 -0
- data/docs/package-lock.json +1791 -0
- data/docs/package.json +17 -0
- data/docs/public/hero.png +0 -0
- data/docs/public/logo.png +0 -0
- data/docs/reference/index.md +143 -0
- data/exe/fontist +1 -2
- data/fontist.gemspec +3 -0
- data/lib/fontist/cli/class_options.rb +7 -0
- data/lib/fontist/cli/thor_ext.rb +79 -0
- data/lib/fontist/cli.rb +2 -0
- data/lib/fontist/config.rb +2 -1
- data/lib/fontist/font.rb +55 -10
- data/lib/fontist/font_installer.rb +22 -51
- data/lib/fontist/formula.rb +77 -3
- data/lib/fontist/formula_suggestion.rb +55 -0
- data/lib/fontist/helpers.rb +2 -0
- data/lib/fontist/import/create_formula.rb +77 -35
- data/lib/fontist/import/formula_builder.rb +63 -81
- data/lib/fontist/import/google/api.rb +25 -0
- data/lib/fontist/import/google/create_google_formula.rb +89 -0
- data/lib/fontist/import/google_import.rb +63 -32
- data/lib/fontist/import/recursive_extraction.rb +0 -16
- data/lib/fontist/manifest/locations.rb +2 -0
- data/lib/fontist/resources/archive_resource.rb +55 -0
- data/lib/fontist/resources/google_resource.rb +64 -0
- data/lib/fontist/style_version.rb +4 -0
- data/lib/fontist/utils/cache.rb +16 -0
- data/lib/fontist/utils/downloader.rb +9 -2
- data/lib/fontist/utils/ui.rb +10 -2
- data/lib/fontist/version.rb +1 -1
- data/lib/fontist.rb +13 -1
- metadata +67 -6
- data/lib/fontist/import/google/new_fonts_fetcher.rb +0 -146
- data/lib/fontist/import/google/skiplist.yml +0 -12
- data/lib/fontist/import/google_check.rb +0 -27
data/docs/package.json
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
{
|
2
|
+
"scripts": {
|
3
|
+
"dev": "vitepress dev",
|
4
|
+
"build": "vitepress build",
|
5
|
+
"preview": "vitepress preview",
|
6
|
+
"format": "prettier -w ."
|
7
|
+
},
|
8
|
+
"type": "module",
|
9
|
+
"devDependencies": {
|
10
|
+
"@types/node": "latest",
|
11
|
+
"prettier": "^3.2.4",
|
12
|
+
"typescript": "latest",
|
13
|
+
"vitepress": "^1.0.0-rc.44",
|
14
|
+
"vue": "^3.4.15",
|
15
|
+
"vue-tsc": "^1.8.27"
|
16
|
+
}
|
17
|
+
}
|
Binary file
|
Binary file
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# Fontist CLI reference
|
2
|
+
|
3
|
+
<!-- This can be converted to a folder & multiple pages at any time. -->
|
4
|
+
|
5
|
+
## `fontist cache`
|
6
|
+
|
7
|
+
The only subcommand available on `fontist cache` is `fontist cache clear`. It clears the `~/.fontist` cache.
|
8
|
+
|
9
|
+
```sh
|
10
|
+
fontist cache clear
|
11
|
+
```
|
12
|
+
|
13
|
+
```
|
14
|
+
Cache has been successfully removed.
|
15
|
+
```
|
16
|
+
|
17
|
+
## `fontist config`
|
18
|
+
|
19
|
+
`fontist config` lets you edit the Fontist config file from the command line instead of opening an editor. There are four subcommands available:
|
20
|
+
|
21
|
+
- `fontist config delete <key>`
|
22
|
+
- `fontist config keys`
|
23
|
+
- `fontist config set <key> <value>`
|
24
|
+
- `fontist config show`
|
25
|
+
|
26
|
+
Here's an example of these commands being used to edit the config file:
|
27
|
+
|
28
|
+
```sh
|
29
|
+
fontist config keys
|
30
|
+
fontist config set font_path /var/myfonts
|
31
|
+
fontist config delete font_path
|
32
|
+
fontist config show
|
33
|
+
```
|
34
|
+
|
35
|
+
```
|
36
|
+
$ fontist config keys
|
37
|
+
Available keys:
|
38
|
+
fonts_path (default: /home/octocat/.fontist/fonts)
|
39
|
+
open_timeout (default: 10)
|
40
|
+
read_timeout (default: 10)
|
41
|
+
|
42
|
+
$ fontist config set fonts_path /var/myfonts
|
43
|
+
'fonts_path' set to '/var/myfonts'.
|
44
|
+
|
45
|
+
$ fontist config delete fonts_path
|
46
|
+
'fonts_path' reset to default ('/home/octocat/.fontist/fonts').
|
47
|
+
|
48
|
+
$ fontist config show
|
49
|
+
Config is empty.
|
50
|
+
```
|
51
|
+
|
52
|
+
### Config reference
|
53
|
+
|
54
|
+
<!-- Move this into its own '/reference/config' page if this grows a lot. -->
|
55
|
+
|
56
|
+
- **`fonts_path`:** Where to put the `.ttf` files. Defaults to `~/.fontist/fonts`
|
57
|
+
|
58
|
+
- **`open_timeout`:** Defaults to 10.
|
59
|
+
|
60
|
+
- **`read_timeout`:** Defaults to 10.
|
61
|
+
|
62
|
+
## `fontist status [font-name]`
|
63
|
+
|
64
|
+
Prints the paths to a particular installed font or all fonts if the `font-name` is omitted. This searches **all fonts available on your system** even those not managed by Fontist.
|
65
|
+
|
66
|
+
```sh
|
67
|
+
fontist status
|
68
|
+
```
|
69
|
+
|
70
|
+
```
|
71
|
+
Fonts found at:
|
72
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-B.ttf
|
73
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-BI.ttf
|
74
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf
|
75
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-RI.ttf
|
76
|
+
- /home/octocat/.fontist/fonts/Arial.ttf (from ms_truetype formula)
|
77
|
+
- /home/octocat/.fontist/fonts/ArialBI.ttf (from ms_truetype formula)
|
78
|
+
- /home/octocat/.fontist/fonts/ArialBd.ttf (from ms_truetype formula)
|
79
|
+
- /home/octocat/.fontist/fonts/ArialI.ttf (from ms_truetype formula)
|
80
|
+
```
|
81
|
+
|
82
|
+
Here's an example narrowed to a specific font:
|
83
|
+
|
84
|
+
```sh
|
85
|
+
fontist status "Open Sans"
|
86
|
+
```
|
87
|
+
|
88
|
+
```
|
89
|
+
Fonts found at:
|
90
|
+
- /home/octocat/.fontist/fonts/OpenSans-Bold.ttf (from open_sans formula)
|
91
|
+
- /home/octocat/.fontist/fonts/OpenSans-BoldItalic.ttf (from open_sans formula)
|
92
|
+
- /home/octocat/.fontist/fonts/OpenSans-Italic.ttf (from open_sans formula)
|
93
|
+
- /home/octocat/.fontist/fonts/OpenSans-Regular.ttf (from open_sans formula)
|
94
|
+
```
|
95
|
+
|
96
|
+
## `fontist list [font-name]`
|
97
|
+
|
98
|
+
Lists the installation status of `font-name` or all fonts if no font name provided.
|
99
|
+
|
100
|
+
```sh
|
101
|
+
fontist status
|
102
|
+
```
|
103
|
+
|
104
|
+
```
|
105
|
+
Fonts found at:
|
106
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-B.ttf
|
107
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-BI.ttf
|
108
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf
|
109
|
+
- /usr/share/fonts/truetype/ubuntu/UbuntuMono-RI.ttf
|
110
|
+
- /home/octocat/.fontist/fonts/Arial.ttf (from ms_truetype formula)
|
111
|
+
- /home/octocat/.fontist/fonts/ArialBI.ttf (from ms_truetype formula)
|
112
|
+
- /home/octocat/.fontist/fonts/ArialBd.ttf (from ms_truetype formula)
|
113
|
+
- /home/octocat/.fontist/fonts/ArialI.ttf (from ms_truetype formula)
|
114
|
+
```
|
115
|
+
|
116
|
+
Here's an example getting the status of a specific font:
|
117
|
+
|
118
|
+
```sh
|
119
|
+
fontist status "Fira Mono"
|
120
|
+
```
|
121
|
+
|
122
|
+
```
|
123
|
+
Font "Fira Mono" not found locally.
|
124
|
+
'Fira Mono' font is missing, please run `fontist install 'Fira Mono'` to download the font.
|
125
|
+
```
|
126
|
+
|
127
|
+
## Environment variables
|
128
|
+
|
129
|
+
### `FONTIST_PATH`
|
130
|
+
|
131
|
+
By default Fontist uses the `~/.fontist` directory to store fonts and its files. It can be changed with the `FONTIST_PATH` environment variable.
|
132
|
+
|
133
|
+
```sh
|
134
|
+
FONTIST_PATH=/var/fontist2 fontist update
|
135
|
+
```
|
136
|
+
|
137
|
+
## Excluded fonts
|
138
|
+
|
139
|
+
`fontist` excludes some fonts from usage when they break other software:
|
140
|
+
|
141
|
+
- `NISC18030.ttf` (GB18030 Bitmap) - macOS [fontist/fontist#344](https://github.com/fontist/fontist/issues/344)
|
142
|
+
|
143
|
+
[📑 View the up-to-date list of known problematic fonts on GitHub](https://github.com/fontist/fontist/blob/main/lib/fontist/exclude.yml)
|
data/exe/fontist
CHANGED
data/fontist.gemspec
CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |spec|
|
|
31
31
|
|
32
32
|
spec.add_runtime_dependency "down", "~> 5.0"
|
33
33
|
spec.add_runtime_dependency "extract_ttc", "~> 0.1"
|
34
|
+
spec.add_runtime_dependency "fuzzy_match", "~> 2.1"
|
34
35
|
spec.add_runtime_dependency "json", "~> 2.0"
|
35
36
|
spec.add_runtime_dependency "nokogiri", "~> 1.0"
|
36
37
|
spec.add_runtime_dependency "mime-types", "~> 3.0"
|
@@ -50,4 +51,6 @@ Gem::Specification.new do |spec|
|
|
50
51
|
spec.add_development_dependency "rubocop", "~> 1.22.1"
|
51
52
|
spec.add_development_dependency "rubocop-rails", "~> 2.9"
|
52
53
|
spec.add_development_dependency "rubocop-performance", "~> 1.10"
|
54
|
+
spec.add_development_dependency "vcr"
|
55
|
+
spec.add_development_dependency "webmock"
|
53
56
|
end
|
@@ -22,6 +22,12 @@ module Fontist
|
|
22
22
|
type: :boolean,
|
23
23
|
desc: "Avoid using cache during download"
|
24
24
|
|
25
|
+
base.class_option :interactive,
|
26
|
+
aliases: :i,
|
27
|
+
type: :boolean,
|
28
|
+
default: true,
|
29
|
+
desc: "Interactive mode"
|
30
|
+
|
25
31
|
base.class_option :formulas_path,
|
26
32
|
type: :string,
|
27
33
|
desc: "Path to formulas"
|
@@ -32,6 +38,7 @@ module Fontist
|
|
32
38
|
Fontist.preferred_family = options[:preferred_family]
|
33
39
|
Fontist.log_level = log_level(options)
|
34
40
|
Fontist.use_cache = !options[:no_cache]
|
41
|
+
Fontist.interactive = options[:interactive]
|
35
42
|
|
36
43
|
if options[:formulas_path]
|
37
44
|
Fontist.formulas_path = Pathname.new(options[:formulas_path])
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "fontist/utils/ui"
|
2
|
+
|
3
|
+
module Fontist
|
4
|
+
module ThorExt
|
5
|
+
# Sources:
|
6
|
+
# - https://github.com/mattbrictson/gem/blob/main/lib/example/thor_ext.rb
|
7
|
+
# - https://mattbrictson.com/blog/fixing-thor-cli-behavior
|
8
|
+
#
|
9
|
+
# Configures Thor to behave more like a typical CLI, with better help
|
10
|
+
# and error handling.
|
11
|
+
#
|
12
|
+
# - Passing -h or --help to a command will show help for that command.
|
13
|
+
# - Unrecognized options will be treated as errors.
|
14
|
+
# - Error messages will be printed in red to stderr, without stack trace.
|
15
|
+
# - Errors will cause Thor to exit with a non-zero status.
|
16
|
+
#
|
17
|
+
# To take advantage of this behavior, your CLI should subclass Thor
|
18
|
+
# and extend this module.
|
19
|
+
#
|
20
|
+
# class CLI < Thor
|
21
|
+
# extend ThorExt::Start
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# Start your CLI with:
|
25
|
+
#
|
26
|
+
# CLI.start
|
27
|
+
#
|
28
|
+
# In tests, prevent Kernel.exit from being called when an error occurs,
|
29
|
+
# like this:
|
30
|
+
#
|
31
|
+
# CLI.start(args, exit_on_failure: false)
|
32
|
+
module Start
|
33
|
+
def self.extended(base)
|
34
|
+
super
|
35
|
+
base.check_unknown_options!
|
36
|
+
end
|
37
|
+
|
38
|
+
def start(given_args = ARGV, config = {})
|
39
|
+
config[:shell] ||= Thor::Base.shell.new
|
40
|
+
handle_help_switches(given_args) do |args|
|
41
|
+
dispatch(nil, args, nil, config)
|
42
|
+
end
|
43
|
+
rescue StandardError => e
|
44
|
+
handle_exception_on_start(e, config)
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
50
|
+
def handle_help_switches(given_args)
|
51
|
+
yield(given_args.dup)
|
52
|
+
rescue Thor::UnknownArgumentError => e
|
53
|
+
retry_with_args = []
|
54
|
+
|
55
|
+
if given_args.first == "help"
|
56
|
+
retry_with_args = ["help"] if given_args.length > 1
|
57
|
+
elsif e.unknown.intersect?(%w[-h --help])
|
58
|
+
retry_with_args = ["help", (given_args - e.unknown).first]
|
59
|
+
end
|
60
|
+
raise unless retry_with_args.any?
|
61
|
+
|
62
|
+
yield(retry_with_args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def handle_exception_on_start(error, config)
|
66
|
+
return if error.is_a?(Errno::EPIPE)
|
67
|
+
raise if Fontist.ui.debug? || !config.fetch(:exit_on_failure, true)
|
68
|
+
|
69
|
+
message = error.message.to_s
|
70
|
+
if message.empty? || !error.is_a?(Thor::Error)
|
71
|
+
message.prepend("[#{error.class}] ")
|
72
|
+
end
|
73
|
+
config[:shell]&.say_error(message, :red)
|
74
|
+
exit(false)
|
75
|
+
end
|
76
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/fontist/cli.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "thor"
|
2
2
|
require "fontist/cli/class_options"
|
3
|
+
require "fontist/cli/thor_ext"
|
3
4
|
require "fontist/repo_cli"
|
4
5
|
require "fontist/cache_cli"
|
5
6
|
require "fontist/import_cli"
|
@@ -9,6 +10,7 @@ require "fontist/config_cli"
|
|
9
10
|
module Fontist
|
10
11
|
class CLI < Thor
|
11
12
|
include ClassOptions
|
13
|
+
extend ThorExt::Start
|
12
14
|
|
13
15
|
STATUS_SUCCESS = 0
|
14
16
|
STATUS_UNKNOWN_ERROR = 1
|
data/lib/fontist/config.rb
CHANGED
data/lib/fontist/font.rb
CHANGED
@@ -2,6 +2,7 @@ require "fontist/font_installer"
|
|
2
2
|
require "fontist/font_path"
|
3
3
|
require "fontist/formula_picker"
|
4
4
|
require "fontist/fontconfig"
|
5
|
+
require "fontist/formula_suggestion"
|
5
6
|
|
6
7
|
module Fontist
|
7
8
|
class Font
|
@@ -109,17 +110,48 @@ module Fontist
|
|
109
110
|
end
|
110
111
|
|
111
112
|
def install_formula
|
112
|
-
download_formula || raise_formula_not_found
|
113
|
+
download_formula || make_suggestions || raise_formula_not_found
|
113
114
|
end
|
114
115
|
|
115
116
|
def download_formula
|
116
|
-
formula = Formula.
|
117
|
+
formula = Formula.find_by_key_or_name(@name)
|
117
118
|
return unless formula
|
118
119
|
return unless formula.downloadable?
|
119
120
|
|
120
121
|
request_formula_installation(formula)
|
121
122
|
end
|
122
123
|
|
124
|
+
def make_suggestions
|
125
|
+
return unless Fontist.interactive?
|
126
|
+
|
127
|
+
suggestions = fuzzy_search_formulas
|
128
|
+
return if suggestions.empty?
|
129
|
+
|
130
|
+
choice = offer_to_choose(suggestions)
|
131
|
+
return unless choice
|
132
|
+
|
133
|
+
request_formula_installation(choice)
|
134
|
+
end
|
135
|
+
|
136
|
+
def fuzzy_search_formulas
|
137
|
+
@formula_suggestion ||= FormulaSuggestion.new
|
138
|
+
@formula_suggestion.find(@name)
|
139
|
+
end
|
140
|
+
|
141
|
+
def offer_to_choose(formulas)
|
142
|
+
Fontist.ui.say("Formula '#{@name}' not found. Did you mean?")
|
143
|
+
|
144
|
+
formulas.each_with_index do |formula, index|
|
145
|
+
Fontist.ui.say("[#{index}] #{formula.name}")
|
146
|
+
end
|
147
|
+
|
148
|
+
choice = Fontist.ui.ask("Please type number or " \
|
149
|
+
"press ENTER to skip installation:").chomp
|
150
|
+
return unless choice.to_i.to_s == choice
|
151
|
+
|
152
|
+
formulas[choice.to_i]
|
153
|
+
end
|
154
|
+
|
123
155
|
def raise_formula_not_found
|
124
156
|
raise Errors::FormulaNotFoundError.new(@name)
|
125
157
|
end
|
@@ -184,6 +216,11 @@ module Fontist
|
|
184
216
|
confirmation = check_and_confirm_required_license(formula)
|
185
217
|
paths = font_installer(formula).install(confirmation: confirmation)
|
186
218
|
|
219
|
+
if paths.nil? || paths.empty?
|
220
|
+
Fontist.ui.error("Fonts not found in formula #{formula}")
|
221
|
+
return
|
222
|
+
end
|
223
|
+
|
187
224
|
Fontist.ui.say("Fonts installed at:")
|
188
225
|
paths.each do |path|
|
189
226
|
Fontist.ui.say("- #{path}")
|
@@ -193,7 +230,7 @@ module Fontist
|
|
193
230
|
def check_and_confirm_required_license(formula)
|
194
231
|
return @confirmation unless formula.license_required
|
195
232
|
|
196
|
-
show_license(formula
|
233
|
+
show_license(formula) unless @hide_licenses
|
197
234
|
return @confirmation if @confirmation.casecmp?("yes")
|
198
235
|
|
199
236
|
confirmation = ask_for_agreement
|
@@ -204,8 +241,8 @@ module Fontist
|
|
204
241
|
)
|
205
242
|
end
|
206
243
|
|
207
|
-
def show_license(
|
208
|
-
Fontist.ui.say(license_agrement_message(
|
244
|
+
def show_license(formula)
|
245
|
+
Fontist.ui.say(license_agrement_message(formula))
|
209
246
|
end
|
210
247
|
|
211
248
|
def ask_for_agreement
|
@@ -215,20 +252,28 @@ module Fontist
|
|
215
252
|
)
|
216
253
|
end
|
217
254
|
|
218
|
-
def license_agrement_message(
|
255
|
+
def license_agrement_message(formula)
|
256
|
+
human_name = human_name(formula)
|
257
|
+
|
219
258
|
<<~MSG
|
220
|
-
FONT LICENSE ACCEPTANCE REQUIRED FOR "#{
|
259
|
+
FONT LICENSE ACCEPTANCE REQUIRED FOR "#{human_name}":
|
221
260
|
|
222
261
|
Fontist can install this font if you accept its licensing conditions.
|
223
262
|
|
224
|
-
FONT LICENSE BEGIN ("#{
|
263
|
+
FONT LICENSE BEGIN ("#{human_name}")
|
225
264
|
-----------------------------------------------------------------------
|
226
|
-
#{license}
|
265
|
+
#{formula.license}
|
227
266
|
-----------------------------------------------------------------------
|
228
|
-
FONT LICENSE END ("#{
|
267
|
+
FONT LICENSE END ("#{human_name}")
|
229
268
|
MSG
|
230
269
|
end
|
231
270
|
|
271
|
+
def human_name(formula)
|
272
|
+
return formula.name if @by_formula
|
273
|
+
|
274
|
+
formula.font_by_name(@name).name
|
275
|
+
end
|
276
|
+
|
232
277
|
def update_fontconfig
|
233
278
|
return unless @update_fontconfig
|
234
279
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require "fontist/utils"
|
2
2
|
require "excavate"
|
3
|
+
require_relative "resources/archive_resource"
|
4
|
+
require_relative "resources/google_resource"
|
3
5
|
|
4
6
|
module Fontist
|
5
7
|
class FontInstaller
|
@@ -48,63 +50,32 @@ module Fontist
|
|
48
50
|
end
|
49
51
|
|
50
52
|
def install_font
|
51
|
-
fonts_paths =
|
53
|
+
fonts_paths = do_install_font
|
52
54
|
fonts_paths.empty? ? nil : fonts_paths
|
53
55
|
end
|
54
56
|
|
55
|
-
def
|
56
|
-
|
57
|
-
@temp_dir = Pathname.new(dir)
|
58
|
-
|
59
|
-
result = yield
|
60
|
-
|
61
|
-
@temp_dir = nil
|
62
|
-
|
63
|
-
result
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def extract
|
68
|
-
archive = download_file(@formula.resources.first)
|
69
|
-
|
70
|
-
install_fonts_from_archive(archive)
|
71
|
-
end
|
72
|
-
|
73
|
-
def install_fonts_from_archive(archive)
|
74
|
-
Fontist.ui.say(%(Installing font "#{@formula.key}".))
|
57
|
+
def do_install_font
|
58
|
+
Fontist.ui.say(%(Installing from formula "#{@formula.key}".))
|
75
59
|
|
76
60
|
Array.new.tap do |fonts_paths|
|
77
|
-
|
61
|
+
resource.files(source_files) do |path|
|
78
62
|
fonts_paths << install_font_file(path) if font_file?(path)
|
79
63
|
end
|
80
64
|
end
|
81
65
|
end
|
82
66
|
|
83
|
-
def
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
result = try_download_file(request, source)
|
90
|
-
return result unless result.is_a?(Errors::InvalidResourceError)
|
91
|
-
|
92
|
-
errors << result
|
93
|
-
end
|
67
|
+
def resource
|
68
|
+
resource_class = if @formula.source == "google"
|
69
|
+
Resources::GoogleResource
|
70
|
+
else
|
71
|
+
Resources::ArchiveResource
|
72
|
+
end
|
94
73
|
|
95
|
-
|
74
|
+
resource_class.new(resource_options, no_progress: @no_progress)
|
96
75
|
end
|
97
76
|
|
98
|
-
def
|
99
|
-
|
100
|
-
request,
|
101
|
-
sha: source.sha256,
|
102
|
-
file_size: source.file_size,
|
103
|
-
progress_bar: !@no_progress
|
104
|
-
)
|
105
|
-
rescue Errors::InvalidResourceError => e
|
106
|
-
Fontist.ui.say(e.message)
|
107
|
-
e
|
77
|
+
def resource_options
|
78
|
+
@formula.resources.first
|
108
79
|
end
|
109
80
|
|
110
81
|
def font_file?(path)
|
@@ -116,16 +87,16 @@ module Fontist
|
|
116
87
|
end
|
117
88
|
|
118
89
|
def source_files
|
119
|
-
@source_files ||=
|
120
|
-
|
121
|
-
|
122
|
-
|
90
|
+
@source_files ||= fonts.flat_map do |font|
|
91
|
+
font.styles.map do |style|
|
92
|
+
style.source_font || style.font
|
93
|
+
end
|
123
94
|
end
|
124
95
|
end
|
125
96
|
|
126
|
-
def
|
127
|
-
|
128
|
-
|
97
|
+
def fonts
|
98
|
+
@formula.fonts.select do |font|
|
99
|
+
@font_name.nil? || font.name.casecmp?(@font_name)
|
129
100
|
end
|
130
101
|
end
|
131
102
|
|
data/lib/fontist/formula.rb
CHANGED
@@ -5,6 +5,11 @@ require "git"
|
|
5
5
|
|
6
6
|
module Fontist
|
7
7
|
class Formula
|
8
|
+
NAMESPACES = {
|
9
|
+
"sil" => "SIL",
|
10
|
+
"macos" => "macOS",
|
11
|
+
}.freeze
|
12
|
+
|
8
13
|
def self.update_formulas_repo
|
9
14
|
Update.call
|
10
15
|
end
|
@@ -15,6 +20,12 @@ module Fontist
|
|
15
20
|
end
|
16
21
|
end
|
17
22
|
|
23
|
+
def self.all_keys
|
24
|
+
Dir[Fontist.formulas_path.join("**/*.yml").to_s].map do |path|
|
25
|
+
path.sub("#{Fontist.formulas_path}/", "").sub(".yml", "")
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
18
29
|
def self.find(font_name)
|
19
30
|
Indexes::FontIndex.from_yaml.load_formulas(font_name).first
|
20
31
|
end
|
@@ -45,6 +56,10 @@ module Fontist
|
|
45
56
|
end.flatten
|
46
57
|
end
|
47
58
|
|
59
|
+
def self.find_by_key_or_name(name)
|
60
|
+
find_by_key(name) || find_by_name(name)
|
61
|
+
end
|
62
|
+
|
48
63
|
def self.find_by_key(key)
|
49
64
|
path = Fontist.formulas_path.join("#{key}.yml")
|
50
65
|
return unless File.exist?(path)
|
@@ -52,6 +67,16 @@ module Fontist
|
|
52
67
|
new_from_file(path)
|
53
68
|
end
|
54
69
|
|
70
|
+
def self.find_by_name(name)
|
71
|
+
key = name_to_key(name)
|
72
|
+
|
73
|
+
find_by_key(key)
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.name_to_key(name)
|
77
|
+
name.downcase.gsub(" ", "_")
|
78
|
+
end
|
79
|
+
|
55
80
|
def self.find_by_font_file(font_file)
|
56
81
|
key = Indexes::FilenameIndex
|
57
82
|
.from_yaml
|
@@ -69,7 +94,7 @@ module Fontist
|
|
69
94
|
|
70
95
|
def initialize(data, path)
|
71
96
|
@data = data
|
72
|
-
@path = path
|
97
|
+
@path = real_path(path)
|
73
98
|
end
|
74
99
|
|
75
100
|
def to_index_formula
|
@@ -84,12 +109,24 @@ module Fontist
|
|
84
109
|
@data.key?("resources")
|
85
110
|
end
|
86
111
|
|
112
|
+
def source
|
113
|
+
return unless @data["resources"]
|
114
|
+
|
115
|
+
@data["resources"].values.first["source"]
|
116
|
+
end
|
117
|
+
|
87
118
|
def path
|
88
119
|
@path
|
89
120
|
end
|
90
121
|
|
91
122
|
def key
|
92
|
-
|
123
|
+
@key ||= {}
|
124
|
+
@key[@path] ||= key_from_path
|
125
|
+
end
|
126
|
+
|
127
|
+
def name
|
128
|
+
@name ||= {}
|
129
|
+
@name[key] ||= namespace.empty? ? base_name : "#{namespace}/#{base_name}"
|
93
130
|
end
|
94
131
|
|
95
132
|
def description
|
@@ -142,6 +179,12 @@ module Fontist
|
|
142
179
|
@data["instructions"]
|
143
180
|
end
|
144
181
|
|
182
|
+
def font_by_name(name)
|
183
|
+
fonts.find do |font|
|
184
|
+
font.name.casecmp?(name)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
145
188
|
def fonts_by_name(name)
|
146
189
|
fonts.select do |font|
|
147
190
|
font.name.casecmp?(name)
|
@@ -166,9 +209,40 @@ module Fontist
|
|
166
209
|
|
167
210
|
private
|
168
211
|
|
212
|
+
def real_path(path)
|
213
|
+
Dir.glob(path).first
|
214
|
+
end
|
215
|
+
|
169
216
|
def key_from_path
|
170
217
|
escaped = Regexp.escape("#{Fontist.formulas_path}/")
|
171
|
-
@path.sub(Regexp.new("^#{escaped}"), "").sub(/\.yml$/, "")
|
218
|
+
@path.sub(Regexp.new("^#{escaped}"), "").sub(/\.yml$/, "").to_s
|
219
|
+
end
|
220
|
+
|
221
|
+
def namespace
|
222
|
+
namespace_from_mappings || namespace_from_key
|
223
|
+
end
|
224
|
+
|
225
|
+
def namespace_from_mappings
|
226
|
+
parts = key.split("/")
|
227
|
+
namespace_from_key = parts.take(parts.size - 1).join("/")
|
228
|
+
NAMESPACES[namespace_from_key]
|
229
|
+
end
|
230
|
+
|
231
|
+
def namespace_from_key
|
232
|
+
parts = key.downcase.gsub("_", " ").split("/")
|
233
|
+
parts.take(parts.size - 1).map do |namespace|
|
234
|
+
namespace.split.map(&:capitalize).join(" ")
|
235
|
+
end.join("/")
|
236
|
+
end
|
237
|
+
|
238
|
+
def base_name
|
239
|
+
@data["name"] || base_name_from_key
|
240
|
+
end
|
241
|
+
|
242
|
+
def base_name_from_key
|
243
|
+
key.split("/").last
|
244
|
+
.downcase.gsub("_", " ")
|
245
|
+
.split.map(&:capitalize).join(" ")
|
172
246
|
end
|
173
247
|
|
174
248
|
def fonts_by_family
|