152 lines
3.9 KiB
Ruby
152 lines
3.9 KiB
Ruby
require 'json'
|
|
require 'active_support/all'
|
|
require 'fileutils'
|
|
require 'shellwords'
|
|
|
|
class ::Metadata2FontsCss < ::Middleman::Extension
|
|
def initialize app, **options_hash, &block
|
|
super
|
|
@additional_extentions = %w[woff]
|
|
end
|
|
def included() true end
|
|
alias registered included
|
|
class <<self
|
|
def included() true end
|
|
alias registered included
|
|
end
|
|
|
|
FontFace = <<EOF.gsub( /^\s*(.*?)\s*$/, '\1').gsub /\n/m, ''
|
|
@font-face {
|
|
font-family: "%<name>s";
|
|
font-weight: %<weight>i;
|
|
font-style: %<style>s;
|
|
src:
|
|
local("%<fullName>s"),
|
|
local("%<postScriptName>s"),
|
|
url("%<woff>s") format("woff"),
|
|
url("%<ttf>s") format("truetype");
|
|
}
|
|
EOF
|
|
|
|
def manipulate_resource_list resources
|
|
fonts_css = StringIO.new
|
|
resources.lazy.
|
|
select {|res| Pathname.new( res.path).basename.to_s == 'METADATA.json' }.
|
|
map do |res|
|
|
JSON.parse( File.read( f))['fonts'].each do |font|
|
|
font = font.symbolize_keys
|
|
font[:ttf] = "/assets/fonts/#{font[:filename]}"
|
|
font[:woff] = "/assets/fonts/#{font[:filename].gsub /\.[ot]tf\Z/, '.woff'}"
|
|
fonts_css.printf FontFace, font
|
|
end
|
|
end
|
|
|
|
resources.delete_if do |res|
|
|
path = Pathname.new res.path
|
|
if 'assets' == path.descend.first.to_s
|
|
case path.basename.to_s
|
|
when 'METADATA.pb' then true
|
|
when 'METADATA.json' then true
|
|
when 'DESCRIPTION.en_us.html' then true
|
|
when 'OFL.txt' then true
|
|
else false
|
|
end
|
|
else false
|
|
end
|
|
end
|
|
|
|
resources << ::Middleman::Sitemap::StringResource.new(
|
|
self.app.sitemap,
|
|
'assets/styles/fonts.css',
|
|
fonts_css.string)
|
|
|
|
resources
|
|
end
|
|
end
|
|
|
|
::Middleman::Extensions.register :fonts_css, ::Metadata2FontsCss
|
|
|
|
class ::Fonts4Web < ::Middleman::Extension
|
|
def initialize app, **options_hash, &block
|
|
super
|
|
@converter = 'sfnt2woff-zopfli'
|
|
@cachepath = Pathname.new '.fonts_cache'
|
|
end
|
|
def included() true end
|
|
alias registered included
|
|
class <<self
|
|
def included() true end
|
|
alias registered included
|
|
end
|
|
|
|
def spawn *a, **options
|
|
a = a.map &:to_s
|
|
if options[:verbose]
|
|
pre = ''
|
|
pre = "cd #{Shellwords.escape options[:chdir]}; " if options.has_key? :chdir
|
|
STDERR.puts "$ #{pre}#{a.shelljoin}"
|
|
end
|
|
options.delete :verbose
|
|
options[:chdir] &&= options[:chdir].to_s
|
|
pid = Process.spawn *a, **options
|
|
_, status = Process.wait2 pid
|
|
status
|
|
end
|
|
|
|
def convert builder, src, dest = nil
|
|
# files:
|
|
f = src.basename
|
|
d = Pathname.new "#{src.basename src.extname}.woff"
|
|
|
|
# files in cache:
|
|
symlink = @cachepath + f
|
|
cache_dest = @cachepath + d
|
|
relsrc = src.expand_path.relative_path_from @cachepath.expand_path
|
|
dest = dest ? Pathname.new( dest) : cache_dest
|
|
|
|
@cachepath.mkpath
|
|
|
|
# dest is not older than src, we can use the cache
|
|
if dest.exist? and dest.lstat >= src.lstat
|
|
builder.trigger :identical, "#{dest}"
|
|
return dest
|
|
end
|
|
|
|
# cache_dest is older than source
|
|
unless cache_dest.exist? and cache_dest.lstat >= src.lstat
|
|
# prepare cache-files:
|
|
symlink.unlink if begin symlink.lstat; rescue Errno::ENOENT; false; end
|
|
symlink.make_symlink relsrc
|
|
|
|
# convert:
|
|
status = spawn @converter, symlink.basename, chdir: symlink.dirname
|
|
raise "Convertion #{src} failed!" unless 0 == status.exitstatus
|
|
raise "Convertion #{src} failed!" unless cache_dest.exist?
|
|
end
|
|
|
|
# deliver dest:
|
|
unless cache_dest == dest
|
|
FileUtils.copy cache_dest, dest, verbose: false
|
|
end
|
|
|
|
builder.trigger :created, "#{dest}"
|
|
dest
|
|
end
|
|
|
|
def after_build builder
|
|
paths = ::Middleman::Util.all_files_under( app.config[:build_dir])
|
|
paths.each do |path|
|
|
path = Pathname.new path
|
|
if 'assets' == path.relative_path_from( Pathname.new(@app.config[:build_dir])).descend.first.to_s
|
|
case path.extname
|
|
when '.otf', '.ttf'
|
|
new = path.dirname + "#{path.basename path.extname}.woff"
|
|
woff = convert builder, path, path.dirname + "#{path.basename path.extname}.woff"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
::Middleman::Extensions.register :fonts4web, ::Fonts4Web
|