Packages

Yet another static website generator written in Elixir with MD parser (forked from serum)

Current section

Files

Jump to
serum_md lib serum markdown.ex
Raw

lib/serum/markdown.ex

defmodule Serum.Markdown do
@moduledoc false
_moduledocp = """
This module provides functions related to dealing with markdown data.
"""
alias Serum.Project
@re_media ~r/(?<type>href|src)="(?:%|%25)media:(?<url>[^"]*)"/
@re_post ~r/(?<type>href|src)="(?:%|%25)post:(?<url>[^"]*)"/
@re_page ~r/(?<type>href|src)="(?:%|%25)page:(?<url>[^"]*)"/
@re_tag ~r/(?<type>href|src)="(?:%|%25)tag:(?<url>[^"]*)"/
@doc "Converts a markdown document into HTML."
@spec to_html(binary(), Project.t()) :: {binary(), map()}
def to_html(markdown, proj) do
{html, meta} =
Md.generate(markdown,
parser: Serum.Md.Parser,
format: [*: :none, p: :indent, article: :indent],
walker:
{:post,
fn
{:p, _, [title]} = _elem, acc when not is_map_key(acc, :title) ->
{"", Map.put(acc, :title, title)}
{:a, %{"data-tag": tag}, _} = elem, acc ->
{elem, Map.update(acc, :tags, [tag], &[tag | &1])}
elem, acc ->
{elem, acc}
end}
)
{process_links(html, proj), meta}
end
@spec process_links(binary(), Project.t()) :: binary()
defp process_links(data, proj) do
data
|> replace_media_links(proj)
|> replace_tag_links(proj)
|> replace_page_links(proj)
|> replace_post_links(proj)
end
@spec replace_media_links(binary(), Project.t()) :: binary()
defp replace_media_links(data, proj) do
Regex.replace(@re_media, data, fn _, attr, val ->
make_html_attr(attr, Path.join([proj.base_url, "media", val]))
end)
end
@spec replace_tag_links(binary(), Project.t()) :: binary()
defp replace_tag_links(data, proj) do
Regex.replace(@re_tag, data, fn _, attr, val ->
make_html_attr(attr, Path.join([proj.base_url, proj.tags_path, val]))
end)
end
@spec replace_page_links(binary(), Project.t()) :: binary()
defp replace_page_links(data, proj) do
Regex.replace(@re_page, data, fn _, attr, val ->
make_html_attr(attr, Path.join([proj.base_url, val <> ".html"]))
end)
end
@spec replace_post_links(binary(), Project.t()) :: binary()
defp replace_post_links(data, proj) do
suffix = post_suffix(proj.pretty_urls)
Regex.replace(@re_post, data, fn _, attr, val ->
make_html_attr(attr, Path.join([proj.base_url, "posts", val <> suffix]))
end)
end
@spec make_html_attr(binary(), binary()) :: binary()
defp make_html_attr(attr, value) do
<<attr::binary, "=\"", value::binary, "\"">>
end
@spec post_suffix(Project.pretty_urls()) :: binary()
defp post_suffix(pretty_urls)
defp post_suffix(true), do: ""
defp post_suffix(:posts), do: ""
defp post_suffix(_pretty_urls), do: ".html"
end