Browsing Category "Programming"
14 Nov
2007

Da perl ich mir doch mal eine Tagcloud!

Für einen Kundenauftrag durfte ich gestern (und heute) eine nette Tagcloud (TC) mit Perl erstellen. Das war in übrigen meine erste TC überhaupt, irgendwie bin ich noch nicht in die Verlegenheit gekommen, sowas schon mal erstellen zu müssen. Perl, das ist wie PHP 4, nur halt anders, die Syntax widerstrebte sich meiner ein wenig, aber ich habe mich damit arrangiert. Auf meinem Notebook hatte ich nebenher selfhtml mit dem Perl-Teil offen, ein wenig Unterstützung braucht man schon, wenn es das erste Mal ist, zumal ich das da ziemlich gut gegliedert finde. Was übrigens das Skript, in den die TC rein sollte, nicht war. Der Autor wusste glaube ich nicht, dass man Code zur Verbesserung der Lesbarkeit auch einrücken kann, es war jedenfalls alles fein linksbündig. Und nach Kommentaren brauchst du gar nicht erst zu fragen, braucht ja keiner...

Nachdem ich ein wenig in der Datei rum gelesen hatte, die am wahrscheinlichsten für die Ausgabe der Seite mit der zukünftigen TC zuständig war, musste ich erstmal finden, wie ich meinen(bis dato noch gar nicht) erstellten Code an die Aussenwelt gebe. Wie genau der Kollege das Handling seiner Templates macht, interessierte mich nicht, dazu war zu wenig Zeit. Jedenfalls fand ich heraus, dass mein Marker einfach in einem assoziativen Array, in Perl im übrigen "Hash" genannt, am besten aufgehoben ist und dann auch im Frontend ausgegeben wird. Schnell ein Skelet einer Subroutine geschrieben und los konnte es gehen. Wie man die Zieldatei, in der die Werte für die TC standen (im übrigen basiert das ganze Skript auf Dateien, eine Datenbank sucht man vergebens), ausliest hab ich mir schnell aus bestehenden Code kopiert. Das fand ich super, denn man konnte den Inhalt zeilenweise direkt an ein Array übergeben:

open(READ, $file) or die "Kann Datei nicht lesen!";
my @searched=;
close(READ);

Damit war die Datengrundlage gegeben, ich brauchte nur noch die Suchwörter aus den Zeilen herausschneiden, das war alles fast 1:1 wie in PHP. Dann jeden Begriff einmal in einen Hash getan mit dem Begriff selber als Key um im Value die Anzahl der Vorkommen zählen zu können. Jetzt musste ich nur den/das Hash noch sortieren, da musste ich mal Mr. Google fragen, denn da half mir selfhtml irgendwie nicht so richtig weiter, denn ich wollte ja nicht nach Keys sortieren, sondern nach den Values des Hashes. Da fand ich folgendes Snippet, was den Spass sortierte und mir die Keys als Array zurück gab:

@keys = sort {$tags{$a} <=> $tags{$b}} keys %tags;

Ich hatte also meine Tags in dem Array und dazu auch gleich noch sortiert. Da musste ich jetzt nur noch drüber laufen (foreach $key(@keys) { ... }) und mein HTML ausgeben. Zuvor natürlich die Schriftgröße entsprechend der Wertigkeit anpassen, einfach anhand des höchsten Vorkommens eines Tags und einer Vorgabe der Maximalschriftart (z.B. 250%) ausrechnen, wie viel Prozent Schriftart ein Vorkommen des Tags hat und dann auf 100% draufschlagen. (Das hab ich jetzt irgendwie wirr ausgedrückt). Letztendlich wäre es das schon fast gewesen, wenn da nicht irgendwelche Zeichen aus der Windows-1252 Kodierung in den Tags auftreten würden. Die musste ich irgendwie umwandeln, am besten in HTML-Entities. Was ich sehr schön an Perl finde: es gibt einen extra Operator für reguläre Ausdrücke. Mit

$tag =~ s/findmich/nimmmichanstatt/g;

kann man also einfach den Suchstring "findmich" mit "nimmmichanstatt" ersetzen. Das hab ich dann für alle Umlaute die in 1252 da standen gemacht (und auch für die, die man nicht sah). Dann hab ich noch in etwa (durch Testen) die Maximalanzahl der Zeichen, die in den DIV der TC passen, ermittelt, und mein Skript noch angepasst, so dass die Zeichen, die ein Tag verbraucht, beim Durchlaufen immer abgezogen werden und der Durchlauf durch das Tag-Array abgebrochen wird, wenn alle Zeichen verbraten sind (Danke an Thomas für den Tipp).

Fertig ist die Tagcloud mit Perl! Und wieder was gelernt...