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,61 @@
1
+ require "webrick"
2
+
3
+ module Bunto
4
+ module Commands
5
+ class Serve
6
+ class Servlet < WEBrick::HTTPServlet::FileHandler
7
+ DEFAULTS = {
8
+ "Cache-Control" => "private, max-age=0, proxy-revalidate, " \
9
+ "no-store, no-cache, must-revalidate"
10
+ }
11
+
12
+ def initialize(server, root, callbacks)
13
+ # So we can access them easily.
14
+ @bunto_opts = server.config[:BuntoOptions]
15
+ set_defaults
16
+ super
17
+ end
18
+
19
+ # Add the ability to tap file.html the same way that Nginx does on our
20
+ # Docker images (or on GitHub Pages.) The difference is that we might end
21
+ # up with a different preference on which comes first.
22
+
23
+ def search_file(req, res, basename)
24
+ # /file.* > /file/index.html > /file.html
25
+ super || super(req, res, "#{basename}.html")
26
+ end
27
+
28
+ #
29
+
30
+ def do_GET(req, res)
31
+ rtn = super
32
+ validate_and_ensure_charset(req, res)
33
+ res.header.merge!(@headers)
34
+ rtn
35
+ end
36
+
37
+ #
38
+
39
+ private
40
+ def validate_and_ensure_charset(_req, res)
41
+ key = res.header.keys.grep(/content-type/i).first
42
+ typ = res.header[key]
43
+
44
+ unless typ =~ /;\s*charset=/
45
+ res.header[key] = "#{typ}; charset=#{@bunto_opts["encoding"]}"
46
+ end
47
+ end
48
+
49
+ #
50
+
51
+ private
52
+ def set_defaults
53
+ hash_ = @bunto_opts.fetch("webrick", {}).fetch("headers", {})
54
+ DEFAULTS.each_with_object(@headers = hash_) do |(key, val), hash|
55
+ hash[key] = val unless hash.key?(key)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,323 @@
1
+ # encoding: UTF-8
2
+
3
+ module Bunto
4
+ class Configuration < Hash
5
+ # Default options. Overridden by values in _config.yml.
6
+ # Strings rather than symbols are used for compatibility with YAML.
7
+ DEFAULTS = Configuration[{
8
+ # Where things are
9
+ 'source' => Dir.pwd,
10
+ 'destination' => File.join(Dir.pwd, '_site'),
11
+ 'plugins_dir' => '_plugins',
12
+ 'layouts_dir' => '_layouts',
13
+ 'data_dir' => '_data',
14
+ 'includes_dir' => '_includes',
15
+ 'collections' => {},
16
+
17
+ # Handling Reading
18
+ 'safe' => false,
19
+ 'include' => ['.htaccess'],
20
+ 'exclude' => [],
21
+ 'keep_files' => ['.git', '.svn'],
22
+ 'encoding' => 'utf-8',
23
+ 'markdown_ext' => 'markdown,mkdown,mkdn,mkd,md',
24
+
25
+ # Filtering Content
26
+ 'show_drafts' => nil,
27
+ 'limit_posts' => 0,
28
+ 'future' => false,
29
+ 'unpublished' => false,
30
+
31
+ # Plugins
32
+ 'whitelist' => [],
33
+ 'gems' => [],
34
+
35
+ # Conversion
36
+ 'markdown' => 'kramdown',
37
+ 'highlighter' => 'rouge',
38
+ 'lsi' => false,
39
+ 'excerpt_separator' => "\n\n",
40
+ 'incremental' => false,
41
+
42
+ # Serving
43
+ 'detach' => false, # default to not detaching the server
44
+ 'port' => '4000',
45
+ 'host' => '127.0.0.1',
46
+ 'baseurl' => '',
47
+
48
+ # Output Configuration
49
+ 'permalink' => 'date',
50
+ 'paginate_path' => '/page:num',
51
+ 'timezone' => nil, # use the local timezone
52
+
53
+ 'quiet' => false,
54
+ 'verbose' => false,
55
+ 'defaults' => [],
56
+
57
+ 'rdiscount' => {
58
+ 'extensions' => []
59
+ },
60
+
61
+ 'redcarpet' => {
62
+ 'extensions' => []
63
+ },
64
+
65
+ 'kramdown' => {
66
+ 'auto_ids' => true,
67
+ 'toc_levels' => '1..6',
68
+ 'entity_output' => 'as_char',
69
+ 'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
70
+ 'input' => "GFM",
71
+ 'hard_wrap' => false,
72
+ 'footnote_nr' => 1
73
+ }
74
+ }]
75
+
76
+ # Public: Turn all keys into string
77
+ #
78
+ # Return a copy of the hash where all its keys are strings
79
+ def stringify_keys
80
+ reduce({}) { |hsh, (k, v)| hsh.merge(k.to_s => v) }
81
+ end
82
+
83
+ def get_config_value_with_override(config_key, override)
84
+ override[config_key] || self[config_key] || DEFAULTS[config_key]
85
+ end
86
+
87
+ # Public: Directory of the Bunto source folder
88
+ #
89
+ # override - the command-line options hash
90
+ #
91
+ # Returns the path to the Bunto source directory
92
+ def source(override)
93
+ get_config_value_with_override('source', override)
94
+ end
95
+
96
+ def quiet(override = {})
97
+ get_config_value_with_override('quiet', override)
98
+ end
99
+ alias_method :quiet?, :quiet
100
+
101
+ def verbose(override = {})
102
+ get_config_value_with_override('verbose', override)
103
+ end
104
+ alias_method :verbose?, :verbose
105
+
106
+ def safe_load_file(filename)
107
+ case File.extname(filename)
108
+ when /\.toml/i
109
+ Bunto::External.require_with_graceful_fail('toml') unless defined?(TOML)
110
+ TOML.load_file(filename)
111
+ when /\.ya?ml/i
112
+ SafeYAML.load_file(filename) || {}
113
+ else
114
+ raise ArgumentError, "No parser for '#{filename}' is available. Use a .toml or .y(a)ml file instead."
115
+ end
116
+ end
117
+
118
+ # Public: Generate list of configuration files from the override
119
+ #
120
+ # override - the command-line options hash
121
+ #
122
+ # Returns an Array of config files
123
+ def config_files(override)
124
+ # Adjust verbosity quickly
125
+ Bunto.logger.adjust_verbosity(:quiet => quiet?(override), :verbose => verbose?(override))
126
+
127
+ # Get configuration from <source>/_config.yml or <source>/<config_file>
128
+ config_files = override.delete('config')
129
+ if config_files.to_s.empty?
130
+ default = %w(yml yaml).find(-> { 'yml' }) do |ext|
131
+ File.exist?(Bunto.sanitized_path(source(override), "_config.#{ext}"))
132
+ end
133
+ config_files = Bunto.sanitized_path(source(override), "_config.#{default}")
134
+ @default_config_file = true
135
+ end
136
+ config_files = [config_files] unless config_files.is_a? Array
137
+ config_files
138
+ end
139
+
140
+ # Public: Read configuration and return merged Hash
141
+ #
142
+ # file - the path to the YAML file to be read in
143
+ #
144
+ # Returns this configuration, overridden by the values in the file
145
+ def read_config_file(file)
146
+ next_config = safe_load_file(file)
147
+ check_config_is_hash!(next_config, file)
148
+ Bunto.logger.info "Configuration file:", file
149
+ next_config
150
+ rescue SystemCallError
151
+ if @default_config_file
152
+ Bunto.logger.warn "Configuration file:", "none"
153
+ {}
154
+ else
155
+ Bunto.logger.error "Fatal:", "The configuration file '#{file}' could not be found."
156
+ raise LoadError, "The Configuration file '#{file}' could not be found."
157
+ end
158
+ end
159
+
160
+ # Public: Read in a list of configuration files and merge with this hash
161
+ #
162
+ # files - the list of configuration file paths
163
+ #
164
+ # Returns the full configuration, with the defaults overridden by the values in the
165
+ # configuration files
166
+ def read_config_files(files)
167
+ configuration = clone
168
+
169
+ begin
170
+ files.each do |config_file|
171
+ new_config = read_config_file(config_file)
172
+ configuration = Utils.deep_merge_hashes(configuration, new_config)
173
+ end
174
+ rescue ArgumentError => err
175
+ Bunto.logger.warn "WARNING:", "Error reading configuration. " \
176
+ "Using defaults (and options)."
177
+ $stderr.puts "#{err}"
178
+ end
179
+
180
+ configuration.fix_common_issues.backwards_compatibilize.add_default_collections
181
+ end
182
+
183
+ # Public: Split a CSV string into an array containing its values
184
+ #
185
+ # csv - the string of comma-separated values
186
+ #
187
+ # Returns an array of the values contained in the CSV
188
+ def csv_to_array(csv)
189
+ csv.split(",").map(&:strip)
190
+ end
191
+
192
+ # Public: Ensure the proper options are set in the configuration to allow for
193
+ # backwards-compatibility with Bunto pre-1.0
194
+ #
195
+ # Returns the backwards-compatible configuration
196
+ def backwards_compatibilize
197
+ config = clone
198
+ # Provide backwards-compatibility
199
+ if config.key?('auto') || config.key?('watch')
200
+ Bunto::Deprecator.deprecation_message "Auto-regeneration can no longer" \
201
+ " be set from your configuration file(s). Use the"\
202
+ " --[no-]watch/-w command-line option instead."
203
+ config.delete('auto')
204
+ config.delete('watch')
205
+ end
206
+
207
+ if config.key? 'server'
208
+ Bunto::Deprecator.deprecation_message "The 'server' configuration option" \
209
+ " is no longer accepted. Use the 'bunto serve'" \
210
+ " subcommand to serve your site with WEBrick."
211
+ config.delete('server')
212
+ end
213
+
214
+ renamed_key 'server_port', 'port', config
215
+ renamed_key 'plugins', 'plugins_dir', config
216
+ renamed_key 'layouts', 'layouts_dir', config
217
+ renamed_key 'data_source', 'data_dir', config
218
+
219
+ if config.key? 'pygments'
220
+ Bunto::Deprecator.deprecation_message "The 'pygments' configuration option" \
221
+ " has been renamed to 'highlighter'. Please update your" \
222
+ " config file accordingly. The allowed values are 'rouge', " \
223
+ "'pygments' or null."
224
+
225
+ config['highlighter'] = 'pygments' if config['pygments']
226
+ config.delete('pygments')
227
+ end
228
+
229
+ %w(include exclude).each do |option|
230
+ config[option] ||= []
231
+ if config[option].is_a?(String)
232
+ Bunto::Deprecator.deprecation_message "The '#{option}' configuration option" \
233
+ " must now be specified as an array, but you specified" \
234
+ " a string. For now, we've treated the string you provided" \
235
+ " as a list of comma-separated values."
236
+ config[option] = csv_to_array(config[option])
237
+ end
238
+ config[option].map!(&:to_s)
239
+ end
240
+
241
+ if (config['kramdown'] || {}).key?('use_coderay')
242
+ Bunto::Deprecator.deprecation_message "Please change 'use_coderay'" \
243
+ " to 'enable_coderay' in your configuration file."
244
+ config['kramdown']['use_coderay'] = config['kramdown'].delete('enable_coderay')
245
+ end
246
+
247
+ if config.fetch('markdown', 'kramdown').to_s.downcase.eql?("maruku")
248
+ Bunto.logger.abort_with "Error:", "You're using the 'maruku' " \
249
+ "Markdown processor, which has been removed as of 3.0.0. " \
250
+ "We recommend you switch to Kramdown. To do this, replace " \
251
+ "`markdown: maruku` with `markdown: kramdown` in your " \
252
+ "`_config.yml` file."
253
+ end
254
+
255
+ config
256
+ end
257
+
258
+ def fix_common_issues
259
+ config = clone
260
+
261
+ if config.key?('paginate') && (!config['paginate'].is_a?(Integer) || config['paginate'] < 1)
262
+ Bunto.logger.warn "Config Warning:", "The `paginate` key must be a" \
263
+ " positive integer or nil. It's currently set to '#{config['paginate'].inspect}'."
264
+ config['paginate'] = nil
265
+ end
266
+
267
+ config
268
+ end
269
+
270
+ def add_default_collections
271
+ config = clone
272
+
273
+ return config if config['collections'].nil?
274
+
275
+ if config['collections'].is_a?(Array)
276
+ config['collections'] = Hash[config['collections'].map { |c| [c, {}] }]
277
+ end
278
+ config['collections']['posts'] ||= {}
279
+ config['collections']['posts']['output'] = true
280
+ config['collections']['posts']['permalink'] = style_to_permalink(config['permalink'])
281
+
282
+ config
283
+ end
284
+
285
+ def renamed_key(old, new, config, _ = nil)
286
+ if config.key?(old)
287
+ Bunto::Deprecator.deprecation_message "The '#{old}' configuration" \
288
+ "option has been renamed to '#{new}'. Please update your config " \
289
+ "file accordingly."
290
+ config[new] = config.delete(old)
291
+ end
292
+ end
293
+
294
+ private
295
+
296
+ def style_to_permalink(permalink_style)
297
+ case permalink_style.to_sym
298
+ when :pretty
299
+ "/:categories/:year/:month/:day/:title/"
300
+ when :none
301
+ "/:categories/:title:output_ext"
302
+ when :date
303
+ "/:categories/:year/:month/:day/:title:output_ext"
304
+ when :ordinal
305
+ "/:categories/:year/:y_day/:title:output_ext"
306
+ else
307
+ permalink_style.to_s
308
+ end
309
+ end
310
+
311
+ # Private: Checks if a given config is a hash
312
+ #
313
+ # extracted_config - the value to check
314
+ # file - the file from which the config was extracted
315
+ #
316
+ # Raises an ArgumentError if given config is not a hash
317
+ def check_config_is_hash!(extracted_config, file)
318
+ unless extracted_config.is_a?(Hash)
319
+ raise ArgumentError.new("Configuration file: (INVALID) #{file}".yellow)
320
+ end
321
+ end
322
+ end
323
+ end
@@ -0,0 +1,48 @@
1
+ module Bunto
2
+ class Converter < Plugin
3
+ # Public: Get or set the highlighter prefix. When an argument is specified,
4
+ # the prefix will be set. If no argument is specified, the current prefix
5
+ # will be returned.
6
+ #
7
+ # highlighter_prefix - The String prefix (default: nil).
8
+ #
9
+ # Returns the String prefix.
10
+ def self.highlighter_prefix(highlighter_prefix = nil)
11
+ @highlighter_prefix = highlighter_prefix if highlighter_prefix
12
+ @highlighter_prefix
13
+ end
14
+
15
+ # Public: Get or set the highlighter suffix. When an argument is specified,
16
+ # the suffix will be set. If no argument is specified, the current suffix
17
+ # will be returned.
18
+ #
19
+ # highlighter_suffix - The String suffix (default: nil).
20
+ #
21
+ # Returns the String suffix.
22
+ def self.highlighter_suffix(highlighter_suffix = nil)
23
+ @highlighter_suffix = highlighter_suffix if highlighter_suffix
24
+ @highlighter_suffix
25
+ end
26
+
27
+ # Initialize the converter.
28
+ #
29
+ # Returns an initialized Converter.
30
+ def initialize(config = {})
31
+ @config = config
32
+ end
33
+
34
+ # Get the highlighter prefix.
35
+ #
36
+ # Returns the String prefix.
37
+ def highlighter_prefix
38
+ self.class.highlighter_prefix
39
+ end
40
+
41
+ # Get the highlighter suffix.
42
+ #
43
+ # Returns the String suffix.
44
+ def highlighter_suffix
45
+ self.class.highlighter_suffix
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,21 @@
1
+ module Bunto
2
+ module Converters
3
+ class Identity < Converter
4
+ safe true
5
+
6
+ priority :lowest
7
+
8
+ def matches(_ext)
9
+ true
10
+ end
11
+
12
+ def output_ext(ext)
13
+ ext
14
+ end
15
+
16
+ def convert(content)
17
+ content
18
+ end
19
+ end
20
+ end
21
+ end