fontist 1.3.0 → 1.4.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.
Files changed (111) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/check_google.yml +28 -0
  3. data/.github/workflows/macosx.yml +3 -0
  4. data/.github/workflows/ubuntu.yml +1 -1
  5. data/.github/workflows/windows.yml +1 -1
  6. data/.gitignore +6 -0
  7. data/.hound.yml +2 -0
  8. data/.rubocop.yml +22 -0
  9. data/README.md +54 -0
  10. data/bin/check_google +8 -0
  11. data/bin/convert_formulas +8 -0
  12. data/bin/fontist +8 -0
  13. data/bin/generate_otfinfo +8 -0
  14. data/bin/import_google +8 -0
  15. data/bin/stripttc +0 -0
  16. data/fontist.gemspec +14 -1
  17. data/lib/fontist.rb +18 -13
  18. data/lib/fontist/cli.rb +118 -0
  19. data/lib/fontist/errors.rb +3 -0
  20. data/lib/fontist/font.rb +117 -2
  21. data/lib/fontist/font_formula.rb +7 -3
  22. data/lib/fontist/fontist_font.rb +70 -0
  23. data/lib/fontist/formula.rb +11 -8
  24. data/lib/fontist/formula_template.rb +103 -0
  25. data/lib/fontist/formulas.rb +41 -0
  26. data/lib/fontist/import.rb +9 -0
  27. data/lib/fontist/import/convert_formulas.rb +65 -0
  28. data/lib/fontist/import/create_formula.rb +74 -0
  29. data/lib/fontist/import/extractors.rb +5 -0
  30. data/lib/fontist/import/extractors/cab_extractor.rb +37 -0
  31. data/lib/fontist/import/extractors/extractor.rb +19 -0
  32. data/lib/fontist/import/extractors/ole_extractor.rb +41 -0
  33. data/lib/fontist/import/extractors/seven_zip_extractor.rb +44 -0
  34. data/lib/fontist/import/extractors/zip_extractor.rb +31 -0
  35. data/lib/fontist/import/files/collection_file.rb +48 -0
  36. data/lib/fontist/import/formula_builder.rb +115 -0
  37. data/lib/fontist/import/formula_serializer.rb +133 -0
  38. data/lib/fontist/import/google.rb +16 -0
  39. data/lib/fontist/import/google/fonts_public.md +10 -0
  40. data/lib/fontist/import/google/fonts_public.pb.rb +71 -0
  41. data/lib/fontist/import/google/fonts_public.proto +46 -0
  42. data/lib/fontist/import/google/new_fonts_fetcher.rb +121 -0
  43. data/lib/fontist/import/google/skiplist.yml +6 -0
  44. data/lib/fontist/import/google_check.rb +34 -0
  45. data/lib/fontist/import/google_import.rb +180 -0
  46. data/lib/fontist/import/helpers/hash_helper.rb +13 -0
  47. data/lib/fontist/import/helpers/system_helper.rb +20 -0
  48. data/lib/fontist/import/otf/font_file.rb +89 -0
  49. data/lib/fontist/import/otf_parser.rb +25 -0
  50. data/lib/fontist/import/otf_style.rb +29 -0
  51. data/lib/fontist/import/otfinfo/otfinfo_requirement.rb +22 -0
  52. data/lib/fontist/import/otfinfo/template.erb +20 -0
  53. data/lib/fontist/import/otfinfo_generate.rb +45 -0
  54. data/lib/fontist/import/recursive_extraction.rb +101 -0
  55. data/lib/fontist/import/template_helper.rb +19 -0
  56. data/lib/fontist/import/text_helper.rb +30 -0
  57. data/lib/fontist/system_font.rb +12 -18
  58. data/lib/fontist/utils.rb +4 -0
  59. data/lib/fontist/utils/cache.rb +69 -0
  60. data/lib/fontist/utils/downloader.rb +15 -2
  61. data/lib/fontist/utils/dsl.rb +4 -0
  62. data/lib/fontist/utils/dsl/font.rb +37 -0
  63. data/lib/fontist/utils/exe_extractor.rb +12 -19
  64. data/lib/fontist/utils/msi_extractor.rb +31 -0
  65. data/lib/fontist/utils/seven_zip_extractor.rb +41 -0
  66. data/lib/fontist/utils/system.rb +23 -0
  67. data/lib/fontist/utils/ui.rb +8 -0
  68. data/lib/fontist/utils/zip_extractor.rb +9 -4
  69. data/lib/fontist/version.rb +1 -1
  70. metadata +154 -49
  71. data/lib/fontist/formulas/andale_font.rb +0 -80
  72. data/lib/fontist/formulas/arial_black_font.rb +0 -79
  73. data/lib/fontist/formulas/cleartype_fonts.rb +0 -227
  74. data/lib/fontist/formulas/comic_font.rb +0 -78
  75. data/lib/fontist/formulas/courier_font.rb +0 -81
  76. data/lib/fontist/formulas/euphemia_font.rb +0 -85
  77. data/lib/fontist/formulas/georgia_font.rb +0 -80
  78. data/lib/fontist/formulas/impact_font.rb +0 -78
  79. data/lib/fontist/formulas/montserrat_font.rb +0 -132
  80. data/lib/fontist/formulas/ms_truetype_fonts.rb +0 -125
  81. data/lib/fontist/formulas/open_sans_fonts.rb +0 -263
  82. data/lib/fontist/formulas/overpass_font.rb +0 -73
  83. data/lib/fontist/formulas/source_fonts.rb +0 -109
  84. data/lib/fontist/formulas/stix_fonts.rb +0 -108
  85. data/lib/fontist/formulas/tahoma_font.rb +0 -147
  86. data/lib/fontist/formulas/webding_font.rb +0 -78
  87. data/spec/fontist/font_formula_spec.rb +0 -67
  88. data/spec/fontist/font_spec.rb +0 -113
  89. data/spec/fontist/formula_spec.rb +0 -67
  90. data/spec/fontist/formulas/andale_font_spec.rb +0 -29
  91. data/spec/fontist/formulas/arial_black_font_spec.rb +0 -29
  92. data/spec/fontist/formulas/cleartype_fonts_spec.rb +0 -38
  93. data/spec/fontist/formulas/comic_font_spec.rb +0 -29
  94. data/spec/fontist/formulas/courier_font_spec.rb +0 -29
  95. data/spec/fontist/formulas/euphemia_font_spec.rb +0 -29
  96. data/spec/fontist/formulas/georgia_font_spec.rb +0 -29
  97. data/spec/fontist/formulas/impact_font_spec.rb +0 -29
  98. data/spec/fontist/formulas/montserrat_font_spec.rb +0 -29
  99. data/spec/fontist/formulas/ms_truetype_fonts_spec.rb +0 -29
  100. data/spec/fontist/formulas/open_sans_fonts_spec.rb +0 -29
  101. data/spec/fontist/formulas/overpass_font_spec.rb +0 -29
  102. data/spec/fontist/formulas/source_fonts_spec.rb +0 -31
  103. data/spec/fontist/formulas/stix_fonts_spec.rb +0 -29
  104. data/spec/fontist/formulas/tahoma_font_spec.rb +0 -29
  105. data/spec/fontist/formulas/webding_font_spec.rb +0 -29
  106. data/spec/fontist/registry_spec.rb +0 -47
  107. data/spec/fontist/system_font_spec.rb +0 -44
  108. data/spec/fontist/utils/downloader_spec.rb +0 -35
  109. data/spec/fontist_spec.rb +0 -5
  110. data/spec/spec_helper.rb +0 -22
  111. data/spec/support/fontist_helper.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1f45a43c4f700cd793576c4783b7098beea7d366c8aeb2654fcc5b6a38c986b0
4
- data.tar.gz: 01ce25c4eae85e3fb20b7cdf0d106a04a2273e770a4261e937c344520a723651
3
+ metadata.gz: 02323a2a83176e79be999c101277ab2d777986b07185ca8d18bbd47c0bae88ec
4
+ data.tar.gz: c5909e4220f762be25a22fe776f4273ef2affa44b68c3f16d6d181b83cfcf287
5
5
  SHA512:
6
- metadata.gz: 6aae04a73aa89e5a7919430cecf56a8da1361bbe7b4a40a5676abe1ca02cc011e95681b7520a2d0ec3f47dd793af48c462f9deb1377b2547ba5d5edbc8c864e4
7
- data.tar.gz: 541d57da927636744955a5917ad39d57fe793bb37b0c31d167252da9efea8815c3675d2e998ed7ef585921415733e2b393de19f16be433d2ca62cfdbf0d00f02
6
+ metadata.gz: 831d21fc0882000bf30003193d8b4bacf8bbe002c8d07bebb1b36ab05cf552cbd844f0ddd0998beb59bc059e54ed365f92e79020c673130a90b61d3db515a2d7
7
+ data.tar.gz: 88f6a870cda4177824d9c5499250e5a45a088afc269e185a942c71bd02ea4589539473e72445a13c38265e7de091a6ca95ffcbde37c4bed08c87c251a02f4cb8
@@ -0,0 +1,28 @@
1
+ name: check_google
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 0 * * *'
6
+
7
+ jobs:
8
+ check:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - uses: actions/checkout@v2
13
+
14
+ - uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: 2.6
17
+
18
+ - name: Install otfinfo
19
+ run: sudo apt-get install lcdf-typetools
20
+
21
+ - name: Install bundler
22
+ run: gem install bundler
23
+
24
+ - name: Setup
25
+ run: bin/setup
26
+
27
+ - name: Check new fonts
28
+ run: TEST_ENV=CI bin/check_google
@@ -20,6 +20,9 @@ jobs:
20
20
  with:
21
21
  ruby-version: 2.6
22
22
 
23
+ - name: Install otfinfo
24
+ run: brew install lcdf-typetools
25
+
23
26
  - name: Install bundler
24
27
  run: gem install bundler
25
28
 
@@ -27,4 +27,4 @@ jobs:
27
27
  run: bin/setup
28
28
 
29
29
  - name: Run tests
30
- run: TEST_ENV=CI bin/rspec
30
+ run: TEST_ENV=CI bin/rspec --tag ~dev
@@ -29,4 +29,4 @@ jobs:
29
29
  bundle install --jobs 4 --retry 3
30
30
 
31
31
  - name: Run tests
32
- run: bundle exec rspec --tag ~skip_in_windows
32
+ run: bundle exec rspec --tag ~skip_in_windows --tag ~dev
data/.gitignore CHANGED
@@ -11,6 +11,12 @@ Gemfile.lock
11
11
  # fonts
12
12
  /spec/fixtures/fonts/*
13
13
  /spec/fixtures/fonts/DejaVuSerif.ttf
14
+ /spec/fixtures/formulas/
15
+ /spec/fixtures/*
16
+ !/spec/fixtures/system.yml
14
17
 
15
18
  # rspec failure tracking
16
19
  .rspec_status
20
+
21
+ # remote file cache
22
+ .rubocop-*
@@ -0,0 +1,2 @@
1
+ ruby:
2
+ config_file: .rubocop.yml
@@ -0,0 +1,22 @@
1
+ inherit_from:
2
+ - 'https://raw.githubusercontent.com/fontist/oss-guides/master/ci/rubocop.yml'
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - 'lib/fontist/import/google/fonts_public.pb.rb'
7
+ - 'lib/fontist/formula_template.rb'
8
+
9
+ Rails:
10
+ Enabled: false
11
+
12
+ Metrics/LineLength:
13
+ Exclude:
14
+ - 'lib/fontist/formulas/**/*.rb'
15
+
16
+ Layout/IndentFirstHashElement:
17
+ Exclude:
18
+ - 'lib/fontist/formulas/**/*.rb'
19
+
20
+ Layout/IndentHeredoc:
21
+ Exclude:
22
+ - 'lib/fontist/formulas/**/*.rb'
data/README.md CHANGED
@@ -26,6 +26,14 @@ Or install it yourself as:
26
26
  gem install fontist
27
27
  ```
28
28
 
29
+ ### Fetch formulas
30
+
31
+ After installation please fetch formulas to your system:
32
+
33
+ ```sh
34
+ fontist update
35
+ ```
36
+
29
37
  ## Usage
30
38
 
31
39
  ### Font
@@ -151,6 +159,50 @@ Run the test suite
151
159
  bin/rspec
152
160
  ```
153
161
 
162
+ ### Formulas storage
163
+
164
+ All formulas are kept in the [formulas][fontist-formulas] repository. If you'd
165
+ like to add a new one or change any existing, please refer to its documentation.
166
+
167
+ ### Auto-generate a formula
168
+
169
+ A formula could be generated from a fonts archive. Just specify a URL to the
170
+ archive:
171
+
172
+ ```sh
173
+ fontist create-formula https://www.latofonts.com/download/lato2ofl-zip/
174
+ cp lato.yml ~/.fontist/formulas/Formulas/
175
+ cd ~/.fontist/formulas
176
+ git add Formulas/lato.yml
177
+ git commit -m "Add Lato formula"
178
+ ```
179
+
180
+ ### Google Import
181
+
182
+ The library contains formulas for [Google Foonts][google-fonts]. A GHA workflow
183
+ checks for fonts update every day. In case an update is found, it could be
184
+ fetched to the library by:
185
+
186
+ ```
187
+ bin/import_google
188
+ ```
189
+
190
+ The script would update formulas which should be committed to a separate
191
+ repository [formulas][fontist-formulas]:
192
+
193
+ ```
194
+ cd ~/.fontist/formulas
195
+ git add Formulas/google
196
+ git commit -m "Google Fonts update"
197
+ git push
198
+ ```
199
+
200
+ ### TTC extraction
201
+
202
+ The stripttc script is used for extraction of TTC files. It's taken from the
203
+ https://github.com/DavidBarts/getfonts repository, and placed in the bin/
204
+ directory.
205
+
154
206
  ## Contributing
155
207
 
156
208
  First, thank you for contributing! We love pull requests from everyone. By
@@ -177,3 +229,5 @@ This gem is developed, maintained and funded by [Ribose Inc.][riboseinc]
177
229
  [issues]: https://github.com/fontist/fontist/issues
178
230
  [squash]: https://github.com/thoughtbot/guides/tree/master/protocol/git#write-a-feature
179
231
  [sandi-metz]: http://robots.thoughtbot.com/post/50655960596/sandi-metz-rules-for-developers
232
+ [fontist-formulas]: https://github.com/fontist/formulas
233
+ [google-fonts]: https://fonts.google.com
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fontist"
6
+ require "fontist/import/google_check"
7
+
8
+ Fontist::Import::GoogleCheck.new.call
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fontist"
6
+ require "fontist/import/convert_formulas"
7
+
8
+ Fontist::Import::ConvertFormulas.new.call
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "fontist"
5
+ require "fontist/cli"
6
+
7
+ status_code = Fontist::CLI.start(ARGV)
8
+ exit status_code.is_a?(Integer) ? status_code : 0
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fontist"
6
+ require "fontist/import/otfinfo_generate"
7
+
8
+ Fontist::Import::OtfinfoGenerate.new(ARGV[0]).call
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "fontist"
6
+ require "fontist/import/google_import"
7
+
8
+ Fontist::Import::GoogleImport.new.call
Binary file
@@ -13,21 +13,34 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = "https://github.com/fontist/fontist"
14
14
  spec.license = "BSD-2-Clause"
15
15
 
16
+ spec.post_install_message = "Please run `fontist update` to fetch formulas"
17
+
16
18
  spec.metadata["homepage_uri"] = spec.homepage
17
19
  spec.metadata["source_code_uri"] = "https://github.com/fontist/fontist"
18
20
  spec.metadata["changelog_uri"] = "https://github.com/fontist/fontist"
19
21
 
20
22
  spec.require_paths = ["lib"]
21
- spec.files = `git ls-files`.split("\n")
23
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
24
+ f.match(%r{^(test|spec|features)/})
25
+ end
26
+ spec.bindir = "bin"
27
+ spec.executables = ["fontist"]
22
28
  spec.test_files = `git ls-files -- {spec}/*`.split("\n")
23
29
 
24
30
  spec.add_runtime_dependency "down", "~> 5.0"
25
31
  spec.add_runtime_dependency "libmspack", "~> 0.1.0"
26
32
  spec.add_runtime_dependency "rubyzip", "~> 2.3.0"
33
+ spec.add_runtime_dependency "seven_zip_ruby", "~> 1.0"
34
+ spec.add_runtime_dependency "ruby-ole", "~> 1.0"
27
35
  spec.add_runtime_dependency "thor", "~> 1.0.1"
36
+ spec.add_runtime_dependency "git", "~> 1.0"
28
37
 
29
38
  spec.add_development_dependency "pry"
30
39
  spec.add_development_dependency "bundler", "~> 2.0"
31
40
  spec.add_development_dependency "rake", "~> 12.3.3"
32
41
  spec.add_development_dependency "rspec", "~> 3.0"
42
+ spec.add_development_dependency "rubocop", "0.75.0"
43
+ spec.add_development_dependency "rubocop-rails"
44
+ spec.add_development_dependency "rubocop-performance"
45
+ spec.add_development_dependency "ruby-protocol-buffers", "~> 1.0"
33
46
  end
@@ -12,6 +12,7 @@ require "fontist/registry"
12
12
  require "fontist/formulas"
13
13
  require "fontist/formula"
14
14
  require "fontist/system_font"
15
+ require "fontist/fontist_font"
15
16
 
16
17
  module Fontist
17
18
  def self.ui
@@ -34,19 +35,23 @@ module Fontist
34
35
  Fontist.fontist_path.join("fonts")
35
36
  end
36
37
 
38
+ def self.formulas_repo_path
39
+ Fontist.fontist_path.join("formulas")
40
+ end
41
+
42
+ def self.formulas_repo_url
43
+ "https://github.com/fontist/formulas.git"
44
+ end
45
+
37
46
  def self.formulas_path
38
- Fontist.lib_path.join("fontist", "formulas")
47
+ Fontist.formulas_repo_path.join("Formulas")
39
48
  end
40
- end
41
49
 
42
- # Loading formulas
43
- #
44
- # The formula loading behavior is dynamic, so what we are actualy
45
- # doing here is looking for formulas in the `./fontist/formulas` directory
46
- # then require thos as we go.
47
- #
48
- # There is a caviat, since the `Dir` method depends on absoulate path
49
- # so moving this loading up or somewhere else might not always ensure
50
- # the fontist related path helpers.
51
- #
52
- Dir[Fontist.formulas_path.join("**.rb").to_s].sort.each { |file| require file }
50
+ def self.downloads_path
51
+ Fontist.fontist_path.join("downloads")
52
+ end
53
+
54
+ def self.system_file_path
55
+ Fontist.lib_path.join("fontist", "system.yml")
56
+ end
57
+ end
@@ -0,0 +1,118 @@
1
+ require "thor"
2
+
3
+ module Fontist
4
+ class CLI < Thor
5
+ STATUS_SUCCESS = 0
6
+ STATUS_ERROR = 1
7
+
8
+ desc "install FONT", "Install font by font or formula"
9
+ def install(font)
10
+ fonts_paths = Fontist::Font.install(font)
11
+ Fontist.ui.success("These fonts are found or installed:")
12
+ Fontist.ui.success(fonts_paths.join("\n"))
13
+ STATUS_SUCCESS
14
+ rescue Fontist::Errors::NonSupportedFontError
15
+ Fontist.ui.error("Could not find font '#{font}'.")
16
+ STATUS_ERROR
17
+ end
18
+
19
+ desc "uninstall/remove FONT", "Uninstall font by font or formula"
20
+ def uninstall(font)
21
+ fonts_paths = Fontist::Font.uninstall(font)
22
+ Fontist.ui.success("These fonts are removed:")
23
+ Fontist.ui.success(fonts_paths.join("\n"))
24
+ STATUS_SUCCESS
25
+ rescue Fontist::Errors::MissingFontError => e
26
+ Fontist.ui.error(e.message)
27
+ STATUS_ERROR
28
+ rescue Fontist::Errors::NonSupportedFontError
29
+ Fontist.ui.error("Could not find font '#{font}'.")
30
+ STATUS_ERROR
31
+ end
32
+ map remove: :uninstall
33
+
34
+ desc "status [FONT]", "Show status of FONT or all fonts in fontist"
35
+ def status(font = nil)
36
+ formulas = Fontist::Font.status(font)
37
+ return error("No font is installed.") if formulas.empty?
38
+
39
+ print_formulas(formulas)
40
+ success
41
+ rescue Fontist::Errors::MissingFontError => e
42
+ error(e.message)
43
+ rescue Fontist::Errors::NonSupportedFontError
44
+ error("Could not find font '#{font}'.")
45
+ end
46
+
47
+ desc "list [FONT]", "List installation status of FONT or fonts in fontist"
48
+ def list(font = nil)
49
+ formulas = Fontist::Font.list(font)
50
+ print_list(formulas)
51
+ success
52
+ rescue Fontist::Errors::NonSupportedFontError
53
+ error("Could not find font '#{font}'.")
54
+ end
55
+
56
+ desc "update", "Update formulas"
57
+ def update
58
+ Formulas.fetch_formulas
59
+ Fontist.ui.say("Formulas have been successfully updated")
60
+ STATUS_SUCCESS
61
+ end
62
+
63
+ desc "create-formula URL", "Create a new formula with fonts from URL"
64
+ option :name, desc: "Example: Times New Roman"
65
+ option :mirror, repeatable: true
66
+ def create_formula(url)
67
+ require "fontist/import/create_formula"
68
+ name = Fontist::Import::CreateFormula.new(url, options).call
69
+ Fontist.ui.say("#{name} formula has been successfully created")
70
+ STATUS_SUCCESS
71
+ end
72
+
73
+ private
74
+
75
+ def success
76
+ STATUS_SUCCESS
77
+ end
78
+
79
+ def error(message)
80
+ Fontist.ui.error(message)
81
+ STATUS_ERROR
82
+ end
83
+
84
+ def print_formulas(formulas)
85
+ formulas.each do |formula, fonts|
86
+ Fontist.ui.success(formula.installer)
87
+
88
+ fonts.each do |font, styles|
89
+ Fontist.ui.success(" #{font.name}")
90
+
91
+ styles.each do |style, path|
92
+ Fontist.ui.success(" #{style.type} (#{path})")
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
99
+ def print_list(formulas)
100
+ formulas.each do |formula, fonts|
101
+ Fontist.ui.say(formula.installer)
102
+
103
+ fonts.each do |font, styles|
104
+ Fontist.ui.say(" #{font.name}")
105
+
106
+ styles.each do |style, installed|
107
+ if installed
108
+ Fontist.ui.success(" #{style.type} (installed)")
109
+ else
110
+ Fontist.ui.error(" #{style.type} (uninstalled)")
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
117
+ end
118
+ end
@@ -6,5 +6,8 @@ module Fontist
6
6
  class TamperedFileError < StandardError; end
7
7
  class InvalidResourceError < StandardError; end
8
8
  class TimeoutError < StandardError; end
9
+ class MissingAttributeError < StandardError; end
10
+ class FontNotFoundError < StandardError; end
11
+ class BinaryCallError < StandardError; end
9
12
  end
10
13
  end
@@ -19,6 +19,18 @@ module Fontist
19
19
  new(name: name, confirmation: confirmation).install
20
20
  end
21
21
 
22
+ def self.uninstall(name)
23
+ new(name: name).uninstall
24
+ end
25
+
26
+ def self.status(name)
27
+ new(name: name).status
28
+ end
29
+
30
+ def self.list(name)
31
+ new(name: name).list
32
+ end
33
+
22
34
  def find
23
35
  find_system_font || downloadable_font || raise(
24
36
  Fontist::Errors::NonSupportedFontError
@@ -31,6 +43,26 @@ module Fontist
31
43
  )
32
44
  end
33
45
 
46
+ def uninstall
47
+ uninstall_font || downloadable_font || raise(
48
+ Fontist::Errors::NonSupportedFontError
49
+ )
50
+ end
51
+
52
+ def status
53
+ return installed_statuses unless @name
54
+
55
+ font_status || downloadable_font || raise(
56
+ Fontist::Errors::NonSupportedFontError
57
+ )
58
+ end
59
+
60
+ def list
61
+ return all_list unless @name
62
+
63
+ font_list || raise(Fontist::Errors::NonSupportedFontError)
64
+ end
65
+
34
66
  def all
35
67
  Fontist::Formula.all.to_h.map { |_name, formula| formula.fonts }.flatten
36
68
  end
@@ -62,8 +94,8 @@ module Fontist
62
94
  if formula
63
95
  raise(
64
96
  Fontist::Errors::MissingFontError,
65
- "#{name}" "Fonts are missing, please run " \
66
- "Fontist::Font.install('#{name}', confirmation: 'yes') to " \
97
+ "#{name} fonts are missing, please run " \
98
+ "`fontist install '#{name}'` to " \
67
99
  "download the font."
68
100
  )
69
101
  end
@@ -109,5 +141,88 @@ module Fontist
109
141
  FONT LICENSE END ("#{name}")
110
142
  MSG
111
143
  end
144
+
145
+ def uninstall_font
146
+ paths = find_fontist_font
147
+ return unless paths
148
+
149
+ paths.each do |path|
150
+ File.delete(path)
151
+ end
152
+
153
+ paths
154
+ end
155
+
156
+ def find_fontist_font
157
+ Fontist::FontistFont.find(name)
158
+ end
159
+
160
+ def installed_statuses
161
+ installed_styles(all_formulas)
162
+ end
163
+
164
+ def all_formulas
165
+ Fontist::Formula.all.to_h.values
166
+ end
167
+
168
+ def font_status
169
+ return unless formula
170
+
171
+ statuses = installed_styles([formula])
172
+ statuses.empty? ? nil : statuses
173
+ end
174
+
175
+ def installed_styles(formulas)
176
+ filter_blank(formulas) do |formula|
177
+ filter_blank(formula.fonts) do |font|
178
+ filter_blank(font.styles) do |style|
179
+ path(style)
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ def filter_blank(elements)
186
+ elements.map { |e| [e, yield(e)] }
187
+ .to_h
188
+ .reject { |_k, v| v.nil? || v.empty? }
189
+ end
190
+
191
+ def path(style)
192
+ font_paths.grep(/#{style.font}/i).first
193
+ end
194
+
195
+ def font_paths
196
+ @font_paths ||= Dir.glob(Fontist.fonts_path.join("**"))
197
+ end
198
+
199
+ def all_list
200
+ list_styles(all_formulas)
201
+ end
202
+
203
+ def font_list
204
+ return unless formula
205
+
206
+ list_styles([formula])
207
+ end
208
+
209
+ def list_styles(formulas)
210
+ map_to_hash(formulas) do |formula|
211
+ map_to_hash(formula.fonts) do |font|
212
+ map_to_hash(font.styles) do |style|
213
+ installed(style)
214
+ end
215
+ end
216
+ end
217
+ end
218
+
219
+ def map_to_hash(elements)
220
+ elements.map { |e| [e, yield(e)] }.to_h
221
+ end
222
+
223
+ def installed(style)
224
+ path(style) ? true : false
225
+ end
226
+
112
227
  end
113
228
  end