diff --git a/lib/jekyll.rb b/lib/jekyll.rb index 05c539ff..7938031d 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -27,6 +27,9 @@ require 'jekyll/tags/highlight' require 'jekyll/tags/include' require 'jekyll/albino' require 'jekyll/static_file' +require 'jekyll/converters/markdown' +require 'jekyll/converters/textile' +require 'jekyll/converters/identity' module Jekyll # Default options. Overriden by values in _config.yml or command-line opts. diff --git a/lib/jekyll/converters/identity.rb b/lib/jekyll/converters/identity.rb new file mode 100644 index 00000000..b21dda7b --- /dev/null +++ b/lib/jekyll/converters/identity.rb @@ -0,0 +1,27 @@ +module Jekyll + + class IdentityConverter + + def initialize(config = {}) + + end + + def content_type + nil + end + + def matches(ext) + true + end + + def output_ext(ext) + ext + end + + def convert(content) + content + end + + end + +end diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb new file mode 100644 index 00000000..3c1aeb50 --- /dev/null +++ b/lib/jekyll/converters/markdown.rb @@ -0,0 +1,69 @@ +module Jekyll + + class MarkdownConverter + + def initialize(config = {}) + # Set the Markdown interpreter (and Maruku self.config, if necessary) + 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' + end + when 'maruku' + begin + require 'maruku' + + def convert(content) + Maruku.new(content).to_html + end + + if config['maruku']['use_divs'] + require 'maruku/ext/div' + puts 'Maruku: Using extended syntax for div elements.' + end + + if config['maruku']['use_tex'] + require 'maruku/ext/math' + puts "Maruku: Using LaTeX extension. Images in `#{config['maruku']['png_dir']}`." + + # Switch off MathML output + MaRuKu::Globals[:html_math_output_mathml] = false + MaRuKu::Globals[:html_math_engine] = 'none' + + # 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'] + end + rescue LoadError + puts "The maruku gem is required for markdown support!" + end + else + raise "Invalid Markdown processor: '#{config['markdown']}' -- did you mean 'maruku' or 'rdiscount'?" + end + end + + def content_type + "markdown" + end + + def matches(ext) + ext =~ /(markdown|mkdn?|md)/i + end + + def output_ext(ext) + ".html" + end + + end + +end diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb new file mode 100644 index 00000000..50d28276 --- /dev/null +++ b/lib/jekyll/converters/textile.rb @@ -0,0 +1,27 @@ +module Jekyll + + class TextileConverter + + def initialize(config = {}) + + end + + def content_type + "textile" + end + + def matches(ext) + ext =~ /textile/i + end + + def output_ext(ext) + ".html" + end + + def convert(content) + RedCloth.new(content).to_html + end + + end + +end diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 644dd053..96e18523 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -22,13 +22,13 @@ module Jekyll # Returns nothing def read_yaml(base, name) self.content = File.read(File.join(base, name)) - + if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)/m self.content = self.content[($1.size + $2.size)..-1] - + self.data = YAML.load($1) end - + self.data ||= {} end @@ -36,26 +36,14 @@ module Jekyll # # Returns nothing def transform - case self.content_type - when 'textile' - self.content = self.site.textile(self.content) - when 'markdown' - self.content = self.site.markdown(self.content) - end + self.content = converter.convert(self.content) end # Determine the extension depending on content_type # # Returns the extensions for the output file def output_ext - case self.content_type - when 'textile' - ".html" - when 'markdown' - ".html" - else - self.ext - end + converter.output_ext(self.ext) end # Determine which formatting engine to use based on this convertible's @@ -63,13 +51,11 @@ module Jekyll # # Returns one of :textile, :markdown or :unknown def content_type - case self.ext[1..-1] - when /textile/i - return 'textile' - when /markdown/i, /mkdn/i, /md/i, /mkd/i - return 'markdown' - end - return 'unknown' + converter.content_type + end + + def converter + @converter ||= self.site.converters.find { |c| c.matches(self.ext) } end # Add any necessary layouts to this convertible document diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index cfec6c2e..91b6cfe9 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -124,7 +124,8 @@ module Jekyll "month" => date.strftime("%m"), "day" => date.strftime("%d"), "title" => CGI.escape(slug), - "categories" => categories.join('/') + "categories" => categories.join('/'), + "output_ext" => self.output_ext }.inject(template) { |result, token| result.gsub(/:#{token.first}/, token.last) }.gsub(/\/\//, "/") diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 4315e2cb..17243296 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -3,7 +3,7 @@ module Jekyll class Site attr_accessor :config, :layouts, :posts, :pages, :static_files, :categories, :exclude, :source, :dest, :lsi, :pygments, :permalink_style, :tags, :time, - :future + :future, :converters # Initialize the site # +config+ is a Hash containing site configurations details @@ -19,6 +19,7 @@ module Jekyll self.permalink_style = config['permalink'].to_sym self.exclude = config['exclude'] || [] self.future = config['future'] + self.converters = [] self.reset self.setup @@ -38,57 +39,11 @@ module Jekyll # Check to see if LSI is enabled. require 'classifier' if self.lsi - # Set the Markdown interpreter (and Maruku self.config, if necessary) - case self.config['markdown'] - when 'rdiscount' - begin - require 'rdiscount' + # converters + converters << Jekyll::MarkdownConverter.new(self.config) + converters << Jekyll::TextileConverter.new(self.config) + converters << Jekyll::IdentityConverter.new(self.config) - def markdown(content) - RDiscount.new(content).to_html - end - - rescue LoadError - puts 'You must have the rdiscount gem installed first' - end - when 'maruku' - begin - require 'maruku' - - def markdown(content) - Maruku.new(content).to_html - end - - if self.config['maruku']['use_divs'] - require 'maruku/ext/div' - puts 'Maruku: Using extended syntax for div elements.' - end - - if self.config['maruku']['use_tex'] - require 'maruku/ext/math' - puts "Maruku: Using LaTeX extension. Images in `#{self.config['maruku']['png_dir']}`." - - # Switch off MathML output - MaRuKu::Globals[:html_math_output_mathml] = false - MaRuKu::Globals[:html_math_engine] = 'none' - - # 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] = self.config['maruku']['png_engine'] - MaRuKu::Globals[:html_png_dir] = self.config['maruku']['png_dir'] - MaRuKu::Globals[:html_png_url] = self.config['maruku']['png_url'] - end - rescue LoadError - puts "The maruku gem is required for markdown support!" - end - else - raise "Invalid Markdown processor: '#{self.config['markdown']}' -- did you mean 'maruku' or 'rdiscount'?" - end - end - - def textile(content) - RedCloth.new(content).to_html end # Do the actual work of processing the site and generating the diff --git a/test/test_tags.rb b/test/test_tags.rb index 64119572..8659ffd7 100644 --- a/test/test_tags.rb +++ b/test/test_tags.rb @@ -2,26 +2,17 @@ require File.dirname(__FILE__) + '/helper' class TestTags < Test::Unit::TestCase - def create_post(content, override = {}, markdown = true) + def create_post(content, override = {}, content_type = "markdown") stub(Jekyll).configuration do Jekyll::DEFAULTS.merge({'pygments' => true}).merge(override) end site = Site.new(Jekyll.configuration) info = { :filters => [Jekyll::Filters], :registers => { :site => site } } - - if markdown - payload = {"content_type" => "markdown"} - else - payload = {"content_type" => "textile"} - end + payload = {"content_type" => content_type} + @converter = site.converters.find { |c| c.content_type == content_type } @result = Liquid::Template.parse(content).render(payload, info) - - if markdown - @result = site.markdown(@result) - else - @result = site.textile(@result) - end + @result = @converter.convert(@result) end def fill_post(code, override = {}) @@ -82,7 +73,7 @@ CONTENT context "using Textile" do setup do - create_post(@content, {}, false) + create_post(@content, {}, "textile") end # Broken in RedCloth 4.1.9