Packages
moar
5.0.0
5.0.0
4.3.0
4.2.0
4.1.0
4.0.0
3.2.0
3.1.0
3.0.0
2.7.0
2.6.0
2.5.0
2.4.2
2.4.1
2.4.0
2.3.0
2.2.0
2.1.0
2.0.1
2.0.0
1.64.0
1.63.1
1.63.0
1.62.0
1.61.2
1.61.1
1.61.0
1.60.0
1.59.2
1.59.1
1.59.0
1.58.0
1.57.0
1.56.2
1.56.1
1.56.0
1.55.0
1.54.0
1.53.0
1.52.1
1.52.0
1.51.0
1.50.0
1.49.0
1.48.0
1.47.0
1.46.0
1.45.1
1.45.0
1.44.0
1.43.0
1.42.0
1.41.0
1.40.0
1.39.0
1.38.0
1.37.0
1.36.0
1.35.0
1.34.0
1.33.0
1.32.0
1.31.0
1.30.0
1.29.0
1.28.0
1.27.0
1.26.0
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.0
1.19.3
1.19.2
1.19.1
1.19.0
1.18.1
1.18.0
1.17.0
1.16.0
1.15.0
1.14.0
1.13.1
1.13.0
1.12.0
1.11.0
1.10.0
1.9.0
1.8.0
1.7.0
1.6.0
1.5.0
1.4.0
1.3.0
1.2.0
1.1.0
1.0.0
0.1.0
A dependency-free utility library containing 100+ useful functions.
Current section
Files
Jump to
Current section
Files
lib/io.ex
defmodule Moar.IO do
# @related [test](test/io_test.exs)
@moduledoc "IO-related functions"
defmodule ANSI do
@doc "Parses a string as described in `Moar.IO.cformat/2`"
@spec parse(String.t()) :: iolist()
def parse(string),
do: Regex.split(pattern(), string, include_captures: true) |> Enum.map(&convert/1)
@doc "Converts one formatting expression to an iolist"
@spec convert(String.t()) :: iolist()
def convert(string) do
trimmed_string = String.trim(string)
if String.first(trimmed_string) == "{" && String.last(trimmed_string) == "}" do
[_, formats, text] = Regex.run(pattern(), trimmed_string)
formats = formats |> String.split(~r/\W+/) |> Enum.map(&String.to_atom/1) |> maybe_unwrap_list()
[formats, text, :reset]
else
string
end
end
defp maybe_unwrap_list([item]), do: item
defp maybe_unwrap_list(list) when is_list(list), do: list
defp pattern, do: ~r/\{([^:]+):\s?([^\}]*)}/
end
@doc "Formats a string and prints it to stdout. See `cformat/2` for details."
@spec cputs(String.t(), boolean()) :: :ok
def cputs(string, emit? \\ IO.ANSI.enabled?()),
do: string |> cformat(emit?) |> IO.puts()
@doc """
Accepts a string with special formatting syntax and converts it into an `iolist` that contains
ANSI color and formatting codes. The second parameter, `emit?` can be used to enable or disable
formatting; it defaults to the value of `IO.ANSI.enabled?/0`.
The formatting syntax looks like:
"My {green: hovercraft} is {red italic: full of eels}!"
The formatting options are the ANSI codes that are allowed to be sent to `IO.ANSI.format/2`.
There doesn't seem to be a list of valid codes, but the names of most of the zero-arity functions
in `IO.ANSI` can be used. The order of the formatting options is not important.
The resulting iolist can be used anywhere that iodata is expected. This module's `cstring/2` function
will take the same input and return a string, and `cputs/2` will take the same input and print it to
stdout.
"""
@spec cformat(String.t(), boolean()) :: iolist()
def cformat(string, emit? \\ IO.ANSI.enabled?()),
do: string |> Moar.IO.ANSI.parse() |> IO.ANSI.format_fragment(emit?)
@doc "Formats a string and returns the formatted string. See `cformat/2` for details."
@spec cstring(String.t(), boolean()) :: String.t()
def cstring(string, emit? \\ IO.ANSI.enabled?()),
do: string |> cformat(emit?) |> to_string()
end