vanilla 1.0.2 → 1.2

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