monad 0.0.1

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 (143) hide show
  1. data/CONTRIBUTING.md +68 -0
  2. data/Gemfile +2 -0
  3. data/LICENSE +21 -0
  4. data/README.md +88 -0
  5. data/Rakefile +136 -0
  6. data/bin/monad +102 -0
  7. data/cucumber.yml +3 -0
  8. data/features/create_sites.feature +112 -0
  9. data/features/data_sources.feature +76 -0
  10. data/features/drafts.feature +25 -0
  11. data/features/embed_filters.feature +60 -0
  12. data/features/markdown.feature +30 -0
  13. data/features/pagination.feature +54 -0
  14. data/features/permalinks.feature +65 -0
  15. data/features/post_data.feature +214 -0
  16. data/features/site_configuration.feature +206 -0
  17. data/features/site_data.feature +101 -0
  18. data/features/step_definitions/monad_steps.rb +175 -0
  19. data/features/support/env.rb +25 -0
  20. data/lib/monad.rb +90 -0
  21. data/lib/monad/command.rb +27 -0
  22. data/lib/monad/commands/build.rb +64 -0
  23. data/lib/monad/commands/doctor.rb +29 -0
  24. data/lib/monad/commands/new.rb +50 -0
  25. data/lib/monad/commands/serve.rb +33 -0
  26. data/lib/monad/configuration.rb +183 -0
  27. data/lib/monad/converter.rb +48 -0
  28. data/lib/monad/converters/identity.rb +21 -0
  29. data/lib/monad/converters/markdown.rb +43 -0
  30. data/lib/monad/converters/markdown/kramdown_parser.rb +44 -0
  31. data/lib/monad/converters/markdown/maruku_parser.rb +47 -0
  32. data/lib/monad/converters/markdown/rdiscount_parser.rb +35 -0
  33. data/lib/monad/converters/markdown/redcarpet_parser.rb +70 -0
  34. data/lib/monad/converters/textile.rb +50 -0
  35. data/lib/monad/convertible.rb +152 -0
  36. data/lib/monad/core_ext.rb +68 -0
  37. data/lib/monad/deprecator.rb +32 -0
  38. data/lib/monad/draft.rb +35 -0
  39. data/lib/monad/drivers/json_driver.rb +39 -0
  40. data/lib/monad/drivers/yaml_driver.rb +23 -0
  41. data/lib/monad/errors.rb +4 -0
  42. data/lib/monad/filters.rb +154 -0
  43. data/lib/monad/generator.rb +4 -0
  44. data/lib/monad/generators/pagination.rb +143 -0
  45. data/lib/monad/layout.rb +42 -0
  46. data/lib/monad/logger.rb +54 -0
  47. data/lib/monad/mime.types +85 -0
  48. data/lib/monad/page.rb +163 -0
  49. data/lib/monad/plugin.rb +75 -0
  50. data/lib/monad/post.rb +377 -0
  51. data/lib/monad/site.rb +455 -0
  52. data/lib/monad/static_file.rb +70 -0
  53. data/lib/monad/tags/gist.rb +30 -0
  54. data/lib/monad/tags/highlight.rb +85 -0
  55. data/lib/monad/tags/include.rb +37 -0
  56. data/lib/monad/tags/post_url.rb +61 -0
  57. data/lib/site_template/.gitignore +1 -0
  58. data/lib/site_template/_config.yml +2 -0
  59. data/lib/site_template/_layouts/default.html +46 -0
  60. data/lib/site_template/_layouts/post.html +9 -0
  61. data/lib/site_template/_posts/0000-00-00-welcome-to-monad.markdown.erb +24 -0
  62. data/lib/site_template/css/main.css +165 -0
  63. data/lib/site_template/css/syntax.css +60 -0
  64. data/lib/site_template/index.html +13 -0
  65. data/monad.gemspec +197 -0
  66. data/script/bootstrap +2 -0
  67. data/test/fixtures/broken_front_matter1.erb +5 -0
  68. data/test/fixtures/broken_front_matter2.erb +4 -0
  69. data/test/fixtures/broken_front_matter3.erb +7 -0
  70. data/test/fixtures/exploit_front_matter.erb +4 -0
  71. data/test/fixtures/front_matter.erb +4 -0
  72. data/test/fixtures/members.yaml +7 -0
  73. data/test/helper.rb +62 -0
  74. data/test/source/.htaccess +8 -0
  75. data/test/source/_includes/sig.markdown +3 -0
  76. data/test/source/_layouts/default.html +27 -0
  77. data/test/source/_layouts/simple.html +1 -0
  78. data/test/source/_plugins/dummy.rb +8 -0
  79. data/test/source/_posts/2008-02-02-not-published.textile +8 -0
  80. data/test/source/_posts/2008-02-02-published.textile +8 -0
  81. data/test/source/_posts/2008-10-18-foo-bar.textile +8 -0
  82. data/test/source/_posts/2008-11-21-complex.textile +8 -0
  83. data/test/source/_posts/2008-12-03-permalinked-post.textile +9 -0
  84. data/test/source/_posts/2008-12-13-include.markdown +8 -0
  85. data/test/source/_posts/2009-01-27-array-categories.textile +10 -0
  86. data/test/source/_posts/2009-01-27-categories.textile +7 -0
  87. data/test/source/_posts/2009-01-27-category.textile +7 -0
  88. data/test/source/_posts/2009-01-27-empty-categories.textile +7 -0
  89. data/test/source/_posts/2009-01-27-empty-category.textile +7 -0
  90. data/test/source/_posts/2009-03-12-hash-#1.markdown +6 -0
  91. data/test/source/_posts/2009-05-18-empty-tag.textile +6 -0
  92. data/test/source/_posts/2009-05-18-empty-tags.textile +6 -0
  93. data/test/source/_posts/2009-05-18-tag.textile +6 -0
  94. data/test/source/_posts/2009-05-18-tags.textile +9 -0
  95. data/test/source/_posts/2009-06-22-empty-yaml.textile +3 -0
  96. data/test/source/_posts/2009-06-22-no-yaml.textile +1 -0
  97. data/test/source/_posts/2010-01-08-triple-dash.markdown +5 -0
  98. data/test/source/_posts/2010-01-09-date-override.textile +7 -0
  99. data/test/source/_posts/2010-01-09-time-override.textile +7 -0
  100. data/test/source/_posts/2010-01-09-timezone-override.textile +7 -0
  101. data/test/source/_posts/2010-01-16-override-data.textile +4 -0
  102. data/test/source/_posts/2011-04-12-md-extension.md +7 -0
  103. data/test/source/_posts/2011-04-12-text-extension.text +0 -0
  104. data/test/source/_posts/2013-01-02-post-excerpt.markdown +14 -0
  105. data/test/source/_posts/2013-01-12-nil-layout.textile +6 -0
  106. data/test/source/_posts/2013-01-12-no-layout.textile +5 -0
  107. data/test/source/_posts/2013-03-19-not-a-post.markdown/.gitkeep +0 -0
  108. data/test/source/_posts/2013-04-11-custom-excerpt.markdown +10 -0
  109. data/test/source/_posts/2013-05-10-number-category.textile +7 -0
  110. data/test/source/_posts/es/2008-11-21-nested.textile +8 -0
  111. data/test/source/about.html +6 -0
  112. data/test/source/category/_posts/2008-9-23-categories.textile +6 -0
  113. data/test/source/contacts.html +5 -0
  114. data/test/source/contacts/bar.html +5 -0
  115. data/test/source/contacts/index.html +5 -0
  116. data/test/source/css/screen.css +76 -0
  117. data/test/source/deal.with.dots.html +7 -0
  118. data/test/source/foo/_posts/bar/2008-12-12-topical-post.textile +8 -0
  119. data/test/source/index.html +22 -0
  120. data/test/source/sitemap.xml +32 -0
  121. data/test/source/symlink-test/symlinked-file +22 -0
  122. data/test/source/win/_posts/2009-05-24-yaml-linebreak.markdown +7 -0
  123. data/test/source/z_category/_posts/2008-9-23-categories.textile +6 -0
  124. data/test/suite.rb +11 -0
  125. data/test/test_command.rb +39 -0
  126. data/test/test_configuration.rb +137 -0
  127. data/test/test_convertible.rb +51 -0
  128. data/test/test_core_ext.rb +88 -0
  129. data/test/test_filters.rb +102 -0
  130. data/test/test_generated_site.rb +83 -0
  131. data/test/test_json_driver.rb +63 -0
  132. data/test/test_kramdown.rb +35 -0
  133. data/test/test_new_command.rb +104 -0
  134. data/test/test_page.rb +193 -0
  135. data/test/test_pager.rb +115 -0
  136. data/test/test_post.rb +573 -0
  137. data/test/test_rdiscount.rb +22 -0
  138. data/test/test_redcarpet.rb +61 -0
  139. data/test/test_redcloth.rb +86 -0
  140. data/test/test_site.rb +374 -0
  141. data/test/test_tags.rb +310 -0
  142. data/test/test_yaml_driver.rb +35 -0
  143. metadata +554 -0
@@ -0,0 +1,25 @@
1
+ require 'fileutils'
2
+ require 'rr'
3
+ require 'test/unit'
4
+
5
+ World do
6
+ include Test::Unit::Assertions
7
+ end
8
+
9
+ TEST_DIR = File.join('/', 'tmp', 'monad')
10
+ JEKYLL_PATH = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'monad')
11
+
12
+ def run_monad(opts = {})
13
+ command = JEKYLL_PATH.clone
14
+ command << " build"
15
+ command << " --drafts" if opts[:drafts]
16
+ command << " >> /dev/null 2>&1" if opts[:debug].nil?
17
+ system command
18
+ end
19
+
20
+ def has_time_component?(date_string)
21
+ date_string.split(" ").size > 1
22
+ end
23
+
24
+ # work around "invalid option: --format" cucumber bug (see #296)
25
+ Test::Unit.run = true if RUBY_VERSION < '1.9'
@@ -0,0 +1,90 @@
1
+ $:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
2
+
3
+ # Require all of the Ruby files in the given directory.
4
+ #
5
+ # path - The String relative path from here to the directory.
6
+ #
7
+ # Returns nothing.
8
+ def require_all(path)
9
+ glob = File.join(File.dirname(__FILE__), path, '*.rb')
10
+ Dir[glob].each do |f|
11
+ require f
12
+ end
13
+ end
14
+
15
+ # rubygems
16
+ require 'rubygems'
17
+
18
+ # stdlib
19
+ require 'fileutils'
20
+ require 'time'
21
+ require 'safe_yaml'
22
+ require 'English'
23
+
24
+ # 3rd party
25
+ require 'liquid'
26
+ require 'maruku'
27
+ require 'colorator'
28
+
29
+ # internal requires
30
+ require 'monad/core_ext'
31
+ require 'monad/logger'
32
+ require 'monad/deprecator'
33
+ require 'monad/configuration'
34
+ require 'monad/site'
35
+ require 'monad/convertible'
36
+ require 'monad/layout'
37
+ require 'monad/page'
38
+ require 'monad/post'
39
+ require 'monad/draft'
40
+ require 'monad/filters'
41
+ require 'monad/static_file'
42
+ require 'monad/errors'
43
+
44
+ # extensions
45
+ require 'monad/plugin'
46
+ require 'monad/converter'
47
+ require 'monad/generator'
48
+ require 'monad/command'
49
+
50
+ require_all 'monad/commands'
51
+ require_all 'monad/converters'
52
+ require_all 'monad/converters/markdown'
53
+ require_all 'monad/generators'
54
+ require_all 'monad/tags'
55
+ require_all 'monad/drivers'
56
+
57
+ SafeYAML::OPTIONS[:suppress_warnings] = true
58
+
59
+ module Monad
60
+ VERSION = '0.0.1'
61
+
62
+ # Public: Generate a Monad configuration Hash by merging the default
63
+ # options with anything in _config.yml, and adding the given options on top.
64
+ #
65
+ # override - A Hash of config directives that override any options in both
66
+ # the defaults and the config file. See Monad::Configuration::DEFAULTS for a
67
+ # list of option names and their defaults.
68
+ #
69
+ # Returns the final configuration Hash.
70
+ def self.configuration(override)
71
+ config = Configuration[Configuration::DEFAULTS]
72
+ override = Configuration[override].stringify_keys
73
+ config = config.read_config_files(config.config_files(override))
74
+
75
+ # Merge DEFAULTS < _config.yml < override
76
+ config = config.deep_merge(override).stringify_keys
77
+ set_timezone(config['timezone']) if config['timezone']
78
+
79
+ config
80
+ end
81
+
82
+ # Static: Set the TZ environment variable to use the timezone specified
83
+ #
84
+ # timezone - the IANA Time Zone
85
+ #
86
+ # Returns nothing
87
+ def self.set_timezone(timezone)
88
+ ENV['TZ'] = timezone
89
+ end
90
+ end
@@ -0,0 +1,27 @@
1
+ module Monad
2
+ class Command
3
+ def self.globs(source, destination)
4
+ Dir.chdir(source) do
5
+ dirs = Dir['*'].select { |x| File.directory?(x) }
6
+ dirs -= [destination, File.expand_path(destination), File.basename(destination)]
7
+ dirs = dirs.map { |x| "#{x}/**/*" }
8
+ dirs += ['*']
9
+ end
10
+ end
11
+
12
+ # Static: Run Site#process and catch errors
13
+ #
14
+ # site - the Monad::Site object
15
+ #
16
+ # Returns nothing
17
+ def self.process_site(site)
18
+ site.process
19
+ rescue Monad::FatalException => e
20
+ puts
21
+ Monad::Logger.error "ERROR:", "YOUR SITE COULD NOT BE BUILT:"
22
+ Monad::Logger.error "", "------------------------------------"
23
+ Monad::Logger.error "", e.message
24
+ exit(1)
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,64 @@
1
+ module Monad
2
+ module Commands
3
+ class Build < Command
4
+ def self.process(options)
5
+ site = Monad::Site.new(options)
6
+
7
+ self.build(site, options)
8
+ self.watch(site, options) if options['watch']
9
+ end
10
+
11
+ # Private: Build the site from source into destination.
12
+ #
13
+ # site - A Monad::Site instance
14
+ # options - A Hash of options passed to the command
15
+ #
16
+ # Returns nothing.
17
+ def self.build(site, options)
18
+ source = options['source']
19
+ destination = options['destination']
20
+ Monad::Logger.info "Source:", source
21
+ Monad::Logger.info "Destination:", destination
22
+ print Monad::Logger.formatted_topic "Generating..."
23
+ self.process_site(site)
24
+ puts "done."
25
+ end
26
+
27
+ # Private: Watch for file changes and rebuild the site.
28
+ #
29
+ # site - A Monad::Site instance
30
+ # options - A Hash of options passed to the command
31
+ #
32
+ # Returns nothing.
33
+ def self.watch(site, options)
34
+ require 'directory_watcher'
35
+
36
+ source = options['source']
37
+ destination = options['destination']
38
+
39
+ Monad::Logger.info "Auto-regeneration:", "enabled"
40
+
41
+ dw = DirectoryWatcher.new(source, :glob => self.globs(source, destination), :pre_load => true)
42
+ dw.interval = 1
43
+
44
+ dw.add_observer do |*args|
45
+ t = Time.now.strftime("%Y-%m-%d %H:%M:%S")
46
+ print Monad::Logger.formatted_topic("Regenerating:") + "#{args.size} files at #{t} "
47
+ self.process_site(site)
48
+ puts "...done."
49
+ end
50
+
51
+ dw.start
52
+
53
+ unless options['serving']
54
+ trap("INT") do
55
+ puts " Halting auto-regeneration."
56
+ exit 0
57
+ end
58
+
59
+ loop { sleep 1000 }
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,29 @@
1
+ module Monad
2
+ module Commands
3
+ class Doctor < Command
4
+ class << self
5
+ def process(options)
6
+ site = Monad::Site.new(options)
7
+ site.read
8
+
9
+ unless deprecated_relative_permalinks(site)
10
+ Monad::Logger.info "Your test results", "are in. Everything looks fine."
11
+ end
12
+ end
13
+
14
+ def deprecated_relative_permalinks(site)
15
+ contains_deprecated_pages = false
16
+ site.pages.each do |page|
17
+ if page.uses_relative_permalinks
18
+ Monad::Logger.warn "Deprecation:", "'#{page.path}' uses relative" +
19
+ " permalinks which will be deprecated in" +
20
+ " Monad v1.1 and beyond."
21
+ contains_deprecated_pages = true
22
+ end
23
+ end
24
+ contains_deprecated_pages
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,50 @@
1
+ require 'erb'
2
+
3
+ module Monad
4
+ module Commands
5
+ class New < Command
6
+ def self.process(args)
7
+ raise ArgumentError.new('You must specify a path.') if args.empty?
8
+
9
+ new_blog_path = File.expand_path(args.join(" "), Dir.pwd)
10
+ FileUtils.mkdir_p new_blog_path
11
+ unless Dir["#{new_blog_path}/**/*"].empty?
12
+ Monad::Logger.error "Conflict:", "#{new_blog_path} exists and is not empty."
13
+ exit(1)
14
+ end
15
+
16
+ create_sample_files new_blog_path
17
+
18
+ File.open(File.expand_path(self.initialized_post_name, new_blog_path), "w") do |f|
19
+ f.write(self.scaffold_post_content(site_template))
20
+ end
21
+ puts "New monad site installed in #{new_blog_path}."
22
+ end
23
+
24
+ def self.scaffold_post_content(template_site)
25
+ ERB.new(File.read(File.expand_path(scaffold_path, site_template))).result
26
+ end
27
+
28
+ # Internal: Gets the filename of the sample post to be created
29
+ #
30
+ # Returns the filename of the sample post, as a String
31
+ def self.initialized_post_name
32
+ "_posts/#{Time.now.strftime('%Y-%m-%d')}-welcome-to-monad.markdown"
33
+ end
34
+
35
+ private
36
+ def self.create_sample_files(path)
37
+ FileUtils.cp_r site_template + '/.', path
38
+ FileUtils.rm File.expand_path(scaffold_path, path)
39
+ end
40
+
41
+ def self.site_template
42
+ File.expand_path("../../site_template", File.dirname(__FILE__))
43
+ end
44
+
45
+ def self.scaffold_path
46
+ "_posts/0000-00-00-welcome-to-monad.markdown.erb"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,33 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Monad
3
+ module Commands
4
+ class Serve < Command
5
+ def self.process(options)
6
+ require 'webrick'
7
+ include WEBrick
8
+
9
+ destination = options['destination']
10
+
11
+ FileUtils.mkdir_p(destination)
12
+
13
+ mime_types_file = File.expand_path('../mime.types', File.dirname(__FILE__))
14
+ mime_types = WEBrick::HTTPUtils::load_mime_types(mime_types_file)
15
+
16
+ # recreate NondisclosureName under utf-8 circumstance
17
+ fh_option = WEBrick::Config::FileHandler
18
+ fh_option[:NondisclosureName] = ['.ht*','~*']
19
+
20
+ s = HTTPServer.new(
21
+ :Port => options['port'],
22
+ :BindAddress => options['host'],
23
+ :MimeTypes => mime_types
24
+ )
25
+
26
+ s.mount(options['baseurl'], HTTPServlet::FileHandler, destination, fh_option)
27
+ t = Thread.new { s.start }
28
+ trap("INT") { s.shutdown }
29
+ t.join()
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,183 @@
1
+ # encoding: UTF-8
2
+
3
+ module Monad
4
+ class Configuration < Hash
5
+
6
+ # Default options. Overridden by values in _config.yml.
7
+ # Strings rather than symbols are used for compatibility with YAML.
8
+ DEFAULTS = {
9
+ 'source' => Dir.pwd,
10
+ 'destination' => File.join(Dir.pwd, '_site'),
11
+ 'plugins' => '_plugins',
12
+ 'layouts' => '_layouts',
13
+ 'keep_files' => ['.git','.svn'],
14
+
15
+ 'timezone' => nil, # use the local timezone
16
+
17
+ 'safe' => false,
18
+ 'show_drafts' => nil,
19
+ 'limit_posts' => 0,
20
+ 'lsi' => false,
21
+ 'future' => true, # remove and make true just default
22
+ 'pygments' => true,
23
+
24
+ 'relative_permalinks' => true, # backwards-compatibility with < 1.0
25
+ # will be set to false once 1.1 hits
26
+
27
+ 'markdown' => 'maruku',
28
+ 'permalink' => 'date',
29
+ 'baseurl' => '/',
30
+ 'include' => ['.htaccess'],
31
+ 'exclude' => [],
32
+ 'paginate_path' => 'page:num',
33
+
34
+ 'markdown_ext' => 'markdown,mkd,mkdn,md',
35
+ 'textile_ext' => 'textile',
36
+
37
+ 'port' => '4000',
38
+ 'host' => '0.0.0.0',
39
+
40
+ 'excerpt_separator' => "\n\n",
41
+
42
+ 'maruku' => {
43
+ 'use_tex' => false,
44
+ 'use_divs' => false,
45
+ 'png_engine' => 'blahtex',
46
+ 'png_dir' => 'images/latex',
47
+ 'png_url' => '/images/latex'
48
+ },
49
+
50
+ 'rdiscount' => {
51
+ 'extensions' => []
52
+ },
53
+
54
+ 'redcarpet' => {
55
+ 'extensions' => []
56
+ },
57
+
58
+ 'kramdown' => {
59
+ 'auto_ids' => true,
60
+ 'footnote_nr' => 1,
61
+ 'entity_output' => 'as_char',
62
+ 'toc_levels' => '1..6',
63
+ 'smart_quotes' => 'lsquo,rsquo,ldquo,rdquo',
64
+ 'use_coderay' => false,
65
+
66
+ 'coderay' => {
67
+ 'coderay_wrap' => 'div',
68
+ 'coderay_line_numbers' => 'inline',
69
+ 'coderay_line_number_start' => 1,
70
+ 'coderay_tab_width' => 4,
71
+ 'coderay_bold_every' => 10,
72
+ 'coderay_css' => 'style'
73
+ }
74
+ },
75
+
76
+ 'redcloth' => {
77
+ 'hard_breaks' => true
78
+ }
79
+ }
80
+
81
+ # Public: Turn all keys into string
82
+ #
83
+ # Return a copy of the hash where all its keys are strings
84
+ def stringify_keys
85
+ reduce({}) { |hsh,(k,v)| hsh.merge(k.to_s => v) }
86
+ end
87
+
88
+ # Public: Directory of the Monad source folder
89
+ #
90
+ # override - the command-line options hash
91
+ #
92
+ # Returns the path to the Monad source directory
93
+ def source(override)
94
+ override['source'] || self['source'] || DEFAULTS['source']
95
+ end
96
+
97
+ # Public: Generate list of configuration files from the override
98
+ #
99
+ # override - the command-line options hash
100
+ #
101
+ # Returns an Array of config files
102
+ def config_files(override)
103
+ # Get configuration from <source>/_config.yml or <source>/<config_file>
104
+ config_files = override.delete('config')
105
+ config_files = File.join(source(override), "_config.yml") if config_files.to_s.empty?
106
+ config_files = [config_files] unless config_files.is_a? Array
107
+ config_files
108
+ end
109
+
110
+ # Public: Read configuration and return merged Hash
111
+ #
112
+ # file - the path to the YAML file to be read in
113
+ #
114
+ # Returns this configuration, overridden by the values in the file
115
+ def read_config_file(file)
116
+ next_config = YAML.safe_load_file(file)
117
+ raise "Configuration file: (INVALID) #{file}".yellow if !next_config.is_a?(Hash)
118
+ Monad::Logger.info "Configuration file:", file
119
+ next_config
120
+ end
121
+
122
+ # Public: Read in a list of configuration files and merge with this hash
123
+ #
124
+ # files - the list of configuration file paths
125
+ #
126
+ # Returns the full configuration, with the defaults overridden by the values in the
127
+ # configuration files
128
+ def read_config_files(files)
129
+ configuration = clone
130
+
131
+ begin
132
+ files.each do |config_file|
133
+ new_config = read_config_file(config_file)
134
+ configuration = configuration.deep_merge(new_config)
135
+ end
136
+ rescue SystemCallError
137
+ # Errno:ENOENT = file not found
138
+ Monad::Logger.warn "Configuration file:", "none"
139
+ rescue => err
140
+ Monad::Logger.warn "WARNING:", "Error reading configuration. " +
141
+ "Using defaults (and options)."
142
+ $stderr.puts "#{err}"
143
+ end
144
+
145
+ configuration.backwards_compatibilize
146
+ end
147
+
148
+ # Public: Ensure the proper options are set in the configuration to allow for
149
+ # backwards-compatibility with Monad pre-1.0
150
+ #
151
+ # Returns the backwards-compatible configuration
152
+ def backwards_compatibilize
153
+ config = clone
154
+ # Provide backwards-compatibility
155
+ if config.has_key?('auto') || config.has_key?('watch')
156
+ Monad::Logger.warn "Deprecation:", "Auto-regeneration can no longer" +
157
+ " be set from your configuration file(s). Use the"+
158
+ " --watch/-w command-line option instead."
159
+ config.delete('auto')
160
+ config.delete('watch')
161
+ end
162
+
163
+ if config.has_key? 'server'
164
+ Monad::Logger.warn "Deprecation:", "The 'server' configuration option" +
165
+ " is no longer accepted. Use the 'monad serve'" +
166
+ " subcommand to serve your site with WEBrick."
167
+ config.delete('server')
168
+ end
169
+
170
+ if config.has_key? 'server_port'
171
+ Monad::Logger.warn "Deprecation:", "The 'server_port' configuration option" +
172
+ " has been renamed to 'port'. Please update your config" +
173
+ " file accordingly."
174
+ # copy but don't overwrite:
175
+ config['port'] = config['server_port'] unless config.has_key?('port')
176
+ config.delete('server_port')
177
+ end
178
+
179
+ config
180
+ end
181
+
182
+ end
183
+ end