Skip to content

Commit

Permalink
docs: lot of updates (#25)
Browse files Browse the repository at this point in the history
* docs: lot of ex_doc updates

* test: docs and tests for text alignment
  • Loading branch information
hpopp authored Aug 31, 2024
1 parent 8fb3568 commit 3bcfc27
Show file tree
Hide file tree
Showing 13 changed files with 362 additions and 38 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

**Added**

- Center and right text alignment options ([#16](https://github.com/codedge-llc/scribe/pull/16)).

**Changed**

- Bumped minimum Elixir version to 1.13.
Expand Down
30 changes: 29 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Useful for printing large collections, such as results of database queries
```elixir
# %User{id: nil, email: nil}

iex(1)> User |> limit(5) |> Repo.all |> Scribe.print
iex(1)> User |> limit(5) |> Repo.all() |> Scribe.print()
+-------------+----------------------------+------+
| :__struct__ | :email | :id |
+-------------+----------------------------+------+
Expand Down Expand Up @@ -154,6 +154,34 @@ iex> Scribe.print(data, width: 80)
iex> Scribe.print(data, colorize: false)
```

### Text Alignment

Pass an `alignment` option of `:left`, `:center`, or `:right` for text alignment.
Defaults to `:left`.

```elixir
iex> Scribe.print(data, alignment: :center)

+------------------------------+------------+--------+
| :body | :current | :id |
+------------------------------+------------+--------+
| "A rather short string." | true | 1234 |
| "A rather short string." | false | 2222 |
| "A rather short string." | true | 4444 |
+------------------------------+------------+--------+
```

```elixir
iex> Scribe.print(data, alignment: :right)
+------------------------------+------------+--------+
| :body | :current | :id |
+------------------------------+------------+--------+
| "A rather short string." | true | 1234 |
| "A rather short string." | false | 2222 |
| "A rather short string." | true | 4444 |
+------------------------------+------------+--------+
```

### Styles

Scribe supports four styling formats natively, with support for custom adapters.
Expand Down
2 changes: 2 additions & 0 deletions lib/default_colors.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ defmodule Scribe.DefaultColors do

defmacro __using__(_) do
quote do
@doc false
def default_color(), do: IO.ANSI.default_color()

@impl true
def color(value) when is_boolean(value), do: IO.ANSI.magenta()
def color(value) when is_nil(value), do: IO.ANSI.magenta()
def color(value) when is_number(value), do: IO.ANSI.yellow()
Expand Down
151 changes: 144 additions & 7 deletions lib/scribe.ex
Original file line number Diff line number Diff line change
@@ -1,14 +1,147 @@
defmodule Scribe do
@moduledoc """
@moduledoc ~S"""
Pretty-print tables of structs and maps
## Usage
A common use case is printing results from an Ecto query.
# %User{id: nil, email: nil}
iex(1)> User |> limit(5) |> Repo.all() |> Scribe.print()
+-------------+----------------------------+------+
| :__struct__ | :email | :id |
+-------------+----------------------------+------+
| User | "myles_fisher@beahan.com" | 5171 |
| User | "dawson_bartell@lynch.org" | 4528 |
| User | "hassan1972@langworth.com" | 1480 |
| User | "kiera.schulist@koch.com" | 2084 |
| User | "cynthia1970@mann.name" | 6599 |
+-------------+----------------------------+------+
## Pagination
Scribe uses [pane](https://github.com/codedge-llc/pane) to paginate large tables.
Use with `Scribe.console/2`.
# %User{id: nil, email: nil, first_name: nil, last_name: nil}
iex(1)> User |> limit(5) |> Repo.all |> Scribe.console
+-------------+------------------------+-------------+-------+------------+
| :__struct__ | :email | :first_name | :id | :last_name |
+-------------+------------------------+-------------+-------+------------+
| User | "celestine_satterfield | "Gene" | 9061 | "Krajcik" |
| User | "lynn1978@bednar.org" | "Maeve" | 9865 | "Gerlach" |
| User | "melisa1975@hilll.biz" | "Theodora" | 2262 | "Wunsch" |
| User | "furman.grady@ryan.org | "Oswaldo" | 4977 | "Simonis" |
| User | "caesar_hirthe@reynold | "Arjun" | 3907 | "Prohaska" |
+-------------+------------------------+-------------+-------+------------+
[1 of 1] (j)next (k)prev (q)quit
## Printing Custom Tables
`Scribe.print/2` takes a list of of columns on the `:data` options key to
customize output. You can use either the atom key or customize the header
with `{"Custom Title", :key}`.
# %User{id: nil, email: nil, first_name: nil, last_name: nil}
User
|> limit(5)
|> Repo.all
|> Scribe.print(data: [{"ID", :id}, :first_name, :last_name])
+------+--------------+-------------+
| "ID" | :first_name | :last_name |
+------+--------------+-------------+
| 9061 | "Gene" | "Krajcik" |
| 9865 | "Maeve" | "Gerlach" |
| 2262 | "Theodora" | "Wunsch" |
| 4977 | "Oswaldo" | "Simonis" |
| 3907 | "Arjun" | "Prohaska" |
+------+--------------+-------------+
### Function Columns
You can specify functions that take the given row's struct or map as its only argument.
# %User{id: nil, email: nil, first_name: nil, last_name: nil}
results =
User
|> limit(5)
|> Repo.all
|> Scribe.print(data: [{"ID", :id}, {"Full Name", fn(x) -> "#{x.last_name}, #{x.first_name}" end}])
+--------------------------+----------------------------------------------+
| "ID" | "Full Name" |
+--------------------------+----------------------------------------------+
| 9061 | "Krajcik, Gene" |
| 9865 | "Gerlach, Maeve" |
| 2262 | "Wunsch, Theodora" |
| 4977 | "Simonis, Oswaldo" |
| 3907 | "Prohaska, Arjun" |
+--------------------------+----------------------------------------------+
## Styling Options
### Width
Pass a `width` option to define table width.
iex> Scribe.print(data, width: 80)
+-------------------+-----------------------------------------------------+
| :id | :key |
+-------------------+-----------------------------------------------------+
| 910 | "B1786AC67B4DEB19" |
| 313 | "30CB8A2DE4750070" |
| 25 | "D0859205FC7E7298" |
| 647 | "8F0060AD0BD6AB04" |
| 253 | "65509A684D619182" |
+-------------------+-----------------------------------------------------+
### Disable Colors
iex> Scribe.print(data, colorize: false)
### Text Alignment
Pass an `alignment` option of `:left`, `:center`, or `:right` for text alignment.
Defaults to `:left`.
iex> Scribe.print(data, alignment: :center)
+------------------------------+------------+--------+
| :body | :current | :id |
+------------------------------+------------+--------+
| "A rather short string." | true | 1234 |
| "A rather short string." | false | 2222 |
| "A rather short string." | true | 4444 |
+------------------------------+------------+--------+
iex> Scribe.print(data, alignment: :right)
+------------------------------+------------+--------+
| :body | :current | :id |
+------------------------------+------------+--------+
| "A rather short string." | true | 1234 |
| "A rather short string." | false | 2222 |
| "A rather short string." | true | 4444 |
+------------------------------+------------+--------+
### Styles
Scribe supports five styling formats natively, with support for custom adapters.
See more in `Scribe.Style`.
"""

alias Scribe.Table

@type data ::
[]
| [...]
| term
@typedoc ~S"""
Printable data. Can be either a struct, map, or list of structs/maps.
"""
@type data :: [map] | [struct] | map | struct

@typedoc ~S"""
Options for configuring table output.
Expand Down Expand Up @@ -55,6 +188,10 @@ defmodule Scribe do
dev |> IO.puts(results)
end

@doc ~S"""
Paginates data and starts a pseudo-interactive console.
"""
@spec console(data, format_opts) :: no_return
def console(results, opts \\ []) do
results
|> format(opts)
Expand All @@ -79,7 +216,7 @@ defmodule Scribe do
+----------+---------+
%{test: 1234, key: :value}
"""
@spec inspect(term, format_opts) :: term
@spec inspect(data, format_opts) :: data
def inspect(results, opts \\ []) do
print(results, opts)
results
Expand All @@ -96,7 +233,7 @@ defmodule Scribe do
iex> format(%{test: 1234}, colorize: false)
"+---------+\n| :test |\n+---------+\n| 1234 |\n+---------+\n"
"""
@spec format([] | [...] | term) :: String.t() | :ok
@spec format(data) :: String.t() | :ok
def format(_results, opts \\ [])
def format([], _opts), do: :ok

Expand Down
14 changes: 12 additions & 2 deletions lib/style.ex
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
defmodule Scribe.Style do
@moduledoc """
Defines styling callbacks for table printing.
## Available Styles
- `Scribe.Style.Default`
- `Scribe.Style.GithubMarkdown`
- `Scribe.Style.NoBorder`
- `Scribe.Style.Psql`
- `Scribe.Style.Pseudo`
"""

@doc ~S"""
Returns default configured style.
Configure in your `mix.exs`
```elixir
Configure in your project:
```
config :scribe, style: Scribe.Style.Psql
```
Defaults to `Scribe.Style.Default` if not specified.
"""
@spec default :: module
def default do
Application.get_env(:scribe, :style, Scribe.Style.Default)
end
Expand Down
19 changes: 18 additions & 1 deletion lib/style/default.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
defmodule Scribe.Style.Default do
@moduledoc false
@moduledoc """
Default style.
## Examples
iex> Scribe.print(data, style: Scribe.Style.Default)
+-------+-----------------------------------+------------------------+
| :id | :inserted_at | :key |
+-------+-----------------------------------+------------------------+
| 457 | "2017-03-27 14:42:34.095202Z" | "CEB0E055ECDF6028" |
| 326 | "2017-03-27 14:42:34.097519Z" | "CF67027F7235B88D" |
| 756 | "2017-03-27 14:42:34.097553Z" | "DE016DFF477BEDDB" |
| 484 | "2017-03-27 14:42:34.097572Z" | "9194A82EF4BB0123" |
| 780 | "2017-03-27 14:42:34.097591Z" | "BF92748B4AAAF14A" |
+-------+-----------------------------------+------------------------+
"""

alias Scribe.Border

@behaviour Scribe.Style

@impl true
def border_at(0, _columns, _max_rows, _max_cols) do
Border.new("+", "|", "-")
end
Expand Down
17 changes: 16 additions & 1 deletion lib/style/github_markdown.ex
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
defmodule Scribe.Style.GithubMarkdown do
@moduledoc false
@moduledoc ~S"""
GitHub markdown style.
## Examples
iex> Scribe.print(data, style: Scribe.Style.GithubMarkdown)
| :id | :inserted_at | :key |
|-------|-----------------------------------|------------------------|
| 457 | "2017-03-27 14:42:34.095202Z" | "CEB0E055ECDF6028" |
| 326 | "2017-03-27 14:42:34.097519Z" | "CF67027F7235B88D" |
| 756 | "2017-03-27 14:42:34.097553Z" | "DE016DFF477BEDDB" |
| 484 | "2017-03-27 14:42:34.097572Z" | "9194A82EF4BB0123" |
| 780 | "2017-03-27 14:42:34.097591Z" | "BF92748B4AAAF14A" |
"""

@behaviour Scribe.Style

use Scribe.DefaultColors

# Top row
@impl true
def border_at(0, _, _, _) do
%Scribe.Border{
bottom_edge: "-",
Expand Down
16 changes: 15 additions & 1 deletion lib/style/no_border.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
defmodule Scribe.Style.NoBorder do
@moduledoc false
@moduledoc ~S"""
No-border style.
## Examples
iex> Scribe.print(data, style: Scribe.Style.NoBorder)
:id :inserted_at :key
457 "2017-03-27 14:42:34.095202Z" "CEB0E055ECDF6028"
326 "2017-03-27 14:42:34.097519Z" "CF67027F7235B88D"
756 "2017-03-27 14:42:34.097553Z" "DE016DFF477BEDDB"
484 "2017-03-27 14:42:34.097572Z" "9194A82EF4BB0123"
780 "2017-03-27 14:42:34.097591Z" "BF92748B4AAAF14A"
"""

alias Scribe.Border

@behaviour Scribe.Style

@impl true
def border_at(_row, _col, _max_rows, _max_cols), do: %Border{}

use Scribe.DefaultColors
Expand Down
19 changes: 18 additions & 1 deletion lib/style/pseudo.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
defmodule Scribe.Style.Pseudo do
@moduledoc false
@moduledoc ~S"""
Pseudo style.
## Examples
iex> Scribe.print(data, style: Scribe.Style.Pseudo)
┌───────┬───────────────────────────────────┬────────────────────────┐
│ :id │ :inserted_at │ :key │
├───────┼───────────────────────────────────┼────────────────────────┤
│ 457 │ "2017-03-27 14:42:34.095202Z" │ "CEB0E055ECDF6028" │
│ 326 │ "2017-03-27 14:42:34.097519Z" │ "CF67027F7235B88D" │
│ 756 │ "2017-03-27 14:42:34.097553Z" │ "DE016DFF477BEDDB" │
│ 484 │ "2017-03-27 14:42:34.097572Z" │ "9194A82EF4BB0123" │
│ 780 │ "2017-03-27 14:42:34.097591Z" │ "BF92748B4AAAF14A" │
└───────┴───────────────────────────────────┴────────────────────────┘
"""

@behaviour Scribe.Style

Expand All @@ -25,6 +41,7 @@ defmodule Scribe.Style.Pseudo do
right_edge: "│"
}

@impl true
def border_at(0, col, _max_rows, max_cols) when col < max_cols - 1 do
%Scribe.Border{
@header_border
Expand Down
Loading

0 comments on commit 3bcfc27

Please sign in to comment.