Guido Socher (homepage)
Yazar hakk�nda:
Olduk�a esnek ve h�zl� bir betik yaz�m dili olmas� sebebi ile Guido Perl'den ho�lanmaktad�r.
Perl'�n a��kkod ile y�r�d���n�zde tan�d��� imkanlar� ve �zg�rl��� ifade eden "Bunu yapmak i�in birden fazla
yolumuz var" slogan�n� sever.
T�rk�e'ye �eviri:
�nan� �z�ubuk�u <inanco(at)atlas.net.tr>
��erik:
|
Managing HTML with Perl, HTML::TagReader
�zet:
E�er 10 HTML sayfas�ndan fazla bir sanal y�reyi idare etmek isterseniz size destek ama�l� baz� yaz�l�mlara ihtiya�
oldu�unu g�receksiniz.
Bir�ok al���lagelmi� yaz�l�m dosyalar� sat�r sat�r (karakter karakter) okur. Maalesef sat�rlar�n SGML/XML/HTML
dosyalar�nda bir anlam� yoktur. SGML/XML/HTML dosyalar� Etiket tabanl�d�r. HTML::TagReader bir dosyay� Etiket ile i�letmek i�in bir
bile�endir.
Bu yaz� Perl'� biraz bildi�inizi varsaymaktad�r. E�er Perl ��renmek istiyorsan�z my Perl tutorials
(January 2000) adresine bir g�z at�n.
_________________ _________________ _________________
|
Giri�
Al���la gelmi� dosyalar sat�r temellidir. �rnek olarak Unix'teki /etc/hosts, /etc/passwd tan�mlama dosyalar� gibi.
Sat�r sat�r veri girmek ve d�zeltmek i�in fonksiyonlar�n�z�n oldu�u daha da eski i�letim sistemleri vard�r.
SGML/XML/HTML
dosyalar� Etiket temellidir. Burada sat�rlar�n bir anlam� yoktur ama yine de dosya edit�rleri ve insanlar halen bir �ekilde
sat�r tabanl�d�rlar.
�zellikle b�y�k HTML dosyalar� genelde bir dizi HTML kodu i�eren sat�rlardan olu�ur. "Tidy" gibi baz� ara�lar html'yi
yorumlat�p okunabilir yaparlar. Biz HTML dahi olsa sat�rlar yerine Etiket kullanmaktay�z. Bunu C-kodu ile mukayese edebilirsiniz.
Teorik olarak t�m kodu basit bir sat�rda yazabilirsiniz. Kimse bunu yapmaz. Yoksa okunamaz olur.
Bu sebeple bir HTML yaz�m denet�isinin "ERROR after tag 4123" yazmas�ndan �ok "ERROR: line ..." yazmas�n� beklersiniz.
Bunun sebebi yaz�m arac�n�z�n belirtilen sat�ra kolayl�kla atlayabilmesidir.
Burada ihtiya� olan g�zel ve kolay bir yolla HTML dosyas�n� Etiket Etiket olarak i�lemek ve halen sat�r numaralar�n�
tutmakt�r..
Muhtemel bir ��z�m
Bir dosyay� Perl'de okuman�n en al���lm�� yolu while(<FILEHANDLE>) i�letimcisi kullanmakt�r. Bu veriyi
sat�r sat�r okuyacak ve her sat�r� $_ de�i�kenine aktaracakt�r. Perl neden bunu yap�yor? Perl, "\n" sat�r sonunu ifade eden
i�e y�nelik INPUT_RECORD_SEPARATOR olarak adland�r�lan bir de�i�kene sahiptir. E�er $/=">" olarak atarsan�z Perl ">"
'� "sat�r sonu" gibi kullanacakt�r. A�a��daki komut sat�r� Perl beti�i sonunda hep ">" olacak �ekilde html dosyas�n�
yeniden bi�imlendirecektir :
perl -ne 'sub BEGIN{$/=">";} s/\s+/ /g; print
"$_\n";' file.html
Bir HTML dosyas� �una benzer
<html><p>some text here</p></html>
will become
<html>
<p>
some text here</p>
</html>
�nemli olan yine de okunulabilirlik de�ildir. Yaz�l�m geli�tirici i�in �nemli olan verinin kodundaki fonksiyonlar�ndan
Etiket Etiket ge�mesidir. Bununla birlikte as�l HTML ayr� sat�rlarda "a" ve "href" i�erse bile bir "<a href= ..." aramak kolay
olacak.
"$/" (INPUT_RECORD_SEPARATOR) '� de�i�tirmek i�lemde art��a sebep olmaz ve olduk�a h�zl�d�r. Yine ayn� �ekilde
kar��la�t�rma i�letimcisini ve al���lm�� deyimleri bir seri gibi kullanmak ve dosyay� al���lm�� deyimlerle i�lemek m�mk�nd�r.
Bu biraz daha karma��k ve yava� olmakla birlikte s�kl�kla kullan�lmaktad�r.
Sorun nerede?? Bu yaz�n�n ba�l��� dedi ki HTML::TagReader fakat ben s�rekli ilave mod�ller gerektirmeyen daha
basit ��z�mlerden bahsediyorum. Bu ��z�mde yanl�� olan bir �eyler olmal�:
- Genelde d�nyadaki t�m HTML dosyalar� hatal�d�r. �rnek olarak C kod �rnekleri bar�nd�ran ve HTML seviyesinde
�u �ekilde g�r�nen milyonlarca sayfa vard�r
if ( limit > 3) ....
instead of
if ( limit > 3) ....
HTML'de "<" bir Etiket ba�lamal� ve">" bitmeli. Hi�biri dosyan�n bir yerinde kendisini belli etmemelidir. �o�u
taray�c� t�m�n� do�ru g�sterir ve hatay� gizler.
- "$/" de�i�tirmek t�m program� etkiler. E�er HTML dosyas�n� okurken bir di�er dosyay� sat�r sat�r i�letmek isterseniz
sorununuz var demektir.
Di�er bir deyi�le "$/" (INPUT_RECORD_SEPARATOR) kullanmak sadece �zel durumlarda m�mk�nd�r.
Elimde neyi
tart��t���m�z� g�sterir �ok yararl� bir �rnek program var. Her ne kadar "$/"� "<"ye atasa da web taray�c�lar� yanl��
konmu� "<" yi ">" gibi destekleyemez. Bu sebeple ">" yerine yanl�� "<" yerle�tirilmi� web sayfas� daha azd�r.
Program tr_tagcontentgrep(click to view) olarak adland�r�lmakta
ve sat�r numaras�n�n kayd�n�n nas�l tutuldu�unu da kod i�erisinde g�rebilirsiniz. tr_tagcontentgrep, Etiket bir�ok sat�rdan
olu�uyor olsa bile, bir dizi (�r: "img") "grep" etmek i�in kullan�labilir. �una benzer:
tr_tagcontentgrep -l img file.html
index.html:53: <IMG src="../images/transpix.gif" alt="">
index.html:257: <IMG SRC="../Logo.gif" width=128
height=53>
HTML::TagReader
HTML::TagReader iki sorunu INPUT_RECORD_SEPARATOR '� uyarlamakla ��z�mler ve ayn� zamanda d�z yaz�lar� Etiket'lerden
ay�rmak i�in �ok daha ho� bir yol sunar. Y�kl� bir HTML:Parser gibi a��r de�ildir ve html kodunu i�letince size istedi�iniz
�eyi sunar:Etiket Etiket okuma y�ntemidir.
Bu kadar laf yeter. ��te nas�l kullanaca��n�z. �nce kodunuz i�erisine mod�l� y�klemek i�in
use HTML::TagReader;
yazmal�s�n�z.
Sonu�ta
my $p=new HTML::TagReader "filename";
kullanarak "dosyaismi" dosyas�n� a�ar�z ve $p i�erisindeki
nesneyi getiririz. Bir sonraki Etiket'i almak i�in �imdi $p->gettag(0) veya $p->getbytoken(0) �a��rabiliriz. getbytoken
Etiket'ler aras�ndaki d�z yaz�lar� verirken gettag sadece Etiket'leri d�nd�r�r (< ve > aras�ndaki i�) ve onun ne oldu�unu size
s�yler (Etiket veya d�z yaz�). Bu fonksiyonla html dosyalar�n� i�letmek olduk�a basittir. Aslen geni� bir sanal y�reyi y�netmektir.
T�m yaz�m �ekline man page of HTML::TagReader adresinden
eri�ilebilir.
�imdi ger�ek bir �rnek program. D�k�man numaras�na g�re d�k�man ba�l��� basmakta:
#!/usr/bin/perl -w
use strict;
use HTML::TagReader;
#
die "USAGE: htmltitle file.html [file2.html...]\n" unless($ARGV[0]);
my $printnow=0;
my ($tagOrText,$tagtype,$linenumber,$column);
#
for my $file (@ARGV){
my $p=new HTML::TagReader "$file";
# read the file with getbytoken:
while(($tagOrText,$tagtype,$linenumber,$column) = $p->getbytoken(0)){
if ($tagtype eq "title"){
$printnow=1;
print "${file}:${linenumber}:${column}: ";
next;
}
next unless($printnow);
if ($tagtype eq "/title" || $tagtype eq "/head" ){
$printnow=0;
print "\n";
next;
}
$tagOrText=~s/\s+/ /; #kill newline, double space and tabs
print $tagOrText;
}
}
# vim: set sw=4 ts=4 si et:
Nas�l �al���yor?
<title> yada <Title> yada <TITLE> ($tagtype olarak "title"a e�it olarak d�nd�ler)
buldu�umuz zaman $p->getbytoken(0) ile html dosyas�n� okuyoruz. Ard�ndan basmaya ba�lamak i�in bir bayrak ($printnow)
at�yoruz ve ne zaman ki </title> bulduk, basmay� durduyoruz.
Program� �u �ekilde kullan�yoruz:
htmltitle file.html somedir/index.html
file.html:4: the cool perl page
somedir/index.html:9: joe's homepage
Elbette tr_tagcontentgrep 'i a�a��dan HTML::TagReader ile uygulamak m�mk�n. Yazmak i�in biraz daha
k�sa ve basit olarak:
#!/usr/bin/perl -w
use HTML::TagReader;
die "USAGE: taggrep.pl searchexpr file.html\n" unless ($ARGV[1]);
my $expression = shift;
my @tag;
for my $file (@ARGV){
my $p=new HTML::TagReader "$file";
while(@tag = $p->gettag(0)){
# $tag[0] is the tag (e.g <a href=...>)
# $tag[1]=linenumber $tag[2]=column
if ($tag[0]=~/$expression/io){
print "$file:$tag[1]:$tag[2]: $tag[0]\n";
}
}
}
Betik k�sad�r ve fazla hata kald�rmaz ancak �te yandan tamamen i�levseldir. "gif" de�i�kenini
yakalamak i�in yaz�lmas� gereken:
taggrep.pl gif file.html
file.html:135:15: <img src="images/2doc.gif" width=34
height=22>
file.html:140:1: <img src="images/tst.gif" height="164"
width="173">
Bir �rnek daha? ��te t�m <font...> ve </font> Etiket'lerini html
kodundan ay�klayacak bir program. Bu font
Etiket'leri baz� zay�f grafik tabanl� taray�c�lar taraf�ndan yo�un olarak kullan�lmakta
ve farkl� taray�c�lar ve ekran
boyutlar� ile g�r�nt�lenmeye �al���ld�klar�nda sorun yaratmaktad�rlar.
Bu basit s�r�m t�m font Etiket'leri ay�klamakta.
Sadece font y�z� ve boyutunu ayarlamak ve rengi
de�i�meden b�rakmak i�in kullanabilirsiniz.
#!/usr/bin/perl -w
use strict;
use HTML::TagReader;
# strip all font tags from html code but leave the rest of the
# code un-changed.
die "USAGE: delfont file.html > newfile.html\n" unless ($ARGV[0]);
my $file = $ARGV[0];
my ($tagOrText,$tagtype,$linenumber,$column);
#
my $p=new HTML::TagReader "$file";
# read the file with getbytoken:
while(($tagOrText,$tagtype,$linenumber,$column) = $p->getbytoken(0)){
if ($tagtype eq "font" || $tagtype eq "/font"){
print STDERR "${file}:${linenumber}:${column}: deleting $tagtype\n";
next;
}
print $tagOrText;
}
# vim: set sw=4 ts=4 si et:
G�rd���n�z gibi sadece birka� sat�rla kolayca kullan��l� programlar yaz�labiliyor.
HTML::TagReader (�rneklere bkz) paket kaynak kodu baz� HTML::TagReader uygulamalar�n� zaten i�ermektedir:
- tr_blck -- HTML sayfalar�ndaki k�r�k linkleri tarar
- tr_llnk -- HTML dosyalar� i�indeki linkleri listeler
- tr_xlnk -- dizinlerdeki linklerle index dosyalar� geni�letir
- tr_mvlnk -- perl komutlar� ile HTML dosyalar�ndaki etiketleri d�zenler.
- tr_staticssi -- SSI direktiflerini geni�letir #include sanal ve
#exec cmd ve statik bir html sayfas� �retir.
- tr_imgaddsize -- <img 'ye width=... ve height=.. ilave eder.
src=...>
tr_xlnk ve tr_staticssi bir sanal y�reden CDRom yapmak istedi�inizde �ok kullan��l�d�r. Bir sanal y�re sunucusu
http://www.linuxfocus.org yazd���n�zda (index.html olmaks�z�n) size http://www.linuxfocus.org/index.html'yi verecektir.
E�er ki t�m dosyalar� ve dizinleri CD ye yazm�� ve taray�c�n�z arac�l��� ile do�rudan CD ye eri�iyorsan�z (dosya:/mnt/cdrom)
bu durumda index.html yerine dizin listesi g�receksiniz ve bu i�lem bir dizini g�steren her linki se�ti�inizde tekrarlanacakt�r.
�lk LinuxFocusCD yi yapan �irket bu hatay� yapt� ve CD yi kullan�m a��s�nda bir felaket oldu. �imdi veriyi tr_xlnk ile al�yorlar
ve CD ler �al���yor.
Eminim ki HTML::TagReader '� kullan��l� bulacaks�n�z. Mutlu programlamalar!
References
Bu yaz� i�in g�r�� bildiriminde bulunabilirsiniz
Her yaz� kendi g�r�� bildirim sayfas�na sahiptir. Bu sayfaya yorumlar�n�z� yazabilir ve di�er okuyucular�n yorumlar�na bakabilirsiniz.
<--, Bu say�n�n ana sayfas�na gider
2003-10-10, generated by lfparser version 2.43