Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Przycinanie tekstu z formatowaniem HTML, jak to zrobić aby zachować formatowanie
Diabl0
post
Post #1





Grupa: Zarejestrowani
Postów: 24
Pomógł: 1
Dołączył: 25.03.2006

Ostrzeżenie: (0%)
-----


Witam

Jak w temacie głowię się nad problemem przycinania tekstu z formatowaniem HTML (tekst z edytorów typu TinyMCE) do określonej ilości znaków z zachowaniem formatowania, i na razie nic sensownego nie wpada mi do głowy (a i google nic nie podpowiada ciekawego).

Problem jest taki: mam jakiś dłuższy tekst z formatowaniem HTML. Dla uproszczenia i przykładu:

ala ma kota
  1. <b>al<i>a</i> <u>ma</u></b> <i>ko<b>ta</b></i>


I potrzebuję na stronie wyświetlić przykładowo 6 znaków z tego tekstu z zachowaniem formatowania czyli:

ala ma
  1. <b>al<i>a</i> <u>ma</u></b>


Ma ktoś jakiś pomysł jak do tego podejść, albo może mnie nakierować na odpowiednią klasę/przykład ?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 4)
NuLL
post
Post #2





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


tidy" title="Zobacz w manualu php" target="_manual
Go to the top of the page
+Quote Post
Diabl0
post
Post #3





Grupa: Zarejestrowani
Postów: 24
Pomógł: 1
Dołączył: 25.03.2006

Ostrzeżenie: (0%)
-----


Ok... Tidy już teraz używam do domknięcia brakujących tagów ale nadal nie wiem jak skrócić ciąg do zadanej długości według widocznych znaków. Zwykłe substr nie zwraca uwagi czy to jest tag czy nie i tnie jak leci. Kombinowałem trochę z substr i strip_tags ale to też raczej błędna droga... Jedyne co mi przychodzi do głowy to żmudna ręczna analiza stringa od początku aż do trafienia w odpowiedni "czysty" znak ale to jest od cholery obliczeń (i raczej sporo kodu).

Dlatego pytam się czy już ktoś tego nie robił tudzież gdzieś widział gotowe rozwiązanie aby nie wymyślać po raz kolejny koła...
Go to the top of the page
+Quote Post
NuLL
post
Post #4





Grupa: Zarejestrowani
Postów: 2 262
Pomógł: 21
Dołączył: 3.05.2004
Skąd: Sopot, Krakow, W-wa

Ostrzeżenie: (0%)
-----


Zgodne z XHTML - wymaga tagow typu <br/>

  1. <?php
  2. function html_substr(
  3. $posttext, #tekst do skrocenia
  4. $minimum_length = 200, #minimalna dlugosc
  5. $length_offset = 20, #dlugosc offsetu
  6. $cut_words = FALSE, #ciac slowa ?
  7. $dots = TRUE #dokleic 3 kropki (IMG:http://forum.php.pl/style_emoticons/default/questionmark.gif)
  8. ) {
  9.  
  10.    $tag_counter = 0;
  11.    $quotes_on = FALSE;
  12.  
  13.    if (strlen($posttext) > $minimum_length) {
  14.  
  15.        $c = 0;
  16.        for ($i = 0; $i < strlen($posttext); $i++) {
  17.  
  18.            $current_char = substr($posttext,$i,1);
  19.            if ($i < strlen($posttext) - 1) {
  20.                $next_char = substr($posttext,$i + 1,1);
  21.            }
  22.            else {
  23.                $next_char = "";
  24.            }
  25.  
  26.            if (!$quotes_on) {
  27.                if ($current_char == '<') {
  28.                    if ($next_char == '/') {
  29.                        $tag_counter += 1;
  30.                    }
  31.                    else {
  32.                        $tag_counter += 3;
  33.                    }
  34.                }
  35.  
  36.                if ($current_char == '/' && $tag_counter <> 0) $tag_counter -= 2;
  37.   
  38.                if ($current_char == '>') $tag_counter -= 1;
  39.  
  40.                if ($current_char == '"') $quotes_on = TRUE;
  41.            }
  42.            else {
  43.                if ($current_char == '"') $quotes_on = FALSE;
  44.            }
  45.            
  46.            if($tag_counter == 2 || $tag_counter == 0){
  47.                $c++;
  48.            }          
  49.                            
  50.            if ($c > $minimum_length - $length_offset && $tag_counter == 0 && ($next_char == ' ' || $cut_words == TRUE)) {
  51.                $posttext = substr($posttext,0,$i + 1);              
  52.                if($dots){
  53.                    $posttext .= '...';
  54.                }
  55.                return $posttext;
  56.            }
  57.        }
  58.    }  
  59.    return $posttext;
  60. }
  61. ?>


Ten post edytował NuLL 20.05.2006, 12:17:04
Go to the top of the page
+Quote Post
Diabl0
post
Post #5





Grupa: Zarejestrowani
Postów: 24
Pomógł: 1
Dołączył: 25.03.2006

Ostrzeżenie: (0%)
-----


Dzięki... Nie jest to ideał (np. wymóg XHTML) ale za to podsunał mi własny pomysł którego szybka implementacja znajduje się poniżej:

  1. <?php
  2.  
  3. /**
  4.  * Diablos HTML truncate
  5.  *
  6.  * My version of choping strings (with html tags) around a specified length.
  7.  *
  8.  * @author Diabl0
  9.  * @version 0.5
  10.  * @uses Tidy Functions
  11.  *
  12.  * @param string $text
  13.  * @param integer $minimum_length
  14.  * @param integer $length_offset
  15.  * @param boolean $word_cut
  16.  * @param string $postfix
  17.  * @return string
  18.  */
  19. function my_html_substr($text, $minimum_length = '256', $length_offset = '20', $word_cut = false, $postfix = '...') {
  20. $tag_counter = 0;
  21. $quotes_on = FALSE;
  22.  
  23. // $text = html_entity_decode($text);
  24. $text = preg_replace('/\s+/', ' ', $text);
  25.  
  26. if (strlen(strip_tags($text)) > $minimum_length) {
  27.  
  28. $st = 0;
  29. for ($i = 0; $i < strlen($text); $i++) {
  30. $current_char = substr($text,$i,1);
  31. if ($current_char == '<') {
  32. // Mamy początek znacznika - zakończenia znacznika
  33. $jump = strpos($text, '>', $i);
  34. $i = $jump;
  35. } else {
  36. // Mamy czysty znak, liczymy go i jedziemy dalej.
  37. $st++;
  38. }
  39.  
  40.  
  41. // Mamy cały string?
  42. if ($st == $minimum_length) {
  43. if ($word_cut != True) {
  44. // Nie możemy ciąć słów :( więc trzeba znależć spację lub enter
  45. $space = strpos($text, ' ', $i);
  46. $enter = strpos($text, "\n", $i);
  47. if ( ($space < $enter OR !$enter) AND $space < strlen($text) AND $space < $minimum_length+$length_offset) {
  48. $output = $output = substr($text, 0, $space);
  49. } elseif ( ($space > $enter OR !$space) AND $enter < strlen($text) AND $enter < $minimum_length+$length_offset) {
  50. $output = $output = substr($text, 0, $enter);
  51. } else {
  52. $output = $text;
  53. }
  54. } else {
  55. // Możemy ciąć więc tniemy jak leci
  56. $output = substr($text, 0, $i);
  57. }
  58.  
  59. $output .= $postfix;
  60. // Mamy nasz upragniony string, czas go poprawić pod kątem zamkniętych znaczników
  61. if( function_exists( 'tidy_parse_string' ) ) {
  62. $tidy_config = array( 'indent' => TRUE, 'wrap' => 0 );
  63. $html = $output;
  64. $html = tidy_repair_string($html, $tidy_config, 'raw');
  65. $html = substr($html, strpos($html, '<body>')+6);
  66. $html = trim(substr($html, 0, strpos($html, '</body>')));
  67. $output = $html;
  68. }
  69.  
  70.  
  71. return $output;
  72. }
  73.  
  74. }
  75. }
  76. return $text;
  77. }
  78.  
  79. ?>


Nie jest on idealny (wymaga Tidy), dokładnie sprawdzony (nie jestem pewien wszystkich warunków), ani nawet ładny (jeszcze nad nim myślę), czy porządnie skomentowany (powstawał na szybko). Ale wrzucam go tutaj do skomentowania (i być może podsunięcia innych ciekawych rozwiązań).
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 08:44