module Octopress
module Plugins
@plugins = []
@local_plugins = []
def self.theme
@theme
end
def self.plugin(name)
if name == 'theme'
@theme
else
found = plugins.reject { |p| p.name != name }
if found.empty?
raise IOError.new "No Theme or Plugin with the name '#{name}' was found."
end
found.first
end
end
def self.plugins
[@theme].concat(@plugins).concat(@local_plugins).compact
end
def self.config(site)
if @config
@config
else
@config = {}
@config['plugins'] = {}
@config['theme'] = @theme.configs(site)
plugins.each do |p|
unless p == @theme
@config['plugins'][p.name] = p.configs(site)
end
end
@config
end
end
def self.include(name, file, site)
p = plugin(name)
p.include(file, site)
end
def self.register_plugin(plugin, name, type='plugin')
new_plugin = plugin.new(name, type)
case type
when 'theme'
@theme = new_plugin
when 'local_plugin'
@local_plugins << new_plugin
else
@plugins << new_plugin
end
end
def self.register_layouts(site)
plugins.each do |p|
p.layouts.clone.each { |layout| layout.register(site) }
end
end
def self.custom_dir(config)
if config['octopress'] and config['octopress']['custom']
config['octopress']['custom']
else
CUSTOM_DIR
end
end
def self.fingerprint(paths)
paths = [paths] unless paths.is_a? Array
Digest::MD5.hexdigest(paths.clone.map! { |path| "#{File.mtime(path).to_i}" }.join)
end
def self.combined_stylesheet_path(media)
File.join('stylesheets', "#{media}-#{@combined_stylesheets[media][:fingerprint]}.css")
end
def self.combined_javascript_path
print = @javascript_fingerprint || ''
File.join('javascripts', "#{print}.js")
end
def self.write_files(site, source, dest)
site.static_files << StaticFileContent.new(source, dest)
end
def self.compile_sass_file(path, options)
::Sass.compile_file(path, options)
end
def self.compile_sass(contents, options)
::Sass.compile(contents, options)
end
def self.sass_config(site, item, default)
if site.config['octopress'] && site.config['octopress']['sass'] && site.config['octopress']['sass'][item]
site.config['octopress']['sass'][item]
else
default
end
end
def self.sass_options(site)
options = {
style: sass_config(site, 'output_style', 'compressed').to_sym,
trace: sass_config(site, 'trace', false),
line_numbers: sass_config(site, 'line_numbers', false)
}
end
def self.write_combined_stylesheet(site)
css = combine_stylesheets(site)
css.keys.each do |media|
options = sass_options(site)
options[:line_numbers] = false
contents = compile_sass(css[media][:contents], options)
write_files(site, contents, combined_stylesheet_path(media))
end
end
def self.write_combined_javascript(site)
js = combine_javascripts(site)
write_files(site, js, combined_javascript_path) unless js == ''
end
def self.combine_stylesheets(site)
unless @combined_stylesheets
css = {}
paths = {}
plugins.each do |plugin|
if plugin.type == 'theme'
plugin_header = "/* Theme: #{plugin.name} */\n"
else
plugin_header = "/* Plugin: #{plugin.name} */\n"
end
stylesheets = plugin.stylesheets.clone.concat plugin.sass
stylesheets.each do |file|
css[file.media] ||= {}
css[file.media][:contents] ||= ''
css[file.media][:contents] << plugin_header
css[file.media][:paths] ||= []
# Add Sass files
if file.respond_to? :compile
css[file.media][:contents].concat file.compile(site)
else
css[file.media][:contents].concat file.path(site).read.strip
end
css[file.media][:paths] << file.path(site)
plugin_header = ''
end
end
css.keys.each do |media|
css[media][:fingerprint] = fingerprint(css[media][:paths])
end
@combined_stylesheets = css
end
@combined_stylesheets
end
def self.combine_javascripts(site)
unless @combined_javascripts
js = ''
plugins.each do |plugin|
paths = plugin.javascript_paths(site)
@javascript_fingerprint = fingerprint(paths)
paths.each do |file|
js.concat Pathname.new(file).read
end
end
@combined_javascripts = js
end
@combined_javascripts
end
def self.combined_stylesheet_tag(site)
tags = ''
combine_stylesheets(site).keys.each do |media|
tags.concat ""
end
tags
end
def self.combined_javascript_tag(site)
unless combine_javascripts(site) == ''
""
end
end
def self.stylesheet_tags(site)
if concat_css(site)
combined_stylesheet_tag(site)
else
css = []
plugins.each do |plugin|
css.concat plugin.stylesheet_tags
css.concat plugin.sass_tags
end
css
end
end
def self.concat_css(site)
if site.config['octopress'] && !site.config['octopress']['concat_css'].nil?
site.config['octopress']['concat_css'] != false
else
true
end
end
def self.concat_js(site)
if site.config['octopress'] && !site.config['octopress']['concat_js'].nil?
site.config['octopress']['concat_js'] != false
else
true
end
end
def self.javascript_tags(site)
if concat_js(site)
combined_javascript_tag(site)
else
js = []
plugins.each do |plugin|
js.concat plugin.javascript_tags
end
js
end
end
def self.copy_javascripts(site)
plugins.each do |plugin|
copy(plugin.javascripts, site)
end
end
def self.copy_stylesheets(site)
stylesheets = plugins.clone.map {
|p| p.stylesheets.clone.concat(p.sass)
}.flatten
copy(stylesheets, site)
end
def self.add_static_files(site)
plugin('user stylesheets').add_files(site)
# Copy/Generate Stylesheets
#
if concat_css(site)
write_combined_stylesheet(site)
else
copy_stylesheets(site)
end
# Copy/Generate Javascripts
#
if concat_js(site)
write_combined_javascript(site)
else
copy_javascripts(site)
end
# Copy other assets
#
copy_static_files(site)
end
def self.copy_static_files(site)
plugins.each do |plugin|
copy(plugin.files, site)
copy(plugin.images, site)
copy(plugin.fonts, site)
end
end
def self.copy(files, site)
files.each { |f| f.copy(site) }
end
end
end