Liking cljdoc? Tell your friends :D

High-Level Table API

The clj-string-layout.table namespace is the easiest entry point for common tables. It lets you choose a named format, pass headers and rows, and describe columns without writing layout DSL strings.

(require '[clj-string-layout.table :as table])

Basic Usage

(table/table {:format :markdown
              :headers ["Name" "Qty"]
              :rows [["apple" 12]
                     ["pear" 4]]})
;; => ["| Name  | Qty |"
;;     "|:----- |:--- |"
;;     "| apple | 12  |"
;;     "| pear  | 4   |"]

Use table-str when the consumer wants one string:

(table/table-str {:format :plain
                  :headers ["Name" "Qty"]
                  :rows [["apple" 12]]})
;; => "Name   Qty\napple  12 "

Named Formats

Available formats are discoverable at runtime:

(table/formats)
;; => #{:plain :markdown :markdown-left :markdown-center :markdown-right
;;      :box :double-box :unicode-box :unicode-double-box
;;      :ascii-box :ascii-double-box :ascii-grid
;;      :csv :tsv :pipe :psql :org :rst :html}
FormatOutput
:plainWhitespace-separated aligned columns.
:markdownMarkdown pipe table.
:markdown-leftMarkdown pipe table with left-aligned columns.
:markdown-centerMarkdown pipe table with center-aligned columns.
:markdown-rightMarkdown pipe table with right-aligned columns.
:boxUnicode box-drawing table with ┌─┬─┐ borders. Aliases: :unicode-box, :ascii-box.
:double-boxUnicode box-drawing table with ╔═╦═╗ borders. Aliases: :unicode-double-box, :ascii-double-box.
:ascii-gridASCII +---+ table.
:csvComma-separated values, CSV-escaped by default.
:tsvTab-separated values.
:pipeCompact pipe-separated values.
:psqlPostgreSQL psql-style terminal table.
:orgOrg mode table.
:rstreStructuredText simple table.
:htmlHTML table with optional header row.

Map Rows And Column Specs

Column specs let you render maps directly and control titles, alignment, formatting, widths, and overflow.

(table/table {:format :markdown
              :columns [{:key :name :title "Name"}
                        {:key :qty :title "Qty" :align :right}]
              :rows [{:name "apple" :qty 12}
                     {:name "pear" :qty 4}]})
;; => ["| Name  | Qty |"
;;     "|:----- | ---:|"
;;     "| apple |  12 |"
;;     "| pear  |   4 |"]

Column keys for vector rows can be numeric indexes:

{:columns [{:key 0 :title "Name"}
           {:key 1 :title "Qty" :align :right}]}

Cell Formatting

Use :format on a column to transform values before rendering:

(table/table {:format :plain
              :columns [{:key :name :title "Name"}
                        {:key :price :title "Price"
                         :align :right
                         :format #(format "$%.2f" (double %))}]
              :rows [{:name "apple" :price 1.5}]})
;; => ["Name   Price"
;;     "apple  $1.50"]

Overflow Policies

Use :width with :overflow to constrain cell text before layout.

PolicyBehavior
:noneDefault. Leave long values unchanged.
:clipCut values at :width.
:ellipsisCut values and append ... where possible.
:wrapSplit values into multiple physical table rows.
:errorThrow ex-info when a value exceeds :width.
(table/table {:format :plain
              :columns [{:key 0 :title "Text" :width 4
                         :overflow :ellipsis}]
              :rows [["abcdef"]]})
;; => ["Text"
;;     "a..."]

Wrapping creates additional rows:

(table/table {:format :plain
              :columns [{:key 0 :title "Txt" :width 3
                         :overflow :wrap}]
              :rows [["abcdef"]]})
;; => ["Txt"
;;     "abc"
;;     "def"]

Escaping

The table API escapes by default for formats where raw values commonly break the syntax:

FormatEscaper
:markdownescape/markdown-cell
:csvescape/csv-cell
:tsvescape/tsv-cell
:orgescape/org-cell
:rstescape/rst-cell
:htmlescape/html

Set :escape? false if you already escaped values yourself.

(table/table {:format :html
              :headers ["<Name>"]
              :rows [["a&b"]]})
;; => ["<table>"
;;     "  <tr><th>&lt;Name&gt;</th></tr>"
;;     "  <tr><td>a&amp;b</td></tr>"
;;     "</table>"]

When To Use The DSL Directly

Use the high-level table API when you need common output formats quickly. Use clj-string-layout.core/layout directly when you need custom borders, multiple repeat groups, custom row predicates, or a format not represented by the table registry.

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close