|
48 | 48 | [v] |
49 | 49 | (str/replace (json/generate-string v) "<" "\\u003c")) |
50 | 50 |
|
51 | | -(defn- render-table-html |
52 | | - "Render tabular data as a plain HTML table. |
| 51 | +(defn- escape-cell |
| 52 | + "Escape a value for use inside a Pandoc pipe-table cell." |
| 53 | + [v] |
| 54 | + (-> (str v) |
| 55 | + (str/replace "|" "\\|") |
| 56 | + (str/replace "\n" "<br>"))) |
| 57 | + |
| 58 | +(defn- render-table-md |
| 59 | + "Render tabular data as a Pandoc pipe-table markdown string. |
| 60 | + Targets markdown so Quarto's table styling applies natively. |
53 | 61 |
|
54 | 62 | Accepts two shapes: |
55 | 63 | {:column-names [...] :row-vectors [[...] ...]} (Tablecloth-ish) |
|
65 | 73 | (let [ks (vec (distinct (mapcat keys v)))] |
66 | 74 | (cons ks (map (fn [m] (mapv #(get m %) ks)) v))))] |
67 | 75 | (when rows |
68 | | - (str (hiccup/html |
69 | | - [:table |
70 | | - [:thead [:tr (for [c (first rows)] [:th (str c)])]] |
71 | | - [:tbody (for [r (rest rows)] |
72 | | - [:tr (for [c r] [:td (str c)])])]]))))) |
| 76 | + (let [row-md (fn [r] (str "| " (str/join " | " (map escape-cell r)) " |")) |
| 77 | + sep (str "|" (str/join "|" (repeat (count (first rows)) "---")) "|")] |
| 78 | + (str/join "\n" |
| 79 | + (concat [(row-md (first rows)) sep] |
| 80 | + (map row-md (rest rows)))))))) |
73 | 81 |
|
74 | 82 | (defn render-by-kind |
75 | 83 | "Pick a Lua-side rendering format for `v` based on `kind`. |
|
125 | 133 | {:format "chart" :lib "highcharts" :rendered (script-safe-json v)} |
126 | 134 |
|
127 | 135 | :kind/table |
128 | | - (if-let [html (render-table-html v)] |
129 | | - {:format "raw-html" :rendered html} |
| 136 | + (if-let [md (render-table-md v)] |
| 137 | + {:format "markdown" :rendered md} |
130 | 138 | {:error (str ":kind/table: value is not recognized as table data. " |
131 | 139 | "Expected {:column-names [...] :row-vectors [[...] ...]} " |
132 | 140 | "or a sequence of maps. Got: " (pr-str v))}) |
|
0 commit comments