Word Wrapping
di Giovanni Bronzini
Mi è capitato in diverse
occasioni di dover "domare" dei testi eccessivamente lunghi
e doverli impaginare.
Questa routine è molto
semplice ma al tempo stesso sfrutta un meccanismo avanzato della
programmazione lineare strutturata quale la ricorsione.
Il sorgente si commenta da sé....
Buon Word-Wrapping a tutti!
Function WORD_WRAP
( str IN varchar, width IN integer)
RETURN varchar2 IS
stopchars constant varchar2(20) := ' ,/-)]}!?.:';
-- estrae la parte sinistra della stringa da esaminare
-- sino alla dimensione massima ammessa
tmp varchar2(200) := substr(str,1,width);
n integer := 0;
pos integer;
-- codice di ritorno a capo
-- chr(13)||chr(10) per sistemi Windows
-- chr(10) per sistemi Unix
cr varchar2(10) := chr(13)||chr(10);
BEGIN
-- se la lunghezza della riga da esaminare e' inferiore
-- alla larghezza massima ammessa restituisce
-- la stringa stessa
if length(str) < width then
return str;
end if;
-- controllo se ci sono dei ritorni a capo
pos := INSTR(tmp,chr(13));
if pos <=width and pos >0 then
return substr(tmp,1,pos-1) || cr || word_wrap(substr(str,pos+2),width);
end if;
pos := INSTR(tmp,chr(10));
if pos <=width and pos > 0 then
return substr(tmp,1,pos-1) || cr || word_wrap(substr(str,pos+1),width);
end if;
-- se il controllo arriva qui allora la riga da
-- esaminare era piu' lunga della dimensione massima
-- ammessa
-- ciclo per determinare quale fra i caratteri validi e'
-- l'ultimo che compare nella sottostringa "tmp"
for c in 1..length(stopchars) loop
pos := INSTR(tmp,substr(stopchars,c,1), -1);
if pos > n then
n := pos;
end if;
end loop;
-- se nessuno di essi e' presente allora viene forzato
-- il ritorno a capo
if n=0 then
return tmp || cr || word_wrap(substr(str,width+1),width);
end if;
-- altrimenti (e' stato trovato)
-- e ritorna una sottostringa estratta da tmp sino al carattere di
-- interruzione, seguita dai caratteri di controllo, e dalla
-- valutazione ricorsiva della stringa rimanente
return substr(tmp,1,n) || cr || word_wrap(substr(str,n+1),width);
END;
|