Packages
nldoc_conversion_reader_tiptap
1.0.0
2.1.1
2.1.0
2.0.1
1.2.40
1.2.39
1.2.38
1.2.37
1.2.36
1.2.35
1.2.34
1.2.33
1.2.32
1.2.31
1.2.30
1.2.29
1.2.28
1.2.27
1.2.26
1.2.25
1.2.24
1.2.23
1.2.22
1.2.21
1.2.20
1.2.19
1.2.18
1.2.17
1.2.16
1.2.15
1.2.14
1.2.13
1.2.12
1.2.11
1.2.10
1.2.9
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
Logic for reading Tiptap format to NLdoc Spec.
Current section
Files
Jump to
Current section
Files
lib/nldoc/conversion/reader/tiptap.ex
defmodule NLdoc.Conversion.Reader.Tiptap do
@moduledoc """
Reader for convert_elementing Tiptap elements to Spec Resources.
"""
alias NLdoc.Conversion.Reader.Tiptap.{Attribute, Mark}
alias NLdoc.Spec.{
BlockQuotation,
DefinitionDetails,
DefinitionList,
DefinitionTerm,
Document,
Heading,
Image,
Link,
ListItem,
OrderedList,
Paragraph,
Preformatted,
Table,
TableCell,
TableHeader,
TableRow,
Text,
UnorderedList
}
# TODO: Support descriptors
# This defines functions to be generated in the for-loops below.
#
# This is a tuple in format:
# 1. Element name in Tiptap.
# 2. Struct from Spec.
# 3. Attributes as keyword list in format {spec_attribute: tiptap_attribute}
# where spec_attribute is an atom and tiptap_attribute is a string.
@element_mappings [
{"doc", Document, [id: "id", assets: "assets"]},
# TODO: Support attribute caption
{"image", Image, [id: "id", source: "assetId", alternative_text: "alt"]},
# TODO: Support attributes cite, caption/footer
{"blockquote", BlockQuotation, [id: "id"]},
{"codeBlock", Preformatted, [id: "id"]},
{"heading", Heading, [id: "id", level: "level"]},
# TODO: Support attributes style type, reversed
{"orderedList", OrderedList, [id: "id", start: "start"]},
# TODO: Support attribute style type
{"bulletList", UnorderedList, [id: "id"]},
{"listItem", ListItem, [id: "id"]},
# TODO: Support attribute caption
{"table", Table, [id: "id"]},
{"tableRow", TableRow, [id: "id"]},
{"tableCell", TableCell, [id: "id", rowspan: "rowspan", colspan: "colspan"]},
# TODO: Support attributes abbreviation, scope
{"tableHeader", TableHeader, [id: "id", rowspan: "rowspan", colspan: "colspan"]},
{"definitionList", DefinitionList, [id: "id"]},
{"definitionTerm", DefinitionTerm, [id: "id"]},
{"definitionDetails", DefinitionDetails, [id: "id"]},
{"paragraph", Paragraph, [id: "id"]},
# Custom cases, will generate &convert_element/1 functions that won't be used.
# Used for setting the attributes.
{"_text", Text, [id: "id"]},
{"_link", Link, [id: "id", uri: "href", purpose: "purpose"]}
]
@type tiptap_attribute_value :: String.t() | number() | boolean()
@type tiptap_attribute :: {String.t(), tiptap_attribute_value()}
@doc """
Converts Tiptap document to a NLdoc document.
"""
@spec convert(map()) :: Document.t()
def convert(element = %{"type" => "doc"}),
do: element |> convert_element() |> hd()
@spec convert_element(map()) :: [NLdoc.Spec.object()]
defp convert_element(%{"type" => "text", "text" => text, "marks" => marks})
when is_binary(text) and text !== "" and is_list(marks),
do: %Text{text: text} |> Mark.apply(marks) |> post_process()
for {tiptap_type, struct_module, mappings} <- @element_mappings,
not String.starts_with?(tiptap_type, "_") do
if Map.has_key?(struct_module.__struct__(), :children) do
defp convert_element(element = %{"type" => unquote(tiptap_type)}) do
children =
element
|> Map.get("content", [])
|> Enum.flat_map(&convert_element/1)
%unquote(struct_module){}
|> Map.put(:children, children)
|> Attribute.apply(element |> Map.get("attrs", %{}), unquote(mappings))
|> post_process()
end
else
defp convert_element(element = %{"type" => unquote(tiptap_type)}),
do:
%unquote(struct_module){}
|> Attribute.apply(element |> Map.get("attrs", %{}), unquote(mappings))
|> post_process()
end
end
# Unsupported element
defp convert_element(_),
do: []
@spec post_process(t) :: [t] when t: term()
defp post_process(element),
do: element |> List.wrap()
end