bunto 1.0.0

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 (95) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.markdown +59 -0
  4. data/bin/bunto +51 -0
  5. data/lib/bunto.rb +179 -0
  6. data/lib/bunto/cleaner.rb +105 -0
  7. data/lib/bunto/collection.rb +205 -0
  8. data/lib/bunto/command.rb +65 -0
  9. data/lib/bunto/commands/build.rb +77 -0
  10. data/lib/bunto/commands/clean.rb +42 -0
  11. data/lib/bunto/commands/doctor.rb +114 -0
  12. data/lib/bunto/commands/help.rb +31 -0
  13. data/lib/bunto/commands/new.rb +82 -0
  14. data/lib/bunto/commands/serve.rb +204 -0
  15. data/lib/bunto/commands/serve/servlet.rb +61 -0
  16. data/lib/bunto/configuration.rb +323 -0
  17. data/lib/bunto/converter.rb +48 -0
  18. data/lib/bunto/converters/identity.rb +21 -0
  19. data/lib/bunto/converters/markdown.rb +92 -0
  20. data/lib/bunto/converters/markdown/kramdown_parser.rb +117 -0
  21. data/lib/bunto/converters/markdown/rdiscount_parser.rb +33 -0
  22. data/lib/bunto/converters/markdown/redcarpet_parser.rb +102 -0
  23. data/lib/bunto/converters/smartypants.rb +34 -0
  24. data/lib/bunto/convertible.rb +297 -0
  25. data/lib/bunto/deprecator.rb +46 -0
  26. data/lib/bunto/document.rb +444 -0
  27. data/lib/bunto/drops/bunto_drop.rb +21 -0
  28. data/lib/bunto/drops/collection_drop.rb +22 -0
  29. data/lib/bunto/drops/document_drop.rb +27 -0
  30. data/lib/bunto/drops/drop.rb +176 -0
  31. data/lib/bunto/drops/site_drop.rb +38 -0
  32. data/lib/bunto/drops/unified_payload_drop.rb +25 -0
  33. data/lib/bunto/drops/url_drop.rb +83 -0
  34. data/lib/bunto/entry_filter.rb +72 -0
  35. data/lib/bunto/errors.rb +10 -0
  36. data/lib/bunto/excerpt.rb +127 -0
  37. data/lib/bunto/external.rb +59 -0
  38. data/lib/bunto/filters.rb +367 -0
  39. data/lib/bunto/frontmatter_defaults.rb +188 -0
  40. data/lib/bunto/generator.rb +3 -0
  41. data/lib/bunto/hooks.rb +101 -0
  42. data/lib/bunto/layout.rb +49 -0
  43. data/lib/bunto/liquid_extensions.rb +22 -0
  44. data/lib/bunto/liquid_renderer.rb +39 -0
  45. data/lib/bunto/liquid_renderer/file.rb +50 -0
  46. data/lib/bunto/liquid_renderer/table.rb +94 -0
  47. data/lib/bunto/log_adapter.rb +115 -0
  48. data/lib/bunto/mime.types +800 -0
  49. data/lib/bunto/page.rb +180 -0
  50. data/lib/bunto/plugin.rb +96 -0
  51. data/lib/bunto/plugin_manager.rb +95 -0
  52. data/lib/bunto/post.rb +329 -0
  53. data/lib/bunto/publisher.rb +21 -0
  54. data/lib/bunto/reader.rb +126 -0
  55. data/lib/bunto/readers/collection_reader.rb +20 -0
  56. data/lib/bunto/readers/data_reader.rb +69 -0
  57. data/lib/bunto/readers/layout_reader.rb +53 -0
  58. data/lib/bunto/readers/page_reader.rb +21 -0
  59. data/lib/bunto/readers/post_reader.rb +62 -0
  60. data/lib/bunto/readers/static_file_reader.rb +21 -0
  61. data/lib/bunto/regenerator.rb +175 -0
  62. data/lib/bunto/related_posts.rb +56 -0
  63. data/lib/bunto/renderer.rb +191 -0
  64. data/lib/bunto/site.rb +391 -0
  65. data/lib/bunto/static_file.rb +141 -0
  66. data/lib/bunto/stevenson.rb +58 -0
  67. data/lib/bunto/tags/highlight.rb +122 -0
  68. data/lib/bunto/tags/include.rb +190 -0
  69. data/lib/bunto/tags/post_url.rb +88 -0
  70. data/lib/bunto/url.rb +136 -0
  71. data/lib/bunto/utils.rb +287 -0
  72. data/lib/bunto/utils/ansi.rb +59 -0
  73. data/lib/bunto/utils/platforms.rb +30 -0
  74. data/lib/bunto/version.rb +3 -0
  75. data/lib/site_template/.gitignore +3 -0
  76. data/lib/site_template/_config.yml +21 -0
  77. data/lib/site_template/_includes/footer.html +38 -0
  78. data/lib/site_template/_includes/head.html +12 -0
  79. data/lib/site_template/_includes/header.html +27 -0
  80. data/lib/site_template/_includes/icon-github.html +1 -0
  81. data/lib/site_template/_includes/icon-github.svg +1 -0
  82. data/lib/site_template/_includes/icon-twitter.html +1 -0
  83. data/lib/site_template/_includes/icon-twitter.svg +1 -0
  84. data/lib/site_template/_layouts/default.html +20 -0
  85. data/lib/site_template/_layouts/page.html +14 -0
  86. data/lib/site_template/_layouts/post.html +15 -0
  87. data/lib/site_template/_posts/0000-00-00-welcome-to-bunto.markdown.erb +25 -0
  88. data/lib/site_template/_sass/_base.scss +206 -0
  89. data/lib/site_template/_sass/_layout.scss +242 -0
  90. data/lib/site_template/_sass/_syntax-highlighting.scss +71 -0
  91. data/lib/site_template/about.md +15 -0
  92. data/lib/site_template/css/main.scss +53 -0
  93. data/lib/site_template/feed.xml +30 -0
  94. data/lib/site_template/index.html +23 -0
  95. metadata +252 -0
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class BuntoDrop < Liquid::Drop
6
+ class << self
7
+ def global
8
+ @global ||= BuntoDrop.new
9
+ end
10
+ end
11
+
12
+ def version
13
+ Bunto::VERSION
14
+ end
15
+
16
+ def environment
17
+ Bunto.env
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class CollectionDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :write?, :output
11
+ def_delegators :@obj, :label, :docs, :files, :directory,
12
+ :relative_directory
13
+
14
+ def to_s
15
+ docs.to_s
16
+ end
17
+
18
+ private
19
+ def_delegator :@obj, :metadata, :fallback_data
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class DocumentDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :next_doc, :next
11
+ def_delegator :@obj, :previous_doc, :previous
12
+ def_delegator :@obj, :relative_path, :path
13
+ def_delegators :@obj, :id, :output, :content, :to_s, :relative_path, :url
14
+
15
+ def collection
16
+ @obj.collection.label
17
+ end
18
+
19
+ def excerpt
20
+ fallback_data['excerpt'].to_s
21
+ end
22
+
23
+ private
24
+ def_delegator :@obj, :data, :fallback_data
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,176 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class Drop < Liquid::Drop
6
+ NON_CONTENT_METHODS = [:[], :[]=, :inspect, :to_h, :fallback_data].freeze
7
+
8
+ # Get or set whether the drop class is mutable.
9
+ # Mutability determines whether or not pre-defined fields may be
10
+ # overwritten.
11
+ #
12
+ # is_mutable - Boolean set mutability of the class (default: nil)
13
+ #
14
+ # Returns the mutability of the class
15
+ def self.mutable(is_mutable = nil)
16
+ if is_mutable
17
+ @is_mutable = is_mutable
18
+ else
19
+ @is_mutable = false
20
+ end
21
+ end
22
+
23
+ def self.mutable?
24
+ @is_mutable
25
+ end
26
+
27
+ # Create a new Drop
28
+ #
29
+ # obj - the Bunto Site, Collection, or Document required by the
30
+ # drop.
31
+ #
32
+ # Returns nothing
33
+ def initialize(obj)
34
+ @obj = obj
35
+ @mutations = {} # only if mutable: true
36
+ end
37
+
38
+ # Access a method in the Drop or a field in the underlying hash data.
39
+ # If mutable, checks the mutations first. Then checks the methods,
40
+ # and finally check the underlying hash (e.g. document front matter)
41
+ # if all the previous places didn't match.
42
+ #
43
+ # key - the string key whose value to fetch
44
+ #
45
+ # Returns the value for the given key, or nil if none exists
46
+ def [](key)
47
+ if self.class.mutable? && @mutations.key?(key)
48
+ @mutations[key]
49
+ elsif self.class.invokable? key
50
+ public_send key
51
+ else
52
+ fallback_data[key]
53
+ end
54
+ end
55
+
56
+ # Set a field in the Drop. If mutable, sets in the mutations and
57
+ # returns. If not mutable, checks first if it's trying to override a
58
+ # Drop method and raises a DropMutationException if so. If not
59
+ # mutable and the key is not a method on the Drop, then it sets the
60
+ # key to the value in the underlying hash (e.g. document front
61
+ # matter)
62
+ #
63
+ # key - the String key whose value to set
64
+ # val - the Object to set the key's value to
65
+ #
66
+ # Returns the value the key was set to unless the Drop is not mutable
67
+ # and the key matches a method in which case it raises a
68
+ # DropMutationException.
69
+ def []=(key, val)
70
+ if respond_to?("#{key}=")
71
+ public_send("#{key}=", val)
72
+ elsif respond_to? key
73
+ if self.class.mutable?
74
+ @mutations[key] = val
75
+ else
76
+ raise Errors::DropMutationException, "Key #{key} cannot be set in the drop."
77
+ end
78
+ else
79
+ fallback_data[key] = val
80
+ end
81
+ end
82
+
83
+ # Generates a list of strings which correspond to content getter
84
+ # methods.
85
+ #
86
+ # Returns an Array of strings which represent method-specific keys.
87
+ def content_methods
88
+ @content_methods ||= (
89
+ self.class.instance_methods(false) - NON_CONTENT_METHODS
90
+ ).map(&:to_s).reject do |method|
91
+ method.end_with?("=")
92
+ end
93
+ end
94
+
95
+ # Check if key exists in Drop
96
+ #
97
+ # key - the string key whose value to fetch
98
+ #
99
+ # Returns true if the given key is present
100
+ def key?(key)
101
+ if self.class.mutable && @mutations.key?(key)
102
+ true
103
+ else
104
+ respond_to?(key) || fallback_data.key?(key)
105
+ end
106
+ end
107
+
108
+ # Generates a list of keys with user content as their values.
109
+ # This gathers up the Drop methods and keys of the mutations and
110
+ # underlying data hashes and performs a set union to ensure a list
111
+ # of unique keys for the Drop.
112
+ #
113
+ # Returns an Array of unique keys for content for the Drop.
114
+ def keys
115
+ (content_methods |
116
+ @mutations.keys |
117
+ fallback_data.keys).flatten
118
+ end
119
+
120
+ # Generate a Hash representation of the Drop by resolving each key's
121
+ # value. It includes Drop methods, mutations, and the underlying object's
122
+ # data. See the documentation for Drop#keys for more.
123
+ #
124
+ # Returns a Hash with all the keys and values resolved.
125
+ def to_h
126
+ keys.each_with_object({}) do |(key, _), result|
127
+ result[key] = self[key]
128
+ end
129
+ end
130
+ alias_method :to_hash, :to_h
131
+
132
+ # Inspect the drop's keys and values through a JSON representation
133
+ # of its keys and values.
134
+ #
135
+ # Returns a pretty generation of the hash representation of the Drop.
136
+ def inspect
137
+ require 'json'
138
+ JSON.pretty_generate to_h
139
+ end
140
+
141
+ # Collects all the keys and passes each to the block in turn.
142
+ #
143
+ # block - a block which accepts one argument, the key
144
+ #
145
+ # Returns nothing.
146
+ def each_key(&block)
147
+ keys.each(&block)
148
+ end
149
+
150
+ def merge(other, &block)
151
+ self.dup.tap do |me|
152
+ if block.nil?
153
+ me.merge!(other)
154
+ else
155
+ me.merge!(other, block)
156
+ end
157
+ end
158
+ end
159
+
160
+ def merge!(other)
161
+ other.each_key do |key|
162
+ if block_given?
163
+ self[key] = yield key, self[key], other[key]
164
+ else
165
+ if Utils.mergable?(self[key]) && Utils.mergable?(other[key])
166
+ self[key] = Utils.deep_merge_hashes(self[key], other[key])
167
+ next
168
+ end
169
+
170
+ self[key] = other[key] unless other[key].nil?
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end
176
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class SiteDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :site_data, :data
11
+ def_delegators :@obj, :time, :pages, :static_files, :documents,
12
+ :tags, :categories
13
+
14
+ def [](key)
15
+ if @obj.collections.key?(key) && key != "posts"
16
+ @obj.collections[key].docs
17
+ else
18
+ super(key)
19
+ end
20
+ end
21
+
22
+ def posts
23
+ @site_posts ||= @obj.posts.docs.sort { |a, b| b <=> a }
24
+ end
25
+
26
+ def html_pages
27
+ @site_html_pages ||= @obj.pages.select { |page| page.html? || page.url.end_with?("/") }
28
+ end
29
+
30
+ def collections
31
+ @site_collections ||= @obj.collections.values.map(&:to_liquid)
32
+ end
33
+
34
+ private
35
+ def_delegator :@obj, :config, :fallback_data
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class UnifiedPayloadDrop < Drop
6
+ mutable true
7
+
8
+ attr_accessor :page, :layout, :content, :paginator
9
+ attr_accessor :highlighter_prefix, :highlighter_suffix
10
+
11
+ def bunto
12
+ BuntoDrop.global
13
+ end
14
+
15
+ def site
16
+ @site_drop ||= SiteDrop.new(@obj)
17
+ end
18
+
19
+ private
20
+ def fallback_data
21
+ @fallback_data ||= {}
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ module Drops
5
+ class UrlDrop < Drop
6
+ extend Forwardable
7
+
8
+ mutable false
9
+
10
+ def_delegator :@obj, :cleaned_relative_path, :path
11
+ def_delegator :@obj, :output_ext, :output_ext
12
+
13
+ def collection
14
+ @obj.collection.label
15
+ end
16
+
17
+ def name
18
+ Utils.slugify(@obj.basename_without_ext)
19
+ end
20
+
21
+ def title
22
+ Utils.slugify(@obj.data['slug'], :mode => "pretty", :cased => true) ||
23
+ Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
24
+ end
25
+
26
+ def slug
27
+ Utils.slugify(@obj.data['slug']) || Utils.slugify(@obj.basename_without_ext)
28
+ end
29
+
30
+ def categories
31
+ category_set = Set.new
32
+ Array(@obj.data['categories']).each do |category|
33
+ category_set << category.to_s.downcase
34
+ end
35
+ category_set.to_a.join('/')
36
+ end
37
+
38
+ def year
39
+ @obj.date.strftime("%Y")
40
+ end
41
+
42
+ def month
43
+ @obj.date.strftime("%m")
44
+ end
45
+
46
+ def day
47
+ @obj.date.strftime("%d")
48
+ end
49
+
50
+ def hour
51
+ @obj.date.strftime("%H")
52
+ end
53
+
54
+ def minute
55
+ @obj.date.strftime("%M")
56
+ end
57
+
58
+ def second
59
+ @obj.date.strftime("%S")
60
+ end
61
+
62
+ def i_day
63
+ @obj.date.strftime("%-d")
64
+ end
65
+
66
+ def i_month
67
+ @obj.date.strftime("%-m")
68
+ end
69
+
70
+ def short_month
71
+ @obj.date.strftime("%b")
72
+ end
73
+
74
+ def short_year
75
+ @obj.date.strftime("%y")
76
+ end
77
+
78
+ def y_day
79
+ @obj.date.strftime("%j")
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,72 @@
1
+ module Bunto
2
+ class EntryFilter
3
+ SPECIAL_LEADING_CHARACTERS = ['.', '_', '#'].freeze
4
+
5
+ attr_reader :site
6
+
7
+ def initialize(site, base_directory = nil)
8
+ @site = site
9
+ @base_directory = derive_base_directory(@site, base_directory.to_s.dup)
10
+ end
11
+
12
+ def base_directory
13
+ @base_directory.to_s
14
+ end
15
+
16
+ def derive_base_directory(site, base_dir)
17
+ if base_dir.start_with?(site.source)
18
+ base_dir[site.source] = ""
19
+ end
20
+ base_dir
21
+ end
22
+
23
+ def relative_to_source(entry)
24
+ File.join(base_directory, entry)
25
+ end
26
+
27
+ def filter(entries)
28
+ entries.reject do |e|
29
+ unless included?(e)
30
+ special?(e) || backup?(e) || excluded?(e) || symlink?(e)
31
+ end
32
+ end
33
+ end
34
+
35
+ def included?(entry)
36
+ glob_include?(site.include, entry)
37
+ end
38
+
39
+ def special?(entry)
40
+ SPECIAL_LEADING_CHARACTERS.include?(entry[0..0]) ||
41
+ SPECIAL_LEADING_CHARACTERS.include?(File.basename(entry)[0..0])
42
+ end
43
+
44
+ def backup?(entry)
45
+ entry[-1..-1] == '~'
46
+ end
47
+
48
+ def excluded?(entry)
49
+ excluded = glob_include?(site.exclude, relative_to_source(entry))
50
+ Bunto.logger.debug "EntryFilter:", "excluded #{relative_to_source(entry)}" if excluded
51
+ excluded
52
+ end
53
+
54
+ def symlink?(entry)
55
+ File.symlink?(entry) && site.safe
56
+ end
57
+
58
+ def ensure_leading_slash(path)
59
+ path[0..0] == "/" ? path : "/#{path}"
60
+ end
61
+
62
+ # Returns true if path matches against any glob pattern.
63
+ # Look for more detail about glob pattern in method File::fnmatch.
64
+ def glob_include?(enum, e)
65
+ entry = ensure_leading_slash(e)
66
+ enum.any? do |exp|
67
+ item = ensure_leading_slash(exp)
68
+ File.fnmatch?(item, entry) || entry.start_with?(item)
69
+ end
70
+ end
71
+ end
72
+ end