bunto 3.2.1 → 3.4.5
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +21 -4
- data/LICENSE +1 -1
- data/README.markdown +20 -25
- data/exe/bunto +1 -1
- data/lib/bunto.rb +10 -4
- data/lib/bunto/collection.rb +11 -4
- data/lib/bunto/commands/build.rb +17 -2
- data/lib/bunto/commands/doctor.rb +1 -1
- data/lib/bunto/commands/new.rb +35 -5
- data/lib/bunto/commands/new_theme.rb +4 -2
- data/lib/bunto/commands/serve.rb +45 -15
- data/lib/bunto/commands/serve/servlet.rb +1 -1
- data/lib/bunto/configuration.rb +9 -7
- data/lib/bunto/converters/markdown/kramdown_parser.rb +2 -2
- data/lib/bunto/converters/markdown/redcarpet_parser.rb +1 -1
- data/lib/bunto/convertible.rb +21 -82
- data/lib/bunto/desktop.ini +1 -1
- data/lib/bunto/document.rb +118 -81
- data/lib/bunto/drops/bunto_drop.rb +1 -1
- data/lib/bunto/drops/static_file_drop.rb +11 -0
- data/lib/bunto/drops/url_drop.rb +5 -0
- data/lib/bunto/entry_filter.rb +9 -10
- data/lib/bunto/excerpt.rb +2 -3
- data/lib/bunto/external.rb +1 -1
- data/lib/bunto/filters.rb +10 -32
- data/lib/bunto/filters/grouping_filters.rb +63 -0
- data/lib/bunto/filters/url_filters.rb +40 -0
- data/lib/bunto/frontmatter_defaults.rb +1 -1
- data/lib/bunto/hooks.rb +9 -9
- data/lib/bunto/log_adapter.rb +1 -1
- data/lib/bunto/page.rb +8 -4
- data/lib/bunto/plugin.rb +1 -1
- data/lib/bunto/reader.rb +2 -1
- data/lib/bunto/readers/data_reader.rb +9 -10
- data/lib/bunto/readers/post_reader.rb +1 -1
- data/lib/bunto/readers/theme_assets_reader.rb +47 -0
- data/lib/bunto/regenerator.rb +1 -1
- data/lib/bunto/related_posts.rb +3 -9
- data/lib/bunto/renderer.rb +26 -6
- data/lib/bunto/site.rb +12 -7
- data/lib/bunto/static_file.rb +20 -9
- data/lib/bunto/tags/highlight.rb +3 -3
- data/lib/bunto/tags/include.rb +9 -5
- data/lib/bunto/tags/link.rb +4 -2
- data/lib/bunto/tags/post_url.rb +4 -2
- data/lib/bunto/theme.rb +8 -4
- data/lib/bunto/theme_builder.rb +2 -2
- data/lib/bunto/url.rb +31 -8
- data/lib/bunto/utils.rb +16 -2
- data/lib/bunto/utils/ansi.rb +1 -1
- data/lib/bunto/utils/exec.rb +25 -0
- data/lib/bunto/utils/platforms.rb +52 -2
- data/lib/bunto/utils/win_tz.rb +73 -0
- data/lib/bunto/version.rb +1 -1
- data/lib/site_template/_config.yml +8 -3
- data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +4 -4
- data/lib/site_template/about.md +1 -1
- data/lib/site_template/index.md +6 -0
- data/lib/theme_template/LICENSE.txt.erb +1 -1
- data/lib/theme_template/README.md.erb +4 -4
- data/lib/theme_template/gitignore.erb +1 -0
- data/lib/theme_template/theme.gemspec.erb +3 -2
- metadata +55 -40
- data/lib/site_template/css/main.scss +0 -39
- data/lib/site_template/feed.xml +0 -30
- data/lib/site_template/index.html +0 -23
@@ -6,7 +6,7 @@ module Bunto
|
|
6
6
|
class Servlet < WEBrick::HTTPServlet::FileHandler
|
7
7
|
DEFAULTS = {
|
8
8
|
"Cache-Control" => "private, max-age=0, proxy-revalidate, " \
|
9
|
-
"no-store, no-cache, must-revalidate"
|
9
|
+
"no-store, no-cache, must-revalidate",
|
10
10
|
}.freeze
|
11
11
|
|
12
12
|
def initialize(server, root, callbacks)
|
data/lib/bunto/configuration.rb
CHANGED
@@ -17,7 +17,9 @@ module Bunto
|
|
17
17
|
# Handling Reading
|
18
18
|
"safe" => false,
|
19
19
|
"include" => [".htaccess"],
|
20
|
-
"exclude" =>
|
20
|
+
"exclude" => %w(
|
21
|
+
node_modules vendor/bundle/ vendor/cache/ vendor/gems/ vendor/ruby/
|
22
|
+
),
|
21
23
|
"keep_files" => [".git", ".svn"],
|
22
24
|
"encoding" => "utf-8",
|
23
25
|
"markdown_ext" => "markdown,mkdown,mkdn,mkd,md",
|
@@ -43,7 +45,7 @@ module Bunto
|
|
43
45
|
"detach" => false, # default to not detaching the server
|
44
46
|
"port" => "4000",
|
45
47
|
"host" => "127.0.0.1",
|
46
|
-
"baseurl" =>
|
48
|
+
"baseurl" => nil, # this mounts at /, i.e. no subdirectory
|
47
49
|
"show_dir_listing" => false,
|
48
50
|
|
49
51
|
# Output Configuration
|
@@ -56,15 +58,15 @@ module Bunto
|
|
56
58
|
"defaults" => [],
|
57
59
|
|
58
60
|
"liquid" => {
|
59
|
-
"error_mode" => "warn"
|
61
|
+
"error_mode" => "warn",
|
60
62
|
},
|
61
63
|
|
62
64
|
"rdiscount" => {
|
63
|
-
"extensions" => []
|
65
|
+
"extensions" => [],
|
64
66
|
},
|
65
67
|
|
66
68
|
"redcarpet" => {
|
67
|
-
"extensions" => []
|
69
|
+
"extensions" => [],
|
68
70
|
},
|
69
71
|
|
70
72
|
"kramdown" => {
|
@@ -74,8 +76,8 @@ module Bunto
|
|
74
76
|
"smart_quotes" => "lsquo,rsquo,ldquo,rdquo",
|
75
77
|
"input" => "GFM",
|
76
78
|
"hard_wrap" => false,
|
77
|
-
"footnote_nr" => 1
|
78
|
-
}
|
79
|
+
"footnote_nr" => 1,
|
80
|
+
},
|
79
81
|
}.map { |k, v| [k, v.freeze] }].freeze
|
80
82
|
|
81
83
|
class << self
|
@@ -11,7 +11,7 @@ module Bunto
|
|
11
11
|
"line_numbers" => "inline",
|
12
12
|
"line_number_start" => 1,
|
13
13
|
"tab_width" => 4,
|
14
|
-
"wrap" => "div"
|
14
|
+
"wrap" => "div",
|
15
15
|
}.freeze
|
16
16
|
|
17
17
|
def initialize(config)
|
@@ -104,7 +104,7 @@ module Bunto
|
|
104
104
|
|
105
105
|
private
|
106
106
|
def modernize_coderay_config
|
107
|
-
|
107
|
+
unless @config["coderay"].empty?
|
108
108
|
Bunto::Deprecator.deprecation_message(
|
109
109
|
"You are using 'kramdown.coderay' in your configuration, " \
|
110
110
|
"please use 'syntax_highlighter_opts' instead."
|
data/lib/bunto/convertible.rb
CHANGED
@@ -35,6 +35,7 @@ module Bunto
|
|
35
35
|
# opts - optional parameter to File.read, default at site configs
|
36
36
|
#
|
37
37
|
# Returns nothing.
|
38
|
+
# rubocop:disable Metrics/AbcSize
|
38
39
|
def read_yaml(base, name, opts = {})
|
39
40
|
filename = File.join(base, name)
|
40
41
|
|
@@ -58,6 +59,7 @@ module Bunto
|
|
58
59
|
|
59
60
|
self.data
|
60
61
|
end
|
62
|
+
# rubocop:enable Metrics/AbcSize
|
61
63
|
|
62
64
|
def validate_data!(filename)
|
63
65
|
unless self.data.is_a?(Hash)
|
@@ -76,18 +78,7 @@ module Bunto
|
|
76
78
|
#
|
77
79
|
# Returns the transformed contents.
|
78
80
|
def transform
|
79
|
-
|
80
|
-
begin
|
81
|
-
converter.convert output
|
82
|
-
rescue => e
|
83
|
-
Bunto.logger.error(
|
84
|
-
"Conversion error:",
|
85
|
-
"#{converter.class} encountered an error while converting '#{path}':"
|
86
|
-
)
|
87
|
-
Bunto.logger.error("", e.to_s)
|
88
|
-
raise e
|
89
|
-
end
|
90
|
-
end
|
81
|
+
_renderer.transform
|
91
82
|
end
|
92
83
|
|
93
84
|
# Determine the extension depending on content_type.
|
@@ -95,7 +86,7 @@ module Bunto
|
|
95
86
|
# Returns the String extension for the output file.
|
96
87
|
# e.g. ".html" for an HTML output file.
|
97
88
|
def output_ext
|
98
|
-
|
89
|
+
_renderer.output_ext
|
99
90
|
end
|
100
91
|
|
101
92
|
# Determine which converter to use based on this convertible's
|
@@ -103,7 +94,7 @@ module Bunto
|
|
103
94
|
#
|
104
95
|
# Returns the Converter instance.
|
105
96
|
def converters
|
106
|
-
|
97
|
+
_renderer.converters
|
107
98
|
end
|
108
99
|
|
109
100
|
# Render Liquid in the content
|
@@ -114,17 +105,7 @@ module Bunto
|
|
114
105
|
#
|
115
106
|
# Returns the converted content
|
116
107
|
def render_liquid(content, payload, info, path)
|
117
|
-
|
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
|
124
|
-
rescue Exception => e
|
125
|
-
Bunto.logger.error "Liquid Exception:",
|
126
|
-
LiquidRenderer.format_error(e, path || self.path)
|
127
|
-
raise e
|
108
|
+
_renderer.render_liquid(content, payload, info, path)
|
128
109
|
end
|
129
110
|
# rubocop: enable RescueException
|
130
111
|
|
@@ -211,40 +192,10 @@ module Bunto
|
|
211
192
|
#
|
212
193
|
# Returns nothing
|
213
194
|
def render_all_layouts(layouts, payload, info)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
"Build Warning:",
|
219
|
-
"Layout '#{data["layout"]}' requested in #{path} does not exist."
|
220
|
-
) if invalid_layout? layout
|
221
|
-
|
222
|
-
used = Set.new([layout])
|
223
|
-
|
224
|
-
# Reset the payload layout data to ensure it starts fresh for each page.
|
225
|
-
payload["layout"] = nil
|
226
|
-
|
227
|
-
while layout
|
228
|
-
Bunto.logger.debug "Rendering Layout:", path
|
229
|
-
payload["content"] = output
|
230
|
-
payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
|
231
|
-
|
232
|
-
self.output = render_liquid(layout.content,
|
233
|
-
payload,
|
234
|
-
info,
|
235
|
-
layout.relative_path)
|
236
|
-
|
237
|
-
# Add layout to dependency tree
|
238
|
-
site.regenerator.add_dependency(
|
239
|
-
site.in_source_dir(path),
|
240
|
-
site.in_source_dir(layout.path)
|
241
|
-
)
|
242
|
-
|
243
|
-
if (layout = layouts[layout.data["layout"]])
|
244
|
-
break if used.include?(layout)
|
245
|
-
used << layout
|
246
|
-
end
|
247
|
-
end
|
195
|
+
_renderer.layouts = layouts
|
196
|
+
self.output = _renderer.place_in_layouts(output, payload, info)
|
197
|
+
ensure
|
198
|
+
@_renderer = nil # this will allow the modifications above to disappear
|
248
199
|
end
|
249
200
|
|
250
201
|
# Add any necessary layouts to this convertible document.
|
@@ -254,32 +205,15 @@ module Bunto
|
|
254
205
|
#
|
255
206
|
# Returns nothing.
|
256
207
|
def do_layout(payload, layouts)
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
info = {
|
262
|
-
:filters => [Bunto::Filters],
|
263
|
-
:registers => { :site => site, :page => payload["page"] }
|
264
|
-
}
|
208
|
+
self.output = _renderer.tap do |renderer|
|
209
|
+
renderer.layouts = layouts
|
210
|
+
renderer.payload = payload
|
211
|
+
end.run
|
265
212
|
|
266
|
-
# render and transform content (this becomes the final content of the object)
|
267
|
-
payload["highlighter_prefix"] = converters.first.highlighter_prefix
|
268
|
-
payload["highlighter_suffix"] = converters.first.highlighter_suffix
|
269
|
-
|
270
|
-
if render_with_liquid?
|
271
|
-
Bunto.logger.debug "Rendering Liquid:", self.relative_path
|
272
|
-
self.content = render_liquid(content, payload, info, path)
|
273
|
-
end
|
274
|
-
Bunto.logger.debug "Rendering Markup:", self.relative_path
|
275
|
-
self.content = transform
|
276
|
-
|
277
|
-
# output keeps track of what will finally be written
|
278
|
-
self.output = content
|
279
|
-
|
280
|
-
render_all_layouts(layouts, payload, info) if place_in_layout?
|
281
213
|
Bunto.logger.debug "Post-Render Hooks:", self.relative_path
|
282
214
|
Bunto::Hooks.trigger hook_owner, :post_render, self
|
215
|
+
ensure
|
216
|
+
@_renderer = nil # this will allow the modifications above to disappear
|
283
217
|
end
|
284
218
|
|
285
219
|
# Write the generated page file to the destination directory.
|
@@ -306,5 +240,10 @@ module Bunto
|
|
306
240
|
data[property]
|
307
241
|
end
|
308
242
|
end
|
243
|
+
|
244
|
+
private
|
245
|
+
def _renderer
|
246
|
+
@_renderer ||= Bunto::Renderer.new(site, self)
|
247
|
+
end
|
309
248
|
end
|
310
249
|
end
|
data/lib/bunto/desktop.ini
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
[.ShellClassInfo]
|
2
|
-
LocalizedResourceName=
|
2
|
+
LocalizedResourceName=jekl
|
data/lib/bunto/document.rb
CHANGED
@@ -9,7 +9,7 @@ module Bunto
|
|
9
9
|
|
10
10
|
YAML_FRONT_MATTER_REGEXP = %r!\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)!m
|
11
11
|
DATELESS_FILENAME_MATCHER = %r!^(?:.+/)*(.*)(\.[^.]+)$!
|
12
|
-
DATE_FILENAME_MATCHER = %r!^(?:.+/)*(\d
|
12
|
+
DATE_FILENAME_MATCHER = %r!^(?:.+/)*(\d{2,4}-\d{1,2}-\d{1,2})-(.*)(\.[^.]+)$!
|
13
13
|
|
14
14
|
# Create a new Document.
|
15
15
|
#
|
@@ -51,19 +51,9 @@ module Bunto
|
|
51
51
|
#
|
52
52
|
# Returns the merged data.
|
53
53
|
def merge_data!(other, source: "YAML front matter")
|
54
|
-
|
55
|
-
if other["categories"].is_a?(String)
|
56
|
-
other["categories"] = other["categories"].split(" ").map(&:strip)
|
57
|
-
end
|
58
|
-
other["categories"] = (data["categories"] || []) | other["categories"]
|
59
|
-
end
|
54
|
+
merge_categories!(other)
|
60
55
|
Utils.deep_merge_hashes!(data, other)
|
61
|
-
|
62
|
-
data["date"] = Utils.parse_date(
|
63
|
-
data["date"].to_s,
|
64
|
-
"Document '#{relative_path}' does not have a valid date in the #{source}."
|
65
|
-
)
|
66
|
-
end
|
56
|
+
merge_date!(source)
|
67
57
|
data
|
68
58
|
end
|
69
59
|
|
@@ -90,8 +80,7 @@ module Bunto
|
|
90
80
|
# Returns a String path which represents the relative path
|
91
81
|
# from the site source to this document
|
92
82
|
def relative_path
|
93
|
-
@relative_path ||=
|
94
|
-
.relative_path_from(Pathname.new(site.source)).to_s
|
83
|
+
@relative_path ||= Pathutil.new(path).relative_path_from(site.source).to_s
|
95
84
|
end
|
96
85
|
|
97
86
|
# The output extension of the document.
|
@@ -207,7 +196,7 @@ module Bunto
|
|
207
196
|
@url = URL.new({
|
208
197
|
:template => url_template,
|
209
198
|
:placeholders => url_placeholders,
|
210
|
-
:permalink => permalink
|
199
|
+
:permalink => permalink,
|
211
200
|
}).to_s
|
212
201
|
end
|
213
202
|
|
@@ -264,20 +253,9 @@ module Bunto
|
|
264
253
|
@data = SafeYAML.load_file(path)
|
265
254
|
else
|
266
255
|
begin
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
)
|
271
|
-
merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
|
272
|
-
|
273
|
-
self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
|
274
|
-
if content =~ YAML_FRONT_MATTER_REGEXP
|
275
|
-
self.content = $POSTMATCH
|
276
|
-
data_file = SafeYAML.load(Regexp.last_match(1))
|
277
|
-
merge_data!(data_file, :source => "YAML front matter") if data_file
|
278
|
-
end
|
279
|
-
|
280
|
-
post_read
|
256
|
+
merge_defaults
|
257
|
+
read_content(opts)
|
258
|
+
read_post_data
|
281
259
|
rescue SyntaxError => e
|
282
260
|
Bunto.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
|
283
261
|
rescue => e
|
@@ -287,56 +265,6 @@ module Bunto
|
|
287
265
|
end
|
288
266
|
end
|
289
267
|
|
290
|
-
def post_read
|
291
|
-
if relative_path =~ DATE_FILENAME_MATCHER
|
292
|
-
date, slug, ext = Regexp.last_match.captures
|
293
|
-
if !data["date"] || data["date"].to_i == site.time.to_i
|
294
|
-
merge_data!({ "date" => date }, :source => "filename")
|
295
|
-
end
|
296
|
-
elsif relative_path =~ DATELESS_FILENAME_MATCHER
|
297
|
-
slug, ext = Regexp.last_match.captures
|
298
|
-
end
|
299
|
-
|
300
|
-
# Try to ensure the user gets a title.
|
301
|
-
data["title"] ||= Utils.titleize_slug(slug)
|
302
|
-
# Only overwrite slug & ext if they aren't specified.
|
303
|
-
data["slug"] ||= slug
|
304
|
-
data["ext"] ||= ext
|
305
|
-
|
306
|
-
populate_categories
|
307
|
-
populate_tags
|
308
|
-
generate_excerpt
|
309
|
-
end
|
310
|
-
|
311
|
-
# Add superdirectories of the special_dir to categories.
|
312
|
-
# In the case of es/_posts, 'es' is added as a category.
|
313
|
-
# In the case of _posts/es, 'es' is NOT added as a category.
|
314
|
-
#
|
315
|
-
# Returns nothing.
|
316
|
-
def categories_from_path(special_dir)
|
317
|
-
superdirs = relative_path.sub(%r!#{special_dir}(.*)!, "")
|
318
|
-
.split(File::SEPARATOR)
|
319
|
-
.reject do |c|
|
320
|
-
c.empty? || c.eql?(special_dir) || c.eql?(basename)
|
321
|
-
end
|
322
|
-
merge_data!({ "categories" => superdirs }, :source => "file path")
|
323
|
-
end
|
324
|
-
|
325
|
-
def populate_categories
|
326
|
-
merge_data!({
|
327
|
-
"categories" => (
|
328
|
-
Array(data["categories"]) +
|
329
|
-
Utils.pluralized_array_from_hash(data, "category", "categories")
|
330
|
-
).map(&:to_s).flatten.uniq
|
331
|
-
})
|
332
|
-
end
|
333
|
-
|
334
|
-
def populate_tags
|
335
|
-
merge_data!({
|
336
|
-
"tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
|
337
|
-
})
|
338
|
-
end
|
339
|
-
|
340
268
|
# Create a Liquid-understandable version of this Document.
|
341
269
|
#
|
342
270
|
# Returns a Hash representing this Document's data.
|
@@ -443,7 +371,116 @@ module Bunto
|
|
443
371
|
end
|
444
372
|
end
|
445
373
|
|
446
|
-
|
374
|
+
def respond_to_missing?(method, *)
|
375
|
+
data.key?(method.to_s) || super
|
376
|
+
end
|
377
|
+
|
378
|
+
private
|
379
|
+
def merge_categories!(other)
|
380
|
+
if other.key?("categories") && !other["categories"].nil?
|
381
|
+
if other["categories"].is_a?(String)
|
382
|
+
other["categories"] = other["categories"].split(%r!\s+!).map(&:strip)
|
383
|
+
end
|
384
|
+
other["categories"] = (data["categories"] || []) | other["categories"]
|
385
|
+
end
|
386
|
+
end
|
387
|
+
|
388
|
+
private
|
389
|
+
def merge_date!(source)
|
390
|
+
if data.key?("date") && !data["date"].is_a?(Time)
|
391
|
+
data["date"] = Utils.parse_date(
|
392
|
+
data["date"].to_s,
|
393
|
+
"Document '#{relative_path}' does not have a valid date in the #{source}."
|
394
|
+
)
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
private
|
399
|
+
def merge_defaults
|
400
|
+
defaults = @site.frontmatter_defaults.all(
|
401
|
+
relative_path,
|
402
|
+
collection.label.to_sym
|
403
|
+
)
|
404
|
+
merge_data!(defaults, :source => "front matter defaults") unless defaults.empty?
|
405
|
+
end
|
406
|
+
|
407
|
+
private
|
408
|
+
def read_content(opts)
|
409
|
+
self.content = File.read(path, Utils.merged_file_read_opts(site, opts))
|
410
|
+
if content =~ YAML_FRONT_MATTER_REGEXP
|
411
|
+
self.content = $POSTMATCH
|
412
|
+
data_file = SafeYAML.load(Regexp.last_match(1))
|
413
|
+
merge_data!(data_file, :source => "YAML front matter") if data_file
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
private
|
418
|
+
def read_post_data
|
419
|
+
populate_title
|
420
|
+
populate_categories
|
421
|
+
populate_tags
|
422
|
+
generate_excerpt
|
423
|
+
end
|
424
|
+
|
425
|
+
private
|
426
|
+
def populate_title
|
427
|
+
if relative_path =~ DATE_FILENAME_MATCHER
|
428
|
+
date, slug, ext = Regexp.last_match.captures
|
429
|
+
modify_date(date)
|
430
|
+
elsif relative_path =~ DATELESS_FILENAME_MATCHER
|
431
|
+
slug, ext = Regexp.last_match.captures
|
432
|
+
end
|
433
|
+
|
434
|
+
# Try to ensure the user gets a title.
|
435
|
+
data["title"] ||= Utils.titleize_slug(slug)
|
436
|
+
# Only overwrite slug & ext if they aren't specified.
|
437
|
+
data["slug"] ||= slug
|
438
|
+
data["ext"] ||= ext
|
439
|
+
end
|
440
|
+
|
441
|
+
private
|
442
|
+
def modify_date(date)
|
443
|
+
if !data["date"] || data["date"].to_i == site.time.to_i
|
444
|
+
merge_data!({ "date" => date }, :source => "filename")
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
# Add superdirectories of the special_dir to categories.
|
449
|
+
# In the case of es/_posts, 'es' is added as a category.
|
450
|
+
# In the case of _posts/es, 'es' is NOT added as a category.
|
451
|
+
#
|
452
|
+
# Returns nothing.
|
453
|
+
private
|
454
|
+
def categories_from_path(special_dir)
|
455
|
+
superdirs = relative_path.sub(%r!#{special_dir}(.*)!, "")
|
456
|
+
.split(File::SEPARATOR)
|
457
|
+
.reject do |c|
|
458
|
+
c.empty? || c == special_dir || c == basename
|
459
|
+
end
|
460
|
+
merge_data!({ "categories" => superdirs }, :source => "file path")
|
461
|
+
end
|
462
|
+
|
463
|
+
private
|
464
|
+
def populate_categories
|
465
|
+
merge_data!({
|
466
|
+
"categories" => (
|
467
|
+
Array(data["categories"]) + Utils.pluralized_array_from_hash(
|
468
|
+
data,
|
469
|
+
"category",
|
470
|
+
"categories"
|
471
|
+
)
|
472
|
+
).map(&:to_s).flatten.uniq,
|
473
|
+
})
|
474
|
+
end
|
475
|
+
|
476
|
+
private
|
477
|
+
def populate_tags
|
478
|
+
merge_data!({
|
479
|
+
"tags" => Utils.pluralized_array_from_hash(data, "tag", "tags").flatten,
|
480
|
+
})
|
481
|
+
end
|
482
|
+
|
483
|
+
private
|
447
484
|
def generate_excerpt
|
448
485
|
if generate_excerpt?
|
449
486
|
data["excerpt"] ||= Bunto::Excerpt.new(self)
|