defmodule AshHqWeb.Pages.Docs do @moduledoc "The page for showing documentation" use Surface.Component alias AshHqWeb.Components.{CalloutText, DocSidebar, RightNav, Tag} alias AshHqWeb.DocRoutes alias Phoenix.LiveView.JS require Logger prop(change_versions, :event, required: true) prop(selected_versions, :map, required: true) prop(libraries, :list, default: []) prop(uri, :string) prop(sidebar_state, :map, required: true) prop(collapse_sidebar, :event, required: true) prop(expand_sidebar, :event, required: true) prop(library, :any) prop(extension, :any) prop(docs, :any) prop(library_version, :any) prop(guide, :any) prop(doc_path, :list, default: []) prop(dsls, :list, default: []) prop(dsl, :any) prop(options, :list, default: []) prop(module, :any) prop(remove_version, :event) prop(add_version, :event) prop(change_version, :event) data(positional_options, :list) @spec render(any) :: Phoenix.LiveView.Rendered.t() def render(assigns) do ~F"""
){{mix_dep:.*}}(?!<\/code>)/, fn text ->
try do
"{{mix_dep:" <> library = String.trim_trailing(text, "}}")
"#{render_mix_dep(assigns, library, text)}
"
rescue
e ->
Logger.error(
"Invalid link #{inspect(e)}\n#{Exception.format_stacktrace(__STACKTRACE__)}"
)
text
end
end)
end
defp render_mix_dep(assigns, library, source) do
library =
Enum.find(assigns[:libraries], &(&1.name == library)) ||
raise "No such library in link: #{source}"
selected_versions = assigns[:selected_versions]
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 ->
nil
version ->
version
end
end
case Version.parse(version.version) do
{:ok, %Version{pre: pre, build: build}}
when not is_nil(pre) or not is_nil(build) ->
~s({:#{library.name}, "~> #{version}"})
{:ok, %Version{major: major, minor: minor, patch: 0}} ->
~s({:#{library.name}, "~> #{major}.#{minor}"})
{:ok, version} ->
~s({:#{library.name}, "~> #{version}"})
end
end
defp render_links(docs, assigns) do
String.replace(docs, ~r/(?!){{link:[^}]*}}(?!<\/code>)/, fn text ->
try do
"{{link:" <> rest = String.trim_trailing(text, "}}")
[library, type, item | rest] = String.split(rest, ":")
render_link(assigns, library, type, item, text, rest)
rescue
e ->
Logger.error(
"Invalid link #{inspect(e)}\n#{Exception.format_stacktrace(__STACKTRACE__)}"
)
text
end
end)
end
defp render_link(assigns, library, type, item, source, rest) do
library =
Enum.find(assigns[:libraries], &(&1.name == library)) ||
raise "No such library in link: #{source}"
selected_versions = assigns[:selected_versions]
version =
if selected_versions[library.id] in ["latest", nil, ""] do
Enum.find(library.versions, &String.contains?(&1.version, ".")) ||
AshHqWeb.Helpers.latest_version(library)
else
case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do
nil ->
nil
version ->
version
end
end
if is_nil(version) do
raise "no version for library"
else
case type do
"guide" ->
guide =
Enum.find(version.guides, &(&1.name == item)) ||
raise "No such guide in link: #{source}"
text = Enum.at(rest, 0) || item
"""
#{text}
"""
"dsl" ->
path =
item
|> String.split(~r/[\/\.]/)
name =
path
|> Enum.join(".")
route = Enum.map_join(path, "/", &DocRoutes.sanitize_name/1)
"""
#{name}
"""
"option" ->
path =
item
|> String.split(~r/[\/\.]/)
name = Enum.join(path, ".")
dsl_path = path |> :lists.droplast() |> Enum.map_join("/", &DocRoutes.sanitize_name/1)
anchor = path |> Enum.map_join("/", &DocRoutes.sanitize_name/1)
"""
#{name}
"""
"module" ->
"""
#{item}
"""
"extension" ->
"""
#{item}
"""
type ->
raise "unimplemented link type #{inspect(type)} in #{source}"
end
end
end
end