From 78cdec784e4c9d5459ff6ba38edc357ca633f6be Mon Sep 17 00:00:00 2001 From: Joshua Sherman Date: Wed, 14 May 2014 10:57:10 -0400 Subject: [PATCH] Finished functionality --- src/LoremIpsum.php | 220 ++++++++++++++++++++++++++++++++++++--- tests/LoremIpsumTest.php | 24 +++-- 2 files changed, 224 insertions(+), 20 deletions(-) diff --git a/src/LoremIpsum.php b/src/LoremIpsum.php index 4fe7856..bdcaa38 100644 --- a/src/LoremIpsum.php +++ b/src/LoremIpsum.php @@ -1,15 +1,42 @@ + * @copyright Copyright 2014, Josh Sherman + * @license http://www.opensource.org/licenses/mit-license.html + * @link https://github.com/joshtronic/php-loremipsum + */ + namespace joshtronic; class LoremIpsum { - private $first = true; - private $sentence_mean = 24.46; - private $sentence_std_dev = 5.08; - private $paragraph_mean = 5.8; - private $paragraph_std_dev = 1.93; + /** + * First + * + * Whether or not we should be starting the string with "Lorem ipsum..." + * + * @access private + * @var boolean + */ + private $first = true; + /** + * Words + * + * A lorem ipsum vocabulary of sorts. Not a complete list as I'm unsure if + * a complete list exists and if so, where to get it. + * + * @access private + * @var array + */ public $words = array( // Lorem ipsum... 'lorem', 'ipsum', 'dolor', 'sit', @@ -61,43 +88,124 @@ class LoremIpsum 'vivamus', 'viverra', 'volutpat', 'vulputate', ); + /** + * Word + * + * Generates a single word of lorem ipsum. + * + * @access public + * @param mixed $tags string or array of HTML tags to wrap output with + * @return string generated lorem ipsum word + */ public function word($tags = false) { return $this->words(1, $tags); } + /** + * Words Array + * + * Generates an array of lorem ipsum words. + * + * @access public + * @param integer $count how many words to generate + * @param mixed $tags string or array of HTML tags to wrap output with + * @return array generated lorem ipsum words + */ public function wordsArray($count = 1, $tags = false) { return $this->words($count, $tags, true); } - // TODO Need to refactor to allow for counts larger than array of words + /** + * Words + * + * Generates words of lorem ipsum. + * + * @access public + * @param integer $count how many words to generate + * @param mixed $tags string or array of HTML tags to wrap output with + * @param boolean $array whether an array or a string should be returned + * @return mixed string or array of generated lorem ipsum words + */ public function words($count = 1, $tags = false, $array = false) { - $this->shuffle(); + $words = array(); + $word_count = 0; - $words = array_slice($this->words, 0, $count); + // Shuffles and appends the word list to compensate for count + // arguments that exceed the size of our vocabulary list + while ($word_count < $count) + { + $shuffle = true; + + while ($shuffle) + { + $this->shuffle(); + + // Checks that the last word of the list and the first word of + // the list that's about to be appended are not the same + if (!$word_count || $words[$word_count - 1] != $this->words[0]) + { + $words = array_merge($words, $this->words); + $word_count = count($words); + $shuffle = false; + } + } + } + + $words = array_slice($words, 0, $count); return $this->output($words, $tags, $array); } + /** + * Sentence + * + * Generates a full sentence of lorem ipsum. + * + * @access public + * @param mixed $tags string or array of HTML tags to wrap output with + * @return string generated lorem ipsum sentence + */ public function sentence($tags = false) { return $this->sentences(1, $tags); } + /** + * Sentences Array + * + * Generates an array of lorem ipsum sentences. + * + * @access public + * @param integer $count how many sentences to generate + * @param mixed $tags string or array of HTML tags to wrap output with + * @return array generated lorem ipsum sentences + */ public function sentencesArray($count = 1, $tags = false) { return $this->sentences($count, $tags, true); } + /** + * Sentences + * + * Generates sentences of lorem ipsum. + * + * @access public + * @param integer $count how many sentences to generate + * @param mixed $tags string or array of HTML tags to wrap output with + * @param boolean $array whether an array or a string should be returned + * @return mixed string or array of generated lorem ipsum sentences + */ public function sentences($count = 1, $tags = false, $array = false) { $sentences = array(); for ($i = 0; $i < $count; $i++) { - $sentences[] = $this->wordsArray($this->gauss($this->sentence_mean, $this->sentence_std_dev)); + $sentences[] = $this->wordsArray($this->gauss(24.46, 5.08)); } $this->punctuate($sentences); @@ -105,21 +213,71 @@ class LoremIpsum return $this->output($sentences, $tags, $array); } + /** + * Paragraph + * + * Generates a full paragraph of lorem ipsum. + * + * @access public + * @param mixed $tags string or array of HTML tags to wrap output with + * @return string generated lorem ipsum paragraph + */ public function paragraph($tags = false) { return $this->paragraphs(1, $tags); } + /** + * Paragraph Array + * + * Generates an array of lorem ipsum paragraphs. + * + * @access public + * @param integer $count how many paragraphs to generate + * @param mixed $tags string or array of HTML tags to wrap output with + * @return array generated lorem ipsum paragraphs + */ public function paragraphsArray($count = 1, $tags = false) { return $this->paragraphs($count, $tags, true); } + /** + * Paragraphss + * + * Generates paragraphs of lorem ipsum. + * + * @access public + * @param integer $count how many paragraphs to generate + * @param mixed $tags string or array of HTML tags to wrap output with + * @param boolean $array whether an array or a string should be returned + * @return mixed string or array of generated lorem ipsum paragraphs + */ public function paragraphs($count = 1, $tags = false, $array = false) { + $paragraphs = array(); + for ($i = 0; $i < $count; $i++) + { + $paragraphs[] = $this->sentences($this->gauss(5.8, 1.93)); + } + + return $this->output($paragraphs, $tags, $array, "\n\n"); } + /** + * Gaussian Distribution + * + * This is some smart kid stuff. I went ahead and combined the N(0,1) logic + * with the N(m,s) logic into this single function. Used to calculate the + * number of words in a sentence, the number of sentences in a paragraph + * and the distribution of commas in a sentence. + * + * @access private + * @param double $mean average value + * @param double $std_dev stadnard deviation + * @return double calculated distribution + */ private function gauss($mean, $std_dev) { $x = mt_rand() / mt_getrandmax(); @@ -129,6 +287,14 @@ class LoremIpsum return $z * $std_dev + $mean; } + /** + * Shuffle + * + * Shuffles the words, forcing "Lorem ipsum..." at the beginning if it is + * the first time we are generating the text. + * + * @access private + */ private function shuffle() { if ($this->first) @@ -148,12 +314,23 @@ class LoremIpsum } } + /** + * Punctuate + * + * Applies punctuation to a sentence. This includes a period at the end, + * the injection of commas as well as capitalizing the first letter of the + * first word of the sentence. + * + * @access private + * @param array $sentences the sentences we would like to punctuate + */ private function punctuate(&$sentences) { foreach ($sentences as $key => $sentence) { $words = count($sentence); + // Only worry about commas on sentences longer than 4 words if ($words > 4) { $mean = log($words, 6); @@ -169,13 +346,28 @@ class LoremIpsum $sentence[$word] .= ','; } } - - $sentences[$key] = ucfirst(implode(' ', $sentence) . '.'); } + + $sentences[$key] = ucfirst(implode(' ', $sentence) . '.'); } } - private function output($strings, $tags, $array) + /** + * Output + * + * Does the rest of the processing of the strings. This includes wrapping + * the strings in HTML tags, handling transformations with the ability of + * back referencing and determining if the passed array should be converted + * into a string or not. + * + * @access private + * @param array $strings an array of generated strings + * @param mixed $tags string or array of HTML tags to wrap output with + * @param boolean $array whether an array or a string should be returned + * @param string $delimiter the string to use when calling implode() + * @return mixed string or array of generated lorem ipsum text + */ + private function output($strings, $tags, $array, $delimiter = ' ') { if ($tags) { @@ -185,6 +377,7 @@ class LoremIpsum } else { + // Flips the array so we can work from the inside out $tags = array_reverse($tags); } @@ -192,6 +385,7 @@ class LoremIpsum { foreach ($tags as $tag) { + // Detects / applies back reference if ($tag[0] == '<') { $string = str_replace('$1', $string, $tag); @@ -208,7 +402,7 @@ class LoremIpsum if (!$array) { - $strings = implode(' ', $strings); + $strings = implode($delimiter, $strings); } return $strings; diff --git a/tests/LoremIpsumTest.php b/tests/LoremIpsumTest.php index ba17c49..36f78f5 100644 --- a/tests/LoremIpsumTest.php +++ b/tests/LoremIpsumTest.php @@ -36,6 +36,11 @@ class LoremIpsumTest extends PHPUnit_Framework_TestCase } } + public function testWordsExceedingVocab() + { + $this->assertCount(500, $this->lipsum->wordsArray(500)); + } + public function testSentence() { $this->assertRegExp('/^[a-z, ]+\.$/i', $this->lipsum->sentence()); @@ -58,25 +63,30 @@ class LoremIpsumTest extends PHPUnit_Framework_TestCase } } - /* public function testParagraph() { - - $this->fail('Not yet implemented.'); + $this->assertRegExp('/^([a-z, ]+\.)+$/i', $this->lipsum->paragraph()); } public function testParagraphs() { - - $this->fail('Not yet implemented.'); + $this->assertRegExp( + '/^([a-z, ]+\.)+\n\n([a-z, ]+\.)+\n\n([a-z, ]+\.)+$/i', + $this->lipsum->paragraphs(3) + ); } public function testParagraphsArray() { + $paragraphs = $this->lipsum->paragraphsArray(3); + $this->assertTrue(is_array($paragraphs)); + $this->assertCount(3, $paragraphs); - $this->fail('Not yet implemented.'); + foreach ($paragraphs as $paragraph) + { + $this->assertRegExp('/^([a-z, ]+\.)+$/i', $paragraph); + } } - */ public function testMarkupString() {