lipsum-cpp 0.5.4
A basic library written in C++ for generating placeholder Lorem Ipsum text.
Loading...
Searching...
No Matches
generatorformats.inl
Go to the documentation of this file.
1
13
14#pragma once
15
16#include "core/internal.hpp"
17
18namespace lipsum
19{
20
21#ifndef LIPSUM_MIN_BUILD
22
23 /*
24 * FORMATS
25 */
26
27 std::string Generator::fmt_paragraph(int num, bool useLipsum, bool useHtml)
28 {
29 std::string ret;
30
31 if (num < 0)
32 {
33 internal::LogWarn(internal::LogType::Warn,
34 "lpsm::Generator::fmt_paragraph(): expected "
35 "num >= 0, got ",
36 num);
37 }
38
39 for (int i = 0; i < num; ++i)
40 {
41 if (i == 0 && useLipsum)
42 {
43 ret += single_fmt_paragraph(USELIPSUM, useHtml);
44 }
45 else
46 {
47 ret += single_fmt_paragraph(NO_USELIPSUM, useHtml);
48 }
49 }
50 return ret;
51 }
52
53 std::string Generator::fmt_text(int numElements, bool useHtml)
54 {
55 std::string ret;
56 if (numElements < 0)
57 {
58 internal::LogWarn(internal::LogType::Warn,
59 "lpsm::Generator::fmt_text(): cannot generate "
60 "negative number of elements.");
61 return ret;
62 }
63 if (numElements >= 1)
64 {
65 ret += fmt_header(1, useHtml);
66 }
67 if (numElements >= 2)
68 {
69 ret += single_fmt_paragraph(NO_USELIPSUM, useHtml);
70 }
71
72 numElements -= 2;
73 int lastRand = 0;
74 int rand = 0;
75 bool ordered;
76 while (numElements > 0)
77 {
78 rand = random_number<int>(0, 2);
79 if ((lastRand == 1 && rand == 1) || numElements == 1)
80 {
81 rand = 0;
82 }
83 ordered = LPSM_FLIP_COIN;
84 switch (rand)
85 {
86 case 0:
87 {
88 ret += single_fmt_paragraph(NO_USELIPSUM, useHtml);
89 break;
90 }
91 case 1:
92 {
93 ret += fmt_header(m_Settings.level.roll(m_Gen,
94 m_Settings.lazy),
95 useHtml);
96 break;
97 }
98 case 2:
99 {
100 ret += fmt_list(ordered, useHtml);
101 break;
102 }
103 }
104 --numElements;
105 lastRand = rand;
106 }
107 return ret;
108 }
109
110 std::string Generator::fmt_header(int level, bool useHtml)
111 {
112 if (level > 6 || level < 1)
113 {
114 internal::LogWarn(internal::LogType::Warn,
115 "lpsm::Generator::fmt_header(): invalid header "
116 "level ",
117 level,
118 ", expected from 1 to 6");
119 }
120 std::string ret;
121 int numWords = m_Settings.wordURL.roll(m_Gen, m_Settings.lazy);
122 std::string words = word(numWords);
123 if (!words.empty())
124 {
125 words.at(0) = LPSM_SAFE_CCTYPE(char, std::toupper, words.at(0));
126 }
127 if (!useHtml)
128 {
129 for (int i = 0; i < level; ++i)
130 {
131 ret += "#";
132 }
133 ret += " ";
134 ret += words += "\n\n";
135 }
136 else
137 {
138 ret += std::string("<h") + internal::ToString(level) + ">";
139 ret += words +=
140 std::string("</h") + internal::ToString(level) + ">\n\n";
141 }
142 return ret;
143 }
144
145 std::string Generator::fmt_emphasis(bool isBold, bool useHtml)
146 {
147 std::string ret;
148 std::string sent =
149 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt);
150
151 if (!useHtml)
152 {
153 ret += (isBold ? "**" : "*");
154 }
155 else
156 {
157 ret += (isBold ? "<strong>" : "<em>");
158 }
159
160 ret += sent;
161
162 if (!useHtml)
163 {
164 ret += (isBold ? "**" : "*");
165 }
166 else
167 {
168 ret += (isBold ? "</strong>" : "</em>");
169 }
170 return ret;
171 }
172
173 std::string Generator::fmt_link(bool useHtml)
174 {
175 std::string link = url();
176 std::string sentence =
177 single_sentence(m_Settings.wordFmt, m_Settings.fragFmt);
178 if (!useHtml)
179 {
180 return std::string("[") + sentence + std::string("](") + link + ")";
181 }
182 return std::string("<a href=\"") + link + std::string("\">") +
183 sentence + "</a>";
184 }
185
186 std::string Generator::fmt_list(bool ordered, bool useHtml)
187 {
188 std::string ret;
189 int points = m_Settings.point.roll(m_Gen, m_Settings.lazy);
190 if (useHtml)
191 {
192 ret += (ordered ? "<ol>" : "<ul>");
193 }
194 for (int i = 0; i < points; ++i)
195 {
196 if (!useHtml)
197 {
198 if (ordered)
199 {
200 ret += internal::ToString(i + 1) + ". ";
201 }
202 else
203 {
204 ret += "- ";
205 }
206 }
207 else
208 {
209 ret += "<li>";
210 }
211 ret += single_sentence(m_Settings.wordFmt, m_Settings.fragFmt);
212 ret += (useHtml ? "</li>" : "\n");
213 }
214 if (useHtml)
215 {
216 ret += (ordered ? "</ol>\n" : "</ul>\n");
217 }
218 ret += "\n";
219 return ret;
220 }
221
222 std::string Generator::xml(int choices)
223 {
224 std::string ret = R"(<?xml version="1.0" encoding="UTF-8"?>)";
225 std::vector<std::string> tagStack;
226 std::string root = m_Source.random_word(m_Gen, m_Settings.lazy);
227 ret += std::string("<") + root + ">";
228
229 int choice;
230
231 for (int i = 0; i < choices; ++i)
232 {
233 choice = random_number<int>(0, 2);
234 switch (choice)
235 {
236 case 0:
237 {
238 std::string toAdd =
239 m_Source.random_word(m_Gen, m_Settings.lazy);
240 std::string attrib =
241 m_Source.random_word(m_Gen, m_Settings.lazy);
242 std::string attribValue =
243 m_Source.random_word(m_Gen, m_Settings.lazy);
244 bool useAttrib = LPSM_FLIP_COIN;
245 if (useAttrib)
246 {
247 ret += std::string("<") + toAdd + std::string(" ") +
248 attrib + std::string("=\"") + attribValue +
249 std::string("\">");
250 }
251 else
252 {
253 ret += std::string("<") + toAdd + ">";
254 }
255 tagStack.push_back(toAdd);
256 break;
257 }
258
259 case 1:
260 {
261 std::string toAdd =
262 m_Source.random_word(m_Gen, m_Settings.lazy);
263 ret += std::string("<") + toAdd + std::string(">") +
265 std::string("</") + toAdd + ">";
266 // ret += toAdd += "";
267 break;
268 }
269
270 default:
271 {
272 if (!tagStack.empty())
273 {
274 ret += std::string("</") + tagStack.back() + ">";
275 tagStack.pop_back();
276 }
277 break;
278 }
279 }
280 }
281
282 while (!tagStack.empty())
283 {
284 ret += std::string("</") + tagStack.back() + ">";
285 tagStack.pop_back();
286 }
287
288 ret += std::string("</") + root + ">";
289
290 return ret;
291 }
292
293 std::string Generator::json(int maxDepth, bool isObject)
294 {
295 int count = m_Settings.jsonLength.roll(m_Gen, m_Settings.lazy);
296 std::string ret = (isObject ? "{" : "[");
297 for (int i = 0; i < count; ++i)
298 {
299 if (i > 0)
300 {
301 ret += ",";
302 }
303
304 if (isObject)
305 {
306
307 std::string key = std::string("\"") +
308 m_Source.random_word(m_Gen, m_Settings.lazy) +
309 internal::ToString(i) + "\"";
310 ret += key + std::string(":") + json_value(maxDepth - 1);
311 }
312 else
313 {
314
315 ret += json_value(maxDepth - 1);
316 }
317 }
318 ret += (isObject ? "}" : "]");
319 return ret;
320 }
321
322 std::string Generator::json_value(int maxDepth)
323 {
324 int choice;
325 constexpr int JSON_VALUE_WARN_DEPTH = 50;
326 LPSM_VERBOSE_LOG(Trace, "Creating a JSON value at depth ", maxDepth);
327 if (maxDepth >= JSON_VALUE_WARN_DEPTH)
328 {
329 internal::LogWarn(internal::LogType::Warn,
330 "lpsm::Generator::json_value(): got maxDepth = ",
331 maxDepth,
332 ", which is "
333 "greater than the recommended maximum depth ",
334 JSON_VALUE_WARN_DEPTH,
335 ".");
336 }
337 if (maxDepth <= 0)
338 {
339 choice = random_number(0, 3);
340 switch (choice)
341 {
342 case 0:
343 {
344 return json_string();
345 }
346 case 1:
347 {
348 return json_number();
349 }
350 case 2:
351 {
352 return LPSM_FLIP_COIN ? "true" : "false";
353 }
354 default:
355 {
356 return "null";
357 }
358 }
359 }
360
361 choice = random_number(0, 5);
362 switch (choice)
363 {
364
365 case 0:
366 {
367 return json_string();
368 }
369 case 1:
370 {
371 return json_number();
372 }
373 case 2:
374 {
375 return LPSM_FLIP_COIN ? "true" : "false";
376 }
377 case 3:
378 {
379 return "null";
380 }
381 case 4:
382 {
383 return json(maxDepth, ARRAY);
384 }
385 default:
386 {
387 return json(maxDepth, OBJECT);
388 }
389 }
390 }
391
392 std::string Generator::csv()
393 {
394 constexpr float CSV_NUMBER_MIN = -1000.0F;
395 constexpr float CSV_NUMBER_MAX = 1000.0F;
396 enum class CsvTypes : int
397 {
398 Int = 0,
399 Float,
400 Sentence,
401 Word,
402 Email,
403 Scramble,
404 IP,
405 Phone
406 };
407
408 int numRows = m_Settings.csvRows.roll(m_Gen, m_Settings.lazy);
409 int numCols = m_Settings.csvCols.roll(m_Gen, m_Settings.lazy);
410 std::vector<CsvTypes> cols;
411 std::string ret;
412 cols.reserve(numCols);
413 for (int i = 0; i < numCols; ++i)
414 {
415 cols.push_back(static_cast<CsvTypes>(random_number<int>(0, 7)));
416 ret += m_Source.random_word(m_Gen, m_Settings.lazy) + ",";
417 }
418 // remove trailing comma
419 if (!ret.empty())
420 {
421 ret.pop_back();
422 }
423 ret += "\n";
424
425 auto csvTypeLogic = [&](CsvTypes type)
426 {
427 switch (type)
428 {
429 case CsvTypes::Int:
430 {
431 ret += json_number() + ",";
432 break;
433 }
434 case CsvTypes::Float:
435 {
436 ret += internal::ToString(
437 random_number<float>(CSV_NUMBER_MIN,
438 CSV_NUMBER_MAX)) +
439 ",";
440 break;
441 }
442 case CsvTypes::Sentence:
443 {
444 ret += std::string("\"") +
446 m_Settings.fragFmt) +
447 "\",";
448 break;
449 }
450 case CsvTypes::Word:
451 {
452 ret += m_Source.random_word(m_Gen, m_Settings.lazy) + ",";
453 break;
454 }
455 case CsvTypes::Email:
456 {
457 ret += email() + ",";
458 break;
459 }
460 case CsvTypes::Scramble:
461 {
462 ret += scramble(16, 'a', 'z') + ",";
463 break;
464 }
465 case CsvTypes::IP:
466 {
468 break;
469 }
470 case CsvTypes::Phone:
471 {
472 ret += "\"";
473 ret += phone_number() + "\",";
474 break;
475 }
476 }
477 };
478
479 for (int i = 0; i < numRows; ++i)
480 {
481 for (int j = 0; j < numCols; ++j)
482 {
483 csvTypeLogic(cols.at(j));
484 }
485 // remove trailing comma
486 if (!ret.empty())
487 {
488 ret.pop_back();
489 }
490 ret += "\n";
491 }
492 return ret;
493 }
494#else
495 // placeholders
496
497 std::string Generator::fmt_paragraph(int, bool, bool)
498 {
499 return "";
500 }
501 std::string Generator::fmt_text(int, bool)
502 {
503 return "";
504 }
505 std::string Generator::fmt_header(int, bool)
506 {
507 return "";
508 }
509 std::string Generator::fmt_emphasis(bool, bool)
510 {
511 return "";
512 }
513 std::string Generator::fmt_link(bool)
514 {
515 return "";
516 }
517 std::string Generator::fmt_list(bool, bool)
518 {
519 return "";
520 }
521 std::string Generator::xml(int)
522 {
523 return "";
524 }
525 std::string Generator::json(int, bool)
526 {
527 return "";
528 }
529 std::string Generator::json_value(int)
530 {
531 return "";
532 }
533 std::string Generator::csv()
534 {
535 return "";
536 }
537#endif
538} // namespace lipsum
std::string xml(int choices=30)
Generate an XML document.
Definition generatorformats.inl:222
std::string ip_addr(bool useIpv6=false, bool usePort=false)
Generate an IP address.
Definition generator.inl:442
std::string fmt_emphasis(bool isBold=true, bool useHtml=false)
Generate an emphasized Markdown or HTML sentence.
Definition generatorformats.inl:145
GeneratorSettings m_Settings
Settings for generation.
Definition generator.hpp:832
std::string scramble(int length=16, char minChar=' ', char maxChar='~')
Generate a random character scramble.
Definition generator.inl:162
std::string fmt_paragraph(int num=1, bool useLipsum=true, bool useHtml=false)
Generate Markdown or HTML paragraphs.
Definition generatorformats.inl:27
std::string sentence(int num=1, bool useLipsum=true)
Generate sentences.
Definition generator.inl:98
std::string json_value(int maxDepth=3)
Generate a JSON value.
Definition generatorformats.inl:322
std::string fmt_header(int level=1, bool useHtml=false)
Generate a Markdown or HTML header.
Definition generatorformats.inl:110
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 fmt_list(bool ordered=false, bool useHtml=false)
Generate a Markdown or HTML list.
Definition generatorformats.inl:186
std::string single_fmt_paragraph(bool useLipsum, bool useHtml)
Generate a single Markdown or HTML paragraph.
Definition generatorcore.inl:210
std::string json_string()
Generate a random JSON string.
Definition generatorcore.inl:260
Source m_Source
Source used for generation.
Definition generator.hpp:844
std::string json(int maxDepth=3, bool isObject=true)
Generate a JSON object or array.
Definition generatorformats.inl:293
T random_number(T min, T max)
Generate a random number.
Definition generator.hpp:755
std::string fmt_link(bool useHtml=false)
Generate a Markdown or HTML link.
Definition generatorformats.inl:173
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 fmt_text(int numElements=15, bool useHtml=false)
Generate a Markdown or HTML document.
Definition generatorformats.inl:53
std::string csv()
Generate a CSV document.
Definition generatorformats.inl:392
std::string json_number()
Generate a random JSON number.
Definition generatorcore.inl:266
std::mt19937 m_Gen
Random number generator.
Definition generator.hpp:834
#define LPSM_SAFE_CCTYPE(type, func, arg)
Simplify safe cctype usage.
Definition core.hpp:36
#define LPSM_FLIP_COIN
Choose between true or false.
Definition core.hpp:31
#define LPSM_VERBOSE_LOG(type,...)
Verbose log messages.
Definition core.hpp:49
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.