LoremIpsum.mjs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /**
  2. * Lorem Ipsum generator.
  3. *
  4. * @author Klaxon [klaxon@veyr.com]
  5. * @copyright Crown Copyright 2018
  6. * @license Apache-2.0
  7. */
  8. /**
  9. * Generate lorem ipsum paragraphs.
  10. *
  11. * @param {number} length
  12. * @returns {string}
  13. */
  14. export function GenerateParagraphs(length=3) {
  15. const paragraphs = [];
  16. while (paragraphs.length < length) {
  17. const paragraphLength = getRandomLength(PARAGRAPH_LENGTH_MEAN, PARAGRAPH_LENGTH_STD_DEV);
  18. const sentences = [];
  19. while (sentences.length < paragraphLength) {
  20. const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
  21. const sentence = getWords(sentenceLength);
  22. sentences.push(formatSentence(sentence));
  23. }
  24. paragraphs.push(formatParagraph(sentences));
  25. }
  26. paragraphs[paragraphs.length-1] = paragraphs[paragraphs.length-1].slice(0, -2);
  27. paragraphs[0] = replaceStart(paragraphs[0]);
  28. return paragraphs.join("");
  29. }
  30. /**
  31. * Generate lorem ipsum sentences.
  32. *
  33. * @param {number} length
  34. * @returns {string}
  35. */
  36. export function GenerateSentences(length=3) {
  37. const sentences = [];
  38. while (sentences.length < length) {
  39. const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
  40. const sentence = getWords(sentenceLength);
  41. sentences.push(formatSentence(sentence));
  42. }
  43. const paragraphs = sentencesToParagraphs(sentences);
  44. return paragraphs.join("");
  45. }
  46. /**
  47. * Generate lorem ipsum words.
  48. *
  49. * @param {number} length
  50. * @returns {string}
  51. */
  52. export function GenerateWords(length=3) {
  53. const words = getWords(length);
  54. const sentences = wordsToSentences(words);
  55. const paragraphs = sentencesToParagraphs(sentences);
  56. return paragraphs.join("");
  57. }
  58. /**
  59. * Generate lorem ipsum bytes.
  60. *
  61. * @param {number} length
  62. * @returns {string}
  63. */
  64. export function GenerateBytes(length=3) {
  65. const str = GenerateWords(length/3);
  66. return str.slice(0, length);
  67. }
  68. /**
  69. * Get array of randomly selected words from the lorem ipsum wordList.
  70. *
  71. * @param {number} length
  72. * @returns {string[]}
  73. * @private
  74. */
  75. function getWords(length=3) {
  76. const words = [];
  77. let word;
  78. let previousWord;
  79. while (words.length < length){
  80. do {
  81. word = wordList[Math.floor(Math.random() * wordList.length)];
  82. } while (previousWord === word);
  83. words.push(word);
  84. previousWord = word;
  85. }
  86. return words;
  87. }
  88. /**
  89. * Convert an array of words into an array of sentences
  90. *
  91. * @param {string[]} words
  92. * @returns {string[]}
  93. * @private
  94. */
  95. function wordsToSentences(words) {
  96. const sentences = [];
  97. while (words.length > 0) {
  98. const sentenceLength = getRandomLength(SENTENCE_LENGTH_MEAN, SENTENCE_LENGTH_STD_DEV);
  99. if (sentenceLength <= words.length) {
  100. sentences.push(formatSentence(words.splice(0, sentenceLength)));
  101. } else {
  102. sentences.push(formatSentence(words.splice(0, words.length)));
  103. }
  104. }
  105. return sentences;
  106. }
  107. /**
  108. * Convert an array of sentences into an array of paragraphs
  109. *
  110. * @param {string[]} sentences
  111. * @returns {string[]}
  112. * @private
  113. */
  114. function sentencesToParagraphs(sentences) {
  115. const paragraphs = [];
  116. while (sentences.length > 0) {
  117. const paragraphLength = getRandomLength(PARAGRAPH_LENGTH_MEAN, PARAGRAPH_LENGTH_STD_DEV);
  118. paragraphs.push(formatParagraph(sentences.splice(0, paragraphLength)));
  119. }
  120. paragraphs[paragraphs.length-1] = paragraphs[paragraphs.length-1].slice(0, -1);
  121. paragraphs[0] = replaceStart(paragraphs[0]);
  122. return paragraphs;
  123. }
  124. /**
  125. * Format an array of words into a sentence.
  126. *
  127. * @param {string[]} words
  128. * @returns {string}
  129. * @private
  130. */
  131. function formatSentence(words) {
  132. // 0.35 chance of a comma being added randomly to the sentence.
  133. if (Math.random() < PROBABILITY_OF_A_COMMA) {
  134. const pos = Math.round(Math.random()*(words.length-1));
  135. words[pos] +=",";
  136. }
  137. let sentence = words.join(" ");
  138. sentence = sentence.charAt(0).toUpperCase() + sentence.slice(1);
  139. sentence += ".";
  140. return sentence;
  141. }
  142. /**
  143. * Format an array of sentences into a paragraph.
  144. *
  145. * @param {string[]} sentences
  146. * @returns {string}
  147. * @private
  148. */
  149. function formatParagraph(sentences) {
  150. let paragraph = sentences.join(" ");
  151. paragraph += "\n\n";
  152. return paragraph;
  153. }
  154. /**
  155. * Get a random number based on a mean and standard deviation.
  156. *
  157. * @param {number} mean
  158. * @param {number} stdDev
  159. * @returns {number}
  160. * @private
  161. */
  162. function getRandomLength(mean, stdDev) {
  163. let length;
  164. do {
  165. length = Math.round((Math.random()*2-1)+(Math.random()*2-1)+(Math.random()*2-1)*stdDev+mean);
  166. } while (length <= 0);
  167. return length;
  168. }
  169. /**
  170. * Replace first 5 words with "Lorem ipsum dolor sit amet"
  171. *
  172. * @param {string[]} str
  173. * @returns {string[]}
  174. * @private
  175. */
  176. function replaceStart(str) {
  177. let words = str.split(" ");
  178. if (words.length > 5) {
  179. words.splice(0, 5, "Lorem", "ipsum", "dolor", "sit", "amet");
  180. return words.join(" ");
  181. } else {
  182. const lorem = ["Lorem", "ipsum", "dolor", "sit", "amet"];
  183. words = lorem.slice(0, words.length);
  184. str = words.join(" ");
  185. str += ".";
  186. return str;
  187. }
  188. }
  189. const SENTENCE_LENGTH_MEAN = 15;
  190. const SENTENCE_LENGTH_STD_DEV = 9;
  191. const PARAGRAPH_LENGTH_MEAN = 5;
  192. const PARAGRAPH_LENGTH_STD_DEV = 2;
  193. const PROBABILITY_OF_A_COMMA = 0.35;
  194. const wordList = [
  195. "ad", "adipisicing", "aliqua", "aliquip", "amet", "anim",
  196. "aute", "cillum", "commodo", "consectetur", "consequat", "culpa",
  197. "cupidatat", "deserunt", "do", "dolor", "dolore", "duis",
  198. "ea", "eiusmod", "elit", "enim", "esse", "est",
  199. "et", "eu", "ex", "excepteur", "exercitation", "fugiat",
  200. "id", "in", "incididunt", "ipsum", "irure", "labore",
  201. "laboris", "laborum", "Lorem", "magna", "minim", "mollit",
  202. "nisi", "non", "nostrud", "nulla", "occaecat", "officia",
  203. "pariatur", "proident", "qui", "quis", "reprehenderit", "sint",
  204. "sit", "sunt", "tempor", "ullamco", "ut", "velit",
  205. "veniam", "voluptate",
  206. ];