|
| 1 | +--- |
| 2 | +description: Transform your Clojure code into a beautiful, journal-style PDF, complete with math, charts, and images. |
| 3 | +category: clay |
| 4 | +tags: [clay, workflow, pdf] |
| 5 | +format: |
| 6 | + pdf: {title: 'Two Columns, One Namespace: Clojure to PDF'} |
| 7 | +date: '2025-08-21' |
| 8 | +toc: true |
| 9 | +classoption: [twocolumn] |
| 10 | +include-in-header: {text: '\AddToHook{env/Highlighting/begin}{\small}'} |
| 11 | +type: post |
| 12 | +geometry: [top=30mm, left=20mm, heightrounded] |
| 13 | +number-sections: true |
| 14 | +documentclass: article |
| 15 | +author: |
| 16 | + name: Timothy Pratley |
| 17 | + url: https://timothypratley.blogspot.com/p/httpswww.html |
| 18 | + image: https://avatars.githubusercontent.com/u/49298?v=4 |
| 19 | + email: timothypratley@gmail.com |
| 20 | + affiliation: |
| 21 | + - {name: Hummi, url: 'https://hummi.app'} |
| 22 | + links: |
| 23 | + - {icon: github, href: 'https://github.com/timothypratley'} |
| 24 | +colorlinks: true |
| 25 | + |
| 26 | +--- |
| 27 | +<style></style><style>.printedClojure .sourceCode { |
| 28 | + background-color: transparent; |
| 29 | + border-style: none; |
| 30 | +} |
| 31 | +</style><style>.clay-limit-image-width .clay-image {max-width: 100%} |
| 32 | +.clay-side-by-side .sourceCode {margin: 0} |
| 33 | +.clay-side-by-side {margin: 1em 0} |
| 34 | +</style> |
| 35 | +<script src="pdf.pdf_files/md-default0.js" type="text/javascript"></script><script src="pdf.pdf_files/md-default1.js" type="text/javascript"></script> |
| 36 | +--- |
| 37 | + |
| 38 | + |
| 39 | +::: {.sourceClojure} |
| 40 | +```clojure |
| 41 | +(require '[tablecloth.api :as tc]) |
| 42 | +``` |
| 43 | +::: |
| 44 | + |
| 45 | + |
| 46 | + |
| 47 | +::: {.sourceClojure} |
| 48 | +```clojure |
| 49 | +(require '[scicloj.tableplot.v1.plotly :as tp]) |
| 50 | +``` |
| 51 | +::: |
| 52 | + |
| 53 | + |
| 54 | + |
| 55 | +::: {.sourceClojure} |
| 56 | +```clojure |
| 57 | +(def quick-ds |
| 58 | + (tc/dataset {:category ["html" "pdf" "revealjs"] |
| 59 | + :value [42 73 58]})) |
| 60 | +``` |
| 61 | +::: |
| 62 | + |
| 63 | + |
| 64 | + |
| 65 | +::: {.sourceClojure} |
| 66 | +```clojure |
| 67 | +(-> quick-ds |
| 68 | + (tp/base {:=title "Instant Visuals"}) |
| 69 | + (tp/layer-bar {:=x :category |
| 70 | + :=y :value})) |
| 71 | +``` |
| 72 | +::: |
| 73 | + |
| 74 | + |
| 75 | + |
| 76 | + |
| 77 | +Example math: |
| 78 | + |
| 79 | +$$ |
| 80 | +\int_{0}^{1} x^2 dx = \frac{1}{3} |
| 81 | +$$ |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | + |
| 86 | +## Introduction |
| 87 | + |
| 88 | +Ever wanted your Clojure project to look like it just rolled off the press at a 19th-century scientific society? |
| 89 | +Or maybe you want to channel your inner Ada Lovelace or Alan Turing and make something that looks like it belongs in a library archive. |
| 90 | + |
| 91 | +This guide shows how to create a two-column, journal-style PDF from Clojure code using Clay. |
| 92 | +You'll see how to export a PDF, add math, and include charts and code blocks. |
| 93 | + |
| 94 | +--- |
| 95 | + |
| 96 | + |
| 97 | +## Making a PDF |
| 98 | + |
| 99 | +Make sure you set the quarto metadata on your namespace to `:format [:quarto :pdf]`, |
| 100 | +or if you prefer to build at the REPL, you can set the format in the options. |
| 101 | + |
| 102 | + |
| 103 | +::: {.sourceClojure} |
| 104 | +```clojure |
| 105 | +(comment |
| 106 | + (require '[scicloj.clay.v2.api :as clay]) |
| 107 | + (clay/make! |
| 108 | + {:source-path "scicloj/clay/pdf.clj" |
| 109 | + :format [:quarto :pdf]}) |
| 110 | + :-) |
| 111 | +``` |
| 112 | +::: |
| 113 | + |
| 114 | + |
| 115 | + |
| 116 | +## Why PDFs? |
| 117 | + |
| 118 | +PDFs are widely used for academic publishing, grant applications, and official documentation. |
| 119 | +They look the same everywhere and are easy to share. |
| 120 | +Sometimes you want a polished, typeset result, something worthy of Ada or Turing! |
| 121 | + |
| 122 | + |
| 123 | +## Quick PDF Export: Using Your Browser |
| 124 | + |
| 125 | +In most cases, the fastest and most reliable way to create a PDF is to use your browser's built-in "Print" or "Save as PDF" feature: |
| 126 | + |
| 127 | +1. Open your Clay-generated HTML page in your web browser. |
| 128 | +2. Press `Cmd+P` (Mac) or `Ctrl+P` (Windows/Linux) to open the print dialog. |
| 129 | +3. Select "Save as PDF" or "Print to PDF" as the destination/printer. |
| 130 | +4. Adjust layout, margins, and other options as needed. |
| 131 | +5. Click "Save" to export your PDF. |
| 132 | + |
| 133 | +This method works well for most reports, blog posts, and slideshows, and preserves the look of your HTML output. |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | + |
| 138 | +## Using the PDF format |
| 139 | + |
| 140 | +But for a traditional, journal-style PDF (e.g., two columns, custom fonts, LaTeX typesetting), use `[:format :pdf]`. |
| 141 | +Some features won't work quite the same, feel free to let us know if you run into issues. |
| 142 | + |
| 143 | + |
| 144 | +## Prerequisites |
| 145 | + |
| 146 | +- Install a TeX distribution (e.g., TinyTeX: `quarto install tinytex`) |
| 147 | +- Install Quarto (https://quarto.org/docs/get-started/) |
| 148 | +- Python and the modules plotly and kaleido |
| 149 | + |
| 150 | + |
| 151 | +## Example: 2-Column Journal Style via Namespace Metadata |
| 152 | + |
| 153 | +The options for a 2-column journal style PDF are now set in the namespace metadata above. |
| 154 | +See the ^{:clay ...} metadata on this namespace for a working example. |
| 155 | + |
| 156 | +- `:documentclass "article"` is standard for journal articles. |
| 157 | +- `:classoption ["twocolumn"]` enables two-column layout. |
| 158 | +- `:mainfont` sets the main text font (requires XeLaTeX or LuaLaTeX). |
| 159 | +- `:geometry` customizes page margins. |
| 160 | +- `:toc` and `:number-sections` add a table of contents and section numbering. |
| 161 | + |
| 162 | + |
| 163 | +## Showcase: Math, Style, and Substance |
| 164 | + |
| 165 | +Inline math: $E = mc^2$ (because every science article needs it!) |
| 166 | + |
| 167 | +Display math: |
| 168 | + |
| 169 | +$$ |
| 170 | +\int_{-\infty}^{\infty} e^{-x^2} dx = \sqrt{\pi} |
| 171 | +$$ |
| 172 | + |
| 173 | +Or a system of equations: |
| 174 | + |
| 175 | +$$ |
| 176 | +\begin{aligned} |
| 177 | + a^2 + b^2 &= c^2 \\ |
| 178 | + e^{i\pi} + 1 &= 0 |
| 179 | +\end{aligned} |
| 180 | +$$ |
| 181 | + |
| 182 | +You can add figures, tables, and code blocks using Clojure code. |
| 183 | + |
| 184 | +For more details and advanced options, see the [Quarto PDF documentation](https://quarto.org/docs/output-formats/pdf-basics.html). |
| 185 | + |
| 186 | +--- |
| 187 | + |
| 188 | + |
| 189 | +## Visualizing Data: Adding Charts to Your PDF |
| 190 | + |
| 191 | +A journal-style PDF can include charts alongside your narrative and code. |
| 192 | +Let's create a simple dataset and visualize it using Tablecloth and Tableplot: |
| 193 | + |
| 194 | + |
| 195 | +::: {.sourceClojure} |
| 196 | +```clojure |
| 197 | +(def scatter-ds |
| 198 | + (tc/dataset {:x [1 2 3 4 5] |
| 199 | + :y [10 20 15 25 18] |
| 200 | + :z [1 2 1 2 1]})) |
| 201 | +``` |
| 202 | +::: |
| 203 | + |
| 204 | + |
| 205 | + |
| 206 | +::: {.sourceClojure} |
| 207 | +```clojure |
| 208 | +(-> scatter-ds |
| 209 | + (tp/base {:=title "Sample Scatter Plot"}) |
| 210 | + (tp/layer-point {:=x :x |
| 211 | + :=y :y |
| 212 | + :=color :z})) |
| 213 | +``` |
| 214 | +::: |
| 215 | + |
| 216 | + |
| 217 | + |
| 218 | + |
| 219 | +Tableplot lets you create histograms, scatter plots, bar charts, and more. |
| 220 | +These charts will appear in your PDF just as they do in your HTML output. |
| 221 | +For more advanced visualizations, see the Tableplot and Plotly documentation. |
| 222 | + |
| 223 | +--- |
| 224 | + |
| 225 | + |
| 226 | +## Conclusion |
| 227 | + |
| 228 | +For most needs, browser-based PDF export is fast and easy. |
| 229 | +For more traditional style typeset PDFs, set `[:format :pdf]` to get a PDF file. |
| 230 | + |
| 231 | + |
| 232 | +```{=html} |
| 233 | +<div style="background-color:grey;height:2px;width:100%;"></div> |
| 234 | +``` |
| 235 | + |
| 236 | + |
| 237 | + |
| 238 | +```{=html} |
| 239 | +<div><pre><small><small>source: <a href="https://github.com/ClojureCivitas/clojurecivitas.github.io/blob/main/src/scicloj/clay/pdf.clj">src/scicloj/clay/pdf.clj</a></small></small></pre></div> |
| 240 | +``` |
0 commit comments