fontist 0.4.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) 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/fontist.gemspec +1 -0
  7. data/lib/fontist.rb +30 -13
  8. data/lib/fontist/errors.rb +3 -1
  9. data/lib/fontist/font.rb +113 -0
  10. data/lib/fontist/font_formula.rb +123 -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 +80 -0
  14. data/lib/fontist/formulas/arial_black_font.rb +79 -0
  15. data/lib/fontist/formulas/cleartype_fonts.rb +227 -0
  16. data/lib/fontist/formulas/comic_font.rb +78 -0
  17. data/lib/fontist/formulas/courier_font.rb +68 -12
  18. data/lib/fontist/formulas/euphemia_font.rb +85 -0
  19. data/lib/fontist/formulas/georgia_font.rb +80 -0
  20. data/lib/fontist/formulas/impact_font.rb +78 -0
  21. data/lib/fontist/formulas/montserrat_font.rb +132 -0
  22. data/lib/fontist/formulas/ms_truetype_fonts.rb +125 -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 +78 -0
  29. data/lib/fontist/registry.rb +43 -0
  30. data/lib/fontist/{data/source.yml → system.yml} +5 -8
  31. data/lib/fontist/system_font.rb +19 -14
  32. data/lib/fontist/utils.rb +10 -0
  33. data/lib/fontist/utils/downloader.rb +79 -0
  34. data/lib/fontist/utils/dsl.rb +77 -0
  35. data/lib/fontist/utils/exe_extractor.rb +72 -0
  36. data/lib/fontist/utils/ui.rb +15 -0
  37. data/lib/fontist/utils/zip_extractor.rb +38 -0
  38. data/lib/fontist/version.rb +1 -1
  39. data/spec/fontist/font_formula_spec.rb +67 -0
  40. data/spec/fontist/font_spec.rb +113 -0
  41. data/spec/fontist/formula_spec.rb +67 -0
  42. data/spec/fontist/formulas/andale_font_spec.rb +29 -0
  43. data/spec/fontist/formulas/arial_black_font_spec.rb +29 -0
  44. data/spec/fontist/formulas/cleartype_fonts_spec.rb +38 -0
  45. data/spec/fontist/formulas/comic_font_spec.rb +29 -0
  46. data/spec/fontist/formulas/courier_font_spec.rb +18 -19
  47. data/spec/fontist/formulas/euphemia_font_spec.rb +29 -0
  48. data/spec/fontist/formulas/georgia_font_spec.rb +29 -0
  49. data/spec/fontist/formulas/impact_font_spec.rb +29 -0
  50. data/spec/fontist/formulas/montserrat_font_spec.rb +29 -0
  51. data/spec/fontist/formulas/ms_truetype_fonts_spec.rb +29 -0
  52. data/spec/fontist/formulas/open_sans_fonts_spec.rb +29 -0
  53. data/spec/fontist/formulas/overpass_font_spec.rb +29 -0
  54. data/spec/fontist/formulas/source_fonts_spec.rb +31 -0
  55. data/spec/fontist/formulas/stix_fonts_spec.rb +29 -0
  56. data/spec/fontist/formulas/tahoma_font_spec.rb +29 -0
  57. data/spec/fontist/formulas/webding_font_spec.rb +29 -0
  58. data/spec/fontist/registry_spec.rb +47 -0
  59. data/spec/fontist/system_font_spec.rb +12 -7
  60. data/spec/fontist/{downloader_spec.rb → utils/downloader_spec.rb} +6 -5
  61. data/spec/spec_helper.rb +4 -2
  62. data/spec/support/fontist_helper.rb +4 -2
  63. metadata +62 -27
  64. data/lib/fontist/data/formulas/courier.yml +0 -26
  65. data/lib/fontist/data/formulas/ms_system.yml +0 -68
  66. data/lib/fontist/data/formulas/ms_vista.yml +0 -118
  67. data/lib/fontist/data/formulas/source_font.yml +0 -163
  68. data/lib/fontist/downloader.rb +0 -70
  69. data/lib/fontist/finder.rb +0 -45
  70. data/lib/fontist/formula_finder.rb +0 -94
  71. data/lib/fontist/formulas/base.rb +0 -72
  72. data/lib/fontist/formulas/helpers/exe_extractor.rb +0 -45
  73. data/lib/fontist/formulas/helpers/zip_extractor.rb +0 -36
  74. data/lib/fontist/formulas/ms_system.rb +0 -29
  75. data/lib/fontist/formulas/ms_vista.rb +0 -42
  76. data/lib/fontist/formulas/source_font.rb +0 -25
  77. data/lib/fontist/installer.rb +0 -42
  78. data/lib/fontist/source.rb +0 -58
  79. data/spec/fontist/finder_spec.rb +0 -41
  80. data/spec/fontist/formula_finder_spec.rb +0 -54
  81. data/spec/fontist/formulas/ms_system_spec.rb +0 -31
  82. data/spec/fontist/formulas/ms_vista_spec.rb +0 -27
  83. data/spec/fontist/formulas/source_font_spec.rb +0 -18
  84. data/spec/fontist/installer_spec.rb +0 -48
  85. 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: 1f45a43c4f700cd793576c4783b7098beea7d366c8aeb2654fcc5b6a38c986b0
4
+ data.tar.gz: 01ce25c4eae85e3fb20b7cdf0d106a04a2273e770a4261e937c344520a723651
5
5
  SHA512:
6
- metadata.gz: a1761bd0c41b66ee758204ee2219505604a8d644cdd96409d7544c8bb528726528e91f9057c4edab6fc7721f336c13a80e5442d7fd148ccb299040f3bface750
7
- data.tar.gz: 7c0889d2f66affbe7c9e4f1f798051fd72305c7f89760469e01d1bb7d037d104c143eabbaff0be1bdd83f6e398898cadac9cee090579cdbdbf0eda4f3dc0c448
6
+ metadata.gz: 6aae04a73aa89e5a7919430cecf56a8da1361bbe7b4a40a5676abe1ca02cc011e95681b7520a2d0ec3f47dd793af48c462f9deb1377b2547ba5d5edbc8c864e4
7
+ data.tar.gz: 541d57da927636744955a5917ad39d57fe793bb37b0c31d167252da9efea8815c3675d2e998ed7ef585921415733e2b393de19f16be433d2ca62cfdbf0d00f02
@@ -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
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
  spec.add_runtime_dependency "down", "~> 5.0"
25
25
  spec.add_runtime_dependency "libmspack", "~> 0.1.0"
26
26
  spec.add_runtime_dependency "rubyzip", "~> 2.3.0"
27
+ spec.add_runtime_dependency "thor", "~> 1.0.1"
27
28
 
28
29
  spec.add_development_dependency "pry"
29
30
  spec.add_development_dependency "bundler", "~> 2.0"
@@ -1,14 +1,23 @@
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/registry"
8
12
  require "fontist/formulas"
9
- require "fontist/formula_finder"
13
+ require "fontist/formula"
14
+ require "fontist/system_font"
10
15
 
11
16
  module Fontist
17
+ def self.ui
18
+ Fontist::Utils::UI
19
+ end
20
+
12
21
  def self.lib_path
13
22
  Fontist.root_path.join("lib")
14
23
  end
@@ -17,14 +26,6 @@ module Fontist
17
26
  Pathname.new(File.dirname(__dir__))
18
27
  end
19
28
 
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
29
  def self.fontist_path
29
30
  Pathname.new(Dir.home).join(".fontist")
30
31
  end
@@ -32,4 +33,20 @@ module Fontist
32
33
  def self.fonts_path
33
34
  Fontist.fontist_path.join("fonts")
34
35
  end
36
+
37
+ def self.formulas_path
38
+ Fontist.lib_path.join("fontist", "formulas")
39
+ end
35
40
  end
41
+
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 }
@@ -3,6 +3,8 @@ module Fontist
3
3
  class LicensingError < StandardError; end
4
4
  class MissingFontError < StandardError; end
5
5
  class NonSupportedFontError < StandardError; end
6
- class TemparedFileError < StandardError; end
6
+ class TamperedFileError < StandardError; end
7
+ class InvalidResourceError < StandardError; end
8
+ class TimeoutError < StandardError; end
7
9
  end
8
10
  end
@@ -0,0 +1,113 @@
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
+ "#{name}" "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
+ check_and_confirm_required_license(formula)
75
+ font_installer(formula).fetch_font(name, confirmation: confirmation)
76
+ end
77
+ end
78
+
79
+ def check_and_confirm_required_license(formula)
80
+ if formula.license_required && !confirmation.casecmp("yes").zero?
81
+ @confirmation = show_license_and_ask_for_input(formula.license)
82
+
83
+ if !confirmation.casecmp("yes").zero?
84
+ raise Fontist::Errors::LicensingError.new(
85
+ "Fontist will not download these fonts unless you accept the terms."
86
+ )
87
+ end
88
+ end
89
+ end
90
+
91
+ def show_license_and_ask_for_input(license)
92
+ Fontist.ui.say(license_agrement_message(license))
93
+ Fontist.ui.ask(
94
+ "\nDo you accept all presented font licenses, and want Fontist " \
95
+ "to download these fonts for you? => TYPE 'Yes' or 'No':"
96
+ )
97
+ end
98
+
99
+ def license_agrement_message(license)
100
+ <<~MSG
101
+ FONT LICENSE ACCEPTANCE REQUIRED FOR "#{name}":
102
+
103
+ Fontist can install this font if you accept its licensing conditions.
104
+
105
+ FONT LICENSE BEGIN ("#{name}")
106
+ -----------------------------------------------------------------------
107
+ #{license}
108
+ -----------------------------------------------------------------------
109
+ FONT LICENSE END ("#{name}")
110
+ MSG
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,123 @@
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, :options, :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::Utils::Downloader.download(
109
+ source[:urls].first,
110
+ sha: source[:sha256],
111
+ file_size: source[:file_size],
112
+ progress_bar: is_progress_bar_enabled
113
+ )
114
+
115
+ @downloaded = true
116
+ downloaded_file
117
+ end
118
+
119
+ def is_progress_bar_enabled
120
+ options.nil? ? false : options.fetch(:progress_bar, false)
121
+ end
122
+ end
123
+ end