diff --git a/lib/jekyll.rb b/lib/jekyll.rb index 6e489264..ead5e138 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -74,6 +74,8 @@ module Jekyll 'markdown_ext' => 'markdown,mkd,mkdn,md', 'textile_ext' => 'textile', + 'excerpt_separator' => "\n\n", + 'maruku' => { 'use_tex' => false, 'use_divs' => false, diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index d40993de..b97dec4b 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -19,7 +19,7 @@ module Jekyll end attr_accessor :site - attr_accessor :data, :content, :output, :ext + attr_accessor :data, :excerpt, :content, :output, :ext attr_accessor :date, :slug, :published, :tags, :categories attr_reader :name @@ -77,8 +77,8 @@ module Jekyll # Returns nothing. def read_yaml(base, name) super(base, name) + self.excerpt = self.extract_excerpt self.data['layout'] = 'post' unless self.data.has_key?('layout') - self.data end # Compares Post objects. First compares the Post date. If the dates are @@ -109,6 +109,14 @@ module Jekyll raise FatalException.new("Post #{name} does not have a valid date.") end + # Transform the contents and excerpt based on the content type. + # + # Returns nothing. + def transform + super + self.excerpt = converter.convert(self.excerpt) + end + # The generated directory into which the post will be placed # upon generation. This is derived from the permalink or, if # permalink is absent, set to the default date @@ -257,7 +265,8 @@ module Jekyll "next" => self.next, "previous" => self.previous, "tags" => self.tags, - "content" => self.content }) + "content" => self.content, + "excerpt" => self.excerpt }) end # Returns the shorthand String identifier of this Post. @@ -283,5 +292,48 @@ module Jekyll nil end end + + protected + + # Internal: Extract excerpt from the content + # + # By default excerpt is your first paragraph of a post: everything before + # the first two new lines: + # + # --- + # title: Example + # --- + # + # First paragraph with [link][1]. + # + # Second paragraph. + # + # [1]: http://example.com/ + # + # This is fairly good option for Markdown and Textile files. But might cause + # problems for HTML posts (which is quite unusual for Jekyll). If default + # excerpt delimiter is not good for you, you might want to set your own via + # configuration option `excerpt_separator`. For example, following is a good + # alternative for HTML posts: + # + # # file: _config.yml + # excerpt_separator: "" + # + # Notice that all markdown-style link references will be appended to the + # excerpt. So the example post above will have this excerpt source: + # + # First paragraph with [link][1]. + # + # [1]: http://example.com/ + # + # Excerpts are rendered same time as content is rendered. + # + # Returns excerpt String + def extract_excerpt + separator = self.site.config['excerpt_separator'] + head, _, tail = self.content.partition(separator) + + "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n") + end end end diff --git a/test/source/_posts/2013-01-02-post-excerpt.markdown b/test/source/_posts/2013-01-02-post-excerpt.markdown new file mode 100644 index 00000000..5cac6eb5 --- /dev/null +++ b/test/source/_posts/2013-01-02-post-excerpt.markdown @@ -0,0 +1,14 @@ +--- +layout: ~ +title: Post Excerpt +--- + +First paragraph with [link ref][link]. + +Second paragraph + +--- + +Third paragraph + +[link]: http://www.jekyllrb.com/ diff --git a/test/test_generated_site.rb b/test/test_generated_site.rb index 552e2417..abda0ba5 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 30, @site.posts.size + assert_equal 31, @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 11492415..5bff6e5e 100644 --- a/test/test_post.rb +++ b/test/test_post.rb @@ -252,6 +252,52 @@ class TestPost < Test::Unit::TestCase assert_equal "

{{ page.title }}

\n

Best post ever

", @post.content end + + context "#excerpt" do + setup do + file = "2013-01-02-post-excerpt.markdown" + @post.process(file) + @post.read_yaml(@source, file) + @post.transform + end + + should "return first paragraph by default" do + assert @post.excerpt.include?("First paragraph"), "contains first paragraph" + assert !@post.excerpt.include?("Second paragraph"), "does not contains second paragraph" + assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph" + end + + should "correctly resolve link references" do + assert @post.excerpt.include?("www.jekyllrb.com"), "contains referenced link URL" + end + + should "return rendered HTML" do + assert_equal "

First paragraph with link ref.

", + @post.excerpt + end + + context "with excerpt_separator setting" do + setup do + file = "2013-01-02-post-excerpt.markdown" + + @post.site.config['excerpt_separator'] = "\n---\n" + + @post.process(file) + @post.read_yaml(@source, file) + @post.transform + end + + should "respect given separator" do + assert @post.excerpt.include?("First paragraph"), "contains first paragraph" + assert @post.excerpt.include?("Second paragraph"), "contains second paragraph" + assert !@post.excerpt.include?("Third paragraph"), "does not contains third paragraph" + end + + should "replace separator with new-lines" do + assert !@post.excerpt.include?("---"), "does not contains separator" + end + end + end end context "when in a site" do