fontist 1.13.2 → 1.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/metanorma.yml +3 -1
- data/README.adoc +230 -142
- data/lib/fontist/cli.rb +14 -14
- data/lib/fontist/errors.rb +12 -0
- data/lib/fontist/font.rb +13 -1
- data/lib/fontist/fontconfig.rb +87 -0
- data/lib/fontist/fontconfig_cli.rb +29 -0
- data/lib/fontist/helpers.rb +21 -0
- data/lib/fontist/import/create_formula.rb +22 -2
- data/lib/fontist/import/files/collection_file.rb +7 -3
- data/lib/fontist/import/formula_builder.rb +23 -7
- data/lib/fontist/import/helpers/system_helper.rb +1 -9
- data/lib/fontist/import/macos/macos_license.txt +596 -0
- data/lib/fontist/import/macos.rb +25 -109
- data/lib/fontist/import/recursive_extraction.rb +11 -1
- data/lib/fontist/import/text_helper.rb +1 -1
- data/lib/fontist/import_cli.rb +17 -5
- data/lib/fontist/utils/system.rb +8 -0
- data/lib/fontist/utils.rb +0 -3
- data/lib/fontist/version.rb +1 -1
- metadata +5 -6
- data/lib/fontist/google_cli.rb +0 -21
- data/lib/fontist/utils/dsl/collection_font.rb +0 -36
- data/lib/fontist/utils/dsl/font.rb +0 -38
- data/lib/fontist/utils/dsl.rb +0 -85
@@ -0,0 +1,87 @@
|
|
1
|
+
module Fontist
|
2
|
+
class Fontconfig
|
3
|
+
def self.update
|
4
|
+
new.update
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.remove(options = {})
|
8
|
+
new(options).remove
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(options = {})
|
12
|
+
@options = options
|
13
|
+
end
|
14
|
+
|
15
|
+
def update
|
16
|
+
ensure_fontconfig_installed
|
17
|
+
create_config
|
18
|
+
regenerate_fontconfig_cache
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove
|
22
|
+
return handle_file_not_found unless config_exists?
|
23
|
+
|
24
|
+
regenerate_fontconfig_cache if fontconfig_installed?
|
25
|
+
remove_config
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def ensure_fontconfig_installed
|
31
|
+
raise Errors::FontconfigNotFoundError unless fontconfig_installed?
|
32
|
+
end
|
33
|
+
|
34
|
+
def fontconfig_installed?
|
35
|
+
Utils::System.fontconfig_installed?
|
36
|
+
end
|
37
|
+
|
38
|
+
def create_config
|
39
|
+
return if File.exist?(config_path)
|
40
|
+
|
41
|
+
FileUtils.mkdir_p(File.dirname(config_path))
|
42
|
+
File.write(config_path, config_content)
|
43
|
+
end
|
44
|
+
|
45
|
+
def config_path
|
46
|
+
File.join(xdg_config_home, "fontconfig", "conf.d", "10-fontist.conf")
|
47
|
+
end
|
48
|
+
|
49
|
+
def xdg_config_home
|
50
|
+
ENV["XDG_CONFIG_HOME"] || File.join(Dir.home, ".config")
|
51
|
+
end
|
52
|
+
|
53
|
+
def config_content
|
54
|
+
<<~CONTENT
|
55
|
+
<?xml version='1.0'?>
|
56
|
+
<!DOCTYPE fontconfig SYSTEM 'fonts.dtd'>
|
57
|
+
<fontconfig>
|
58
|
+
<dir>#{Fontist.fonts_path}</dir>
|
59
|
+
</fontconfig>
|
60
|
+
CONTENT
|
61
|
+
end
|
62
|
+
|
63
|
+
def regenerate_fontconfig_cache
|
64
|
+
Helpers.run("fc-cache -f")
|
65
|
+
end
|
66
|
+
|
67
|
+
def ensure_file_exists
|
68
|
+
return if @options[:force]
|
69
|
+
|
70
|
+
raise Errors::FontconfigFileNotFoundError unless File.exist?(config_path)
|
71
|
+
end
|
72
|
+
|
73
|
+
def config_exists?
|
74
|
+
File.exist?(config_path)
|
75
|
+
end
|
76
|
+
|
77
|
+
def handle_file_not_found
|
78
|
+
return if @options[:force]
|
79
|
+
|
80
|
+
raise Errors::FontconfigFileNotFoundError
|
81
|
+
end
|
82
|
+
|
83
|
+
def remove_config
|
84
|
+
FileUtils.rm(config_path)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Fontist
|
2
|
+
class FontconfigCLI < Thor
|
3
|
+
include CLI::ClassOptions
|
4
|
+
|
5
|
+
desc "update", "Update fontconfig configuration to use fontist fonts"
|
6
|
+
def update
|
7
|
+
handle_class_options(options)
|
8
|
+
Fontconfig.update
|
9
|
+
Fontist.ui.success("Fontconfig file has been successfully updated.")
|
10
|
+
CLI::STATUS_SUCCESS
|
11
|
+
rescue Errors::FontconfigNotFoundError => e
|
12
|
+
Fontist.ui.error(e.message)
|
13
|
+
CLI::STATUS_FONTCONFIG_NOT_FOUND
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "remove", "Remove fontist file in fontconfig configuration"
|
17
|
+
option :force, type: :boolean, aliases: :f,
|
18
|
+
desc: "Proceed even if does not exist"
|
19
|
+
def remove
|
20
|
+
handle_class_options(options)
|
21
|
+
Fontconfig.remove(options)
|
22
|
+
Fontist.ui.success("Fontconfig file has been successfully removed.")
|
23
|
+
CLI::STATUS_SUCCESS
|
24
|
+
rescue Errors::FontconfigFileNotFoundError => e
|
25
|
+
Fontist.ui.error(e.message)
|
26
|
+
CLI::STATUS_FONTCONFIG_FILE_NOT_FOUND
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/fontist/helpers.rb
CHANGED
@@ -3,5 +3,26 @@ module Fontist
|
|
3
3
|
def self.parse_to_object(data)
|
4
4
|
JSON.parse(data.to_json, object_class: OpenStruct)
|
5
5
|
end
|
6
|
+
|
7
|
+
def self.run(command)
|
8
|
+
Fontist.ui.debug("Run `#{command}`")
|
9
|
+
|
10
|
+
result = `#{command}`
|
11
|
+
unless $CHILD_STATUS.to_i.zero?
|
12
|
+
raise Errors::BinaryCallError,
|
13
|
+
"Failed to run #{command}, status: #{$CHILD_STATUS}"
|
14
|
+
end
|
15
|
+
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.silence_stream(stream)
|
20
|
+
old_stream = stream.dup
|
21
|
+
stream.reopen(RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ ? "NUL:" : "/dev/null") # rubocop:disable Performance/RegexpMatch, Metrics/LineLength
|
22
|
+
stream.sync = true
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
stream.reopen(old_stream)
|
26
|
+
end
|
6
27
|
end
|
7
28
|
end
|
@@ -55,12 +55,32 @@ module Fontist
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def save(builder)
|
58
|
-
|
59
|
-
path = @options[:formula_dir] ? File.join(@options[:formula_dir], filename) : filename
|
58
|
+
path = vacant_path
|
60
59
|
yaml = YAML.dump(Helpers::HashHelper.stringify_keys(builder.formula))
|
61
60
|
File.write(path, yaml)
|
62
61
|
path
|
63
62
|
end
|
63
|
+
|
64
|
+
def vacant_path
|
65
|
+
path = path_from_name
|
66
|
+
return path unless @options[:keep_existing] && File.exist?(path)
|
67
|
+
|
68
|
+
2.upto(9) do |i|
|
69
|
+
candidate = path.sub(/\.yml$/, "#{i}.yml")
|
70
|
+
return candidate unless File.exist?(candidate)
|
71
|
+
end
|
72
|
+
|
73
|
+
raise Errors::GeneralError, "Formula #{path} already exists."
|
74
|
+
end
|
75
|
+
|
76
|
+
def path_from_name
|
77
|
+
filename = Import.name_to_filename(builder.name)
|
78
|
+
if @options[:formula_dir]
|
79
|
+
File.join(@options[:formula_dir], filename)
|
80
|
+
else
|
81
|
+
filename
|
82
|
+
end
|
83
|
+
end
|
64
84
|
end
|
65
85
|
end
|
66
86
|
end
|
@@ -26,9 +26,9 @@ module Fontist
|
|
26
26
|
|
27
27
|
def read
|
28
28
|
switch_to_temp_dir do |tmp_dir|
|
29
|
-
extract_ttfs(tmp_dir)
|
30
|
-
Otf::FontFile.new(path)
|
31
|
-
|
29
|
+
extract_ttfs(tmp_dir)
|
30
|
+
.map { |path| Otf::FontFile.new(path) }
|
31
|
+
.reject { |font_file| hidden_or_pua_encoded?(font_file) }
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -47,6 +47,10 @@ module Fontist
|
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
+
def hidden_or_pua_encoded?(font_file)
|
51
|
+
font_file.family_name.start_with?(".")
|
52
|
+
end
|
53
|
+
|
50
54
|
def detect_extension
|
51
55
|
base_extension = "ttc"
|
52
56
|
|
@@ -4,9 +4,10 @@ require_relative "text_helper"
|
|
4
4
|
module Fontist
|
5
5
|
module Import
|
6
6
|
class FormulaBuilder
|
7
|
-
FORMULA_ATTRIBUTES = %i[description homepage resources
|
7
|
+
FORMULA_ATTRIBUTES = %i[platforms description homepage resources
|
8
8
|
font_collections fonts extract copyright
|
9
|
-
license_url
|
9
|
+
license_url requires_license_agreement
|
10
|
+
open_license digest command].freeze
|
10
11
|
|
11
12
|
attr_writer :archive,
|
12
13
|
:url,
|
@@ -28,9 +29,15 @@ module Fontist
|
|
28
29
|
def name
|
29
30
|
return @options[:name] if @options[:name]
|
30
31
|
|
31
|
-
|
32
|
-
|
33
|
-
|
32
|
+
common = %i[family_name type]
|
33
|
+
.map { |attr| both_fonts.map(&attr).uniq }
|
34
|
+
.map { |names| TextHelper.longest_common_prefix(names) }
|
35
|
+
.map { |prefix| prefix unless prefix == "Regular" }
|
36
|
+
.compact
|
37
|
+
.join(" ")
|
38
|
+
return common unless common.empty?
|
39
|
+
|
40
|
+
both_fonts.map(&:family_name).first
|
34
41
|
end
|
35
42
|
|
36
43
|
private
|
@@ -50,6 +57,10 @@ module Fontist
|
|
50
57
|
files
|
51
58
|
end
|
52
59
|
|
60
|
+
def platforms
|
61
|
+
@options[:platforms]
|
62
|
+
end
|
63
|
+
|
53
64
|
def description
|
54
65
|
name
|
55
66
|
end
|
@@ -175,12 +186,17 @@ module Fontist
|
|
175
186
|
both_fonts.map(&:license_url).compact.first
|
176
187
|
end
|
177
188
|
|
189
|
+
def requires_license_agreement
|
190
|
+
@options[:requires_license_agreement]
|
191
|
+
end
|
192
|
+
|
178
193
|
def open_license
|
179
|
-
unless @license_text
|
194
|
+
unless @license_text || requires_license_agreement
|
180
195
|
Fontist.ui.error("WARN: please add license manually")
|
181
|
-
return
|
182
196
|
end
|
183
197
|
|
198
|
+
return unless @license_text
|
199
|
+
|
184
200
|
Fontist.ui.error("WARN: ensure it's an open license, otherwise " \
|
185
201
|
"change the 'open_license' attribute to " \
|
186
202
|
"'requires_license_agreement'")
|
@@ -4,15 +4,7 @@ module Fontist
|
|
4
4
|
module SystemHelper
|
5
5
|
class << self
|
6
6
|
def run(command)
|
7
|
-
Fontist.
|
8
|
-
|
9
|
-
result = `#{command}`
|
10
|
-
unless $CHILD_STATUS.to_i.zero?
|
11
|
-
raise Errors::BinaryCallError,
|
12
|
-
"Failed to run #{command}, status: #{$CHILD_STATUS}"
|
13
|
-
end
|
14
|
-
|
15
|
-
result
|
7
|
+
Fontist::Helpers.run(command)
|
16
8
|
end
|
17
9
|
end
|
18
10
|
end
|