fontist 0.4.0 → 1.0.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/macosx.yml +1 -1
  3. data/.github/workflows/ubuntu.yml +1 -1
  4. data/.gitignore +4 -2
  5. data/README.md +87 -25
  6. data/lib/fontist.rb +28 -13
  7. data/lib/fontist/downloader.rb +11 -11
  8. data/lib/fontist/errors.rb +1 -0
  9. data/lib/fontist/font.rb +78 -0
  10. data/lib/fontist/font_formula.rb +116 -0
  11. data/lib/fontist/formula.rb +90 -0
  12. data/lib/fontist/formulas.rb +10 -5
  13. data/lib/fontist/formulas/andale_font.rb +79 -0
  14. data/lib/fontist/formulas/arial_black_font.rb +78 -0
  15. data/lib/fontist/formulas/cleartype_fonts.rb +225 -0
  16. data/lib/fontist/formulas/comic_font.rb +77 -0
  17. data/lib/fontist/formulas/courier_font.rb +67 -12
  18. data/lib/fontist/formulas/euphemia_font.rb +85 -0
  19. data/lib/fontist/formulas/georgia_font.rb +79 -0
  20. data/lib/fontist/formulas/impact_font.rb +77 -0
  21. data/lib/fontist/formulas/montserrat_font.rb +132 -0
  22. data/lib/fontist/formulas/ms_truetype_fonts.rb +124 -0
  23. data/lib/fontist/formulas/open_sans_fonts.rb +263 -0
  24. data/lib/fontist/formulas/overpass_font.rb +73 -0
  25. data/lib/fontist/formulas/source_fonts.rb +109 -0
  26. data/lib/fontist/formulas/stix_fonts.rb +108 -0
  27. data/lib/fontist/formulas/tahoma_font.rb +147 -0
  28. data/lib/fontist/formulas/webding_font.rb +77 -0
  29. data/lib/fontist/registry.rb +42 -0
  30. data/lib/fontist/{data/source.yml → system.yml} +0 -7
  31. data/lib/fontist/system_font.rb +9 -13
  32. data/lib/fontist/utils.rb +8 -0
  33. data/lib/fontist/utils/dsl.rb +73 -0
  34. data/lib/fontist/utils/exe_extractor.rb +72 -0
  35. data/lib/fontist/utils/zip_extractor.rb +38 -0
  36. data/lib/fontist/version.rb +1 -1
  37. data/spec/fontist/downloader_spec.rb +2 -1
  38. data/spec/fontist/font_formula_spec.rb +67 -0
  39. data/spec/fontist/font_spec.rb +87 -0
  40. data/spec/fontist/formula_spec.rb +67 -0
  41. data/spec/fontist/formulas/andale_font_spec.rb +29 -0
  42. data/spec/fontist/formulas/arial_black_font_spec.rb +29 -0
  43. data/spec/fontist/formulas/cleartype_fonts_spec.rb +38 -0
  44. data/spec/fontist/formulas/comic_font_spec.rb +29 -0
  45. data/spec/fontist/formulas/courier_font_spec.rb +18 -19
  46. data/spec/fontist/formulas/euphemia_font_spec.rb +29 -0
  47. data/spec/fontist/formulas/georgia_font_spec.rb +29 -0
  48. data/spec/fontist/formulas/impact_font_spec.rb +29 -0
  49. data/spec/fontist/formulas/montserrat_font_spec.rb +29 -0
  50. data/spec/fontist/formulas/ms_truetype_fonts_spec.rb +29 -0
  51. data/spec/fontist/formulas/open_sans_fonts_spec.rb +29 -0
  52. data/spec/fontist/formulas/overpass_font_spec.rb +29 -0
  53. data/spec/fontist/formulas/source_fonts_spec.rb +31 -0
  54. data/spec/fontist/formulas/stix_fonts_spec.rb +29 -0
  55. data/spec/fontist/formulas/tahoma_font_spec.rb +29 -0
  56. data/spec/fontist/formulas/webding_font_spec.rb +29 -0
  57. data/spec/fontist/registry_spec.rb +47 -0
  58. data/spec/fontist/system_font_spec.rb +6 -6
  59. data/spec/spec_helper.rb +4 -2
  60. data/spec/support/fontist_helper.rb +4 -2
  61. metadata +45 -25
  62. data/lib/fontist/data/formulas/courier.yml +0 -26
  63. data/lib/fontist/data/formulas/ms_system.yml +0 -68
  64. data/lib/fontist/data/formulas/ms_vista.yml +0 -118
  65. data/lib/fontist/data/formulas/source_font.yml +0 -163
  66. data/lib/fontist/finder.rb +0 -45
  67. data/lib/fontist/formula_finder.rb +0 -94
  68. data/lib/fontist/formulas/base.rb +0 -72
  69. data/lib/fontist/formulas/helpers/exe_extractor.rb +0 -45
  70. data/lib/fontist/formulas/helpers/zip_extractor.rb +0 -36
  71. data/lib/fontist/formulas/ms_system.rb +0 -29
  72. data/lib/fontist/formulas/ms_vista.rb +0 -42
  73. data/lib/fontist/formulas/source_font.rb +0 -25
  74. data/lib/fontist/installer.rb +0 -42
  75. data/lib/fontist/source.rb +0 -58
  76. data/spec/fontist/finder_spec.rb +0 -41
  77. data/spec/fontist/formula_finder_spec.rb +0 -54
  78. data/spec/fontist/formulas/ms_system_spec.rb +0 -31
  79. data/spec/fontist/formulas/ms_vista_spec.rb +0 -27
  80. data/spec/fontist/formulas/source_font_spec.rb +0 -18
  81. data/spec/fontist/installer_spec.rb +0 -48
  82. data/spec/fontist/source_spec.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ba98ed24043b39252548b63233baad24570d02b80cc97d46da8e6f82b80abc3
4
- data.tar.gz: 0412c264ac03becf765a3c81dad018dcd0ac3607fbe48b58469453a043740d9f
3
+ metadata.gz: 8dbc313275aceace35c9a4f5e39bf17af46e8d0c2d661f4270909c36d6dc855e
4
+ data.tar.gz: 8abacb5373f59f3e0df5fae5baeb2a81adfab4eb40a5ae55a12867c4da646d88
5
5
  SHA512:
6
- metadata.gz: a1761bd0c41b66ee758204ee2219505604a8d644cdd96409d7544c8bb528726528e91f9057c4edab6fc7721f336c13a80e5442d7fd148ccb299040f3bface750
7
- data.tar.gz: 7c0889d2f66affbe7c9e4f1f798051fd72305c7f89760469e01d1bb7d037d104c143eabbaff0be1bdd83f6e398898cadac9cee090579cdbdbf0eda4f3dc0c448
6
+ metadata.gz: d5b234dcafb1ad011c508b1972b2b0ba79aa0222cdc5117d6c47250f2a8e4f3ec62f9404ac039ee8452b88aa050200201d1b3957e2ff70c7da1f54556b82a41a
7
+ data.tar.gz: 49dc8f923c050fc6d793fe5a24315e75728e5baa9c50cb97ca596641d4344d301bdab3bd96b0e6f7157b745daaa78e5755325e22d2dc97dd72aff6bf4ddae8d4
@@ -27,4 +27,4 @@ jobs:
27
27
  run: bin/setup
28
28
 
29
29
  - name: Run tests
30
- run: bin/rspec
30
+ run: TEST_ENV=CI bin/rspec
@@ -27,4 +27,4 @@ jobs:
27
27
  run: bin/setup
28
28
 
29
29
  - name: Run tests
30
- run: bin/rspec
30
+ run: TEST_ENV=CI bin/rspec
data/.gitignore CHANGED
@@ -7,8 +7,10 @@
7
7
  /spec/reports/
8
8
  /tmp/
9
9
  Gemfile.lock
10
- /assets/*
11
- !/assets/fonts/.keep
10
+
11
+ # fonts
12
+ /spec/fixtures/fonts/*
13
+ /spec/fixtures/fonts/DejaVuSerif.ttf
12
14
 
13
15
  # rspec failure tracking
14
16
  .rspec_status
data/README.md CHANGED
@@ -28,40 +28,102 @@ gem install fontist
28
28
 
29
29
  ## Usage
30
30
 
31
- ### Find a font
31
+ ### Font
32
32
 
33
- The fontist library allows us to easily locate or download a any of the supported
34
- fonts and then it returns the complete path for the path. To find any font in a
35
- user's system we can use the following interface.
33
+ The `Fontist::Font` is your go to place to deal with any font using fontist. This
34
+ interface will allow you to find a font or install a font. Lets start with how
35
+ can we find a font in your system.
36
+
37
+ #### Finding a font
38
+
39
+ The `Fontist::Fontist.find` interface can be used a find a font in your system.
40
+ It will look into the operating system specific font directories, and also the
41
+ fontist specific `~/.fontist` directory.
36
42
 
37
43
  ```ruby
38
- Fontist::Finder.find("Calibri")
44
+ Fontist::Font.find(name)
39
45
  ```
40
46
 
41
- ### Supported fonts
47
+ If fontist find a font then it will return the paths, but if not found then it
48
+ will could raise an unsupported font error or maybe an installation instruction
49
+ for that specific font.
50
+
51
+ #### Install a font
52
+
53
+ The `Fontist::Font.install` interface can be used to install any supported font.
54
+ This interface first checks if you already have that font installed or not and
55
+ if you do then it will return the paths.
56
+
57
+ If you don't but supported by fontist, then it will download the font and copy
58
+ it to `~/.fontist` directory and also return the paths.
42
59
 
43
60
  ```ruby
44
- [
45
- "Arial",
46
- "Calibri",
47
- "Cambria",
48
- "Candara",
49
- "Consola",
50
- "Constantia",
51
- "Corbel",
52
- "Courier",
53
- "Meiryo",
54
- "Meiryo UI",
55
- "Source Code Pro",
56
- "Source Han Sans",
57
- "Source Sans Pro",
58
- "Source Serif Pro",
59
- "Times New Roman",
60
- "Trebuchet",
61
- "Verdana"
62
- ]
61
+ Fontist::Font.install(name, confirmation: "no")
63
62
  ```
64
63
 
64
+ If there are some issue with the provided font, like not supported or some other
65
+ issue then it will raise those errors.
66
+
67
+ #### List all fonts
68
+
69
+ The `Fontist::Font` interface exposes an interface to list all supported fonts,
70
+ this might be useful if want to know the name of the font or the available
71
+ styles. You can do that by using:
72
+
73
+ ```ruby
74
+ Fontist::Font.all
75
+ ```
76
+
77
+ The return values are ` OpenStruct` object, so you can easily do any other
78
+ operation you would do in any ruby object.
79
+
80
+ ### Formula
81
+
82
+ The `fontist` gem internally usages the `Fontist::Formula` interface to find a
83
+ registered formula or fonts supported by any formula. Unless, you need to do
84
+ anything with that you shouldn't need to work with this interface directly. But
85
+ if you do then these are the public interface it offers.
86
+
87
+ #### Find a formula
88
+
89
+ The `Fontist::Formula.find` interface allows you to find any of the registered
90
+ formula. This interface takes a font name as an argument and it looks through
91
+ each of the registered formula that offers this font installation. Usages:
92
+
93
+ ```ruby
94
+ Fontist::Formula.find("Calibri")
95
+ ```
96
+
97
+ The above method will find which formula offers this font and then it will
98
+ return a installable formula that can be used to check licences or install that
99
+ fonts in your system.
100
+
101
+ #### Find formula fonts
102
+
103
+ Normally, each font name can be associated with multiple styles or collection, for
104
+ example the `Calibri` font might contains a `regular`, `bola` or `italic` styles
105
+ fonts and if you want a interface that can return the complete list then this is
106
+ your friend. You can use it as following:
107
+
108
+ ```ruby
109
+ Fontist::Formula.find_fonts("Calibri")
110
+ ```
111
+
112
+
113
+ #### List all formulas
114
+
115
+ The `Fontist::Formula` interface exposes an interface to list all registered
116
+ font formula. This might be useful if want to know the name of the formula or
117
+ what type fonts can be installed using that formula. Usages:
118
+
119
+ ```ruby
120
+ Fontist::Formula.all
121
+ ```
122
+
123
+ The return values are ` OpenStruct` object, so you can easily do any other
124
+ operation you would do in any ruby object.
125
+
126
+
65
127
  ## Development
66
128
 
67
129
  We are following Sandi Metz's Rules for this gem, you can read the
@@ -1,12 +1,19 @@
1
+ require "down"
2
+ require "digest"
3
+ require "json"
4
+ require "yaml"
5
+ require "singleton"
6
+
1
7
  require "fontist/errors"
2
8
  require "fontist/version"
3
9
 
4
- require "fontist/finder"
5
- require "fontist/source"
6
- require "fontist/installer"
7
- require "fontist/system_font"
10
+ require "fontist/font"
11
+ require "fontist/downloader"
12
+
13
+ require "fontist/registry"
8
14
  require "fontist/formulas"
9
- require "fontist/formula_finder"
15
+ require "fontist/formula"
16
+ require "fontist/system_font"
10
17
 
11
18
  module Fontist
12
19
  def self.lib_path
@@ -17,14 +24,6 @@ module Fontist
17
24
  Pathname.new(File.dirname(__dir__))
18
25
  end
19
26
 
20
- def self.assets_path
21
- Fontist.root_path.join("assets")
22
- end
23
-
24
- def self.data_path
25
- Fontist.lib_path.join("fontist", "data")
26
- end
27
-
28
27
  def self.fontist_path
29
28
  Pathname.new(Dir.home).join(".fontist")
30
29
  end
@@ -32,4 +31,20 @@ module Fontist
32
31
  def self.fonts_path
33
32
  Fontist.fontist_path.join("fonts")
34
33
  end
34
+
35
+ def self.formulas_path
36
+ Fontist.lib_path.join("fontist", "formulas")
37
+ end
35
38
  end
39
+
40
+ # Loading formulas
41
+ #
42
+ # The formula loading behavior is dynamic, so what we are actualy
43
+ # doing here is looking for formulas in the `./fontist/formulas` directory
44
+ # then require thos as we go.
45
+ #
46
+ # There is a caviat, since the `Dir` method depends on absoulate path
47
+ # so moving this loading up or somewhere else might not always ensure
48
+ # the fontist related path helpers.
49
+ #
50
+ Dir[Fontist.formulas_path.join("**.rb").to_s].sort.each { |file| require file }
@@ -1,26 +1,23 @@
1
- require "down"
2
- require "digest"
3
-
4
1
  module Fontist
5
2
  class Downloader
6
3
  def initialize(file, file_size: nil, sha: nil, progress: nil)
7
- @sha = sha
8
4
  @file = file
9
5
  @progress = progress
6
+ @sha = [sha].flatten.compact
10
7
  @file_size = (file_size || default_file_size).to_i
11
8
  end
12
9
 
13
10
  def download
14
11
  file = download_file
15
- verify_file_checksum(file) || raise_invalid_file
16
- end
17
12
 
18
- def verify_file_checksum(file)
19
- file if Digest::SHA256.file(file) === sha
20
- end
13
+ if !sha.empty? && !sha.include?(Digest::SHA256.file(file).to_s)
14
+ raise(Fontist::Errors::TemparedFileError.new(
15
+ "The downloaded file from #{@file} doesn't " \
16
+ "match with the expected sha256 checksum!"
17
+ ))
18
+ end
21
19
 
22
- def raise_invalid_file
23
- raise(Fontist::Errors::TemparedFileError)
20
+ file
24
21
  end
25
22
 
26
23
  def self.download(file, options = {})
@@ -52,6 +49,9 @@ module Fontist
52
49
  bar.increment(progress / byte_to_megabyte) if @progress === true
53
50
  }
54
51
  )
52
+
53
+ rescue Down::NotFound
54
+ raise(Fontist::Errors::InvalidResourceError.new("Invalid URL: #{@file}"))
55
55
  end
56
56
  end
57
57
 
@@ -4,5 +4,6 @@ module Fontist
4
4
  class MissingFontError < StandardError; end
5
5
  class NonSupportedFontError < StandardError; end
6
6
  class TemparedFileError < StandardError; end
7
+ class InvalidResourceError < StandardError; end
7
8
  end
8
9
  end
@@ -0,0 +1,78 @@
1
+ module Fontist
2
+ class Font
3
+ def initialize(options = {})
4
+ @name = options.fetch(:name, nil)
5
+ @confirmation = options.fetch(:confirmation, "no")
6
+
7
+ check_or_create_fontist_path!
8
+ end
9
+
10
+ def self.all
11
+ new.all
12
+ end
13
+
14
+ def self.find(name)
15
+ new(name: name).find
16
+ end
17
+
18
+ def self.install(name, confirmation: "no")
19
+ new(name: name, confirmation: confirmation).install
20
+ end
21
+
22
+ def find
23
+ find_system_font || downloadable_font || raise(
24
+ Fontist::Errors::NonSupportedFontError
25
+ )
26
+ end
27
+
28
+ def install
29
+ find_system_font || download_font || raise(
30
+ Fontist::Errors::NonSupportedFontError
31
+ )
32
+ end
33
+
34
+ def all
35
+ Fontist::Formula.all.to_h.map { |_name, formula| formula.fonts }.flatten
36
+ end
37
+
38
+ private
39
+
40
+ attr_reader :name, :confirmation
41
+
42
+ def find_system_font
43
+ Fontist::SystemFont.find(name)
44
+ end
45
+
46
+ def check_or_create_fontist_path!
47
+ unless Fontist.fonts_path.exist?
48
+ require "fileutils"
49
+ FileUtils.mkdir_p(Fontist.fonts_path)
50
+ end
51
+ end
52
+
53
+ def font_installer(formula)
54
+ Object.const_get(formula.installer)
55
+ end
56
+
57
+ def formula
58
+ @formula ||= Fontist::Formula.find(name)
59
+ end
60
+
61
+ def downloadable_font
62
+ if formula
63
+ raise(
64
+ Fontist::Errors::MissingFontError,
65
+ "Fonts are missing, please run " \
66
+ "Fontist::Font.install('#{name}', confirmation: 'yes') to " \
67
+ "download the font"
68
+ )
69
+ end
70
+ end
71
+
72
+ def download_font
73
+ if formula
74
+ font_installer(formula).fetch_font(name, confirmation: confirmation)
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,116 @@
1
+ module Fontist
2
+ class FontFormula
3
+ include Singleton
4
+ extend Fontist::Utils::Dsl
5
+ include Fontist::Utils::ZipExtractor
6
+ include Fontist::Utils::ExeExtractor
7
+
8
+ attr_accessor :license, :license_url, :license_required
9
+ attr_accessor :key, :homepage, :description, :temp_resource
10
+
11
+ def font_list
12
+ @font_list ||= []
13
+ end
14
+
15
+ def resources
16
+ @resources ||= {}
17
+ end
18
+
19
+ def fonts
20
+ @fonts ||= font_list.uniq
21
+ end
22
+
23
+ def extract_font_styles(options)
24
+ extract_from_file(options) ||
25
+ extract_from_collection(options) || default_font
26
+ end
27
+
28
+ def reinitialize
29
+ @downloaded = false
30
+ @matched_fonts = []
31
+ end
32
+
33
+ def self.fetch_font(name, confirmation:)
34
+ if instance.license_required && confirmation.downcase != "yes"
35
+ raise(Fontist::Errors::LicensingError)
36
+ end
37
+
38
+ instance.reinitialize
39
+ instance.install_font(name, confirmation)
40
+ end
41
+
42
+ def install_font(name, confirmation)
43
+ run_in_temp_dir { extract }
44
+ matched_fonts_uniq = matched_fonts.flatten.uniq
45
+ matched_fonts_uniq.empty? ? nil : matched_fonts_uniq
46
+ end
47
+
48
+ private
49
+
50
+ attr_reader :downloaded, :matched_fonts
51
+
52
+ def resource(name, &block)
53
+ source = resources[name]
54
+ block_given? ? yield(source) : source
55
+ end
56
+
57
+ def fonts_path
58
+ @fonts_path ||= Fontist.fonts_path
59
+ end
60
+
61
+ def default_font
62
+ [{ type: "Regular", font: temp_resource[:filename] }]
63
+ end
64
+
65
+ def run_in_temp_dir(&block)
66
+ Dir.mktmpdir(nil, Dir.tmpdir) do |dir|
67
+ @temp_dir = Pathname.new(dir)
68
+
69
+ yield
70
+ @temp_dir = nil
71
+ end
72
+ end
73
+
74
+ def extract_from_file(options)
75
+ styles = options.fetch(:match_styles_from_file, [])
76
+
77
+ unless styles.empty?
78
+ styles.map { |type, file | { type: type, font: file } }
79
+ end
80
+ end
81
+
82
+ def match_fonts(fonts_dir, font_name)
83
+ fonts = map_names_to_fonts(font_name).join("|")
84
+ font = fonts_dir.grep(/#{fonts}/i)
85
+ @matched_fonts.push(font) if font
86
+
87
+ font
88
+ end
89
+
90
+ def extract_from_collection(options)
91
+ styles = options.fetch(:extract_styles_from_collection, [])
92
+
93
+ unless styles.empty?
94
+ styles.map do |type, file|
95
+ { type: type, collection: file, font: temp_resource[:filename] }
96
+ end
97
+ end
98
+ end
99
+
100
+ def map_names_to_fonts(font_name)
101
+ fonts = Fontist::Formula.find_fonts(font_name)
102
+ fonts = fonts.map { |font| font.styles.map(&:font) }.flatten if fonts
103
+
104
+ fonts || []
105
+ end
106
+
107
+ def download_file(source)
108
+ downloaded_file = Fontist::Downloader.download(
109
+ source[:urls].sample, sha: source[:sha256], file_size: source[:file_size]
110
+ )
111
+
112
+ @downloaded = true
113
+ downloaded_file
114
+ end
115
+ end
116
+ end