middleman-fonts/lib/middleman-fonts/fonts4web.rb

157 lines
4.4 KiB
Ruby

require 'json'
require 'active_support/all'
require 'fileutils'
require 'shellwords'
require 'digest/md5'
class ::Middleman::Sitemap::Fonts4Web < ::Middleman::Sitemap::Resource
def initialize store, path, source
source_dir = Pathname.new( store.app.config[:source]).expand_path
STDERR.printf "fonts4web %p\n", path: path, source: source, source_dir: source_dir
super store, path, nil
@source = source
end
def binary?() true end
def render *_
convert( Pathname.new( @source)).read
end
def convert src
STDERR.puts "convert #{src}"
# files:
f = src.basename
md5sum = Digest::MD5.hexdigest src.read
# files in cache:
symlink = @cachepath/"#{f.basename f.extname}-#{md5sum}#{f.extname}"
cache_dest = @cachepath/"#{symlink.basename f.extname}.woff"
relsrc = src.expand_path.relative_path_from @cachepath.expand_path
dest = dest ? Pathname.new( dest) : cache_dest.expand_path
@cachepath.mkpath
identical = true
# cache_dest is older than source
unless cache_dest.exist?
identical = false
# 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
#FileUtils.copy cache_dest, dest, verbose: false
#builder.trigger identical ? :identical : :created, "#{dest}"
dest
end
end
class ::Middleman::Extensions::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
md5sum = Digest::MD5.hexdigest src.read
# files in cache:
symlink = @cachepath/"#{f.basename f.extname}-#{md5sum}#{f.extname}"
cache_dest = @cachepath/"#{symlink.basename f.extname}.woff"
relsrc = src.expand_path.relative_path_from @cachepath.expand_path
dest = dest ? Pathname.new( dest) : cache_dest.expand_path
@cachepath.mkpath
identical = true
# cache_dest is older than source
unless cache_dest.exist?
identical = false
# 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
FileUtils.copy cache_dest, dest, verbose: false
builder.trigger identical ? :identical : :created, "#{dest}"
dest
end
#def manipulate_resource_list resources
# source_dir = Pathname.new @app.config[:source]
# paths = {}
# resources.each {|res| paths[res.path] = res }
# resources.each do |res|
# path = Pathname.new res.path
# if 'assets' == path.descend.first.to_s
# case path.extname
# when '.otf', '.ttf'
# new = path.dirname/"#{path.basename path.extname}.woff"
# unless paths.has_key? new
# STDERR.puts "convert #{new} <= #{path}"
# resource = ::Middleman::Sitemap::Fonts4Web.new( @app.sitemap, new.to_s, res)
# if false
# woff = convert source_dir.expand_path/path #, path.dirname/"#{path.basename path.extname}.woff"
# resources << ::Middleman::Sitemap::Fonts4Web.new( @app.sitemap, new.to_s, woff.to_s)
# end
# resources << resource
# paths[new.to_s] = resource
# end
# end
# end
# end
# resources
#end
def after_build builder
paths = ::Middleman::Util.all_files_under app.config[:build_dir]
paths.each do |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"
unless paths.include?( new)
convert builder, path, path.dirname/"#{path.basename path.extname}.woff"
end
end
end
end
end
end