extended auxiliary files support

- support for css in header/footer
- support for js/coffee/whatever
- main integrated into render/inject/tmp flow

=> all html files get every css/js injected
This commit is contained in:
Loic Nageleisen 2014-02-21 16:14:18 +01:00
parent 6623656530
commit bc91aa7012
3 changed files with 88 additions and 19 deletions

View file

@ -11,8 +11,13 @@ GEM
celluloid (0.15.2) celluloid (0.15.2)
timers (~> 1.1.0) timers (~> 1.1.0)
coderay (1.0.9) coderay (1.0.9)
coffee-script (2.2.0)
coffee-script-source
execjs
coffee-script-source (1.7.0)
commonjs (0.2.7) commonjs (0.2.7)
diff-lcs (1.2.4) diff-lcs (1.2.4)
execjs (2.0.2)
ffi (1.9.0) ffi (1.9.0)
formatador (0.2.4) formatador (0.2.4)
guard (2.1.1) guard (2.1.1)
@ -67,6 +72,7 @@ PLATFORMS
ruby ruby
DEPENDENCIES DEPENDENCIES
coffee-script
guard-rspec guard-rspec
less less
pry pry

View file

@ -11,23 +11,23 @@ module Tilt
def prepare; end def prepare; end
def evaluate(scope, locals, &block) def evaluate(scope, locals, &block)
main = render_html(main_html_file, scope, locals, &block) files = aux_files
files << main_html_file
render_to_tmp(*aux_files, scope, locals, block) do |tmp| render_to_tmp(*files, scope, locals, block) do |tmp|
opts = pdfkit_options opts = pdfkit_options
if header if header
htmp = tmp.select { |_, f| f =~ /#{File.basename header}/ }.first[1] htmp = tmp.select { |_, f, _| f == header }.first[2]
opts.merge!('header-html' => htmp) if header opts.merge!('header-html' => htmp) if header
end end
if footer if footer
ftmp = tmp.select { |_, f| f =~ /#{File.basename footer}/ }.first[1] ftmp = tmp.select { |_, f, _| f == footer }.first[2]
opts.merge!('footer-html' => ftmp) if footer opts.merge!('footer-html' => ftmp) if footer
end end
kit = PDFKit.new(main, opts) main = tmp.select { |_, f, _| f == main_html_file }.first[2]
tmp.each { |t, f| kit.stylesheets << f if t == 'text/css' } kit = PDFKit.new(File.read(main), opts)
@output = kit.to_pdf @output = kit.to_pdf
end end
@ -46,7 +46,9 @@ module Tilt
end end
def aux_files def aux_files
files = css_files files = []
files.concat css_files
files.concat js_files
files << header if header files << header if header
files << footer if footer files << footer if footer
@ -85,6 +87,16 @@ module Tilt
config.fetch('stylesheets', []).map { |f| absolutize(f) } config.fetch('stylesheets', []).map { |f| absolutize(f) }
end end
def js_files
js_from_config || find_js
end
def js_from_config
return unless config.key?('javascripts')
config.fetch('javascripts', []).map { |f| absolutize(f) }
end
def pdfkit_options def pdfkit_options
config.fetch('pdfkit', {}) config.fetch('pdfkit', {})
end end
@ -101,33 +113,83 @@ module Tilt
Dir.glob(File.join(dirname, name + '.css*')) Dir.glob(File.join(dirname, name + '.css*'))
end end
def find_js
Dir.glob(File.join(dirname, name + '.js*'))
end
def render_html(file, scope, locals, &block) def render_html(file, scope, locals, &block)
Tilt.new(file).render(scope, locals, &block) Tilt.new(file).render(scope, locals, &block)
end end
def inject_css!(document, stylesheet)
append_to_head!(document, "<style>#{stylesheet}</style>")
end
def inject_js!(document, script)
append_to_head!(document, "<script>#{script}</script>")
end
def append_to_head!(document, tag)
if document.match(/<\/head>/)
document.gsub!(/(<\/head>)/) { |s| tag + s }
else
document.insert(0, tag)
end
end
def render_to_tmp(*files, scope, locals, block) def render_to_tmp(*files, scope, locals, block)
tmps = [] tmps = []
noop = %w[html css] no_tilt = %w[html css js]
css = files.map do |file| result = files.map do |file|
ext = File.extname(file).sub(/^\./, '') ext = File.extname(file).sub(/^\./, '')
if noop.include?(ext) if no_tilt.include?(ext)
["text/#{ext}", file] mime = case ext
when 'js', 'javascript' then 'application/javascript'
else "text/#{ext}"
end
rendered = File.read(file)
else else
template = Tilt.new(file) template = Tilt.new(file)
mime = template.class.default_mime_type mime = template.class.default_mime_type
ext = mime.split('/').last ext = mime.split('/').last
rendered = template.render(scope, locals, &block)
end
[ext, mime, file, rendered]
end
result.sort! do |a, b|
a[1] <=> b[1] # css < html
end
styles = result.select { |_, mime, _, _| mime == 'text/css' }
scripts = result.select { |_, mime, _, _| mime == 'application/javascript' }
result.map! do |ext, mime, file, rendered|
if mime == 'text/html'
styles.each do |_, _, _, style|
inject_css!(rendered, style)
end
scripts.each do |_, _, _, script|
inject_js!(rendered, script)
end
end
[ext, mime, file, rendered]
end
result.map! do |ext, mime, file, rendered|
tmp = Tempfile.new([File.basename(file), '.' + ext]) tmp = Tempfile.new([File.basename(file), '.' + ext])
tmps << tmp tmps << tmp
rendered = template.render(scope, locals, &block)
tmp.write(rendered) tmp.write(rendered)
tmp.close tmp.close
[mime, tmp.path] path = tmp.path
end
[mime, file, path]
end end
yield css yield result
ensure ensure
tmps.each { |tmp| tmp.close! } tmps.each { |tmp| tmp.close! }
end end

View file

@ -22,6 +22,7 @@ Gem::Specification.new do |s|
s.add_development_dependency 'therubyracer' s.add_development_dependency 'therubyracer'
s.add_development_dependency 'less' s.add_development_dependency 'less'
s.add_development_dependency 'coffee-script'
s.add_development_dependency 'slim' s.add_development_dependency 'slim'
s.add_development_dependency 'rspec', '~> 2.14' s.add_development_dependency 'rspec', '~> 2.14'
s.add_development_dependency 'rake' s.add_development_dependency 'rake'