bunto 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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