flay.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: flay.php 7847 2008-11-08 02:54:07Z renan.saddam $ */
00003 /**
00004  * Text-to-HTML parser.
00005  *
00006  * Text-to-html parser, similar to {@link http://textism.com/tools/textile/ Textile} or {@link http://www.whytheluckystiff.net/ruby/redcloth/ RedCloth}.
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs
00021  * @since         CakePHP(tm) v 0.2.9
00022  * @version       $Revision: 7847 $
00023  * @modifiedby    $LastChangedBy: renan.saddam $
00024  * @lastmodified  $Date: 2008-11-07 21:54:07 -0500 (Fri, 07 Nov 2008) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Included libraries.
00029  *
00030  */
00031 if (!class_exists('Object')) {
00032     uses('object');
00033 }
00034 /**
00035  * Text-to-HTML parser.
00036  *
00037  * Text-to-html parser, similar to Textile or RedCloth, only with a little different syntax.
00038  *
00039  * @package       cake
00040  * @subpackage    cake.cake.libs
00041  */
00042 class Flay extends Object{
00043 /**
00044  * Text to be parsed.
00045  *
00046  * @var string
00047  * @access public
00048  */
00049     var $text = null;
00050 /**
00051  * Set this to allow HTML in the markup.
00052  *
00053  * @var boolean
00054  * @access public
00055  */
00056     var $allow_html = false;
00057 /**
00058  * Constructor.
00059  *
00060  * @param string $text Text to transform
00061  */
00062     function __construct($text = null) {
00063         $this->text = $text;
00064         parent::__construct();
00065     }
00066 /**
00067  * Returns given text translated to HTML using the Flay syntax.
00068  *
00069  * @param string $text String to format
00070  * @param boolean $bare Set this to only do <p> transforms and > to &gt;, no typography additions.
00071  * @param boolean $allowHtml Set this to trim whitespace and disable all HTML
00072  * @return string Formatted text
00073  * @access public
00074  */
00075     function toHtml($text = null, $bare = false, $allowHtml = false) {
00076         if (empty($text) && empty($this->text)) {
00077             return false;
00078         }
00079         $text = $text ? $text : $this->text;
00080         // trim whitespace and disable all HTML
00081         if ($allowHtml) {
00082             $text = trim($text);
00083         } else {
00084             $text = str_replace('<', '&lt;', str_replace('>', '&gt;', trim($text)));
00085         }
00086 
00087         if (!$bare) {
00088             // multi-paragraph functions
00089             $text=preg_replace('#(?:[\n]{0,2})"""(.*)"""(?:[\n]{0,2})#s', "\n\n%BLOCKQUOTE%\n\n\\1\n\n%ENDBLOCKQUOTE%\n\n", $text);
00090             $text=preg_replace('#(?:[\n]{0,2})===(.*)===(?:[\n]{0,2})#s', "\n\n%CENTER%\n\n\\1\n\n%ENDCENTER%\n\n", $text);
00091         }
00092 
00093         // pre-parse newlines
00094         $text=preg_replace("#\r\n#", "\n", $text);
00095         $text=preg_replace("#[\n]{2,}#", "%PARAGRAPH%", $text);
00096         $text=preg_replace('#[\n]{1}#', "%LINEBREAK%", $text);
00097         $out ='';
00098 
00099         foreach (split('%PARAGRAPH%', $text)as $line) {
00100             if ($line) {
00101                 if (!$bare) {
00102                     $links = array();
00103                     $regs = null;
00104 
00105                     if (preg_match_all('#\[([^\[]{4,})\]#', $line, $regs)) {
00106                         foreach ($regs[1] as $reg) {
00107                             $links[] = $reg;
00108                             $line = str_replace("[{$reg}]", '%LINK' . (count($links) - 1) . '%', $line);
00109                         }
00110                     }
00111                     // bold
00112                     $line = ereg_replace("\*([^\*]*)\*", "<strong>\\1</strong>", $line);
00113                     // italic
00114                     $line = ereg_replace("_([^_]*)_", "<em>\\1</em>", $line);
00115                 }
00116                 // entities
00117                 $line = str_replace(' - ', ' &ndash; ', $line);
00118                 $line = str_replace(' -- ', ' &mdash; ', $line);
00119                 $line = str_replace('(C)', '&copy;', $line);
00120                 $line = str_replace('(R)', '&reg;', $line);
00121                 $line = str_replace('(TM)', '&trade;', $line);
00122                 // guess e-mails
00123                 $emails = null;
00124                 if (preg_match_all("#([_A-Za-z0-9+-+]+(?:\.[_A-Za-z0-9+-]+)*@[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)*)#", $line, $emails)) {
00125                     foreach ($emails[1] as $email) {
00126                         $line = str_replace($email, "<a href=\"mailto:{$email}\">{$email}</a>", $line);
00127                     }
00128                 }
00129 
00130                 if (!$bare) {
00131                     $urls = null;
00132                     if (preg_match_all("#((?:http|https|ftp|nntp)://[^ ]+)#", $line, $urls)) {
00133                         foreach ($urls[1] as $url) {
00134                             $line = str_replace($url, "<a href=\"{$url}\">{$url}</a>", $line);
00135                         }
00136                     }
00137 
00138                     if (preg_match_all("#(www\.[^\n\%\ ]+[^\n\%\,\.\ ])#", $line, $urls)) {
00139                         foreach ($urls[1] as $url) {
00140                             $line = str_replace($url, "<a href=\"http://{$url}\">{$url}</a>", $line);
00141                         }
00142                     }
00143 
00144                     if ($count = count($links)) {
00145                         for ($ii = 0; $ii < $count; $ii++) {
00146                             if (preg_match("#^(http|https|ftp|nntp)://#", $links[$ii])) {
00147                                 $prefix = null;
00148                             } else {
00149                                 $prefix = 'http://';
00150                             }
00151                             if (preg_match('#^[^\ ]+\.(jpg|jpeg|gif|png)$#', $links[$ii])) {
00152                                 $with = "<img src=\"{$prefix}{$links[$ii]}\" alt=\"\" />";
00153                             } elseif (preg_match('#^([^\]\ ]+)(?:\ ([^\]]+))?$#', $links[$ii], $regs)) {
00154                                 if (isset($regs[2])) {
00155                                     if (preg_match('#\.(jpg|jpeg|gif|png)$#', $regs[2])) {
00156                                         $body = "<img src=\"{$prefix}{$regs[2]}\" alt=\"\" />";
00157                                     } else {
00158                                         $body = $regs[2];
00159                                     }
00160                                 } else {
00161                                     $body = $links[$ii];
00162                                 }
00163                                 $with = "<a href=\"{$prefix}{$regs[1]}\" target=\"_blank\">{$body}</a>";
00164                             } else {
00165                                 $with = $prefix . $links[$ii];
00166                             }
00167                             $line = str_replace("%LINK{$ii}%", $with, $line);
00168                         }
00169                     }
00170                 }
00171                 $out .= str_replace('%LINEBREAK%', "<br />\n", "<p>{$line}</p>\n");
00172             }
00173         }
00174 
00175         if (!$bare) {
00176             $out = str_replace('<p>%BLOCKQUOTE%</p>', "<blockquote>", $out);
00177             $out = str_replace('<p>%ENDBLOCKQUOTE%</p>', "</blockquote>", $out);
00178             $out = str_replace('<p>%CENTER%</p>', "<center>", $out);
00179             $out = str_replace('<p>%ENDCENTER%</p>', "</center>", $out);
00180         }
00181         return $out;
00182     }
00183 /**
00184  * Return the words of the string as an array.
00185  *
00186  * @param string $string
00187  * @return array Array of words
00188  * @access public
00189  */
00190     function extractWords($string) {
00191         $split = preg_split('/[\s,\.:\/="!\(\)<>~\[\]]+/', $string);
00192         return $split;
00193      }
00194 /**
00195  * Return given string with words in array colorMarked, up to a number of times (defaults to 5).
00196  *
00197  * @param array $words          Words to look for and markup
00198  * @param string $string        String to look in
00199  * @param integer $max_snippets Max number of snippets to extract
00200  * @return string String with words marked
00201  * @see colorMark
00202  * @access public
00203  */
00204     function markedSnippets($words, $string, $max_snippets = 5) {
00205         $string = strip_tags($string);
00206         $snips = array();
00207         $rest = $string;
00208         foreach ($words as $word) {
00209             if (preg_match_all("/[\s,]+.{0,40}{$word}.{0,40}[\s,]+/i", $rest, $r)) {
00210                 foreach ($r as $result) {
00211                     $rest = str_replace($result, '', $rest);
00212                 }
00213                 $snips = array_merge($snips, $r[0]);
00214             }
00215         }
00216 
00217         if (count($snips) > $max_snippets) {
00218             $snips = array_slice($snips, 0, $max_snippets);
00219         }
00220         $joined = join(' <b>...</b> ', $snips);
00221         $snips = $joined ? "<b>...</b> {$joined} <b>...</b>" : substr($string, 0, 80) . '<b>...</b>';
00222         return $this->colorMark($words, $snips);
00223     }
00224 /**
00225  * Returns string with EM elements with color classes added.
00226  *
00227  * @param array $words Array of words to be colorized
00228  * @param string $string Text in which the words might be found
00229  * @return string String with words colorized
00230  * @access public
00231  */
00232     function colorMark($words, $string) {
00233         $colors=array('yl', 'gr', 'rd', 'bl', 'fu', 'cy');
00234         $nextColorIndex = 0;
00235         foreach ($words as $word) {
00236             $string = preg_replace("/({$word})/i", '<em class="' . $colors[$nextColorIndex % count($colors)] . "\">\\1</em>", $string);
00237             $nextColorIndex++;
00238         }
00239         return $string;
00240     }
00241 /**
00242  * Returns given text with tags stripped out.
00243  *
00244  * @param string $text Text to clean
00245  * @return string Cleaned text
00246  * @access public
00247  */
00248     function toClean($text) {
00249         $strip = strip_tags(html_entity_decode($text, ENT_QUOTES));
00250         return $strip;
00251     }
00252 /**
00253  * Return parsed text with tags stripped out.
00254  *
00255  * @param string $text Text to parse and clean
00256  * @return string Cleaned text
00257  * @access public
00258  */
00259     function toParsedAndClean($text) {
00260         return $this->toClean(Flay::toHtml($text));
00261     }
00262 /**
00263  * Return a fragment of a text, up to $length characters long, with an ellipsis after it.
00264  *
00265  * @param string $text      Text to be truncated.
00266  * @param integer $length   Max length of text.
00267  * @param string $ellipsis  Sign to print after truncated text.
00268  * @return string Fragment
00269  * @access public
00270  */
00271     function fragment($text, $length, $ellipsis = '...') {
00272         $soft = $length - 5;
00273         $hard = $length + 5;
00274         $rx = '/(.{' . $soft . ',' . $hard . '})[\s,\.:\/="!\(\)<>~\[\]]+.*/';
00275 
00276         if (preg_match($rx, $text, $r)) {
00277             $out = $r[1];
00278         } else {
00279             $out = substr($text, 0, $length);
00280         }
00281         $out = $out . (strlen($out) < strlen($text) ? $ellipsis : null);
00282         return $out;
00283     }
00284 }
00285 ?>

Generated on Sun Nov 22 00:30:53 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7