diff --git a/lib/jekyll/configuration.rb b/lib/jekyll/configuration.rb index 05a097c7..43244b47 100644 --- a/lib/jekyll/configuration.rb +++ b/lib/jekyll/configuration.rb @@ -14,6 +14,8 @@ module Jekyll 'timezone' => nil, # use the local timezone + 'encoding' => nil, # use the system encoding + 'safe' => false, 'detach' => false, # default to not detaching the server 'show_drafts' => nil, diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 5f493800..44bd8b9a 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -20,16 +20,23 @@ module Jekyll self.content || '' end + # Returns merged optin hash for File.read of self.site (if exists) + # and a given param + def merged_file_read_opts(opts) + (self.site ? self.site.file_read_opts : {}).merge(opts) + end + # Read the YAML frontmatter. # # base - The String path to the dir containing the file. # name - The String filename of the file. + # opts - optional parameter to File.read, default at site configs # # Returns nothing. - def read_yaml(base, name) + def read_yaml(base, name, opts = {}) begin - self.content = File.read(File.join(base, name)) - + self.content = File.read_with_options(File.join(base, name), + merged_file_read_opts(opts)) if self.content =~ /\A(---\s*\n.*?\n?)^(---\s*$\n?)/m self.content = $POSTMATCH self.data = YAML.safe_load($1) diff --git a/lib/jekyll/core_ext.rb b/lib/jekyll/core_ext.rb index 1a7b1816..54f7c9d5 100644 --- a/lib/jekyll/core_ext.rb +++ b/lib/jekyll/core_ext.rb @@ -69,3 +69,18 @@ module Enumerable any? { |exp| File.fnmatch?(exp, e) } end end + +# Ruby 1.8's File.read don't support option. +# read_with_options ignore optional parameter for 1.8, +# and act as alias for 1.9 or later. +class File + if RUBY_VERSION < '1.9' + def self.read_with_options(path, opts = {}) + self.read(path) + end + else + def self.read_with_options(path, opts = {}) + self.read(path, opts) + end + end +end diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index ef7be1fc..6084631a 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -3,7 +3,7 @@ module Jekyll attr_accessor :config, :layouts, :posts, :pages, :static_files, :categories, :exclude, :include, :source, :dest, :lsi, :pygments, :permalink_style, :tags, :time, :future, :safe, :plugins, :limit_posts, - :show_drafts, :keep_files, :baseurl + :show_drafts, :keep_files, :baseurl, :file_read_opts attr_accessor :converters, :generators @@ -22,6 +22,9 @@ module Jekyll self.plugins = plugins_path self.permalink_style = config['permalink'].to_sym + self.file_read_opts = {} + self.file_read_opts[:encoding] = config['encoding'] if config['encoding'] + self.reset self.setup end diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb index 2b0d82b4..57095ce7 100644 --- a/lib/jekyll/tags/include.rb +++ b/lib/jekyll/tags/include.rb @@ -70,6 +70,11 @@ eos end end + # Grab file read opts in the context + def file_read_opts(context) + context.registers[:site].file_read_opts + end + def render(context) dir = File.join(context.registers[:site].source, INCLUDES_DIR) if error = validate_dir(dir, context.registers[:site].safe) @@ -81,7 +86,7 @@ eos return error end - partial = Liquid::Template.parse(source(file)) + partial = Liquid::Template.parse(source(file, context)) context.stack do context['include'] = parse_params(context) if @params @@ -108,8 +113,8 @@ eos end # This method allows to modify the file content by inheriting from the class. - def source(file) - File.read(file) + def source(file, context) + File.read_with_options(file, file_read_opts(context)) end end end diff --git a/site/docs/configuration.md b/site/docs/configuration.md index fa92c6d1..31bf7048 100644 --- a/site/docs/configuration.md +++ b/site/docs/configuration.md @@ -99,6 +99,22 @@ class="flag">flags (specified on the command-line) that control them.

timezone: TIMEZONE

+ + +

Encoding

+

+ Set the encoding of files by name. Only available for Ruby + 1.9 or later). + The default value is nil, which use Ruby default, + ASCII-8BIT. + Available encoding for the ruby in use, can be shown by + command ruby -e 'puts Encoding::list.join("\n")' +

+ + +

encoding: ENCODING

+ + @@ -266,6 +282,7 @@ include: ['.htaccess'] exclude: [] keep_files: ['.git','.svn'] timezone: nil +encoding: nil future: true show_drafts: nil diff --git a/test/test_convertible.rb b/test/test_convertible.rb index ee7fc8e3..694c152c 100644 --- a/test/test_convertible.rb +++ b/test/test_convertible.rb @@ -40,7 +40,7 @@ class TestConvertible < Test::Unit::TestCase should "not parse if there is encoding error in file" do name = 'broken_front_matter3.erb' out = capture_stdout do - ret = @convertible.read_yaml(@base, name) + ret = @convertible.read_yaml(@base, name, :encoding => 'utf-8') assert_equal({}, ret) end assert_match(/invalid byte sequence in UTF-8/, out)