Skip to content

Commit

Permalink
Merge pull request #6 from digitalonboarding/jc/warnings
Browse files Browse the repository at this point in the history
Jc/warnings
  • Loading branch information
crossman authored Mar 13, 2019
2 parents c6572fc + bfd447a commit a7b7e3d
Show file tree
Hide file tree
Showing 9 changed files with 614 additions and 247 deletions.
5 changes: 5 additions & 0 deletions .formatter.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[
import_deps: [],
inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"],
subdirectories: []
]
23 changes: 12 additions & 11 deletions lib/draft.ex
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ defmodule Draft do
input
|> Map.get("blocks")
|> Enum.reduce([], &group_list_items/2)
|> Enum.map(&(process_block(&1, entity_map, context)))
|> Enum.map(&process_block(&1, entity_map, context))
|> Enum.join("")
end

Expand All @@ -37,21 +37,22 @@ defmodule Draft do
[%{"type"=>"unordered-list","data"=>%{"children"=>[%{"key"=>"1","text"=>"Hello","type"=>"unordered-list-item","depth"=>0,"inlineStyleRanges"=>[],"entityRanges"=>[],"data"=>%{}}]}}]
"""

defp group_list_items(block, acc) do
def group_list_items(block, acc) do
case block["type"] do
type when type in ["unordered-list-item", "ordered-list-item"] ->
list_type = String.replace(block["type"], "-item", "")

with {last_item, all_but_last_item} when not is_nil(last_item) <- List.pop_at(acc, length(acc) - 1),
type when type == list_type <- Map.get(last_item, "type")
#FIXME: this ignores depth
do
all_but_last_item ++ [add_block_item_to_previous_list(last_item, block)]
else
_ -> acc ++ [%{"type" => list_type,
"data" => %{"children" => [block]}}]
# FIXME: this ignores depth
with {last_item, all_but_last_item} when not is_nil(last_item) <-
List.pop_at(acc, length(acc) - 1),
type when type == list_type <- Map.get(last_item, "type") do
all_but_last_item ++ [add_block_item_to_previous_list(last_item, block)]
else
_ -> acc ++ [%{"type" => list_type, "data" => %{"children" => [block]}}]
end
_ -> acc ++ [block]

_ ->
acc ++ [block]
end
end

Expand Down
58 changes: 32 additions & 26 deletions lib/draft/block.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,59 @@ defmodule Draft.Block do
"<br>"
end

def process_block(%{"type" => "header-" <> header,
"text" => text} = block,
entity_map, context) do
tag = header_tags[header]
def process_block(
%{"type" => "header-" <> header, "text" => text} = block,
entity_map,
context
) do
tag = header_tags()[header]
"<#{tag}>#{apply_ranges(block, entity_map, context)}</#{tag}>"
end

def process_block(%{"type" => "blockquote",
"text" => text} = block,
entity_map, context) do
def process_block(%{"type" => "blockquote", "text" => text} = block, entity_map, context) do
"<blockquote>#{apply_ranges(block, entity_map, context)}</blockquote>"
end

def process_block(%{"type" => "unstyled",
"text" => text} = block,
entity_map, context) do
def process_block(%{"type" => "unstyled", "text" => text} = block, entity_map, context) do
"<p>#{apply_ranges(block, entity_map, context)}</p>"
end

def process_block(%{"type" => "unordered-list",
"data" => %{"children" => children}},
entity_map, context) do
"<ul>#{Enum.map(children, &(process_block(&1, entity_map, context))) |> Enum.join("")}</ul>"
def process_block(
%{"type" => "unordered-list", "data" => %{"children" => children}},
entity_map,
context
) do
"<ul>#{Enum.map(children, &process_block(&1, entity_map, context)) |> Enum.join("")}</ul>"
end

def process_block(%{"type" => "ordered-list",
"data" => %{"children" => children}},
entity_map, context) do
"<ol>#{Enum.map(children, &(process_block(&1, entity_map, context))) |> Enum.join("")}</ol>"
def process_block(
%{"type" => "ordered-list", "data" => %{"children" => children}},
entity_map,
context
) do
"<ol>#{Enum.map(children, &process_block(&1, entity_map, context)) |> Enum.join("")}</ol>"
end

def process_block(%{"type" => "ordered-list-item",
"text" => text} = block,
entity_map, context) do
def process_block(
%{"type" => "ordered-list-item", "text" => text} = block,
entity_map,
context
) do
"<li>#{apply_ranges(block, entity_map, context)}</li>"
end

def process_block(%{"type" => "unordered-list-item",
"text" => text} = block,
entity_map, context) do
def process_block(
%{"type" => "unordered-list-item", "text" => text} = block,
entity_map,
context
) do
"<li>#{apply_ranges(block, entity_map, context)}</li>"
end

def header_tags do
%{
"one" => "h1",
"two" => "h2",
"one" => "h1",
"two" => "h2",
"three" => "h3"
}
end
Expand Down
45 changes: 28 additions & 17 deletions lib/draft/ranges.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ defmodule Draft.Ranges do
|> DraftTree.process_tree(fn text, styles, key ->
cond do
!is_nil(styles) ->
css = styles
|> Enum.map(fn style -> process_style(style, context) end)
|> Enum.join(" ")
css =
styles
|> Enum.map(fn style -> process_style(style, context) end)
|> Enum.join(" ")

"<span style=\"#{css}\">#{text}</span>"

Expand All @@ -38,24 +39,26 @@ defmodule Draft.Ranges do
"font-style: italic;"
end

def process_entity(%{"type"=>"LINK","mutability"=>"MUTABLE","data"=>%{"url"=>url}}, text, _) do
def process_entity(
%{"type" => "LINK", "mutability" => "MUTABLE", "data" => %{"url" => url}},
text,
_
) do
"<a href=\"#{url}\">#{text}</a>"
end

defp group_style_ranges(ranges) do
ranges
|> Enum.group_by(fn range -> {range["offset"], range["length"]} end)
|> Enum.map(fn {{offset, length}, ranges} ->
%{"offset" => offset,
"length" => length,
"styles" => ranges |> Enum.map(&(&1["style"]))}
%{"offset" => offset, "length" => length, "styles" => ranges |> Enum.map(& &1["style"])}
end)
end

@doc """
Cuts up multiple potentially overlapping ranges into more mutually exclusive ranges
"""
defp divvy_style_ranges(style_ranges, entity_ranges) do
def divvy_style_ranges(style_ranges, entity_ranges) do
Enum.map(style_ranges, fn style_range ->
ranges_to_points(entity_ranges ++ style_ranges)
|> Enum.filter(fn point ->
Expand All @@ -64,13 +67,19 @@ defmodule Draft.Ranges do
|> Enum.reduce([style_range], fn point, acc ->
{already_split, [main]} = Enum.split(acc, length(acc) - 1)

already_split ++ [
%{"style" => style_range["style"],
"offset" => main["offset"],
"length" => point - main["offset"]},
%{"style" => style_range["style"],
"offset" => point,
"length" => main["length"] - (point - main["offset"])}]
already_split ++
[
%{
"style" => style_range["style"],
"offset" => main["offset"],
"length" => point - main["offset"]
},
%{
"style" => style_range["style"],
"offset" => point,
"length" => main["length"] - (point - main["offset"])
}
]
end)
end)
|> List.flatten()
Expand All @@ -82,8 +91,10 @@ defmodule Draft.Ranges do
cond do
range1["offset"] != range2["offset"] ->
range1["offset"] < range2["offset"]

range1["length"] != range2["length"] ->
range1["length"] >= range2["length"]

true ->
is_nil(range2["styles"])
end
Expand All @@ -94,8 +105,8 @@ defmodule Draft.Ranges do
Enum.reduce(ranges, [], fn range, acc ->
acc ++ [range["offset"], range["offset"] + range["length"]]
end)
|> Enum.uniq
|> Enum.sort
|> Enum.uniq()
|> Enum.sort()
end
end
end
Expand Down
60 changes: 42 additions & 18 deletions lib/draft/tree.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,65 @@ defmodule DraftTree do
end

defp insert_node(tree, range, text) do
first_included_child = Enum.find(tree.children, fn child ->
range["offset"] >= child.offset &&
(range["length"] + range["offset"]) <= (child.length + child.offset)
end)
first_included_child =
Enum.find(tree.children, fn child ->
range["offset"] >= child.offset &&
range["length"] + range["offset"] <= child.length + child.offset
end)

case first_included_child do
nil ->
Map.put(tree, :children, tree.children ++ [
%Node{
length: range["length"],
offset: range["offset"],
styles: range["styles"],
key: range["key"],
text: String.slice(text, range["offset"], range["length"])
}
])
Map.put(
tree,
:children,
tree.children ++
[
%Node{
length: range["length"],
offset: range["offset"],
styles: range["styles"],
key: range["key"],
text: String.slice(text, range["offset"], range["length"])
}
]
)

child ->
{all_but_last_item, _} = Enum.split(tree.children, length(tree.children) - 1)

Map.put(tree, :children, all_but_last_item ++ [
insert_node(child, range, text)
])
Map.put(
tree,
:children,
all_but_last_item ++
[
insert_node(child, range, text)
]
)
end
end

def process_tree(%{children: [], key: key, styles: styles, text: text}, processor) do
processor.(text, styles, key)
end

def process_tree(%{children: children, key: key, styles: styles, offset: offset, length: length, text: text}, processor) do
def process_tree(
%{
children: children,
key: key,
styles: styles,
offset: offset,
length: length,
text: text
},
processor
) do
Enum.map(children, fn child -> {child, process_tree(child, processor)} end)
|> Enum.reverse()
|> Enum.reduce(text, fn {child, child_text}, acc ->
{start, rest} = String.split_at(acc, child.offset - offset)
{_, finish} = String.split_at(rest, child.offset - offset + child.length - String.length(start))

{_, finish} =
String.split_at(rest, child.offset - offset + child.length - String.length(start))

start <> child_text <> finish
end)
Expand Down
14 changes: 8 additions & 6 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ defmodule Draft.Mixfile do
use Mix.Project

def project do
[app: :draft,
version: "0.1.0",
elixir: "~> 1.3",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
deps: deps()]
[
app: :draft,
version: "0.1.0",
elixir: "~> 1.3",
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
deps: deps()
]
end

# Configuration for the OTP application
Expand Down
Loading

0 comments on commit a7b7e3d

Please sign in to comment.