Lorem Ipsum Generator — Zig source
Generate placeholder Lorem Ipsum text - paragraphs and sentences with adjustable counts. Classic Latin word pool, instant copy.
This is the Zig implementation — the same logic the interactive tool runs, in a shareable, citable form.
// lorem-ipsum — Zig port: canonical Lorem Ipsum generator (sentences, paragraphs, blocks).
const std = @import("std");
// The canonical word pool — identical across every port.
const words = [_][]const u8{
"lorem", "ipsum", "dolor", "sit", "amet", "consectetur", "adipiscing", "elit",
"sed", "do", "eiusmod", "tempor", "incididunt", "ut", "labore", "et",
"dolore", "magna", "aliqua", "enim", "ad", "minim", "veniam", "quis",
"nostrud", "exercitation", "ullamco", "laboris", "nisi", "aliquip", "ex", "ea",
"commodo", "consequat", "duis", "aute", "irure", "in", "reprehenderit",
"voluptate", "velit", "esse", "cillum", "eu", "fugiat", "nulla", "pariatur",
"excepteur", "sint", "occaecat", "cupidatat", "non", "proident", "sunt",
"culpa", "qui", "officia", "deserunt", "mollit", "anim", "id", "est", "laborum",
};
// DefaultPrng is non-crypto, matching the TS source's Math.random().
const Lorem = struct {
prng: std.Random.DefaultPrng,
fn init(seed: u64) Lorem {
return .{ .prng = std.Random.DefaultPrng.init(seed) };
}
// Uniform integer in [0, n); 0 for n == 0 so callers never divide by zero.
fn randBelow(self: *Lorem, n: usize) usize {
return if (n == 0) 0 else self.prng.random().uintLessThan(usize, n);
}
// One capitalized sentence of min_words..max_words random words.
fn sentence(self: *Lorem, a: std.mem.Allocator, min_words: usize, max_words: usize) ![]u8 {
// Saturating subtraction collapses a reversed range to exactly
// min_words words, matching the TS max(1, ...) guard.
const span = @max(1, (max_words + 1) -| min_words);
const n = min_words + self.randBelow(span);
var buf = std.ArrayList(u8).init(a);
const w = buf.writer();
for (0..n) |i| {
if (i != 0) try w.writeByte(' ');
try w.writeAll(words[self.randBelow(words.len)]);
}
// Capitalize the first character only — the tail keeps its spelling.
if (buf.items.len != 0) buf.items[0] = std.ascii.toUpper(buf.items[0]);
try w.writeByte('.');
return buf.toOwnedSlice();
}
// sentences default-length (8..16 word) sentences joined by spaces.
fn paragraph(self: *Lorem, a: std.mem.Allocator, sentences: usize) ![]u8 {
var buf = std.ArrayList(u8).init(a);
const w = buf.writer();
for (0..sentences) |i| {
if (i != 0) try w.writeByte(' ');
const s = try self.sentence(a, 8, 16);
defer a.free(s);
try w.writeAll(s);
}
return buf.toOwnedSlice();
}
fn text(self: *Lorem, a: std.mem.Allocator, paragraphs: usize, per_para: usize) ![]u8 {
var buf = std.ArrayList(u8).init(a);
const w = buf.writer();
for (0..paragraphs) |i| {
if (i != 0) try w.writeAll("\n\n");
const p = try self.paragraph(a, per_para);
defer a.free(p);
try w.writeAll(p);
}
return buf.toOwnedSlice();
}
};
pub fn main() !void {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const a = arena.allocator();
var generator = Lorem.init(0x5EED);
const out = try generator.text(a, 3, 5);
try std.io.getStdOut().writer().print("{s}\n", .{out});
}
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →