hasFormatting = $hasFormatting; $this->hasParagraphs = $hasParagraphs; } /** * Get a random string. * * @param int $length Text length * @param string[] $words Vocabulary * * @return string * * @since 1.0.0 */ public function generateText(int $length, ?array $words = null) : string { if ($length === 0) { return ''; } $words ??= self::LOREM_IPSUM; $punctuation = $this->generatePunctuation($length); $punctuationCount = \array_count_values( \array_map( function ($item) { return $item[1]; }, $punctuation ) ) + ['.' => 0, '!' => 0, '?' => 0]; $this->sentences = $punctuationCount['.'] + $punctuationCount['!'] + $punctuationCount['?']; if ($this->hasParagraphs) { $paragraph = $this->generateParagraph($this->sentences); } if ($this->hasFormatting) { $formatting = $this->generateFormatting($length); } $sentenceCount = 0; $text = ''; $puid = 0; $paid = 0; $wordCount = \count($words); for ($i = 0; $i < $length + 1; ++$i) { $lastChar = \substr($text, -1); $word = $words[\mt_rand(0, $wordCount - 1)] ?? ''; if ($lastChar === '.' || $lastChar === '!' || $lastChar === '?' || !$lastChar) { $word = \ucfirst($word); ++$sentenceCount; /** @noinspection PhpUndefinedVariableInspection */ if ($this->hasParagraphs) { ++$paid; $text .= '

'; } } /** @noinspection PhpUndefinedVariableInspection */ if ($this->hasFormatting && isset($formatting[$i])) { $word = '<' . $formatting[$i] . '>' . $word . ''; } $text .= ' ' . $word; if ($punctuation[$puid][0] === $i) { $text .= $punctuation[$puid][1]; ++$puid; } } $text = \ltrim($text); return $this->hasParagraphs ? '

' . $text . '

' : $text; } /** * Generate punctuation. * * @param int $length Text length * * @return array> * * @since 1.0.0 */ private function generatePunctuation(int $length) : array { $minSentences = 4; $maxSentences = 20; $minCommaSpacing = 3; $probComma = 0.2; $probDot = 0.8; $probExc = 0.4; $punctuation = []; for ($i = 0; $i < $length;) { $sentenceLength = \mt_rand($minSentences, $maxSentences); if ($i + $sentenceLength > $length || $length - ($i + $sentenceLength) < $minSentences) { $sentenceLength = $length - $i; } /* Handle comma */ $posComma = []; if (\mt_rand(0, 100) <= $probComma * 100 && $sentenceLength >= 2 * $minCommaSpacing) { $posComma[] = \mt_rand($minCommaSpacing, $sentenceLength - $minCommaSpacing); $punctuation[] = [$i + $posComma[0], ',']; if (\mt_rand(0, 100) <= $probComma * 100 && $sentenceLength > $posComma[0] + $minCommaSpacing * 2) { $posComma[] = \mt_rand($posComma[0] + $minCommaSpacing, $sentenceLength - $minCommaSpacing); $punctuation[] = [$i + $posComma[1], ',']; } } $i += $sentenceLength; /* Handle sentence ending */ if (\mt_rand(0, 100) <= $probDot * 100) { $punctuation[] = [$i, '.']; continue; } if (\mt_rand(0, 100) <= $probExc * 100) { $punctuation[] = [$i, '!']; continue; } $punctuation[] = [$i, '?']; } return $punctuation; } /** * Generate paragraphs. * * @param int $length Amount of sentences * * @return int[] * * @since 1.0.0 */ private function generateParagraph(int $length) : array { $minSentence = 3; $maxSentence = 10; $paragraph = []; for ($i = 0; $i < $length;) { $paragraphLength = \mt_rand($minSentence, $maxSentence); if ($i + $paragraphLength > $length || $length - ($i + $paragraphLength) < $minSentence) { $paragraphLength = $length - $i; } $i += $paragraphLength; $paragraph[] = $i; } return $paragraph; } /** * Generate random formatting. * * @param int $length Amount of words * * @return string[] * * @since 1.0.0 */ private function generateFormatting(int $length) : array { $probCursive = 0.005; $probBold = 0.005; $probUline = 0.005; $formatting = []; for ($i = 0; $i < $length; ++$i) { if (\mt_rand(0, 1000) <= 1000 * $probUline) { $formatting[$i] = 'u'; } if (\mt_rand(0, 1000) <= 1000 * $probBold) { $formatting[$i] = 'b'; } if (\mt_rand(0, 1000) <= 1000 * $probCursive) { $formatting[$i] = 'i'; } } return $formatting; } }