Skip to content

Instantly share code, notes, and snippets.

@christhekeele
Last active August 16, 2020 08:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christhekeele/7261afc017e6a0bfe8e2533b088e3e54 to your computer and use it in GitHub Desktop.
Save christhekeele/7261afc017e6a0bfe8e2533b088e3e54 to your computer and use it in GitHub Desktop.
Turn markdown files into HTML in Elixir projects at compile-time.
####
# USAGE:
#
# 1. Add Earmark to your dependencies
# 2. Place this file in lib/mix/compile.markdown.ex
# 3. Add to your mix.exs project's compilers:, ie:
# compilers: [:markdown] ++ Mix.compilers()
# 4. Profit?
defmodule Mix.Tasks.Compile.Markdown do
use Mix.Task
@impl true
def run(_args) do
project = Mix.Project.config()
paths = project[:elixirc_paths]
options = struct(Earmark.Options, get_in(project, [:earmark, :options]) || [])
for source <- Mix.Utils.extract_files(paths, "*.{md,markdown}.eex") do
destination = String.replace(source, ~r/\.(md|markdown)\.eex/, ".html.eex")
content = open_file(source) |> IO.stream(:line) |> Enum.to_list
options = %{options | file: source}
result = Earmark.as_html!(content, options)
File.write!(destination, result)
end
:ok
end
defp open_file(filename), do: io_device(File.open(filename, [:utf8]), filename)
defp io_device({:ok, io_device}, _), do: io_device
defp io_device({:error, reason}, filename) do
IO.puts(:stderr, "#{filename}: #{:file.format_error(reason)}")
exit(1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment