require 'nokogiri'
require 'htmlbeautifier'
module Stylish
module Importers
class StartupFrameworkImporter < Stylish::Theme::Importer
ImagePathConversions = {
'../../common-files/img/' => 'startup-framework/',
'../../common-files/icons/' => 'startup-framework/icons/',
/.*common-files\/img\// => 'startup-framework/',
/.*common-files\/icons\// => 'startup-framework/icons/'
}
StylesheetReplacements = {
}
AllScripts = %w(
modernizr.custom
jquery-2.0.3.min
jquery.ui.touch-punch.min
bootstrap.min
bootstrap-select
bootstrap-switch
jquery.tagsinput
flatui-checkbox
flatui-radio
easing.min
froogaloop.min
jquery.backgroundvideo.min
jquery.bxslider.min
jquery.parallax.min
jquery.placeholder
jquery.scrollTo-1.4.3.1-min
jquery.sharrre.min
jquery-svg
jquery-svganim
masonry.pkgd.min
page-transitions
typeahead
)
def name
"startup-framework"
end
def logger
@logger ||= ::Logger.new(STDOUT)
end
def map_source_paths
# the importer will be created with a pointer to the source folder
# distribution of the startup framework. We want the Developer folder
# to be considered our source.
if source.basename != 'Developer' && source.join('Developer').exist?
self.source = source.join('Developer')
end
define_path :samples_path, source.join('samples')
define_path :components_path, source.join('ui-kit')
define_path :default_layout_path, samples_path.join('template','template-less.html')
folders = components_path.children.reduce({}) do |memo, folder|
key = folder.basename.to_s.gsub(/ui-kit-/,'').pluralize.capitalize
memo[key] = folder.expand_path
memo
end
set :component_folders, folders
set :default_layout_fragment, Nokogiri::HTML(default_layout_path.read)
set :stylesheet_dependencies_path, stylesheets_output_path.join('dependencies')
set :javascript_dependencies_path, javascripts_output_path.join('dependencies')
export :component_categories, folders.keys
end
def move_common_javascript_dependencies_into_global_theme
info "== Moving JS dependencies into place"
paths = Dir[source.join("common-files/js/**/*.js")].reject do |path|
path.match(/startup-kit|jquery-ui-|jquery-1/)
end
paths += Dir[source.join('flat-ui/js/**/*.js')].reject do |path|
path.match(/html5shiv|icon-font-ie7|application|respond|jquery-1|jquery-ui-1/)
end
paths.each do |path|
info " - copying #{ File.basename(path) }"
filename = File.basename(path).to_s
filename.gsub! 'jquery.svg', 'jquery-svg'
FileUtils.cp(path, javascript_dependencies_path.join(filename))
end
info "== Adding dependency paths"
self.dependency_paths << javascript_dependencies_path
self.dependency_paths << javascript_dependencies_path.parent
javascript_dependencies_path.join("all.js").open("w+") do |fh|
content = AllScripts.map {|script| "//= require #{script}" }.join("\n")
fh.write(content)
end
end
def move_common_stylesheet_dependencies_into_global_theme
paths = Dir[source.join('common-files/less/**/*.less')].reject do |path|
path.match(/startup-kit_header|gallery/)
end
FileUtils.mkdir_p stylesheet_dependencies_path.join('startup-framework')
info "== Adding import path: #{ stylesheet_dependencies_path.join('startup-framework') }"
self.import_paths << stylesheet_dependencies_path
self.import_paths << stylesheet_dependencies_path.parent
info "== Coppying Common CSS"
paths.each do |path|
info " - copying #{ File.basename(path) }"
FileUtils.cp(path, stylesheet_dependencies_path.join('startup-framework',File.basename(path)))
end
unless options[:skip_flat_ui]
info "== Importing Flat-UI Stylesheets"
FileUtils.cp_r source.join('flat-ui','less'), stylesheet_dependencies_path.join('flat-ui')
FileUtils.cp source.join('flat-ui','bootstrap','css', 'bootstrap.css'), stylesheet_dependencies_path.join('flat-ui-bootstrap.css')
info "== Adding import path: #{ stylesheet_dependencies_path.join('flat-ui') }"
end
self.dependency_paths.push stylesheet_dependencies_path
self.dependency_paths.push stylesheet_dependencies_path.parent
copy_fonts
copy_images
end
def copy_fonts
info "== Copying Fonts"
paths = Dir[source.join('flat-ui','fonts/**/*.*')] +
Dir[source.join('flat-ui','bootstrap/fonts/glyphicons-*.*')] +
Dir[source.join('common-files','fonts','**/*.*')]
paths.each do |path|
FileUtils.cp(path, fonts_output_path)
end
self.dependency_paths.push(fonts_output_path.parent)
end
def copy_images
info "== Copying Images"
FileUtils.cp_r source.join('common-files','icons'), images_output_path
source.join('common-files','img').children.each do |child|
info " - copying #{ File.basename(child) }"
FileUtils.cp_r(child, images_output_path)
end
self.dependency_paths.push images_output_path.parent
end
def info(msg)
logger.info(msg)
end
def extract_component_markup_from path, group_name
path = Pathname(path)
contents = path.read
fragment = Nokogiri::HTML(contents)
markers = find_component_markers_in_file(path) do |marker|
marker.include?(group_name.downcase) || marker.include?(group_name.downcase.singularize)
end
markers.map do |marker|
markup = fragment.css(".#{marker}, .#{marker}-sub").to_html.to_s.gsub(/\r\n\s+/,'')
markup = HtmlBeautifier.beautify(markup)
["#{marker}.html", markup]
end
end
def extract_component_markup
info "== Extracting component markup"
component_folders.each do |folder_name, path|
component_output_base = components_output_path.join(folder_name.to_s.downcase.parameterize)
['index.html','index2.html'].each do |html_file|
html_file = path.join(html_file)
next unless html_file.exist?
extracted = extract_component_markup_from(html_file, folder_name)
info "== Extracting from #{ html_file }: #{ extracted.length }"
extracted.each do |item|
marker, markup = item
info " -- Extracted: #{ marker }"
component_output_base.join(marker).open("w+") {|fh| fh.write(markup) }
end
end
end
end
def extract_component_dependency_stylesheets
component_folders.each do |folder_name, path|
base = stylesheets_output_path.join(folder_name.to_s.downcase.parameterize)
files = Dir[path.join('less/**/*.less')].reject {|file| file.match(/styles?\.less/) }
files.each {|f| FileUtils.cp(f, base.join(File.basename(f))) }
end
end
# @private pulls out the per component javascript and associated it properly
#
# @note here we go through and extract the namespaced javascript functions
# that may or may not be defined on a per component basis
def extract_component_dependency_javascripts
end
def find_component_markers_in_file path_to_file, &filter
lines = Pathname(path_to_file).read.to_s.lines.map(&:strip)
marker_lines = lines.grep(/\<\!\-\-\s?.*\s?\-\-\>/)
marker_lines.select!(&filter) if block_given?
marker_lines.map do |line|
line.match(/--(.*)--/)[1].to_s.strip
end
end
end
end
end
# The Startup Framework Importer is responsible for taking the
# startup framework distribution, as it is divided up, and move
# the dependencies to a more asset pipeline friendly organization.
#
# We will also decompose the sample templates, into the Stylish organizational
# model of themes, layouts, and categorized components.
#
# In practice for the CSS this means:
#
# startup base path has the flat ui dependency, and the common files
#
# then there are common files to each ui-kit category (blog, price, project)
#
# and then specific css files for each component in the ui-kit category
#
# For the javascript it means
#
# loop through the index html files for each of the ui kit folders
#
# find all of the dependencies that get loaded before startup-kit.js
#
# generate a generic dependencies manifest file
#
# parse the startup-kit.js file and separate the namespaced functions
# for each startupKit.uiKitContent functions and associate them with the components