defmodule Magma.Matter.Text.Section do
use Magma.Matter, fields: [:main_text]
alias Magma.Concept
alias Magma.Matter.Text
alias Magma.Artefacts.TableOfContents
alias Magma.View
require Logger
@type t :: %__MODULE__{}
@impl true
def artefacts, do: [Magma.Artefacts.Article]
@impl true
def relative_base_path(%__MODULE__{main_text: main_text}) do
Text.relative_base_path(main_text)
end
@impl true
def relative_concept_path(%__MODULE__{} = section) do
section
|> relative_base_path()
|> Path.join("#{concept_name(section)}.md")
end
@impl true
def concept_name(%__MODULE__{name: name, main_text: main_text}) do
"#{main_text.name} - #{name}"
end
@impl true
def concept_title(%__MODULE__{name: name}), do: name
@impl true
def default_description(%__MODULE__{}, abstract: abstract), do: abstract
@impl true
def context_knowledge(
%Concept{subject: %__MODULE__{main_text: %{type: type} = main_text}} = concept
) do
"""
#{super(concept)}
#{Magma.Config.TextType.context_knowledge_transclusion(type)}
#### Outline of the '#{main_text.name}' content #{View.transclude(TableOfContents.default_name(concept), :title)}
""" <>
case Concept.load(main_text.name) do
{:ok, text_concept} ->
View.include_context_knowledge(text_concept)
{:error, error} ->
Logger.warning("error on main text context knowledge extraction: #{inspect(error)}")
""
end
end
@impl true
def prompt_concept_description_title(%__MODULE__{name: name}) do
"Description of the intended content of the '#{name}' section"
end
def new(attrs) when is_list(attrs) do
{:ok, struct(__MODULE__, attrs)}
end
def new(main_text, name) do
new(name: name, main_text: main_text)
end
def new!(attrs) do
case new(attrs) do
{:ok, matter} -> matter
{:error, error} -> raise error
end
end
def new!(main_text, name) do
case new(main_text, name) do
{:ok, matter} -> matter
{:error, error} -> raise error
end
end
@impl true
def extract_from_metadata(_document_name, document_title, metadata) do
{main_text_link, metadata} = Map.pop(metadata, :magma_section_of)
if main_text_link do
with {:ok, main_text_concept} <- Concept.load_linked(main_text_link),
{:ok, matter} <- new(main_text_concept.subject, document_title) do
{:ok, matter, metadata}
end
else
{:error, "magma_section_of missing"}
end
end
def render_front_matter(%__MODULE__{} = section) do
"""
#{super(section)}
magma_section_of: "#{View.link_to(section.main_text)}"
"""
|> String.trim_trailing()
end
end