Packages

Extractly `mix xtra` task to render `EEx` templates with easy access to hexdocs. The Extractly module gives easy access to Elixir metainformation of the application using the extractly package, notably, module and function documentation.

Current section

Files

Jump to
extractly lib extractly toc renderer ast_renderer.ex
Raw

lib/extractly/toc/renderer/ast_renderer.ex

defmodule Extractly.Toc.Renderer.AstRenderer do
@doc ~S"""
Transform a normalized tuple list (that is a list of tuples of the form {n, text})
in which there exists an entry of the form {m, text} for all m betwenn min(n) and
max(n)
Two formats are supported
### The _simple_ `PushList`
where the tuple list is transformed into a linear structural
representation of the different levels by representing opening and closing brackets by
the symbols `:open` and `:close`
iex(1)> render_push_list([{1, "I"}, {3, "I - (i)"}, {1, "II"}, {2, "II 1"}])
["I", :open, :open, "I - (i)", :close, :close, "II", :open, "II 1", :close]
This format is ideal to be transformed into, e.g. an HTML representation
"""
def render_push_list(normalized_tuples, options \\ [])
def render_push_list(normalized_tuples, _options), do: _render_push_list(normalized_tuples, {1, []})
@doc ~S"""
### A structural nested array (extracted from the `PushList`)
iex(2)> render_ast([{1, "I"}, {3, "I - (i)"}, {1, "II"}, {2, "II 1"}])
["I", [["I - (i)"]], "II", ["II 1"]]
"""
def render_ast(normalized_tuples, options \\ [])
def render_ast(normalized_tuples, _options), do:
normalized_tuples
|> _render_push_list({1, []})
# |> IO.inspect
|> _make_tree([])
defp _add_closes_and_reverse(n, push_list)
defp _add_closes_and_reverse(1, push_list), do: Enum.reverse(push_list)
defp _add_closes_and_reverse(n, push_list), do: _add_closes_and_reverse(n-1, [:close|push_list])
defp _render_push_list(tuples, result)
defp _render_push_list([], {n, push_list}), do: _add_closes_and_reverse(n, push_list)
defp _render_push_list([tuple|rest], result), do: _render_push_list(rest, _new_result(tuple, result))
defp _make_tree(push_list, result)
defp _make_tree([], result), do: Enum.reverse(result)
defp _make_tree([:close|rest], result), do: _make_tree(rest, _up_and_reverse([[]|result]))
defp _make_tree([head|rest], result), do: _make_tree(rest, [head|result])
defp _new_result(tuple, result)
defp _new_result({tlevel, text}, {clevel, result}) when tlevel == clevel, do: {clevel, [text|result]}
defp _new_result({tlevel, text}, {clevel, result}) when tlevel > clevel do
{tlevel, [text|_prepend(:open, tlevel-clevel, result)]}
end
defp _new_result({tlevel, text}, {clevel, result}) do
{tlevel, [text|_prepend(:close, clevel-tlevel, result)]}
end
defp _prepend(sym, count, to)
defp _prepend(_, 0, to), do: to
defp _prepend(sym, n, to), do: _prepend(sym, n-1, [sym|to])
defp _up_and_reverse(result)
defp _up_and_reverse([head, :open|result]), do: [head|result]
defp _up_and_reverse([head, text|result]), do: _up_and_reverse([[text|head]|result])
end
# SPDX-License-Identifier: Apache-2.0