fontist 0.4.0 → 1.3.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.
- checksums.yaml +4 -4
- data/.github/workflows/macosx.yml +1 -1
- data/.github/workflows/ubuntu.yml +1 -1
- data/.gitignore +4 -2
- data/README.md +87 -25
- data/fontist.gemspec +1 -0
- data/lib/fontist.rb +30 -13
- data/lib/fontist/errors.rb +3 -1
- data/lib/fontist/font.rb +113 -0
- data/lib/fontist/font_formula.rb +123 -0
- data/lib/fontist/formula.rb +90 -0
- data/lib/fontist/formulas.rb +10 -5
- data/lib/fontist/formulas/andale_font.rb +80 -0
- data/lib/fontist/formulas/arial_black_font.rb +79 -0
- data/lib/fontist/formulas/cleartype_fonts.rb +227 -0
- data/lib/fontist/formulas/comic_font.rb +78 -0
- data/lib/fontist/formulas/courier_font.rb +68 -12
- data/lib/fontist/formulas/euphemia_font.rb +85 -0
- data/lib/fontist/formulas/georgia_font.rb +80 -0
- data/lib/fontist/formulas/impact_font.rb +78 -0
- data/lib/fontist/formulas/montserrat_font.rb +132 -0
- data/lib/fontist/formulas/ms_truetype_fonts.rb +125 -0
- data/lib/fontist/formulas/open_sans_fonts.rb +263 -0
- data/lib/fontist/formulas/overpass_font.rb +73 -0
- data/lib/fontist/formulas/source_fonts.rb +109 -0
- data/lib/fontist/formulas/stix_fonts.rb +108 -0
- data/lib/fontist/formulas/tahoma_font.rb +147 -0
- data/lib/fontist/formulas/webding_font.rb +78 -0
- data/lib/fontist/registry.rb +43 -0
- data/lib/fontist/{data/source.yml → system.yml} +5 -8
- data/lib/fontist/system_font.rb +19 -14
- data/lib/fontist/utils.rb +10 -0
- data/lib/fontist/utils/downloader.rb +79 -0
- data/lib/fontist/utils/dsl.rb +77 -0
- data/lib/fontist/utils/exe_extractor.rb +72 -0
- data/lib/fontist/utils/ui.rb +15 -0
- data/lib/fontist/utils/zip_extractor.rb +38 -0
- data/lib/fontist/version.rb +1 -1
- data/spec/fontist/font_formula_spec.rb +67 -0
- data/spec/fontist/font_spec.rb +113 -0
- data/spec/fontist/formula_spec.rb +67 -0
- data/spec/fontist/formulas/andale_font_spec.rb +29 -0
- data/spec/fontist/formulas/arial_black_font_spec.rb +29 -0
- data/spec/fontist/formulas/cleartype_fonts_spec.rb +38 -0
- data/spec/fontist/formulas/comic_font_spec.rb +29 -0
- data/spec/fontist/formulas/courier_font_spec.rb +18 -19
- data/spec/fontist/formulas/euphemia_font_spec.rb +29 -0
- data/spec/fontist/formulas/georgia_font_spec.rb +29 -0
- data/spec/fontist/formulas/impact_font_spec.rb +29 -0
- data/spec/fontist/formulas/montserrat_font_spec.rb +29 -0
- data/spec/fontist/formulas/ms_truetype_fonts_spec.rb +29 -0
- data/spec/fontist/formulas/open_sans_fonts_spec.rb +29 -0
- data/spec/fontist/formulas/overpass_font_spec.rb +29 -0
- data/spec/fontist/formulas/source_fonts_spec.rb +31 -0
- data/spec/fontist/formulas/stix_fonts_spec.rb +29 -0
- data/spec/fontist/formulas/tahoma_font_spec.rb +29 -0
- data/spec/fontist/formulas/webding_font_spec.rb +29 -0
- data/spec/fontist/registry_spec.rb +47 -0
- data/spec/fontist/system_font_spec.rb +12 -7
- data/spec/fontist/{downloader_spec.rb → utils/downloader_spec.rb} +6 -5
- data/spec/spec_helper.rb +4 -2
- data/spec/support/fontist_helper.rb +4 -2
- metadata +62 -27
- data/lib/fontist/data/formulas/courier.yml +0 -26
- data/lib/fontist/data/formulas/ms_system.yml +0 -68
- data/lib/fontist/data/formulas/ms_vista.yml +0 -118
- data/lib/fontist/data/formulas/source_font.yml +0 -163
- data/lib/fontist/downloader.rb +0 -70
- data/lib/fontist/finder.rb +0 -45
- data/lib/fontist/formula_finder.rb +0 -94
- data/lib/fontist/formulas/base.rb +0 -72
- data/lib/fontist/formulas/helpers/exe_extractor.rb +0 -45
- data/lib/fontist/formulas/helpers/zip_extractor.rb +0 -36
- data/lib/fontist/formulas/ms_system.rb +0 -29
- data/lib/fontist/formulas/ms_vista.rb +0 -42
- data/lib/fontist/formulas/source_font.rb +0 -25
- data/lib/fontist/installer.rb +0 -42
- data/lib/fontist/source.rb +0 -58
- data/spec/fontist/finder_spec.rb +0 -41
- data/spec/fontist/formula_finder_spec.rb +0 -54
- data/spec/fontist/formulas/ms_system_spec.rb +0 -31
- data/spec/fontist/formulas/ms_vista_spec.rb +0 -27
- data/spec/fontist/formulas/source_font_spec.rb +0 -18
- data/spec/fontist/installer_spec.rb +0 -48
- data/spec/fontist/source_spec.rb +0 -24
@@ -6,18 +6,15 @@ system:
|
|
6
6
|
windows:
|
7
7
|
paths:
|
8
8
|
- C:/Windows/Fonts/**/**.{ttc,ttf}
|
9
|
+
- C:/Users/{username}/AppData/Local/Microsoft/Windows/Fonts/**/**.{ttc,ttf}
|
9
10
|
|
10
|
-
|
11
|
+
macos:
|
11
12
|
paths:
|
13
|
+
- /Library/Fonts/**/**.{ttf,ttc}
|
12
14
|
- /System/Library/Fonts/**/**.{ttf,ttc}
|
15
|
+
- /Users/{username}/Library/Fonts/**.{ttf,ttc}
|
16
|
+
- /Applications/Microsoft**/Contents/Resources/**/**.{ttf,ttc}
|
13
17
|
|
14
18
|
unix:
|
15
19
|
paths:
|
16
20
|
- /usr/share/fonts/**/**.{ttf,ttc}
|
17
|
-
|
18
|
-
remote:
|
19
|
-
formulas:
|
20
|
-
- ./formulas/ms_vista.yml
|
21
|
-
- ./formulas/ms_system.yml
|
22
|
-
- ./formulas/source_font.yml
|
23
|
-
- ./formulas/courier.yml
|
data/lib/fontist/system_font.rb
CHANGED
@@ -3,8 +3,6 @@ module Fontist
|
|
3
3
|
def initialize(font:, sources: nil)
|
4
4
|
@font = font
|
5
5
|
@user_sources = sources || []
|
6
|
-
|
7
|
-
check_or_create_fontist_path
|
8
6
|
end
|
9
7
|
|
10
8
|
def self.find(font, sources: [])
|
@@ -22,33 +20,32 @@ module Fontist
|
|
22
20
|
|
23
21
|
attr_reader :font, :user_sources
|
24
22
|
|
25
|
-
def
|
26
|
-
|
27
|
-
require "
|
28
|
-
|
23
|
+
def normalize_default_paths
|
24
|
+
@normalize_default_paths ||= default_sources["paths"].map do |path|
|
25
|
+
require "etc"
|
26
|
+
passwd = Etc.getpwuid
|
27
|
+
|
28
|
+
passwd ? path.gsub("{username}", passwd.name) : path
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def font_paths
|
33
33
|
Dir.glob((
|
34
34
|
user_sources +
|
35
|
-
|
35
|
+
normalize_default_paths +
|
36
36
|
[fontist_fonts_path.join("**")]
|
37
37
|
).flatten.uniq)
|
38
38
|
end
|
39
39
|
|
40
40
|
def lookup_using_font_name
|
41
|
-
font_names = map_name_to_valid_font_names
|
42
|
-
font_paths.grep(/#{font_names.join("|")}/i)
|
41
|
+
font_names = map_name_to_valid_font_names || []
|
42
|
+
font_paths.grep(/#{font_names.join("|")}/i) unless font_names.empty?
|
43
43
|
end
|
44
44
|
|
45
45
|
def fontist_fonts_path
|
46
46
|
@fontist_fonts_path ||= Fontist.fonts_path
|
47
47
|
end
|
48
48
|
|
49
|
-
def default_sources
|
50
|
-
@default_sources ||= Source.all.system[user_os.to_s]
|
51
|
-
end
|
52
49
|
|
53
50
|
def user_os
|
54
51
|
@user_os ||= (
|
@@ -57,7 +54,7 @@ module Fontist
|
|
57
54
|
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
58
55
|
:windows
|
59
56
|
when /darwin|mac os/
|
60
|
-
:
|
57
|
+
:macos
|
61
58
|
when /linux/
|
62
59
|
:linux
|
63
60
|
when /solaris|bsd/
|
@@ -69,8 +66,16 @@ module Fontist
|
|
69
66
|
end
|
70
67
|
|
71
68
|
def map_name_to_valid_font_names
|
72
|
-
fonts =
|
69
|
+
fonts = Formula.find_fonts(font)
|
73
70
|
fonts.map { |font| font.styles.map(&:font) }.flatten if fonts
|
74
71
|
end
|
72
|
+
|
73
|
+
def system_path_file
|
74
|
+
File.open(Fontist.lib_path.join("fontist", "system.yml"))
|
75
|
+
end
|
76
|
+
|
77
|
+
def default_sources
|
78
|
+
@default_sources ||= YAML.load(system_path_file)["system"][user_os.to_s]
|
79
|
+
end
|
75
80
|
end
|
76
81
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Utils
|
3
|
+
class Downloader
|
4
|
+
def initialize(file, file_size: nil, sha: nil, progress_bar: nil)
|
5
|
+
# TODO: If the first mirror fails, try the second one
|
6
|
+
@file = file
|
7
|
+
@sha = [sha].flatten.compact
|
8
|
+
@progress_bar = set_progress_bar(progress_bar)
|
9
|
+
@file_size = (file_size || default_file_size).to_i
|
10
|
+
end
|
11
|
+
|
12
|
+
def download
|
13
|
+
file = download_file
|
14
|
+
|
15
|
+
if !sha.empty? && !sha.include?(Digest::SHA256.file(file).to_s)
|
16
|
+
raise(Fontist::Errors::TamperedFileError.new(
|
17
|
+
"The downloaded file from #{@file} doesn't " \
|
18
|
+
"match with the expected sha256 checksum!"
|
19
|
+
))
|
20
|
+
end
|
21
|
+
|
22
|
+
file
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.download(file, options = {})
|
26
|
+
new(file, options).download
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :file, :sha, :file_size
|
32
|
+
|
33
|
+
def default_file_size
|
34
|
+
5 * byte_to_megabyte
|
35
|
+
end
|
36
|
+
|
37
|
+
def byte_to_megabyte
|
38
|
+
@byte_to_megabyte ||= 1024 * 1024
|
39
|
+
end
|
40
|
+
|
41
|
+
def download_path
|
42
|
+
options[:download_path] || Fontist.root_path.join("tmp")
|
43
|
+
end
|
44
|
+
|
45
|
+
def set_progress_bar(progress_bar)
|
46
|
+
ENV.fetch("TEST_ENV", "") === "CI" ? false : progress_bar
|
47
|
+
end
|
48
|
+
|
49
|
+
def download_file
|
50
|
+
bar = ProgressBar.new(file_size / byte_to_megabyte)
|
51
|
+
|
52
|
+
Down.download(
|
53
|
+
@file,
|
54
|
+
open_timeout: 10,
|
55
|
+
read_timeout: 10,
|
56
|
+
progress_proc: -> (progress) {
|
57
|
+
bar.increment(progress / byte_to_megabyte) if @progress_bar === true
|
58
|
+
}
|
59
|
+
)
|
60
|
+
|
61
|
+
rescue Down::NotFound
|
62
|
+
raise(Fontist::Errors::InvalidResourceError.new("Invalid URL: #{@file}"))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
class ProgressBar
|
67
|
+
def initialize(total)
|
68
|
+
@counter = 1
|
69
|
+
@total = total
|
70
|
+
end
|
71
|
+
|
72
|
+
def increment(progress)
|
73
|
+
complete = sprintf("%#.2f%%", ((@counter.to_f / @total.to_f) * 100))
|
74
|
+
print "\r\e[0KDownloads: #{@counter}MB/#{@total}MB (#{complete})"
|
75
|
+
@counter = progress
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Utils
|
3
|
+
module Dsl
|
4
|
+
def key(key)
|
5
|
+
instance.key = key
|
6
|
+
end
|
7
|
+
|
8
|
+
def desc(description)
|
9
|
+
instance.description = description
|
10
|
+
end
|
11
|
+
|
12
|
+
def homepage(homepage)
|
13
|
+
instance.homepage = homepage
|
14
|
+
end
|
15
|
+
|
16
|
+
def resource(resource_name, &block)
|
17
|
+
instance.resources[resource_name] ||= {}
|
18
|
+
instance.temp_resource = instance.resources[resource_name]
|
19
|
+
|
20
|
+
yield(block) if block_given?
|
21
|
+
instance.temp_resource = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def url(url)
|
25
|
+
instance.temp_resource.merge!(urls: [url])
|
26
|
+
end
|
27
|
+
|
28
|
+
def urls(urls = [])
|
29
|
+
instance.temp_resource.merge!(urls: urls)
|
30
|
+
end
|
31
|
+
|
32
|
+
def sha256(sha256)
|
33
|
+
instance.temp_resource.merge!(sha256: sha256)
|
34
|
+
end
|
35
|
+
|
36
|
+
def file_size(file_size)
|
37
|
+
instance.temp_resource.merge!(file_size: file_size )
|
38
|
+
end
|
39
|
+
|
40
|
+
def provides_font_collection(name = nil, &block)
|
41
|
+
instance.temp_resource = {}
|
42
|
+
yield(block) if block_given?
|
43
|
+
instance.temp_resource = {}
|
44
|
+
end
|
45
|
+
|
46
|
+
def filename(name)
|
47
|
+
instance.temp_resource.merge!(filename: name)
|
48
|
+
end
|
49
|
+
|
50
|
+
def provides_font(font, options = {})
|
51
|
+
font_styles = instance.extract_font_styles(options)
|
52
|
+
instance.font_list.push(name: font, styles: font_styles)
|
53
|
+
end
|
54
|
+
|
55
|
+
def test
|
56
|
+
end
|
57
|
+
|
58
|
+
def requires_license_agreement(license)
|
59
|
+
instance.license = license
|
60
|
+
instance.license_required = true
|
61
|
+
end
|
62
|
+
|
63
|
+
def open_license(license)
|
64
|
+
instance.license = license
|
65
|
+
instance.license_required = false
|
66
|
+
end
|
67
|
+
|
68
|
+
def license_url(url)
|
69
|
+
instance.license_url = url
|
70
|
+
end
|
71
|
+
|
72
|
+
def display_progress_bar(value )
|
73
|
+
instance.options = (instance.options || {}).merge(progress_bar: value )
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Fontist
|
2
|
+
module Utils
|
3
|
+
module ExeExtractor
|
4
|
+
def cab_extract(exe_file, download: true, font_ext: /.tt|.ttc/i)
|
5
|
+
download = @downloaded === true ? false : download
|
6
|
+
|
7
|
+
exe_file = download_file(exe_file).path if download
|
8
|
+
cab_file = decompressor.search(exe_file)
|
9
|
+
cabbed_fonts = grep_fonts(cab_file.files, font_ext) || []
|
10
|
+
fonts_paths = extract_cabbed_fonts_to_assets(cabbed_fonts)
|
11
|
+
|
12
|
+
yield(fonts_paths) if block_given?
|
13
|
+
end
|
14
|
+
|
15
|
+
def exe_extract(source)
|
16
|
+
cab_file = decompressor.search(download_file(source).path)
|
17
|
+
yield(build_cab_file_hash(cab_file.files)) if block_given?
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def decompressor
|
23
|
+
@decompressor ||= (
|
24
|
+
require "libmspack"
|
25
|
+
LibMsPack::CabDecompressor.new
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def grep_fonts(file, font_ext)
|
30
|
+
Array.new.tap do |fonts|
|
31
|
+
while file
|
32
|
+
fonts.push(file) if file.filename.match(font_ext)
|
33
|
+
file = file.next
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def extract_cabbed_fonts_to_assets(cabbed_fonts)
|
39
|
+
Array.new.tap do |fonts|
|
40
|
+
cabbed_fonts.each do |font|
|
41
|
+
font_path = fonts_path.join(font.filename).to_s
|
42
|
+
decompressor.extract(font, font_path)
|
43
|
+
|
44
|
+
fonts.push(font_path)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def build_cab_file_hash(file)
|
50
|
+
Hash.new.tap do |cab_files|
|
51
|
+
while file
|
52
|
+
filename = file.filename
|
53
|
+
if filename.include?("cab")
|
54
|
+
file_path = temp_dir.join(filename).to_s
|
55
|
+
|
56
|
+
decompressor.extract(file, file_path)
|
57
|
+
cab_files[filename.to_s] = file_path
|
58
|
+
end
|
59
|
+
|
60
|
+
file = file.next
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def temp_dir
|
66
|
+
@temp_dir ||= raise(
|
67
|
+
NotImplementedError.new("You must implement this method"),
|
68
|
+
)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "zip"
|
2
|
+
require "pathname"
|
3
|
+
|
4
|
+
module Fontist
|
5
|
+
module Utils
|
6
|
+
module ZipExtractor
|
7
|
+
def zip_extract(resource, download: true, fonts_sub_dir: "")
|
8
|
+
zip_file = download_file(resource) if download
|
9
|
+
zip_file ||= resource.urls.first
|
10
|
+
|
11
|
+
fonts_paths = unzip_fonts(zip_file, fonts_sub_dir)
|
12
|
+
block_given? ? yield(fonts_paths) : fonts_paths
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :unzip, :zip_extract
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def unzip_fonts(file, fonts_sub_dir = "")
|
20
|
+
Zip.on_exists_proc = true
|
21
|
+
Array.new.tap do |fonts|
|
22
|
+
|
23
|
+
Zip::File.open(file) do |zip_file|
|
24
|
+
zip_file.glob("#{fonts_sub_dir}*.{ttf,ttc,otf}").each do |entry|
|
25
|
+
if entry.name
|
26
|
+
filename = Pathname.new(entry.name).basename
|
27
|
+
font_path = fonts_path.join(filename.to_s)
|
28
|
+
fonts.push(font_path.to_s)
|
29
|
+
|
30
|
+
entry.extract(font_path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/fontist/version.rb
CHANGED
@@ -0,0 +1,67 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
RSpec.describe "Fontist::Formulas::DemoFormula" do
|
4
|
+
describe "initialization" do
|
5
|
+
it "registers formula resources through the DSL" do
|
6
|
+
formula = Fontist::Formulas::DemoFormula.instance
|
7
|
+
resource = formula.resources["demo-formula"]
|
8
|
+
demo_font = formula.font_list.first
|
9
|
+
|
10
|
+
expect(formula.key).to eq(:demo_formula)
|
11
|
+
expect(formula.license_required).to be_truthy
|
12
|
+
expect(formula.description).to eq("Demo font formula")
|
13
|
+
expect(formula.license).to eq("Vendor specific font licences")
|
14
|
+
expect(formula.homepage).to eq("https://github.com/fontist/fontist")
|
15
|
+
|
16
|
+
expect(resource[:file_size]).to eq("1234567890")
|
17
|
+
expect(resource[:urls].first).to eq("https://github.com/fontist/fontist")
|
18
|
+
expect(resource[:sha256]).to eq("594e0f42e6581add4dead70c1dfb9")
|
19
|
+
|
20
|
+
expect(demo_font[:styles].count).to eq(2)
|
21
|
+
expect(demo_font[:name]).to eq("Demo font")
|
22
|
+
expect(demo_font[:styles].first[:font]).to eq("demo-font.ttf")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "method invokation" do
|
27
|
+
it "invokes the correct method for installation" do
|
28
|
+
expect {
|
29
|
+
Fontist::Formulas::DemoFormula.fetch_font("Demo font", confirmation: "yes")
|
30
|
+
}.not_to raise_error
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Fontist
|
35
|
+
module Formulas
|
36
|
+
class DemoFormula < FontFormula
|
37
|
+
key :demo_formula
|
38
|
+
desc "Demo font formula"
|
39
|
+
homepage "https://github.com/fontist/fontist"
|
40
|
+
requires_license_agreement "Vendor specific font licences"
|
41
|
+
|
42
|
+
resource "demo-formula" do
|
43
|
+
urls [ "https://github.com/fontist/fontist" ]
|
44
|
+
sha256 "594e0f42e6581add4dead70c1dfb9"
|
45
|
+
file_size "1234567890"
|
46
|
+
end
|
47
|
+
|
48
|
+
provides_font "Demo font", match_styles_from_file: {
|
49
|
+
"Regular" => "demo-font.ttf",
|
50
|
+
"Italic" => "demo-fonti.ttf"
|
51
|
+
}
|
52
|
+
|
53
|
+
provides_font_collection("Meiryo Bold") do |coll|
|
54
|
+
filename "demo-font.ttc"
|
55
|
+
provides_font "Demo collection", extract_styles_from_collection: {
|
56
|
+
"Regular" => "demo-col-font.ttf",
|
57
|
+
"Italic" => "demo-col-fonti.ttf"
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
def extract
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|