[php] Skracanie tekstu z uwzględnieniem bbcode

szukaj na forum nowy temat odpowiedz

Strona [ 1 ] z 1

apok ten post 01-12-2006 14:43





Chcę, żeby na stronie głównej były wyświetlane tylko początki newsów - pierwsze 600 znaków. Problem polega na tym, że w newsach mogą być stsowane tagi bbcode:
[img][/img], [quote][/quote], [url][/url], [url=],[/url], [b][/b], [i][/i], [u][/u], [color=][/color], [br], [hr], [center][/center]
I jeśli cały tag nie zmieści się w tych 600 znakach (zacznie się, ale nie skończy), to będą komplikacje. Chyba wiadomo jakie.
Czy wie ktoś w jaki sposób się przed tym zabezpieczyć? Chciałbym, żeby było coś takiego, że jeśli nie zmieści się tag np. obrazka, to zostanie pominięty całkiem(wycięty), czyli tekst zostanie skrócony do miejsca gdzie zaczyna się ten tag. Jeśli się zmieści, to oczywiście ma zostać. Jeśli nie zmieszczą się całe tagi takie jak [b], [u], [quote] itp, to zostaną poprostu zamknięte wcześniej, zaraz po tych 600 znakach.
Wie ktoś jak takie coś zrobić?
Przejdź na górę strony
cytuj
mysz ten post 02-12-2006 00:40
avatar

Użytkownik
Status: Offline
Dołączył: 15-09-2006
Skąd: Szczecin
Nie prościej wyciąć wszystkie tagi (bez ich zawartosci oczywiscie), i dopiero później obcinac do 600 znaków?
http://sztolcman.eu
http://urzenia.net
Przejdź na górę strony
cytuj
apok ten post 02-12-2006 22:49





No, ale pasuje, żeby na stronie głównej te taki też działały, a jak je wytnę, to chyba nic z tego
Przejdź na górę strony
cytuj
mysz ten post 02-12-2006 23:54
avatar

Użytkownik
Status: Offline
Dołączył: 15-09-2006
Skąd: Szczecin
Generalnie w inny sposób, poza ręcznym liczeniem znaków i patrzeniem, czy rozpoczęty tag został zamknięty, nic nie zrobisz.
Czyli liczysz znaczki, każde wystąpienie '[' sprawdzasz, czy jest rozpoczęciem taga, jeśli tak to przestajesz liczenia aż do ']', sprawdzasz czy tag jest pojedynczy czy podwójny, jeśli podwójny to odkładasz go sobie na stos. Liczysz dalej, aż natkniesz się na zakończenie taga (jeśli był podwójny), zdejmujesz go wtedy za stosu, i kiczysz dalej. Jak dojdziesz do 600, to sprawdzasz czy na stosie są jeszcze jakieś tagi, jak tak, to je zamykasz i wtedy kończysz.

Oczywiście nie znaczy że masz o robić po jednej literce - pokombinuj albo z regexpami (choć nie wiem czy sensownie Ci tutaj pomogą), albo strpos(), albo różne takie. Walcz :)

Ale zagadnienie nawet ciekawe, może jak znajde chwilę wolnego to napiszę jakieś przyjemne narzędzie do tego :) Zapisuję sobie pomysł w moim małym TODO ;)
http://sztolcman.eu
http://urzenia.net
Przejdź na górę strony
cytuj
Adamo ten post 03-12-2006 00:09
avatar

Użytkownik
Status: Offline
Dołączył: 13-03-2004
Skąd: daleeeeeko
ucinasz 600 znaków, szukasz ostatniej pozycji [ i osobno ], jeśli pozycja [ jest późniejsza niż ostatniego ] to dodajesz na końcu ] albo ucinasz wszystko po nim i parsujesz normalnie jak to robisz przy pełnym artykule (oczywiście zadziała jeśli obsługę tego bbcode'u masz poprawnie zrobioną)
Dwie zasady gwarantujące sukces:
1. Nigdy nie mów nikomu wszystkiego

Ostatnio zmodyfikowany: 03-12-2006 00:13 przez Adamo
Przejdź na górę strony
cytuj
mysz ten post 03-12-2006 10:23
avatar

Użytkownik
Status: Offline
Dołączył: 15-09-2006
Skąd: Szczecin
@Adamo: ale wtedy cała zajawka nie będzie widoczna jako 600 znaków, tylko 600 znaków - długość znaczników. Czyli w skrajnych wypadkach może jej prawie nie być.
A sądzę że da się to zrobić całkiem efektywnie w taki sposób jak opisałem.
http://sztolcman.eu
http://urzenia.net
Przejdź na górę strony
cytuj
Adamo ten post 03-12-2006 14:46
avatar

Użytkownik
Status: Offline
Dołączył: 13-03-2004
Skąd: daleeeeeko
aha fuckt, jakoś późno było to coś mi się poprzestawiało ;P
@nav: to chyba raczej do tego wątku
//tru - n

no na pewno nie da się tego zrobić inaczej niż mysz sugeruje, jedyne pytanie czy trzeba się bawić po znaku czy też strpos i tym podobne czy można wykorzystać gotowe funkcje
Dwie zasady gwarantujące sukces:
1. Nigdy nie mów nikomu wszystkiego

Ostatnio zmodyfikowany: 03-12-2006 15:52 przez nav
Przejdź na górę strony
cytuj
mysz ten post 03-12-2006 21:40
avatar

Użytkownik
Status: Offline
Dołączył: 15-09-2006
Skąd: Szczecin
Najlepsza koncpecja, jaką udało mi się wymyśleć tak na dość szybko, to to co poniżej:
//funkcja pomocnicza
//zwraca:
//nazwa tagu - jeśli jest to rozpoczęcie tagu podwojnego
//1 - jeśli to pojedynczy tag
//0 - jeśli to zwykły tekst
//-1 - jeśli to zakończenie tagu
function check_tag($s) {
        if (preg_match('!^\[(img|quote|url|b|i|u|color|center)(\s*=\s*.*?)?\]$!i', $s, $match)) { //tag rozpoczynający
                return $match[1];
        } else if (preg_match('!^\[/(img|quote|url|b|i|u|color|center)\]$!i', $s)) { //tag kończący
                return -1;
        } else if (preg_match('!^\[(br|hr)\]$!i', $s)) { //tag pojedynczy
                return 1;
        } else { // zwykly string
                return 0;
        }
}

//$str    - string
//$len    - długość
//$type   - string lub array
//$concat - string służący do łączenia poszczególnych kawałków
function strTagsCut($str, $len, $type='string', $concat='') {
        static $tags = array(
                'single' => array('br', 'hr'),
                'double' => array('img','quote','url','b', 'i', 'u', 'color', 'center'),
        );
        $pat = sprintf('!(\[/?(?:%s|%s)(?:\s*=\s*.*?]*)?\])!i',
                implode('|', $tags['single']),
                implode('|', $tags['double'])
        );

        $splitted = preg_split($pat, $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
        $count    = 0;
        $stack    = array();
        $new      = array();
        foreach ($splitted as $part) {

                $tag = check_tag($part);
                if (is_string($tag)) {
                        array_push($stack, $tag);

                } else if ($tag === 0) {
                        $l = strlen($part);
                        if (($count+$l) >= $len) {
                                $new[] = substr($part, 0, -($count+$l-$len));
                                foreach (array_reverse($stack) as $el) {
                                        $new[] = sprintf('[/%s]', $el);
                                }
                                break;
                        }
                        $count += $l;

                } else if ($tag === -1) {
                        array_pop($stack);
                }

                $new[] = $part;

        }

        return $type=='array' ? $new : join($concat, $new);
}


Sposób użycia:
echo strTagsCut($jakis_tekst, 600);

http://sztolcman.eu
http://urzenia.net
Przejdź na górę strony
cytuj
apok ten post 04-12-2006 14:03





Dzięki za kod. W sumie, to nie liczyłem, że komuś się będzie chciało całą funkcję pisać, tylko ktoś mi coś podpowie, więc naprawdę dzięki za pomoc.
Tylko dalej jest pewnien problem z tagami:
[url]http://asdasdasdasdasd[/url] i [img]http://cośtamasdasdasdasd[/img]

[url=http:/asdasdasdasdasd]nazwa linka[/url] działa dobrze, bo skraca najwyżej tekst nazwa linka, ale [url]http://www.asdasdasd.asd[/url] nie może skracać tekstu wewnątrz tagów, bo właśnie tam jest url. Da się coś z tym zrobić? Tak samo z img, bo wtedy otrzymam niepełny adres obrazka
Przejdź na górę strony
cytuj
mysz ten post 04-12-2006 15:46
avatar

Użytkownik
Status: Offline
Dołączył: 15-09-2006
Skąd: Szczecin
A może na serwer też wgrać za Ciebie? :/ IMO to już trochę się wysilić możesz sam. I tak zrobiłem dużo. Jak widzę, za dużo...

Manual trackback: http://urzenia.net/316/skracanie-tekstu/
http://sztolcman.eu
http://urzenia.net
Przejdź na górę strony
cytuj
szukaj na forum nowy temat odpowiedz

Strona [ 1 ] z 1

1 użytkownik(ów) przegląda ten temat (1 gości)
(żadnych zarejestrowanych użytkowników)

Copyright © 2000-2006 by Coyote Group 0.9.3-pre3
Czas generowania strony: 0.1404 sek. (zapytań SQL: 9)