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.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +21 -4
  3. data/LICENSE +1 -1
  4. data/README.markdown +20 -25
  5. data/exe/bunto +1 -1
  6. data/lib/bunto.rb +10 -4
  7. data/lib/bunto/collection.rb +11 -4
  8. data/lib/bunto/commands/build.rb +17 -2
  9. data/lib/bunto/commands/doctor.rb +1 -1
  10. data/lib/bunto/commands/new.rb +35 -5
  11. data/lib/bunto/commands/new_theme.rb +4 -2
  12. data/lib/bunto/commands/serve.rb +45 -15
  13. data/lib/bunto/commands/serve/servlet.rb +1 -1
  14. data/lib/bunto/configuration.rb +9 -7
  15. data/lib/bunto/converters/markdown/kramdown_parser.rb +2 -2
  16. data/lib/bunto/converters/markdown/redcarpet_parser.rb +1 -1
  17. data/lib/bunto/convertible.rb +21 -82
  18. data/lib/bunto/desktop.ini +1 -1
  19. data/lib/bunto/document.rb +118 -81
  20. data/lib/bunto/drops/bunto_drop.rb +1 -1
  21. data/lib/bunto/drops/static_file_drop.rb +11 -0
  22. data/lib/bunto/drops/url_drop.rb +5 -0
  23. data/lib/bunto/entry_filter.rb +9 -10
  24. data/lib/bunto/excerpt.rb +2 -3
  25. data/lib/bunto/external.rb +1 -1
  26. data/lib/bunto/filters.rb +10 -32
  27. data/lib/bunto/filters/grouping_filters.rb +63 -0
  28. data/lib/bunto/filters/url_filters.rb +40 -0
  29. data/lib/bunto/frontmatter_defaults.rb +1 -1
  30. data/lib/bunto/hooks.rb +9 -9
  31. data/lib/bunto/log_adapter.rb +1 -1
  32. data/lib/bunto/page.rb +8 -4
  33. data/lib/bunto/plugin.rb +1 -1
  34. data/lib/bunto/reader.rb +2 -1
  35. data/lib/bunto/readers/data_reader.rb +9 -10
  36. data/lib/bunto/readers/post_reader.rb +1 -1
  37. data/lib/bunto/readers/theme_assets_reader.rb +47 -0
  38. data/lib/bunto/regenerator.rb +1 -1
  39. data/lib/bunto/related_posts.rb +3 -9
  40. data/lib/bunto/renderer.rb +26 -6
  41. data/lib/bunto/site.rb +12 -7
  42. data/lib/bunto/static_file.rb +20 -9
  43. data/lib/bunto/tags/highlight.rb +3 -3
  44. data/lib/bunto/tags/include.rb +9 -5
  45. data/lib/bunto/tags/link.rb +4 -2
  46. data/lib/bunto/tags/post_url.rb +4 -2
  47. data/lib/bunto/theme.rb +8 -4
  48. data/lib/bunto/theme_builder.rb +2 -2
  49. data/lib/bunto/url.rb +31 -8
  50. data/lib/bunto/utils.rb +16 -2
  51. data/lib/bunto/utils/ansi.rb +1 -1
  52. data/lib/bunto/utils/exec.rb +25 -0
  53. data/lib/bunto/utils/platforms.rb +52 -2
  54. data/lib/bunto/utils/win_tz.rb +73 -0
  55. data/lib/bunto/version.rb +1 -1
  56. data/lib/site_template/_config.yml +8 -3
  57. data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +4 -4
  58. data/lib/site_template/about.md +1 -1
  59. data/lib/site_template/index.md +6 -0
  60. data/lib/theme_template/LICENSE.txt.erb +1 -1
  61. data/lib/theme_template/README.md.erb +4 -4
  62. data/lib/theme_template/gitignore.erb +1 -0
  63. data/lib/theme_template/theme.gemspec.erb +3 -2
  64. metadata +55 -40
  65. data/lib/site_template/css/main.scss +0 -39
  66. data/lib/site_template/feed.xml +0 -30
  67. data/lib/site_template/index.html +0 -23
@@ -20,7 +20,7 @@ module Bunto
20
20
  def to_h
21
21
  @to_h ||= {
22
22
  "version" => version,
23
- "environment" => environment
23
+ "environment" => environment,
24
24
  }
25
25
  end
26
26
 
@@ -0,0 +1,11 @@
1
+ module Bunto
2
+ module Drops
3
+ class StaticFileDrop < Drop
4
+ extend Forwardable
5
+ def_delegators :@obj, :name, :extname, :modified_time, :basename
6
+ def_delegator :@obj, :relative_path, :path
7
+ def_delegator :@obj, :data, :fallback_data
8
+ def_delegator :@obj, :type, :collection
9
+ end
10
+ end
11
+ end
@@ -78,6 +78,11 @@ module Bunto
78
78
  def y_day
79
79
  @obj.date.strftime("%j")
80
80
  end
81
+
82
+ private
83
+ def fallback_data
84
+ {}
85
+ end
81
86
  end
82
87
  end
83
88
  end
@@ -2,7 +2,7 @@ module Bunto
2
2
  class EntryFilter
3
3
  attr_reader :site
4
4
  SPECIAL_LEADING_CHARACTERS = [
5
- ".", "_", "#", "~"
5
+ ".", "_", "#", "~",
6
6
  ].freeze
7
7
 
8
8
  def initialize(site, base_directory = nil)
@@ -36,8 +36,7 @@ module Bunto
36
36
  end
37
37
 
38
38
  def included?(entry)
39
- glob_include?(site.include,
40
- entry)
39
+ glob_include?(site.include, entry)
41
40
  end
42
41
 
43
42
  def special?(entry)
@@ -50,14 +49,14 @@ module Bunto
50
49
  end
51
50
 
52
51
  def excluded?(entry)
53
- excluded = glob_include?(site.exclude, relative_to_source(entry))
54
- if excluded
55
- Bunto.logger.debug(
56
- "EntryFilter:",
57
- "excluded #{relative_to_source(entry)}"
58
- )
52
+ glob_include?(site.exclude, relative_to_source(entry)).tap do |excluded|
53
+ if excluded
54
+ Bunto.logger.debug(
55
+ "EntryFilter:",
56
+ "excluded #{relative_to_source(entry)}"
57
+ )
58
+ end
59
59
  end
60
- excluded
61
60
  end
62
61
 
63
62
  # --
@@ -30,8 +30,7 @@ module Bunto
30
30
  @data
31
31
  end
32
32
 
33
- def trigger_hooks(*)
34
- end
33
+ def trigger_hooks(*); end
35
34
 
36
35
  # 'Path' of the excerpt.
37
36
  #
@@ -118,7 +117,7 @@ module Bunto
118
117
  if tail.empty?
119
118
  head
120
119
  else
121
- "" << head << "\n\n" << tail.scan(%r!^\[[^\]]+\]:.+$!).join("\n")
120
+ "" << head << "\n\n" << tail.scan(%r!^ {0,3}\[[^\]]+\]:.+$!).join("\n")
122
121
  end
123
122
  end
124
123
  end
@@ -48,7 +48,7 @@ In order to use Bunto as currently configured, you'll need to install this gem.
48
48
 
49
49
  The full error message from Ruby is: '#{e.message}'
50
50
 
51
- If you run into trouble, you can find helpful resources at http://bunto.github.io/help/!
51
+ If you run into trouble, you can find helpful resources at https://buntorb.com/help/!
52
52
  MSG
53
53
  raise Bunto::Errors::MissingDependencyException, name
54
54
  end
@@ -1,10 +1,15 @@
1
- require "uri"
1
+ require "addressable/uri"
2
2
  require "json"
3
3
  require "date"
4
4
  require "liquid"
5
5
 
6
+ require_all "bunto/filters"
7
+
6
8
  module Bunto
7
9
  module Filters
10
+ include URLFilters
11
+ include GroupingFilters
12
+
8
13
  # Convert a Markdown string into HTML output.
9
14
  #
10
15
  # input - The Markdown String to convert.
@@ -147,7 +152,7 @@ module Bunto
147
152
  #
148
153
  # Returns the escaped String.
149
154
  def uri_escape(input)
150
- URI.escape(input)
155
+ Addressable::URI.normalize_component(input)
151
156
  end
152
157
 
153
158
  # Replace any whitespace in the input string with a single space
@@ -172,6 +177,7 @@ module Bunto
172
177
  # word "and" for the last one.
173
178
  #
174
179
  # array - The Array of Strings to join.
180
+ # connector - Word used to connect the last 2 items in the array
175
181
  #
176
182
  # Examples
177
183
  #
@@ -179,8 +185,7 @@ module Bunto
179
185
  # # => "apples, oranges, and grapes"
180
186
  #
181
187
  # Returns the formatted String.
182
- def array_to_sentence_string(array)
183
- connector = "and"
188
+ def array_to_sentence_string(array, connector = "and")
184
189
  case array.length
185
190
  when 0
186
191
  ""
@@ -202,29 +207,6 @@ module Bunto
202
207
  as_liquid(input).to_json
203
208
  end
204
209
 
205
- # Group an array of items by a property
206
- #
207
- # input - the inputted Enumerable
208
- # property - the property
209
- #
210
- # Returns an array of Hashes, each looking something like this:
211
- # {"name" => "larry"
212
- # "items" => [...] } # all the items where `property` == "larry"
213
- def group_by(input, property)
214
- if groupable?(input)
215
- input.group_by { |item| item_property(item, property).to_s }
216
- .each_with_object([]) do |item, array|
217
- array << {
218
- "name" => item.first,
219
- "items" => item.last,
220
- "size" => item.last.size
221
- }
222
- end
223
- else
224
- input
225
- end
226
- end
227
-
228
210
  # Filter an array of objects
229
211
  #
230
212
  # input - the object array
@@ -378,11 +360,6 @@ module Bunto
378
360
  end.localtime
379
361
  end
380
362
 
381
- private
382
- def groupable?(element)
383
- element.respond_to?(:group_by)
384
- end
385
-
386
363
  private
387
364
  def item_property(item, property)
388
365
  if item.respond_to?(:to_liquid)
@@ -433,6 +410,7 @@ module Bunto
433
410
 
434
411
  condition
435
412
  end
413
+
436
414
  end
437
415
  end
438
416
 
@@ -0,0 +1,63 @@
1
+ module Bunto
2
+ module Filters
3
+ module GroupingFilters
4
+ # Group an array of items by a property
5
+ #
6
+ # input - the inputted Enumerable
7
+ # property - the property
8
+ #
9
+ # Returns an array of Hashes, each looking something like this:
10
+ # {"name" => "larry"
11
+ # "items" => [...] } # all the items where `property` == "larry"
12
+ def group_by(input, property)
13
+ if groupable?(input)
14
+ groups = input.group_by { |item| item_property(item, property).to_s }
15
+ grouped_array(groups)
16
+ else
17
+ input
18
+ end
19
+ end
20
+
21
+ # Group an array of items by an expression
22
+ #
23
+ # input - the object array
24
+ # variable - the variable to assign each item to in the expression
25
+ # expression -a Liquid comparison expression passed in as a string
26
+ #
27
+ # Returns the filtered array of objects
28
+ def group_by_exp(input, variable, expression)
29
+ return input unless groupable?(input)
30
+
31
+ parsed_expr = parse_expression(expression)
32
+ @context.stack do
33
+ groups = input.group_by do |item|
34
+ @context[variable] = item
35
+ parsed_expr.render(@context)
36
+ end
37
+ grouped_array(groups)
38
+ end
39
+ end
40
+
41
+ private
42
+ def parse_expression(str)
43
+ Liquid::Variable.new(str, {})
44
+ end
45
+
46
+ private
47
+ def groupable?(element)
48
+ element.respond_to?(:group_by)
49
+ end
50
+
51
+ private
52
+ def grouped_array(groups)
53
+ groups.each_with_object([]) do |item, array|
54
+ array << {
55
+ "name" => item.first,
56
+ "items" => item.last,
57
+ "size" => item.last.size,
58
+ }
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,40 @@
1
+ require "addressable/uri"
2
+
3
+ module Bunto
4
+ module Filters
5
+ module URLFilters
6
+ # Produces an absolute URL based on site.url and site.baseurl.
7
+ #
8
+ # input - the URL to make absolute.
9
+ #
10
+ # Returns the absolute URL as a String.
11
+ def absolute_url(input)
12
+ return if input.nil?
13
+ site = @context.registers[:site]
14
+ return relative_url(input).to_s if site.config["url"].nil?
15
+ Addressable::URI.parse(site.config["url"] + relative_url(input)).normalize.to_s
16
+ end
17
+
18
+ # Produces a URL relative to the domain root based on site.baseurl.
19
+ #
20
+ # input - the URL to make relative to the domain root
21
+ #
22
+ # Returns a URL relative to the domain root as a String.
23
+ def relative_url(input)
24
+ return if input.nil?
25
+ site = @context.registers[:site]
26
+ parts = [site.config["baseurl"], input]
27
+ Addressable::URI.parse(
28
+ parts.compact.map { |part| ensure_leading_slash(part.to_s) }.join
29
+ ).normalize.to_s
30
+ end
31
+
32
+ private
33
+ def ensure_leading_slash(input)
34
+ return input if input.nil? || input.empty? || input.start_with?("/")
35
+ "/#{input}"
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -188,7 +188,7 @@ module Bunto
188
188
  if path.nil? || path.empty?
189
189
  ""
190
190
  else
191
- path.gsub(%r!\A/!, "").gsub(%r!([^/])\z!, '\1')
191
+ path.gsub(%r!\A/|(?<=[^/])\z!, "".freeze)
192
192
  end
193
193
  end
194
194
  end
@@ -6,7 +6,7 @@ module Bunto
6
6
  PRIORITY_MAP = {
7
7
  :low => 10,
8
8
  :normal => 20,
9
- :high => 30
9
+ :high => 30,
10
10
  }.freeze
11
11
 
12
12
  # initial empty hooks
@@ -17,26 +17,26 @@ module Bunto
17
17
  :post_read => [],
18
18
  :pre_render => [],
19
19
  :post_render => [],
20
- :post_write => []
20
+ :post_write => [],
21
21
  },
22
22
  :pages => {
23
23
  :post_init => [],
24
24
  :pre_render => [],
25
25
  :post_render => [],
26
- :post_write => []
26
+ :post_write => [],
27
27
  },
28
28
  :posts => {
29
29
  :post_init => [],
30
30
  :pre_render => [],
31
31
  :post_render => [],
32
- :post_write => []
32
+ :post_write => [],
33
33
  },
34
34
  :documents => {
35
35
  :post_init => [],
36
36
  :pre_render => [],
37
37
  :post_render => [],
38
- :post_write => []
39
- }
38
+ :post_write => [],
39
+ },
40
40
  }
41
41
 
42
42
  # map of all hooks and their priorities
@@ -54,7 +54,7 @@ module Bunto
54
54
 
55
55
  # Ensure the priority is a Fixnum
56
56
  def self.priority_value(priority)
57
- return priority if priority.is_a?(Fixnum)
57
+ return priority if priority.is_a?(Integer)
58
58
  PRIORITY_MAP[priority] || DEFAULT_PRIORITY
59
59
  end
60
60
 
@@ -64,7 +64,7 @@ module Bunto
64
64
  :post_init => [],
65
65
  :pre_render => [],
66
66
  :post_render => [],
67
- :post_write => []
67
+ :post_write => [],
68
68
  }
69
69
 
70
70
  unless @registry[owner][event]
@@ -80,7 +80,7 @@ module Bunto
80
80
  end
81
81
 
82
82
  def self.insert_hook(owner, event, priority, &block)
83
- @hook_priority[block] = "#{priority}.#{@hook_priority.size}".to_f
83
+ @hook_priority[block] = [-priority, @hook_priority.size]
84
84
  @registry[owner][event] << block
85
85
  end
86
86
 
@@ -6,7 +6,7 @@ module Bunto
6
6
  :debug => ::Logger::DEBUG,
7
7
  :info => ::Logger::INFO,
8
8
  :warn => ::Logger::WARN,
9
- :error => ::Logger::ERROR
9
+ :error => ::Logger::ERROR,
10
10
  }.freeze
11
11
 
12
12
  # Public: Create a new instance of a log writer
@@ -40,7 +40,11 @@ module Bunto
40
40
  @base = base
41
41
  @dir = dir
42
42
  @name = name
43
- @path = site.in_source_dir(base, dir, name)
43
+ @path = if site.in_theme_dir(base) == base # we're in a theme
44
+ site.in_theme_dir(base, dir, name)
45
+ else
46
+ site.in_source_dir(base, dir, name)
47
+ end
44
48
 
45
49
  process(name)
46
50
  read_yaml(File.join(base, dir), name)
@@ -54,7 +58,7 @@ module Bunto
54
58
 
55
59
  # The generated directory into which the page will be placed
56
60
  # upon generation. This is derived from the permalink or, if
57
- # permalink is absent, we be '/'
61
+ # permalink is absent, will be '/'
58
62
  #
59
63
  # Returns the String destination directory.
60
64
  def dir
@@ -94,7 +98,7 @@ module Bunto
94
98
  @url ||= URL.new({
95
99
  :template => template,
96
100
  :placeholders => url_placeholders,
97
- :permalink => permalink
101
+ :permalink => permalink,
98
102
  }).to_s
99
103
  end
100
104
 
@@ -104,7 +108,7 @@ module Bunto
104
108
  {
105
109
  :path => @dir,
106
110
  :basename => basename,
107
- :output_ext => output_ext
111
+ :output_ext => output_ext,
108
112
  }
109
113
  end
110
114
 
@@ -5,7 +5,7 @@ module Bunto
5
5
  :highest => 100,
6
6
  :lowest => -100,
7
7
  :normal => 0,
8
- :high => 10
8
+ :high => 10,
9
9
  }.freeze
10
10
 
11
11
  #
@@ -18,6 +18,7 @@ module Bunto
18
18
  sort_files!
19
19
  @site.data = DataReader.new(site).read(site.config["data_dir"])
20
20
  CollectionReader.new(site).read
21
+ ThemeAssetsReader.new(site).read
21
22
  end
22
23
 
23
24
  # Sorts posts, pages, and static files.
@@ -70,7 +71,7 @@ module Bunto
70
71
  #
71
72
  # Returns nothing.
72
73
  def retrieve_dirs(_base, dir, dot_dirs)
73
- dot_dirs.map do |file|
74
+ dot_dirs.each do |file|
74
75
  dir_path = site.in_source_dir(dir, file)
75
76
  rel_path = File.join(dir, file)
76
77
  unless @site.dest.sub(%r!/$!, "") == dir_path