Carnet Wiki

filtre couper en gardant mise en page

Version 3 — Mars 2015 JLuc

Version Rastapopoulos

- nom d’origine : ltaskel_truncate
-  contexte de création :

<blockquote class="spip">

J’utilise ça avec Accès Restreint et l’option define(’AR_TOUJOURS_TOUT_VOIR’, true) ;
qui permet de gérer soi-même les tests de zone, de restriction etc
Avec cette option d’accès restreint, ça ne filtre plus les boucles automatiques, on re-voit tout comme d’habitude mais dans mon squelette je peux tester avec les fonctions du plugin si un contenu est restreint
notamment avec #ID_ARTICLE|accesrestreint_article_restreint et si ça c’est restreint, alors j’affiche l’article en HTML tronqué et donc en gardant sa mise en page, y compris les images insérées, qui resteraient dans la partie non tronquée
Exemple d’utilisation : http://www.latribunedelart.com/fragonard-and-the-fantasy-figure-painting-the-imagination

</blockquote>

/**
* Truncates text.
*
* Cuts a string to the length of $length and replaces the last characters
* with the ending if the text is longer than length.
*
* ### Options:
*
* - <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+ZW5kaW5nPC9jb2RlPg=="></span> Will be used as Ending and appended to the trimmed string
* - <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+ZXhhY3Q8L2NvZGU+"></span> If false, $text will not be cut mid-word
* - <span class="base64" title="PGNvZGUgY2xhc3M9InNwaXBfY29kZSBzcGlwX2NvZGVfaW5saW5lIiBkaXI9Imx0ciI+aHRtbDwvY29kZT4="></span> If true, HTML tags would be handled correctly
*
* @param string  $text String to truncate.
* @param integer $length Length of returned string, including ellipsis.
* @param array $options An array of html attributes and options.
* @return string Trimmed string.
* @access public
* @link http://book.cakephp.org/view/1469/Text#truncate-1625
*/
function truncate_html ($text, $length = 100, $options = array()) {
    $default = array(
        'ending' => '...', 'exact' => true, 'html' => false
    );
    $options = array_merge($default, $options);
    extract($options);


if ($html) {
        if (mb_strlen(preg_replace('/<.*?>/', '', $text)) &lt;= $length) {
            return $text;
        }
        $totalLength = mb_strlen(strip_tags($ending));
        $openTags = array();
        $truncate = '';


preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER);
        foreach ($tags as $tag) {
            if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) {
                if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) {
                    array_unshift($openTags, $tag[2]);
                } else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) {
                    $pos = array_search($closeTag[1], $openTags);
                    if ($pos !== false) {
                        array_splice($openTags, $pos, 1);
                    }
                }
            }
            $truncate .= $tag[1];


$contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', ' ', $tag[3]));
            if ($contentLength + $totalLength > $length) {
                $left = $length - $totalLength;
                $entitiesLength = 0;
                if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|&#x[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) {
                    foreach ($entities[0] as $entity) {
                        if ($entity[1] + 1 - $entitiesLength &lt;= $left) {
                            $left--;
                            $entitiesLength += mb_strlen($entity[0]);
                        } else {
                            break;
                        }
                    }
                }


$truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength);
                break;
            } else {
                $truncate .= $tag[3];
                $totalLength += $contentLength;
            }
            if ($totalLength >= $length) {
                break;
            }
        }
    } else {
        if (mb_strlen($text) <= $length) {
            return $text;
        } else {
            $truncate = mb_substr($text, 0, $length - mb_strlen($ending));
        }
    }
    if (!$exact) {
        $spacepos = mb_strrpos($truncate, ' ');
        if (isset($spacepos)) {
            if ($html) {
                $bits = mb_substr($truncate, $spacepos);
                preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
                if (!empty($droppedTags)) {
                    foreach ($droppedTags as $closingTag) {
                        if (!in_array($closingTag[1], $openTags)) {
                            array_unshift($openTags, $closingTag[1]);
                        }
                    }
                }
            }
            $truncate = mb_substr($truncate, 0, $spacepos);
        }
    }
    $truncate .= $ending;


if ($html) {
        foreach ($openTags as $tag) {
            $truncate .= '</'.$tag.'>';
        }
    }


return $truncate;
}

Version X

-  Origine incertaine : http://forum.spip.net/fr_242912.html
-  Nom original : trunqhtml

/*
 * Coupe une chaine en gardant le formatage HTML
 * @param string $text Texte à couper
 * @param integer $length Longueur à garder
 * @param string $ending Caractères à ajouter à la fin
 * @param boolean $exact Coupure exacte
 * @return string
 */
function couper_html($text, $length, $ending = '...', $exact = false) {
    if(strlen(preg_replace('/<.*?>/', '', $text)) <= $length) {
        return $text;
    }
    preg_match_all('/(<.+?>)?([^<>]*)/is', $text, $matches, PREG_SET_ORDER);
    $total_length = ;
    $arr_elements = array();
    $truncate = '';
    foreach($matches as $element) {
        if(!empty($element[1])) {
            if(preg_match('/^<\s*.+?\/\s*>$/s', $element[1])) {
            } else if(preg_match('/^<\s*\/([^\s]+?)\s*>$/s', $element[1], $element2)) {
                $pos = array_search($element2[1], $arr_elements);
                if($pos !== false) {
                    unset($arr_elements[$pos]);
                }
            } else if(preg_match('/^<\s*([^\s>!]+).*?>$/s', $element[1], $element2)) {
                array_unshift($arr_elements,
                strtolower($element2[1]));
            }
            $truncate .= $element[1];
        }
        $content_length = strlen(preg_replace('/(&[a-z]{1,6};|&#[0-9]+;)/i', ' ', $element[2]));
        if($total_length >= $length) {
            break;
        } elseif ($total_length+$content_length > $length) {
            $left = $total_length>$length?$total_length-$length:$length-$total_length;
            $entities_length = ;
            if(preg_match_all('/&[a-z]{1,6};|&#[0-9]+;/i', $element[2], $element3, PREG_OFFSET_CAPTURE)) {
                foreach($element3[0] as $entity) {
                    if($entity[1]+1-$entities_length <= $left) {
                        $left--;
                        $entities_length += strlen($entity[0]);
                    } else break;
                }
            }
            $truncate .= substr($element[2], , $left+$entities_length);
            break;
        } else {
            $truncate .= $element[2];
            $total_length += $content_length;
        }
    }
    if(!$exact) {
        $spacepos = strrpos($truncate, ' ');
        if(isset($spacepos)) {
            $truncate = substr($truncate, , $spacepos);
        }
    }
    $truncate .= $ending;
    foreach($arr_elements as $element) {
        $truncate .= '</' . $element . '>';
    }
    return $truncate;
}