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 . '' . $formatting[$i] . '>';
}
$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;
}
}