fontist 1.8.12 → 1.10.0

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.
@@ -3,17 +3,37 @@ module Fontist
3
3
  class GeneralError < StandardError; end
4
4
 
5
5
  class BinaryCallError < GeneralError; end
6
+
6
7
  class FontIndexCorrupted < GeneralError; end
8
+
7
9
  class FontNotFoundError < GeneralError; end
10
+
11
+ # for backward compatibility with metanorma,
12
+ # it depends on this exception to automatically download formulas
8
13
  class FormulaIndexNotFoundError < GeneralError; end
14
+
15
+ class MainRepoNotFoundError < FormulaIndexNotFoundError; end
16
+
9
17
  class InvalidResourceError < GeneralError; end
18
+
10
19
  class LicensingError < GeneralError; end
20
+
11
21
  class ManifestCouldNotBeFoundError < GeneralError; end
22
+
12
23
  class ManifestCouldNotBeReadError < GeneralError; end
24
+
13
25
  class MissingAttributeError < GeneralError; end
26
+
27
+ class RepoNotFoundError < GeneralError; end
28
+
29
+ class RepoCouldNotBeUpdatedError < GeneralError; end
30
+
14
31
  class TamperedFileError < GeneralError; end
32
+
15
33
  class TimeoutError < GeneralError; end
34
+
16
35
  class UnknownFontTypeError < GeneralError; end
36
+
17
37
  class UnknownArchiveError < GeneralError; end
18
38
 
19
39
  class FontError < GeneralError
data/lib/fontist/font.rb CHANGED
@@ -166,7 +166,7 @@ module Fontist
166
166
  end
167
167
 
168
168
  def uninstall_font
169
- paths = find_fontist_font
169
+ paths = find_fontist_paths
170
170
  return unless paths
171
171
 
172
172
  paths.each do |path|
@@ -176,8 +176,13 @@ module Fontist
176
176
  paths
177
177
  end
178
178
 
179
- def find_fontist_font
180
- Fontist::FontistFont.find(name)
179
+ def find_fontist_paths
180
+ fonts = Fontist::SystemIndex.fontist_index.find(name, nil)
181
+ return unless fonts
182
+
183
+ fonts.map do |font|
184
+ font[:path]
185
+ end
181
186
  end
182
187
 
183
188
  def installed_paths
@@ -203,9 +208,9 @@ module Fontist
203
208
  end
204
209
 
205
210
  def font_list
206
- return unless formula
211
+ return if formulas.empty?
207
212
 
208
- list_styles([formula])
213
+ list_styles(formulas)
209
214
  end
210
215
 
211
216
  def list_styles(formulas)
@@ -54,11 +54,12 @@ module Fontist
54
54
  end
55
55
 
56
56
  def download_file(source)
57
- url = source.urls.first
57
+ request = source.urls.first
58
+ url = request.respond_to?(:url) ? request.url : request
58
59
  Fontist.ui.say(%(Downloading font "#{@formula.key}" from #{url}))
59
60
 
60
61
  Fontist::Utils::Downloader.download(
61
- url,
62
+ request,
62
63
  sha: source.sha256,
63
64
  file_size: source.file_size,
64
65
  progress_bar: !@no_progress
@@ -1,17 +1,12 @@
1
1
  require "fontist/index"
2
2
  require "fontist/helpers"
3
+ require "fontist/update"
3
4
  require "git"
4
5
 
5
6
  module Fontist
6
7
  class Formula
7
8
  def self.update_formulas_repo
8
- if Dir.exist?(Fontist.formulas_repo_path)
9
- Git.open(Fontist.formulas_repo_path).pull
10
- else
11
- Git.clone(Fontist.formulas_repo_url,
12
- Fontist.formulas_repo_path,
13
- depth: 1)
14
- end
9
+ Update.call
15
10
  end
16
11
 
17
12
  def self.all
@@ -129,7 +129,7 @@ module Fontist
129
129
 
130
130
  fonts = groups.map do |name, group|
131
131
  { name: name,
132
- styles: group.map(&style_type) }
132
+ styles: styles_from_files(group, style_type) }
133
133
  end
134
134
 
135
135
  fonts.sort_by do |x|
@@ -137,6 +137,10 @@ module Fontist
137
137
  end
138
138
  end
139
139
 
140
+ def styles_from_files(files, style_type)
141
+ files.map(&style_type).sort_by { |x| x[:type] }
142
+ end
143
+
140
144
  def extract
141
145
  @extractor.operations
142
146
  end
@@ -156,6 +156,10 @@ module Fontist
156
156
  h.merge!(family_name: style.family_name,
157
157
  type: style.style,
158
158
  full_name: style.full_name)
159
+ if style.preferred_family_name
160
+ h[:preferred_family_name] = style.preferred_family_name
161
+ end
162
+ h[:preferred_type] = style.preferred_style if style.preferred_style
159
163
  h.merge!(style.to_h.select do |k, _|
160
164
  %i(post_script_name version description copyright).include?(k)
161
165
  end.compact)
@@ -10,7 +10,8 @@ module Fontist
10
10
  otfinfo: Otfinfo::OtfinfoRequirement.new,
11
11
  }.freeze
12
12
 
13
- STYLE_ATTRIBUTES = %i[family_name type full_name post_script_name
13
+ STYLE_ATTRIBUTES = %i[family_name type preferred_family_name
14
+ preferred_type full_name post_script_name
14
15
  version description copyright font
15
16
  source_font].freeze
16
17
 
@@ -35,11 +36,19 @@ module Fontist
35
36
  end
36
37
 
37
38
  def family_name
38
- info["Preferred family"] || info["Family"]
39
+ info["Family"]
39
40
  end
40
41
 
41
42
  def type
42
- info["Preferred subfamily"] || info["Subfamily"]
43
+ info["Subfamily"]
44
+ end
45
+
46
+ def preferred_family_name
47
+ info["Preferred family"]
48
+ end
49
+
50
+ def preferred_type
51
+ info["Preferred subfamily"]
43
52
  end
44
53
 
45
54
  def full_name
@@ -7,8 +7,8 @@ module Fontist
7
7
  end
8
8
 
9
9
  def call
10
- style = { family_name: @info["Preferred family"] || @info["Family"],
11
- style: @info["Preferred subfamily"] || @info["Subfamily"],
10
+ style = { family_name: @info["Family"],
11
+ style: @info["Subfamily"],
12
12
  full_name: @info["Full name"],
13
13
  post_script_name: @info["PostScript name"],
14
14
  version: version(@info["Version"]),
@@ -16,6 +16,14 @@ module Fontist
16
16
  filename: File.basename(@path),
17
17
  copyright: @info["Copyright"] }
18
18
 
19
+ if @info["Preferred family"]
20
+ style[:preferred_family_name] = @info["Preferred family"]
21
+ end
22
+
23
+ if @info["Preferred subfamily"]
24
+ style[:preferred_style] = @info["Preferred subfamily"]
25
+ end
26
+
19
27
  OpenStruct.new(style)
20
28
  end
21
29
 
@@ -2,6 +2,12 @@
2
2
  {
3
3
  family_name: "<%= s.family_name %>",
4
4
  style: "<%= s.style %>",
5
+ <%- if s.preferred_family_name -%>
6
+ preferred_family_name: "<%= s.preferred_family_name %>",
7
+ <%- end -%>
8
+ <%- if s.preferred_style -%>
9
+ preferred_type: "<%= s.preferred_style %>",
10
+ <%- end -%>
5
11
  full_name: "<%= s.full_name %>",
6
12
  <%- if s.post_script_name -%>
7
13
  post_script_name: "<%= s.post_script_name %>",
data/lib/fontist/index.rb CHANGED
@@ -3,9 +3,45 @@ require_relative "indexes/filename_index"
3
3
 
4
4
  module Fontist
5
5
  class Index
6
+ def self.rebuild_for_main_repo
7
+ unless Dir.exist?(Fontist.private_formulas_path)
8
+ return do_rebuild_for_main_repo_with
9
+ end
10
+
11
+ Dir.mktmpdir do |dir|
12
+ tmp_private_path = File.join(dir, "private")
13
+ FileUtils.mv(Fontist.private_formulas_path, tmp_private_path)
14
+
15
+ do_rebuild_for_main_repo_with
16
+
17
+ FileUtils.mv(tmp_private_path, Fontist.private_formulas_path)
18
+ end
19
+ end
20
+
21
+ def self.do_rebuild_for_main_repo_with
22
+ Fontist.formula_preferred_family_index_path =
23
+ Fontist.formulas_repo_path.join("index.yml")
24
+ Fontist.formula_filename_index_path =
25
+ Fontist.formulas_repo_path.join("filename_index.yml")
26
+
27
+ rebuild
28
+
29
+ Fontist.formula_preferred_family_index_path = nil
30
+ Fontist.formula_filename_index_path = nil
31
+ end
32
+
6
33
  def self.rebuild
7
- Fontist::Indexes::FontIndex.rebuild
34
+ Fontist::Indexes::DefaultFamilyFontIndex.rebuild
35
+ Fontist::Indexes::PreferredFamilyFontIndex.rebuild
8
36
  Fontist::Indexes::FilenameIndex.rebuild
37
+
38
+ reset_cache
39
+ end
40
+
41
+ def self.reset_cache
42
+ Fontist::Indexes::DefaultFamilyFontIndex.reset_cache
43
+ Fontist::Indexes::PreferredFamilyFontIndex.reset_cache
44
+ Fontist::Indexes::FilenameIndex.reset_cache
9
45
  end
10
46
  end
11
47
  end
@@ -5,10 +5,14 @@ module Fontist
5
5
  class BaseIndex
6
6
  def self.from_yaml
7
7
  @from_yaml ||= begin
8
- unless File.exist?(path)
9
- raise Errors::FormulaIndexNotFoundError.new("Please fetch `#{path}` index with `fontist update`.")
8
+ unless Dir.exist?(Fontist.formulas_repo_path)
9
+ raise Errors::MainRepoNotFoundError.new(
10
+ "Please fetch formulas with `fontist update`.",
11
+ )
10
12
  end
11
13
 
14
+ rebuild unless File.exist?(path)
15
+
12
16
  data = YAML.load_file(path)
13
17
  new(data)
14
18
  end
@@ -18,6 +22,10 @@ module Fontist
18
22
  raise NotImplementedError, "Please define path of an index"
19
23
  end
20
24
 
25
+ def self.reset_cache
26
+ @from_yaml = nil
27
+ end
28
+
21
29
  def self.rebuild
22
30
  index = new
23
31
  index.build
@@ -59,6 +67,8 @@ module Fontist
59
67
  end
60
68
 
61
69
  def to_yaml
70
+ dir = File.dirname(self.class.path)
71
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
62
72
  File.write(self.class.path, YAML.dump(to_h))
63
73
  end
64
74
 
@@ -0,0 +1,21 @@
1
+ require_relative "base_index"
2
+
3
+ module Fontist
4
+ module Indexes
5
+ class DefaultFamilyFontIndex < BaseIndex
6
+ def self.path
7
+ Fontist.formula_index_path
8
+ end
9
+
10
+ def add_formula(formula)
11
+ formula.fonts.each do |font|
12
+ add_index_formula(font.name, formula.to_index_formula)
13
+ end
14
+ end
15
+
16
+ def normalize_key(key)
17
+ key.downcase
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,21 +1,16 @@
1
- require_relative "base_index"
1
+ require_relative "default_family_font_index"
2
+ require_relative "preferred_family_font_index"
2
3
 
3
4
  module Fontist
4
5
  module Indexes
5
- class FontIndex < BaseIndex
6
- def self.path
7
- Fontist.formula_index_path
8
- end
9
-
10
- def add_formula(formula)
11
- formula.fonts.each do |font|
12
- add_index_formula(font.name, formula.to_index_formula)
6
+ class FontIndex
7
+ def self.from_yaml
8
+ if Fontist.preferred_family?
9
+ PreferredFamilyFontIndex.from_yaml
10
+ else
11
+ DefaultFamilyFontIndex.from_yaml
13
12
  end
14
13
  end
15
-
16
- def normalize_key(key)
17
- key.downcase
18
- end
19
14
  end
20
15
  end
21
16
  end
@@ -0,0 +1,24 @@
1
+ require_relative "base_index"
2
+
3
+ module Fontist
4
+ module Indexes
5
+ class PreferredFamilyFontIndex < BaseIndex
6
+ def self.path
7
+ Fontist.formula_preferred_family_index_path
8
+ end
9
+
10
+ def add_formula(formula)
11
+ formula.fonts.each do |font|
12
+ font.styles.each do |style|
13
+ font_name = style.preferred_family_name || font.name
14
+ add_index_formula(font_name, formula.to_index_formula)
15
+ end
16
+ end
17
+ end
18
+
19
+ def normalize_key(key)
20
+ key.downcase
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,60 @@
1
+ require "git"
2
+
3
+ module Fontist
4
+ class Repo
5
+ class << self
6
+ def setup(name, url)
7
+ ensure_private_formulas_path_exists
8
+ fetch_repo(name, url)
9
+ Index.rebuild
10
+ end
11
+
12
+ def update(name)
13
+ path = repo_path(name)
14
+ unless Dir.exist?(path)
15
+ raise(Errors::RepoNotFoundError, "No such repo '#{name}'.")
16
+ end
17
+
18
+ Git.open(path).pull
19
+ Index.rebuild
20
+ end
21
+
22
+ def remove(name)
23
+ path = repo_path(name)
24
+ unless Dir.exist?(path)
25
+ raise(Errors::RepoNotFoundError, "No such repo '#{name}'.")
26
+ end
27
+
28
+ FileUtils.rm_r(path)
29
+ Index.rebuild
30
+ end
31
+
32
+ def list
33
+ Dir.glob(Fontist.private_formulas_path.join("*"))
34
+ .select { |path| File.directory?(path) }
35
+ .map { |path| File.basename(path) }
36
+ end
37
+
38
+ private
39
+
40
+ def ensure_private_formulas_path_exists
41
+ Fontist.private_formulas_path.tap do |path|
42
+ FileUtils.mkdir_p(path) unless Dir.exist?(path)
43
+ end
44
+ end
45
+
46
+ def fetch_repo(name, url)
47
+ path = repo_path(name)
48
+ if Dir.exist?(path)
49
+ Git.open(path).pull
50
+ else
51
+ Git.clone(url, path, depth: 1)
52
+ end
53
+ end
54
+
55
+ def repo_path(name)
56
+ Fontist.private_formulas_path.join(name)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,51 @@
1
+ module Fontist
2
+ class RepoCLI < Thor
3
+ desc "setup NAME URL",
4
+ "Setup a custom fontist repo named NAME for the repository at URL " \
5
+ "and fetches its formulas"
6
+ def setup(name, url)
7
+ Repo.setup(name, url)
8
+ Fontist.ui.success(
9
+ "Fontist repo '#{name}' from '#{url}' has been successfully set up.",
10
+ )
11
+ CLI::STATUS_SUCCESS
12
+ end
13
+
14
+ desc "update NAME", "Update formulas in a fontist repo named NAME"
15
+ def update(name)
16
+ Repo.update(name)
17
+ Fontist.ui.success(
18
+ "Fontist repo '#{name}' has been successfully updated.",
19
+ )
20
+ CLI::STATUS_SUCCESS
21
+ rescue Errors::RepoNotFoundError
22
+ handle_repo_not_found(name)
23
+ end
24
+
25
+ desc "remove NAME", "Remove fontist repo named NAME"
26
+ def remove(name)
27
+ Repo.remove(name)
28
+ Fontist.ui.success(
29
+ "Fontist repo '#{name}' has been successfully removed.",
30
+ )
31
+ CLI::STATUS_SUCCESS
32
+ rescue Errors::RepoNotFoundError
33
+ handle_repo_not_found(name)
34
+ end
35
+
36
+ desc "list", "List fontist repos"
37
+ def list
38
+ Repo.list.each do |name|
39
+ Fontist.ui.say(name)
40
+ end
41
+ CLI::STATUS_SUCCESS
42
+ end
43
+
44
+ private
45
+
46
+ def handle_repo_not_found(name)
47
+ Fontist.ui.error("Fontist repo '#{name}' is not found.")
48
+ CLI::STATUS_REPO_NOT_FOUND
49
+ end
50
+ end
51
+ end