2019-11-11 00:35:52 +01:00
|
|
|
defmodule Philomena.Textile.Renderer do
|
2019-12-01 18:11:00 +01:00
|
|
|
# todo: belongs in PhilomenaWeb
|
2019-11-11 00:35:52 +01:00
|
|
|
alias Textile.Parser
|
|
|
|
alias Philomena.Images.Image
|
|
|
|
alias Philomena.Repo
|
|
|
|
import Phoenix.HTML
|
|
|
|
import Phoenix.HTML.Link
|
|
|
|
import Ecto.Query
|
|
|
|
|
|
|
|
@parser %Parser{
|
|
|
|
image_transform: &Camo.Image.image_url/1
|
|
|
|
}
|
|
|
|
|
2019-12-19 20:32:12 +01:00
|
|
|
# Kill bogus compile time dependency on ImageView
|
|
|
|
@image_view Module.concat(["PhilomenaWeb.ImageView"])
|
|
|
|
|
2019-12-01 18:11:00 +01:00
|
|
|
def render_one(post, conn) do
|
|
|
|
hd(render_collection([post], conn))
|
2019-11-11 00:35:52 +01:00
|
|
|
end
|
|
|
|
|
2019-12-01 18:11:00 +01:00
|
|
|
def render_collection(posts, conn) do
|
2019-11-11 00:35:52 +01:00
|
|
|
parsed =
|
|
|
|
posts
|
|
|
|
|> Enum.map(fn post ->
|
2019-11-18 02:33:50 +01:00
|
|
|
Parser.parse(@parser, post.body)
|
2019-11-11 00:35:52 +01:00
|
|
|
end)
|
|
|
|
|
|
|
|
images =
|
|
|
|
parsed
|
|
|
|
|> Enum.flat_map(fn tree ->
|
|
|
|
tree
|
|
|
|
|> Enum.flat_map(fn
|
|
|
|
{:text, text} ->
|
|
|
|
[text]
|
|
|
|
_ ->
|
|
|
|
[]
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
|> find_images
|
|
|
|
|
|
|
|
parsed
|
|
|
|
|> Enum.map(fn tree ->
|
|
|
|
tree
|
|
|
|
|> Enum.map(fn
|
|
|
|
{:text, text} ->
|
|
|
|
text
|
|
|
|
|> replacement_entities()
|
2019-12-01 18:11:00 +01:00
|
|
|
|> replacement_images(conn, images)
|
2019-11-11 00:35:52 +01:00
|
|
|
|
|
|
|
{_k, markup} ->
|
|
|
|
markup
|
|
|
|
end)
|
|
|
|
|> Enum.join()
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp replacement_entities(t) do
|
|
|
|
t
|
|
|
|
|> String.replace("->", "→")
|
|
|
|
|> String.replace("--", "—")
|
|
|
|
|> String.replace("...", "…")
|
|
|
|
|> String.replace(~r|(\s)-(\s)|, "\\1—\\2")
|
|
|
|
|> String.replace("(tm)", "&tm;")
|
|
|
|
|> String.replace("(c)", "©")
|
|
|
|
|> String.replace("(r)", "®")
|
|
|
|
|> String.replace("'", "’")
|
|
|
|
end
|
|
|
|
|
2019-12-01 18:11:00 +01:00
|
|
|
defp replacement_images(t, conn, images) do
|
2019-11-11 00:35:52 +01:00
|
|
|
t
|
|
|
|
|> String.replace(~r|>>(\d+)([pts])?|, fn match ->
|
|
|
|
# Stupid, but the method doesn't give us capture group information
|
|
|
|
match_data = Regex.run(~r|>>(\d+)([pts])?|, match, capture: :all_but_first)
|
|
|
|
[image_id | rest] = match_data
|
|
|
|
image = images[String.to_integer(image_id)]
|
|
|
|
|
|
|
|
case [image | rest] do
|
|
|
|
[nil, _] ->
|
|
|
|
match
|
|
|
|
|
|
|
|
[nil] ->
|
|
|
|
match
|
|
|
|
|
|
|
|
[image, "p"] ->
|
2019-12-19 20:32:12 +01:00
|
|
|
Phoenix.View.render(@image_view, "_image_target.html", image: image, size: :medium, conn: conn)
|
2019-11-11 00:35:52 +01:00
|
|
|
|> safe_to_string()
|
|
|
|
|
|
|
|
[image, "t"] ->
|
2019-12-19 20:32:12 +01:00
|
|
|
Phoenix.View.render(@image_view, "_image_target.html", image: image, size: :small, conn: conn)
|
2019-11-11 00:35:52 +01:00
|
|
|
|> safe_to_string()
|
|
|
|
|
|
|
|
[image, "s"] ->
|
2019-12-19 20:32:12 +01:00
|
|
|
Phoenix.View.render(@image_view, "_image_target.html", image: image, size: :thumb_small, conn: conn)
|
2019-11-11 00:35:52 +01:00
|
|
|
|> safe_to_string()
|
|
|
|
|
|
|
|
[image] ->
|
|
|
|
link(">>#{image.id}", to: "/#{image.id}")
|
|
|
|
|> safe_to_string()
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
defp find_images(text_segments) do
|
2019-12-23 00:42:07 +01:00
|
|
|
text_segments
|
|
|
|
|> Enum.flat_map(fn t ->
|
|
|
|
Regex.scan(~r|>>(\d+)|, t, capture: :all_but_first)
|
|
|
|
|> Enum.map(fn [first] -> String.to_integer(first) end)
|
|
|
|
end)
|
|
|
|
|> find_image_ids()
|
|
|
|
end
|
2019-11-11 00:35:52 +01:00
|
|
|
|
2019-12-23 00:42:07 +01:00
|
|
|
defp find_image_ids([]), do: %{}
|
|
|
|
defp find_image_ids(image_ids) do
|
2019-11-11 00:35:52 +01:00
|
|
|
Image
|
|
|
|
|> where([i], i.id in ^image_ids)
|
|
|
|
|> where([i], i.hidden_from_users == false)
|
2019-12-23 00:42:07 +01:00
|
|
|
|> join(:left, [i], _ in assoc(i, :tags))
|
|
|
|
|> preload([_i, t], tags: t)
|
2019-11-11 00:35:52 +01:00
|
|
|
|> Repo.all()
|
|
|
|
|> Map.new(fn image -> {image.id, image} end)
|
|
|
|
end
|
2019-12-19 08:02:08 +01:00
|
|
|
end
|