diff --git a/History.txt b/History.txt index 1fe095f8..f98912fc 100644 --- a/History.txt +++ b/History.txt @@ -2,6 +2,9 @@ * Major Enhancements * Proper plugin system (#19, #100) * Add safe mode so unsafe converters/generators can be added + * Maruku is now the only processor dependency installed by default. + Other processors will be lazy-loaded when necessary (and prompt the + user to install them when necessary) (#57) * Minor Enhancements * Inclusion/exclusion of future dated posts (#59) * Generation for a specific time (#59) diff --git a/bin/jekyll b/bin/jekyll index b33d4247..fec32d35 100755 --- a/bin/jekyll +++ b/bin/jekyll @@ -142,7 +142,11 @@ if options['auto'] end else puts "Building site: #{source} -> #{destination}" - site.process + begin + site.process + rescue Jekyll::FatalException + exit(1) + end puts "Successfully generated site: #{source} -> #{destination}" end diff --git a/jekyll.gemspec b/jekyll.gemspec index 2cf024f9..71ea1f9d 100644 --- a/jekyll.gemspec +++ b/jekyll.gemspec @@ -23,13 +23,16 @@ Gem::Specification.new do |s| s.rdoc_options = ["--charset=UTF-8"] s.extra_rdoc_files = %w[README.textile LICENSE] - s.add_runtime_dependency('RedCloth', [">= 4.2.1"]) s.add_runtime_dependency('liquid', [">= 1.9.0"]) s.add_runtime_dependency('classifier', [">= 1.3.1"]) - s.add_runtime_dependency('maruku', [">= 0.5.9"]) s.add_runtime_dependency('directory_watcher', [">= 1.1.1"]) + s.add_runtime_dependency('maruku', [">= 0.5.9"]) - s.add_development_dependency('DEVDEPNAME', [">= 1.1.0", "< 2.0.0"]) + s.add_development_dependency('redgreen', [">= 4.2.1"]) + s.add_development_dependency('shoulda', [">= 4.2.1"]) + s.add_development_dependency('rr', [">= 4.2.1"]) + s.add_development_dependency('cucumber', [">= 4.2.1"]) + s.add_development_dependency('RedCloth', [">= 4.2.1"]) # = MANIFEST = s.files = %w[ diff --git a/lib/jekyll.rb b/lib/jekyll.rb index ad6cb62a..8229af36 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -22,7 +22,7 @@ require 'yaml' # 3rd party require 'liquid' -require 'redcloth' +require 'maruku' # internal requires require 'jekyll/core_ext' @@ -34,6 +34,7 @@ require 'jekyll/post' require 'jekyll/filters' require 'jekyll/albino' require 'jekyll/static_file' +require 'jekyll/errors' # extensions require 'jekyll/plugin' diff --git a/lib/jekyll/converter.rb b/lib/jekyll/converter.rb index 61398bf1..c2528d14 100644 --- a/lib/jekyll/converter.rb +++ b/lib/jekyll/converter.rb @@ -25,6 +25,13 @@ module Jekyll @pygments_suffix end + # Initialize the converter. + # + # Returns an initialized Converter. + def initialize(config = {}) + @config = config + end + # Get the pygments prefix. # # Returns the String prefix. diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb index 0210c786..4e50ef5a 100644 --- a/lib/jekyll/converters/markdown.rb +++ b/lib/jekyll/converters/markdown.rb @@ -6,36 +6,30 @@ module Jekyll pygments_prefix '\n' pygments_suffix '\n' - def initialize(config = {}) + def setup + return if @setup # Set the Markdown interpreter (and Maruku self.config, if necessary) - case config['markdown'] + case @config['markdown'] when 'rdiscount' begin require 'rdiscount' - - def convert(content) - RDiscount.new(content).to_html - end - rescue LoadError - puts 'You must have the rdiscount gem installed first' + STDERR.puts 'You are missing a library required for Markdown. Please run:' + STDERR.puts ' $ [sudo] gem install rdiscount' + raise FatalException.new("Missing dependency: rdiscount") end when 'maruku' begin require 'maruku' - def convert(content) - Maruku.new(content).to_html - end - - if config['maruku']['use_divs'] + if @config['maruku']['use_divs'] require 'maruku/ext/div' - puts 'Maruku: Using extended syntax for div elements.' + STDERR.puts 'Maruku: Using extended syntax for div elements.' end - if config['maruku']['use_tex'] + if @config['maruku']['use_tex'] require 'maruku/ext/math' - puts "Maruku: Using LaTeX extension. Images in `#{config['maruku']['png_dir']}`." + STDERR.puts "Maruku: Using LaTeX extension. Images in `#{@config['maruku']['png_dir']}`." # Switch off MathML output MaRuKu::Globals[:html_math_output_mathml] = false @@ -44,16 +38,21 @@ module Jekyll # Turn on math to PNG support with blahtex # Resulting PNGs stored in `images/latex` MaRuKu::Globals[:html_math_output_png] = true - MaRuKu::Globals[:html_png_engine] = config['maruku']['png_engine'] - MaRuKu::Globals[:html_png_dir] = config['maruku']['png_dir'] - MaRuKu::Globals[:html_png_url] = config['maruku']['png_url'] + MaRuKu::Globals[:html_png_engine] = @config['maruku']['png_engine'] + MaRuKu::Globals[:html_png_dir] = @config['maruku']['png_dir'] + MaRuKu::Globals[:html_png_url] = @config['maruku']['png_url'] end rescue LoadError - puts "The maruku gem is required for markdown support!" + STDERR.puts 'You are missing a library required for Markdown. Please run:' + STDERR.puts ' $ [sudo] gem install maruku' + raise FatalException.new("Missing dependency: maruku") end else - raise "Invalid Markdown processor: '#{config['markdown']}' -- did you mean 'maruku' or 'rdiscount'?" + STDERR.puts "Invalid Markdown processor: #{@config['markdown']}" + STDERR.puts " Valid options are [ maruku | rdiscount ]" + raise FatalException.new("Invalid Markdown process: #{@config['markdown']}") end + @setup = true end def matches(ext) @@ -64,6 +63,15 @@ module Jekyll ".html" end + def convert(content) + setup + case @config['markdown'] + when 'rdiscount' + RDiscount.new(content).to_html + when 'maruku' + Maruku.new(content).to_html + end + end end end diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb index 60f2153b..072e393a 100644 --- a/lib/jekyll/converters/textile.rb +++ b/lib/jekyll/converters/textile.rb @@ -6,6 +6,16 @@ module Jekyll pygments_prefix '' pygments_suffix '' + def setup + return if @setup + require 'redcloth' + @setup = true + rescue LoadError + STDERR.puts 'You are missing a library required for Textile. Please run:' + STDERR.puts ' $ [sudo] gem install RedCloth' + raise FatalException.new("Missing dependency: RedCloth") + end + def matches(ext) ext =~ /textile/i end @@ -15,9 +25,9 @@ module Jekyll end def convert(content) + setup RedCloth.new(content).to_html end - end end diff --git a/lib/jekyll/errors.rb b/lib/jekyll/errors.rb new file mode 100644 index 00000000..296d8371 --- /dev/null +++ b/lib/jekyll/errors.rb @@ -0,0 +1,6 @@ +module Jekyll + + class FatalException < StandardError + end + +end \ No newline at end of file diff --git a/test/helper.rb b/test/helper.rb index 8521bdb4..61636a4e 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -3,6 +3,9 @@ gem 'RedCloth', '>= 4.2.1' require File.join(File.dirname(__FILE__), *%w[.. lib jekyll]) +require 'RedCloth' +require 'rdiscount' + require 'test/unit' require 'redgreen' require 'shoulda' @@ -10,6 +13,9 @@ require 'rr' include Jekyll +# Send STDERR into the void to suppress program output messages +STDERR.reopen(test(?e, '/dev/null') ? '/dev/null' : 'NUL:') + class Test::Unit::TestCase include RR::Adapters::TestUnit diff --git a/test/test_site.rb b/test/test_site.rb index 09654ab9..f18791de 100644 --- a/test/test_site.rb +++ b/test/test_site.rb @@ -133,18 +133,20 @@ class TestSite < Test::Unit::TestCase end context 'with an invalid markdown processor in the configuration' do - - should 'give a meaningful error message' do + should 'not throw an error at initialization time' do bad_processor = 'not a processor name' - begin + assert_nothing_raised do Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) - flunk 'Invalid markdown processors should cause a failure on site creation' - rescue RuntimeError => e - assert e.to_s =~ /invalid|bad/i - assert e.to_s =~ %r{#{bad_processor}} end end + should 'throw FatalException at process time' do + bad_processor = 'not a processor name' + s = Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) + assert_raise Jekyll::FatalException do + s.process + end + end end end