Skip to content

Commit

Permalink
Deprecate to/from_ansidata in favour of to/from_chardata
Browse files Browse the repository at this point in the history
because these functions don't actually work with IO.ANSI.ansidata.
  • Loading branch information
fuelen committed Jul 21, 2024
1 parent 30f6093 commit d4bec69
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 82 deletions.
8 changes: 4 additions & 4 deletions lib/owl/box.ex
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ defmodule Owl.Box do
...> |> Owl.Data.tag(:green)
...> |> Owl.Box.new(title: Owl.Data.tag("Red!", :red))
...> |> Owl.Data.tag(:cyan)
...> |> Owl.Data.to_ansidata()
...> |> Owl.Data.to_chardata()
...> |> to_string()
\"""
\e[36m┌─\e[31mRed!\e[36m────┐\e[39m
Expand All @@ -116,7 +116,7 @@ defmodule Owl.Box do
...> |> Owl.Data.tag(:green)
...> |> Owl.Box.new(title: Owl.Data.tag("Red!", :red))
...> |> Owl.Data.tag(:cyan)
...> |> Owl.Data.to_ansidata()
...> |> Owl.Data.to_chardata()
...> |> to_string()
\"""
\e[36m┌─\e[31mRed!\e[36m────┐\e[39m
Expand All @@ -131,7 +131,7 @@ defmodule Owl.Box do
...> border_style: :double,
...> border_tag: :cyan
...> )
...> |> Owl.Data.to_ansidata()
...> |> Owl.Data.to_chardata()
...> |> to_string()
\"""
\e[36m╔\e[39m\e[36m══════════════════\e[39m\e[36m╗\e[39m
Expand All @@ -148,7 +148,7 @@ defmodule Owl.Box do
...> border_style: :double,
...> border_tag: :cyan
...> )
...> |> Owl.Data.to_ansidata()
...> |> Owl.Data.to_chardata()
...> |> to_string()
\"""
\e[36m╔\e[39m\e[36m═\e[39mGreeting!\e[36m════════\e[39m\e[36m╗\e[39m
Expand Down
59 changes: 35 additions & 24 deletions lib/owl/data.ex
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
defmodule Owl.Data do
@moduledoc """
A set of functions for `t:iodata/0` with [tags](`Owl.Tag`).
A set of functions for `t:chardata/0` with [tags](`Owl.Tag`).
"""

alias Owl.Data.Sequence

@typedoc """
A recursive data type that is similar to `t:iodata/0`, but additionally supports `t:Owl.Tag.t/1`.
A recursive data type that is similar to `t:chardata/0`, but additionally supports `t:Owl.Tag.t/1`.
Can be printed using `Owl.IO.puts/2`.
"""
Expand Down Expand Up @@ -94,7 +94,7 @@ defmodule Owl.Data do
iex> ["Hello ", Owl.Data.tag("world", :red), ["!"]] |> Owl.Data.untag()
["Hello ", "world", ["!"]]
"""
@spec untag(t()) :: iodata()
@spec untag(t()) :: IO.chardata()
def untag(data) when is_list(data) do
Enum.map(data, &untag_child/1)
end
Expand Down Expand Up @@ -227,8 +227,8 @@ defmodule Owl.Data do
iex> ["first\\nsecond\\n", Owl.Data.tag("third\\nfourth", :red)]
...> |> Owl.Data.lines()
...> |> Owl.Data.unlines()
...> |> Owl.Data.to_ansidata()
Owl.Data.to_ansidata(["first\\nsecond\\n", Owl.Data.tag("third\\nfourth", :red)])
...> |> Owl.Data.to_chardata()
Owl.Data.to_chardata(["first\\nsecond\\n", Owl.Data.tag("third\\nfourth", :red)])
"""
@spec unlines([t()]) :: [t()]
def unlines(data) do
Expand Down Expand Up @@ -258,16 +258,15 @@ defmodule Owl.Data do
end

@doc ~S"""
Transforms data to `t:IO.ANSI.ansidata/0` format which can be consumed by `IO` module.
Transforms data to `t:chardata/0` format which can be consumed by `IO` module.
## Examples
iex> "hello" |> Owl.Data.tag(:red) |> Owl.Data.to_ansidata()
iex> "hello" |> Owl.Data.tag(:red) |> Owl.Data.to_chardata()
[[[[[] | "\e[31m"], "hello"] | "\e[39m"] | "\e[0m"]
"""
@spec to_ansidata(t()) :: IO.ANSI.ansidata()
def to_ansidata(data) do
@spec to_chardata(t()) :: IO.chardata()
def to_chardata(data) do
# combination of lines + unlines is needed in order to break background and do not spread it to the end of the line
data
|> lines()
Expand All @@ -276,6 +275,12 @@ defmodule Owl.Data do
|> IO.ANSI.format()
end

@doc false
@deprecated "Use `Owl.Data.to_chardata/1` instead"
def to_ansidata(data) do
to_chardata(data)
end

defp do_to_ansidata(
%Owl.Tag{sequences: sequences, data: data},
open_tags
Expand Down Expand Up @@ -309,11 +314,11 @@ defmodule Owl.Data do
defp do_to_ansidata(term, _open_tags), do: term

@doc ~S"""
Transforms data from `t:IO.ANSI.ansidata/0`, replacing raw escape sequences with tags (see `tag/2`).
Transforms chardata, replacing raw escape sequences with tags (see `tag/2`).
This makes it possible to use data formatted outside of Owl with other Owl modules, like `Owl.Box`.
The `ansidata` passed to this function must contain escape sequences as separate binaries, not concatenated with other data.
The `data` passed to this function must contain escape sequences as separate binaries, not concatenated with other data.
For instance, the following will work:
iex> Owl.Data.from_ansidata(["\e[31m", "hello"])
Expand All @@ -326,16 +331,22 @@ defmodule Owl.Data do
## Examples
iex> [:red, "hello"] |> IO.ANSI.format() |> Owl.Data.from_ansidata()
iex> [:red, "hello"] |> IO.ANSI.format() |> Owl.Data.from_chardata()
Owl.Data.tag("hello", :red)
"""
@spec from_ansidata(IO.ANSI.ansidata()) :: t()
def from_ansidata(ansidata) do
{data, _open_tags} = do_from_ansidata(ansidata, %{})
@spec from_chardata(IO.chardata()) :: t()
def from_chardata(data) do
{data, _open_tags} = do_from_chardata(data, %{})
data
end

defp do_from_ansidata(binary, open_tags) when is_binary(binary) do
@doc false
@deprecated "Use `Owl.Data.from_chardata/1` instead"
def from_ansidata(data) do
from_chardata(data)
end

defp do_from_chardata(binary, open_tags) when is_binary(binary) do
case Sequence.ansi_to_type(binary) do
:reset ->
{[], %{}}
Expand All @@ -348,21 +359,21 @@ defmodule Owl.Data do
end
end

defp do_from_ansidata(integer, open_tags) when is_integer(integer) do
defp do_from_chardata(integer, open_tags) when is_integer(integer) do
{tag_all(integer, open_tags), open_tags}
end

defp do_from_ansidata([], open_tags) do
defp do_from_chardata([], open_tags) do
{[], open_tags}
end

defp do_from_ansidata([inner], open_tags) do
do_from_ansidata(inner, open_tags)
defp do_from_chardata([inner], open_tags) do
do_from_chardata(inner, open_tags)
end

defp do_from_ansidata([head | tail], open_tags) do
{head, open_tags} = do_from_ansidata(head, open_tags)
{tail, open_tags} = do_from_ansidata(tail, open_tags)
defp do_from_chardata([head | tail], open_tags) do
{head, open_tags} = do_from_chardata(head, open_tags)
{tail, open_tags} = do_from_chardata(tail, open_tags)

case {head, tail} do
{[], _} ->
Expand Down
8 changes: 4 additions & 4 deletions lib/owl/io.ex
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ defmodule Owl.IO do
rest -> puts(rest |> Enum.reverse() |> Owl.Data.unlines())
end

prompt = Owl.Data.to_ansidata(last_row)
prompt = Owl.Data.to_chardata(last_row)
pid = spawn_link(fn -> loop_prompt(prompt) end)
ref = make_ref()
value = IO.gets(prompt)
Expand All @@ -457,7 +457,7 @@ defmodule Owl.IO do

defp gets(false = _secret, prompt) do
prompt
|> Owl.Data.to_ansidata()
|> Owl.Data.to_chardata()
|> IO.gets()
|> normalize_gets_result()
end
Expand Down Expand Up @@ -550,7 +550,7 @@ defmodule Owl.IO do
"""
@spec puts(Owl.Data.t(), device :: IO.device()) :: :ok
def puts(data, device \\ :stdio) do
data = Owl.Data.to_ansidata(data)
data = Owl.Data.to_chardata(data)

IO.puts(device, data)
end
Expand Down Expand Up @@ -599,7 +599,7 @@ defmodule Owl.IO do
|> Keyword.merge(opts)
|> Keyword.update(:label, nil, fn
nil -> nil
value -> Owl.Data.to_ansidata(value)
value -> Owl.Data.to_chardata(value)
end)
)
end
Expand Down
2 changes: 1 addition & 1 deletion lib/owl/progress_bar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ defmodule Owl.ProgressBar do
...> partial_symbols: [Owl.Data.tag("-", :green), Owl.Data.tag("=", :blue)],
...> empty_symbol: " ",
...> screen_width: 40
...> })|> Owl.Data.to_ansidata() |> to_string
...> })|> Owl.Data.to_chardata() |> to_string()
"Demo [\e[34m=\e[39m ] 4%\e[0m"
iex> Owl.ProgressBar.render(%{
Expand Down
2 changes: 1 addition & 1 deletion lib/owl/table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ defmodule Owl.Table do
...> padding_x: 1,
...> sort_columns: :desc
...> )
...> |> Owl.Data.to_ansidata()
...> |> Owl.Data.to_chardata()
...> |> to_string()
\"""
╭──────────┬──────────╮
Expand Down
8 changes: 4 additions & 4 deletions test/owl/box_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -304,8 +304,8 @@ defmodule Owl.BoxTest do

assert [Owl.Data.tag("Hi there!", :red), " Hi", [Owl.Data.tag("!!!", :green)]]
|> Owl.Box.new(max_width: 6, word_wrap: :normal, border_style: :none)
|> Owl.Data.to_ansidata()
|> Owl.Data.from_ansidata()
|> Owl.Data.to_chardata()
|> Owl.Data.from_chardata()
|> List.flatten() == [
Owl.Data.tag("Hi", :red),
" ",
Expand All @@ -322,8 +322,8 @@ defmodule Owl.BoxTest do
assert "A B C"
|> Owl.Data.tag([:red, :green_background])
|> Owl.Box.new(word_wrap: :normal, border_style: :none, max_width: 80)
|> Owl.Data.to_ansidata()
|> Owl.Data.from_ansidata()
|> Owl.Data.to_chardata()
|> Owl.Data.from_chardata()
<~> [
[
[
Expand Down
Loading

0 comments on commit d4bec69

Please sign in to comment.