Skip to content

Commit

Permalink
Re-implement handling Liquid blocks in excerpts (#7250)
Browse files Browse the repository at this point in the history
Merge pull request 7250
  • Loading branch information
ashmaroli authored and jekyllbot committed Nov 4, 2018
1 parent b586bed commit 592b530
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 38 deletions.
50 changes: 29 additions & 21 deletions lib/jekyll/excerpt.rb
Expand Up @@ -131,36 +131,45 @@ def render_with_liquid?
#
# Returns excerpt String

LIQUID_TAG_REGEX = %r!{%-?\s*(\w+).+\s*-?%}!m.freeze
LIQUID_TAG_REGEX = %r!{%-?\s*(\w+)\s*.*?-?%}!m.freeze
MKDWN_LINK_REF_REGEX = %r!^ {0,3}\[[^\]]+\]:.+$!.freeze

def extract_excerpt(doc_content)
head, _, tail = doc_content.to_s.partition(doc.excerpt_separator)

# append appropriate closing tag (to a Liquid block), to the "head" if the
# partitioning resulted in leaving the closing tag somewhere in the "tail"
# partition.
# append appropriate closing tag(s) (for each Liquid block), to the `head` if the
# partitioning resulted in leaving the closing tag somewhere in the `tail` partition.
if head.include?("{%")
head =~ LIQUID_TAG_REGEX
tag_name = Regexp.last_match(1)

if liquid_block?(tag_name) && head.match(%r!{%-?\s*end#{tag_name}\s*-?%}!).nil?
print_build_warning
modified = false
tag_names = head.scan(LIQUID_TAG_REGEX)
tag_names.flatten!
tag_names.reverse_each do |tag_name|
next unless liquid_block?(tag_name)
next if head =~ endtag_regex_stash(tag_name)

modified = true
head << "\n{% end#{tag_name} %}"
end
print_build_warning if modified
end

if tail.empty?
head
else
head.to_s.dup << "\n\n" << tail.scan(MKDWN_LINK_REF_REGEX).join("\n")
end
return head if tail.empty?

head << "\n\n" << tail.scan(MKDWN_LINK_REF_REGEX).join("\n")
end

private

def endtag_regex_stash(tag_name)
@endtag_regex_stash ||= {}
@endtag_regex_stash[tag_name] ||= %r!{%-?\s*end#{tag_name}.*?\s*-?%}!m
end

def liquid_block?(tag_name)
Liquid::Template.tags[tag_name].superclass == Liquid::Block
return false unless tag_name.is_a?(String)
return false if tag_name.start_with?("end")

Liquid::Template.tags[tag_name].ancestors.include?(Liquid::Block)
rescue NoMethodError
Jekyll.logger.error "Error:",
"A Liquid tag in the excerpt of #{doc.relative_path} couldn't be parsed."
Expand All @@ -169,12 +178,11 @@ def liquid_block?(tag_name)

def print_build_warning
Jekyll.logger.warn "Warning:", "Excerpt modified in #{doc.relative_path}!"
Jekyll.logger.warn "",
"Found a Liquid block containing separator '#{doc.excerpt_separator}'" \
" and has been modified with the appropriate closing tag."
Jekyll.logger.warn "",
"Feel free to define a custom excerpt or excerpt_separator in the" \
" document's Front Matter if the generated excerpt is unsatisfactory."
Jekyll.logger.warn "", "Found a Liquid block containing the excerpt separator" \
" #{doc.excerpt_separator.inspect}. "
Jekyll.logger.warn "", "The block has been modified with the appropriate closing tag."
Jekyll.logger.warn "", "Feel free to define a custom excerpt or excerpt_separator in the"
Jekyll.logger.warn "", "document's Front Matter if the generated excerpt is unsatisfactory."
end
end
end
23 changes: 18 additions & 5 deletions test/source/_posts/2018-01-28-closed-liquid-block-excerpt.markdown
Expand Up @@ -2,10 +2,23 @@
layout: post
---

{% if
page.layout == "post" %}
You’ll find this post in your `_posts` directory.
To add new posts, simply add a file in the `_posts` directory.
{% endif %}
{%
highlight
ruby
%}
{% assign foo = 'foobar' %}
{% raw
%}
def print_hi(name)
puts "Hi, #{name}"
end
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{%
endraw
%}
{%
endhighlight
%}

So let's talk business.
20 changes: 15 additions & 5 deletions test/source/_posts/2018-01-28-open-liquid-block-excerpt.markdown
Expand Up @@ -2,10 +2,20 @@
layout: post
---

{% if page.layout == "post" %}
You’ll find this post in your `_posts` directory.
{%
highlight
ruby
%}
{% assign foo = 'foobar' %}
{% raw
%}
def print_hi(name)
puts "Hi, #{name}"
end

{% else %}
print_hi('Tom')
#=> prints 'Hi, Tom' to STDOUT.
{% endraw %}
{% endhighlight %}

To add new posts, simply add a file in the `_posts` directory.
{% endif %}
So let's talk business.
25 changes: 18 additions & 7 deletions test/test_excerpt.rb
Expand Up @@ -184,12 +184,17 @@ def do_render(document)
@post = setup_post("2018-01-28-open-liquid-block-excerpt.markdown")
@excerpt = @post.data["excerpt"]

assert_includes @post.content, "{% if"
refute_includes @post.content.split("\n\n")[0], "{% endif %}"
head = @post.content.split("\n\n")[0]

assert_includes @post.content, "{%\n highlight\n"
assert_includes @post.content, "{% raw"
refute_includes head, "{% endraw %}"
refute_includes head, "{% endhighlight %}"
end

should "be appended to as necessary and generated" do
assert_includes @excerpt.content, "{% endif %}"
assert_includes @excerpt.content, "{% endraw %}"
assert_includes @excerpt.content, "{% endhighlight %}"
assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
end
end
Expand All @@ -201,13 +206,19 @@ def do_render(document)
@post = setup_post("2018-01-28-closed-liquid-block-excerpt.markdown")
@excerpt = @post.data["excerpt"]

assert_includes @post.content, "{% if"
assert_includes @post.content.split("\n\n")[0], "{% endif %}"
head = @post.content.split("\n\n")[0]

assert_includes @post.content, "{%\n highlight\n"
assert_includes @post.content, "{% raw"
assert_includes head, "{%\n endraw\n%}"
assert_includes head, "{%\n endhighlight\n%}"
end

should "not be appended to but generated as is" do
assert_includes @excerpt.content, "{% endif %}"
refute_includes @excerpt.content, "{% endif %}\n\n{% endif %}"
assert_includes @excerpt.content, "{%\n endraw\n%}"
assert_includes @excerpt.content, "{%\n endhighlight\n%}"
refute_includes @excerpt.content, "{%\n endraw\n%}\n\n{% endraw %}"
refute_includes @excerpt.content, "{%\n endhighlight\n%}\n\n{% endhighlight %}"
assert_equal true, @excerpt.is_a?(Jekyll::Excerpt)
end
end
Expand Down

0 comments on commit 592b530

Please sign in to comment.