diff --git a/History.txt b/History.txt index ef9a75ee..d0091fd0 100644 --- a/History.txt +++ b/History.txt @@ -1,6 +1,9 @@ == HEAD * Major Enhancements * Add command line importer functionality (#253) + * Add Redcarpet Markdown support (#318) + * Make markdown/textile extensions configurable (#312) + * Add `markdownify` filter * Minor Enhancements * Switch to Albino gem * Bundler support diff --git a/bin/jekyll b/bin/jekyll index 753eedad..2e33f377 100755 --- a/bin/jekyll +++ b/bin/jekyll @@ -82,6 +82,10 @@ opts = OptionParser.new do |opts| opts.on("--rdiscount", "Use rdiscount gem for Markdown") do options['markdown'] = 'rdiscount' end + + opts.on("--redcarpet", "Use redcarpet gem for Markdown") do + options['markdown'] = 'redcarpet' + end opts.on("--kramdown", "Use kramdown gem for Markdown") do options['markdown'] = 'kramdown' diff --git a/features/site_configuration.feature b/features/site_configuration.feature index 0681c2f5..8d3bee5d 100644 --- a/features/site_configuration.feature +++ b/features/site_configuration.feature @@ -55,6 +55,13 @@ Feature: Site configuration Then the _site directory should exist And I should see "Google" in "_site/index.html" + Scenario: Use Redcarpet for markup + Given I have an "index.markdown" page that contains "[Google](http://google.com)" + And I have a configuration file with "markdown" set to "redcarpet" + When I run jekyll + Then the _site directory should exist + And I should see "Google" in "_site/index.html" + Scenario: Use Maruku for markup Given I have an "index.markdown" page that contains "[Google](http://google.com)" And I have a configuration file with "markdown" set to "maruku" diff --git a/jekyll.gemspec b/jekyll.gemspec index 2b2efdba..d23bd192 100644 --- a/jekyll.gemspec +++ b/jekyll.gemspec @@ -5,7 +5,7 @@ Gem::Specification.new do |s| s.name = 'jekyll' s.version = '0.10.0' - s.date = '2010-12-16' + s.date = '2011-05-30' s.rubyforge_project = 'jekyll' s.summary = "A simple, blog aware, static site generator." @@ -32,12 +32,14 @@ Gem::Specification.new do |s| s.add_development_dependency('redgreen', ">= 1.2.2") s.add_development_dependency('shoulda', ">= 2.11.3") s.add_development_dependency('rr', ">= 1.0.2") - s.add_development_dependency('cucumber', ">= 0.10.0") + s.add_development_dependency('cucumber', ">= 0.10.3") s.add_development_dependency('RedCloth', ">= 4.2.1") s.add_development_dependency('rdiscount', ">= 1.6.5") - + s.add_development_dependency('redcarpet', ">= 1.9.0") + # = MANIFEST = s.files = %w[ + Gemfile History.txt LICENSE README.textile @@ -56,7 +58,6 @@ Gem::Specification.new do |s| features/support/env.rb jekyll.gemspec lib/jekyll.rb - lib/jekyll/albino.rb lib/jekyll/converter.rb lib/jekyll/converters/identity.rb lib/jekyll/converters/markdown.rb @@ -70,13 +71,16 @@ Gem::Specification.new do |s| lib/jekyll/layout.rb lib/jekyll/migrators/csv.rb lib/jekyll/migrators/drupal.rb + lib/jekyll/migrators/enki.rb lib/jekyll/migrators/marley.rb lib/jekyll/migrators/mephisto.rb lib/jekyll/migrators/mt.rb + lib/jekyll/migrators/posterous.rb lib/jekyll/migrators/textpattern.rb + lib/jekyll/migrators/tumblr.rb lib/jekyll/migrators/typo.rb - lib/jekyll/migrators/wordpress.com.rb lib/jekyll/migrators/wordpress.rb + lib/jekyll/migrators/wordpressdotcom.rb lib/jekyll/page.rb lib/jekyll/plugin.rb lib/jekyll/post.rb @@ -132,6 +136,7 @@ Gem::Specification.new do |s| test/test_pager.rb test/test_post.rb test/test_rdiscount.rb + test/test_redcarpet.rb test/test_site.rb test/test_tags.rb test/test_redcloth.rb diff --git a/lib/jekyll.rb b/lib/jekyll.rb index 3ffc36b4..9ff0ce7d 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -65,6 +65,9 @@ module Jekyll 'pygments' => false, 'markdown' => 'maruku', 'permalink' => 'date', + + 'markdown_ext' => 'markdown,mkd,mkdn,md', + 'textile_ext' => 'textile', 'maruku' => { 'use_tex' => false, @@ -76,6 +79,9 @@ module Jekyll 'rdiscount' => { 'extensions' => [] }, + 'redcarpet' => { + 'extensions' => [] + }, 'kramdown' => { 'auto_ids' => true, 'footnote_nr' => 1, diff --git a/lib/jekyll/converters/markdown.rb b/lib/jekyll/converters/markdown.rb index 00c56d7c..b5655476 100644 --- a/lib/jekyll/converters/markdown.rb +++ b/lib/jekyll/converters/markdown.rb @@ -10,6 +10,15 @@ module Jekyll return if @setup # Set the Markdown interpreter (and Maruku self.config, if necessary) case @config['markdown'] + when 'redcarpet' + begin + require 'redcarpet' + @redcarpet_extensions = @config['redcarpet']['extensions'].map { |e| e.to_sym } + rescue LoadError + STDERR.puts 'You are missing a library required for Markdown. Please run:' + STDERR.puts ' $ [sudo] gem install redcarpet' + raise FatalException.new("Missing dependency: redcarpet") + end when 'kramdown' begin require 'kramdown' @@ -65,9 +74,10 @@ module Jekyll end @setup = true end - + def matches(ext) - ext =~ /(markdown|mkdn?|md)/i + rgx = '(' + @config['markdown_ext'].gsub(',','|') +')' + ext =~ Regexp.new(rgx, Regexp::IGNORECASE) end def output_ext(ext) @@ -77,6 +87,8 @@ module Jekyll def convert(content) setup case @config['markdown'] + when 'redcarpet' + Redcarpet.new(content, *@redcarpet_extensions).to_html when 'kramdown' # Check for use of coderay if @config['kramdown']['use_coderay'] diff --git a/lib/jekyll/converters/textile.rb b/lib/jekyll/converters/textile.rb index 347ab197..6433dbb5 100644 --- a/lib/jekyll/converters/textile.rb +++ b/lib/jekyll/converters/textile.rb @@ -17,7 +17,8 @@ module Jekyll end def matches(ext) - ext =~ /textile/i + rgx = '(' + @config['textile_ext'].gsub(',','|') +')' + ext =~ Regexp.new(rgx, Regexp::IGNORECASE) end def output_ext(ext) diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 1723fa0d..46dbfea1 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -1,3 +1,5 @@ +require 'set' + # Convertible provides methods for converting a pagelike item # from a certain type of markup into actual content # @@ -86,6 +88,8 @@ module Jekyll # recursively render layouts layout = layouts[self.data["layout"]] + used = Set.new([layout]) + while layout payload = payload.deep_merge({"content" => self.output, "page" => layout.data}) @@ -95,7 +99,13 @@ module Jekyll puts "Liquid Exception: #{e.message} in #{self.data["layout"]}" end - layout = layouts[layout.data["layout"]] + if layout = layouts[layout.data["layout"]] + if used.include?(layout) + layout = nil # avoid recursive chain + else + used << layout + end + end end end end diff --git a/lib/jekyll/filters.rb b/lib/jekyll/filters.rb index dbd9f511..eb61d84a 100644 --- a/lib/jekyll/filters.rb +++ b/lib/jekyll/filters.rb @@ -9,7 +9,20 @@ module Jekyll # # Returns the HTML formatted String. def textilize(input) - TextileConverter.new.convert(input) + site = @context.registers[:site] + converter = site.getConverterImpl(Jekyll::TextileConverter) + converter.convert(input) + end + + # Convert a Markdown string into HTML output. + # + # input - The Markdown String to convert. + # + # Returns the HTML formatted String. + def markdownify(input) + site = @context.registers[:site] + converter = site.getConverterImpl(Jekyll::MarkdownConverter) + converter.convert(input) end # Format a date in short format e.g. "27 Jan 2011". diff --git a/lib/jekyll/migrators/tumblr.rb b/lib/jekyll/migrators/tumblr.rb index 0345b4a9..d7cb3969 100644 --- a/lib/jekyll/migrators/tumblr.rb +++ b/lib/jekyll/migrators/tumblr.rb @@ -65,7 +65,7 @@ module Jekyll content << "
something really simple
", @filter.textilize("something *really* simple") end + should "markdownify with simple string" do + assert_equal "something really simple
", @filter.markdownify("something **really** simple") + end + should "convert array to sentence string with no args" do assert_equal "", @filter.array_to_sentence_string([]) end diff --git a/test/test_generated_site.rb b/test/test_generated_site.rb index c7087031..9fb7a409 100644 --- a/test/test_generated_site.rb +++ b/test/test_generated_site.rb @@ -14,7 +14,7 @@ class TestGeneratedSite < Test::Unit::TestCase end should "ensure post count is as expected" do - assert_equal 26, @site.posts.size + assert_equal 28, @site.posts.size end should "insert site.posts into the index" do diff --git a/test/test_post.rb b/test/test_post.rb index 323ab7dc..1c3ea641 100644 --- a/test/test_post.rb +++ b/test/test_post.rb @@ -397,6 +397,47 @@ class TestPost < Test::Unit::TestCase post = Post.new(@site, File.join(File.dirname(__FILE__), *%w[source]), 'foo', 'bar/2008-12-12-topical-post.textile') assert_equal ['foo'], post.categories end - end + + context "converter file extension settings" do + setup do + stub(Jekyll).configuration { Jekyll::DEFAULTS } + @site = Site.new(Jekyll.configuration) + end + + should "process .md as markdown under default configuration" do + post = setup_post '2011-04-12-md-extension.md' + conv = post.converter + assert conv.kind_of? Jekyll::MarkdownConverter + end + + should "process .text as indentity under default configuration" do + post = setup_post '2011-04-12-text-extension.text' + conv = post.converter + assert conv.kind_of? Jekyll::IdentityConverter + end + + should "process .text as markdown under alternate configuration" do + @site.config['markdown_ext'] = 'markdown,mdw,mdwn,md,text' + post = setup_post '2011-04-12-text-extension.text' + conv = post.converter + assert conv.kind_of? Jekyll::MarkdownConverter + end + + should "process .md as markdown under alternate configuration" do + @site.config['markdown_ext'] = 'markdown,mkd,mkdn,md,text' + post = setup_post '2011-04-12-text-extension.text' + conv = post.converter + assert conv.kind_of? Jekyll::MarkdownConverter + end + + should "process .text as textile under alternate configuration" do + @site.config['textile_ext'] = 'textile,text' + post = setup_post '2011-04-12-text-extension.text' + conv = post.converter + assert conv.kind_of? Jekyll::TextileConverter + end + + end + end diff --git a/test/test_redcarpet.rb b/test/test_redcarpet.rb new file mode 100644 index 00000000..1359c449 --- /dev/null +++ b/test/test_redcarpet.rb @@ -0,0 +1,21 @@ +require File.dirname(__FILE__) + '/helper' + +class TestRedcarpet < Test::Unit::TestCase + context "redcarpet" do + setup do + config = { + 'redcarpet' => { 'extensions' => ['smart'] }, + 'markdown' => 'redcarpet' + } + @markdown = MarkdownConverter.new config + end + + should "pass redcarpet options" do + assert_equal "“smart”
", @markdown.convert('"smart"').strip + end + end +end diff --git a/test/test_tags.rb b/test/test_tags.rb index ba3d0d3e..50750757 100644 --- a/test/test_tags.rb +++ b/test/test_tags.rb @@ -125,5 +125,16 @@ CONTENT assert_match %r{FINISH HIM}, @result end end + + context "using Redcarpet" do + setup do + create_post(@content, 'markdown' => 'redcarpet') + end + + should "parse correctly" do + assert_match %r{FIGHT!}, @result + assert_match %r{FINISH HIM}, @result + end + end end end