View Source Owl.Data (Owl v0.12.0)

A set of functions for t:chardata/0 with tags.

Summary

Types

ANSI escape sequence.

t()

A recursive data type that is similar to t:chardata/0, but additionally supports Owl.Tag.t/1.

Functions

Adds a prefix before each line of the data.

Returns list of t() containing count elements each.

Transforms chardata, replacing raw escape sequences with tags (see tag/2).

Returns length of the data.

Splits data by new lines.

Returns a data starting at the offset start, and of the given length.

Divides data into parts based on a pattern saving sequences for tagged data in new tags.

Transforms data to t:chardata/0 format which can be consumed by IO module.

Truncates data, so the length of returning data is <= length.

Creates a t/0 from an a list of t/0, it inserts new line characters between original elements.

Removes information about sequences and keeps only content of the tag.

Zips corresponding lines into 1 line.

Types

@type sequence() ::
  :black
  | :red
  | :green
  | :yellow
  | :blue
  | :magenta
  | :cyan
  | :white
  | :black_background
  | :red_background
  | :green_background
  | :yellow_background
  | :blue_background
  | :magenta_background
  | :cyan_background
  | :white_background
  | :light_black_background
  | :light_red_background
  | :light_green_background
  | :light_yellow_background
  | :light_blue_background
  | :light_magenta_background
  | :light_cyan_background
  | :light_white_background
  | :default_color
  | :default_background
  | :blink_slow
  | :blink_rapid
  | :faint
  | :bright
  | :inverse
  | :underline
  | :italic
  | :overlined
  | :reverse
  | binary()

ANSI escape sequence.

An atom alias of ANSI escape sequence.

A binary representation of color like "\e[38;5;33m" (which is IO.ANSI.color(33) or IO.ANSI.color(0, 2, 5)).

@type t() ::
  [binary() | non_neg_integer() | t() | Owl.Tag.t(t())]
  | Owl.Tag.t(t())
  | binary()

A recursive data type that is similar to t:chardata/0, but additionally supports Owl.Tag.t/1.

Can be printed using Owl.IO.puts/2.

Functions

Link to this function

add_prefix(data, prefix)

View Source
@spec add_prefix(t(), t()) :: t()

Adds a prefix before each line of the data.

An important feature is that styling of the data will be saved for each line.

Example

iex> "first\nsecond" |> Owl.Data.tag(:red) |> Owl.Data.add_prefix(Owl.Data.tag("test: ", :yellow))
[
  [Owl.Data.tag("test: ", :yellow), Owl.Data.tag(["first"], :red)],
  "\n",
  [Owl.Data.tag("test: ", :yellow), Owl.Data.tag(["second"], :red)]
]
Link to this function

chunk_every(data, count)

View Source
@spec chunk_every(data :: t(), count :: pos_integer()) :: [t()]

Returns list of t() containing count elements each.

Example

iex> Owl.Data.chunk_every(
...>   ["first second ", Owl.Data.tag(["third", Owl.Data.tag(" fourth", :blue)], :red)],
...>   7
...> )
[
  "first s",
  ["econd ", Owl.Data.tag(["t"], :red)],
  Owl.Data.tag(["hird", Owl.Data.tag([" fo"], :blue)], :red),
  Owl.Data.tag(["urth"], :blue)
]
@spec from_chardata(IO.chardata()) :: t()

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.

Examples

iex> [:red, "hello"] |> IO.ANSI.format() |> Owl.Data.from_chardata()
Owl.Data.tag("hello", :red)

іex> {output, 0} = Owl.System.cmd("bat", ["README.md", "--color=always", "--style=plain"])
...> output
...> |> Owl.Data.from_chardata()
...> |> Owl.Box.new(title: Owl.Data.tag("README.md", :cyan), border_tag: :light_cyan)
...> |> Owl.IO.puts()
@spec length(t()) :: non_neg_integer()

Returns length of the data.

Examples

iex> Owl.Data.length(["222"])
3

iex> Owl.Data.length([222])
1

iex> Owl.Data.length([[[]]])
0

iex> Owl.Data.length(["222", Owl.Data.tag(["333", "444"], :green)])
9

# if ucwidth dependency is present, then it is used to calculate the length of the string
iex> Owl.Data.length("😂")
2
@spec lines(t()) :: [t()]

Splits data by new lines.

A special case of split/2.

Example

iex> Owl.Data.lines(["first\nsecond\n", Owl.Data.tag("third\nfourth", :red)])
["first", "second", Owl.Data.tag(["third"], :red), Owl.Data.tag(["fourth"], :red)]
Link to this function

slice(data, start, length)

View Source
@spec slice(t(), integer(), pos_integer()) :: t()

Returns a data starting at the offset start, and of the given length.

It is like String.slice/3 but for t/0.

Examples

iex> Owl.Data.slice([Owl.Data.tag("Hello world", :red), Owl.Data.tag("!", :green)], 6, 7)
[Owl.Data.tag(["world"], :red), Owl.Data.tag(["!"], :green)]

iex> Owl.Data.slice(Owl.Data.tag("Hello world", :red), 20, 10)
[]
@spec split(t(), String.pattern() | Regex.t()) :: [t()]

Divides data into parts based on a pattern saving sequences for tagged data in new tags.

Example

iex> Owl.Data.split(["first second ", Owl.Data.tag("third fourth", :red)], " ")
["first", "second", Owl.Data.tag(["third"], :red), Owl.Data.tag(["fourth"], :red)]

iex> Owl.Data.split(["first   second ", Owl.Data.tag("third    fourth", :red)], ~r/ +/)
["first", "second", Owl.Data.tag(["third"], :red), Owl.Data.tag(["fourth"], :red)]
Link to this function

tag(data, sequence_or_sequences)

View Source
@spec tag(data, sequence() | [sequence()]) :: Owl.Tag.t(data) when data: t()

Builds a tag.

Examples

iex> Owl.Data.tag(["hello ", Owl.Data.tag("world", :green), "!!!"], :red)
Owl.Data.tag(["hello ", Owl.Data.tag("world", :green), "!!!"], :red)

iex> Owl.Data.tag("hello world", [:green, :red_background])
Owl.Data.tag("hello world", [:green, :red_background])
@spec to_chardata(t()) :: IO.chardata()

Transforms data to t:chardata/0 format which can be consumed by IO module.

Examples

iex> "hello" |> Owl.Data.tag(:red) |> Owl.Data.to_chardata()
[[[[[] | "\e[31m"], "hello"] | "\e[39m"] | "\e[0m"]
@spec truncate(t(), pos_integer()) :: t()

Truncates data, so the length of returning data is <= length.

Puts ellipsis symbol at the end if data was truncated.

Examples

iex> Owl.Data.truncate([Owl.Data.tag("Hello", :red), Owl.Data.tag(" world!", :green)], 10)
[Owl.Data.tag(["Hello"], :red), Owl.Data.tag([" wor"], :green), "…"]

iex> Owl.Data.truncate("Hello", 10)
"Hello"

iex> Owl.Data.truncate("Hello", 4)
["Hel", "…"]

iex> Owl.Data.truncate("Hello", 5)
"Hello"

iex> Owl.Data.truncate("Hello", 1)
"…"
@spec unlines([t()]) :: [t()]

Creates a t/0 from an a list of t/0, it inserts new line characters between original elements.

Examples

iex> Owl.Data.unlines(["a", "b", "c"])
["a", "\n", "b", "\n", "c"]

iex> ["first\nsecond\n", Owl.Data.tag("third\nfourth", :red)]
...> |> Owl.Data.lines()
...> |> Owl.Data.unlines()
...> |> Owl.Data.to_chardata()
Owl.Data.to_chardata(["first\nsecond\n", Owl.Data.tag("third\nfourth", :red)])
@spec untag(t()) :: IO.chardata()

Removes information about sequences and keeps only content of the tag.

Examples

iex> Owl.Data.tag("Hello", :red) |> Owl.Data.untag()
"Hello"

iex> Owl.Data.tag([72, 101, 108, 108, 111], :red) |> Owl.Data.untag()
~c"Hello"

iex> Owl.Data.tag(["Hello", Owl.Data.tag("world", :green)], :red) |> Owl.Data.untag()
["Hello", "world"]

iex> ["Hello ", Owl.Data.tag("world", :red), ["!"]] |> Owl.Data.untag()
["Hello ", "world", ["!"]]
@spec zip(t(), t()) :: t()

Zips corresponding lines into 1 line.

The zipping finishes as soon as either data completes.

Examples

iex> Owl.Data.zip("a\nb\nc", "d\ne\nf")
[["a", "d"], "\n", ["b", "e"], "\n", ["c", "f"]]

iex> Owl.Data.zip("a\nb", "c")
[["a", "c"]]

iex> 1..3
...> |> Enum.map(&to_string/1)
...> |> Enum.map(&Owl.Box.new/1) |> Enum.reduce(&Owl.Data.zip/2) |> to_string()
"""
┌─┐┌─┐┌─┐
│3││2││1│
└─┘└─┘└─┘
""" |> String.trim_trailing()