bunto 3.0.0 → 3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -11,37 +11,42 @@ module Bunto
11
11
  end
12
12
 
13
13
  def update_deprecated_types(set)
14
- return set unless set.key?('scope') && set['scope'].key?('type')
15
-
16
- set['scope']['type'] =
17
- case set['scope']['type']
18
- when 'page'
19
- Deprecator.defaults_deprecate_type('page', 'pages')
20
- 'pages'
21
- when 'post'
22
- Deprecator.defaults_deprecate_type('post', 'posts')
23
- 'posts'
24
- when 'draft'
25
- Deprecator.defaults_deprecate_type('draft', 'drafts')
26
- 'drafts'
14
+ return set unless set.key?("scope") && set["scope"].key?("type")
15
+
16
+ set["scope"]["type"] =
17
+ case set["scope"]["type"]
18
+ when "page"
19
+ Deprecator.defaults_deprecate_type("page", "pages")
20
+ "pages"
21
+ when "post"
22
+ Deprecator.defaults_deprecate_type("post", "posts")
23
+ "posts"
24
+ when "draft"
25
+ Deprecator.defaults_deprecate_type("draft", "drafts")
26
+ "drafts"
27
27
  else
28
- set['scope']['type']
28
+ set["scope"]["type"]
29
29
  end
30
30
 
31
31
  set
32
32
  end
33
33
 
34
34
  def ensure_time!(set)
35
- return set unless set.key?('values') && set['values'].key?('date')
36
- return set if set['values']['date'].is_a?(Time)
37
- set['values']['date'] = Utils.parse_date(set['values']['date'], "An invalid date format was found in a front-matter default set: #{set}")
35
+ return set unless set.key?("values") && set["values"].key?("date")
36
+ return set if set["values"]["date"].is_a?(Time)
37
+ set["values"]["date"] = Utils.parse_date(
38
+ set["values"]["date"],
39
+ "An invalid date format was found in a front-matter default set: #{set}"
40
+ )
38
41
  set
39
42
  end
40
43
 
41
44
  # Finds a default value for a given setting, filtered by path and type
42
45
  #
43
- # path - the path (relative to the source) of the page, post or :draft the default is used in
44
- # type - a symbol indicating whether a :page, a :post or a :draft calls this method
46
+ # path - the path (relative to the source) of the page,
47
+ # post or :draft the default is used in
48
+ # type - a symbol indicating whether a :page,
49
+ # a :post or a :draft calls this method
45
50
  #
46
51
  # Returns the default value or nil if none was found
47
52
  def find(path, type, setting)
@@ -49,9 +54,9 @@ module Bunto
49
54
  old_scope = nil
50
55
 
51
56
  matching_sets(path, type).each do |set|
52
- if set['values'].key?(setting) && has_precedence?(old_scope, set['scope'])
53
- value = set['values'][setting]
54
- old_scope = set['scope']
57
+ if set["values"].key?(setting) && has_precedence?(old_scope, set["scope"])
58
+ value = set["values"][setting]
59
+ old_scope = set["scope"]
55
60
  end
56
61
  end
57
62
  value
@@ -67,11 +72,11 @@ module Bunto
67
72
  defaults = {}
68
73
  old_scope = nil
69
74
  matching_sets(path, type).each do |set|
70
- if has_precedence?(old_scope, set['scope'])
71
- defaults = Utils.deep_merge_hashes(defaults, set['values'])
72
- old_scope = set['scope']
75
+ if has_precedence?(old_scope, set["scope"])
76
+ defaults = Utils.deep_merge_hashes(defaults, set["values"])
77
+ old_scope = set["scope"]
73
78
  else
74
- defaults = Utils.deep_merge_hashes(set['values'], defaults)
79
+ defaults = Utils.deep_merge_hashes(set["values"], defaults)
75
80
  end
76
81
  end
77
82
  defaults
@@ -91,9 +96,9 @@ module Bunto
91
96
  end
92
97
 
93
98
  def applies_path?(scope, path)
94
- return true if !scope.key?('path') || scope['path'].empty?
99
+ return true if !scope.key?("path") || scope["path"].empty?
95
100
 
96
- scope_path = Pathname.new(scope['path'])
101
+ scope_path = Pathname.new(scope["path"])
97
102
  Pathname.new(sanitize_path(path)).ascend do |ascended_path|
98
103
  if ascended_path.to_s == scope_path.to_s
99
104
  return true
@@ -113,7 +118,7 @@ module Bunto
113
118
  # Returns true if either of the above conditions are satisfied,
114
119
  # otherwise returns false
115
120
  def applies_type?(scope, type)
116
- !scope.key?('type') || scope['type'].eql?(type.to_s)
121
+ !scope.key?("type") || scope["type"].eql?(type.to_s)
117
122
  end
118
123
 
119
124
  # Checks if a given set of default values is valid
@@ -122,7 +127,7 @@ module Bunto
122
127
  #
123
128
  # Returns true if the set is valid and can be used in this class
124
129
  def valid?(set)
125
- set.is_a?(Hash) && set['values'].is_a?(Hash)
130
+ set.is_a?(Hash) && set["values"].is_a?(Hash)
126
131
  end
127
132
 
128
133
  # Determines if a new scope has precedence over an old one
@@ -131,27 +136,29 @@ module Bunto
131
136
  # new_scope - the new scope hash
132
137
  #
133
138
  # Returns true if the new scope has precedence over the older
139
+ # rubocop: disable PredicateName
134
140
  def has_precedence?(old_scope, new_scope)
135
141
  return true if old_scope.nil?
136
142
 
137
- new_path = sanitize_path(new_scope['path'])
138
- old_path = sanitize_path(old_scope['path'])
143
+ new_path = sanitize_path(new_scope["path"])
144
+ old_path = sanitize_path(old_scope["path"])
139
145
 
140
146
  if new_path.length != old_path.length
141
147
  new_path.length >= old_path.length
142
- elsif new_scope.key? 'type'
148
+ elsif new_scope.key?("type")
143
149
  true
144
150
  else
145
- !old_scope.key? 'type'
151
+ !old_scope.key? "type"
146
152
  end
147
153
  end
154
+ # rubocop: enable PredicateName
148
155
 
149
156
  # Collects a list of sets that match the given path and type
150
157
  #
151
158
  # Returns an array of hashes
152
159
  def matching_sets(path, type)
153
160
  valid_sets.select do |set|
154
- !set.key?('scope') || applies?(set['scope'], path, type)
161
+ !set.key?("scope") || applies?(set["scope"], path, type)
155
162
  end
156
163
  end
157
164
 
@@ -162,7 +169,7 @@ module Bunto
162
169
  #
163
170
  # Returns an array of hashes
164
171
  def valid_sets
165
- sets = @site.config['defaults']
172
+ sets = @site.config["defaults"]
166
173
  return [] unless sets.is_a?(Array)
167
174
 
168
175
  sets.map do |set|
@@ -170,7 +177,7 @@ module Bunto
170
177
  ensure_time!(update_deprecated_types(set))
171
178
  else
172
179
  Bunto.logger.warn "Defaults:", "An invalid front-matter default set was found:"
173
- Bunto.logger.warn "#{set}"
180
+ Bunto.logger.warn set.to_s
174
181
  nil
175
182
  end
176
183
  end.compact
@@ -181,7 +188,7 @@ module Bunto
181
188
  if path.nil? || path.empty?
182
189
  ""
183
190
  else
184
- path.gsub(/\A\//, '').gsub(/([^\/])\z/, '\1')
191
+ path.gsub(%r!\A/!, "").gsub(%r!([^/])\z!, '\1')
185
192
  end
186
193
  end
187
194
  end
@@ -4,38 +4,38 @@ module Bunto
4
4
 
5
5
  # compatibility layer for octopress-hooks users
6
6
  PRIORITY_MAP = {
7
- :low => 10,
7
+ :low => 10,
8
8
  :normal => 20,
9
- :high => 30
9
+ :high => 30
10
10
  }.freeze
11
11
 
12
12
  # initial empty hooks
13
13
  @registry = {
14
- :site => {
15
- :after_init => [],
14
+ :site => {
15
+ :after_init => [],
16
16
  :after_reset => [],
17
- :post_read => [],
18
- :pre_render => [],
17
+ :post_read => [],
18
+ :pre_render => [],
19
19
  :post_render => [],
20
- :post_write => []
20
+ :post_write => []
21
21
  },
22
- :pages => {
23
- :post_init => [],
24
- :pre_render => [],
22
+ :pages => {
23
+ :post_init => [],
24
+ :pre_render => [],
25
25
  :post_render => [],
26
- :post_write => []
26
+ :post_write => []
27
27
  },
28
- :posts => {
29
- :post_init => [],
30
- :pre_render => [],
28
+ :posts => {
29
+ :post_init => [],
30
+ :pre_render => [],
31
31
  :post_render => [],
32
- :post_write => []
32
+ :post_write => []
33
33
  },
34
34
  :documents => {
35
- :post_init => [],
36
- :pre_render => [],
35
+ :post_init => [],
36
+ :pre_render => [],
37
37
  :post_render => [],
38
- :post_write => []
38
+ :post_write => []
39
39
  }
40
40
  }
41
41
 
@@ -61,10 +61,10 @@ module Bunto
61
61
  # register a single hook to be called later, internal API
62
62
  def self.register_one(owner, event, priority, &block)
63
63
  @registry[owner] ||={
64
- :post_init => [],
65
- :pre_render => [],
64
+ :post_init => [],
65
+ :pre_render => [],
66
66
  :post_render => [],
67
- :post_write => []
67
+ :post_write => []
68
68
  }
69
69
 
70
70
  unless @registry[owner][event]
@@ -11,6 +11,9 @@ module Bunto
11
11
  # Gets the path to this layout.
12
12
  attr_reader :path
13
13
 
14
+ # Gets the path to this layout relative to its base
15
+ attr_reader :relative_path
16
+
14
17
  # Gets/Sets the extension of this layout.
15
18
  attr_accessor :ext
16
19
 
@@ -37,6 +40,7 @@ module Bunto
37
40
  @base_dir = site.source
38
41
  @path = site.in_source_dir(base, name)
39
42
  end
43
+ @relative_path = @path.sub(@base_dir, "")
40
44
 
41
45
  self.data = {}
42
46
 
@@ -52,13 +56,5 @@ module Bunto
52
56
  def process(name)
53
57
  self.ext = File.extname(name)
54
58
  end
55
-
56
- # The path to the layout, relative to the site source.
57
- #
58
- # Returns a String path which represents the relative path
59
- # from the site source to this layout
60
- def relative_path
61
- @relative_path ||= Pathname.new(path).relative_path_from(Pathname.new(@base_dir)).to_s
62
- end
63
59
  end
64
60
  end
@@ -1,10 +1,11 @@
1
- require 'bunto/liquid_renderer/file'
2
- require 'bunto/liquid_renderer/table'
1
+ require "bunto/liquid_renderer/file"
2
+ require "bunto/liquid_renderer/table"
3
3
 
4
4
  module Bunto
5
5
  class LiquidRenderer
6
6
  def initialize(site)
7
7
  @site = site
8
+ Liquid::Template.error_mode = @site.config["liquid"]["error_mode"].to_sym
8
9
  reset
9
10
  end
10
11
 
@@ -13,7 +14,10 @@ module Bunto
13
14
  end
14
15
 
15
16
  def file(filename)
16
- filename = @site.in_source_dir(filename).sub(/\A#{Regexp.escape(@site.source)}\//, '')
17
+ filename = @site.in_source_dir(filename).sub(
18
+ %r!\A#{Regexp.escape(@site.source)}/!,
19
+ ""
20
+ )
17
21
 
18
22
  LiquidRenderer::File.new(self, filename).tap do
19
23
  @stats[filename] ||= {}
@@ -35,5 +39,12 @@ module Bunto
35
39
  def stats_table(n = 50)
36
40
  LiquidRenderer::Table.new(@stats).to_s(n)
37
41
  end
42
+
43
+ def self.format_error(e, path)
44
+ if e.is_a? Tags::IncludeTagError
45
+ return "#{e.message} in #{e.path}, included in #{path}"
46
+ end
47
+ "#{e.message} in #{path}"
48
+ end
38
49
  end
39
50
  end
@@ -8,7 +8,7 @@ module Bunto
8
8
 
9
9
  def parse(content)
10
10
  measure_time do
11
- @template = Liquid::Template.parse(content, line_numbers: true)
11
+ @template = Liquid::Template.parse(content, :line_numbers => true)
12
12
  end
13
13
 
14
14
  self
@@ -30,6 +30,10 @@ module Bunto
30
30
  end
31
31
  end
32
32
 
33
+ def warnings
34
+ @template.warnings
35
+ end
36
+
33
37
  private
34
38
 
35
39
  def measure_bytes
@@ -31,8 +31,8 @@ module Bunto
31
31
  str = ""
32
32
 
33
33
  row_data.each_index do |cell_index|
34
- str << '-' * widths[cell_index]
35
- str << '-+-' unless cell_index == row_data.length-1
34
+ str << "-" * widths[cell_index]
35
+ str << "-+-" unless cell_index == row_data.length-1
36
36
  end
37
37
 
38
38
  str << "\n"
@@ -40,16 +40,16 @@ module Bunto
40
40
  end
41
41
 
42
42
  def generate_row(row_data, widths)
43
- str = ''
43
+ str = ""
44
44
 
45
45
  row_data.each_with_index do |cell_data, cell_index|
46
- if cell_index == 0
47
- str << cell_data.ljust(widths[cell_index], ' ')
48
- else
49
- str << cell_data.rjust(widths[cell_index], ' ')
50
- end
46
+ str << if cell_index.zero?
47
+ cell_data.ljust(widths[cell_index], " ")
48
+ else
49
+ cell_data.rjust(widths[cell_index], " ")
50
+ end
51
51
 
52
- str << ' | ' unless cell_index == row_data.length-1
52
+ str << " | " unless cell_index == row_data.length-1
53
53
  end
54
54
 
55
55
  str << "\n"
@@ -79,7 +79,7 @@ module Bunto
79
79
  row << filename
80
80
  row << file_stats[:count].to_s
81
81
  row << format_bytes(file_stats[:bytes])
82
- row << "%.3f" % file_stats[:time]
82
+ row << format("%.3f", file_stats[:time])
83
83
  table << row
84
84
  end
85
85
 
@@ -88,7 +88,7 @@ module Bunto
88
88
 
89
89
  def format_bytes(bytes)
90
90
  bytes /= 1024.0
91
- "%.2fK" % bytes
91
+ format("%.2fK", bytes)
92
92
  end
93
93
  end
94
94
  end
@@ -7,7 +7,7 @@ module Bunto
7
7
  :info => ::Logger::INFO,
8
8
  :warn => ::Logger::WARN,
9
9
  :error => ::Logger::ERROR
10
- }
10
+ }.freeze
11
11
 
12
12
  # Public: Create a new instance of a log writer
13
13
  #
@@ -98,7 +98,7 @@ module Bunto
98
98
  #
99
99
  # Returns the formatted message
100
100
  def message(topic, message)
101
- msg = formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ')
101
+ msg = formatted_topic(topic) + message.to_s.gsub(%r!\s+!, " ")
102
102
  messages << msg
103
103
  msg
104
104
  end
@@ -9,7 +9,7 @@ module Bunto
9
9
 
10
10
  alias_method :extname, :ext
11
11
 
12
- FORWARD_SLASH = '/'.freeze
12
+ FORWARD_SLASH = "/".freeze
13
13
 
14
14
  # Attributes for Liquid templates
15
15
  ATTRIBUTES_FOR_LIQUID = %w(
@@ -18,16 +18,16 @@ module Bunto
18
18
  name
19
19
  path
20
20
  url
21
- )
21
+ ).freeze
22
22
 
23
23
  # A set of extensions that are considered HTML or HTML-like so we
24
24
  # should not alter them, this includes .xhtml through XHTM5.
25
25
 
26
- HTML_EXTENSIONS = %W(
26
+ HTML_EXTENSIONS = %w(
27
27
  .html
28
28
  .xhtml
29
29
  .htm
30
- )
30
+ ).freeze
31
31
 
32
32
  # Initialize a new Page.
33
33
  #
@@ -71,7 +71,7 @@ module Bunto
71
71
  #
72
72
  # Returns the String permalink or nil if none has been set.
73
73
  def permalink
74
- data.nil? ? nil : data['permalink']
74
+ data.nil? ? nil : data["permalink"]
75
75
  end
76
76
 
77
77
  # The template of the permalink.
@@ -92,9 +92,9 @@ module Bunto
92
92
  # Returns the String url.
93
93
  def url
94
94
  @url ||= URL.new({
95
- :template => template,
95
+ :template => template,
96
96
  :placeholders => url_placeholders,
97
- :permalink => permalink
97
+ :permalink => permalink
98
98
  }).to_s
99
99
  end
100
100
 
@@ -135,12 +135,12 @@ module Bunto
135
135
  #
136
136
  # Returns the path to the source file
137
137
  def path
138
- data.fetch('path') { relative_path.sub(/\A\//, '') }
138
+ data.fetch("path") { relative_path }
139
139
  end
140
140
 
141
141
  # The path to the page source file, relative to the site source
142
142
  def relative_path
143
- File.join(*[@dir, @name].map(&:to_s).reject(&:empty?))
143
+ File.join(*[@dir, @name].map(&:to_s).reject(&:empty?)).sub(%r!\A\/!, "")
144
144
  end
145
145
 
146
146
  # Obtain destination path.
@@ -167,7 +167,7 @@ module Bunto
167
167
 
168
168
  # Returns the Boolean of whether this Page is an index file or not.
169
169
  def index?
170
- basename == 'index'
170
+ basename == "index"
171
171
  end
172
172
 
173
173
  def trigger_hooks(hook_name, *args)