bunto 3.0.0 → 3.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +124 -76
  3. data/README.markdown +49 -12
  4. data/{bin → exe}/bunto +18 -14
  5. data/lib/bunto.rb +83 -78
  6. data/lib/bunto/cleaner.rb +10 -8
  7. data/lib/bunto/collection.rb +33 -17
  8. data/lib/bunto/command.rb +19 -13
  9. data/lib/bunto/commands/build.rb +22 -14
  10. data/lib/bunto/commands/clean.rb +9 -8
  11. data/lib/bunto/commands/doctor.rb +10 -8
  12. data/lib/bunto/commands/help.rb +4 -3
  13. data/lib/bunto/commands/new.rb +30 -21
  14. data/lib/bunto/commands/new_theme.rb +36 -0
  15. data/lib/bunto/commands/serve.rb +26 -20
  16. data/lib/bunto/commands/serve/servlet.rb +4 -5
  17. data/lib/bunto/configuration.rb +187 -125
  18. data/lib/bunto/converters/markdown.rb +19 -9
  19. data/lib/bunto/converters/markdown/kramdown_parser.rb +12 -5
  20. data/lib/bunto/converters/markdown/rdiscount_parser.rb +4 -4
  21. data/lib/bunto/converters/markdown/redcarpet_parser.rb +90 -84
  22. data/lib/bunto/convertible.rb +38 -25
  23. data/lib/bunto/deprecator.rb +11 -6
  24. data/lib/bunto/desktop.ini +2 -0
  25. data/lib/bunto/document.rb +53 -51
  26. data/lib/bunto/drops/bunto_drop.rb +12 -0
  27. data/lib/bunto/drops/document_drop.rb +40 -5
  28. data/lib/bunto/drops/drop.rb +49 -10
  29. data/lib/bunto/drops/excerpt_drop.rb +15 -0
  30. data/lib/bunto/drops/site_drop.rb +4 -2
  31. data/lib/bunto/drops/url_drop.rb +4 -4
  32. data/lib/bunto/entry_filter.rb +64 -19
  33. data/lib/bunto/errors.rb +6 -3
  34. data/lib/bunto/excerpt.rb +4 -6
  35. data/lib/bunto/external.rb +4 -4
  36. data/lib/bunto/filters.rb +72 -39
  37. data/lib/bunto/frontmatter_defaults.rb +45 -38
  38. data/lib/bunto/hooks.rb +21 -21
  39. data/lib/bunto/layout.rb +4 -8
  40. data/lib/bunto/liquid_renderer.rb +14 -3
  41. data/lib/bunto/liquid_renderer/file.rb +5 -1
  42. data/lib/bunto/liquid_renderer/table.rb +11 -11
  43. data/lib/bunto/log_adapter.rb +2 -2
  44. data/lib/bunto/page.rb +10 -10
  45. data/lib/bunto/plugin.rb +5 -5
  46. data/lib/bunto/plugin_manager.rb +12 -8
  47. data/lib/bunto/publisher.rb +1 -1
  48. data/lib/bunto/reader.rb +11 -7
  49. data/lib/bunto/readers/data_reader.rb +9 -9
  50. data/lib/bunto/readers/layout_reader.rb +7 -7
  51. data/lib/bunto/readers/page_reader.rb +3 -1
  52. data/lib/bunto/readers/post_reader.rb +9 -10
  53. data/lib/bunto/readers/static_file_reader.rb +3 -1
  54. data/lib/bunto/regenerator.rb +50 -28
  55. data/lib/bunto/related_posts.rb +1 -1
  56. data/lib/bunto/renderer.rb +33 -23
  57. data/lib/bunto/site.rb +94 -51
  58. data/lib/bunto/static_file.rb +33 -26
  59. data/lib/bunto/stevenson.rb +6 -5
  60. data/lib/bunto/tags/highlight.rb +50 -35
  61. data/lib/bunto/tags/include.rb +42 -31
  62. data/lib/bunto/tags/link.rb +11 -4
  63. data/lib/bunto/tags/post_url.rb +8 -7
  64. data/lib/bunto/theme.rb +10 -8
  65. data/lib/bunto/theme_builder.rb +117 -0
  66. data/lib/bunto/url.rb +21 -14
  67. data/lib/bunto/utils.rb +57 -28
  68. data/lib/bunto/utils/ansi.rb +9 -9
  69. data/lib/bunto/utils/platforms.rb +2 -2
  70. data/lib/bunto/version.rb +1 -1
  71. data/lib/site_template/_config.yml +3 -1
  72. data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +3 -3
  73. data/lib/site_template/about.md +3 -3
  74. data/lib/site_template/css/main.scss +3 -17
  75. data/lib/theme_template/CODE_OF_CONDUCT.md.erb +74 -0
  76. data/lib/theme_template/Gemfile +2 -0
  77. data/lib/theme_template/LICENSE.txt.erb +21 -0
  78. data/lib/theme_template/README.md.erb +48 -0
  79. data/lib/theme_template/_layouts/default.html +1 -0
  80. data/lib/theme_template/_layouts/page.html +5 -0
  81. data/lib/theme_template/_layouts/post.html +5 -0
  82. data/lib/theme_template/example/_config.yml.erb +1 -0
  83. data/lib/theme_template/example/_post.md +12 -0
  84. data/lib/theme_template/example/index.html +14 -0
  85. data/lib/theme_template/example/style.scss +7 -0
  86. data/lib/theme_template/gitignore.erb +4 -0
  87. data/lib/theme_template/theme.gemspec.erb +18 -0
  88. metadata +40 -19
  89. data/lib/site_template/_includes/footer.html +0 -38
  90. data/lib/site_template/_includes/head.html +0 -12
  91. data/lib/site_template/_includes/header.html +0 -27
  92. data/lib/site_template/_includes/icon-github.html +0 -1
  93. data/lib/site_template/_includes/icon-github.svg +0 -1
  94. data/lib/site_template/_includes/icon-twitter.html +0 -1
  95. data/lib/site_template/_includes/icon-twitter.svg +0 -1
  96. data/lib/site_template/_layouts/default.html +0 -20
  97. data/lib/site_template/_layouts/page.html +0 -14
  98. data/lib/site_template/_layouts/post.html +0 -15
  99. data/lib/site_template/_sass/_base.scss +0 -200
  100. data/lib/site_template/_sass/_layout.scss +0 -242
  101. data/lib/site_template/_sass/_syntax-highlighting.scss +0 -71
@@ -9,23 +9,33 @@ module Bunto
9
9
  return if @setup ||= false
10
10
  unless (@parser = get_processor)
11
11
  Bunto.logger.error "Invalid Markdown processor given:", @config["markdown"]
12
- Bunto.logger.info "", "Custom processors are not loaded in safe mode" if @config["safe"]
13
- Bunto.logger.error "", "Available processors are: #{valid_processors.join(", ")}"
12
+ if @config["safe"]
13
+ Bunto.logger.info "", "Custom processors are not loaded in safe mode"
14
+ end
15
+ Bunto.logger.error(
16
+ "",
17
+ "Available processors are: #{valid_processors.join(", ")}"
18
+ )
14
19
  raise Errors::FatalException, "Bailing out; invalid Markdown processor."
15
20
  end
16
21
 
17
22
  @setup = true
18
23
  end
19
24
 
25
+ # Rubocop does not allow reader methods to have names starting with `get_`
26
+ # To ensure compatibility, this check has been disabled on this method
27
+ #
28
+ # rubocop:disable Style/AccessorMethodName
20
29
  def get_processor
21
30
  case @config["markdown"].downcase
22
31
  when "redcarpet" then return RedcarpetParser.new(@config)
23
32
  when "kramdown" then return KramdownParser.new(@config)
24
33
  when "rdiscount" then return RDiscountParser.new(@config)
25
34
  else
26
- get_custom_processor
35
+ custom_processor
27
36
  end
28
37
  end
38
+ # rubocop:enable Style/AccessorMethodName
29
39
 
30
40
  # Public: Provides you with a list of processors, the ones we
31
41
  # support internally and the ones that you have provided to us (if you
@@ -41,13 +51,13 @@ module Bunto
41
51
 
42
52
  def third_party_processors
43
53
  self.class.constants - \
44
- %w(KramdownParser RDiscountParser RedcarpetParser PRIORITIES).map(
45
- &:to_sym
46
- )
54
+ %w(KramdownParser RDiscountParser RedcarpetParser PRIORITIES).map(
55
+ &:to_sym
56
+ )
47
57
  end
48
58
 
49
59
  def extname_list
50
- @extname_list ||= @config['markdown_ext'].split(',').map do |e|
60
+ @extname_list ||= @config["markdown_ext"].split(",").map do |e|
51
61
  ".#{e.downcase}"
52
62
  end
53
63
  end
@@ -66,7 +76,7 @@ module Bunto
66
76
  end
67
77
 
68
78
  private
69
- def get_custom_processor
79
+ def custom_processor
70
80
  converter_name = @config["markdown"]
71
81
  if custom_class_allowed?(converter_name)
72
82
  self.class.const_get(converter_name).new(@config)
@@ -83,7 +93,7 @@ module Bunto
83
93
 
84
94
  private
85
95
  def custom_class_allowed?(parser_name)
86
- parser_name !~ /[^A-Za-z0-9_]/ && self.class.constants.include?(
96
+ parser_name !~ %r![^A-Za-z0-9_]! && self.class.constants.include?(
87
97
  parser_name.to_sym
88
98
  )
89
99
  end
@@ -24,7 +24,8 @@ module Bunto
24
24
 
25
25
  # Setup and normalize the configuration:
26
26
  # * Create Kramdown if it doesn't exist.
27
- # * Set syntax_highlighter, detecting enable_coderay and merging highlighter if none.
27
+ # * Set syntax_highlighter, detecting enable_coderay and merging
28
+ # highlighter if none.
28
29
  # * Merge kramdown[coderay] into syntax_highlighter_opts stripping coderay_.
29
30
  # * Make sure `syntax_highlighter_opts` exists.
30
31
 
@@ -52,7 +53,9 @@ module Bunto
52
53
  end
53
54
  end
54
55
 
55
- # config[kramdown][syntax_higlighter] > config[kramdown][enable_coderay] > config[highlighter]
56
+ # config[kramdown][syntax_higlighter] >
57
+ # config[kramdown][enable_coderay] >
58
+ # config[highlighter]
56
59
  # Where `enable_coderay` is now deprecated because Kramdown
57
60
  # supports Rouge now too.
58
61
 
@@ -68,8 +71,10 @@ module Bunto
68
71
 
69
72
  @highlighter = begin
70
73
  if @config.key?("enable_coderay") && @config["enable_coderay"]
71
- Bunto::Deprecator.deprecation_message "You are using 'enable_coderay', " \
74
+ Bunto::Deprecator.deprecation_message(
75
+ "You are using 'enable_coderay', " \
72
76
  "use syntax_highlighter: coderay in your configuration file."
77
+ )
73
78
 
74
79
  "coderay"
75
80
  else
@@ -81,7 +86,7 @@ module Bunto
81
86
  private
82
87
  def strip_coderay_prefix(hash)
83
88
  hash.each_with_object({}) do |(key, val), hsh|
84
- cleaned_key = key.gsub(/\Acoderay_/, "")
89
+ cleaned_key = key.gsub(%r!\Acoderay_!, "")
85
90
 
86
91
  if key != cleaned_key
87
92
  Bunto::Deprecator.deprecation_message(
@@ -100,8 +105,10 @@ module Bunto
100
105
  private
101
106
  def modernize_coderay_config
102
107
  if highlighter == "coderay"
103
- Bunto::Deprecator.deprecation_message "You are using 'kramdown.coderay' in your configuration, " \
108
+ Bunto::Deprecator.deprecation_message(
109
+ "You are using 'kramdown.coderay' in your configuration, " \
104
110
  "please use 'syntax_highlighter_opts' instead."
111
+ )
105
112
 
106
113
  @config["syntax_highlighter_opts"] = begin
107
114
  strip_coderay_prefix(
@@ -5,14 +5,14 @@ module Bunto
5
5
  def initialize(config)
6
6
  Bunto::External.require_with_graceful_fail "rdiscount"
7
7
  @config = config
8
- @rdiscount_extensions = @config['rdiscount']['extensions'].map(&:to_sym)
8
+ @rdiscount_extensions = @config["rdiscount"]["extensions"].map(&:to_sym)
9
9
  end
10
10
 
11
11
  def convert(content)
12
12
  rd = RDiscount.new(content, *@rdiscount_extensions)
13
13
  html = rd.to_html
14
- if @config['rdiscount']['toc_token']
15
- html = replace_generated_toc(rd, html, @config['rdiscount']['toc_token'])
14
+ if @config["rdiscount"]["toc_token"]
15
+ html = replace_generated_toc(rd, html, @config["rdiscount"]["toc_token"])
16
16
  end
17
17
  html
18
18
  end
@@ -21,7 +21,7 @@ module Bunto
21
21
  def replace_generated_toc(rd, html, toc_token)
22
22
  if rd.generate_toc && html.include?(toc_token)
23
23
  utf8_toc = rd.toc_content
24
- utf8_toc.force_encoding('utf-8') if utf8_toc.respond_to?(:force_encoding)
24
+ utf8_toc.force_encoding("utf-8") if utf8_toc.respond_to?(:force_encoding)
25
25
  html.gsub(toc_token, utf8_toc)
26
26
  else
27
27
  html
@@ -1,102 +1,108 @@
1
- module Bunto
2
- module Converters
3
- class Markdown
4
- class RedcarpetParser
5
- module CommonMethods
6
- def add_code_tags(code, lang)
7
- code = code.to_s
8
- code = code.sub(/<pre>/, "<pre><code class=\"language-#{lang}\" data-lang=\"#{lang}\">")
9
- code = code.sub(/<\/pre>/, "</code></pre>")
10
- code
11
- end
12
- end
13
-
14
- module WithPygments
15
- include CommonMethods
16
- def block_code(code, lang)
17
- Bunto::External.require_with_graceful_fail("pygments")
18
- lang = lang && lang.split.first || "text"
19
- add_code_tags(
20
- Pygments.highlight(code, :lexer => lang, :options => { :encoding => 'utf-8' }),
21
- lang
22
- )
23
- end
24
- end
1
+ class Bunto::Converters::Markdown::RedcarpetParser
2
+ module CommonMethods
3
+ def add_code_tags(code, lang)
4
+ code = code.to_s
5
+ code = code.sub(
6
+ %r!<pre>!,
7
+ "<pre><code class=\"language-#{lang}\" data-lang=\"#{lang}\">"
8
+ )
9
+ code = code.sub(%r!</pre>!, "</code></pre>")
10
+ code
11
+ end
12
+ end
25
13
 
26
- module WithoutHighlighting
27
- require 'cgi'
14
+ module WithPygments
15
+ include CommonMethods
16
+ def block_code(code, lang)
17
+ Bunto::External.require_with_graceful_fail("pygments")
18
+ lang = lang && lang.split.first || "text"
19
+ add_code_tags(
20
+ Pygments.highlight(
21
+ code,
22
+ {
23
+ :lexer => lang,
24
+ :options => { :encoding => "utf-8" }
25
+ }
26
+ ),
27
+ lang
28
+ )
29
+ end
30
+ end
28
31
 
29
- include CommonMethods
32
+ module WithoutHighlighting
33
+ require "cgi"
30
34
 
31
- def code_wrap(code)
32
- "<figure class=\"highlight\"><pre>#{CGI::escapeHTML(code)}</pre></figure>"
33
- end
35
+ include CommonMethods
34
36
 
35
- def block_code(code, lang)
36
- lang = lang && lang.split.first || "text"
37
- add_code_tags(code_wrap(code), lang)
38
- end
39
- end
37
+ def code_wrap(code)
38
+ "<figure class=\"highlight\"><pre>#{CGI.escapeHTML(code)}</pre></figure>"
39
+ end
40
40
 
41
- module WithRouge
42
- def block_code(code, lang)
43
- code = "<pre>#{super}</pre>"
41
+ def block_code(code, lang)
42
+ lang = lang && lang.split.first || "text"
43
+ add_code_tags(code_wrap(code), lang)
44
+ end
45
+ end
44
46
 
45
- output = "<div class=\"highlight\">"
46
- output << add_code_tags(code, lang)
47
- output << "</div>"
48
- end
47
+ module WithRouge
48
+ def block_code(code, lang)
49
+ code = "<pre>#{super}</pre>"
49
50
 
50
- protected
51
- def rouge_formatter(_lexer)
52
- Rouge::Formatters::HTML.new(:wrap => false)
53
- end
54
- end
51
+ output = "<div class=\"highlight\">"
52
+ output << add_code_tags(code, lang)
53
+ output << "</div>"
54
+ end
55
55
 
56
- def initialize(config)
57
- External.require_with_graceful_fail("redcarpet")
58
- @config = config
59
- @redcarpet_extensions = {}
60
- @config['redcarpet']['extensions'].each { |e| @redcarpet_extensions[e.to_sym] = true }
56
+ protected
57
+ def rouge_formatter(_lexer)
58
+ Rouge::Formatters::HTML.new(:wrap => false)
59
+ end
60
+ end
61
61
 
62
- @renderer ||= class_with_proper_highlighter(@config['highlighter'])
63
- end
62
+ def initialize(config)
63
+ Bunto::External.require_with_graceful_fail("redcarpet")
64
+ @config = config
65
+ @redcarpet_extensions = {}
66
+ @config["redcarpet"]["extensions"].each do |e|
67
+ @redcarpet_extensions[e.to_sym] = true
68
+ end
64
69
 
65
- def class_with_proper_highlighter(highlighter)
66
- case highlighter
67
- when "pygments"
68
- Class.new(Redcarpet::Render::HTML) do
69
- include WithPygments
70
- end
71
- when "rouge"
72
- Class.new(Redcarpet::Render::HTML) do
73
- Bunto::External.require_with_graceful_fail(%w(
74
- rouge
75
- rouge/plugins/redcarpet
76
- ))
70
+ @renderer ||= class_with_proper_highlighter(@config["highlighter"])
71
+ end
77
72
 
78
- unless Gem::Version.new(Rouge.version) > Gem::Version.new("1.3.0")
79
- abort "Please install Rouge 1.3.0 or greater and try running Bunto again."
80
- end
73
+ def class_with_proper_highlighter(highlighter)
74
+ Class.new(Redcarpet::Render::HTML) do
75
+ case highlighter
76
+ when "pygments"
77
+ include WithPygments
78
+ when "rouge"
79
+ Bunto::External.require_with_graceful_fail(%w(
80
+ rouge rouge/plugins/redcarpet
81
+ ))
81
82
 
82
- include Rouge::Plugins::Redcarpet
83
- include CommonMethods
84
- include WithRouge
85
- end
86
- else
87
- Class.new(Redcarpet::Render::HTML) do
88
- include WithoutHighlighting
89
- end
90
- end
83
+ unless Gem::Version.new(Rouge.version) > Gem::Version.new("1.3.0")
84
+ abort "Please install Rouge 1.3.0 or greater and try running Bunto again."
91
85
  end
92
86
 
93
- def convert(content)
94
- @redcarpet_extensions[:fenced_code_blocks] = !@redcarpet_extensions[:no_fenced_code_blocks]
95
- @renderer.send :include, Redcarpet::Render::SmartyPants if @redcarpet_extensions[:smart]
96
- markdown = Redcarpet::Markdown.new(@renderer.new(@redcarpet_extensions), @redcarpet_extensions)
97
- markdown.render(content)
98
- end
87
+ include Rouge::Plugins::Redcarpet
88
+ include CommonMethods
89
+ include WithRouge
90
+ else
91
+ include WithoutHighlighting
99
92
  end
100
93
  end
101
94
  end
95
+
96
+ def convert(content)
97
+ @redcarpet_extensions[:fenced_code_blocks] = \
98
+ !@redcarpet_extensions[:no_fenced_code_blocks]
99
+ if @redcarpet_extensions[:smart]
100
+ @renderer.send :include, Redcarpet::Render::SmartyPants
101
+ end
102
+ markdown = Redcarpet::Markdown.new(
103
+ @renderer.new(@redcarpet_extensions),
104
+ @redcarpet_extensions
105
+ )
106
+ markdown.render(content)
107
+ end
102
108
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'set'
3
+ require "set"
4
4
 
5
5
  # Convertible provides methods for converting a pagelike item
6
6
  # from a certain type of markup into actual content
@@ -20,12 +20,12 @@ module Bunto
20
20
  module Convertible
21
21
  # Returns the contents as a String.
22
22
  def to_s
23
- content || ''
23
+ content || ""
24
24
  end
25
25
 
26
26
  # Whether the file is published or not, as indicated in YAML front-matter
27
27
  def published?
28
- !(data.key?('published') && data['published'] == false)
28
+ !(data.key?("published") && data["published"] == false)
29
29
  end
30
30
 
31
31
  # Read the YAML frontmatter.
@@ -47,7 +47,7 @@ module Bunto
47
47
  end
48
48
  rescue SyntaxError => e
49
49
  Bunto.logger.warn "YAML Exception reading #{filename}: #{e.message}"
50
- rescue Exception => e
50
+ rescue => e
51
51
  Bunto.logger.warn "Error reading file #{filename}: #{e.message}"
52
52
  end
53
53
 
@@ -61,12 +61,13 @@ module Bunto
61
61
 
62
62
  def validate_data!(filename)
63
63
  unless self.data.is_a?(Hash)
64
- raise Errors::InvalidYAMLFrontMatterError, "Invalid YAML front matter in #{filename}"
64
+ raise Errors::InvalidYAMLFrontMatterError,
65
+ "Invalid YAML front matter in #{filename}"
65
66
  end
66
67
  end
67
68
 
68
69
  def validate_permalink!(filename)
69
- if self.data['permalink'] && self.data['permalink'].size == 0
70
+ if self.data["permalink"] && self.data["permalink"].empty?
70
71
  raise Errors::InvalidPermalinkError, "Invalid permalink in #{filename}"
71
72
  end
72
73
  end
@@ -79,7 +80,10 @@ module Bunto
79
80
  begin
80
81
  converter.convert output
81
82
  rescue => e
82
- Bunto.logger.error "Conversion error:", "#{converter.class} encountered an error while converting '#{path}':"
83
+ Bunto.logger.error(
84
+ "Conversion error:",
85
+ "#{converter.class} encountered an error while converting '#{path}':"
86
+ )
83
87
  Bunto.logger.error("", e.to_s)
84
88
  raise e
85
89
  end
@@ -110,14 +114,19 @@ module Bunto
110
114
  #
111
115
  # Returns the converted content
112
116
  def render_liquid(content, payload, info, path)
113
- site.liquid_renderer.file(path).parse(content).render!(payload, info)
114
- rescue Tags::IncludeTagError => e
115
- Bunto.logger.error "Liquid Exception:", "#{e.message} in #{e.path}, included in #{path || self.path}"
116
- raise e
117
+ template = site.liquid_renderer.file(path).parse(content)
118
+ template.warnings.each do |e|
119
+ Bunto.logger.warn "Liquid Warning:",
120
+ LiquidRenderer.format_error(e, path || self.path)
121
+ end
122
+ template.render!(payload, info)
123
+ # rubocop: disable RescueException
117
124
  rescue Exception => e
118
- Bunto.logger.error "Liquid Exception:", "#{e.message} in #{path || self.path}"
125
+ Bunto.logger.error "Liquid Exception:",
126
+ LiquidRenderer.format_error(e, path || self.path)
119
127
  raise e
120
128
  end
129
+ # rubocop: enable RescueException
121
130
 
122
131
  # Convert this Convertible's data to a Hash suitable for use by Liquid.
123
132
  #
@@ -168,7 +177,7 @@ module Bunto
168
177
  #
169
178
  # Returns true if extname == .coffee, false otherwise.
170
179
  def coffeescript_file?
171
- '.coffee'.eql?(ext)
180
+ ".coffee" == ext
172
181
  end
173
182
 
174
183
  # Determine whether the file should be rendered with Liquid.
@@ -205,14 +214,20 @@ module Bunto
205
214
  # recursively render layouts
206
215
  layout = layouts[data["layout"]]
207
216
 
208
- Bunto.logger.warn("Build Warning:", "Layout '#{data["layout"]}' requested in #{path} does not exist.") if invalid_layout? layout
217
+ Bunto.logger.warn(
218
+ "Build Warning:",
219
+ "Layout '#{data["layout"]}' requested in #{path} does not exist."
220
+ ) if invalid_layout? layout
209
221
 
210
222
  used = Set.new([layout])
211
223
 
224
+ # Reset the payload layout data to ensure it starts fresh for each page.
225
+ payload["layout"] = nil
226
+
212
227
  while layout
213
228
  Bunto.logger.debug "Rendering Layout:", path
214
229
  payload["content"] = output
215
- payload["layout"] = Utils.deep_merge_hashes(payload["layout"] || {}, layout.data)
230
+ payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
216
231
 
217
232
  self.output = render_liquid(layout.content,
218
233
  payload,
@@ -225,12 +240,9 @@ module Bunto
225
240
  site.in_source_dir(layout.path)
226
241
  )
227
242
 
228
- if layout = layouts[layout.data["layout"]]
229
- if used.include?(layout)
230
- layout = nil # avoid recursive chain
231
- else
232
- used << layout
233
- end
243
+ if (layout = layouts[layout.data["layout"]])
244
+ break if used.include?(layout)
245
+ used << layout
234
246
  end
235
247
  end
236
248
  end
@@ -246,7 +258,10 @@ module Bunto
246
258
 
247
259
  Bunto.logger.debug "Pre-Render Hooks:", self.relative_path
248
260
  Bunto::Hooks.trigger hook_owner, :pre_render, self, payload
249
- info = { :filters => [Bunto::Filters], :registers => { :site => site, :page => payload["page"] } }
261
+ info = {
262
+ :filters => [Bunto::Filters],
263
+ :registers => { :site => site, :page => payload["page"] }
264
+ }
250
265
 
251
266
  # render and transform content (this becomes the final content of the object)
252
267
  payload["highlighter_prefix"] = converters.first.highlighter_prefix
@@ -275,9 +290,7 @@ module Bunto
275
290
  def write(dest)
276
291
  path = destination(dest)
277
292
  FileUtils.mkdir_p(File.dirname(path))
278
- File.open(path, 'wb') do |f|
279
- f.write(output)
280
- end
293
+ File.write(path, output, :mode => "wb")
281
294
  Bunto::Hooks.trigger hook_owner, :post_write, self
282
295
  end
283
296