Move block run

move_new_block
Thomas Reynolds 2016-01-12 16:03:23 -08:00
parent 8daa5eba3e
commit c213bd19df
14 changed files with 161 additions and 150 deletions

View File

@ -70,27 +70,27 @@ module Middleman
# Which port preview should start on. # Which port preview should start on.
# @return [Fixnum] # @return [Fixnum]
config.define_setting :port, 4567, 'The preview server port' define_setting :port, 4567, 'The preview server port'
# Which server name should be used # Which server name should be used
# @return [NilClass, String] # @return [NilClass, String]
config.define_setting :server_name, nil, 'The server name of preview server' define_setting :server_name, nil, 'The server name of preview server'
# Which bind address the preview server should use # Which bind address the preview server should use
# @return [NilClass, String] # @return [NilClass, String]
config.define_setting :bind_address, nil, 'The bind address of the preview server' define_setting :bind_address, nil, 'The bind address of the preview server'
# Whether to serve the preview server over HTTPS. # Whether to serve the preview server over HTTPS.
# @return [Boolean] # @return [Boolean]
config.define_setting :https, false, 'Serve the preview server over SSL/TLS' define_setting :https, false, 'Serve the preview server over SSL/TLS'
# The (optional) path to the SSL cert to use for the preview server. # The (optional) path to the SSL cert to use for the preview server.
# @return [String] # @return [String]
config.define_setting :ssl_certificate, nil, 'Path to an X.509 certificate to use for the preview server' define_setting :ssl_certificate, nil, 'Path to an X.509 certificate to use for the preview server'
# The (optional) private key for the certificate in :ssl_certificate. # The (optional) private key for the certificate in :ssl_certificate.
# @return [String] # @return [String]
config.define_setting :ssl_private_key, nil, "Path to an RSA private key for the preview server's certificate" define_setting :ssl_private_key, nil, "Path to an RSA private key for the preview server's certificate"
# Name of the source directory # Name of the source directory
# @return [String] # @return [String]
@ -214,6 +214,7 @@ module Middleman
@callbacks.install_methods!(self, [ @callbacks.install_methods!(self, [
:initialized, :initialized,
:configure, :configure,
:before_extensions,
:before_sitemap, :before_sitemap,
:before_configuration, :before_configuration,
:after_configuration, :after_configuration,
@ -245,6 +246,8 @@ module Middleman
::Middleman::FileRenderer.cache.clear ::Middleman::FileRenderer.cache.clear
::Middleman::TemplateRenderer.cache.clear ::Middleman::TemplateRenderer.cache.clear
execute_callbacks(:before_extensions)
@extensions = ::Middleman::ExtensionManager.new(self) @extensions = ::Middleman::ExtensionManager.new(self)
# Evaluate a passed block if given # Evaluate a passed block if given
@ -257,13 +260,6 @@ module Middleman
::Middleman::Extension.clear_after_extension_callbacks ::Middleman::Extension.clear_after_extension_callbacks
after_configuration_eval(&method(:prune_tilt_templates))
start_lifecycle
end
# Boot the app.
def start_lifecycle
# Before config is parsed, before extensions get to it. # Before config is parsed, before extensions get to it.
execute_callbacks(:initialized) execute_callbacks(:initialized)
@ -273,10 +269,6 @@ module Middleman
# Eval config. # Eval config.
evaluate_configuration! evaluate_configuration!
if Object.const_defined?(:Encoding)
Encoding.default_external = config[:encoding]
end
# Run any `configure` blocks for the current environment. # Run any `configure` blocks for the current environment.
execute_callbacks([:configure, config[:environment]]) execute_callbacks([:configure, config[:environment]])
@ -286,6 +278,12 @@ module Middleman
# Post parsing, pre-extension callback # Post parsing, pre-extension callback
execute_callbacks(:after_configuration_eval) execute_callbacks(:after_configuration_eval)
if Object.const_defined?(:Encoding)
Encoding.default_external = config[:encoding]
end
prune_tilt_templates!
# After extensions have worked after_config # After extensions have worked after_config
execute_callbacks(:after_configuration) execute_callbacks(:after_configuration)
@ -317,7 +315,7 @@ module Middleman
end end
# Clean up missing Tilt exts # Clean up missing Tilt exts
def prune_tilt_templates def prune_tilt_templates!
::Tilt.mappings.each do |key, _| ::Tilt.mappings.each do |key, _|
begin begin
::Tilt[".#{key}"] ::Tilt[".#{key}"]

View File

@ -8,6 +8,8 @@ module Middleman
class Data < Extension class Data < Extension
attr_reader :data_store attr_reader :data_store
define_setting :data_dir, 'data', 'The directory data files are stored in'
# Make the internal `data_store` method available as `app.data` # Make the internal `data_store` method available as `app.data`
expose_to_application data: :data_store expose_to_application data: :data_store
@ -21,7 +23,6 @@ module Middleman
super super
@data_store = DataStore.new(app, DATA_FILE_MATCHER) @data_store = DataStore.new(app, DATA_FILE_MATCHER)
app.config.define_setting :data_dir, 'data', 'The directory data files are stored in'
start_watching(app.config[:data_dir]) start_watching(app.config[:data_dir])
end end

View File

@ -17,6 +17,8 @@ class Padrino::Helpers::OutputHelpers::ErbHandler
end end
class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
define_setting :relative_links, false, 'Whether to generate relative links instead of absolute ones'
def initialize(app, options_hash={}, &block) def initialize(app, options_hash={}, &block)
super super
@ -30,8 +32,6 @@ class Middleman::CoreExtensions::DefaultHelpers < ::Middleman::Extension
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::RenderHelpers ::Middleman::TemplateContext.send :include, ::Padrino::Helpers::RenderHelpers
::Middleman::TemplateContext.send :include, ::Padrino::Helpers::NumberHelpers ::Middleman::TemplateContext.send :include, ::Padrino::Helpers::NumberHelpers
# ::Middleman::TemplateContext.send :include, ::Padrino::Helpers::TranslationHelpers # ::Middleman::TemplateContext.send :include, ::Padrino::Helpers::TranslationHelpers
app.config.define_setting :relative_links, false, 'Whether to generate relative links instead of absolute ones'
end end
# The helpers # The helpers

View File

@ -2,17 +2,12 @@ module Middleman
module CoreExtensions module CoreExtensions
# Load helpers in `helpers/` # Load helpers in `helpers/`
class ExternalHelpers < Extension class ExternalHelpers < Extension
def initialize(app, options_hash={}, &block) define_setting :helpers_dir, 'helpers', 'Directory to autoload helper modules from'
super define_setting :helpers_filename_glob, '**.rb', 'Glob pattern for matching helper ruby files'
define_setting :helpers_filename_to_module_name_proc, proc { |filename|
# Setup a default helpers paths basename = File.basename(filename, File.extname(filename))
app.config.define_setting :helpers_dir, 'helpers', 'Directory to autoload helper modules from' basename.camelcase
app.config.define_setting :helpers_filename_glob, '**.rb', 'Glob pattern for matching helper ruby files' }, 'Proc implementing the conversion from helper filename to module name'
app.config.define_setting :helpers_filename_to_module_name_proc, proc { |filename|
basename = File.basename(filename, File.extname(filename))
basename.camelcase
}, 'Proc implementing the conversion from helper filename to module name'
end
def after_configuration def after_configuration
helpers_path = File.join(app.root, app.config[:helpers_dir]) helpers_path = File.join(app.root, app.config[:helpers_dir])

View File

@ -24,8 +24,8 @@ module Middleman
normalized_path = '/' + ::Middleman::Util.strip_leading_slash(normalized_path) if normalized_path.is_a?(String) normalized_path = '/' + ::Middleman::Util.strip_leading_slash(normalized_path) if normalized_path.is_a?(String)
resources resources
.select { |r| ::Middleman::Util.path_match(normalized_path, "/#{r.path}")} .select { |r| ::Middleman::Util.path_match(normalized_path, "/#{r.path}") }
.each { |r| r.add_metadata(metadata) } .each { |r| r.add_metadata(metadata) }
resources resources
end end

View File

@ -3,13 +3,7 @@ require 'rack/showexceptions'
# Support rack/showexceptions during development # Support rack/showexceptions during development
module Middleman::CoreExtensions module Middleman::CoreExtensions
class ShowExceptions < ::Middleman::Extension class ShowExceptions < ::Middleman::Extension
def initialize(app, options_hash={}, &block) define_setting :show_exceptions, ENV['TEST'] ? false : true, 'Whether to catch and display exceptions'
super
return if app.config.defines_setting? :show_exceptions
app.config.define_setting :show_exceptions, ENV['TEST'] ? false : true, 'Whether to catch and display exceptions'
end
def ready def ready
app.use ::Rack::ShowExceptions if !app.build? && app.config[:show_exceptions] app.use ::Rack::ShowExceptions if !app.build? && app.config[:show_exceptions]

View File

@ -135,6 +135,23 @@ module Middleman
config.define_setting(key, default, description, options) config.define_setting(key, default, description, options)
end end
# @api private
# @return [Middleman::Configuration::ConfigurationManager] The defined global options for this extension.
def global_config
@_global_config ||= ::Middleman::Configuration::ConfigurationManager.new
end
# Add an global option to this extension.
# @see Middleman::Configuration::ConfigurationManager#define_setting
# @example
# option :compress, false, 'Whether to compress the output'
# @param [Symbol] key The name of the option
# @param [Object] default The default value for the option
# @param [String] description A human-readable description of what the option does
def define_setting(key, default=nil, description=nil, options={})
global_config.define_setting(key, default, description, options)
end
# Short-hand for simple Sitemap manipulation # Short-hand for simple Sitemap manipulation
# @example A generator which returns an array of resources # @example A generator which returns an array of resources
# resources :make_resources # resources :make_resources

View File

@ -9,6 +9,8 @@ module Middleman
@app = app @app = app
@activated = {} @activated = {}
::Middleman::Extensions.load_settings(@app)
manager = self manager = self
{ {

View File

@ -120,6 +120,18 @@ module Middleman
app.extensions.activate descriptor[:name] app.extensions.activate descriptor[:name]
end end
end end
def load_settings(app)
registered.each do |name, _|
begin
ext = load(name)
unless ext.global_config.all_settings.empty?
app.config.load_settings(ext.global_config.all_settings)
end
rescue LoadError
end
end
end
end end
end end
end end

View File

@ -4,12 +4,11 @@ module Middleman
module Renderers module Renderers
# Sass renderer # Sass renderer
class Less < ::Middleman::Extension class Less < ::Middleman::Extension
define_setting :less, {}, 'LESS compiler options'
def initialize(app, options={}, &block) def initialize(app, options={}, &block)
super super
# Default less options
app.config.define_setting :less, {}, 'LESS compiler options'
# Tell Tilt to use it as well (for inline sass blocks) # Tell Tilt to use it as well (for inline sass blocks)
::Tilt.register 'less', LocalLoadingLessTemplate ::Tilt.register 'less', LocalLoadingLessTemplate
::Tilt.prefer(LocalLoadingLessTemplate) ::Tilt.prefer(LocalLoadingLessTemplate)

View File

@ -2,14 +2,8 @@ module Middleman
module Renderers module Renderers
# Markdown renderer # Markdown renderer
class Markdown < ::Middleman::Extension class Markdown < ::Middleman::Extension
# Once registered define_setting :markdown_engine, :kramdown, 'Preferred markdown engine'
def initialize(app, options={}, &block) define_setting :markdown_engine_prefix, ::Tilt, 'The parent module for markdown template engines'
super
# Set our preference for a markdown engine
app.config.define_setting :markdown_engine, :kramdown, 'Preferred markdown engine'
app.config.define_setting :markdown_engine_prefix, ::Tilt, 'The parent module for markdown template engines'
end
# Once configuration is parsed # Once configuration is parsed
def after_configuration def after_configuration

View File

@ -1,9 +1,17 @@
require 'sass' require 'sass'
module Middleman module Middleman
module Renderers module Renderers
# Sass renderer # Sass renderer
class Sass < ::Middleman::Extension class Sass < ::Middleman::Extension
opts = { output_style: :nested }
opts[:line_comments] = false if ENV['TEST']
define_setting :sass, opts, 'Sass engine options'
define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files'
define_setting :sass_source_maps, nil, 'Whether to inline sourcemap into Sass'
# Setup extension # Setup extension
def initialize(app, options={}, &block) def initialize(app, options={}, &block)
super super
@ -12,15 +20,6 @@ module Middleman
app.files.ignore :sass_cache, :source, /(^|\/)\.sass-cache\// app.files.ignore :sass_cache, :source, /(^|\/)\.sass-cache\//
opts = { output_style: :nested }
opts[:line_comments] = false if ENV['TEST']
# Default sass options
app.config.define_setting :sass, opts, 'Sass engine options'
app.config.define_setting :sass_assets_paths, [], 'Paths to extra SASS/SCSS files'
app.config.define_setting :sass_source_maps, app.development?, 'Whether to inline sourcemap into Sass'
# Tell Tilt to use it as well (for inline sass blocks) # Tell Tilt to use it as well (for inline sass blocks)
::Tilt.register 'sass', SassPlusCSSFilenameTemplate ::Tilt.register 'sass', SassPlusCSSFilenameTemplate
::Tilt.prefer(SassPlusCSSFilenameTemplate) ::Tilt.prefer(SassPlusCSSFilenameTemplate)
@ -75,7 +74,7 @@ module Middleman
ctx = @context ctx = @context
more_opts = { more_opts = {
load_paths: ::Sass.load_paths | ctx.config[:sass_assets_paths], load_paths: ::Sass.load_paths | ctx.app.config[:sass_assets_paths],
filename: eval_file, filename: eval_file,
line: line, line: line,
syntax: syntax, syntax: syntax,
@ -85,7 +84,7 @@ module Middleman
) )
} }
if ctx.config[:sass_source_maps] if ctx.app.config[:sass_source_maps] || (ctx.app.config[:sass_source_maps].nil? && ctx.app.development?)
more_opts[:source_map_file] = '.' more_opts[:source_map_file] = '.'
more_opts[:source_map_embed] = true more_opts[:source_map_embed] = true
more_opts[:source_map_contents] = true more_opts[:source_map_contents] = true

View File

@ -4,11 +4,7 @@ require 'stylus/tilt'
module Middleman module Middleman
module Renderers module Renderers
class Stylus < ::Middleman::Extension class Stylus < ::Middleman::Extension
def initialize(app, options={}, &block) define_setting :styl, {}, 'Stylus config options'
super
app.config.define_setting :styl, {}, 'Stylus config options'
end
end end
end end
end end

View File

@ -5,98 +5,102 @@ require 'middleman-core/util'
require 'middleman-core/contracts' require 'middleman-core/contracts'
require 'backports/2.1.0/array/to_h' require 'backports/2.1.0/array/to_h'
module Middleman::Util::Data module Middleman
include Contracts module Util
module Data
include Contracts
module_function module_function
# Get the frontmatter and plain content from a file # Get the frontmatter and plain content from a file
# @param [String] path # @param [String] path
# @return [Array<Hash, String>] # @return [Array<Hash, String>]
Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]] Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]]
def parse(full_path, frontmatter_delims, known_type=nil) def parse(full_path, frontmatter_delims, known_type=nil)
return [{}, nil] if Middleman::Util.binary?(full_path) return [{}, nil] if Middleman::Util.binary?(full_path)
# Avoid weird race condition when a file is renamed # Avoid weird race condition when a file is renamed
begin begin
content = File.read(full_path) content = File.read(full_path)
rescue EOFError, IOError, Errno::ENOENT rescue EOFError, IOError, Errno::ENOENT
return [{}, nil] return [{}, nil]
end end
start_delims, stop_delims = frontmatter_delims start_delims, stop_delims = frontmatter_delims
.values .values
.flatten(1) .flatten(1)
.transpose .transpose
.map(&Regexp.method(:union)) .map(&Regexp.method(:union))
match = / match = /
\A(?:[^\r\n]*coding:[^\r\n]*\r?\n)? \A(?:[^\r\n]*coding:[^\r\n]*\r?\n)?
(?<start>#{start_delims})[ ]*\r?\n (?<start>#{start_delims})[ ]*\r?\n
(?<frontmatter>.*?)[ ]*\r?\n? (?<frontmatter>.*?)[ ]*\r?\n?
^(?<stop>#{stop_delims})[ ]*\r?\n? ^(?<stop>#{stop_delims})[ ]*\r?\n?
\r?\n? \r?\n?
(?<additional_content>.*) (?<additional_content>.*)
/mx.match(content) || {} /mx.match(content) || {}
unless match[:frontmatter] unless match[:frontmatter]
case known_type case known_type
when :yaml when :yaml
return [parse_yaml(content, full_path), nil] return [parse_yaml(content, full_path), nil]
when :json when :json
return [parse_json(content, full_path), nil] return [parse_json(content, full_path), nil]
end
end
case [match[:start], match[:stop]]
when *frontmatter_delims[:yaml]
[
parse_yaml(match[:frontmatter], full_path),
match[:additional_content]
]
when *frontmatter_delims[:json]
[
parse_json("{#{match[:frontmatter]}}", full_path),
match[:additional_content]
]
else
[
{},
content
]
end
end end
end
case [match[:start], match[:stop]] # Parse YAML frontmatter out of a string
when *frontmatter_delims[:yaml] # @param [String] content
[ # @return [Hash]
parse_yaml(match[:frontmatter], full_path), Contract String, Pathname, Bool => Hash
match[:additional_content] def parse_yaml(content, full_path)
] symbolize_recursive(YAML.load(content) || {})
when *frontmatter_delims[:json] rescue StandardError, Psych::SyntaxError => error
[ warn "YAML Exception parsing #{full_path}: #{error.message}"
parse_json("{#{match[:frontmatter]}}", full_path), {}
match[:additional_content] end
]
else
[
{},
content
]
end
end
# Parse YAML frontmatter out of a string # Parse JSON frontmatter out of a string
# @param [String] content # @param [String] content
# @return [Hash] # @return [Hash]
Contract String, Pathname, Bool => Hash Contract String, Pathname => Hash
def parse_yaml(content, full_path) def parse_json(content, full_path)
symbolize_recursive(YAML.load(content) || {}) symbolize_recursive(JSON.parse(content) || {})
rescue StandardError, Psych::SyntaxError => error rescue StandardError => error
warn "YAML Exception parsing #{full_path}: #{error.message}" warn "JSON Exception parsing #{full_path}: #{error.message}"
{} {}
end end
# Parse JSON frontmatter out of a string def symbolize_recursive(value)
# @param [String] content case value
# @return [Hash] when Hash
Contract String, Pathname => Hash value.map { |k, v| [k.to_sym, symbolize_recursive(v)] }.to_h
def parse_json(content, full_path) when Array
symbolize_recursive(JSON.parse(content) || {}) value.map { |v| symbolize_recursive(v) }
rescue StandardError => error else
warn "JSON Exception parsing #{full_path}: #{error.message}" value
{} end
end end
def symbolize_recursive(value)
case value
when Hash
value.map { |k, v| [k.to_sym, symbolize_recursive(v)] }.to_h
when Array
value.map { |v| symbolize_recursive(v) }
else
value
end end
end end
end end