• Stars
    star
    290
  • Rank 142,981 (Top 3 %)
  • Language
    Elixir
  • License
    MIT License
  • Created over 8 years ago
  • Updated 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Pretty print tables of Elixir structs and maps.

CI Hex.pm Hex.pm

Scribe

Pretty-print tables of Elixir structs and maps. Inspired by hirb.

Installation

  1. Add scribe to your list of dependencies in mix.exs:
def deps do
  [
    {:scribe, "~> 0.10"}
  ]
end

Usage

Print a list of maps or structs as a table. Header columns are taken from the keys of the first element.

iex(1)> data = [%{key: "value", another_key: 123},
...(1)> [%{key: "test", another_key: :key}]
iex(2)> Scribe.print(data)
+----------------+-------------+
| :another_key   | :key        |
+----------------+-------------+
| 123            | "value"     |
| :key           | "test"      |
+----------------+-------------+

Useful for printing large collections, such as results of database queries

# %User{id: nil, email: nil}

iex(1)> User |> limit(5) |> Repo.all |> Scribe.print
+-------------+----------------------------+------+
| :__struct__ | :email                     | :id  |
+-------------+----------------------------+------+
| User        | "[email protected]"  | 5171 |
| User        | "[email protected]" | 4528 |
| User        | "[email protected]" | 1480 |
| User        | "[email protected]"  | 2084 |
| User        | "[email protected]"    | 6599 |
+-------------+----------------------------+------+

Use Scribe Automatically

Scribe can override Inspect to automatically return maps in table format. Add the following to your config/dev.exs:

config :scribe,
  compile_auto_inspect: true,
  auto_inspect: true

Temporarily disable in the shell if needed:

iex(1)> Scribe.auto_inspect(false)
:ok

Note: Auto-inspect will not work in production Distillery releases. Leave it out of your prod.exs

Pagination

Scribe uses 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        | "[email protected]"  | "Maeve"     | 9865  | "Gerlach"  |
| User        | "[email protected]" | "Theodora"  | 2262  | "Wunsch"   |
| User        | "[email protected] | "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"                            |
+--------------------------+----------------------------------------------+

:ok

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)

Styles

Scribe supports four styling formats natively, with support for custom adapters.

Default

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"     |
+-------+-----------------------------------+------------------------+

Psql

iex> Scribe.print(data, style: Scribe.Style.Psql)

 :id   | :inserted_at                      | :key
-------+-----------------------------------+------------------------
 700   | "2017-03-27 14:41:33.411442Z"     | "A2FA80D0F6DF9388"
 890   | "2017-03-27 14:41:33.412955Z"     | "F95094328A91D950"
 684   | "2017-03-27 14:41:33.412991Z"     | "1EAC6B28045ED644"
 531   | "2017-03-27 14:41:33.413015Z"     | "DC2377B696355642"
 648   | "2017-03-27 14:41:33.413037Z"     | "EA9311B4683A52B3"

Github Markdown

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"     |

Pseudo

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"     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

NoBorder

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"

Set a default one in your Mix config if you like:

config :scribe, style: Scribe.Style.Psql