hyde-fonts 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/hyde_fonts/font_data.rb +24 -0
- data/lib/hyde_fonts/font_face.rb +38 -0
- data/lib/hyde_fonts/font_ruleset.rb +28 -0
- data/lib/hyde_fonts/font_variant.rb +18 -0
- data/lib/hyde_fonts/generated_css_file.rb +33 -0
- data/lib/hyde_fonts/generated_font_file.rb +34 -0
- data/lib/hyde_fonts/hyde_fonts.rb +111 -0
- data/lib/hyde_fonts/provider_google.rb +71 -0
- data/lib/hyde_fonts.rb +8 -0
- metadata +72 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ef7f7a15334f4df1f96be84e4c34b6e5b63500170c559ec590e36379c03695f3
|
4
|
+
data.tar.gz: f3cfdf6988e1de02511abce55f29c39a940c4090140c323971fda3aa8ca2005d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 07d8d6fdd0a29e3d458d40ec1ccff14d4952b94891b3c5aee73405d626943e894e38b8a3b9182241e6b4e7e12d25dda210f5407e3b28fa196d9ada950f29c14f
|
7
|
+
data.tar.gz: 65ccfe4b9510c92d7a05b700f4dbb84ac1fe456fa2893f58637c9d2c87a72c30c1b52b8ef66909f78613be732705041f9c533c2d2d2b885dcb4ac0e19e8e05cc
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Hyde
|
2
|
+
class FontData
|
3
|
+
attr_reader :faces
|
4
|
+
|
5
|
+
def initialize(data)
|
6
|
+
@data = data
|
7
|
+
@faces = []
|
8
|
+
@sizes = []
|
9
|
+
|
10
|
+
return unless @data
|
11
|
+
|
12
|
+
parse_faces
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_faces
|
16
|
+
|
17
|
+
for face in @data['faces'] do
|
18
|
+
faces.push(Hyde::FontFace.new(face))
|
19
|
+
end
|
20
|
+
|
21
|
+
return faces
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Hyde
|
2
|
+
class FontFace
|
3
|
+
attr_reader :provider
|
4
|
+
attr_accessor :css
|
5
|
+
|
6
|
+
def initialize(face)
|
7
|
+
@name = face['name']
|
8
|
+
@provider = face['provider']
|
9
|
+
@weights = face['weights']
|
10
|
+
@variants = parse_variants
|
11
|
+
@css = []
|
12
|
+
end
|
13
|
+
|
14
|
+
def sort_variants
|
15
|
+
@variants.sort do |a, b|
|
16
|
+
(a.italic == b.italic) ? a.weight <=> b.weight : a.italic <=> b.italic
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
variants = sort_variants.map { |variant| variant.to_s }
|
22
|
+
|
23
|
+
@name + ':ital,wght@' + variants.join(';')
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def parse_variants
|
29
|
+
variants = []
|
30
|
+
|
31
|
+
for variant in @weights
|
32
|
+
variants.push(Hyde::FontVariant.new(weight: variant['value'], italic: variant['italic']))
|
33
|
+
end
|
34
|
+
|
35
|
+
return variants
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Hyde
|
2
|
+
class FontRuleset
|
3
|
+
attr_reader :filename, :char_set, :family, :style, :weight, :uri, :format, :ruleset, :local_rule_set
|
4
|
+
|
5
|
+
def initialize(raw_css_ruleset)
|
6
|
+
@ruleset = raw_css_ruleset
|
7
|
+
|
8
|
+
/\/\* (?'character_set'.*) \*\// =~ raw_css_ruleset
|
9
|
+
/^\s*font-family:\s'(?'family'[\w]*)';$/ =~ raw_css_ruleset
|
10
|
+
/^\s*font-style:\s(?'style'[\w]*);$/ =~ raw_css_ruleset
|
11
|
+
/^\s*font-weight:\s(?'weight'[\w]*);$/ =~ raw_css_ruleset
|
12
|
+
/\s\ssrc:\surl\((?'uri'.*)\)\s.*\('(?'format'.*)'\);$$/ =~ raw_css_ruleset
|
13
|
+
|
14
|
+
@char_set = character_set
|
15
|
+
@family = family
|
16
|
+
@style = style
|
17
|
+
@weight = weight
|
18
|
+
@uri = URI(uri)
|
19
|
+
@format = format
|
20
|
+
|
21
|
+
@filename = [@family, @style, @weight, @char_set + '.' + @format].join('_')
|
22
|
+
end
|
23
|
+
|
24
|
+
def local_ruleset(path)
|
25
|
+
@ruleset.gsub(/(?<=url\().*(?=\)\s)/, '/' + File.join(path, @filename))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Hyde
|
2
|
+
class FontVariant
|
3
|
+
attr_reader :italic, :weight
|
4
|
+
|
5
|
+
def initialize(weight:, italic:)
|
6
|
+
@weight = weight
|
7
|
+
@italic = 0
|
8
|
+
|
9
|
+
if italic == true
|
10
|
+
@italic = 1
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
@italic.to_s + ',' + @weight.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Hyde
|
2
|
+
# Alternative class for jekyll's static files
|
3
|
+
# this allows the creation of files without a source file
|
4
|
+
|
5
|
+
class GeneratedCssFile < Jekyll::StaticFile
|
6
|
+
attr_accessor :file_contents
|
7
|
+
attr_reader :generator, :x
|
8
|
+
|
9
|
+
def initialize(site, dir, name)
|
10
|
+
@site = site
|
11
|
+
@dir = dir
|
12
|
+
@name = name
|
13
|
+
@relative_path = File.join(*[@dir, @name].compact)
|
14
|
+
@extname = File.extname(@name)
|
15
|
+
@type = @collection&.label&.to_sym
|
16
|
+
@generator = 'hyde_fonts'
|
17
|
+
end
|
18
|
+
|
19
|
+
def write(dest)
|
20
|
+
dest_path = destination(dest)
|
21
|
+
return false if File.exist?(dest_path)
|
22
|
+
|
23
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
24
|
+
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
25
|
+
|
26
|
+
File.open(dest_path, 'w') do |output_file|
|
27
|
+
output_file << file_contents
|
28
|
+
end
|
29
|
+
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Hyde
|
2
|
+
# Alternative class for jekyll's static files
|
3
|
+
# this allows the creation of files without a source file
|
4
|
+
|
5
|
+
class GeneratedFontFile < Jekyll::StaticFile
|
6
|
+
attr_accessor :file_contents
|
7
|
+
attr_reader :generator, :dest_path
|
8
|
+
|
9
|
+
def initialize(site, dir, name)
|
10
|
+
@site = site
|
11
|
+
@dir = dir
|
12
|
+
@name = name
|
13
|
+
@relative_path = File.join(*[@dir, @name].compact)
|
14
|
+
@extname = File.extname(@name)
|
15
|
+
@type = @collection&.label&.to_sym
|
16
|
+
@generator = 'hyde_fonts'
|
17
|
+
@dest_path = ''
|
18
|
+
end
|
19
|
+
|
20
|
+
def write(dest)
|
21
|
+
return false if File.exist?(dest_path)
|
22
|
+
|
23
|
+
@dest_path = destination(dest)
|
24
|
+
FileUtils.mkdir_p(File.dirname(dest_path))
|
25
|
+
FileUtils.rm(dest_path) if File.exist?(dest_path)
|
26
|
+
|
27
|
+
File.open(dest_path, 'w') do |output_file|
|
28
|
+
output_file << file_contents
|
29
|
+
end
|
30
|
+
|
31
|
+
true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'jekyll'
|
2
|
+
require_relative 'font_data.rb'
|
3
|
+
require_relative 'font_face.rb'
|
4
|
+
require_relative 'font_ruleset.rb'
|
5
|
+
require_relative 'font_variant.rb'
|
6
|
+
require_relative 'generated_css_file.rb'
|
7
|
+
require_relative 'generated_font_file.rb'
|
8
|
+
require_relative 'provider_google.rb'
|
9
|
+
|
10
|
+
module Jekyll
|
11
|
+
class HydeFontsTag < Liquid::Tag
|
12
|
+
def initialize(tag_name, text, tokens)
|
13
|
+
super
|
14
|
+
|
15
|
+
@tag_name = tag_name
|
16
|
+
@text = text.strip
|
17
|
+
@tokens = tokens
|
18
|
+
end
|
19
|
+
|
20
|
+
def render(context)
|
21
|
+
config = context.registers[:site].config['hyde_fonts']
|
22
|
+
return unless config['enable'] == true
|
23
|
+
|
24
|
+
file = context.registers[:site].static_files.find { |file|
|
25
|
+
file.is_a?(Hyde::GeneratedCssFile)
|
26
|
+
}
|
27
|
+
|
28
|
+
if @text == 'inline'
|
29
|
+
file.file_contents
|
30
|
+
else
|
31
|
+
"<link href='" + file.relative_path + "' rel='stylesheet'>"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Liquid::Template.register_tag('hyde_fonts', Jekyll::HydeFontsTag)
|
37
|
+
|
38
|
+
class HydeFontsGenerator < Generator
|
39
|
+
def generate(site)
|
40
|
+
Hyde::Fonts.new(site).generate()
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module Hyde
|
46
|
+
class Fonts
|
47
|
+
@@config = {
|
48
|
+
"data_path" => 'fonts',
|
49
|
+
"file_output_path" => 'assets/fonts',
|
50
|
+
"css_output_name" => 'fonts.css',
|
51
|
+
"css_minify" => true,
|
52
|
+
"enable" => true,
|
53
|
+
"fetch_fonts" => true,
|
54
|
+
"keep_files" => false
|
55
|
+
}
|
56
|
+
|
57
|
+
def initialize(site)
|
58
|
+
@site = site
|
59
|
+
@config = site.config.dig('hyde_fonts') || @@config
|
60
|
+
|
61
|
+
if config('keep_files') == true
|
62
|
+
@site.config['keep_files'].push(config('file_output_path'))
|
63
|
+
end
|
64
|
+
|
65
|
+
if site.config.dig('hyde_fonts').nil?
|
66
|
+
@site.config['hyde_fonts'] = @config
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def generate
|
71
|
+
# get faces from jekyll data file
|
72
|
+
font_data = Hyde::FontData.new(data)
|
73
|
+
|
74
|
+
# handle font providers
|
75
|
+
for face in font_data.faces
|
76
|
+
case face.provider
|
77
|
+
when 'google'
|
78
|
+
Hyde::FontProviderGoogle.new(@site, @config).fetch(face)
|
79
|
+
when 'local'
|
80
|
+
# TODO handle local fonts
|
81
|
+
# Hyde::FontProviderLocal.new(@site, @config).fetch(face)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
css = font_data.faces.map { |face| face.css }
|
86
|
+
# generate static file containing face css rulesets
|
87
|
+
css_file = Hyde::GeneratedCssFile.new(@site, config('file_output_path'), config('css_output_name'))
|
88
|
+
css_file.file_contents = minify(css.join("\n"))
|
89
|
+
|
90
|
+
@site.static_files << css_file
|
91
|
+
end
|
92
|
+
|
93
|
+
private
|
94
|
+
|
95
|
+
def config(*keys)
|
96
|
+
@config.dig(*keys)
|
97
|
+
end
|
98
|
+
|
99
|
+
def data
|
100
|
+
@site.data.dig(config('data_path'), 'fonts')
|
101
|
+
end
|
102
|
+
|
103
|
+
def minify(css)
|
104
|
+
return css if config('css_minify') == false
|
105
|
+
|
106
|
+
converter_config = { 'sass' => { 'style' => 'compressed' } }
|
107
|
+
|
108
|
+
Jekyll::Converters::Scss.new(converter_config).convert(css)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module Hyde
|
5
|
+
class FontProviderGoogle
|
6
|
+
def initialize(site, config)
|
7
|
+
@site = site
|
8
|
+
@config = config
|
9
|
+
end
|
10
|
+
|
11
|
+
def fetch(face)
|
12
|
+
@face = face
|
13
|
+
|
14
|
+
begin
|
15
|
+
uri_payload = Net::HTTP.get(face_uri, {
|
16
|
+
"User-Agent": 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/117.0'
|
17
|
+
})
|
18
|
+
rescue
|
19
|
+
Jekyll.logger.warn('Fonts Warning:', 'Unable to reach Google Fonts service.')
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
rulesets = parse_css_payload(uri_payload)
|
24
|
+
|
25
|
+
# TODO if @config['fetch_fonts'] is false, don't download the files
|
26
|
+
|
27
|
+
for ruleset in rulesets
|
28
|
+
fetch_font_from_ruleset(ruleset)
|
29
|
+
face.css.push(rewrite_ruleset_to_local(ruleset))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def face_uri
|
36
|
+
google_uri_base = 'https://fonts.googleapis.com/css2'
|
37
|
+
params = [['display', 'swap']]
|
38
|
+
params.push(['family', @face.to_s])
|
39
|
+
|
40
|
+
uri = google_uri_base + '?' + params.map { |param| param.join('=') }.join('&')
|
41
|
+
|
42
|
+
URI(uri)
|
43
|
+
end
|
44
|
+
|
45
|
+
def parse_css_payload(css)
|
46
|
+
css.scan(/\/\*[^}]*}/).map do |raw_ruleset|
|
47
|
+
Hyde::FontRuleset.new(raw_ruleset)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def fetch_font_from_ruleset(ruleset)
|
52
|
+
filename = ruleset.filename
|
53
|
+
file = Hyde::GeneratedFontFile.new(@site, @config['file_output_path'], filename)
|
54
|
+
|
55
|
+
destination_fname = file.destination('./')
|
56
|
+
|
57
|
+
if @config['keep_files'] == true
|
58
|
+
return if File.exist?(destination_fname)
|
59
|
+
end
|
60
|
+
|
61
|
+
font_uri_payload = Net::HTTP.get(ruleset.uri)
|
62
|
+
file.file_contents = font_uri_payload
|
63
|
+
|
64
|
+
@site.static_files << file
|
65
|
+
end
|
66
|
+
|
67
|
+
def rewrite_ruleset_to_local(ruleset)
|
68
|
+
ruleset.local_ruleset(@config['file_output_path'])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/hyde_fonts.rb
ADDED
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hyde-fonts
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Gregory Daynes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-12-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: jekyll
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5.0'
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.0'
|
33
|
+
description: Hyde Fonts is a plugin for Jekyll to make adding Google fonts based on
|
34
|
+
configuration.
|
35
|
+
email: email@gregdaynes.com
|
36
|
+
executables: []
|
37
|
+
extensions: []
|
38
|
+
extra_rdoc_files: []
|
39
|
+
files:
|
40
|
+
- lib/hyde_fonts.rb
|
41
|
+
- lib/hyde_fonts/font_data.rb
|
42
|
+
- lib/hyde_fonts/font_face.rb
|
43
|
+
- lib/hyde_fonts/font_ruleset.rb
|
44
|
+
- lib/hyde_fonts/font_variant.rb
|
45
|
+
- lib/hyde_fonts/generated_css_file.rb
|
46
|
+
- lib/hyde_fonts/generated_font_file.rb
|
47
|
+
- lib/hyde_fonts/hyde_fonts.rb
|
48
|
+
- lib/hyde_fonts/provider_google.rb
|
49
|
+
homepage: https://gregdaynes.com
|
50
|
+
licenses:
|
51
|
+
- MIT
|
52
|
+
metadata: {}
|
53
|
+
post_install_message:
|
54
|
+
rdoc_options: []
|
55
|
+
require_paths:
|
56
|
+
- lib
|
57
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
requirements: []
|
68
|
+
rubygems_version: 3.4.6
|
69
|
+
signing_key:
|
70
|
+
specification_version: 4
|
71
|
+
summary: Plugin for jekyll to manage google fonts
|
72
|
+
test_files: []
|