diff --git a/FhtagnGenerator.php b/FhtagnGenerator.php new file mode 100644 index 0000000..e0d606e --- /dev/null +++ b/FhtagnGenerator.php @@ -0,0 +1,551 @@ + + + Cthuvian Ipsum Generator + + + + + + +
+

Cthuvian Ipsum Generator + +

+
+ + +
+ + + + + + + + + + + +
+ +
+ + + + + + 333333) $iCount = '333333'; + if($iCount < 1) $iCount = '1'; + +?> + + + + + + + + + + + + + + + + + + +
Word count:
Format: + +
Fixed first sentence: + +Yes'; + echo 'No'; + +?> +
+
+ +
+ +
+ + + + + +A lorem ipsun generator based on H.P.Lovecraft's Cthulhu Mythos
+Code based on Mathew Tinsley's PHP Lorem Ipsum
+Wordlist from Cthuvian / English dictionary at www.yog-sothoth.com forums
+Source code at Github
. +Why lorem ipsum when you can Cthulhu fhtagn? + +
+
+ +'; +} + +function checkBool(&$iFhtagn) +{ + if($iFhtagn == 'yes') + { + $iFhtagn = true; + return true; + } + else if($iFhtagn == 'no') + { + $iFhtagn = false; + return true; + } + else + { + return false; + } +} +?> + +
+ by ephemer +
+ + + + + + + BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + private $words, $wordsPerParagraph, $wordsPerSentence, $prefix, $suffix, $start; + + function __construct($wordsPer = 100) + { + $this->wordsPerParagraph = $wordsPer; + $this->wordsPerSentence = 24.460; + $this->start = array( + 'Ph\'nglui', + 'mglw\'nafh', + 'Cthulhu', + 'R\'lyeh', + 'wgah\'nagl', + 'fhtagn.'); + + $this->words = array( + 'Cthulhu', + 'R\'lyeh', + 'Dagon', + 'Hastur', + 'Yoggoth', + 'Nyarlathotep', + 'Shub-Niggurath', + 'Tsathoggua', + 'Azathoth', + 'Chaugnar Faugn', + 'ah', + '\'ai', + 'athg', + '\'bthnk', + 'bug', + 'ch\'', + 'chtenff', + 'ebunma', + 'ee', + 'ehye', + 'ep', + '\'fhalma', + 'fhtagn', + 'fm\'latgh', + 'ftaghu', + 'geb', + 'gnaiih', + 'gof\'nn', + 'goka', + 'gotha', + 'grah\'n', + 'hafh\'drn', + 'hai', + 'hlirgh', + 'hrii', + 'hupadgh', + 'ilyaa', + 'k\'yarnak', + 'kadishtu', + 'kn\'a', + 'li\'hee', + 'llll', + 'lloig', + 'lw\'nafh', + 'mg', + 'mnahn\'', + 'n\'gha', + 'n\'ghft', + 'nglui', + 'nilgh\'ri', + 'nog', + 'nw', + 'ooboshu', + 'orr\'e', + 'phlegeth', + 'r\'luh', + 'ron', + 's\'uhn', + 'sgn\'wahl', + 'shagg', + 'shogg', + 'shtunggli', + 'shugg', + 'sll\'ha', + 'stell\'bsna', + 'syha\'h', + 'tharanak', + 'throd', + 'uaaah', + 'uh\'e', + 'uln', + 'vulgtlagln', + 'vulgtm', + 'wgah\'n', + 'y\'hah', + 'ya', + 'zhro'); + + $this->prefix = array( + 'c', + 'f\'', + 'h\'', + 'na', + 'nafl', + 'ng', + 'nnn', + 'ph\'', + 'y-'); + + $this->suffix = array( + 'agl', + 'nyth', + 'og', + 'or', + 'oth', + 'yar'); + } + + function getContent($count, $format = 'html', $fhtagn = true) + { + $format = strtolower($format); + + if($count <= 0) + return ''; + + switch($format) + { + case 'text': + return $this->getText($count, $fhtagn); + case 'plain': + return $this->getPlain($count, $fhtagn); + default: + return $this->getHTML($count, $fhtagn); + } + } + + private function getWords(&$arr, $count, $fhtagn) + { + $i = 0; + + if($fhtagn) + { + $j = 0; + for($j; $j < count($this->start); $j++) + { + $arr[$j] = $this->start[$j]; + } + $i = count($this->start); + } + + for($i; $i < $count; $i++) + { + $index = array_rand($this->words); + $word = $this->words[$index]; + + //echo $index . '=>' . $word . '
'; + + if($i > 0 && $arr[$i - 1] == $word) + $i--; + else + { + if(mt_rand(0,99) > 79) + $word = $this->prefix[array_rand($this->prefix)] . $word; + else if(mt_rand(0,99) > 89) + $word .= $this->suffix[array_rand($this->suffix)]; + + if($fhtagn && $i == count($this->start)) $word = ucfirst($word); + + $arr[$i] = $word; + } + } + } + + private function getPlain($count, $fhtagn, $returnStr = true) + { + $words = array(); + $this->getWords($words, $count, $fhtagn); + //print_r($words); + + $delta = $count; + $curr = 0; + $sentences = array(); + while($delta > 0) + { + $senSize = $this->gaussianSentence(); + //echo $curr . '
'; + if(($delta - $senSize) < 4) + $senSize = $delta; + + $delta -= $senSize; + + $sentence = array(); + for($i = $curr; $i < ($curr + $senSize); $i++) + $sentence[] = $words[$i]; + + $this->punctuate($sentence); + $curr = $curr + $senSize; + $sentences[] = $sentence; + } + + if($returnStr) + { + $output = ''; + foreach($sentences as $s) + foreach($s as $w) + $output .= $w . ' '; + + return $output; + } + else + return $sentences; + } + + private function getText($count, $fhtagn) + { + $sentences = $this->getPlain($count, $fhtagn, false); + $paragraphs = $this->getParagraphArr($sentences); + + $paragraphStr = array(); + foreach($paragraphs as $p) + { + $paragraphStr[] = $this->paragraphToString($p); + } + + $paragraphStr[0] = "\t" . $paragraphStr[0]; + return implode("\n\n\t", $paragraphStr); + } + + private function getParagraphArr($sentences) + { + $wordsPer = $this->wordsPerParagraph; + $sentenceAvg = $this->wordsPerSentence; + $total = count($sentences); + + $paragraphs = array(); + $pCount = 0; + $currCount = 0; + $curr = array(); + + for($i = 0; $i < $total; $i++) + { + $s = $sentences[$i]; + $currCount += count($s); + $curr[] = $s; + if($currCount >= ($wordsPer - round($sentenceAvg / 2.00)) || $i == $total - 1) + { + $currCount = 0; + $paragraphs[] = $curr; + $curr = array(); + //print_r($paragraphs); + } + //print_r($paragraphs); + } + + return $paragraphs; + } + + private function getHTML($count, $fhtagn) + { + $sentences = $this->getPlain($count, $fhtagn, false); + $paragraphs = $this->getParagraphArr($sentences); + //print_r($paragraphs); + + $paragraphStr = array(); + foreach($paragraphs as $p) + { + $paragraphStr[] = "

\n" . $this->paragraphToString($p, true) . '

'; + } + + //add new lines for the sake of clean code + return implode("\n", $paragraphStr); + } + + private function paragraphToString($paragraph, $htmlCleanCode = false) + { + $paragraphStr = ''; + foreach($paragraph as $sentence) + { + foreach($sentence as $word) + $paragraphStr .= $word . ' '; + + if($htmlCleanCode) + $paragraphStr .= "\n"; + } + return $paragraphStr; + } + + /* + * Inserts commas and periods in the given + * word array. + */ + private function punctuate(& $sentence) + { + $count = count($sentence); + $sentence[$count - 1] = $sentence[$count - 1] . '.'; + $sentence[0] = ucfirst($sentence[0]); + + if($count < 4) + return $sentence; + + $commas = $this->numberOfCommas($count); + + for($i = 1; $i <= $commas; $i++) + { + $index = (int) round($i * $count / ($commas + 1)); + + if($index < ($count - 1) && $index > 0) + { + $sentence[$index] = $sentence[$index] . ','; + } + } + } + + /* + * Determines the number of commas for a + * sentence of the given length. Average and + * standard deviation are determined superficially + */ + private function numberOfCommas($len) + { + $avg = (float) log($len, 6); + $stdDev = (float) $avg / 6.000; + + return (int) round($this->gauss_ms($avg, $stdDev)); + } + + /* + * Returns a number on a gaussian distribution + * based on the average word length of an english + * sentence. + * Statistics Source: + * http://hearle.nahoo.net/Academic/Maths/Sentence.html + * Average: 24.46 + * Standard Deviation: 5.08 + */ + private function gaussianSentence() + { + $avg = (float) 24.460; + $stdDev = (float) 5.080; + + return (int) round($this->gauss_ms($avg, $stdDev)); + } + + /* + * The following three functions are used to + * compute numbers with a guassian distrobution + * Source: + * http://us.php.net/manual/en/function.rand.php#53784 + */ + private function gauss() + { // N(0,1) + // returns random number with normal distribution: + // mean=0 + // std dev=1 + + // auxilary vars + $x=$this->random_0_1(); + $y=$this->random_0_1(); + + // two independent variables with normal distribution N(0,1) + $u=sqrt(-2*log($x))*cos(2*pi()*$y); + $v=sqrt(-2*log($x))*sin(2*pi()*$y); + + // i will return only one, couse only one needed + return $u; + } + + private function gauss_ms($m=0.0,$s=1.0) + { + return $this->gauss()*$s+$m; + } + + private function random_0_1() + { + return (float)rand()/(float)getrandmax(); + } +} // class +?> + + + + + diff --git a/README.md b/README.md index eaf8ed1..39079fc 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,15 @@ # Cthuvian-Ipsum-Generator Cthuvian Ipsum Generator +A lorem ipsun generator based on [H.P. Lovecraft's](https://www.hplovecraft.com/) [Cthulhu Mythos](https://en.wikipedia.org/wiki/Cthulhu_Mythos) + +## History +Way back in 2010, I wanted to try out this PHP thing, and ended up doing a [page](https://ephemer.kapsi.fi/FhtagnGenerator.php) for generating lorem ipsum placeholder text in Cthuvian (also called R'lyehian), the fictional language from H.P. Lovecraft's writings. + +I used some resources which seem to no longer exist on the internet: ++ PHP Lorem Ipsum generator by Mathew Tinsley, originally found at [http://tinsology.net/scripts/php-lorem-ipsum-generator/](http://tinsology.net/scripts/php-lorem-ipsum-generator/) ++ Improved wordlist (with prefixes and suffixes) from Cthuvian / English dictionary, originally found at [http://www.yog-sothoth.com/threads/8683-The-Complete-CTHUVIAN-ENGLISH-DICTIONARY](http://www.yog-sothoth.com/threads/8683-The-Complete-CTHUVIAN-ENGLISH-DICTIONARY) + +The code is put here "as was" for historical accuracy and is outdated and horrible in many ways, but hey, it still works, as seen on the [original page](https://ephemer.kapsi.fi/FhtagnGenerator.php). Maybe I'll make a modern version of it. Probably I won't. + +## License +[MIT](https://choosealicense.com/licenses/mit/) \ No newline at end of file diff --git a/images/cthicon.ico b/images/cthicon.ico new file mode 100644 index 0000000..f36a0de Binary files /dev/null and b/images/cthicon.ico differ diff --git a/images/cthulhu.png b/images/cthulhu.png new file mode 100644 index 0000000..b070e3b Binary files /dev/null and b/images/cthulhu.png differ