fontist 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2dc209840287f224caec09be365402ca43e3605debfed69d01f3f89f12d27093
4
- data.tar.gz: 2ba6e5c3359cfa30afe30ecf96b4f11311e33c12dcce5053b7e37ea9c1750ce9
3
+ metadata.gz: 4832b87f5d5535536b6f2f2e2761bf8ff8dbd82770703f93e201e2c7e81f496d
4
+ data.tar.gz: 32e720d4a33cb78a88bcdd8bf3b80bc24abec544d3dd755a459ae2a1a4a78d6b
5
5
  SHA512:
6
- metadata.gz: b3e2a83f4c56ca2092954e9602827dcc6fe74ba4ba40d52f5e8ce6b0ca532cec67558fcf5a2e24775b13d263843ff2fab045f66838468a9d5fe0f087c3c08e23
7
- data.tar.gz: 5d8968907e2955e7657044ad60c6c8c66ffc0f90d4e06f219b4bde01ad43f949b8dfc24a3477a6eebd269535d14dd26b7222c841c1f2b216f9e5a9111c9c931d
6
+ metadata.gz: 6567b976d958bc852244e5080753eb1fc2e44f8231fe08f3cded4076d510c553565160cf83c108e2e6c309cce042393acf7e19ab34e5a851f4c879a7f9c642ae
7
+ data.tar.gz: 2bab58316fdc830954b93daa716deaac90912ee4906510fad27efba2c0323af8cdb9bade71d5a5f257461063576863b44e1bfc0b72f7cdde1839689acb497f95
@@ -12,8 +12,13 @@ module Fontist
12
12
  desc "install FONT", "Install font by font or formula"
13
13
  option :force, type: :boolean, aliases: :f,
14
14
  desc: "Install even if it's already installed in system"
15
+ option :confirm_license, type: :boolean, desc: "Confirm license agreement"
15
16
  def install(font)
16
- Fontist::Font.install(font, force: options[:force])
17
+ Fontist::Font.install(
18
+ font,
19
+ force: options[:force],
20
+ confirmation: options[:confirm_license] ? "yes" : "no"
21
+ )
17
22
  STATUS_SUCCESS
18
23
  rescue Fontist::Errors::NonSupportedFontError
19
24
  could_not_find_font(font)
@@ -94,6 +99,7 @@ module Fontist
94
99
  option :name, desc: "Example: Times New Roman"
95
100
  option :mirror, repeatable: true
96
101
  option :subarchive, desc: "Subarchive to choose when there are several ones"
102
+ option :subdir, desc: "Subdirectory to take fonts from"
97
103
  def create_formula(url)
98
104
  require "fontist/import/create_formula"
99
105
  name = Fontist::Import::CreateFormula.new(url, options).call
@@ -7,6 +7,7 @@ module Fontist
7
7
  class InvalidResourceError < StandardError; end
8
8
  class TimeoutError < StandardError; end
9
9
  class MissingAttributeError < StandardError; end
10
+ class UnknownFontTypeError < StandardError; end
10
11
  class FontNotFoundError < StandardError; end
11
12
  class BinaryCallError < StandardError; end
12
13
  class ManifestCouldNotBeReadError < StandardError; end
@@ -95,8 +95,10 @@ module Fontist
95
95
  styles = options.fetch(:extract_styles_from_collection, [])
96
96
 
97
97
  unless styles.empty?
98
- styles.map do |type, file|
99
- { type: type, collection: file, font: temp_resource[:filename] }
98
+ styles.map do |attributes|
99
+ filenames = temp_resource.slice(:filename, :source_filename)
100
+ Fontist::Utils::Dsl::CollectionFont.new(attributes.merge(filenames))
101
+ .attributes
100
102
  end
101
103
  end
102
104
  end
@@ -126,5 +128,31 @@ module Fontist
126
128
  def is_progress_bar_enabled
127
129
  options.nil? ? true : options.fetch(:progress_bar, true)
128
130
  end
131
+
132
+ def font_file?(filename)
133
+ source_files.include?(filename)
134
+ end
135
+
136
+ def source_files
137
+ @source_files ||= fonts.flat_map do |font|
138
+ font[:styles].map do |style|
139
+ style[:source_font] || style[:font]
140
+ end
141
+ end
142
+ end
143
+
144
+ def target_filename(source_filename)
145
+ target_filenames[source_filename]
146
+ end
147
+
148
+ def target_filenames
149
+ @target_filenames ||= fonts.flat_map do |font|
150
+ font[:styles].map do |style|
151
+ source = style[:source_font] || style[:font]
152
+ target = style[:font]
153
+ [source, target]
154
+ end
155
+ end.to_h
156
+ end
129
157
  end
130
158
  end
@@ -19,8 +19,8 @@ module Fontist
19
19
  new(font_name: name).find_fonts
20
20
  end
21
21
 
22
- def self.find_styles(font, style)
23
- new(font_name: font, style_name: style).find_styles
22
+ def self.find_styles_with_fonts(font, style)
23
+ new(font_name: font, style_name: style).find_styles_with_fonts
24
24
  end
25
25
 
26
26
  def all
@@ -37,12 +37,16 @@ module Fontist
37
37
  fonts.empty? ? nil : fonts
38
38
  end
39
39
 
40
- def find_styles
40
+ def find_styles_with_fonts
41
41
  formulas.values.flat_map do |formula|
42
42
  formula.fonts.flat_map do |f|
43
- f.styles.select do |s|
43
+ selected = f.styles.select do |s|
44
44
  f.name.casecmp?(font_name) && s.type.casecmp?(style_name)
45
45
  end
46
+
47
+ selected.map do |s|
48
+ { font: f, style: s }
49
+ end
46
50
  end
47
51
  end
48
52
  end
@@ -23,10 +23,23 @@ module Fontist
23
23
  formula.font_collections.each do |collection|
24
24
  provides_font_collection do
25
25
  filename collection.filename
26
+ source_filename collection.source_filename
26
27
 
27
28
  collection.fonts.each do |font|
28
- styles = font.styles.map { |s| [s.type, s.full_name] }.to_h
29
- provides_font font.name, extract_styles_from_collection: styles
29
+ provides_font(
30
+ font.name,
31
+ extract_styles_from_collection: font.styles.map do |style|
32
+ {
33
+ family_name: style.family_name,
34
+ style: style.type,
35
+ full_name: style.full_name,
36
+ post_script_name: style.post_script_name,
37
+ version: style.version,
38
+ description: style.description,
39
+ copyright: style.copyright,
40
+ }
41
+ end
42
+ )
30
43
  end
31
44
  end
32
45
  end
@@ -45,6 +58,7 @@ module Fontist
45
58
  version: style.version,
46
59
  description: style.description,
47
60
  filename: style.font,
61
+ source_filename: style.source_font,
48
62
  copyright: style.copyright,
49
63
  }
50
64
  end
@@ -8,10 +8,6 @@ require_relative "formula_builder"
8
8
  module Fontist
9
9
  module Import
10
10
  class CreateFormula
11
- FONT_PATTERN = /(\.ttf|\.otf)/i.freeze
12
- FONT_COLLECTION_PATTERN = /\.ttc/i.freeze
13
- LICENSE_PATTERN = /(OFL\.txt|UFL\.txt|LICENSE\.txt|COPYING)$/i.freeze
14
-
15
11
  def initialize(url, options = {})
16
12
  @url = url
17
13
  @options = options
@@ -26,41 +22,30 @@ module Fontist
26
22
  def formula
27
23
  builder = FormulaBuilder.new
28
24
  builder.url = @url
29
- builder.archive = download(@url)
30
- builder.extractor = extractor(builder.archive)
25
+ builder.archive = archive
26
+ builder.extractor = extractor
31
27
  builder.options = @options
32
- builder.font_files = font_files(builder.extractor)
33
- builder.font_collection_files = font_collection_files(builder.extractor)
34
- builder.license_text = license_texts(builder.extractor).first
28
+ builder.font_files = extractor.font_files
29
+ builder.font_collection_files = extractor.font_collection_files
30
+ builder.license_text = extractor.license_text
35
31
  builder.formula
36
32
  end
37
33
 
38
- def download(url)
39
- return url if File.exist?(url)
40
-
41
- Fontist::Utils::Downloader.download(url, progress_bar: true).path
34
+ def extractor
35
+ @extractor ||=
36
+ RecursiveExtraction.new(archive,
37
+ subarchive: @options[:subarchive],
38
+ subdir: @options[:subdir])
42
39
  end
43
40
 
44
- def extractor(archive)
45
- RecursiveExtraction.new(archive, subarchive: @options[:subarchive])
41
+ def archive
42
+ @archive ||= download(@url)
46
43
  end
47
44
 
48
- def font_files(extractor)
49
- extractor.extract(FONT_PATTERN) do |path|
50
- Otf::FontFile.new(path)
51
- end
52
- end
53
-
54
- def font_collection_files(extractor)
55
- extractor.extract(FONT_COLLECTION_PATTERN) do |path|
56
- Files::CollectionFile.new(path)
57
- end
58
- end
45
+ def download(url)
46
+ return url if File.exist?(url)
59
47
 
60
- def license_texts(extractor)
61
- extractor.extract(LICENSE_PATTERN) do |path|
62
- File.read(path)
63
- end
48
+ Fontist::Utils::Downloader.download(url, progress_bar: true).path
64
49
  end
65
50
 
66
51
  def save(hash)
@@ -11,10 +11,15 @@ module Fontist
11
11
  def initialize(path)
12
12
  @path = path
13
13
  @fonts = read
14
+ @extension = "ttc"
14
15
  end
15
16
 
16
17
  def filename
17
- File.basename(@path)
18
+ File.basename(@path, ".*") + "." + @extension
19
+ end
20
+
21
+ def source_filename
22
+ File.basename(@path) unless filename == File.basename(@path)
18
23
  end
19
24
 
20
25
  private
@@ -0,0 +1,17 @@
1
+ module Fontist
2
+ module Import
3
+ module Files
4
+ class FileRequirement
5
+ def initialize
6
+ `file -v`
7
+ rescue Errno::ENOENT
8
+ abort "`file` is not available. (Or is PATH not setup properly?)"
9
+ end
10
+
11
+ def call(path)
12
+ Helpers::SystemHelper.run("file --brief '#{path}'")
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,48 @@
1
+ require_relative "file_requirement"
2
+
3
+ module Fontist
4
+ module Import
5
+ module Files
6
+ class FontDetector
7
+ REQUIREMENTS = { file: FileRequirement.new }.freeze
8
+
9
+ FONT_LABELS = ["OpenType font data",
10
+ "TrueType Font data"].freeze
11
+
12
+ COLLECTION_LABEL = "TrueType font collection data".freeze
13
+
14
+ FONT_EXTENSIONS = {
15
+ "OpenType font data" => "otf",
16
+ "TrueType Font data" => "ttf",
17
+ "TrueType font collection data" => "ttc",
18
+ }.freeze
19
+
20
+ def self.detect(path)
21
+ brief = file_brief(path)
22
+
23
+ if brief.start_with?(*FONT_LABELS)
24
+ :font
25
+ elsif brief.start_with?(COLLECTION_LABEL)
26
+ :collection
27
+ else
28
+ :other
29
+ end
30
+ end
31
+
32
+ def self.standard_extension(path)
33
+ brief = file_brief(path)
34
+
35
+ FONT_EXTENSIONS.each do |label, extension|
36
+ return extension if brief.start_with?(label)
37
+ end
38
+
39
+ raise Errors::UnknownFontTypeError.new(path)
40
+ end
41
+
42
+ def self.file_brief(path)
43
+ REQUIREMENTS[:file].call(path)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -107,7 +107,10 @@ module Fontist
107
107
 
108
108
  collections = @font_collection_files.map do |file|
109
109
  fonts = fonts_from_files(file.fonts, :to_collection_style)
110
- { filename: file.filename, fonts: fonts }
110
+
111
+ { filename: file.filename,
112
+ source_filename: file.source_filename,
113
+ fonts: fonts }.compact
111
114
  end
112
115
 
113
116
  collections.sort_by do |x|
@@ -152,8 +155,9 @@ module Fontist
152
155
  return
153
156
  end
154
157
 
155
- Fontist.ui.error("WARN: ensure it's an open license, otherwise change \
156
- to 'requires_license_agreement'")
158
+ Fontist.ui.error("WARN: ensure it's an open license, otherwise " \
159
+ "change the 'open_license' attribute to " \
160
+ "'requires_license_agreement'")
157
161
 
158
162
  TextHelper.cleanup(@license_text)
159
163
  end
@@ -1,5 +1,6 @@
1
1
  require_relative "../otfinfo/otfinfo_requirement"
2
2
  require_relative "../text_helper"
3
+ require_relative "../files/font_detector"
3
4
 
4
5
  module Fontist
5
6
  module Import
@@ -10,14 +11,19 @@ module Fontist
10
11
  }.freeze
11
12
 
12
13
  STYLE_ATTRIBUTES = %i[family_name type full_name post_script_name
13
- version description copyright font].freeze
14
- COLLECTION_ATTRIBUTES = STYLE_ATTRIBUTES.reject { |a| a == :font }
14
+ version description copyright font
15
+ source_font].freeze
16
+
17
+ COLLECTION_ATTRIBUTES = STYLE_ATTRIBUTES.reject do |a|
18
+ %i[font source_font].include?(a)
19
+ end
15
20
 
16
21
  attr_reader :path
17
22
 
18
23
  def initialize(path)
19
24
  @path = path
20
25
  @info = read
26
+ @extension = detect_extension
21
27
  end
22
28
 
23
29
  def to_style
@@ -55,7 +61,11 @@ module Fontist
55
61
  end
56
62
 
57
63
  def font
58
- File.basename(@path)
64
+ File.basename(@path, ".*") + "." + @extension
65
+ end
66
+
67
+ def source_font
68
+ File.basename(@path) unless font == File.basename(@path)
59
69
  end
60
70
 
61
71
  def copyright
@@ -85,6 +95,10 @@ module Fontist
85
95
  .map { |x| x.map { |y| Fontist::Import::TextHelper.cleanup(y) } }
86
96
  .to_h
87
97
  end
98
+
99
+ def detect_extension
100
+ Files::FontDetector.standard_extension(@path)
101
+ end
88
102
  end
89
103
  end
90
104
  end
@@ -1,28 +1,40 @@
1
1
  require "find"
2
2
  require_relative "extractors"
3
+ require_relative "files/font_detector"
3
4
 
4
5
  module Fontist
5
6
  module Import
6
7
  class RecursiveExtraction
7
- BOTH_FONTS_PATTERN = "**/*.{ttf,otf,ttc}*".freeze
8
+ FONTS_PATTERN = "**/*.{ttf,otf,ttc}".freeze
8
9
  ARCHIVE_EXTENSIONS = %w[zip msi exe cab].freeze
10
+ LICENSE_PATTERN = /(OFL\.txt|UFL\.txt|LICENSE\.txt|COPYING)$/i.freeze
9
11
 
10
- def initialize(archive, subarchive: nil)
12
+ def initialize(archive, subarchive: nil, subdir: nil)
11
13
  @archive = archive
12
14
  @subarchive = subarchive
15
+ @subdir = subdir
13
16
  @operations = []
17
+ @font_files = []
18
+ @collection_files = []
14
19
  end
15
20
 
16
21
  def extension
17
22
  File.extname(filename(@archive)).sub(/^\./, "")
18
23
  end
19
24
 
20
- def extract(pattern)
21
- Array.new.tap do |results|
22
- Find.find(extracted_path) do |path| # rubocop:disable Style/CollectionMethods, Metrics/LineLength
23
- results << yield(path) if path.match(pattern)
24
- end
25
- end
25
+ def font_files
26
+ ensure_extracted
27
+ @font_files
28
+ end
29
+
30
+ def font_collection_files
31
+ ensure_extracted
32
+ @collection_files
33
+ end
34
+
35
+ def license_text
36
+ ensure_extracted
37
+ @license_text
26
38
  end
27
39
 
28
40
  def operations
@@ -50,7 +62,11 @@ module Fontist
50
62
 
51
63
  def extract_recursively(archive)
52
64
  path = operate_on_archive(archive)
53
- return path if fonts_exist?(path)
65
+ match_files(path)
66
+ if matched?
67
+ save_operation_subdir
68
+ return path
69
+ end
54
70
 
55
71
  next_archive = find_archive(path)
56
72
  extract_recursively(next_archive)
@@ -84,9 +100,50 @@ module Fontist
84
100
  @operations << { format: extractor.format }
85
101
  end
86
102
 
87
- def fonts_exist?(path)
88
- fonts = Dir.glob(File.join(path, BOTH_FONTS_PATTERN))
89
- !fonts.empty?
103
+ def match_files(dir_path)
104
+ Find.find(dir_path) do |entry_path| # rubocop:disable Style/CollectionMethods
105
+ match_license(entry_path)
106
+ match_font(entry_path) if font_directory?(entry_path, dir_path)
107
+ end
108
+ end
109
+
110
+ def match_license(path)
111
+ @license_text ||= File.read(path) if license?(path)
112
+ end
113
+
114
+ def license?(file)
115
+ file.match?(LICENSE_PATTERN)
116
+ end
117
+
118
+ def font_directory?(path, base_path)
119
+ return true unless @subdir
120
+
121
+ relative_path = Pathname.new(path).relative_path_from(base_path).to_s
122
+ dirname = File.dirname(relative_path)
123
+ normalized_pattern = @subdir.chomp("/")
124
+ File.fnmatch?(normalized_pattern, dirname)
125
+ end
126
+
127
+ def match_font(path)
128
+ case Files::FontDetector.detect(path)
129
+ when :font
130
+ @font_files << Otf::FontFile.new(path)
131
+ when :collection
132
+ @collection_files << Files::CollectionFile.new(path)
133
+ end
134
+ end
135
+
136
+ def matched?
137
+ [@font_files, @collection_files].any? do |files|
138
+ files.size.positive?
139
+ end
140
+ end
141
+
142
+ def save_operation_subdir
143
+ return unless @subdir
144
+
145
+ @operations.last[:options] ||= {}
146
+ @operations.last[:options][:fonts_sub_dir] = @subdir
90
147
  end
91
148
 
92
149
  def find_archive(path)
@@ -1,8 +1,8 @@
1
- require_relative "common"
1
+ require_relative "locations"
2
2
 
3
3
  module Fontist
4
4
  module Manifest
5
- class Install < Common
5
+ class Install < Locations
6
6
  def initialize(manifest, confirmation: "no")
7
7
  @manifest = manifest
8
8
  @confirmation = confirmation
@@ -15,15 +15,11 @@ module Fontist
15
15
  private
16
16
 
17
17
  def file_paths(font, style)
18
- paths = find_installed_font(font, style)
19
- return paths unless paths.empty?
18
+ paths = super
19
+ return paths unless paths["paths"].empty?
20
20
 
21
21
  install_font(font)
22
- find_installed_font(font, style)
23
- end
24
-
25
- def find_installed_font(font, style)
26
- Fontist::SystemFont.find_with_style(font, style)
22
+ super
27
23
  end
28
24
 
29
25
  def install_font(font)
@@ -1,12 +1,59 @@
1
- require_relative "common"
2
-
3
1
  module Fontist
4
2
  module Manifest
5
- class Locations < Common
3
+ class Locations
4
+ def initialize(manifest)
5
+ @manifest = manifest
6
+ end
7
+
8
+ def self.call(manifest)
9
+ new(manifest).call
10
+ end
11
+
12
+ def call
13
+ font_names.zip(font_paths).to_h
14
+ end
15
+
6
16
  private
7
17
 
18
+ def font_names
19
+ fonts.keys
20
+ end
21
+
22
+ def fonts
23
+ @fonts ||= begin
24
+ unless File.exist?(@manifest)
25
+ raise Fontist::Errors::ManifestCouldNotBeFoundError
26
+ end
27
+
28
+ fonts = YAML.load_file(@manifest)
29
+ unless fonts.is_a?(Hash)
30
+ raise Fontist::Errors::ManifestCouldNotBeReadError
31
+ end
32
+
33
+ fonts
34
+ end
35
+ end
36
+
37
+ def font_paths
38
+ fonts.map do |font, styles|
39
+ styles_to_ary = [styles].flatten
40
+ style_paths_map(font, styles_to_ary)
41
+ end
42
+ end
43
+
44
+ def style_paths_map(font, names)
45
+ paths = style_paths(font, names)
46
+ names.zip(paths).to_h
47
+ end
48
+
49
+ def style_paths(font, names)
50
+ names.map do |style|
51
+ file_paths(font, style)
52
+ end
53
+ end
54
+
8
55
  def file_paths(font, style)
9
- Fontist::SystemFont.find_with_style(font, style)
56
+ Fontist::SystemFont.find_with_style(font, style).transform_keys(&:to_s)
10
57
  end
11
58
  end
12
59
  end
@@ -22,10 +22,10 @@ module Fontist
22
22
  end
23
23
 
24
24
  def find_with_style
25
- paths = lookup_using_font_and_style
26
- return paths unless paths.empty?
25
+ styles = Formula.find_styles_with_fonts(font, style)
27
26
 
28
- grep_font_paths(font, style)
27
+ { full_name: style_full_name(styles),
28
+ paths: style_paths(styles) }
29
29
  end
30
30
 
31
31
  private
@@ -95,9 +95,22 @@ module Fontist
95
95
  @default_sources ||= YAML.load(system_path_file)["system"][user_os.to_s]
96
96
  end
97
97
 
98
- def lookup_using_font_and_style
99
- styles = Formula.find_styles(font, style)
100
- filenames = styles.map(&:font)
98
+ def style_full_name(styles)
99
+ return if styles.empty?
100
+
101
+ s = styles.first
102
+ s[:style]["full_name"] || s[:font]["name"]
103
+ end
104
+
105
+ def style_paths(styles)
106
+ filenames = styles.map { |x| x[:style]["font"] }
107
+ paths = lookup_using_filenames(filenames)
108
+ return paths unless paths.empty?
109
+
110
+ grep_font_paths(font, style)
111
+ end
112
+
113
+ def lookup_using_filenames(filenames)
101
114
  filenames.flat_map do |filename|
102
115
  search_font_paths(filename)
103
116
  end
@@ -2,6 +2,7 @@ require "fontist/utils/ui"
2
2
  require "fontist/utils/system"
3
3
  require "fontist/utils/dsl"
4
4
  require "fontist/utils/dsl/font"
5
+ require "fontist/utils/dsl/collection_font"
5
6
  require "fontist/utils/downloader"
6
7
  require "fontist/utils/zip_extractor"
7
8
  require "fontist/utils/exe_extractor"
@@ -47,6 +47,10 @@ module Fontist
47
47
  instance.temp_resource.merge!(filename: name)
48
48
  end
49
49
 
50
+ def source_filename(name)
51
+ instance.temp_resource.merge!(source_filename: name)
52
+ end
53
+
50
54
  def provides_font(font, options = {})
51
55
  font_styles = instance.extract_font_styles(options)
52
56
  instance.font_list.push(name: font, styles: font_styles)
@@ -0,0 +1,36 @@
1
+ module Fontist
2
+ module Utils
3
+ module Dsl
4
+ class CollectionFont
5
+ REQUIRED_ATTRIBUTES = %i[style].freeze
6
+
7
+ attr_reader :attributes
8
+
9
+ def initialize(attributes)
10
+ REQUIRED_ATTRIBUTES.each do |required_attribute|
11
+ unless attributes[required_attribute]
12
+ raise(Fontist::Errors::MissingAttributeError.new(
13
+ "Missing attribute: #{required_attribute}"
14
+ ))
15
+ end
16
+ end
17
+
18
+ self.attributes = attributes
19
+ end
20
+
21
+ def attributes=(attrs)
22
+ @attributes = { family_name: attrs[:family_name],
23
+ type: attrs[:style],
24
+ collection: attrs[:full_name],
25
+ full_name: attrs[:full_name],
26
+ post_script_name: attrs[:post_script_name],
27
+ version: attrs[:version],
28
+ description: attrs[:description],
29
+ copyright: attrs[:copyright],
30
+ font: attrs[:filename],
31
+ source_font: attrs[:source_filename] }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -29,7 +29,8 @@ module Fontist
29
29
  version: attrs[:version],
30
30
  description: attrs[:description],
31
31
  copyright: attrs[:copyright],
32
- font: attrs[:filename] }
32
+ font: attrs[:filename],
33
+ source_font: attrs[:source_filename] }
33
34
  end
34
35
  end
35
36
  end
@@ -8,7 +8,7 @@ module Fontist
8
8
 
9
9
  Fontist.ui.say(%(Installing font "#{key}".))
10
10
  cab_file = decompressor.search(exe_file)
11
- cabbed_fonts = grep_fonts(cab_file.files, font_ext) || []
11
+ cabbed_fonts = grep_fonts(cab_file.files) || []
12
12
  fonts_paths = extract_cabbed_fonts_to_assets(cabbed_fonts)
13
13
 
14
14
  block_given? ? yield(fonts_paths) : fonts_paths
@@ -29,10 +29,10 @@ module Fontist
29
29
  )
30
30
  end
31
31
 
32
- def grep_fonts(file, font_ext)
32
+ def grep_fonts(file)
33
33
  Array.new.tap do |fonts|
34
34
  while file
35
- fonts.push(file) if file.filename.match(font_ext)
35
+ fonts.push(file) if font_file?(file.filename)
36
36
  file = file.next
37
37
  end
38
38
  end
@@ -41,7 +41,8 @@ module Fontist
41
41
  def extract_cabbed_fonts_to_assets(cabbed_fonts)
42
42
  Array.new.tap do |fonts|
43
43
  cabbed_fonts.each do |font|
44
- font_path = fonts_path.join(font.filename).to_s
44
+ target_filename = target_filename(font.filename)
45
+ font_path = fonts_path.join(target_filename).to_s
45
46
  decompressor.extract(font, font_path)
46
47
 
47
48
  fonts.push(font_path)
@@ -4,41 +4,49 @@ require "pathname"
4
4
  module Fontist
5
5
  module Utils
6
6
  module ZipExtractor
7
- # fonts_sub_dir is unused now, but formulas have this option
8
- # rubocop:disable Lint/UnusedMethodArgument
9
- def zip_extract(resource, download: true, fonts_sub_dir: "")
7
+ def zip_extract(resource, download: true, fonts_sub_dir: nil)
10
8
  zip_file = download_file(resource) if download
11
9
  zip_file ||= resource.urls.first
12
10
 
13
11
  Fontist.ui.say(%(Installing font "#{key}".))
14
- fonts_paths = unzip_fonts(zip_file)
12
+ fonts_paths = unzip_fonts(zip_file, fonts_sub_dir)
15
13
  block_given? ? yield(fonts_paths) : fonts_paths
16
14
  end
17
- # rubocop:enable Lint/UnusedMethodArgument
18
15
 
19
16
  alias_method :unzip, :zip_extract
20
17
 
21
18
  private
22
19
 
23
20
  # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
24
- def unzip_fonts(file)
21
+ def unzip_fonts(file, subdir)
25
22
  Zip.on_exists_proc = true
26
23
 
27
24
  Array.new.tap do |fonts|
28
25
  Zip::File.open(file) do |zip_file|
29
- zip_file.glob("**/*.{ttf,ttc,otf}").each do |entry|
26
+ zip_file.each do |entry|
30
27
  if entry.name
31
- filename = Pathname.new(entry.name).basename
32
- font_path = fonts_path.join(filename.to_s)
33
- fonts.push(font_path.to_s)
28
+ filename = Pathname.new(entry.name).basename.to_s
29
+ if font_directory?(entry.name, subdir) && font_file?(filename)
30
+ target_filename = target_filename(filename)
31
+ font_path = fonts_path.join(target_filename)
32
+ fonts.push(font_path.to_s)
34
33
 
35
- entry.extract(font_path)
34
+ entry.extract(font_path)
35
+ end
36
36
  end
37
37
  end
38
38
  end
39
39
  end
40
40
  end
41
41
  # rubocop:enable Metrics/MethodLength, Metrics/AbcSize
42
+
43
+ def font_directory?(path, subdir)
44
+ return true unless subdir
45
+
46
+ dirname = File.dirname(path)
47
+ normalized_pattern = subdir.chomp("/")
48
+ File.fnmatch?(normalized_pattern, dirname)
49
+ end
42
50
  end
43
51
  end
44
52
  end
@@ -1,3 +1,3 @@
1
1
  module Fontist
2
- VERSION = "1.6.0".freeze
2
+ VERSION = "1.7.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fontist
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-11-20 00:00:00.000000000 Z
12
+ date: 2020-11-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: down
@@ -284,6 +284,8 @@ files:
284
284
  - lib/fontist/import/extractors/seven_zip_extractor.rb
285
285
  - lib/fontist/import/extractors/zip_extractor.rb
286
286
  - lib/fontist/import/files/collection_file.rb
287
+ - lib/fontist/import/files/file_requirement.rb
288
+ - lib/fontist/import/files/font_detector.rb
287
289
  - lib/fontist/import/formula_builder.rb
288
290
  - lib/fontist/import/formula_serializer.rb
289
291
  - lib/fontist/import/google.rb
@@ -306,7 +308,6 @@ files:
306
308
  - lib/fontist/import/template_helper.rb
307
309
  - lib/fontist/import/text_helper.rb
308
310
  - lib/fontist/manifest.rb
309
- - lib/fontist/manifest/common.rb
310
311
  - lib/fontist/manifest/install.rb
311
312
  - lib/fontist/manifest/locations.rb
312
313
  - lib/fontist/registry.rb
@@ -316,6 +317,7 @@ files:
316
317
  - lib/fontist/utils/cache.rb
317
318
  - lib/fontist/utils/downloader.rb
318
319
  - lib/fontist/utils/dsl.rb
320
+ - lib/fontist/utils/dsl/collection_font.rb
319
321
  - lib/fontist/utils/dsl/font.rb
320
322
  - lib/fontist/utils/exe_extractor.rb
321
323
  - lib/fontist/utils/msi_extractor.rb
@@ -1,60 +0,0 @@
1
- module Fontist
2
- module Manifest
3
- class Common
4
- def initialize(manifest)
5
- @manifest = manifest
6
- end
7
-
8
- def self.call(manifest)
9
- new(manifest).call
10
- end
11
-
12
- def call
13
- font_names.zip(font_paths).to_h
14
- end
15
-
16
- private
17
-
18
- def font_names
19
- fonts.keys
20
- end
21
-
22
- def fonts
23
- @fonts ||= begin
24
- unless File.exist?(@manifest)
25
- raise Fontist::Errors::ManifestCouldNotBeFoundError
26
- end
27
-
28
- fonts = YAML.load_file(@manifest)
29
- unless fonts.is_a?(Hash)
30
- raise Fontist::Errors::ManifestCouldNotBeReadError
31
- end
32
-
33
- fonts
34
- end
35
- end
36
-
37
- def font_paths
38
- fonts.map do |font, styles|
39
- styles_to_ary = [styles].flatten
40
- style_paths_map(font, styles_to_ary)
41
- end
42
- end
43
-
44
- def style_paths_map(font, names)
45
- paths = style_paths(font, names)
46
- names.zip(paths).to_h
47
- end
48
-
49
- def style_paths(font, names)
50
- names.map do |style|
51
- file_paths(font, style)
52
- end
53
- end
54
-
55
- def file_paths(_font, _style)
56
- raise NotImplementedError.new("Implement #file_paths in child class")
57
- end
58
- end
59
- end
60
- end