{"id":13507633,"url":"https://github.com/djm/table_rex","last_synced_at":"2025-05-14T11:10:53.443Z","repository":{"id":40659882,"uuid":"47346984","full_name":"djm/table_rex","owner":"djm","description":"An Elixir app which generates text-based tables for display","archived":false,"fork":false,"pushed_at":"2025-02-16T14:24:36.000Z","size":704,"stargazers_count":258,"open_issues_count":2,"forks_count":28,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-31T13:04:20.175Z","etag":null,"topics":["cli","elixir","hex","table"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/djm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-03T17:06:27.000Z","updated_at":"2025-03-18T23:43:23.000Z","dependencies_parsed_at":"2024-05-01T16:19:37.758Z","dependency_job_id":"62a619af-b04e-4cc6-9952-803b24207c17","html_url":"https://github.com/djm/table_rex","commit_stats":{"total_commits":128,"total_committers":21,"mean_commits":6.095238095238095,"dds":0.1640625,"last_synced_commit":"e744f687fdd22ccf1cd2d8417e630e13756adbc9"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djm%2Ftable_rex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djm%2Ftable_rex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djm%2Ftable_rex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/djm%2Ftable_rex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/djm","download_url":"https://codeload.github.com/djm/table_rex/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248339861,"owners_count":21087335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","elixir","hex","table"],"created_at":"2024-08-01T02:00:37.235Z","updated_at":"2025-04-11T04:19:52.486Z","avatar_url":"https://github.com/djm.png","language":"Elixir","funding_links":[],"categories":["Command Line Applications"],"sub_categories":[],"readme":"\u003cimg src=\"http://i.imgur.com/ipa4UVa.png\" width=\"500\" /\u003e\n\n[![Hex.pm](https://img.shields.io/hexpm/v/table_rex.svg)](https://hex.pm/packages/table_rex)\n[![Build Status](https://github.com/djm/table_rex/workflows/TableRex%20CI/badge.svg)](https://github.com/djm/table_rex/actions)\n[![Awesome Elixir](https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg)](https://github.com/h4cc/awesome-elixir#command-line-applications)\n\n**An Elixir app which generates text-based tables for display**\n\n\u003cimg src=\"https://raw.githubusercontent.com/djm/table_rex/main/assets/examples.gif\" width=\"500\" alt=\"Layout Examples\" /\u003e\n\n#### Features\n\n* A one-liner for rendering ASCII-style tables with sane defaults.\n* Rendering via:\n  * the built-in plain-text \"ASCII-style\" renderer.\n  * your own rendering module.\n\nThe data structures support:\n\n* column \u0026 cell level text alignment: left, center, right.\n* table titles \u0026 column headers.\n* sorting based on raw input data (rather than just strings).\n* column, header \u0026 cell level \u003cimg src=\"http://i.imgur.com/LCfvYYM.png\" width=\"44\" /\u003e support, including backgrounds.\n* automatic but defineable column \u0026 cell level padding.\n* CJK \u0026 Unicode support in the cells.\n* styling the table with various vertical \u0026 horizontal framing (including GitHub flavoured markdown).\n* styling the table with custom separator symbols.\n* multi-line cell support.\n\nThe built-in \"ASCII-style\" renderer supports all of these features\nout-of-the-box, but your custom renderers can support a subset if\nthey wish.\n\n#### Documentation\n\nSee the quick start below or check out the\n[full API docs at HexDocs](https://hexdocs.pm/table_rex/).\n\n#### Stability\n\nThis software is now post v1 and therefore, as per semver, can be considered\nstable and will have no breaking changes without incrementing the major version\nnumber. Any breaking changes, and they will be few and far between, will be\ndocumented in the [CHANGELOG](CHANGELOG.md).\n\nThe project officially will attempt to support the last 3 minor versions of\nElixir, and the latest 2 majors for OTP. If you are looking for support for\nolder version, then look at older releases.\n\nOfficial version support:\n\n* Elixir: 1.13 \u0026 up\n* OTP: 24 \u0026 up\n\n## Installation\n\nThe package is [available on Hex](https://hex.pm/packages/table_rex), therefore:\n\n**Add** `table_rex` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [{:table_rex, \"~\u003e 4.1.0\"}]\nend\n```\n\nThen run `mix deps.get`. That's it for modern Elixir.\n\n## Quick Start\n\nUse the `TableRex.quick_render` and `TableRex.quick_render!` functions; for\nthose that just want a table quickly.\n\nGiven this data:\n\n```elixir\ntitle = \"Drum \u0026 Bass Releases\"\nheader = [\"Artist\", \"Track\", \"Label\", \"Year\"]\nrows = [\n  [\"Konflict\", \"Cyanide\", \"Renegade Hardware\", 1999],\n  [\"Marcus Intalex\", \"Temperance\", \"Soul:r\", 2004],\n  [\"Kryptic Minds\", \"The Forgotten\", \"Defcom Records\", 2007]\n]\n```\n\n### TableRex.quick_render!/1\n\n```elixir\nTableRex.quick_render!(rows)\n|\u003e IO.puts\n```\n\n```\n+----------------|---------------|-------------------|------+\n| Konflict       | Cyanide       | Renegade Hardware | 1999 |\n| Marcus Intalex | Temperance    | Soul:r            | 2004 |\n| Kryptic Minds  | The Forgotten | Defcom Records    | 2007 |\n+----------------|---------------|-------------------|------+\n```\n\n### TableRex.quick_render!/2\n\n```elixir\nTableRex.quick_render!(rows, header)\n|\u003e IO.puts\n```\n\n```\n+----------------|---------------|-------------------|------+\n| Artist         | Track         | Label             | Year |\n+----------------|---------------|-------------------|------+\n| Konflict       | Cyanide       | Renegade Hardware | 1999 |\n| Marcus Intalex | Temperance    | Soul:r            | 2004 |\n| Kryptic Minds  | The Forgotten | Defcom Records    | 2007 |\n+----------------|---------------|-------------------|------+\n```\n\n### TableRex.quick_render!/3\n\n```elixir\nTableRex.quick_render!(rows, header, title)\n|\u003e IO.puts\n```\n\n```\n+-----------------------------------------------------------+\n|                   Drum \u0026 Bass Releases                    |\n+----------------|---------------|-------------------|------+\n| Artist         | Track         | Label             | Year |\n+----------------|---------------|-------------------|------+\n| Konflict       | Cyanide       | Renegade Hardware | 1999 |\n| Marcus Intalex | Temperance    | Soul:r            | 2004 |\n| Kryptic Minds  | The Forgotten | Defcom Records    | 2007 |\n+----------------|---------------|-------------------|------+\n```\n\n### Utilising TableRex.Table for deeper customisation\n\nThese examples all use: `alias TableRex.Table` to shorten the namespace.\n\n**Set alignment \u0026 padding for specific columns or column ranges:**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.put_column_meta(0, align: :right, padding: 5) # `0` is the column index.\n|\u003e Table.put_column_meta(1..2, align: :center) # `1..2` is a range of column indexes. :all also works.\n|\u003e Table.render!\n|\u003e IO.puts\n```\n\n```\n+------------------------|---------------|-------------------|------+\n|             Artist     | Track         | Label             | Year |\n+------------------------|---------------|-------------------|------+\n|           Konflict     |    Cyanide    | Renegade Hardware | 1999 |\n|     Marcus Intalex     |  Temperance   |      Soul:r       | 2004 |\n|      Kryptic Minds     | The Forgotten |  Defcom Records   | 2007 |\n+------------------------|---------------|-------------------|------+\n```\n\n**Sort the rows of the table using a column's values:**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.sort(3, :desc) # `3` is the column index, order is :desc or :asc for descending/ascending.\n|\u003e Table.render!\n|\u003e IO.puts\n```\n\n```\n+----------------|---------------|-------------------|------+\n| Artist         | Track         | Label             | Year |\n+----------------|---------------|-------------------|------+\n| Kryptic Minds  | The Forgotten | Defcom Records    | 2007 |\n| Marcus Intalex | Temperance    | Soul:r            | 2004 |\n| Konflict       | Cyanide       | Renegade Hardware | 1999 |\n+----------------|---------------|-------------------|------+\n```\n\n**Change the table styling:**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.put_column_meta(:all, align: :center)\n|\u003e Table.render!(header_separator_symbol: \"=\", horizontal_style: :all)\n|\u003e IO.puts\n```\n\n```\n+----------------|---------------|-------------------|------+\n|     Artist     |     Track     |       Label       | Year |\n+================+===============+===================+======+\n|    Konflict    |    Cyanide    | Renegade Hardware | 1999 |\n+----------------|---------------|-------------------|------+\n| Marcus Intalex |  Temperance   |      Soul:r       | 2004 |\n+----------------|---------------|-------------------|------+\n| Kryptic Minds  | The Forgotten |  Defcom Records   | 2007 |\n+----------------|---------------|-------------------|------+\n```\n\n_Available render options:_\n\n* `horizontal_style`: one of `:off`, `:frame`, `:header`, `:gfm` (GitHub Flavoured Markdown) or `:all`.\n* `vertical_style`: one of `:off`, `:frame` or `:all`.\n* `horizontal_symbol`: draws horizontal row separators.\n* `vertical_symbol`: draws vertical separators.\n* `intersection_symbol`: draws the symbol where horizontal and vertical\n  seperators intersect.\n* `top_frame_symbol`: draws the frame's top horizontal separator.\n* `title_separator_symbol`: draws the horizontal separator under the title.\n* `header_separator_symbol`: draws to draw the horizontal separator under the\n  header.\n* `bottom_frame_symbol`: draws the frame's bottom horizontal separator.\n\n**Set cell level meta (including for the header cells):**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.put_header_meta(0..4, align: :center) # row index(es)\n|\u003e Table.put_cell_meta(2, 1, align: :right) # column index, row index.\n|\u003e Table.render!\n|\u003e IO.puts\n```\n\n```\n+----------------|---------------|-------------------|------+\n|     Artist     |     Track     |       Label       | Year |\n+----------------|---------------|-------------------|------+\n| Konflict       | Cyanide       | Renegade Hardware | 1999 |\n| Marcus Intalex | Temperance    |            Soul:r | 2004 |\n| Kryptic Minds  | The Forgotten | Defcom Records    | 2007 |\n+----------------|---------------|-------------------|------+\n```\n\n**Set color for the column, header, and cell:**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.put_column_meta(0, color: :red) # sets column header to red, too\n|\u003e Table.put_header_meta(1..4, color: IO.ANSI.color(31))\n|\u003e Table.put_cell_meta(2, 1, color: [:green_background, :white])\n|\u003e Table.render!\n|\u003e IO.puts\n```\n\n_Supported color value types:_\n\n* atom: a named ANSI sequence defined in\n  [IO.ANSI](https://hexdocs.pm/elixir/IO.ANSI.html#content)\n* string: an embedded ANSI sequence\n* chardata: a list of atoms and/or strings\n* function: `(text, value) -\u003e text`\n  * where text is the padded value and where the value is a string\n  * **Note:** to render the correct padding, always format and return the text\n\n**Conditionally set a color:**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.put_column_meta(3, color: fn(text, value) -\u003e if value in [\"1999\", \"2007\"], do: [:blue, text], else: text end)\n|\u003e Table.render!\n|\u003e IO.puts\n```\n\n**Change/pass in your own renderer module:**\n\nThe default renderer is `TableRex.Renderer.Text`.\n\nCustom renderer modules must be behaviours of `TableRex.Renderer`.\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.render!(renderer: YourCustom.Renderer.Module)\n```\n\n**Go mad:**\n\n```elixir\nTable.new(rows, header)\n|\u003e Table.render!(horizontal_style: :all, top_frame_symbol: \"*\", header_separator_symbol: \"=\", horizontal_symbol: \"~\", vertical_symbol: \"!\")\n|\u003e IO.puts\n```\n\n```\n+****************+***************+*******************+******+\n! Artist         ! Track         ! Label             ! Year !\n+================+===============+===================+======+\n! Konflict       ! Cyanide       ! Renegade Hardware ! 1999 !\n+~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~+~~~~~~+\n! Marcus Intalex ! Temperance    ! Soul:r            ! 2004 !\n+~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~+~~~~~~+\n! Kryptic Minds  ! The Forgotten ! Defcom Records    ! 2007 !\n+----------------|---------------|-------------------|------+\n```\n\n## Run the tests\n\nWe have an extensive test suite which helps showcase project usage. For example:\nthe\n[quick render functions](https://github.com/djm/table_rex/blob/main/test/table_rex_test.exs),\n[table manipulation API](https://github.com/djm/table_rex/blob/main/test/table_rex/table_test.exs)\nor\n[the text renderer module](https://github.com/djm/table_rex/blob/main/test/table_rex/renderer/text_test.exs).\n\nTo run the test suite, from the project directory, do:\n\n```bash\nmix test\n```\n\n## Release package to Hex\n\nFirst, bump the semver version \u0026 write the changelog, pushing that commit.\n\nThen, tag HEAD with the version \u0026 push:\n\n```bash\ngit tag -a vx.x.x -m \"vx.x.x\"\ngit push --tags\n```\n\nThen login \u0026 publish to Hex:\n\n```bash\n# Ensure Hex is installed \u0026 updated\nmix local.hex --force\n\n# Login to hex to retrieve API Key\nmix hex.user auth\n\n# Ensure you have docs deps\nMIX_ENV=docs mix deps.get\n\n# Then publish by first setting to docs env to allow building to hexdocs.\nMIX_ENV=docs mix hex.publish\n```\n\n## Roadmap/Contributing\n\nFirst off, welcome \u0026 thanks!\n\nWe use the Github Issues tracker.\n\nIf you have found something wrong, please raise an issue.\n\nIf you'd like to contribute, check the issues to see where you can help.\n\nContributions are welcome from anyone at any time but if the piece of work is\nsignificant in size, please raise an issue first to avoid instances of wasted\nwork.\n\n## License\n\nMIT. See the [full license](LICENSE).\n\n## Thanks\n\n* Ryanz720, for the\n  [original T-Rex image](https://commons.wikimedia.org/wiki/File:Trex_Roar.jpg).\n\n* Everyone in #elixir-lang on freenode, for answering the endless questions.\n\n* All of our contributors.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjm%2Ftable_rex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdjm%2Ftable_rex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdjm%2Ftable_rex/lists"}