ash_hq/lib/ash_hq_web/helpers.ex

154 lines
4.9 KiB
Elixir
Raw Normal View History

defmodule AshHqWeb.Helpers do
@moduledoc "Simple helpers for doc liveviews"
2022-09-13 11:36:28 +12:00
require Logger
def latest_version(library) do
case library.versions do
[] ->
nil
versions ->
Enum.min(versions, &(Version.compare(&1.version, &2.version) != :lt))
end
end
2022-09-13 11:36:28 +12:00
def source_link(%AshHq.Docs.Module{file: file}, library, library_version) do
"https://github.com/#{library.repo_org}/#{library.name}/tree/v#{library_version.version}/#{file}"
2022-09-13 11:36:28 +12:00
end
def source_link(%AshHq.Docs.MixTask{file: file}, library, library_version) do
"https://github.com/#{library.repo_org}/#{library.name}/tree/v#{library_version.version}/#{file}"
end
2022-09-13 11:36:28 +12:00
def source_link(%AshHq.Docs.Function{file: file, line: line}, library, library_version) do
if line do
"https://github.com/#{library.repo_org}/#{library.name}/tree/v#{library_version.version}/#{file}#L#{line}"
2022-09-13 11:36:28 +12:00
else
"https://github.com/#{library.repo_org}/#{library.name}/tree/v#{library_version.version}/#{file}"
2022-09-13 11:36:28 +12:00
end
end
def render_replacements(libraries, selected_versions, docs) do
Spark.DocIndex.render_replacements(
docs,
%{
2022-12-11 08:45:23 +13:00
code_block: ~r/<code class=".*elixir.*">[\s\S]*?(?=<\/code>)/
},
fn
:mix_dep, %{text: text, library: library}, context ->
dep = render_mix_dep(libraries, library, selected_versions, text)
if context == :code_block do
dep
else
"<pre><code>#{dep}</code></pre>"
end
:link, %{type: "option", item: item, name_override: name, library: library}, _ ->
path =
item
|> String.trim_leading("/")
|> String.split(~r/[\/\.]/)
|> Enum.drop(1)
name = name || join_path(path)
dsl_path = path |> :lists.droplast() |> Enum.map_join("/", &sanitize_name/1)
anchor = path |> List.last() |> sanitize_name()
2022-11-16 07:47:25 +13:00
~s(<a href="/docs/dsl/#{library}/#{version(libraries, library, selected_versions)}/#{dsl_path}##{anchor}">#{name}</a>)
:link, %{type: "dsl", item: item, name_override: name, library: library}, _ ->
path =
item
|> String.trim_leading("/")
|> String.split(~r/[\/\.]/)
|> Enum.drop(1)
dsl_path = Enum.map_join(path, "/", &sanitize_name/1)
name = name || join_path(path)
2022-11-16 07:47:25 +13:00
~s(<a href="/docs/dsl/#{library}/#{version(libraries, library, selected_versions)}/#{dsl_path}">#{name}</a>)
:link, %{type: "extension", item: item, name_override: name, library: library}, _ ->
2022-11-16 07:47:25 +13:00
~s(<a href="/docs/dsl/#{library}/#{version(libraries, library, selected_versions)}/#{sanitize_name(item)}">#{name || item}</a>)
:link, %{type: "guide", item: item, name_override: name, library: library}, _ ->
2022-11-16 07:47:25 +13:00
~s(<a href="/docs/guides/#{library}/#{version(libraries, library, selected_versions)}/#{sanitize_name(item)}">#{name || item}</a>)
:link, %{type: "module", item: item, name_override: name, library: library}, _ ->
2022-11-16 07:47:25 +13:00
~s(<a href="/docs/module/#{library}/#{version(libraries, library, selected_versions)}/#{sanitize_name(item)}">#{name || item}</a>)
:link, %{type: "library", name_override: name, library: library}, _ ->
2022-11-16 07:47:25 +13:00
~s(<a href="/docs/#{library}/#{version(libraries, library, selected_versions)}">#{name || library}</a>)
_, %{text: text}, _ ->
raise "No link handler for: `#{text}`"
end
)
end
2022-11-16 07:47:25 +13:00
defp version(libraries, library, selected_versions) do
libraries
|> Enum.find(&(&1.name == library))
|> case do
nil ->
"latest"
library ->
case selected_versions[library.id] do
empty when empty in [nil, ""] ->
"latest"
id ->
Enum.find(library.versions, &(&1.id == id)).version
end
end
rescue
_ ->
"latest"
end
defp join_path(path) do
Enum.join(path, " > ")
end
defp sanitize_name(name) do
String.downcase(String.replace(name, ~r/[^A-Za-z0-9_]/, "-"))
2022-09-13 11:36:28 +12:00
end
defp render_mix_dep(libraries, library, selected_versions, source) do
library =
Enum.find(libraries, &(&1.name == library)) ||
raise "No such library in link: #{source}"
version =
if selected_versions[library.id] == "latest" do
AshHqWeb.Helpers.latest_version(library)
else
case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do
nil ->
AshHqWeb.Helpers.latest_version(library)
2022-09-13 11:36:28 +12:00
version ->
version
end
end
if !version do
raise "No such library in link: #{source}"
end
2022-09-13 11:36:28 +12:00
case Version.parse(version.version) do
{:ok, %Version{pre: pre, build: build}}
when pre != [] or not is_nil(build) ->
2022-09-13 11:36:28 +12:00
~s({:#{library.name}, "~> #{version.version}"})
{:ok, %Version{major: major, minor: minor}} ->
2022-09-13 11:36:28 +12:00
~s({:#{library.name}, "~> #{major}.#{minor}"})
end
end
end