diff --git a/README b/README index a5785f98..652aa94c 100644 --- a/README +++ b/README @@ -1,13 +1,23 @@ This is the SASS Port of Blueprint ---------------------------------------------------------------- To install: -git clone git://github.com/chriseppstein/haml.git +git clone git://github.com/nex3/haml.git cd haml && rake install && cd - git clone git://github.com/chriseppstein/blueprint-css.git +cd blueprint-css && git checkout sass && cd - + +To compile the examples: cd blueprint-css rake examples open built_examples +To generate a project: +blueprint-css/bin/blueprint myproject + +To update a project after editing a sass file: +cd myproject +blueprint-css/bin/blueprint -u + To see what's left to be done (and find stuff you can contribute) read the TODO diff --git a/TODO b/TODO index 6af50299..fc95470c 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,8 @@ This is a list of Tasks that have to get done before this branch is ready to become a candidate for merge to master. -* Make the examples looks the same - - body margin - - fancy-type plugin * Allow customization of all the parameters that used to be available in the .yml config file - grid dimensions - project path - ... * blueprint command-line - - create project - - update project - unpack blueprint - configure rails project ala haml diff --git a/lib/blueprint/commands/base.rb b/lib/blueprint/commands/base.rb new file mode 100644 index 00000000..e5bc6863 --- /dev/null +++ b/lib/blueprint/commands/base.rb @@ -0,0 +1,78 @@ +module Blueprint + module Commands + class Base + attr_accessor :working_directory, :options + def initialize(working_directory, options) + self.working_directory = working_directory + self.options = options + end + + def perform + raise StandardError.new("Not Implemented") + end + + protected + + def projectize(path) + File.join(project_directory, separate(path)) + end + # create a directory and all the directories necessary to reach it. + def directory(subdir, options) + dir = subdir ? projectize(subdir) : project_directory + if File.exists?(dir) && File.directory?(dir) && options[:force] + print_action :exists, basename(dir) + File::SEPARATOR + elsif File.exists?(dir) && File.directory?(dir) + msg = "Directory #{basename(dir)} already exists. Run with -f to force project creation." + raise ::Blueprint::Exec::ExecError.new(msg) + elsif File.exists?(dir) + msg = "#{basename(dir)} already exists and is not a directory." + raise ::Blueprint::Exec::ExecError.new(msg) + else + print_action :directory, basename(dir) + File::SEPARATOR + FileUtils.mkdir_p(dir) unless options[:dry_run] + end + end + + # copy/process a template in the blueprint template directory to the project directory. + def template(from, to, options) + to = projectize(to) + from = File.join(templates_directory, separate(from)) + if File.exists?(to) && !options[:force] + #TODO: Detect differences & provide an overwrite prompt + msg = "#{basename(to)} already exists." + raise ::Blueprint::Exec::ExecError.new(msg) + elsif File.exists?(to) + print_action :remove, basename(to) + FileUtils.rm to unless options[:dry_run] + end + print_action :create, basename(to) + FileUtils.cp from, to unless options[:dry_run] + end + + # returns the path to the templates directory and caches it + def templates_directory + @templates_directory ||= File.expand_path(File.join(File.dirname(__FILE__), separate('../../../templates'))) + end + + # Write paths like we're on unix and then fix it + def separate(path) + path.gsub(%r{/}, File::SEPARATOR) + end + + def basename(file, extra = 0) + if file.length > (working_directory.length + extra) + file[(working_directory.length + extra + 1)..-1] + else + File.basename(file) + end + end + + ACTIONS = [:directory, :exists, :remove, :create] + MAX_ACTION_LENGTH = ACTIONS.inject(0){|memo, a| [memo, a.to_s.length].max} + def print_action(action, extra) + puts "#{' ' * (MAX_ACTION_LENGTH - action.to_s.length)}#{action} #{extra}" + end + + end + end +end \ No newline at end of file diff --git a/lib/blueprint/commands/create_project.rb b/lib/blueprint/commands/create_project.rb index 62521195..c0b71ee7 100644 --- a/lib/blueprint/commands/create_project.rb +++ b/lib/blueprint/commands/create_project.rb @@ -1,16 +1,28 @@ +require 'fileutils' +require File.join(File.dirname(__FILE__), 'base') +require File.join(File.dirname(__FILE__), 'update_project') + module Blueprint module Commands - class CreateProject + class CreateProject < Base - attr_accessor :working_directory, :project_name, :options + attr_accessor :project_directory, :project_name - def initialize(working_directory, options = {}) - self.working_directory, self.options = working_directory, options + def initialize(working_directory, options) + super(working_directory, options) self.project_name = options[:project_name] + self.project_directory = File.expand_path File.join(working_directory, project_name) end + # all commands must implement perform def perform - puts "Creating project #{project_name} in #{working_directory}" + directory nil, options + directory 'stylesheets', options.merge(:force => true) + directory 'src', options.merge(:force => true) + template 'project/screen.sass', 'src/screen.sass', options + template 'project/print.sass', 'src/print.sass', options + template 'project/ie.sass', 'src/ie.sass', options + UpdateProject.new(working_directory, options).perform end end diff --git a/lib/blueprint/commands/update_project.rb b/lib/blueprint/commands/update_project.rb index c5cd99d8..28fdb40d 100644 --- a/lib/blueprint/commands/update_project.rb +++ b/lib/blueprint/commands/update_project.rb @@ -1,22 +1,31 @@ +require 'rubygems' +require 'sass' +require 'fileutils' +require 'pathname' +require File.join(File.dirname(__FILE__), 'base') + module Blueprint module Commands - class UpdateProject + class UpdateProject < Base + Base::ACTIONS << :compile + Base::ACTIONS << :overwrite + attr_accessor :project_directory, :project_name, :options def initialize(working_directory, options = {}) - self.options = options + super(working_directory, options) if options[:project_name] options[:project_name] = options[:project_name][0..-2] if options[:project_name][-1..-1] == File::SEPARATOR self.project_name = File.basename(options[:project_name]) - if File.directory?(options[:project_name]) + if options[:project_name][0] == File::SEPARATOR self.project_directory = options[:project_name] elsif File.directory?(File.join(working_directory, options[:project_name])) - self.project_directory = options[:project_name] + self.project_directory = File.expand_path(File.join(working_directory, options[:project_name])) else if File.exists?(options[:project_name]) or File.exists?(File.join(working_directory, options[:project_name])) raise ::Blueprint::Exec::ExecError.new("#{options[:project_name]} is not a directory.") - else + elsif !(options[:force] || options[:dry_run]) raise ::Blueprint::Exec::ExecError.new("#{options[:project_name]} does not exist.") end end @@ -27,7 +36,58 @@ def initialize(working_directory, options = {}) end def perform - puts "Updating project #{project_name} in #{project_directory}" + Dir.glob(separate("#{project_directory}/src/**/[^_]*.sass")).each do |sass_file| + stylesheet_name = sass_file[("#{project_directory}/src/".length)..-6] + compile "src/#{stylesheet_name}.sass", "stylesheets/#{stylesheet_name}.css", options + end + end + + # Compile one Sass file + def compile(sass_filename, css_filename, options) + sass_filename = projectize(sass_filename) + css_filename = projectize(css_filename) + if !File.directory?(File.dirname(css_filename)) + directory basename(File.dirname(css_filename)), options.merge(:force => true) unless options[:dry_run] + end + if File.exists?(css_filename) + print_action :overwrite, basename(css_filename) + else + print_action :compile, basename(css_filename) + end + unless options[:dry_run] + engine = ::Sass::Engine.new(open(sass_filename).read, + :filename => sass_filename, + :line_comments => options[:environment] == :development, + :style => output_style, + :css_filename => css_filename, + :load_paths => sass_load_paths) + output = open(css_filename,'w') + output.write(engine.render) + output.close + end + end + + def output_style + @output_style ||= options[:style] || if options[:environment] == :development + :nested + else + :compact + end + end + + # where to load sass files from + def sass_load_paths + @sass_load_paths ||= [project_src_directory, blueprint_src_directory] + end + + # The directory where the blueprint source files are located. + def blueprint_src_directory + @blueprint_src_directory ||= File.expand_path(File.join(File.dirname(__FILE__), separate('../../../src'))) + end + + # The directory where the project source files are located. + def project_src_directory + @project_src_directory ||= separate("#{project_directory}/src") end end diff --git a/lib/blueprint/exec.rb b/lib/blueprint/exec.rb index c39c12f2..a1a286f0 100644 --- a/lib/blueprint/exec.rb +++ b/lib/blueprint/exec.rb @@ -53,7 +53,8 @@ def parse! self.opts.parse!(self.args) if ARGV.size > 0 self.options[:project_name] = ARGV.shift - end + end + self.options[:environment] ||= :production end def set_opts(opts) @@ -72,6 +73,18 @@ def set_opts(opts) self.options[:update] = true end + opts.on('-f', '--force', :NONE, 'Force. Allows some commands to succeed when they would otherwise fail.') do + self.options[:force] = true + end + + opts.on('-e ENV', '--environment ENV', [:development, :production], 'Select an output mode (development, production)') do |env| + self.options[:environment] = env + end + + opts.on('--dry-run', :NONE, 'Dry Run. Tells you what it plans to do.') do + self.options[:dry_run] = true + end + opts.on('--trace', :NONE, 'Show a full traceback on error') do self.options[:trace] = true end diff --git a/templates/project/grid.png b/templates/project/grid.png new file mode 100644 index 00000000..129d4a29 Binary files /dev/null and b/templates/project/grid.png differ diff --git a/templates/project/ie.sass b/templates/project/ie.sass new file mode 100644 index 00000000..07029fbb --- /dev/null +++ b/templates/project/ie.sass @@ -0,0 +1,4 @@ +@import blueprint-ie + +body + +blueprint-ie \ No newline at end of file diff --git a/templates/project/print.sass b/templates/project/print.sass new file mode 100644 index 00000000..22938d1d --- /dev/null +++ b/templates/project/print.sass @@ -0,0 +1,4 @@ +@import blueprint-print + +body + +blueprint-print \ No newline at end of file diff --git a/templates/project/screen.sass b/templates/project/screen.sass new file mode 100644 index 00000000..a2fc1286 --- /dev/null +++ b/templates/project/screen.sass @@ -0,0 +1,11 @@ +@import blueprint +@import modules/scaffolding + +html + +blueprint-reset-html + +body + +blueprint + // Remove the scaffolding when you're ready to start doing visual design. + // Or leave it in if you're happy with how blueprint looks out-of-the-box + +scaffolding