Add importing html and save it to Article

Additionally defines a wizard logic which is partially unused yet.
This commit is contained in:
Thelonius Kort
2022-12-29 16:43:52 +01:00
parent 60a22d011e
commit b7bd9195b6
24 changed files with 452 additions and 25 deletions

View File

@ -0,0 +1,52 @@
defmodule Outlook.InternalTree.Html do
alias Outlook.InternalTree.InternalNode
alias Outlook.InternalTree.TranslationUnit
def to_html([ %InternalNode{type: :element} = node | rest]) do
attr_string = Map.put(node.attributes, :uuid, node.uuid)
|> Enum.map_join(" ", fn {k,v} -> "#{k}=\"#{v}\"" end)
"<#{node.name} #{attr_string}>" <>
to_html(node.content) <>
"</#{node.name}>" <>
to_html(rest)
end
def to_html([ %InternalNode{type: :text} = node | rest]) do
node.content <> to_html(rest)
end
def to_html([ %InternalNode{type: :comment} = node | rest]) do
"<!--#{node.content}-->" <> to_html(rest)
end
def to_html([ %TranslationUnit{} = tunit | rest]) do
~s(<span class="tunit" uuid="#{tunit.uuid}" tu-status="#{tunit.status}">#{tunit.content}</span>) <> to_html(rest)
end
def to_html([]), do: ""
def to_html_preview([ %InternalNode{type: :element} = node | rest], target_id) do
attr_string = Map.put(node.attributes, :uuid, node.uuid)
|> Enum.map_join(" ", fn {k,v} -> "#{k}=\"#{v}\"" end)
"<#{node.name} #{attr_string}>" <>
to_html_preview(node.content, target_id) <>
"</#{node.name}>" <>
to_html_preview(rest, target_id)
end
def to_html_preview([ %InternalNode{type: :text} = node | rest], target_id) do
~s(<span uuid="#{node.uuid}">#{node.content}</span>) <> to_html_preview(rest, target_id)
end
def to_html_preview([ %InternalNode{type: :comment} = node | rest], target_id) do
~s(<span uuid="#{node.uuid}"><!--#{node.content}--></span>) <> to_html_preview(rest, target_id)
end
def to_html_preview([ %TranslationUnit{} = tunit | rest], target_id) do
~s|<span class="tunit" uuid="#{tunit.uuid}" tu-status="#{tunit.status}" phx-click="select_current_tunit"
phx-value-uuid="#{tunit.uuid}" phx-target="#{target_id}">#{tunit.content}</span>| <> to_html_preview(rest, target_id)
end
def to_html_preview([], _target_id), do: ""
end

View File

@ -0,0 +1,70 @@
defmodule Outlook.InternalTree.Basic do
alias Ecto.UUID
alias Outlook.InternalTree.InternalNode
alias Outlook.InternalTree.TranslationUnit
alias Outlook.InternalTree.Html
@splitmarker "@@translationunit@@"
def set_split_markers([ %InternalNode{type: :text} = textnode | rest ]) do
[ %InternalNode{textnode |
content: String.replace(textnode.content, ~r|([.?!]["'”]?\s*)|u, "\\1#{@splitmarker}")
} | set_split_markers(rest) ]
end
def set_split_markers([ %InternalNode{type: :element} = node | rest ]) do
[ %InternalNode{node | content: set_split_markers(node.content)}
| set_split_markers(rest) ]
end
def set_split_markers([ node | rest ]) do
[ node | set_split_markers(rest) ]
end
def set_split_markers([]), do: []
def partition_textnodes([ %InternalNode{type: :element} = node | rest ]) do
[ %InternalNode{node | content: case get_sibling_collocation(node.content) do
:block -> partition_textnodes(node.content)
:inline -> inline_to_translation_units(node.content)
_ -> node # rare case of only whitespace textnode(s) - does this ever happen?
end
} | partition_textnodes(rest) ]
end
def partition_textnodes([ node | rest ]) do
[ node | partition_textnodes(rest) ]
end
def partition_textnodes([]), do: []
defp inline_to_translation_units(contents) do
contents
# |> Html.strip_attributes # to be implemented
|> Html.to_html()
|> String.split(@splitmarker, trim: true)
|> Enum.map(fn sentence ->
%TranslationUnit{
content: sentence,
status: :untranslated,
uuid: UUID.generate()
}
end
)
end
defp contains_elements?(content) do
end
@doc "Returns just either :block or :inline. Assumes that it doesn't contain both."
def get_sibling_collocation(content) do
content
|> Enum.map(fn node -> node.sibling_with end)
|> Enum.uniq()
|> List.delete(:both)
|> List.first
end
end

View File

@ -0,0 +1,19 @@
defmodule Outlook.Articles.RawInternalTree do
use Ecto.Type
def type, do: :string
def cast([] = tree) do
{:ok, tree}
end
def cast(_), do: :error
def load(tree) when is_binary(tree) do
{:ok, Jason.decode!(tree, keys: :atoms!)}
end
def dump([] = tree ), do: {:ok, Jason.encode!(tree)}
def dump(_), do: :error
end

View File

@ -0,0 +1,29 @@
defmodule Outlook.Articles.RawInternalTreeSchema do
use Ecto.Schema
import Ecto.Changeset
alias Outlook.Articles.RawInternalTree
embedded_schema do
field :tree, RawInternalTree
end
@doc false
def changeset(raw_tree, attrs) do
raw_tree
|> check_sibling_collocation(:tree)
end
def check_sibling_collocation(changeset, field) when is_atom(field) do
validate_change(changeset, field, fn field, value ->
case value do
true ->
[]
false ->
[{field, "html should be useful"}]
end
end)
end
end

View File

@ -0,0 +1,4 @@
defmodule Outlook.InternalTree.TranslationUnit do
@derive Jason.Encoder
defstruct status: :atom, uuid: "", content: ""
end