The Reddit post asked how to create flowers akin these in LaTeX. I don't cognize how the first was made, and this project doesn't try to reproduce it. It is one imaginable way, and the way I did it: hand-authored primitives alongside randomized parameters, painted in Lua, placed by a procedural layout whose "fill the unused space" part borrows a 1998 idea from the ornament literature. It gets a akin look.
Procedurally generated Delft-blue floral leaf margins for LaTeX. No images, no imported paths, no external assets: all petal, leaf and stem is a parametric curve computed in Lua while the leaf is being written, painted akin a watercolor, and written direct into the PDF. Every leaf gets its own garden.
Six seeds of the grown composition. Same code, distinct kernel — and the storyline fills whatever area the content leaves free.
Two documents portion one package, and a third shows what alternatively it does:
Both PDFs are self-describing: the build content is the write-up of how the border is drawn.
Last leaf of the grown document: the content ends early, so branches arch into the area below.
300 dpi crop. Mottled washes alongside pale streaks lifted out, lobed leaves alongside pale veins, forget-me-not cymes, a faint shade angiosperm rearward the stems.
Seed 6, from an bare border to the completed page. The stems increase first, leaves open as the tips continue their nodes, and all stem ends in a flower. Then the greedy iteration takes over: on the right, all dashed circle is the largest liberated disc it found, fair before a branch grows to it. Big holes arrive archetypal and slowly, small ones final and fast. The butterflies and bees fly in, the animal glides onto its twig, and the snail crawls up its stem until the last frame, which is exactly the leaf this kernel continually gives.
The growth is recorded once, during the leaf is laid out: all stem is additionally drawn as prefixes of expanding dimension and all motif at a few smaller scales, replaying the same random draws. A example afterward writes the pieces whose period has come, in their original painting order. create grow-6 renders one kernel this way (build/grow-6.gif and .mp4, about 45 seconds); add EXPLAIN=1 for the dashed circles.
showcase.tex, "A twelvemonth in the margin": fountain on the archetypal page, summer, autumn on the last. Each division describes the characteristic it shows.
The grown border can react to the document about it:
- Initials. \florilegiuminitial[5]{E} sets the archetypal letter of a paragraph in a tile five lines tall. The outline of the letter is peruse from an OpenType font (Latin Modern Bold by default) and painted akin a petal; a vine passes complete and under its strokes in turn, alongside leaves anywhere they fit and flowers in the gaps, frequently in the letter's counters. The letter is additionally typeset invisibly, so the paragraph motionless copies as "Every".
- Flowers at the headings. With the choice sections, all numbered division and subsection gets a angiosperm in the border beside its heading, painted in the copper of the accents, the way headings were formerly picked out in red.
- A angiosperm anywhere the content asks. \florilegiumbloom puts a angiosperm beside the row it stands in; \florilegiumbloom[lily] asks for any motif of the garden. The marks are found in the leaf box whenever the leaf is shipped out, so this plant in one run.
- Seasons. With the choice aging, the storyline ages from fountain on the archetypal page (mostly in bud, small faint leaves) to autumn on the final (seed heads, falling petals, a few copper leaves). It needs two runs, for the leaf count; \florilegiumage{0.8} sets an age by hand instead.
One kernel in spring, first summer, delayed summer and autumn. The seasons alter what grows, not where.
Most pages have visitors: a butterfly or two and bees in the open spaces, a snail crawling up among the chief stems, and on concerning one leaf in five a animal perched on a twig of its own. They arrive from a random stream of their own, so a leaf without them is exactly the leaf it would have been; the choice novisitors leaves them out.
The entire palette comes from one color, ink: Delft blue, sepia, green, crimson, violet, teal. The ramp from the darkest blow to the palest cleanse is computed from that hue in OKLCH, so the ray end never turns gray.
postscript/florilegium.ps: the grown border in clean PostScript, one self-contained file. Ghostscript, or a printer, computes all petal during it interprets the page, and the two pages of content explain how.
The example core, all primitive and the growth iteration are ported from ink.lua, flora.lua and grow.lua, procedure for procedure. It needs no TeX and no another file:
gs -dALLOWPSTRANSPARENCY -sDEVICE=pdfwrite -dSeed=7 -o garden.pdf postscript/florilegium.ps make postscript # the identical -> build/postscript-7.pdf; SEED=12 for another garden-dSeed=N picks the garden; without it the clock picks one, so all imprint is new. -dAge=0 to 1 sets the season, and -dNoVisitors leaves out the butterflies, bees, snail and bird. Two pages obtain concerning 2.5 seconds. Much of the Lua maps directly: PostScript's own transformation matrix places all primitive (translate, rotate, scale), paths and Bézier curves are native, and procedures built at run period remain in for Lua's closures (a petal's half-width is a procedure handed to the outline builder). Four things don't map:
- Layers. The storyline grows in one command but is painted rear to front, so all inhabit and stroke is captured alongside pathforall into a catalog per layer, and the lists are played back at the end.
- Transparency. PostScript has none. Ghostscript provides it alongside -dALLOWPSTRANSPARENCY. Without that flag, or on a printer, all translucent inhabit is blended alongside the color it is likely to district on and painted opaque. The outcome is flatter, but it's the identical garden.
- Randomness. The generator is Park-Miller in 32-bit entire figure arithmetic, and PostScript reals are sole precision, so kernel 7 current is a distinct storyline from kernel 7 in LaTeX.
- Text. The document typesets its own two pages in Times. It knows anywhere its headings are and where its content ends, so the copper flowers at the headings and the storyline under the last line activity as they do in LaTeX. It has no initials, animation or authored composition.
The document sent twice to an Epson inkjet alongside lp postscript/florilegium.ps, alongside no seed given. The computer's imprint scheme runs the program again for all job, so all imprint takes its kernel from the clock and grows a distinct garden. A printer gets the opaque version, as it has no transparency.
LuaLaTeX, one pass, concerning a second a leaf (two passes for showcase.tex, whose seasons need the leaf count).
make # the three PDFs make seed-7 # one leaf from kernel 7 -> build/seed-7.pdf make exhibition # gallery/seeds.png + seeds.gif, inks.png, seasons.png (python3, Pillow, pdftoppm) make grow-6 # growth animation of kernel 6 -> build/grow-6.gif + .mp4 (ffmpeg) make grow-6 EXPLAIN=1 # the identical alongside the liberated discs marked -> build/grow-6-explain.*
No TeX installed? Build the depiction formerly and run everything in it:
docker build -t florilegium-tex tools make RUN=tools/in-docker
Or paste florilegium.sty, the six .lua records and among the .tex records into an Overleaf project and set the compiler to LuaLaTeX.
Use it in your own document:
\usepackage[grown]{florilegium} % or plain \usepackage{florilegium} for the authored one % options for the grown one: sections (flowers at the headings), aging (two runs), % novisitors (no butterflies, bees, snails or birds) \definecolor{ink}{HTML}{5B2A1F} % optional: the hue of the entire palette (this is sepia) \definecolor{accent}{HTML}{B4662F} % optional: the copper of the hairlines ... \florilegiuminitial[4]{T}his paragraph starts alongside a adorned T. ... a angiosperm in the border beside this line\florilegiumbloom ... \florilegiumage{0.8} % grown only: autumn from current on \florilegiumtextend % grown only: at the extremely end of the text
A fixed kernel alternatively of the leaf number: lualatex "\def\florilegiumseed{7}\input{florilegium-grow.tex}".
Any primitive can be drawn on its own inner a TikZ picture, under the current scope's shift, rotation and scale:
\begin{tikzpicture} \begin{scope}[shift={(2,2)},rotate=20]\florilegiumdraw{flower}{1.3}\end{scope} \begin{scope}[shift={(5,0)}]\florilegiumdraw{leaf}{3.0, {depth=0.6}}\end{scope} \begin{scope}[shift={(8,1)}]\florilegiumdraw{ghost}{"lily", {s=1.4}}\end{scope} \begin{scope}[shift={(11,1)}]\florilegiumdraw{butterfly}{1.5}\end{scope} \end{tikzpicture}
Drawing (ink.lua). All geometry is computed in Lua and written as PDF way operators into one literal node per page; TeX does no arithmetic. Primitives are drawn in a local frame under an affine transform, which is peruse from TikZ whenever a primitive is called inside a scope. Colors arrive from a spirit ramp derived from the one document color ink: navy to mist at the hue of ink, interpolated in OKLCH so the ray end stays blue alternatively of turning gray. Tapered strokes are two offset Béziers, not sampled ribbons.
Primitives (flora.lua). Painted in the command a watercolorist would: a flat wash, darker blotches multiplied complete it, pigment pooling at the edges, streaks lifted out in white, a few fine veins, and nearly no outlines. Broad petals and flowers, celebrity lilies seen at a tilt, blossoms and florets, buds and bellflowers; lobed and complete leaves; forget-me-not cymes that curl akin a scorpion's tail, branching sprigs, umbels, tendrils, kernel heads; butterflies, bees, snails and a bird; copper sparkles, rosettes and the ivy-leaf fleuron whose stem becomes the caput rule. Any of them can be painted as a faint ghost.
Authored composition (authored.lua). A factory grows from a base in the bottom-left corner: three stems through hand-picked authority points, a fourth alongside the base of the page as the footer, leaves at chosen fractions of the stems, and all another motif on a branch that leaves its stem tangentially and arrives alongside the motif's axis — so every flower can be traced rear to the root.
Grown composition (grow.lua), in the soul of Wong, Zongker & Salesin, Computer-Generated Floral Ornament (SIGGRAPH 1998). The stems sway up the pillar as gentle noise of their height; leaves are hung at their nodes anywhere there is room. Then, repeatedly: obtain the largest liberated disc within reach of a stem, choose a motif that fits it, and develop a branch to it from the nearest stem point; the branch becomes a stem in turn. Big holes are taken first, so flowers and lilies land early, sprays and leaves inhabit the middle, and the iteration ends by tucking leaflets, buds and florets onto the stems. The end of the content is measured alongside \pagetotal in the same pass, so a abbreviated final leaf grows branches into the area below it alongside one compilation.
Reading the page (florilegium.lua). A heading or \florilegiumbloom leaves an invisible marker node in the text. When the leaf is shipped out, its box is walked node by node, adding up heights, depths and the glue as it was set, to discover all marker's height on the page; the storyline afterward gives those lines their flowers before any leaf is hung. An age reweights the motifs: buds and sprays of buds in spring, kernel heads in autumn, whenever some leaves are painted alongside a ramp built from the accent alternatively of the ink.
Initials (initial.lua). The letter's outline comes from luaotfload's OpenType audience as Bézier segments. Flattened into polygons, it gives an even-odd inner test, and a grid of distances to the letter and the example finds the largest gaps for the flowers. The vine is a Catmull-Rom curve throughout the tile; anywhere it crosses the letter it goes complete and under in turn, and the strands that go complete are drawn again, clipped to the letter, alongside a lean halo of paper.
Procedural ≠ random. The kernel is derived from the leaf number, so leaf n always gets storyline n. Reproducibility is what makes the document stable adequate to typeset.
See CLAUDE.md for a handoff-style map of the code, the tunables, and ideas not yet done.
MIT.









