(ns tc-md-example
(:require
[nextjournal.clerk :as clerk]
[tech.v3.dataset.print :as p]
[tablecloth.api :as tc]))

Markdown Tables

You can create markdown tables by concating some strings together like so.

The syntax for markdown tables is here.

(clerk/md
(str
"| Foo | Bar | Baz |\n"
"| :--- | :---: | ---: |\n"
"| foo | bar | 12.00 |\n"
"| quz | quux | 1.0 |\n"))
FooBarBaz
foobar12.00
quzquux1.0

This means you can also get data out of a tablecloth/tech.ml dataset and format it too.

(defn md-row
[v]
(str "| " (apply str (interpose " | " v)) " |\n"))
#object[tc_md_example$md_row 0x3f1d3284 "
tc_md_example$md_row@3f1d3284"
]
(defn md-table
[{:keys [columns alignment-spec data]}]
(clerk/md
(apply
str
(into [(md-row columns)
(md-row alignment-spec)]
(comp
(map
(fn [row]
((apply juxt
(map (fn [column] (fn [m] (m column))) columns))
row)))
(map md-row))
(tc/rows data :as-maps)))))
#object[tc_md_example$md_table 0x22f50fc5 "
tc_md_example$md_table@22f50fc5"
]
(md-table
{:columns ["Foo" "Bar" "Baz"]
:alignment-spec [":---" ":---:" "---:"]
:data (tc/dataset {"Foo" ["foo0" "foo1" "foo2"]
"Bar" ["bar0" "bar1" "bar2"]
"Baz" [12.0 1.00 1.01]})})
FooBarBaz
foo0bar012.0
foo1bar11.0
foo2bar21.01

You can also use p/dataset->str with {:print-line-policy:markdown}

You need to strip out the table name as well if you don’t want that.

You can do that with this lovely multiline java regular expression:

#"^(?s).+\n\n(.+)"

The (?s) at the front makes it multiline.

(clerk/md
(as-> (tc/dataset {"Foo" ["foo0" "foo1" "foo2"]
"Bar" ["bar0" "bar1" "bar2"]
"Baz" [12.0 1.00 1.01]}) $
(p/dataset->str $ {:print-line-policy :markdown})
(re-find #"^(?s).+\n\n(.+)" $) ;; strip out the dataset name
(last $)))
FooBarBaz
foo0bar012.00
foo1bar11.00
foo2bar21.01