From 0097482f19eff850e1efe7261c603050635307d1 Mon Sep 17 00:00:00 2001 From: Catalin Constantin Mititiuc Date: Tue, 17 Jun 2025 11:17:37 -0700 Subject: [PATCH] Update README --- README.md | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bf7b0b0..daab11f 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,151 @@ # Pandoc -**TODO: Add description** +A watcher and a Mix task that uses Pandoc to convert markdown files to html. + +## Requirements + +- inotify-tools +- pandoc ## Installation -If [available in Hex](https://hex.pm/docs/publish), the package can be installed -by adding `pandoc` to your list of dependencies in `mix.exs`: - ```elixir +# mix.exs + def deps do [ - {:pandoc, "~> 0.1.0"} + {:pandoc, "~> 0.1.0", runtime: Mix.env() == :dev} ] end + +defp aliases do + [ + # ... + "documents.build": ["pandoc hello"], + "statics.build": ["assets.build", "documents.build"], + "statics.deploy": ["assets.deploy", "documents.build"] + ] +end +``` + +```elixir +# config/config.exs + +config :pandoc, + hello: [ + args: ~w(--mathjax -o ../priv/static/posts), + cd: Path.expand("../documents", __DIR__) + ] +``` + +```elixir +# config/dev.exs + +config :hello, HelloWeb.Endpoint, + # ... + watchers: [ + # ... + pandoc: {Pandoc, :run, [:hello, ~w(--watch)]} + ] + +config :pandoc, hello: [pattern: "**/*.md"] +``` + +```elixir +# lib/hello_web/router.ex + + scope "/", HelloWeb do + pipe_through :browser + + get "/drafts/:id", PostController, :draft + get "/posts/:id", PostController, :show + get "/posts", PostController, :index + + get "/", PageController, :home + end +``` + +```elixir +# lib/hello_web/controllers/posts_controller.ex + +defmodule HelloWeb.PostController do + use HelloWeb, :controller + + alias Hello.Document + @path "documents/**/*.md" + paths = Path.wildcard(@path) + @paths_hash :erlang.md5(paths) + for path <- paths, do: @external_resource(path) + @posts Document.list() + + def __mix_recompile__?(), do: @path |> Path.wildcard() |> :erlang.md5() != @paths_hash + + def index(conn, _params) do + render(conn, :index, posts: @posts) + end + + def show(conn, %{"id" => id}) do + assigns = [ + post: :hello |> :code.priv_dir() |> Path.join("static/posts/#{id}.html") |> File.read!() + ] + + render(conn, :show, assigns) + end + + def drafts(conn, %{"id" => id}) do + config = Application.get_env(:pandoc, :hello) + + opts = [ + cd: config[:cd] || File.cwd!() + ] + + filename = List.keyfind(@posts, id, 0) |> elem(1) |> Map.get(:filename) + path = Path.join("_drafts", filename) + + render(conn, :show, post: "pandoc" |> System.cmd([path], opts) |> elem(0)) + end +``` + +```elixir +# lib/hello/document.ex + +defmodule Stasis.Document do + require Logger + + @ext ".md" + @pattern Application.compile_env(:pandoc, [:hello, :pattern]) + + def list() do + "documents" + |> Path.join(@pattern) + |> Path.wildcard() + |> Enum.map(fn path -> {Path.basename(path), path} end) + |> Enum.sort(fn {basename_a, _}, {basename_b, _} -> basename_a < basename_b end) + |> Enum.reduce([], fn {filename, path}, acc -> + id = Path.rootname(filename, @ext) + data = if "_drafts" in Path.split(path), do: %{:draft, true}, else: %{} + + [{id, data} | acc] + end) + end +``` + +```elixir +# lib/hello_web/controllers/post_html/index.html.heex + +<%= for {id, data} <- @posts do %> +

+ <.link href={href(Path.rootname(filename), data[:draft])} method="get"> + <%= id %> + +

+<% end %> +``` + +```elixir +# lib/hello_web/controllers/post_html/show.html.heex + +<%= raw(@post) %> ``` Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)