vanilla 1.0.2 → 1.2

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 (105) hide show
  1. data/Rakefile +112 -109
  2. data/bin/vanilla +35 -6
  3. data/lib/vanilla.rb +10 -14
  4. data/lib/vanilla/app.rb +109 -41
  5. data/lib/vanilla/console.rb +22 -2
  6. data/lib/vanilla/dynasnip.rb +4 -36
  7. data/lib/vanilla/renderers.rb +12 -0
  8. data/lib/vanilla/renderers/base.rb +58 -34
  9. data/lib/vanilla/renderers/bold.rb +0 -2
  10. data/lib/vanilla/renderers/erb.rb +1 -3
  11. data/lib/vanilla/renderers/haml.rb +13 -0
  12. data/lib/vanilla/renderers/markdown.rb +0 -2
  13. data/lib/vanilla/renderers/raw.rb +0 -2
  14. data/lib/vanilla/renderers/ruby.rb +12 -6
  15. data/lib/vanilla/renderers/textile.rb +0 -2
  16. data/lib/vanilla/request.rb +19 -17
  17. data/lib/vanilla/routes.rb +9 -20
  18. data/lib/vanilla/snip_reference_parser.rb +94 -0
  19. data/lib/vanilla/static.rb +28 -0
  20. data/pristine_app/Gemfile +3 -0
  21. data/pristine_app/Gemfile.lock +32 -0
  22. data/pristine_app/README +47 -0
  23. data/pristine_app/config.ru +26 -0
  24. data/pristine_app/public/vanilla.css +15 -0
  25. data/pristine_app/soups/base/layout.snip +18 -0
  26. data/pristine_app/soups/base/start.snip +19 -0
  27. data/pristine_app/soups/dynasnips/current_snip.rb +29 -0
  28. data/{lib/vanilla → pristine_app/soups}/dynasnips/debug.rb +5 -3
  29. data/pristine_app/soups/dynasnips/index.rb +12 -0
  30. data/{lib/vanilla → pristine_app/soups}/dynasnips/link_to.rb +4 -2
  31. data/pristine_app/soups/dynasnips/link_to_current_snip.rb +14 -0
  32. data/pristine_app/soups/dynasnips/page_title.rb +9 -0
  33. data/{lib/vanilla → pristine_app/soups}/dynasnips/pre.rb +7 -5
  34. data/{lib/vanilla → pristine_app/soups}/dynasnips/raw.rb +8 -5
  35. data/pristine_app/soups/extras/comments.rb +78 -0
  36. data/{lib/vanilla/dynasnips → pristine_app/soups/extras}/kind.rb +19 -17
  37. data/{lib/vanilla/dynasnips → pristine_app/soups/extras}/rand.rb +2 -0
  38. data/pristine_app/soups/extras/url_to.rb +7 -0
  39. data/pristine_app/soups/tutorial/bad_dynasnip.snip +8 -0
  40. data/pristine_app/soups/tutorial/hello_world.snip +20 -0
  41. data/pristine_app/soups/tutorial/markdown_example.snip +13 -0
  42. data/pristine_app/soups/tutorial/snip.snip +9 -0
  43. data/pristine_app/soups/tutorial/soup.snip +3 -0
  44. data/pristine_app/soups/tutorial/test.snip +30 -0
  45. data/pristine_app/soups/tutorial/textile_example.snip +11 -0
  46. data/pristine_app/soups/tutorial/tutorial-another-snip.snip +1 -0
  47. data/pristine_app/soups/tutorial/tutorial-basic-snip-inclusion.snip +1 -0
  48. data/pristine_app/soups/tutorial/tutorial-dynasnips.snip.markdown +56 -0
  49. data/pristine_app/soups/tutorial/tutorial-layout.snip +56 -0
  50. data/pristine_app/soups/tutorial/tutorial-links.snip +4 -0
  51. data/pristine_app/soups/tutorial/tutorial-renderers.snip.markdown +77 -0
  52. data/pristine_app/soups/tutorial/tutorial.snip.markdown +69 -0
  53. data/pristine_app/soups/tutorial/vanilla-rb.snip +16 -0
  54. data/pristine_app/soups/tutorial/vanilla.snip +8 -0
  55. data/test/dynasnip_test.rb +42 -0
  56. data/test/dynasnips/link_to_current_snip_test.rb +19 -0
  57. data/test/dynasnips/link_to_test.rb +27 -0
  58. data/test/dynasnips/page_title_test.rb +19 -0
  59. data/test/renderers/base_renderer_test.rb +43 -0
  60. data/test/renderers/erb_renderer_test.rb +29 -0
  61. data/test/renderers/haml_renderer_test.rb +35 -0
  62. data/test/renderers/markdown_renderer_test.rb +31 -0
  63. data/test/renderers/raw_renderer_test.rb +23 -0
  64. data/test/renderers/ruby_renderer_test.rb +59 -0
  65. data/test/snip_inclusion_test.rb +56 -0
  66. data/test/snip_reference_parser_test.rb +123 -0
  67. data/test/test_helper.rb +75 -0
  68. data/test/vanilla_app_test.rb +83 -0
  69. data/test/vanilla_presenting_test.rb +125 -0
  70. data/test/vanilla_request_test.rb +87 -0
  71. metadata +179 -78
  72. data/config.example.yml +0 -5
  73. data/config.ru +0 -9
  74. data/lib/defensio.rb +0 -59
  75. data/lib/tasks/vanilla.rake +0 -177
  76. data/lib/vanilla/dynasnips/comments.rb +0 -108
  77. data/lib/vanilla/dynasnips/current_snip.rb +0 -32
  78. data/lib/vanilla/dynasnips/edit.rb +0 -63
  79. data/lib/vanilla/dynasnips/edit_link.rb +0 -24
  80. data/lib/vanilla/dynasnips/index.rb +0 -11
  81. data/lib/vanilla/dynasnips/link_to_current_snip.rb +0 -16
  82. data/lib/vanilla/dynasnips/login.rb +0 -56
  83. data/lib/vanilla/dynasnips/new.rb +0 -14
  84. data/lib/vanilla/dynasnips/notes.rb +0 -42
  85. data/lib/vanilla/dynasnips/url_to.rb +0 -7
  86. data/lib/vanilla/snip_handling.rb +0 -33
  87. data/lib/vanilla/snips/start.rb +0 -27
  88. data/lib/vanilla/snips/system.rb +0 -76
  89. data/lib/vanilla/snips/tutorial.rb +0 -157
  90. data/lib/vanilla/test_snips.rb +0 -85
  91. data/public/hatch.png +0 -0
  92. data/public/javascripts/jquery.js +0 -3549
  93. data/public/javascripts/vanilla.js +0 -21
  94. data/spec/dynasnip_spec.rb +0 -31
  95. data/spec/renderers/base_renderer_spec.rb +0 -40
  96. data/spec/renderers/erb_renderer_spec.rb +0 -27
  97. data/spec/renderers/markdown_renderer_spec.rb +0 -29
  98. data/spec/renderers/raw_renderer_spec.rb +0 -21
  99. data/spec/renderers/ruby_renderer_spec.rb +0 -42
  100. data/spec/renderers/vanilla_app_detecting_renderer_spec.rb +0 -35
  101. data/spec/spec_helper.rb +0 -64
  102. data/spec/vanilla_app_spec.rb +0 -38
  103. data/spec/vanilla_presenting_spec.rb +0 -84
  104. data/spec/vanilla_request_spec.rb +0 -73
  105. data/spec/vanilla_snip_finding_spec.rb +0 -28
data/Rakefile CHANGED
@@ -1,122 +1,125 @@
1
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), 'lib')
2
- require 'vanilla'
3
- load File.join(File.dirname(__FILE__), *%w[lib tasks vanilla.rake])
4
-
5
- require 'spec'
6
- require 'spec/rake/spectask'
7
- Spec::Rake::SpecTask.new do |t|
8
- t.spec_opts = %w(--format specdoc --colour)
9
- t.libs = ["spec"]
10
- end
11
-
12
- task :default => :spec
13
-
14
-
15
1
  require "rubygems"
16
2
  require "rake/gempackagetask"
17
3
  require "rake/rdoctask"
18
4
 
19
- # This builds the actual gem. For details of what all these options
20
- # mean, and other ones you can add, check the documentation here:
21
- #
22
- # http://rubygems.org/read/chapter/20
23
- #
24
- spec = Gem::Specification.new do |s|
25
-
26
- # Change these as appropriate
27
- s.name = "vanilla"
28
- s.version = "1.0.2"
29
- s.summary = "A bliki-type web content thing."
30
- s.author = "James Adam"
31
- s.email = "james@lazyatom.com.com"
32
- s.homepage = "http://github.com/lazyatom/vanilla-rb"
33
-
34
- s.has_rdoc = true
35
- s.extra_rdoc_files = %w(README)
36
- s.rdoc_options = %w(--main README)
37
-
38
- # Add any extra files to include in the gem
39
- s.files = %w(config.example.yml config.ru Rakefile README) + Dir.glob("{spec,lib,bin,public}/**/*")
40
- s.executables = ['vanilla']
41
- s.require_paths = ["lib"]
42
-
43
- # All the other gems we need.
44
- s.add_dependency("rack", ">= 0.9.1")
45
- s.add_dependency("soup", ">= 0.2.1")
46
- s.add_dependency("ratom", ">= 0.3.5")
47
- s.add_dependency("RedCloth", ">= 4.1.1")
48
- s.add_dependency("BlueCloth", ">= 1.0.0")
49
-
50
- s.add_development_dependency("rspec") # add any other gems for testing/development
51
-
52
- # If you want to publish automatically to rubyforge, you'll may need
53
- # to tweak this, and the publishing task below too.
54
- s.rubyforge_project = "vanilla"
55
- end
5
+ require "bundler/setup"
6
+ require "vanilla"
56
7
 
57
- # This task actually builds the gem. We also regenerate a static
58
- # .gemspec file, which is useful if something (i.e. GitHub) will
59
- # be automatically building a gem for this project. If you're not
60
- # using GitHub, edit as appropriate.
61
- Rake::GemPackageTask.new(spec) do |pkg|
62
- pkg.gem_spec = spec
63
-
64
- # Generate the gemspec file for github.
65
- file = File.dirname(__FILE__) + "/#{spec.name}.gemspec"
66
- File.open(file, "w") {|f| f << spec.to_ruby }
67
- end
8
+ task :default => :test
68
9
 
69
- # Generate documentation
70
- Rake::RDocTask.new do |rd|
71
- rd.main = "README"
72
- rd.rdoc_files.include("README", "lib/**/*.rb")
73
- rd.rdoc_dir = "rdoc"
10
+ require "rake/testtask"
11
+ Rake::TestTask.new do |t|
12
+ t.libs << "test"
13
+ t.ruby_opts << "-rubygems"
14
+ t.test_files = FileList["test/**/*_test.rb"]
15
+ t.verbose = true
74
16
  end
75
17
 
76
- desc 'Clear out RDoc and generated packages'
77
- task :clean => [:clobber_rdoc, :clobber_package] do
78
- rm "#{spec.name}.gemspec"
79
- end
18
+ if Object.const_defined?(:Gem)
19
+ # This builds the actual gem. For details of what all these options
20
+ # mean, and other ones you can add, check the documentation here:
21
+ #
22
+ # http://rubygems.org/read/chapter/20
23
+ #
24
+ spec = Gem::Specification.new do |s|
80
25
 
81
- # If you want to publish to RubyForge automatically, here's a simple
82
- # task to help do that. If you don't, just get rid of this.
83
- # Be sure to set up your Rubyforge account details with the Rubyforge
84
- # gem; you'll need to run `rubyforge setup` and `rubyforge config` at
85
- # the very least.
86
- begin
87
- require "rake/contrib/sshpublisher"
88
- namespace :rubyforge do
89
-
90
- desc "Release gem and RDoc documentation to RubyForge"
91
- task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
92
-
93
- namespace :release do
94
- desc "Release a new version of this gem"
95
- task :gem => [:package] do
96
- require 'rubyforge'
97
- rubyforge = RubyForge.new
98
- rubyforge.configure
99
- rubyforge.login
100
- rubyforge.userconfig['release_notes'] = spec.summary
101
- path_to_gem = File.join(File.dirname(__FILE__), "pkg", "#{spec.name}-#{spec.version}.gem")
102
- puts "Publishing #{spec.name}-#{spec.version.to_s} to Rubyforge..."
103
- rubyforge.add_release(spec.rubyforge_project, spec.name, spec.version.to_s, path_to_gem)
104
- end
105
-
106
- desc "Publish RDoc to RubyForge."
107
- task :docs => [:rdoc] do
108
- config = YAML.load(
109
- File.read(File.expand_path('~/.rubyforge/user-config.yml'))
110
- )
111
-
112
- host = "#{config['username']}@rubyforge.org"
113
- remote_dir = "/var/www/gforge-projects/vanilla-rb/" # Should be the same as the rubyforge project name
114
- local_dir = 'rdoc'
115
-
116
- Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
26
+ # Change these as appropriate
27
+ s.name = "vanilla"
28
+ s.version = Vanilla::VERSION
29
+ s.summary = "A bliki-type web content thing."
30
+ s.author = "James Adam"
31
+ s.email = "james@lazyatom.com.com"
32
+ s.homepage = "http://github.com/lazyatom/vanilla-rb"
33
+
34
+ s.has_rdoc = true
35
+ s.extra_rdoc_files = %w(README)
36
+ s.rdoc_options = %w(--main README)
37
+
38
+ # Add any extra files to include in the gem
39
+ s.files = %w(Rakefile README) + Dir.glob("{test,lib,bin,pristine_app}/**/*")
40
+ s.executables = ['vanilla']
41
+ s.require_paths = ["lib"]
42
+
43
+ # All the other gems we need.
44
+ s.add_dependency("rack", ">= 0.9.1")
45
+ s.add_dependency("soup", ">= 1.0.6")
46
+ s.add_dependency("ratom", ">= 0.3.5")
47
+ s.add_dependency("RedCloth", ">= 4.1.1")
48
+ s.add_dependency("BlueCloth", ">= 1.0.0")
49
+ s.add_dependency("haml")
50
+ s.add_dependency("parslet", ">= 1.2.0")
51
+
52
+ s.add_development_dependency("kintama", ">= 0.1.6") # add any other gems for testing/development
53
+ s.add_development_dependency("mocha")
54
+
55
+ # If you want to publish automatically to rubyforge, you'll may need
56
+ # to tweak this, and the publishing task below too.
57
+ s.rubyforge_project = "vanilla"
58
+ end
59
+
60
+ # This task actually builds the gem. We also regenerate a static
61
+ # .gemspec file, which is useful if something (i.e. GitHub) will
62
+ # be automatically building a gem for this project. If you're not
63
+ # using GitHub, edit as appropriate.
64
+ #
65
+ # To publish your gem online, install the 'gemcutter' gem; Read more
66
+ # about that here: http://gemcutter.org/pages/gem_docs
67
+ Rake::GemPackageTask.new(spec) do |pkg|
68
+ pkg.gem_spec = spec
69
+ end
70
+
71
+ # Stolen from jeweler
72
+ def prettyify_array(gemspec_ruby, array_name)
73
+ gemspec_ruby.gsub(/s\.#{array_name.to_s} = \[.+?\]/) do |match|
74
+ leadin, files = match[0..-2].split("[")
75
+ leadin + "[\n #{files.split(",").join(",\n ")}\n ]"
76
+ end
77
+ end
78
+
79
+ task :gemspec do
80
+ output = spec.to_ruby
81
+ output = prettyify_array(output, :files)
82
+ output = prettyify_array(output, :test_files)
83
+ output = prettyify_array(output, :extra_rdoc_files)
84
+
85
+ file = File.expand_path("../#{spec.name}.gemspec", __FILE__)
86
+ File.open(file, "w") {|f| f << output }
87
+ end
88
+
89
+ task :package => :gemspec
90
+
91
+ # Generate documentation
92
+ Rake::RDocTask.new do |rd|
93
+ rd.main = "README"
94
+ rd.rdoc_files.include("README", "lib/**/*.rb")
95
+ rd.rdoc_dir = "rdoc"
96
+ end
97
+
98
+ desc 'Clear out RDoc and generated packages'
99
+ task :clean => [:clobber_rdoc, :clobber_package] do
100
+ rm "#{spec.name}.gemspec"
101
+ end
102
+
103
+ desc 'Tag the repository in git with gem version number'
104
+ task :tag => [:gemspec, :package] do
105
+ if `git diff --cached`.empty?
106
+ if `git tag`.split("\n").include?("v#{spec.version}")
107
+ raise "Version #{spec.version} has already been released"
117
108
  end
109
+ `git add #{File.expand_path("../#{spec.name}.gemspec", __FILE__)}`
110
+ `git commit -m "Released version #{spec.version}"`
111
+ `git tag v#{spec.version}`
112
+ `git push --tags`
113
+ `git push`
114
+ else
115
+ raise "Unstaged changes still waiting to be committed"
118
116
  end
119
117
  end
120
- rescue LoadError
121
- puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
118
+
119
+ desc "Tag and publish the gem to rubygems.org"
120
+ task :publish => :tag do
121
+ `gem push pkg/#{spec.name}-#{spec.version}.gem`
122
+ end
123
+ else
124
+ puts "Gem management tasks unavailable, as rubygems was not fully loaded."
122
125
  end
@@ -1,9 +1,38 @@
1
1
  #!/usr/bin/env ruby
2
- require 'rubygems'
3
- require 'rake'
4
- load File.join(File.dirname(__FILE__), *%w[.. lib tasks vanilla.rake])
5
2
 
6
- mkdir(ARGV[0])
7
- cd(ARGV[0])
3
+ def create(new_app_dir)
4
+ require 'fileutils'
5
+ pristine_app = File.expand_path("../../pristine_app", __FILE__)
6
+ FileUtils.cp_r(pristine_app, new_app_dir)
7
+ FileUtils.mkdir_p(File.join(new_app_dir, "tmp"))
8
+ require 'vanilla'
9
+ File.open(File.join(new_app_dir, "Gemfile"), "w") do |f|
10
+ f.write "source :rubygems\n\n# Vanilla itself.\ngem 'vanilla', '#{Vanilla::VERSION}'"
11
+ end
12
+ puts File.readlines(File.join(new_app_dir, "README"))[0..16].join
13
+ end
8
14
 
9
- Rake::Task['vanilla:setup'].invoke
15
+ def console
16
+ $LOAD_PATH << "lib"
17
+ require "rubygems"
18
+ require "bundler/setup"
19
+ require "irb"
20
+ require "vanilla/console"
21
+ ARGV.clear
22
+ puts "The Soup is simmering."
23
+ IRB.start
24
+ end
25
+
26
+ def upgrade
27
+ # TODO
28
+ puts "TODO, but should be easier thanks to multi-space soup."
29
+ end
30
+
31
+ case ARGV[0]
32
+ when "console"
33
+ console
34
+ when "upgrade"
35
+ upgrade
36
+ else
37
+ create(ARGV[0])
38
+ end
@@ -1,20 +1,16 @@
1
- require 'rubygems'
2
-
3
- gem 'soup', '>= 0.1.4'
4
- require 'soup'
5
- require 'vanilla/snip_handling'
6
-
7
1
  module Vanilla
8
- include SnipHandling
9
- end
2
+ VERSION = "1.2"
10
3
 
11
- # Load all the other renderer subclasses
12
- Dir[File.join(File.dirname(__FILE__), 'vanilla', 'renderers', '*.rb')].each { |f| require f }
13
-
14
- # Load the routing information
15
- require 'vanilla/routes'
4
+ autoload :Renderers, "vanilla/renderers"
5
+ autoload :App, "vanilla/app"
6
+ autoload :Dynasnip, "vanilla/dynasnip"
7
+ autoload :Request, "vanilla/request"
8
+ autoload :Routes, "vanilla/routes"
9
+ autoload :Static, "vanilla/static"
10
+ autoload :SnipReferenceParser, "vanilla/snip_reference_parser"
11
+ end
16
12
 
17
13
  # Load all the base dynasnip classes
18
14
  Dir[File.join(File.dirname(__FILE__), 'vanilla', 'dynasnips', '*.rb')].each do |dynasnip|
19
15
  require dynasnip
20
- end
16
+ end
@@ -1,28 +1,45 @@
1
- require 'vanilla'
2
- require 'vanilla/request'
1
+ require 'soup'
3
2
 
4
3
  module Vanilla
5
4
  class App
6
-
7
- attr_reader :request, :response, :config
8
-
9
- def initialize(config_file=nil)
10
- prepare_configuration(config_file)
11
- Soup.prepare
5
+ include Vanilla::Routes
6
+
7
+ attr_reader :request, :response, :config, :soup
8
+
9
+ # Create a new Vanilla application
10
+ # Configuration options:
11
+ #
12
+ # :soup - provide the path to the soup data
13
+ # :soups - provide an array of paths to soup data
14
+ # :renderers - a hash of names to classes
15
+ # :default_renderer - the class to use when no renderer is provided;
16
+ # defaults to 'Vanilla::Renderers::Base'
17
+ # :default_layout_snip - the snip to use as a layout when rendering to HTML;
18
+ # defaults to 'layout'
19
+ # :root_snip - the snip to load for the root ('/') url;
20
+ # defaults to 'start'
21
+ def initialize(config={})
22
+ @config = config
23
+ if @config[:soup].nil? && @config[:soups].nil?
24
+ @config.merge!(:soup => File.expand_path("soup"))
25
+ end
26
+ @soup = prepare_soup(config)
27
+ prepare_renderers(config[:renderers])
12
28
  end
13
-
29
+
14
30
  # Returns a Rack-appropriate 3-element array (via Rack::Response#finish)
15
31
  def call(env)
16
- @request = Vanilla::Request.new(env)
32
+ env['vanilla.app'] = self
33
+ @request = Vanilla::Request.new(env, self)
17
34
  @response = Rack::Response.new
18
35
 
19
36
  begin
20
37
  output = formatted_render(request.snip, request.part, request.format)
21
38
  rescue => e
22
39
  @response.status = 500
23
- output = e.to_s
40
+ output = e.to_s + e.backtrace.join("\n")
24
41
  end
25
- response_format = request.format
42
+ response_format = request.format
26
43
  response_format = 'plain' if response_format == 'raw'
27
44
  @response['Content-Type'] = "text/#{response_format}"
28
45
  @response.write(output)
@@ -32,11 +49,16 @@ module Vanilla
32
49
  def formatted_render(snip, part=nil, format=nil)
33
50
  case format
34
51
  when 'html', nil
35
- Renderers::Erb.new(self).render(Vanilla.snip('system'), :main_template)
52
+ layout = layout_for(snip)
53
+ if layout == snip
54
+ "Rendering of the current layout would result in infinite recursion."
55
+ else
56
+ render(layout)
57
+ end
36
58
  when 'raw', 'css', 'js'
37
- Renderers::Raw.new(self).render(snip, part || :content)
59
+ Renderers::Raw.new(self).render(snip, part)
38
60
  when 'text', 'atom', 'xml'
39
- render(snip, part || :content)
61
+ render(snip, part)
40
62
  else
41
63
  raise "Unknown format '#{format}'"
42
64
  end
@@ -45,42 +67,88 @@ module Vanilla
45
67
  # render a snip using either the renderer given, or the renderer
46
68
  # specified by the snip's "render_as" property, or Render::Base
47
69
  # if nothing else is given.
48
- def render(snip, part=:content, args=[])
70
+ def render(snip, part=:content, args=[], enclosing_snip=snip)
49
71
  rendering(snip) do |renderer|
50
- renderer.render(snip, part, args)
72
+ renderer.render(snip, part, args, enclosing_snip)
73
+ end
74
+ end
75
+
76
+ # Returns the renderer class for a given snip
77
+ def renderer_for(snip)
78
+ if snip
79
+ find_renderer(snip.render_as || snip.extension)
80
+ else
81
+ default_renderer
82
+ end
83
+ end
84
+
85
+ def default_layout_snip
86
+ soup[config[:default_layout_snip] || 'layout']
87
+ end
88
+
89
+ def layout_for(snip)
90
+ if snip
91
+ renderer_for(snip).new(self).layout_for(snip)
92
+ else
93
+ default_layout_snip
94
+ end
95
+ end
96
+
97
+ def snip(attributes)
98
+ @soup << attributes
99
+ end
100
+
101
+ def register_renderer(klass, *types)
102
+ types.each do |type|
103
+ if klass.is_a?(String)
104
+ klass = klass.split("::").inject(Object) { |o, name| o.const_get(name) }
105
+ end
106
+ @renderers[type.to_s] = klass
51
107
  end
52
108
  end
53
109
 
54
- # Given the snip and parameters, yield an instance of the appropriate
55
- # Vanilla::Render::Base subclass
110
+ private
111
+
112
+ def prepare_renderers(additional_renderers={})
113
+ @renderers = Hash.new(config[:default_renderer] || Vanilla::Renderers::Base)
114
+ @renderers.merge!({
115
+ "base" => Vanilla::Renderers::Base,
116
+ "markdown" => Vanilla::Renderers::Markdown,
117
+ "bold" => Vanilla::Renderers::Bold,
118
+ "erb" => Vanilla::Renderers::Erb,
119
+ "rb" => Vanilla::Renderers::Ruby,
120
+ "ruby" => Vanilla::Renderers::Ruby,
121
+ "haml" => Vanilla::Renderers::Haml,
122
+ "raw" => Vanilla::Renderers::Raw,
123
+ "textile" => Vanilla::Renderers::Textile
124
+ })
125
+ additional_renderers.each { |name, klass| register_renderer(klass, name) } if additional_renderers
126
+ end
127
+
128
+ def find_renderer(name)
129
+ @renderers[(name ? name.downcase : nil)]
130
+ end
131
+
132
+ def default_renderer
133
+ @renderers[nil]
134
+ end
135
+
56
136
  def rendering(snip)
57
137
  renderer_instance = renderer_for(snip).new(self)
58
138
  yield renderer_instance
59
139
  rescue Exception => e
60
- "<pre>[Error rendering '#{snip.name}' - \"" +
61
- e.message.gsub("<", "&lt;").gsub(">", "&gt;") + "\"]\n" +
140
+ snip_name = snip ? snip.name : nil
141
+ "<pre>[Error rendering '#{snip_name}' - \"" +
142
+ e.message.gsub("<", "&lt;").gsub(">", "&gt;") + "\"]\n" +
62
143
  e.backtrace.join("\n").gsub("<", "&lt;").gsub(">", "&gt;") + "</pre>"
63
144
  end
64
-
65
- # Returns the renderer class for a given snip
66
- def renderer_for(snip)
67
- return Renderers::Base unless snip.render_as && !snip.render_as.empty?
68
- Vanilla::Renderers.const_get(snip.render_as)
69
- end
70
-
71
- # Other things can call this when a snip cannot be loaded.
72
- def render_missing_snip(snip_name)
73
- "[snip '#{snip_name}' cannot be found]"
74
- end
75
-
76
- private
77
-
78
- def prepare_configuration(config_file)
79
- config_file ||= "config.yml"
80
- @config = YAML.load(File.open(config_file)) rescue {}
81
- @config[:filename] = config_file
82
- def @config.save!
83
- File.open(self[:filename], 'w') { |f| f.puts self.to_yaml }
145
+
146
+ def prepare_soup(config)
147
+ if config[:soups]
148
+ backends = [config[:soups]].flatten.map { |path| ::Soup::Backends::FileBackend.new(path) }
149
+ ::Soup.new(::Soup::Backends::MultiSoup.new(*backends))
150
+ else
151
+ ::Soup.new(::Soup::Backends::FileBackend.new(config[:soup]))
84
152
  end
85
153
  end
86
154
  end