lipsum-cpp 0.5.4
A basic library written in C++ for generating placeholder Lorem Ipsum text.
Loading...
Searching...
No Matches
generator.inl
Go to the documentation of this file.
1
13#pragma once
14
15#include "core/internal.hpp"
16#include "generatorcore.inl"
17#include "generatorformats.inl"
18
19#ifndef LIPSUM_MIN_BUILD
20static std::string ClearApostrAndCh(char letter, const std::string& str)
21{
22 std::string ret;
23 ret.reserve(str.size());
24 for (const char& let : str)
25 {
26 if (let != '\'' && let != letter)
27 {
28 ret.push_back(let);
29 }
30 }
31 return ret;
32}
33
34static std::string
35ClearApostrAndCh(char let1, char let2, const std::string& str)
36{
37 std::string ret;
38 ret.reserve(str.size());
39 for (const char& let : str)
40 {
41 if (let != '\'' && let != let1 && let != let2)
42 {
43 ret.push_back(let);
44 }
45 }
46 return ret;
47}
48
49static std::string CapitalizeStr(const std::string& str)
50{
51 std::string ret = str;
52 for (auto& letter : ret)
53 {
54 letter = LPSM_SAFE_CCTYPE(char, std::toupper, letter);
55 }
56 return ret;
57}
58#endif
59
60namespace lipsum
61{
62
63 /*
64 * CORE
65 */
66
67 std::string Generator::word(int num)
68 {
69
70 std::string ret;
71
72 if (num < 0)
73 {
74 internal::LogWarn(internal::LogType::Warn,
75 "lpsm::Generator::word(): expected num >= 0, "
76 "got ",
77 num);
78 }
79
80 for (int i = 0; i < num; ++i)
81 {
82 ret += m_Source.random_word(m_Gen, m_Settings.lazy) += " ";
83 }
84
85 if (!ret.empty())
86 {
87 ret.pop_back();
88 }
89 return ret;
90 }
91
92 std::string Generator::fragment()
93 {
94 int numWords = m_Settings.word.roll(m_Gen, m_Settings.lazy);
95 return word(numWords);
96 }
97
98 std::string Generator::sentence(int num, bool useLipsum)
99 {
100 std::string result;
101
102 if (num < 0)
103 {
104 internal::LogWarn(internal::LogType::Warn,
105 "lpsm::Generator::sentence(): expected num "
106 ">= 0, got ",
107 num);
108 }
109
110 for (int i = 0; i < num; ++i)
111 {
112 if (i == 0 && useLipsum)
113 {
114 result += GenerateDefaultLipsumSentence() + " ";
115 }
116 else
117 {
118 result += single_sentence(m_Settings.word, m_Settings.frag) +=
119 " ";
120 }
121 }
122 return result;
123 }
124
125 std::string Generator::paragraph(int num, bool useLipsum)
126 {
127 std::string result;
128
129 if (num < 0)
130 {
131 internal::LogWarn(internal::LogType::Warn,
132 "lpsm::Generator::paragraph(): expected num "
133 ">= 0, got ",
134 num);
135 }
136
137 for (int i = 0; i < num; ++i)
138 {
139 if (i == 0 && useLipsum)
140 {
141 result += single_paragraph(USELIPSUM);
142 }
143 else
144 {
145 result += single_paragraph(NO_USELIPSUM);
146 }
147 }
148 return result;
149 }
150
151 std::string Generator::text(bool useLipsum)
152 {
153 int num = m_Settings.para.roll(m_Gen, m_Settings.lazy);
154 return paragraph(num, useLipsum);
155 }
156
157#ifndef LIPSUM_MIN_BUILD
158 /*
159 * MISC
160 */
161
162 std::string Generator::scramble(int length, char minChar, char maxChar)
163 {
164 std::string ret;
165 if (length < 0)
166 {
167 internal::LogWarn(internal::LogType::Warn,
168 "lpsm::Generator::scramble(): expected length >= "
169 "0, "
170 "got ",
171 length);
172 }
173 else
174 {
175 ret.reserve(length);
176 }
177 for (int i = 0; i < length; ++i)
178 {
179 ret.push_back(random_number(minChar, maxChar));
180 }
181 return ret;
182 }
183
184 std::string Generator::url()
185 {
186 return std::string("https://") + plain_url() + std::string("/#") +
187 slug('-');
188 }
189
191 {
192 return std::string("lpsmcpp-") +
193 m_Source.random_word(m_Gen, m_Settings.lazy) + tld();
194 }
195
196 std::string Generator::email()
197 {
198 return m_Source.random_word(m_Gen, m_Settings.lazy) + std::string(".") +
199 m_Source.random_word(m_Gen, m_Settings.lazy) + std::string("@") +
200 plain_url();
201 }
202
203 std::string Generator::slug(char separator)
204 {
205 std::string result;
206 int numWords = m_Settings.wordURL.roll(m_Gen, m_Settings.lazy);
207 result = word(numWords);
208 std::replace(result.begin(), result.end(), ' ', separator);
209 return result;
210 }
211
213 {
214 std::string ret;
215 std::string innerWord;
216 int numWords = -2;
217 switch (case_)
218 {
219 case CaseSlugCase::CamelCase:
220 {
221 numWords = m_Settings.wordURL.roll(m_Gen, m_Settings.lazy);
222 ret += m_Source.random_word(m_Gen, m_Settings.lazy);
223 --numWords;
224 [[fallthrough]];
225 }
226 case CaseSlugCase::PascalCase:
227 {
228 if (numWords == -2)
229 {
230 numWords = m_Settings.wordURL.roll(m_Gen, m_Settings.lazy);
231 }
232 for (int i = 0; i < numWords; ++i)
233 {
234 innerWord = ClearApostrAndCh(
235 '-',
236 '_',
237 m_Source.random_word(m_Gen, m_Settings.lazy));
238 innerWord.at(0) = LPSM_SAFE_CCTYPE(char,
239 std::toupper,
240 innerWord.at(0));
241 ret += innerWord;
242 }
243 break;
244 }
245 case CaseSlugCase::SnakeCase:
246 {
247 ret = ClearApostrAndCh('-', slug('_'));
248 break;
249 }
250 case CaseSlugCase::ShoutyCase:
251 {
252 ret = CapitalizeStr(ClearApostrAndCh('-', slug('_')));
253 break;
254 }
255 case CaseSlugCase::KebabCase:
256 {
257 ret = ClearApostrAndCh('_', slug('-'));
258 break;
259 }
260 case CaseSlugCase::TrainCase:
261 {
262 ret = CapitalizeStr(ClearApostrAndCh('_', slug('-')));
263 break;
264 }
265 }
266 return ret;
267 }
268
270 {
271 std::string ret;
272 std::vector<std::string> varNames;
273 std::string mainNamespace =
274 scramble(m_Settings.wordURL.roll(m_Gen, m_Settings.lazy),
275 'a',
276 'z');
277 int numStatements = m_Settings.point.roll(m_Gen, m_Settings.lazy);
278 if (numStatements <= 0)
279 {
280 internal::LogWarn(internal::LogType::Warn,
281 "lpsm::Generator::code(): expected numStatements "
282 "> 0, got ",
283 numStatements);
284 }
285
286 auto varBlock = [&](CaseSlugCase varCase,
287 CaseSlugCase funcCase,
288 const std::string& varDeclarer,
289 const std::string& namespSep)
290 {
291 for (int i = 0; i < numStatements; ++i)
292 {
293 varNames.push_back(case_slug(varCase));
294 ret += varDeclarer + varNames.back() + std::string(" = ") +
295 mainNamespace + namespSep + case_slug(funcCase) +
296 "();\n";
297 }
298 };
299
300 auto cppBlock = [&]()
301 {
302 ret += std::string("#include <") + mainNamespace +
303 std::string("/") + mainNamespace + ".hpp>\n";
304 ret += "#include <iostream>\nint main()\n{\n";
305 ret += std::string(" // ") +
306 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt) +
307 "\n";
308 varBlock(CaseSlugCase::CamelCase,
309 CaseSlugCase::PascalCase,
310 " auto ",
311 "::");
312 ret += " std::cout";
313 for (int i = 0; i < numStatements; ++i)
314 {
315 ret += std::string(" << ") + varNames.at(i) + " << ' '";
316 }
317 ret += " << '\\n';\n return 0;\n}";
318 };
319
320 auto pyBlock = [&]()
321 {
322 ret += std::string("import ") + mainNamespace + "\n";
323 ret += "if __name__ == \"__main__\":\n";
324 ret += std::string(" # ") +
325 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt) +
326 "\n";
327 // pyVars();
328 varBlock(CaseSlugCase::SnakeCase,
329 CaseSlugCase::SnakeCase,
330 " ",
331 ".");
332 ret += " print(f\"";
333 for (int i = 0; i < numStatements; ++i)
334 {
335 ret += std::string("{") + varNames.at(i) + std::string("} ");
336 }
337 ret += "\")\n";
338 };
339
340 auto rsBlock = [&]()
341 {
342 ret += std::string("use ") + mainNamespace + ";\n";
343 ret += "fn main()\n{\n";
344 ret += std::string(" // ") +
345 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt) +
346 "\n";
347 // rsVars();
348 varBlock(CaseSlugCase::SnakeCase,
349 CaseSlugCase::SnakeCase,
350 " let ",
351 "::");
352 ret += " println!(\"";
353 for (int i = 0; i < numStatements; ++i)
354 {
355 ret += std::string("{} ");
356 }
357 ret += "\"";
358 for (int i = 0; i < numStatements; ++i)
359 {
360 ret += std::string(", ") + varNames.at(i);
361 }
362 ret += ");\n}";
363 };
364
365 auto cBlock = [&]()
366 {
367 ret += std::string("#include <") + mainNamespace +
368 std::string("/") + mainNamespace + ".h>\n";
369 ret += "#include <stdio.h>\n";
370 ret += "int main(void)\n{\n";
371 ret += std::string(" // ") +
372 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt) +
373 "\n";
374 varBlock(CaseSlugCase::CamelCase,
375 CaseSlugCase::PascalCase,
376 " int ",
377 "_");
378 ret += " printf(\"";
379 for (int i = 0; i < numStatements; ++i)
380 {
381 ret += std::string("%d ");
382 }
383 ret += "\"";
384 for (int i = 0; i < numStatements; ++i)
385 {
386 ret += std::string(", ") + varNames.at(i);
387 }
388 ret += ");\n}";
389 };
390
391 auto jsBlock = [&]()
392 {
393 ret += std::string("import * as ") + mainNamespace +
394 std::string(" from \"./") + mainNamespace + ".js\";\n";
395 ret += std::string("// ") +
396 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt) +
397 "\n";
398 varBlock(CaseSlugCase::CamelCase,
399 CaseSlugCase::CamelCase,
400 "const ",
401 ".");
402 ret += "console.log(";
403 ret += varNames.front();
404 for (int i = 1; i < numStatements; ++i)
405 {
406 ret += std::string(", \" \", ") + varNames.at(i);
407 }
408 ret += ");\n";
409 };
410
411 switch (lang)
412 {
413 case CodeLanguage::Cpp:
414 {
415 cppBlock();
416 break;
417 }
418 case CodeLanguage::Python:
419 {
420 pyBlock();
421 break;
422 }
423 case CodeLanguage::Rust:
424 {
425 rsBlock();
426 break;
427 }
428 case CodeLanguage::C:
429 {
430 cBlock();
431 break;
432 }
433 case CodeLanguage::JavaScript:
434 {
435 jsBlock();
436 break;
437 }
438 }
439 return ret;
440 }
441
442 std::string Generator::ip_addr(bool useIpv6, bool usePort)
443 {
444 std::ostringstream ret;
445 std::string port = internal::ToString(random_number(1023, 65535));
446 if (useIpv6)
447 {
448 ret << (usePort ? "[" : "");
449 ret << std::hex;
450 for (int i = 0; i < 7; ++i)
451 {
452 ret << random_number(0, 65535) << ":";
453 }
454 ret << random_number(0, 65535);
455 ret << (usePort ? "]" : "");
456 if (usePort)
457 {
458 ret << ":" << port;
459 }
460 return ret.str();
461 }
462 ret << random_number(0, 255) << ".";
463 ret << random_number(0, 255) << ".";
464 ret << random_number(0, 255) << ".";
465 ret << random_number(0, 255);
466 if (usePort)
467 {
468 ret << ":";
469 ret << port;
470 }
471 return ret.str();
472 }
473
475 {
476 std::string ret = "(+1) ";
477 ret += internal::ToString(random_number(0, 999));
478 ret += "-";
479 ret += internal::ToString(random_number(0, 999));
480 ret += "-";
481 ret += internal::ToString(random_number(0, 9999));
482 return ret;
483 }
484#else
485 std::string Generator::phone_number()
486 {
487 return "";
488 }
489 std::string Generator::scramble(int, char, char)
490 {
491 return "";
492 }
493 std::string Generator::url()
494 {
495 return "";
496 }
497 std::string Generator::plain_url()
498 {
499 return "";
500 }
501 std::string Generator::email()
502 {
503 return "";
504 }
505 std::string Generator::slug(char)
506 {
507 return "";
508 }
510 {
511 return "";
512 }
513 std::string Generator::code(CodeLanguage)
514 {
515 return "";
516 }
517 std::string Generator::ip_addr(bool, bool)
518 {
519 return "";
520 }
521#endif
522
523} // namespace lipsum
std::string ip_addr(bool useIpv6=false, bool usePort=false)
Generate an IP address.
Definition generator.inl:442
GeneratorSettings m_Settings
Settings for generation.
Definition generator.hpp:832
std::string plain_url()
Generate a plain URL.
Definition generator.inl:190
std::string scramble(int length=16, char minChar=' ', char maxChar='~')
Generate a random character scramble.
Definition generator.inl:162
std::string sentence(int num=1, bool useLipsum=true)
Generate sentences.
Definition generator.inl:98
std::string word(int num=1)
Generate words.
Definition generator.inl:67
std::string single_sentence(const ArgVec2 &wordArg, const ArgVec2 &frag)
Generate a single sentence.
Definition generatorcore.inl:181
std::string text(bool useLipsum=true)
Generate a random number of random paragraphs.
Definition generator.inl:151
Source m_Source
Source used for generation.
Definition generator.hpp:844
T random_number(T min, T max)
Generate a random number.
Definition generator.hpp:755
std::string url()
Generate a URL.
Definition generator.inl:184
std::string phone_number()
Generate a phone number.
Definition generator.inl:474
std::string email()
Generate an email.
Definition generator.inl:196
std::string fragment()
Generate a sentence fragment.
Definition generator.inl:92
std::string tld()
Pick a random TLD.
Definition generatorcore.inl:167
std::string single_paragraph(bool useLipsum)
Generate a single paragraph.
Definition generatorcore.inl:317
std::string code(CodeLanguage lang=CodeLanguage::Cpp)
Generate a code block.
Definition generator.inl:269
std::string slug(char separator='-')
Generate a slug.
Definition generator.inl:203
std::mt19937 m_Gen
Random number generator.
Definition generator.hpp:834
std::string case_slug(CaseSlugCase case_=CaseSlugCase::CamelCase)
Generate a case slug.
Definition generator.inl:212
std::string paragraph(int num=1, bool useLipsum=true)
Generate paragraphs.
Definition generator.inl:125
#define LPSM_SAFE_CCTYPE(type, func, arg)
Simplify safe cctype usage.
Definition core.hpp:36
Definition of core lipsum::Generator functions.
Definition of lipsum::Generator functions for formats.
Declaration of lipsum::internal.
void LogWarn(LogType type, const Args &... args)
Log a warning.
Definition internal.hpp:126
std::string ToString(const T &param)
Convert an object to a string.
Definition internal.hpp:242
This is the main namespace of lipsum-cpp.
CodeLanguage
Languages used by lipsum::Generator::code().
Definition generator.hpp:76
LIPSUM_API std::string GenerateDefaultLipsumSentence()
Generate the beginning Lorem Ipsum sentence.
Definition misc.inl:38
CaseSlugCase
Cases used by lipsum::Generator::case_slug().
Definition generator.hpp:58