Skip to content

Commit f20ef46

Browse files
author
Thomaz Leite
committed
Implement IO.ANSI format/2 and format_fragment/2
1 parent 6ce9709 commit f20ef46

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

lib/elixir/lib/io/ansi.ex

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,46 @@ defmodule IO.ANSI do
134134
raise ArgumentError, "invalid ANSI sequence specification: #{other}"
135135
end
136136

137+
def format(chardata, emit \\ terminal?) do
138+
do_format(chardata, [], emit, :maybe)
139+
end
140+
141+
def format_fragment(chardata, emit \\ terminal?) do
142+
do_format(chardata, [], emit, false)
143+
end
144+
145+
defp do_format([], buffer, _emit, append_reset) do
146+
if append_reset == true do
147+
Enum.reverse(buffer) ++ IO.ANSI.reset
148+
else
149+
Enum.reverse(buffer)
150+
end
151+
end
152+
153+
defp do_format(chardata, buffer, emit, append_reset) when not is_list(chardata) do
154+
do_format([chardata], buffer, emit, append_reset)
155+
end
156+
157+
defp do_format(chardata, buffer, emit, append_reset) do
158+
[elem|rest] = chardata
159+
160+
cond do
161+
is_atom(elem) and emit ->
162+
try do
163+
do_format(rest, [apply(IO.ANSI, elem, [])|buffer], emit, !!append_reset)
164+
rescue
165+
_ in UndefinedFunctionError ->
166+
raise ArgumentError, message: "invalid ANSI sequence specification: #{elem}"
167+
end
168+
is_atom(elem) and not emit ->
169+
do_format(rest, buffer, emit, append_reset)
170+
is_list(elem) ->
171+
do_format(elem ++ rest, buffer, emit, append_reset)
172+
true ->
173+
do_format(rest, [elem|buffer], emit, append_reset)
174+
end
175+
end
176+
137177
@doc ~S"""
138178
Escapes a string by converting named ANSI sequences into actual ANSI codes.
139179

lib/elixir/test/elixir/io/ansi_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ defmodule IO.ANSITest do
6464
end
6565

6666
test :format_improper_list do
67-
data = ["Hello, ", :red, "world!" | :reset]
67+
data = ["Hello, ", :red, "world" | "!"]
6868

6969
assert IO.chardata_to_string(IO.ANSI.format(data, true)) ==
7070
"Hello, #{IO.ANSI.red}world!#{IO.ANSI.reset}"

0 commit comments

Comments
 (0)