Clean up whitespace, play with cane for testing style quality and code complexity

This commit is contained in:
Thomas Reynolds 2012-08-13 15:39:06 -07:00
parent 955c66a54f
commit 446aa6a4ba
133 changed files with 895 additions and 871 deletions

View file

@ -17,6 +17,7 @@ group :test do
gem "slim"
gem "coffee-filter", "~> 0.1.1"
gem "liquid", "~> 2.2"
gem "cane"
platforms :ruby do
gem "therubyracer"

View file

@ -87,5 +87,12 @@ task :test do
end
end
desc "Rune cane for all middleman gems"
task :cane do
GEM_PATHS.each do |g|
sh "cd #{File.join(ROOT, g)} && #{Gem.ruby} -S cane"
end
end
desc "Run tests for all middleman gems"
task :default => :test

View file

@ -21,10 +21,10 @@ Cucumber::Rake::Task.new(:test, 'Run features that should pass') do |t|
exempt_tags << "--tags ~@nojava" if RUBY_PLATFORM == "java"
exempt_tags << "--tags ~@encoding" unless Object.const_defined?(:Encoding)
exempt_tags << "--tags ~@travishatesme" if ENV["TRAVIS"] == "true"
t.cucumber_opts = "--color #{exempt_tags.join(" ")} --strict --format #{ENV['CUCUMBER_FORMAT'] || 'Fivemat'}"
end
YARD::Rake::YardocTask.new
task :default => :test
task :default => :test

2
middleman-core/.cane Normal file
View file

@ -0,0 +1,2 @@
--exclusions-file .cane-exclusions.yml
--no-doc

View file

@ -0,0 +1,5 @@
style:
- lib/middleman-core/vendor/hooks-0.2.0/lib/hooks/inheritable_attribute.rb
- lib/middleman-core/vendor/hooks-0.2.0/test/hooks_test.rb
- lib/middleman-core/vendor/hooks-0.2.0/test/inheritable_attribute_test.rb
- lib/middleman-core/vendor/hooks-0.2.0/lib/hooks.rb

View file

@ -1,7 +1,7 @@
Given /^page "([^\"]*)" has layout "([^\"]*)"$/ do |url, layout|
@initialize_commands ||= []
@initialize_commands << lambda {
page(url, :layout => layout.to_sym)
@initialize_commands << lambda {
page(url, :layout => layout.to_sym)
}
end
@ -12,4 +12,4 @@ Given /^"([^\"]*)" with_layout block has layout "([^\"]*)"$/ do |url, layout|
page(url)
end
}
end
end

View file

@ -3,4 +3,4 @@ ENV["AUTOLOAD_SPROCKETS"] = "false"
PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core')
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core', 'step_definitions')
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-core', 'step_definitions')

View file

@ -1 +1 @@
set :automatic_directory_matcher, "--"
set :automatic_directory_matcher, "--"

View file

@ -1,4 +1,4 @@
with_layout false do
page "/data.html"
page "/data3.html"
end
end

View file

@ -1 +1 @@
set :layout, false
set :layout, false

View file

@ -8,4 +8,4 @@ page "/target_ignore.html", :proxy => "/should_be_ignored3.html", :ignore => tru
page "/fake/#{num}.html", :proxy => "/real/index.html" do
@num = num
end
end
end

View file

@ -8,4 +8,4 @@ page "/target_ignore.html", :proxy => "/should_be_ignored3.html", :ignore => tru
page "/fake/#{num}.html", :proxy => "/real/index.html" do
@num = num
end
end
end

View file

@ -1,3 +1,3 @@
with_layout false do
page "/request-path.html"
end
end

View file

@ -1 +1 @@
set :erb, :layout_engine => :str
set :erb, :layout_engine => :str

View file

@ -1,3 +1,3 @@
data.pages.each do |p|
page p.from, :proxy => p.to
end
end

View file

@ -1,4 +1,4 @@
require "lib/hello_helper"
helpers HelloHelper
page "/", :layout => false
page "/", :layout => false

View file

@ -1,3 +1,3 @@
module Derp
def three; "Three"; end
end
end

View file

@ -1,3 +1,3 @@
module FourHelpers
def four; "Four"; end
end
end

View file

@ -1,3 +1,3 @@
module OneHelper
def one; "One"; end
end
end

View file

@ -1,3 +1,3 @@
module YetAnotherThingy
def two; "Two"; end
end
end

View file

@ -2,4 +2,4 @@ module HelloHelper
def hello
"Hello World"
end
end
end

View file

@ -9,4 +9,4 @@ module ExtensionA
end
end
activate ExtensionA, :hello => "world", :hola => "mundo"
activate ExtensionA, :hello => "world", :hola => "mundo"

View file

@ -1,4 +1,4 @@
# Proxy ignored.html, which should ignore itself through a frontmatter
page 'proxied.html', :proxy => 'ignored.html'
page 'override_layout.html', :layout => :alternate
page 'page_mentioned.html'
page 'page_mentioned.html'

View file

@ -1,4 +1,4 @@
###
###
# Compass
###
@ -16,13 +16,13 @@
###
# Per-page layout changes:
#
#
# With no layout
# page "/path/to/file.html", :layout => false
#
#
# With alternative layout
# page "/path/to/file.html", :layout => :otherlayout
#
#
# A path which all have the same layout
# with_layout :admin do
# page "/admin/*"
@ -60,21 +60,21 @@
configure :build do
# For example, change the Compass output style for deployment
# activate :minify_css
# Minify Javascript on build
# activate :minify_javascript
# Enable cache buster
# activate :cache_buster
# Use relative URLs
# activate :relative_assets
# Compress PNGs after build
# First: gem install middleman-smusher
# require "middleman-smusher"
# activate :smusher
# Or use a different image path
# set :http_path, "/Content/images/"
end
end

View file

@ -1 +1 @@
page "/index.html", :layout => false
page "/index.html", :layout => false

View file

@ -1,3 +1,3 @@
with_layout false do
page "/spaces in file.html"
end
end

View file

@ -1 +1 @@
set :layout, :custom
set :layout, :custom

View file

@ -1,3 +1,3 @@
set :layout, :custom
page "/", :layout => :another
page "/", :layout => :another

View file

@ -1 +1 @@
set :layout, :custom
set :layout, :custom

View file

@ -3,4 +3,4 @@ page "/path/*", :layout => "alt"
# Doesn't work, and shouldn't
# page "/path/*" do
# set :layout, "alt"
# end
# end

View file

@ -8,4 +8,4 @@ end
map "/sinatra" do
run MySinatra
end
end

View file

@ -2,4 +2,4 @@ page "/sub/fake.html", :proxy => "/proxied.html", :ignore => true
page "/sub/fake2.html", :proxy => "/proxied.html", :ignore => true
page "/directory-indexed/fake.html", :proxy => "/proxied.html", :ignore => true
page "/directory-indexed/fake2.html", :proxy => "/proxied.html", :ignore => true
page "/directory-indexed/fake2.html", :proxy => "/proxied.html", :ignore => true

View file

@ -1 +1 @@
page "/admin/*", :layout => :admin
page "/admin/*", :layout => :admin

6
middleman-core/lib/middleman-core.rb Executable file → Normal file
View file

@ -4,13 +4,13 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
# Top-level Middleman namespace
module Middleman
# Backwards compatibility namespace
module Features; end
end
require "middleman-core/version"
require "middleman-core/util"
require "middleman-core/extensions"
require "middleman-core/application"
require "middleman-core/application"

View file

@ -18,7 +18,7 @@ module Middleman
class Application
# Uses callbacks
include Hooks
# Before request hook
define_hook :before
@ -215,7 +215,7 @@ module Middleman
def settings
self
end
delegate :logger, :instrument, :to => ::Middleman::Util
# Work around this bug: http://bugs.ruby-lang.org/issues/4521

View file

@ -6,7 +6,7 @@ require "thor/group"
module Middleman
module Cli
# The base task from which everything else etends
class Base < Thor
class << self
@ -18,7 +18,7 @@ module Middleman
if ARGV[0] != "help" && (ARGV.length < 1 || ARGV.first.include?("-"))
ARGV.unshift("server")
end
super
end
end
@ -28,7 +28,7 @@ module Middleman
require 'middleman-core/version'
say "Middleman #{Middleman::VERSION}"
end
# Override the Thor help method to find help for subtasks
# @param [Symbol, String, nil] meth
# @param [Boolean] subcommand
@ -43,24 +43,24 @@ module Middleman
list += klass.printable_tasks(false)
end
list.sort!{ |a,b| a[0] <=> b[0] }
shell.say "Tasks:"
shell.print_table(list, :ident => 2, :truncate => true)
shell.say
end
end
# Intercept missing methods and search subtasks for them
# @param [Symbol] meth
def method_missing(meth, *args)
meth = meth.to_s
if self.class.map.has_key?(meth)
meth = self.class.map[meth]
end
klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}")
if klass.nil?
tasks_dir = File.join(Dir.pwd, "tasks")
@ -69,7 +69,7 @@ module Middleman
klass, task = Thor::Util.find_class_and_task_by_namespace("#{meth}:#{meth}")
end
end
if klass.nil?
super
else

View file

@ -2,59 +2,59 @@ require "middleman-core"
# CLI Module
module Middleman::Cli
# The CLI Build class
class Build < Thor
include Thor::Actions
attr_reader :debugging
check_unknown_options!
namespace :build
desc "build [options]", "Builds the static site for deployment"
method_option :clean,
:type => :boolean,
:aliases => "-c",
:default => false,
method_option :clean,
:type => :boolean,
:aliases => "-c",
:default => false,
:desc => 'Removes orphaned files or directories from build'
method_option :glob,
:type => :string,
:aliases => "-g",
:default => nil,
method_option :glob,
:type => :string,
:aliases => "-g",
:default => nil,
:desc => 'Build a subset of the project'
method_option :verbose,
:type => :boolean,
:type => :boolean,
:default => false,
:desc => 'Print debug messages'
method_option :instrument,
:type => :string,
:type => :string,
:default => false,
:desc => 'Print instrument messages'
method_option :profile,
:type => :boolean,
:default => false,
:desc => 'Generate profiling report for the build'
# Core build Thor command
# @return [void]
def build
if !ENV["MM_ROOT"]
raise Thor::Error, "Error: Could not find a Middleman project config, perhaps you are in the wrong folder?"
end
# Use Rack::Test for inspecting a running server for output
require "rack"
require "rack/test"
require 'find'
@debugging = Middleman::Cli::Base.respond_to?(:debugging) && Middleman::Cli::Base.debugging
@had_errors = false
self.class.shared_instance(options["verbose"], options["instrument"])
self.class.shared_rack
opts = {}
@ -66,12 +66,12 @@ module Middleman::Cli
if @had_errors && !@debugging
self.shell.say "There were errors during this build, re-run with --verbose to see the full exception."
end
exit(1) if @had_errors
self.class.shared_instance.run_hook :after_build, self
end
# Static methods
class << self
def exit_on_failure?
@ -87,14 +87,14 @@ module Middleman::Cli
logger(verbose ? 0 : 1, instrument)
end
end
# Middleman::Application class singleton
#
# @return [Middleman::Application]
def shared_server
@_shared_server ||= shared_instance.class
end
# Rack::Test::Session singleton
#
# @return [Rack::Test::Session]
@ -104,13 +104,13 @@ module Middleman::Cli
::Rack::Test::Session.new(mock)
end
end
# Set the root path to the Middleman::Application's root
def source_root
shared_instance.root
end
end
no_tasks {
# Render a resource to a file.
#
@ -134,10 +134,10 @@ module Middleman::Cli
output_file
end
def handle_error(file_name, response, e=Thor::Error.new(response))
@had_errors = true
say_status :error, file_name, :red
if self.debugging
raise e
@ -148,7 +148,7 @@ module Middleman::Cli
end
}
end
# A Thor Action, modular code, which does the majority of the work.
class GlobAction < ::Thor::Actions::EmptyDirectory
attr_reader :source
@ -169,7 +169,7 @@ module Middleman::Cli
super(base, @destination, config)
end
# Execute the action
# @return [void]
def invoke!
@ -179,21 +179,21 @@ module Middleman::Cli
end
protected
# Remove files which were not built in this cycle
# @return [void]
def clean!
files = @cleaning_queue.select { |q| q.file? }
directories = @cleaning_queue.select { |q| q.directory? }
files.each do |f|
files.each do |f|
base.remove_file f, :force => true
end
directories = directories.sort_by {|d| d.to_s.length }.reverse!
directories.each do |d|
base.remove_file d, :force => true if directory_empty? d
base.remove_file d, :force => true if directory_empty? d
end
end
@ -216,11 +216,11 @@ module Middleman::Cli
def queue_current_paths
@cleaning_queue = []
return unless File.exist?(@destination)
paths = ::Middleman::Util.all_files_under(@destination)
@cleaning_queue += paths.select do |path|
!path.to_s.match(/\/\./) || path.to_s.match(/\.htaccess/)
end
end
end
# Actually build the app
@ -228,7 +228,7 @@ module Middleman::Cli
def execute!
# Sort order, images, fonts, js/css and finally everything else.
sort_order = %w(.png .jpeg .jpg .gif .bmp .svg .svgz .ico .woff .otf .ttf .eot .js .css)
# Pre-request CSS to give Compass a chance to build sprites
logger.debug "== Prerendering CSS"
@ -237,7 +237,7 @@ module Middleman::Cli
end.each do |resource|
Middleman::Cli::Build.shared_rack.get(URI.escape(resource.destination_path))
end
logger.debug "== Checking for Compass sprites"
# Double-check for compass sprites
@ -265,7 +265,7 @@ module Middleman::Cli
::Middleman::Profiling.report("build")
end
end
# Alias "b" to "build"
Base.map({ "b" => "build" })
end

View file

@ -1,26 +1,26 @@
# CLI Module
module Middleman::Cli
# A initializing Bundler
class Bundle < Thor
include Thor::Actions
check_unknown_options!
namespace :bundle
desc "bundle", "Setup initial bundle", :hide => true
# The setup task
def bundle
run('bundle install --without development test')#, :capture => true)
end
end
# A upgrading Bundler
class Upgrade < Thor
include Thor::Actions
check_unknown_options!
namespace :upgrade
desc "upgrade", "Upgrade installed bundle"
@ -32,7 +32,7 @@ module Middleman::Cli
end
end
end
# Map "u" to "upgrade"
Base.map({
"u" => "upgrade"

View file

@ -1,19 +1,19 @@
# CLI Module
module Middleman::Cli
# A thor task for creating new projects
class Extension < Thor
include Thor::Actions
check_unknown_options!
namespace :extension
# Required path for the new project to be generated
argument :name, :type => :string
desc "extension [options]", "Create Middleman extension scaffold NAME"
# The extension task
# @param [String] name
def extension
@ -25,7 +25,7 @@ module Middleman::Cli
template "features/support/env.rb", File.join(name, "features", "support", "env.rb")
empty_directory File.join(name, "fixtures")
end
# Template files are relative to this file
# @return [String]
def self.source_root

View file

@ -2,35 +2,35 @@ require "middleman-core/templates"
# CLI Module
module Middleman::Cli
# A thor task for creating new projects
class Init < Thor
check_unknown_options!
namespace :init
desc "init NAME [options]", "Create new project NAME"
available_templates = ::Middleman::Templates.registered.keys.join(", ")
method_option "template",
:aliases => "-T",
method_option "template",
:aliases => "-T",
:default => "default",
:desc => "Use a project template: #{available_templates}"
method_option "css_dir",
# :default => "stylesheets",
method_option "css_dir",
# :default => "stylesheets",
:desc => 'The path to the css files'
method_option "js_dir",
# :default => "javascripts",
method_option "js_dir",
# :default => "javascripts",
:desc => 'The path to the javascript files'
method_option "images_dir",
# :default => "images",
method_option "images_dir",
# :default => "images",
:desc => 'The path to the image files'
method_option "rack",
:type => :boolean,
:default => false,
method_option "rack",
:type => :boolean,
:default => false,
:desc => 'Include a config.ru file'
method_option "bundler",
:type => :boolean,
:default => false,
method_option "bundler",
:type => :boolean,
:default => false,
:desc => 'Create a Gemfile and use Bundler to manage gems'
# The init task
# @param [String] name
@ -39,7 +39,7 @@ module Middleman::Cli
unless ::Middleman::Templates.registered.has_key?(key)
raise Thor::Error.new "Unknown project template '#{key}'"
end
thor_group = ::Middleman::Templates.registered[key]
thor_group.new([name], options).invoke_all
end
@ -48,7 +48,7 @@ module Middleman::Cli
def self.exit_on_failure?
true
end
# Map "i", "new" and "n" to "init"
Base.map({
"i" => "init",

View file

@ -1,36 +1,36 @@
# CLI Module
module Middleman::Cli
# Server thor task
class Server < Thor
check_unknown_options!
namespace :server
desc "server [options]", "Start the preview server"
method_option :environment,
:aliases => "-e",
:default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development',
:aliases => "-e",
:default => ENV['MM_ENV'] || ENV['RACK_ENV'] || 'development',
:desc => "The environment Middleman will run under"
method_option :host,
:type => :string,
:aliases => "-h",
:default => "0.0.0.0",
:default => "0.0.0.0",
:desc => "Bind to HOST address"
method_option :port,
:aliases => "-p",
:default => "4567",
:aliases => "-p",
:default => "4567",
:desc => "The port Middleman will listen on"
method_option :verbose,
:type => :boolean,
:type => :boolean,
:default => false,
:desc => 'Print debug messages'
method_option :instrument,
:type => :string,
:type => :string,
:default => false,
:desc => 'Print instrument messages'
method_option "disable-watcher",
:type => :boolean,
method_option "disable-watcher",
:type => :boolean,
:default => false,
:desc => 'Disable the file change and delete watcher process'
method_option :profile,
@ -42,7 +42,7 @@ module Middleman::Cli
def server
require "middleman-core"
require "middleman-core/preview_server"
if !ENV["MM_ROOT"]
puts "== Could not find a Middleman project config.rb"
puts "== Treating directory as a static site to be served"
@ -58,7 +58,7 @@ module Middleman::Cli
:instrumenting => options["instrument"],
:"disable-watcher" => options["disable-watcher"]
}
puts "== The Middleman is loading"
::Middleman::PreviewServer.start(params)
end
@ -66,8 +66,8 @@ module Middleman::Cli
def self.exit_on_failure?
true
end
end
# Map "s" to "server"
Base.map({ "s" => "server" })
end

View file

@ -1,9 +1,9 @@
module Middleman
module CoreExtensions
# Convenience methods to allow config.rb to talk to the Builder
module Builder
# Extension registered
class << self
# @private
@ -14,4 +14,4 @@ module Middleman
end
end
end
end
end

View file

@ -1,10 +1,10 @@
module Middleman
module CoreExtensions
# The data extension parses YAML and JSON files in the data/ directory
# and makes them available to config.rb, templates and extensions
module Data
# Extension registered
class << self
# @private
@ -12,13 +12,13 @@ module Middleman
# Data formats
require "yaml"
require "active_support/json"
app.set :data_dir, "data"
app.send :include, InstanceMethods
end
alias :included :registered
end
# Instance methods
module InstanceMethods
# Setup data files before anything else so they are available when
@ -27,14 +27,14 @@ module Middleman
self.files.changed DataStore.matcher do |file|
self.data.touch_file(file) if file.match(%r{^#{self.data_dir}\/})
end
self.files.deleted DataStore.matcher do |file|
self.data.remove_file(file) if file.match(%r{^#{self.data_dir}\/})
end
super
end
# The data object
#
# @return [DataStore]
@ -42,13 +42,13 @@ module Middleman
@_data ||= DataStore.new(self)
end
end
# The core logic behind the data extension.
class DataStore
# Static methods
class << self
# The regex which tells Middleman which files are for data
#
# @return [Regexp]
@ -56,7 +56,7 @@ module Middleman
%r{[\w-]+\.(yml|yaml|json)$}
end
end
# Store static data hash
#
# @param [Symbol] name Name of the data, used for namespacing
@ -78,7 +78,7 @@ module Middleman
@_callback_sources[name.to_s] = proc unless name.nil? || proc.nil?
@_callback_sources
end
# Setup data store
#
# @param [Middleman::Application] app The current instance of Middleman
@ -86,7 +86,7 @@ module Middleman
@app = app
@local_data = {}
end
# Update the internal cache for a given file path
#
# @param [String] file The file to be re-parsed
@ -95,7 +95,7 @@ module Middleman
file = File.expand_path(file, @app.root)
extension = File.extname(file)
basename = File.basename(file, extension)
if %w(.yaml .yml).include?(extension)
data = YAML.load_file(file)
elsif extension == ".json"
@ -106,7 +106,7 @@ module Middleman
@local_data[basename] = ::Middleman::Util.recursively_enhance(data)
end
# Remove a given file from the internal cache
#
# @param [String] file The file to be cleared
@ -116,26 +116,26 @@ module Middleman
basename = File.basename(file, extension)
@local_data.delete(basename) if @local_data.has_key?(basename)
end
# Get a hash hash from either internal static data or a callback
#
# @param [String, Symbol] path The name of the data namespace
# @return [Hash, nil]
def data_for_path(path)
response = nil
@@local_sources ||= {}
@@callback_sources ||= {}
if self.store.has_key?(path.to_s)
response = self.store[path.to_s]
elsif self.callbacks.has_key?(path.to_s)
response = self.callbacks[path.to_s].call()
end
response
end
# "Magically" find namespaces of data if they exist
#
# @param [String] path The namespace to search for
@ -145,36 +145,36 @@ module Middleman
return @local_data[path.to_s]
else
result = data_for_path(path)
if result
return ::Middleman::Util.recursively_enhance(result)
end
end
super
end
# Convert all the data into a static hash
#
# @return [Hash]
def to_h
data = {}
self.store.each do |k, v|
data[k] = data_for_path(k)
end
self.callbacks.each do |k, v|
data[k] = data_for_path(k)
end
(@local_data || {}).each do |k, v|
data[k] = v
end
data
end
end
end
end
end
end

View file

@ -32,7 +32,7 @@
module Middleman
module CoreExtensions
module Extensions
# Register extension
class << self
# @private
@ -44,13 +44,13 @@ module Middleman
app.define_hook :before_configuration
app.define_hook :build_config
app.define_hook :development_config
if ENV["AUTOLOAD_SPROCKETS"]
app.set :autoload_sprockets, (ENV["AUTOLOAD_SPROCKETS"] == "true")
else
app.set :autoload_sprockets, true
end
app.extend ClassMethods
app.send :include, InstanceMethods
app.delegate :configure, :to => :"self.class"
@ -67,23 +67,23 @@ module Middleman
def configure(env, &block)
send("#{env}_config", &block)
end
# Alias `extensions` to access registered extensions
#
# @return [Array<Module>]
def extensions
@extensions ||= []
end
# Register a new extension
#
#
# @param [Module] extension Extension modules to register
# @param [Hash] options Per-extension options hash
# @return [void]
def register(extension, options={}, &block)
@extensions ||= []
@extensions += [extension]
extend extension
if extension.respond_to?(:registered)
if extension.method(:registered).arity === 1
@ -94,7 +94,7 @@ module Middleman
end
end
end
# Instance methods
module InstanceMethods
# This method is available in the project's `config.rb`.
@ -111,7 +111,7 @@ module Middleman
else
::Middleman::Extensions.load(ext.to_sym)
end
if ext_module.nil?
logger.warning "== Unknown Extension: #{ext}"
else
@ -119,24 +119,24 @@ module Middleman
self.class.register(ext_module, options, &block)
end
end
# Load features before starting server
def initialize
super
self.class.inst = self
run_hook :before_configuration
# Search the root of the project for required files
$LOAD_PATH.unshift(root)
# Check for and evaluate local configuration
local_config = File.join(root, "config.rb")
if File.exists? local_config
logger.debug "== Reading: Local config"
instance_eval File.read(local_config), local_config, 1
end
if autoload_sprockets
begin
require "middleman-sprockets"
@ -144,12 +144,12 @@ module Middleman
rescue LoadError
end
end
run_hook :build_config if build?
run_hook :development_config if development?
run_hook :after_configuration
logger.debug "Loaded extensions:"
self.class.extensions.each do |ext|
logger.debug "== Extension: #{ext}"
@ -158,4 +158,4 @@ module Middleman
end
end
end
end
end

View file

@ -2,10 +2,10 @@
module Middleman
module CoreExtensions
module ExternalHelpers
# Setup extension
class << self
# once registered
def registered(app)
# Setup a default helpers paths
@ -15,19 +15,19 @@ module Middleman
basename = File.basename(filename, File.extname(filename))
basename.camelcase
}
# After config
app.after_configuration do
helpers_path = File.expand_path(helpers_dir, root)
next unless File.exists?(helpers_path)
Dir[File.join(helpers_path, helpers_filename_glob)].each do |filename|
module_name = helpers_filename_to_module_name_proc.call(filename)
next unless module_name
require filename
next unless Object.const_defined?(module_name.to_sym)
helpers Object.const_get(module_name.to_sym)
end
end
@ -36,4 +36,4 @@ module Middleman
end
end
end
end
end

View file

@ -5,7 +5,7 @@ require "set"
module Middleman
module CoreExtensions
module FileWatcher
IGNORE_LIST = [
/^\.bundle\//,
/^\.sass-cache\//,
@ -22,16 +22,16 @@ module Middleman
# Setup extension
class << self
# Once registered
def registered(app)
app.send :include, InstanceMethods
# Before parsing config, load the data/ directory
app.before_configuration do
files.reload_path(data_dir)
end
# After config, load everything else
app.ready do
files.reload_path('.')
@ -39,32 +39,32 @@ module Middleman
end
alias :included :registered
end
# Instance methods
module InstanceMethods
# Access the file api
# @return [Middleman::CoreExtensions::FileWatcher::API]
def files
@_files_api ||= API.new(self)
end
end
# Core File Change API class
class API
attr_reader :app
delegate :logger, :to => :app
# Initialize api and internal path cache
def initialize(app)
@app = app
@known_paths = Set.new
@_changed = []
@_deleted = []
end
# Add callback to be run on file change
#
# @param [nil,Regexp] matcher A Regexp to match the change path against
@ -73,7 +73,7 @@ module Middleman
@_changed << [block, matcher] if block_given?
@_changed
end
# Add callback to be run on file deletion
#
# @param [nil,Regexp] matcher A Regexp to match the deleted path against
@ -82,7 +82,7 @@ module Middleman
@_deleted << [block, matcher] if block_given?
@_deleted
end
# Notify callbacks that a file changed
#
# @param [Pathname] path The file that changed
@ -104,7 +104,7 @@ module Middleman
@known_paths.delete(path)
self.run_callbacks(path, :deleted)
end
# Manually trigger update events
#
# @param [Pathname] path The path to reload
@ -115,20 +115,20 @@ module Middleman
Dir.chdir @app.root_path do
path = Pathname(path)
return unless path.exist?
glob = (path + "**/*").to_s
subset = @known_paths.select { |p| p.fnmatch(glob) }
::Middleman::Util.all_files_under(path).each do |filepath|
if only_new
next if subset.include?(filepath)
else
subset.delete(filepath)
end
self.did_change(filepath)
end
subset.each(&method(:did_delete)) unless only_new
end
end
@ -140,7 +140,7 @@ module Middleman
def find_new_files(path)
reload_path(path, true)
end
protected
# Whether this path is ignored
# @param [Pathname] path
@ -148,7 +148,7 @@ module Middleman
def ignored?(path)
IGNORE_LIST.any? { |r| path.to_s.match(r) }
end
# Notify callbacks for a file given an array of callbacks
#
# @param [Pathname] path The file that was changed

View file

@ -1,22 +1,22 @@
# Extensions namespace
module Middleman::CoreExtensions
# Frontmatter namespace
module FrontMatter
# Setup extension
class << self
# Once registered
def registered(app)
# Parsing YAML frontmatter
require "yaml"
# Parsing JSON frontmatter
require "active_support/json"
app.send :include, InstanceMethods
app.before_configuration do
files.changed { |file| frontmatter_manager.clear_data(file) }
files.deleted { |file| frontmatter_manager.clear_data(file) }
@ -29,36 +29,36 @@ module Middleman::CoreExtensions
:frontmatter,
frontmatter_manager
)
sitemap.provides_metadata do |path|
fmdata = frontmatter_manager.data(path).first
data = {}
%w(layout layout_engine).each do |opt|
data[opt.to_sym] = fmdata[opt] unless fmdata[opt].nil?
end
{ :options => data, :page => fmdata }
end
end
end
alias :included :registered
end
class FrontmatterManager
attr_reader :app
delegate :logger, :to => :app
def initialize(app)
@app = app
@cache = {}
end
def data(path)
p = normalize_path(path)
@cache[p] ||= frontmatter_and_content(p)
end
def clear_data(file)
# Copied from Sitemap::Store#file_to_path, but without
# removing the file extension
@ -69,13 +69,13 @@ module Middleman::CoreExtensions
@cache.delete(path)
end
YAML_ERRORS = [ Exception, ArgumentError ]
if defined?(Psych) && defined?(Psych::SyntaxError)
YAML_ERRORS << Psych::SyntaxError
end
# Parse YAML frontmatter out of a string
# @param [String] content
# @return [Array<Hash, String>]
@ -99,10 +99,10 @@ module Middleman::CoreExtensions
rescue
[{}, content]
end
def parse_json_front_matter(content)
json_regex = /\A(;;;\s*\n.*?\n?)^(;;;\s*$\n?)/m
if content =~ json_regex
content = content.sub(json_regex, "")
@ -122,16 +122,16 @@ module Middleman::CoreExtensions
rescue
[{}, content]
end
# Get the frontmatter and plain content from a file
# @param [String] path
# @return [Array<Thor::CoreExt::HashWithIndifferentAccess, String>]
def frontmatter_and_content(path)
full_path = File.expand_path(path, @app.source_dir)
content = File.read(full_path)
data = {}
begin
if content =~ /\A.*coding:/
lines = content.split(/\n/)
@ -150,11 +150,11 @@ module Middleman::CoreExtensions
[::Middleman::Util.recursively_enhance(data).freeze, content]
end
def normalize_path(path)
path.sub(@app.source_dir, "").sub(/^\//, "")
end
# Update the main sitemap resource list
# @return [void]
def manipulate_resource_list(resources)
@ -163,21 +163,21 @@ module Middleman::CoreExtensions
r.frontmatter_ignored = true
end
end
resources
end
end
module ResourceInstanceMethods
def frontmatter_ignored?
@_frontmatter_ignored || false
end
def frontmatter_ignored=(v)
@_frontmatter_ignored = v
end
def ignored?
if frontmatter_ignored?
true
@ -193,21 +193,21 @@ module Middleman::CoreExtensions
end
end
module InstanceMethods
# Access the Frontmatter API
def frontmatter_manager
@_frontmatter_manager ||= FrontmatterManager.new(self)
end
# Get the template data from a path
# @param [String] path
# @return [String]
def template_data_for_file(path)
frontmatter_manager.data(path).last
end
end
end
end

View file

@ -10,15 +10,15 @@ end
module Middleman
module CoreExtensions
module Rendering
# Setup extension
class << self
# Once registered
def registered(app)
# Include methods
app.send :include, InstanceMethods
# Activate custom renderers
require "middleman-core/renderers/erb"
app.register Middleman::Renderers::ERb
@ -61,7 +61,7 @@ module Middleman
app.register Middleman::Renderers::Slim
rescue LoadError
end
# Less Support
begin
require "middleman-core/renderers/less"
@ -69,17 +69,17 @@ module Middleman
rescue LoadError
end
end
alias :included :registered
end
# Custom error class for handling
class TemplateNotFound < RuntimeError
end
# Rendering instance methods
module InstanceMethods
# Add or overwrite a default template extension
#
# @param [Hash] extension_map
@ -89,7 +89,7 @@ module Middleman
@_template_extensions.merge!(extension_map) if extension_map
@_template_extensions
end
# Render a template, with layout, given a path
#
# @param [String] path
@ -103,8 +103,8 @@ module Middleman
# Store last engine for later (could be inside nested renders)
@current_engine, engine_was = engine, @current_engine
# Use a dup of self as a context so that instance variables set within
# Use a dup of self as a context so that instance variables set within
# the template don't persist for other templates.
context = self.dup
blocks.each do |block|
@ -126,26 +126,26 @@ module Middleman
raise "Tried to render a layout (calls yield) at #{path} like it was a template. Non-default layouts need to be in #{source}/layouts."
end
end
# Certain output file types don't use layouts
needs_layout = !%w(.js .json .css .txt).include?(File.extname(path))
# If we need a layout and have a layout, use it
if needs_layout && layout_path = fetch_layout(engine, opts)
content = render_individual_file(layout_path, locs, opts, context) { content }
end
# Return result
content
ensure
# Pop all the saved variables from earlier as we may be returning to a
# Pop all the saved variables from earlier as we may be returning to a
# previous render (layouts, partials, nested layouts).
@current_engine = engine_was
@content_blocks = nil
@current_locs = nil
@current_opts = nil
end
# Sinatra/Padrino compatible render method signature referenced by some view
# helpers. Especially partials.
#
@ -179,7 +179,7 @@ module Middleman
end
end
end
# Look in the root for the partial with the current engine
if !found_partial && !engine.nil?
found_partial, found_engine = resolve_template(data, :preferred_engine => engine, :try_without_underscore => true)
@ -207,17 +207,17 @@ module Middleman
# @return [String]
def render_individual_file(path, locs = {}, opts = {}, context = self, &block)
path = path.to_s
# Save current buffer for later
@_out_buf, _buf_was = "", @_out_buf
# Read from disk or cache the contents of the file
body = if opts[:template_body]
opts.delete(:template_body)
else
template_data_for_file(path)
end
# Merge per-extension options from config
extension = File.extname(path)
options = opts.merge(options_for_ext(extension))
@ -234,15 +234,15 @@ module Middleman
# Reset stored buffer
@_out_buf = _buf_was
end
# Get the template data from a path
# @param [String] path
# @return [String]
def template_data_for_file(path)
File.read(File.expand_path(path, source_dir))
end
# Get a hash of configuration options for a given file extension, from
# Get a hash of configuration options for a given file extension, from
# config.rb
#
# @param [String] ext
@ -252,7 +252,7 @@ module Middleman
cache.fetch(:options_for_ext, ext) do
options = {}
# Find all the engines which handle this extension in tilt. Look for
# Find all the engines which handle this extension in tilt. Look for
# config variables of that name and merge it
extension_class = ::Tilt[ext]
::Tilt.mappings.each do |ext, engines|
@ -264,7 +264,7 @@ module Middleman
options
end
end
# Find a layout for a given engine
#
# @param [Symbol] engine
@ -274,7 +274,7 @@ module Middleman
# The layout name comes from either the system default or the options
local_layout = opts.has_key?(:layout) ? opts[:layout] : layout
return false unless local_layout
# Look for engine-specific options
engine_options = respond_to?(engine) ? send(engine) : {}
@ -303,7 +303,7 @@ module Middleman
end
end
end
# Find a layout on-disk, optionally using a specific engine
# @param [String] name
# @param [Symbol] preferred_engine
@ -311,47 +311,47 @@ module Middleman
def locate_layout(name, preferred_engine=nil)
# Whether we've found the layout
layout_path = false
# If we prefer a specific engine
if !preferred_engine.nil?
# Check root
layout_path, layout_engine = resolve_template(name, :preferred_engine => preferred_engine)
# Check layouts folder
if !layout_path
layout_path, layout_engine = resolve_template(File.join("layouts", name.to_s), :preferred_engine => preferred_engine)
end
end
# Check root, no preference
if !layout_path
layout_path, layout_engine = resolve_template(name)
end
# Check layouts folder, no preference
if !layout_path
layout_path, layout_engine = resolve_template(File.join("layouts", name.to_s))
end
# Return the path
layout_path
end
# Allow layouts to be wrapped in the contents of other layouts
# @param [String, Symbol] layout_name
# @return [void]
def wrap_layout(layout_name, &block)
# Save current buffer for later
@_out_buf, _buf_was = "", @_out_buf
layout_path = locate_layout(layout_name, current_engine)
extension = File.extname(layout_path)
engine = extension[1..-1].to_sym
# Store last engine for later (could be inside nested renders)
@current_engine, engine_was = engine, @current_engine
begin
content = if block_given?
capture_html(&block)
@ -362,18 +362,18 @@ module Middleman
# Reset stored buffer
@_out_buf = _buf_was
end
concat_content render_individual_file(layout_path, @current_locs || {}, @current_opts || {}, self) { content }
ensure
@current_engine = engine_was
end
# The currently rendering engine
# @return [Symbol, nil]
def current_engine
@current_engine ||= nil
end
# Find a template on disk given a output path
# @param [String] request_path
# @param [Hash] options
@ -387,7 +387,7 @@ module Middleman
# By default, any engine will do
preferred_engine = "*"
# Unless we're specifically looking for a preferred engine
if options.has_key?(:preferred_engine)
extension_class = ::Tilt[options[:preferred_engine]]
@ -410,12 +410,12 @@ module Middleman
# Look for files that match
path_with_ext = on_disk_path + "." + preferred_engine
found_path = Dir[path_with_ext].find do |path|
::Tilt[path]
end
if !found_path && options[:try_without_underscore] &&
if !found_path && options[:try_without_underscore] &&
path_no_underscore = path_with_ext.
sub(relative_path, relative_path.sub(/^_/, "").
sub(/\/_/, "/"))
@ -423,7 +423,7 @@ module Middleman
::Tilt[path]
end
end
# If we found one, return it and the found engine
if found_path || (File.exists?(on_disk_path) && !File.directory?(on_disk_path))
engine = found_path ? File.extname(found_path)[1..-1].to_sym : nil

View file

@ -4,33 +4,33 @@ require "rack/file"
module Middleman
module CoreExtensions
# Base helper to manipulate asset paths
module Request
# Extension registered
class << self
# @private
def registered(app)
# CSSPIE HTC File
::Rack::Mime::MIME_TYPES['.htc'] = 'text/x-component'
# Let's serve all HTML as UTF-8
::Rack::Mime::MIME_TYPES['.html'] = 'text/html; charset=utf-8'
::Rack::Mime::MIME_TYPES['.htm'] = 'text/html; charset=utf-8'
app.extend ClassMethods
app.extend ServerMethods
Middleman.extend CompatibleClassMethods
# Include instance methods
app.send :include, InstanceMethods
end
alias :included :registered
end
module ClassMethods
# Reset Rack setup
#
@ -39,7 +39,7 @@ module Middleman
@app = nil
@prototype = nil
end
# The shared Rack instance being build
#
# @private
@ -47,7 +47,7 @@ module Middleman
def app
@app ||= ::Rack::Builder.new
end
# Get the static instance
#
# @private
@ -59,7 +59,7 @@ module Middleman
mm
end
end
# Set the shared instance
#
# @private
@ -68,27 +68,27 @@ module Middleman
def inst=(inst)
@inst = inst
end
# Return built Rack app
#
# @private
# @return [Rack::Builder]
def to_rack_app(&block)
inner_app = inst(&block)
(@middleware || []).each do |m|
app.use(m[0], *m[1], &m[2])
end
app.map("/") { run inner_app }
(@mappings || []).each do |m|
app.map(m[0], &m[1])
end
app
end
# Prototype app. Used in config.ru
#
# @private
@ -103,7 +103,7 @@ module Middleman
def call(env)
prototype.call(env)
end
# Use Rack middleware
#
# @param [Class] middleware Middleware module
@ -112,7 +112,7 @@ module Middleman
@middleware ||= []
@middleware << [middleware, args, block]
end
# Add Rack App mapped to specific path
#
# @param [String] map Path to map
@ -122,7 +122,7 @@ module Middleman
@mappings << [map, block]
end
end
module ServerMethods
# Create a new Class which is based on Middleman::Application
# Used to create a safe sandbox into which extensions and
@ -136,7 +136,7 @@ module Middleman
const_set("MiddlemanApplication#{@@servercounter}", Class.new(Middleman::Application))
end
end
module CompatibleClassMethods
# Create a new Class which is based on Middleman::Application
# Used to create a safe sandbox into which extensions and
@ -164,15 +164,15 @@ module Middleman
# @return [void]
def current_path=(path)
@current_path = path
@request = ::Thor::CoreExt::HashWithIndifferentAccess.new({
:path => path,
:params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {}
@request = ::Thor::CoreExt::HashWithIndifferentAccess.new({
:path => path,
:params => req ? ::Thor::CoreExt::HashWithIndifferentAccess.new(req.params) : {}
})
end
def use(*args, &block); self.class.use(*args, &block); end
def map(*args, &block); self.class.map(*args, &block); end
# Rack env
attr_accessor :env
@ -187,7 +187,7 @@ module Middleman
def call(env)
dup.call!(env)
end
# Rack Interface
#
# @param env Rack environment
@ -215,8 +215,8 @@ module Middleman
def halt(response)
throw :halt, response
end
# Core response method. We process the request, check with
# Core response method. We process the request, check with
# the sitemap, and return the correct file, response or status
# message.
#
@ -252,7 +252,7 @@ module Middleman
return send_file(resource.source_file, env, res) unless resource.template?
current_path = request_path.dup
# Set a HTTP content type based on the request's extensions
content_type(res, resource.mime_type)
@ -275,7 +275,7 @@ module Middleman
logger.debug "== Finishing Request: #{request_path} (#{(Time.now - start_time).round(2)}s)"
halt res.finish
end
# Add a new mime-type for a specific extension
#
# @param [Symbol] type File extension

View file

@ -2,22 +2,22 @@
module Middleman
module CoreExtensions
module Routing
# Setup extension
class << self
# Once registered
def registered(app)
# Include methods
app.send :include, InstanceMethods
end
alias :included :registered
end
# Routing instance methods
module InstanceMethods
# Takes a block which allows many pages to have the same layout
#
# with_layout :admin do
@ -29,13 +29,13 @@ module Middleman
# @return [void]
def with_layout(layout_name, &block)
old_layout = layout
set :layout, layout_name
instance_exec(&block) if block_given?
ensure
set :layout, old_layout
end
# The page method allows the layout to be set on a specific path
#
# page "/about.html", :layout => false
@ -45,36 +45,36 @@ module Middleman
# @param [Hash] opts
# @return [void]
def page(url, opts={}, &block)
blocks = []
blocks << block if block_given?
# Default layout
opts[:layout] = layout if opts[:layout].nil?
# If the url is a regexp
if url.is_a?(Regexp) || url.include?("*")
# Use the metadata loop for matching against paths at runtime
sitemap.provides_metadata_for_path url do |url|
{ :options => opts, :blocks => blocks }
end
return
end
# Normalized path
url = full_path(url)
# Setup proxy
if opts.has_key?(:proxy)
proxy(url, opts[:proxy])
if opts.has_key?(:ignore) && opts[:ignore]
ignore(opts[:proxy])
opts.delete(:ignore)
end
end
opts.delete(:proxy)
else
if opts.has_key?(:ignore) && opts[:ignore]
@ -82,7 +82,7 @@ module Middleman
opts.delete(:ignore)
end
end
# Setup a metadata matcher for rendering those options
sitemap.provides_metadata_for_path url do |url|
{ :options => opts, :blocks => blocks }
@ -91,4 +91,4 @@ module Middleman
end
end
end
end
end

View file

@ -3,7 +3,7 @@ module Middleman::CoreExtensions::RubyEncoding
# Setup extension
class << self
# Once registerd
def registered(app)
app.send :include, InstanceMethods

View file

@ -5,10 +5,10 @@ require 'rack/showexceptions'
module Middleman
module CoreExtensions
module ShowExceptions
# Setup extension
class << self
# Once registered
def registered(app)
# When in dev
@ -20,12 +20,12 @@ module Middleman
end
end
end
# Custom exception class
# TODO: Style this ourselves
class Middleware < ::Rack::ShowExceptions
end
end
end
end
end

View file

@ -59,16 +59,16 @@ module Middleman
# @private
def load_extensions_in_path
require "rubygems"
begin
require "middleman-more"
rescue LoadError
end
extensions = rubygems_latest_specs.select do |spec|
spec_has_file?(spec, EXTENSION_FILE)
end
extensions.each do |spec|
require spec.name
end
@ -100,4 +100,4 @@ module Middleman
File.exists?(full_path)
end
end
end
end

View file

@ -2,11 +2,11 @@
require "pathname"
module Middleman
class << self
def setup_load_paths
@_is_setup ||= begin
# Only look for config.rb if MM_ROOT isn't set
if !ENV["MM_ROOT"] && found_path = locate_root
ENV["MM_ROOT"] = found_path
@ -39,18 +39,18 @@ module Middleman
else
::Middleman.load_extensions_in_path
end
true
end
end
# Recursive method to find config.rb
def locate_root(cwd = Pathname.new(Dir.pwd))
return cwd.to_s if (cwd + 'config.rb').exist?
return false if cwd.root?
locate_root(cwd.parent)
end
end
end
end

View file

@ -3,17 +3,17 @@ require 'active_support/core_ext/logger'
require "securerandom"
module Middleman
# The Middleman Logger
class Logger < ::Logger
# Force output to STDOUT
def initialize(log_level=1, is_instrumenting=false, target=STDOUT)
super(STDOUT)
self.level = log_level
@instrumenting = is_instrumenting
if @instrumenting != false
::ActiveSupport::Notifications.subscribe(/\.middleman$/, self)
end
@ -26,4 +26,4 @@ module Middleman
self.info "== Instrument (#{evt.name.sub(/.middleman$/, '')}): #{evt.duration}ms"
end
end
end
end

View file

@ -1,17 +1,17 @@
require "webrick"
module Middleman
WINDOWS = !!(RUBY_PLATFORM =~ /(mingw|bccwin|wince|mswin32)/i) unless const_defined?(:WINDOWS)
module PreviewServer
DEFAULT_PORT = 4567
class << self
attr_reader :app
delegate :logger, :to => :app
# Start an instance of Middleman::Application
# @return [void]
def start(options={})
@ -19,12 +19,12 @@ module Middleman
if options[:environment]
set :environment, options[:environment].to_sym
end
logger(options[:debug] ? 0 : 1, options[:instrumenting] || false)
end
port = options[:port] || DEFAULT_PORT
logger.info "== The Middleman is standing watch on port #{port}"
@webrick ||= setup_webrick(
@ -32,17 +32,17 @@ module Middleman
port,
options[:debug] || false
)
mount_instance(app)
start_file_watcher unless options[:"disable-watcher"]
@initialized ||= false
unless @initialized
@initialized = true
register_signal_handlers unless ::Middleman::WINDOWS
# Save the last-used options so it may be re-used when
# reloading later on.
@last_options = options
@ -62,7 +62,7 @@ module Middleman
end
unmount_instance
end
# Simply stop, then start the server
# @return [void]
def reload
@ -76,17 +76,17 @@ module Middleman
stop
@webrick.shutdown
end
private
def start_file_watcher
# Watcher Library
require "listen"
return if @listener
@listener = Listen.to(Dir.pwd, :relative_paths => true)
@listener.change do |modified, added, removed|
added_and_modified = (modified + added)
@ -102,7 +102,7 @@ module Middleman
@app.files.did_change(path)
end
end
unless removed.empty?
# See if the changed file is config.rb or lib/*.rb
if needs_to_reload?(removed)
@ -116,11 +116,11 @@ module Middleman
end
end
end
# Don't block this thread
@listener.start(false)
end
# Trap the interupt signal and shut down smoothly
# @return [void]
def register_signal_handlers
@ -128,28 +128,28 @@ module Middleman
trap("TERM") { shutdown }
trap("QUIT") { shutdown }
end
# Initialize webrick
# Initialize webrick
# @return [void]
def setup_webrick(host, port, is_logging)
@host = host
@port = port
http_opts = {
:BindAddress => @host,
:Port => @port,
:AccessLog => []
}
if is_logging
http_opts[:Logger] = FilteredWebrickLog.new
else
http_opts[:Logger] = ::WEBrick::Log.new(nil, 0)
end
::WEBrick::HTTPServer.new(http_opts)
end
# Attach a new Middleman::Application instance
# @param [Middleman::Application] app
# @return [void]
@ -157,7 +157,7 @@ module Middleman
@app = app
@webrick.mount "/", ::Rack::Handler::WEBrick, @app.class.to_rack_app
end
# Detach the current Middleman::Application instance
# @return [void]
def unmount_instance

View file

@ -1,6 +1,6 @@
module Middleman
module Profiling
# The profiler instance. There can only be one!
def self.profiler=(prof)
@profiler = prof

View file

@ -1,12 +1,12 @@
# Require gem
require "coffee_script"
module Middleman
module Renderers
# CoffeeScript Renderer
module CoffeeScript
# Setup extension
class << self
# Once registered
@ -14,14 +14,14 @@ module Middleman
app.before_configuration do
template_extensions :coffee => :js
end
# Tell Tilt to use it as well (for inline scss blocks)
::Tilt.register 'coffee', DebuggingCoffeeScriptTemplate
::Tilt.prefer(DebuggingCoffeeScriptTemplate)
end
alias :included :registered
end
# A Template for Tilt which outputs debug messages
class DebuggingCoffeeScriptTemplate < ::Tilt::CoffeeScriptTemplate
# Add exception messaging
@ -30,7 +30,7 @@ module Middleman
# @return [String]
def evaluate(context, locals, &block)
return super if context.build?
begin
super
rescue ::ExecJS::RuntimeError => e
@ -42,4 +42,4 @@ module Middleman
end
end
end
end
end

View file

@ -4,17 +4,17 @@ module Middleman
module ERb
# Setup extension
class << self
# once registered
def registered(app)
# Setup a default ERb engine
app.set :erb_engine, :erb
app.set :erb_engine_prefix, ::Tilt
app.before_configuration do
template_extensions :erb => :html
end
# After config
app.after_configuration do
# Find the user's prefered engine
@ -24,7 +24,7 @@ module Middleman
engine = engine == "erb" ? "ERB" : engine.camelize
erb_engine = erb_engine_prefix.const_get("#{engine}Template")
end
# Tell Tilt to use the preferred engine
::Tilt.prefer(erb_engine)
end
@ -33,4 +33,4 @@ module Middleman
end
end
end
end
end

View file

@ -3,10 +3,10 @@ require "haml"
module Middleman
module Renderers
# Haml Renderer
module Haml
# Setup extension
class << self
# Once registered
@ -14,10 +14,10 @@ module Middleman
app.before_configuration do
template_extensions :haml => :html
end
# Add haml helpers to context
app.send :include, ::Haml::Helpers
# Setup haml helper paths
app.ready do
init_haml_helpers
@ -27,4 +27,4 @@ module Middleman
end
end
end
end
end

View file

@ -2,22 +2,22 @@ require "less"
module Middleman
module Renderers
# Sass renderer
module Less
# Setup extension
class << self
# Once registered
def registered(app)
# Default sass options
app.set :less, {}
app.before_configuration do
template_extensions :less => :css
end
app.after_configuration do
::Less.paths << File.expand_path(css_dir, source_dir)
end
@ -26,13 +26,13 @@ module Middleman
::Tilt.register 'less', LocalLoadingLessTemplate
::Tilt.prefer(LocalLoadingLessTemplate)
end
alias :included :registered
end
# A SassTemplate for Tilt which outputs debug messages
class LocalLoadingLessTemplate < ::Tilt::LessTemplate
def prepare
if ::Less.const_defined? :Engine
@engine = ::Less::Engine.new(data)
@ -41,9 +41,9 @@ module Middleman
@engine = parser.parse(data)
end
end
end
end
end
end
end

View file

@ -6,30 +6,30 @@ module Middleman
# Liquid Renderer
module Liquid
# Setup extension
class << self
# Once registerd
def registered(app)
app.before_configuration do
template_extensions :liquid => :html
end
# After config, setup liquid partial paths
app.after_configuration do
::Liquid::Template.file_system = ::Liquid::LocalFileSystem.new(source_dir)
# Convert data object into a hash for liquid
sitemap.provides_metadata %r{\.liquid$} do |path|
{ :locals => { :data => data.to_h } }
end
end
end
alias :included :registered
end
end
end
end
end

View file

@ -1,18 +1,18 @@
module Middleman
module Renderers
# Markdown renderer
module Markdown
# Setup extension
class << self
# Once registered
def registered(app)
# Set our preference for a markdown engine
app.set :markdown_engine, :maruku
app.set :markdown_engine_prefix, ::Tilt
app.before_configuration do
template_extensions :markdown => :html,
:mdown => :html,
@ -20,10 +20,10 @@ module Middleman
:mkd => :html,
:mkdn => :html
end
# Once configuration is parsed
app.after_configuration do
begin
# Look for the user's preferred engine
if markdown_engine == :redcarpet
@ -35,22 +35,22 @@ module Middleman
engine = markdown_engine.to_s
engine = engine == "rdiscount" ? "RDiscount" : engine.camelize
markdown_engine_prefix.const_get("#{engine}Template")
else
else
markdown_engine_prefix
end
# Tell tilt to use that engine
::Tilt.prefer(markdown_engine_klass)
end
end
rescue LoadError
logger.warn "Requested Markdown engine (#{markdown_engine}) not found. Maybe the gem needs to be installed and required?"
end
end
end
alias :included :registered
end
end
end
end

View file

@ -4,26 +4,26 @@ module Middleman
module Renderers
class RedcarpetTemplate < ::Tilt::RedcarpetTemplate::Redcarpet2
# Overwrite built-in Tilt version.
# Overwrite built-in Tilt version.
# Don't overload :renderer option with smartypants
# Support renderer-level options
def generate_renderer
return options.delete(:renderer) if options.has_key?(:renderer)
# Pick a renderer
renderer = MiddlemanRedcarpetHTML
# Support SmartyPants
if options.delete(:smartypants)
renderer = Class.new(renderer) do
include ::Redcarpet::Render::SmartyPants
end
end
# Renderer Options
possible_render_opts = [:filter_html, :no_images, :no_links, :no_styles, :safe_links_only, :with_toc_data, :hard_wrap, :xhtml]
render_options = possible_render_opts.inject({}) do |sum, opt|
sum[opt] = options.delete(opt) if options.has_key?(opt)
sum
@ -52,7 +52,7 @@ module Middleman
middleman_app.link_to(content, link, :title => title)
end
end
::Tilt.register RedcarpetTemplate, 'markdown', 'mkd', 'md'
end
end

View file

@ -2,23 +2,23 @@ require "sass"
module Middleman
module Renderers
# Sass renderer
module Sass
# Setup extension
class << self
# Once registered
def registered(app)
# Default sass options
app.set :sass, {}
# Location of SASS .sass_cache directory.
# @return [String]
# set :sass_cache_path, "/tmp/middleman-app-name/sass_cache"
app.set(:sass_cache_path) { File.join(app.root_path, '.sass_cache') } # runtime compile of path
app.before_configuration do
template_extensions :scss => :css,
:sass => :css
@ -32,19 +32,19 @@ module Middleman
::Tilt.register 'scss', ScssPlusCSSFilenameTemplate
::Tilt.prefer(ScssPlusCSSFilenameTemplate)
end
alias :included :registered
end
# A SassTemplate for Tilt which outputs debug messages
class SassPlusCSSFilenameTemplate < ::Tilt::SassTemplate
# Define the expected syntax for the template
# @return [Symbol]
def syntax
:sass
end
def prepare; end
# Add exception messaging
@ -54,31 +54,31 @@ module Middleman
def evaluate(context, locals, &block)
@context = context
@engine = ::Sass::Engine.new(data, sass_options)
begin
@engine.render
rescue ::Sass::SyntaxError => e
::Sass::SyntaxError.exception_to_css(e, :full_exception => true)
end
end
private
# Change Sass path, for url functions, to the build folder if we're building
# @return [Hash]
def sass_options
location_of_sass_file = File.expand_path(@context.source, @context.root)
parts = basename.split('.')
parts.pop
css_filename = File.join(location_of_sass_file, @context.css_dir, parts.join("."))
options.merge(:filename => eval_file, :line => line, :syntax => syntax, :css_filename => css_filename)
end
end
# SCSS version of the above template
class ScssPlusCSSFilenameTemplate < SassPlusCSSFilenameTemplate
# Define the expected syntax for the template
# @return [Symbol]
def syntax
@ -87,4 +87,4 @@ module Middleman
end
end
end
end
end

View file

@ -3,28 +3,28 @@ require "slim"
module Middleman
module Renderers
# Slim renderer
module Slim
# Setup extension
class << self
# Once registered
def registered(app)
app.before_configuration do
template_extensions :slim => :html
end
# Setup Slim options to work with partials
::Slim::Engine.set_default_options(
:buffer => '@_out_buf',
:buffer => '@_out_buf',
:generator => ::Temple::Generators::StringBuffer
)
end
alias :included :registered
end
end
end
end
end

View file

@ -7,72 +7,72 @@ require "middleman-core/sitemap/extensions/ignores"
# Core Sitemap Extensions
module Middleman
module Sitemap
# Setup Extension
class << self
# Once registered
def registered(app)
app.register Middleman::Sitemap::Extensions::Proxies
app.register Middleman::Sitemap::Extensions::Ignores
# Set to automatically convert some characters into a directory
app.set :automatic_directory_matcher, nil
# Setup callbacks which can exclude paths from the sitemap
app.set :ignored_sitemap_matchers, {
# dotfiles and folders in the root
:root_dotfiles => proc { |file| file.match(%r{^\.}) },
# Files starting with an dot, but not .htaccess
:source_dotfiles => proc { |file|
:source_dotfiles => proc { |file|
file.match(%r{/\.}) && !file.match(%r{/\.htaccess})
},
# Files starting with an underscore, but not a double-underscore
:partials => proc { |file| file.match(%r{/_}) && !file.match(%r{/__}) },
:layout => proc { |file|
:layout => proc { |file|
file.match(%r{^source/layout\.}) || file.match(%r{^source/layouts/})
}
}
# Include instance methods
app.send :include, InstanceMethods
# Initialize Sitemap
app.before_configuration do
sitemap
end
end
alias :included :registered
end
# Sitemap instance methods
module InstanceMethods
# Get the sitemap class instance
# @return [Middleman::Sitemap::Store]
def sitemap
@_sitemap ||= Store.new(self)
end
# Get the resource object for the current path
# @return [Middleman::Sitemap::Resource]
def current_page
current_resource
end
# Get the resource object for the current path
# @return [Middleman::Sitemap::Resource]
def current_resource
sitemap.find_resource_by_destination_path(current_path)
end
end
end
end

View file

@ -3,42 +3,42 @@ module Middleman
module Sitemap
module Extensions
module Ignores
# Setup extension
class << self
# Once registered
def registered(app)
# Include methods
app.send :include, InstanceMethods
::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods
end
alias :included :registered
end
# Helpers methods for Resources
module ResourceInstanceMethods
# Whether the Resource is ignored
# @return [Boolean]
def ignored?
@app.ignore_manager.ignored?(path) ||
@app.ignore_manager.ignored?(path) ||
(!proxy? &&
@app.ignore_manager.ignored?(source_file.sub("#{@app.source_dir}/", ""))
)
end
end
# Ignore-related instance methods
module InstanceMethods
def ignore_manager
@_ignore_manager ||= IgnoreManager.new(self)
end
# Ignore a path or add an ignore callback
# @param [String, Regexp] path Path glob expression, or path regex
# @return [void]
@ -46,7 +46,7 @@ module Middleman
ignore_manager.ignore(path, &block)
end
end
# Class to handle managing ignores
class IgnoreManager
def initialize(app)
@ -55,7 +55,7 @@ module Middleman
# Array of callbacks which can ass ignored
@ignored_callbacks = []
end
# Ignore a path or add an ignore callback
# @param [String, Regexp] path Path glob expression, or path regex
# @return [void]
@ -88,4 +88,4 @@ module Middleman
end
end
end
end
end

View file

@ -1,11 +1,11 @@
require 'set'
module Middleman
module Sitemap
module Extensions
class OnDisk
attr_accessor :sitemap
@ -14,22 +14,22 @@ module Middleman
def initialize(sitemap)
@sitemap = sitemap
@app = @sitemap.app
@file_paths_on_disk = Set.new
scoped_self = self
@waiting_for_ready = true
# Register file change callback
@app.files.changed do |file|
scoped_self.touch_file(file, !scoped_self.waiting_for_ready)
end
# Register file delete callback
@app.files.deleted do |file|
scoped_self.remove_file(file, !scoped_self.waiting_for_ready)
end
@app.ready do
scoped_self.waiting_for_ready = false
scoped_self.sitemap.rebuild_resource_list!(:on_disk_ready)
@ -57,7 +57,7 @@ module Middleman
# whether or not it belongs in the sitemap (like a partial)
@sitemap.rebuild_resource_list!(:touched_file) if rebuild
end
# Remove a file from the store
# @param [String] file
# @return [void]
@ -66,7 +66,7 @@ module Middleman
@sitemap.rebuild_resource_list!(:removed_file) if rebuild
end
end
# Update the main sitemap resource list
# @return [void]
def manipulate_resource_list(resources)

View file

@ -1,32 +1,32 @@
module Middleman
module Sitemap
module Extensions
module Proxies
# Setup extension
class << self
# Once registered
def registered(app)
::Middleman::Sitemap::Resource.send :include, ResourceInstanceMethods
# Include methods
app.send :include, InstanceMethods
end
alias :included :registered
end
module ResourceInstanceMethods
# Whether this page is a proxy
# @return [Boolean]
def proxy?
!!@proxied_to
end
# Set this page to proxy to a target path
# @param [String] target
# @return [void]
@ -35,13 +35,13 @@ module Middleman
raise "You can't proxy #{path} to itself!" if target == path
@proxied_to = target
end
# The path of the page this page is proxied to, or nil if it's not proxied.
# @return [String]
def proxied_to
@proxied_to
end
# Whether this page has a template file
# @return [Boolean]
def template?
@ -51,15 +51,15 @@ module Middleman
super
end
end
def get_source_file
if proxy?
proxy_resource = store.find_resource_by_path(proxied_to)
unless proxy_resource
raise "Path #{path} proxies to unknown file #{proxied_to}:#{store.resources.map(&:path)}"
end
if proxy_resource.proxy?
raise "You can't proxy #{path} to #{proxied_to} which is itself a proxy."
end
@ -68,24 +68,24 @@ module Middleman
end
end
end
module InstanceMethods
def proxy_manager
@_proxy_manager ||= ProxyManager.new(self)
end
def proxy(*args)
proxy_manager.proxy(*args)
end
end
class ProxyManager
def initialize(app)
@app = app
@proxy_paths = {}
end
# Setup a proxy from a path to a target
# @param [String] path
# @param [String] target

View file

@ -1,23 +1,23 @@
module Middleman
module Sitemap
module Extensions
module Traversal
# This resource's parent resource
# @return [Middleman::Sitemap::Resource, nil]
def parent
parts = path.split("/")
parts.pop if path.include?(app.index_file)
return nil if parts.length < 1
parts.pop
parts << app.index_file
parent_path = "/" + parts.join("/")
store.find_resource_by_destination_path(parent_path)
end
@ -57,13 +57,13 @@ module Middleman
return [] unless parent
parent.children.reject { |p| p == self }
end
# Whether this resource either a directory index, or has the same name as an existing directory in the source
# @return [Boolean]
def directory_index?
path.include?(app.index_file) || path =~ /\/$/ || eponymous_directory?
end
# Whether the resource has the same name as a directory in the source
# (e.g., if the resource is named 'gallery.html' and a path exists named 'gallery/', this would return true)
# @return [Boolean]
@ -71,7 +71,7 @@ module Middleman
full_path = File.join(app.source_dir, eponymous_directory_path)
!!(File.exists?(full_path) && File.directory?(full_path))
end
# The path for this resource if it were a directory, and not a file
# (e.g., for 'gallery.html' this would return 'gallery/')
# @return [String]
@ -81,4 +81,4 @@ module Middleman
end
end
end
end
end

View file

@ -2,33 +2,33 @@ require "middleman-core/sitemap/extensions/traversal"
module Middleman
# Sitemap namespace
# Sitemap namespace
module Sitemap
# Sitemap Resource class
class Resource
include Middleman::Sitemap::Extensions::Traversal
# @return [Middleman::Application]
attr_reader :app
delegate :logger, :instrument, :to => :app
# @return [Middleman::Sitemap::Store]
attr_reader :store
# The source path of this resource (relative to the source directory,
# without template extensions)
# @return [String]
attr_reader :path
# Set the on-disk source file for this resource
# @return [String]
# attr_reader :source_file
def source_file
@source_file || get_source_file
end
# Initialize resource with parent store and URL
# @param [Middleman::Sitemap::Store] store
# @param [String] path
@ -38,24 +38,24 @@ module Middleman
@app = @store.app
@path = path
@source_file = source_file
@destination_paths = [@path]
@local_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] }
end
# Whether this resource has a template file
# @return [Boolean]
def template?
return false if source_file.nil?
!::Tilt[source_file].nil?
end
# Get the metadata for both the current source_file and the current path
# @return [Hash]
def metadata
result = store.metadata_for_path(path).dup
file_meta = store.metadata_for_file(source_file).dup
if file_meta.has_key?(:blocks)
result[:blocks] << file_meta.delete(:blocks)
@ -69,7 +69,7 @@ module Middleman
result.deep_merge!(local_meta)
result[:blocks] = result[:blocks].flatten.compact
result
end
@ -82,32 +82,32 @@ module Middleman
@local_metadata.deep_merge!(metadata)
@local_metadata[:blocks] << block if block_given?
end
# Get the output/preview URL for this resource
# @return [String]
def destination_path
@destination_paths.last
end
# Set the output/preview URL for this resource
# @param [String] path
# @return [void]
def destination_path=(path)
@destination_paths << path
end
# Extension of the path (i.e. '.js')
# @return [String]
def ext
File.extname(path)
end
# Mime type of the path
# @return [String]
def mime_type
app.mime_type ext
end
# Render this resource
# @return [String]
def render(opts={}, locs={}, &block)
@ -124,7 +124,7 @@ module Middleman
if md.has_key?(:page)
app.data.store("page", md[:page])
end
blocks = md[:blocks].dup rescue []
blocks << block if block_given?
@ -132,7 +132,7 @@ module Middleman
app.render_template(source_file, locs, opts, blocks)
end
end
# A path without the directory index - so foo/index.html becomes
# just foo. Best for linking.
# @return [String]

View file

@ -2,10 +2,10 @@
require "active_support/core_ext/hash/deep_merge"
module Middleman
# Sitemap namespace
module Sitemap
# The Store class
#
# The Store manages a collection of Resource objects, which represent
@ -13,10 +13,10 @@ module Middleman
# which is the path relative to the source directory, minus any template
# extensions. All "path" parameters used in this class are source paths.
class Store
# @return [Middleman::Application]
attr_accessor :app
# Initialize with parent app
# @param [Middleman::Application] app
def initialize(app)
@ -25,10 +25,10 @@ module Middleman
@_cached_metadata = {}
@_lookup_cache = { :path => {}, :destination_path => {} }
@resource_list_manipulators = []
# Register classes which can manipulate the main site map list
register_resource_list_manipulator(:on_disk, Middleman::Sitemap::Extensions::OnDisk.new(self), false)
# Proxies
register_resource_list_manipulator(:proxies, @app.proxy_manager, false)
end
@ -42,7 +42,7 @@ module Middleman
@resource_list_manipulators << [name, inst]
rebuild_resource_list!(:registered_new) if immediately_rebuild
end
# Rebuild the list of resources from scratch, using registed manipulators
# @return [void]
def rebuild_resource_list!(reason=nil)
@ -59,7 +59,7 @@ module Middleman
newres
end
end
# Find a resource given its original path
# @param [String] request_path The original path of a resource.
# @return [Middleman::Sitemap::Resource]
@ -67,7 +67,7 @@ module Middleman
request_path = ::Middleman::Util.normalize_path(request_path)
@_lookup_cache[:path][request_path]
end
# Find a resource given its destination path
# @param [String] request_path The destination (output) path of a resource.
# @return [Middleman::Sitemap::Resource]
@ -75,7 +75,7 @@ module Middleman
request_path = ::Middleman::Util.normalize_path(request_path)
@_lookup_cache[:destination_path][request_path]
end
# Get the array of all resources
# @param [Boolean] include_ignored Whether to include ignored resources
# @return [Array<Middleman::Sitemap::Resource>]
@ -86,7 +86,7 @@ module Middleman
@resources.reject(&:ignored?)
end
end
# Register a handler to provide metadata on a file path
# @param [Regexp] matcher
# @return [Array<Array<Proc, Regexp>>]
@ -95,16 +95,16 @@ module Middleman
@_provides_metadata << [block, matcher] if block_given?
@_provides_metadata
end
# Get the metadata for a specific file
# @param [String] source_file
# @return [Hash]
def metadata_for_file(source_file)
blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] }
provides_metadata.inject(blank_metadata) do |result, (callback, matcher)|
next result if !matcher.nil? && !source_file.match(matcher)
metadata = callback.call(source_file)
if metadata.has_key?(:blocks)
@ -115,10 +115,10 @@ module Middleman
result.deep_merge(metadata)
end
end
# Register a handler to provide metadata on a url path
# @param [Regexp] matcher
# @param [Symbol] origin an indicator of where this metadata came from - only one
# @param [Symbol] origin an indicator of where this metadata came from - only one
# block per [matcher, origin] pair may exist.
# @return [Array<Array<Proc, Regexp>>]
def provides_metadata_for_path(matcher=nil, origin=nil, &block)
@ -138,7 +138,7 @@ module Middleman
end
@_provides_metadata_for_path
end
# Get the metadata for a specific URL
# @param [String] request_path
# @return [Hash]
@ -146,7 +146,7 @@ module Middleman
return @_cached_metadata[request_path] if @_cached_metadata[request_path]
blank_metadata = { :options => {}, :locals => {}, :page => {}, :blocks => [] }
@_cached_metadata[request_path] = provides_metadata_for_path.inject(blank_metadata) do |result, (callback, matcher)|
case matcher
when Regexp
@ -154,9 +154,9 @@ module Middleman
when String
next result unless File.fnmatch("/" + matcher.sub(%r{^/}, ''), "/#{request_path}")
end
metadata = callback.call(request_path)
if metadata.has_key?(:blocks)
result[:blocks] << metadata[:blocks]
metadata.delete(:blocks)
@ -165,26 +165,26 @@ module Middleman
result.deep_merge(metadata)
end
end
# Get the URL path for an on-disk file
# @param [String] file
# @return [String]
def file_to_path(file)
file = File.expand_path(file, @app.root)
prefix = @app.source_dir.sub(/\/$/, "") + "/"
return false unless file.start_with?(prefix)
path = file.sub(prefix, "")
# Replace a file name containing automatic_directory_matcher with a folder
unless @app.automatic_directory_matcher.nil?
path = path.gsub(@app.automatic_directory_matcher, "/")
end
extensionless_path(path)
end
# Get a path without templating extensions
# @param [String] file
# @return [String]

View file

@ -9,4 +9,4 @@ require "middleman-core/step_definitions/server_steps"
Before do
@aruba_timeout_seconds = 30
end
end

View file

@ -21,7 +21,7 @@ Given /^a fixture app "([^\"]*)"$/ do |path|
target_path = File.join(PROJECT_ROOT_PATH, "fixtures", path)
FileUtils.cp_r(target_path, current_dir)
step %Q{I cd to "#{path}"}
end

View file

@ -8,7 +8,7 @@ end
Given /^"([^\"]*)" feature is "([^\"]*)"$/ do |feature, state|
@initialize_commands ||= []
if state == "enabled"
@initialize_commands << lambda { activate(feature.to_sym) }
end
@ -16,7 +16,7 @@ end
Given /^"([^\"]*)" feature is "enabled" with "([^\"]*)"$/ do |feature, options_str|
@initialize_commands ||= []
options = eval("{#{options_str}}")
@initialize_commands << lambda { activate(feature.to_sym, options) }
@ -39,20 +39,20 @@ Given /^the Server is running$/ do
else
ENV["MM_SOURCE"] = ""
end
initialize_commands = @initialize_commands || []
initialize_commands.unshift lambda {
set :root, root_dir
set :environment, @current_env || :development
set :show_exceptions, false
}
@server_inst = Middleman::Application.server.inst do
initialize_commands.each do |p|
instance_exec(&p)
end
end
app_rack = @server_inst.class.to_rack_app
@browser = ::Rack::Test::Session.new(::Rack::MockSession.new(app_rack))
end

View file

@ -4,12 +4,12 @@ require "thor/group"
# Templates namespace
module Middleman::Templates
# Static methods
class << self
# Get list of registered templates and add new ones
#
#
# Middleman::Templates.register(:ext_name, klass)
#
# @param [Symbol] name The name of the template
@ -20,15 +20,15 @@ module Middleman::Templates
@_template_mappings[name] = klass if name && klass
@_template_mappings
end
# Middleman::Templates.register(name, klass)
alias :registered :register
end
# Base Template class. Handles basic options and paths.
class Base < ::Thor::Group
include Thor::Actions
def initialize(names, options)
super
source_paths << File.join(File.dirname(__FILE__), 'templates')
@ -36,25 +36,25 @@ module Middleman::Templates
# Required path for the new project to be generated
argument :location, :type => :string
# Name of the template being used to generate the project.
class_option :template, :default => "default"
# Output a config.ru file for Rack if --rack is passed
class_option :rack, :type => :boolean, :default => false
# Write a Rack config.ru file for project
# @return [void]
def generate_rack!
return unless options[:rack]
template "shared/config.ru", File.join(location, "config.ru")
end
# Write a Bundler Gemfile file for project
# @return [void]
def generate_bundler!
template "shared/Gemfile.tt", File.join(location, "Gemfile")
inside(location) do
::Middleman::Cli::Bundle.new.invoke(:bundle)
end unless ENV["TEST"]
@ -62,7 +62,7 @@ module Middleman::Templates
# Output a .gitignore file
class_option :git, :type => :boolean, :default => true
# Write a .gitignore file for project
# @return [void]
def generate_gitignore!

View file

@ -1,22 +1,22 @@
# Default Middleman template
class Middleman::Templates::Default < Middleman::Templates::Base
class_option "css_dir",
:default => "stylesheets",
class_option "css_dir",
:default => "stylesheets",
:desc => 'The path to the css files'
class_option "js_dir",
:default => "javascripts",
class_option "js_dir",
:default => "javascripts",
:desc => 'The path to the javascript files'
class_option "images_dir",
:default => "images",
class_option "images_dir",
:default => "images",
:desc => 'The path to the image files'
# Template files are relative to this file
# @return [String]
def self.source_root
File.dirname(__FILE__)
end
# Actually output the files
# @return [void]
def build_scaffold!
@ -31,8 +31,8 @@ class Middleman::Templates::Default < Middleman::Templates::Base
empty_directory File.join(location, "source", options[:images_dir])
copy_file "default/source/images/background.png", File.join(location, "source", options[:images_dir], "background.png")
copy_file "default/source/images/middleman.png", File.join(location, "source", options[:images_dir], "middleman.png")
end
end
end
# Register this template
Middleman::Templates.register(:default, Middleman::Templates::Default)
Middleman::Templates.register(:default, Middleman::Templates::Default)

View file

@ -1,4 +1,4 @@
PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
require "middleman-core"
require "middleman-core/step_definitions"
require File.join(PROJECT_ROOT_PATH, 'lib', '<%= name %>')
require File.join(PROJECT_ROOT_PATH, 'lib', '<%= name %>')

View file

@ -4,22 +4,22 @@ require "middleman-core"
# Extension namespace
module MyExtension
class << self
# Called when user `activate`s your extension
def registered(app, options={})
# Setup extension-specific config
app.set :config_variable, false
# Include class methods
# app.extend ClassMethods
# Include instance methods
# app.send :include, InstanceMethods
app.after_configuration do
# Do something
# config_variable is now either the default or the user's
# config_variable is now either the default or the user's
# setting from config.rb
end
end
@ -30,20 +30,20 @@ module MyExtension
# def a_class_method
# end
# end
# module InstanceMethods
# def an_instance_method
# end
# end
end
# Register extensions which can be activated
# Make sure we have the version of Middleman we expect
# ::Middleman::Extensions.register(:extension_name) do
#
#
# # Return the extension module
# ::MyExtension
#
# end
#
# end

View file

@ -1 +1 @@
require "<%= name %>"
require "<%= name %>"

View file

@ -1,22 +1,22 @@
# HTML5 Boilerplate template
class Middleman::Templates::Html5 < Middleman::Templates::Base
class_option "css_dir",
:default => "css",
class_option "css_dir",
:default => "css",
:desc => 'The path to the css files'
class_option "js_dir",
:default => "js",
class_option "js_dir",
:default => "js",
:desc => 'The path to the javascript files'
class_option "images_dir",
:default => "img",
class_option "images_dir",
:default => "img",
:desc => 'The path to the image files'
# Templates are relative to this file
# @return [String]
def self.source_root
File.dirname(__FILE__)
end
# Output the files
# @return [void]
def build_scaffold!
@ -27,4 +27,4 @@ class Middleman::Templates::Html5 < Middleman::Templates::Base
end
# Register the template
Middleman::Templates.register(:html5, Middleman::Templates::Html5)
Middleman::Templates.register(:html5, Middleman::Templates::Html5)

View file

View file

View file

@ -1,6 +1,6 @@
# Local templates
class Middleman::Templates::Local < Middleman::Templates::Base
# Look for templates in ~/.middleman
# @return [String]
def self.source_root
@ -11,15 +11,15 @@ class Middleman::Templates::Local < Middleman::Templates::Base
# @return [void]
def build_scaffold!
directory options[:template].to_s, location
end
end
end
# Iterate over the directories in the templates path and register each one.
Dir[File.join(Middleman::Templates::Local.source_root, "*")].each do |dir|
next unless File.directory?(dir)
template_file = File.join(dir, "template.rb")
if File.exists?(template_file)
require template_file
else

View file

@ -1,6 +1,6 @@
# Mobile HTML5 Boilerplate
class Middleman::Templates::Mobile < Middleman::Templates::Base
# Slightly different paths
class_option :css_dir, :default => "css"
class_option :js_dir, :default => "js"
@ -11,7 +11,7 @@ class Middleman::Templates::Mobile < Middleman::Templates::Base
def self.source_root
File.dirname(__FILE__)
end
# Output the files
# @return [void]
def build_scaffold!
@ -22,4 +22,4 @@ class Middleman::Templates::Mobile < Middleman::Templates::Base
end
# Register the template
Middleman::Templates.register(:mobile, Middleman::Templates::Mobile)
Middleman::Templates.register(:mobile, Middleman::Templates::Mobile)

View file

View file

View file

@ -11,7 +11,7 @@ require "thor"
require "pathname"
module Middleman
module Util
# The logger
@ -21,16 +21,16 @@ module Middleman
if !@_logger || args.length > 0
@_logger = ::Middleman::Logger.new(*args)
end
@_logger
end
# Facade for ActiveSupport/Notification
def self.instrument(name, payload={}, &block)
name << ".middleman" unless name =~ /\.middleman$/
::ActiveSupport::Notifications.instrument(name, payload, &block)
end
# Recursively convert a normal Hash into a HashWithIndifferentAccess
#
# @private
@ -52,13 +52,13 @@ module Middleman
data
end
end
# Normalize a path to not include a leading slash
# @param [String] path
# @return [String]
def self.normalize_path(path)
# The tr call works around a bug in Ruby's Unicode handling
path.sub(/^\//, "").tr('','')
path.sub(/^\//, "").tr('','')
end
# Extract the text of a Rack response as a string.
@ -79,7 +79,7 @@ module Middleman
response.to_s
end
end
# Takes a matcher, which can be a literal string
# or a string containing glob expressions, or a
# regexp, or a proc, or anything else that responds
@ -98,7 +98,7 @@ module Middleman
File.fnmatch(matcher.to_s, path)
end
end
# Get a recusive list of files inside a set of paths.
# Works with symlinks.
#
@ -129,7 +129,7 @@ module Middleman
end
# Whether the key is in the cache
#
#
# @param key Anything Hash can use as a key
# @return [Boolean]
def has_key?(key)

View file

@ -11,50 +11,50 @@ require File.join(File.dirname(__FILE__), "hooks/inheritable_attribute")
#
# after_dinner do puts "Ice cream!" end
# after_dinner :have_a_desert # => refers to CatWidget#have_a_desert
#
#
# Running the callbacks happens on instances. It will run the block and #have_a_desert from above.
#
# cat.run_hook :after_dinner
module Hooks
VERSION = "0.2.0"
def self.included(base)
base.extend InheritableAttribute
base.extend ClassMethods
end
module ClassMethods
def define_hook(name)
accessor_name = "_#{name}_callbacks"
setup_hook_accessors(accessor_name)
define_hook_writer(name, accessor_name)
end
# Like Hooks#run_hook but for the class. Note that +:callbacks+ must be class methods.
#
# Example:
#
# class Cat
# after_eight :grab_a_beer
#
#
# def self.grab_a_beer(*) # and so on...
#
#
# where <tt>Cat.run_hook :after_eight</tt> will call the class method +grab_a_beer+.
def run_hook(name, *args)
run_hook_for(name, self, *args)
end
end
def run_hook_for(name, scope, *args)
callbacks_for_hook(name).each do |callback|
if callback.kind_of? Symbol
scope.send(callback, *args)
else
scope.instance_exec(*args, &callback)
end
end
end
end
# Returns the callbacks for +name+. Handy if you want to run the callbacks yourself, say when
# they should be executed in another context.
#
@ -69,30 +69,30 @@ module Hooks
def callbacks_for_hook(name)
send("_#{name}_callbacks")
end
private
def define_hook_writer(hook, accessor_name)
self.send(:define_method, hook.to_sym) do |&block|
if self.class.respond_to?(hook)
self.class.send(hook.to_sym, &block)
end
end
instance_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{hook}(method=nil, &block)
#{accessor_name} << (block || method)
end
RUBY_EVAL
end
def setup_hook_accessors(accessor_name)
inheritable_attr(accessor_name)
send("#{accessor_name}=", []) # initialize ivar.
end
end
end
# Runs the callbacks (method/block) for the specified hook +name+. Additional arguments will
# Runs the callbacks (method/block) for the specified hook +name+. Additional arguments will
# be passed to the callback.
#
# Example:
@ -100,7 +100,7 @@ module Hooks
# cat.run_hook :after_dinner, "i want ice cream!"
#
# will invoke the callbacks like
#
#
# desert("i want ice cream!")
# block.call("i want ice cream!")
def run_hook(name, *args)

View file

@ -22,12 +22,12 @@ module Hooks
def #{name}=(v)
@#{name} = v
end
def #{name}
return @#{name} unless superclass.respond_to?(:#{name}) and value = superclass.#{name}
@#{name} ||= value.clone # only do this once.
end
}
end
end
end
end

View file

@ -3,76 +3,76 @@ require 'test_helper'
class HooksTest < Test::Unit::TestCase
class TestClass
include Hooks
def executed
@executed ||= [];
end
end
context "Hooks.define_hook" do
setup do
@klass = Class.new(TestClass)
@mum = @klass.new
@mum.class.define_hook :after_eight
end
should "provide accessors to the stored callbacks" do
assert_equal [], @klass._after_eight_callbacks
@klass._after_eight_callbacks << :dine
assert_equal [:dine], @klass._after_eight_callbacks
end
should "respond to Class.callbacks_for_hook" do
assert_equal [], @klass.callbacks_for_hook(:after_eight)
@klass.after_eight :dine
assert_equal [:dine], @klass.callbacks_for_hook(:after_eight)
end
context "creates a public writer for the hook that" do
should "accepts method names" do
@klass.after_eight :dine
assert_equal [:dine], @klass._after_eight_callbacks
end
should "accepts blocks" do
@klass.after_eight do true; end
assert @klass._after_eight_callbacks.first.kind_of? Proc
end
should "be inherited" do
@klass.after_eight :dine
subklass = Class.new(@klass)
assert_equal [:dine], subklass._after_eight_callbacks
end
end
context "Hooks#run_hook" do
should "run without parameters" do
@mum.instance_eval do
def a; executed << :a; nil; end
def b; executed << :b; end
self.class.after_eight :b
self.class.after_eight :a
end
@mum.run_hook(:after_eight)
assert_equal [:b, :a], @mum.executed
end
should "accept arbitrary parameters" do
@mum.instance_eval do
def a(me, arg); executed << arg+1; end
end
@mum.class.after_eight :a
@mum.class.after_eight lambda { |me, arg| me.executed << arg-1 }
@mum.run_hook(:after_eight, @mum, 1)
assert_equal [2, 0], @mum.executed
end
@ -82,7 +82,7 @@ class HooksTest < Test::Unit::TestCase
assert_equal [:c], @mum.executed
end
end
context "in class context" do
should "run a callback block" do
executed = []
@ -90,51 +90,51 @@ class HooksTest < Test::Unit::TestCase
executed << :klass
end
@klass.run_hook :after_eight
assert_equal [:klass], executed
end
should "run a class methods" do
executed = []
@klass.instance_eval do
after_eight :have_dinner
def have_dinner(executed)
executed << :have_dinner
end
end
@klass.run_hook :after_eight, executed
assert_equal [:have_dinner], executed
end
end
end
context "Deriving" do
setup do
@klass = Class.new(TestClass)
@mum = @klass.new
@mum.class.define_hook :after_eight
end
should "inherit the hook" do
@klass.class_eval do
after_eight :take_shower
def take_shower
executed << :take_shower
end
end
@kid = Class.new(@klass) do
after_eight :have_dinner
def have_dinner
executed << :have_dinner
end
end.new
assert_equal [:take_shower, :have_dinner], @kid.run_hook(:after_eight)
end
end

View file

@ -6,48 +6,48 @@ class HooksTest < Test::Unit::TestCase
@klass = Class.new(Object) do
extend Hooks::InheritableAttribute
end
@mum = @klass.new
@klass.inheritable_attr :drinks
end
should "provide a reader with empty inherited attributes, already" do
assert_equal nil, @klass.drinks
end
should "provide a reader with empty inherited attributes in a derived class" do
assert_equal nil, Class.new(@klass).drinks
#@klass.drinks = true
#Class.new(@klass).drinks # TODO: crashes.
end
should "provide an attribute copy in subclasses" do
@klass.drinks = []
assert @klass.drinks.object_id != Class.new(@klass).drinks.object_id
end
should "provide a writer" do
@klass.drinks = [:cabernet]
assert_equal [:cabernet], @klass.drinks
end
should "inherit attributes" do
@klass.drinks = [:cabernet]
subklass_a = Class.new(@klass)
subklass_a.drinks << :becks
subklass_b = Class.new(@klass)
assert_equal [:cabernet], @klass.drinks
assert_equal [:cabernet, :becks], subklass_a.drinks
assert_equal [:cabernet], subklass_b.drinks
end
should "not inherit attributes if we set explicitely" do
@klass.drinks = [:cabernet]
subklass = Class.new(@klass)
subklass.drinks = [:merlot] # we only want merlot explicitely.
assert_equal [:merlot], subklass.drinks # no :cabernet, here
end

View file

@ -1,4 +1,4 @@
require "middleman-core/load_paths"
::Middleman.setup_load_paths
require "middleman-core"
require "middleman-core"

2
middleman-more/.cane Normal file
View file

@ -0,0 +1,2 @@
--exclusions-file .cane-exclusions.yml
--no-doc

View file

@ -0,0 +1,3 @@
style:
- lib/middleman-more/extensions/minify_css/rainpress.rb
- lib/middleman-more/extensions/automatic_image_sizes/fastimage.rb

View file

@ -6,5 +6,5 @@ PROJECT_ROOT_PATH = File.dirname(File.dirname(File.dirname(__FILE__)))
core_root = File.expand_path("../../../../middleman-core/lib/middleman-core", __FILE__)
require core_root
require File.join(core_root, "step_definitions")
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-more')
require File.join(core_root, "step_definitions")
require File.join(PROJECT_ROOT_PATH, 'lib', 'middleman-more')

View file

@ -3,4 +3,4 @@ set :layout, false
activate :asset_host
set :asset_host do |asset|
"http://assets%d.example.com" % (asset.hash % 4)
end
end

Some files were not shown because too many files have changed in this diff Show more