Last active
August 29, 2015 13:56
-
-
Save drFabio/9128225 to your computer and use it in GitHub Desktop.
HTML PHP Truncator using tidy. IT counts the texts chars to N chars, if the word didn't end yet it ends, and it closes the html tags that it's left open
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
echo '<pre>'; | |
$subject='<p>Lorem</p> | |
<pre class="brush:js;auto-links:false;toolbar:false" contenteditable="false"> //$(\'textarea[name=html]\').editor(); | |
tinymce.init({selector:\'textarea[name=html]\', | |
plugins: [ // plugins list | |
"preview sh4tinymce wordcount" | |
], | |
toolbar: "undo redo | sh4tinymce | preview" // toolbar list | |
});</pre> | |
<p> Ipsum dolor sit amet</p>'; | |
$hTruncator=new HtmlTruncator($subject,'<a href="#"> More ... </a>'); | |
echo htmlspecialchars($hTruncator->truncateHtml(10)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Truncate an html to at Least N characters, close the remaining tags, and end the world in which it stopped. | |
* Optionally preserve syntaxHighlighter code | |
* @author Fabio Oliveira Costa <[email protected]> | |
*/ | |
class HtmlTruncator{ | |
protected $_tidy; | |
protected $_alwaysShowSyntaxHighlighter; | |
protected $_moreSufix; | |
/** | |
* | |
* @param string $raw the raw HTML we want to truncate | |
* @param int $maxLength the max length of simple text we want | |
* @param string $moreSufix the sufix for more if any | |
*/ | |
public function __construct($raw,$moreSufix='',$alwaysShowSyntaxHighlighter=true){ | |
$this->_tidy=tidy_parse_string($raw)->body(); | |
$this->_moreSufix=$moreSufix; | |
$this->_alwaysShowSyntaxHighlighter=$alwaysShowSyntaxHighlighter; | |
} | |
/** | |
* Make a left tag | |
* @param tidyNode $tidy [description] | |
* @return string | |
*/ | |
protected static function _makeLeftTag(tidyNode $tidy){ | |
if($tidy->isText()){ | |
return ''; | |
} | |
$atrs=''; | |
if(!empty($tidy->attribute)){ | |
foreach ($tidy->attribute as $k => $v) { | |
$atrs.=' '.$k.'="'.$v.'"'; | |
} | |
} | |
return '<'.$tidy->name.$atrs.'>'; | |
} | |
protected static function _makeRightTag(tidyNode $tidy){ | |
if($tidy->isText()){ | |
return ''; | |
} | |
return '</'.$tidy->name.'>'; | |
} | |
/** | |
* Truncate the html that this HtmlTruncator represent to more or less length characters | |
* @param int $length | |
* @return string the truncated html | |
*/ | |
public function truncateHtml($length){ | |
$finished=false; | |
$counting=0; | |
$excerpt=''; | |
$ret= $this->_truncateHtml($this->_tidy,$length,$finished,$counting,$excerpt); | |
if($finished){ | |
return $ret.$this->_moreSufix; | |
} | |
else{ | |
return $ret; | |
} | |
} | |
/** | |
* Check whether this node is the syntax highlighter node | |
* @param tidyNode $tidy [description] | |
* @return boolean [description] | |
*/ | |
protected static function _isSyntaxHighlighter(tidyNode $tidy){ | |
if($tidy->name==='pre'){ | |
if(array_key_exists('class', $tidy->attribute) && strrpos($tidy->attribute['class'], 'brush')!==false){ | |
return true; | |
} | |
} | |
return false; | |
} | |
protected function _truncateHtml(tidyNode $tidy,$length,&$finished,&$counting) { | |
if(empty($tidy)){ | |
return ''; | |
} | |
$excerpt=''; | |
if($this->_alwaysShowSyntaxHighlighter && static::_isSyntaxHighlighter($tidy)){ | |
return static::_makeLeftTag($tidy).$tidy->value.static::_makeRightTag($tidy); | |
} | |
else if($tidy->hasChildren()){ | |
foreach($tidy->child as $c){ | |
$excerpt.=$this->_truncateHtml($c,$length,$finished,$counting); | |
if($finished){ | |
break; | |
} | |
} | |
if($tidy->name==='body'){ | |
return $excerpt; | |
} | |
return static::_makeLeftTag($tidy).$excerpt.static::_makeRightTag($tidy); | |
} | |
else{ | |
if($tidy->isText()){ | |
$text=$tidy->value; | |
$size=strlen($text); | |
if($counting+$size>=$length){ | |
//First space after the minimum chars | |
$lastSpace=strpos($text,' ',$length-$counting); | |
if($lastSpace!==false){ | |
$text=substr($text, 0,$lastSpace); | |
} | |
$size=$lastSpace; | |
$finished=true; | |
} | |
$counting+=$size; | |
return $text; | |
} | |
return static::_makeLeftTag($tidy).static::_makeRightTag($tidy); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment