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