Preston Hager
Preston Hager

Reputation: 1611

Using a Liquid filter to split Markdown/HTML by horizontal break (Jekyll)

I would like to split some markdown content by sections denoted by a horizontal line. In standard markdown, this is denoted by 3 or more asterisks, dashes, or underscores. So I need to split some plain text content by either ***, ---, or ___, and any amount more than three as well, so that something like five dashes, -----, could work too.

Currently I have the following markdown file which I am parsing:

---
layout: section_one
---

Content here!

-----

Another section in markdown

-----

Final content.

The layout file is then named section_one.html with the contents:

<!-- DOCTYPE and html/body and stuff -->
{% assign content_split = content | split: "<hr>" %}
<div>{{ content_split[0] }}</div>

According to the lovely Shopify Liquid documentation, there is a split filter on Strings. Since the content data seems to contain parsed HTML, I tried splitting by the <hr> tag. This did not split the content anywhere.

I then tried splitting the content by --- and ----- since that's what I have in the markdown file, this did not work either.

Finally, I tried using page.content instead of content, which does work, but is not very compact as I would need to split and strip extra -, *, and _. Which overall turns into a tag something like:

{{ page.content | split: '---' | join: "\u2063" | split '***' | ... way more here ... | split "\u2063" }}

This formula has the disadvantage of being able to only use 3 characters, not more than 3. If were to loop through and strip the -, then I couldn't start the content with a - either such as creating a list.

How can I best split a markdown string or parsed markdown (HTML) by the horizontal line breaks?

Upvotes: 0

Views: 13

Answers (1)

Preston Hager
Preston Hager

Reputation: 1611

After some more research, I decided to make a custom liquid filter. When creating liquid filters, you can take some content as the input as well as parameters. Not sure how to best use parameters for this use-case yet but so far what I have is fairly simple.

module Jekyll
  module MarkdownSplit
    def markdown_split(content)
      content.split(/^\s*[-*_]{3,}\s*$/m)
    end
  end
end

Liquid::Template.register_filter(Jekyll::MarkdownSplit)

If you're not using Jekyll, you'll need to probably put the MarkdownSplit filter under it's own module or whatever platform you're using. Right now, this will split using a regex that matches to any ---, ***, or ___ line (not just part of a line/phrase). This means if you have two in a row, you may end up with empty content so I'm leaving it up to the content creator to see this.

Upvotes: 0

Related Questions