Skip to content

Instantly share code, notes, and snippets.

@leok7v
Created January 6, 2023 08:22
Show Gist options
  • Save leok7v/b8ff88dcd5f36a742200568fcf293891 to your computer and use it in GitHub Desktop.
Save leok7v/b8ff88dcd5f36a742200568fcf293891 to your computer and use it in GitHub Desktop.
lorem ipsum generator in C
#include <assert.h>
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct {
char* text;
int32_t count; // at least 1KB
int32_t min_paragraphs; // at least 1
int32_t max_paragraphs;
int32_t min_sentences; // at least 1
int32_t max_sentences;
int32_t min_words; // at least 2
int32_t max_words;
} lorem_ipsum_generator_params_t;
#define countof(array) (sizeof(array) / sizeof(array[0]))
static void lorem_ipsum_generator(lorem_ipsum_generator_params_t p) {
assert(p.count >= 1024); // at least 1KB expected
assert(0 < p.min_paragraphs && p.min_paragraphs <= p.max_paragraphs);
assert(0 < p.min_sentences && p.min_sentences <= p.max_sentences);
assert(2 < p.min_words && p.min_words <= p.max_words);
static const char* words[] = { "lorem", "ipsum", "dolor", "sit", "amet",
"consectetur", "adipiscing", "elit", "quisque", "faucibus", "ex", "sapien",
"vitae", "pellentesque", "sem", "placerat", "in", "id", "cursus", "mi",
"pretium", "tellus", "duis", "convallis", "tempus", "leo", "eu", "aenean",
"sed", "diam", "urna", "tempor", "pulvinar", "vivamus", "fringilla", "lacus",
"nec", "metus", "bibendum", "egestas", "iaculis", "massa", "nisl",
"malesuada", "lacinia", "integer", "nunc", "posuere", "ut", "hendrerit",
"semper", "vel", "class", "aptent", "taciti", "sociosqu", "ad", "litora",
"torquent", "per", "conubia", "nostra", "inceptos", "himenaeos", "orci",
"varius", "natoque", "penatibus", "et", "magnis", "dis", "parturient",
"montes", "nascetur", "ridiculus", "mus", "donec", "rhoncus", "eros",
"lobortis", "nulla", "molestie", "mattis", "scelerisque", "maximus", "eget",
"fermentum", "odio", "phasellus", "non", "purus", "est", "efficitur",
"laoreet", "mauris", "pharetra", "vestibulum", "fusce", "dictum", "risus",
"blandit", "quis", "suspendisse", "aliquet", "nisi", "sodales", "consequat",
"magna", "ante", "condimentum", "neque", "at", "luctus", "nibh", "finibus",
"facilisis", "dapibus", "etiam", "interdum", "tortor", "ligula", "congue",
"sollicitudin", "erat", "viverra", "ac", "tincidunt", "nam", "porta",
"elementum", "a", "enim", "euismod", "quam", "justo", "lectus", "commodo",
"augue", "arcu", "dignissim", "velit", "aliquam", "imperdiet", "mollis",
"nullam", "volutpat", "porttitor", "ullamcorper", "rutrum", "gravida",
"cras", "eleifend", "turpis", "fames", "primis", "vulputate", "ornare",
"sagittis", "vehicula", "praesent", "dui", "felis", "venenatis", "ultrices",
"proin", "libero", "feugiat", "tristique", "accumsan", "maecenas", "potenti",
"ultricies", "habitant", "morbi", "senectus", "netus", "suscipit", "auctor",
"curabitur", "facilisi", "cubilia", "curae", "hac", "habitasse", "platea",
"dictumst"
};
char* s = p.text;
char* end = p.text + p.count - 64;
uint32_t paragraphs = p.min_paragraphs +
(p.min_paragraphs == p.max_paragraphs ? 0 :
random() % (p.max_paragraphs - p.min_paragraphs + 1));
while (paragraphs > 0 && s < end) {
uint32_t sentences_in_paragraph = p.min_sentences +
(p.min_sentences == p.max_sentences ? 0 :
random() % (p.max_sentences - p.min_sentences + 1));
while (sentences_in_paragraph > 0 && s < end) {
const uint32_t words_in_sentence = p.min_words +
(p.min_words == p.max_words ? 0 :
random() % (p.max_words - p.min_words + 1));
for (uint32_t i = 0; i < words_in_sentence && s < end; i++) {
const char* word = words[random() % countof(words)];
memcpy(s, word, strlen(word));
if (i == 0) { *s = (char)toupper(*s); }
s += strlen(word);
if (i < words_in_sentence - 1 && s < end) {
const char* delimiter = "\x20";
int32_t punctuation = random() % 128;
switch (punctuation) {
case 0:
case 1:
case 2: delimiter = ", "; break;
case 3:
case 4: delimiter = "; "; break;
case 6: delimiter = ": "; break;
case 7: delimiter = " - "; break;
default: break;
}
memcpy(s, delimiter, strlen(delimiter));
s += strlen(delimiter);
}
}
if (sentences_in_paragraph > 1 && s < end) {
memcpy(s, ".\x20", 2);
s += 2;
} else {
*s++ = '.';
}
sentences_in_paragraph--;
}
if (paragraphs > 1 && s < end) {
*s++ = '\n';
}
paragraphs--;
}
*s = 0;
}
int main() {
static char text[64 * 1024];
lorem_ipsum_generator_params_t p = {
.text = text,
.count = countof(text),
.min_paragraphs = 4,
.max_paragraphs = 15,
.min_sentences = 4,
.max_sentences = 20,
.min_words = 8,
.max_words = 16
};
srandom(time(NULL));
lorem_ipsum_generator(p);
printf("%s\n", p.text);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment