Database Publishing mit Perl

Hier werde ich zeigen, wie wir datenbankgestützt Layouts mit QuarkXPress™ erzeugen können. Als Datenbank muß nicht unbedingt eine ausgewachsene SQL Datenbank dienen, die Datenbankfunktionalität z.B. von Claris Works reicht für den Anfang aus. Wir brauchen auch keine kostspieligen XTensions. Die Schritte von den Daten bis zum Layout sehen folgendermassen aus:

Skizze Poor Mans Database Publishing

Hauptthema ist hier natürlich das Perl Skript. Als Beispiel werden wir uns einen Veranstaltungskalender vornehmen. Wer noch nicht mit der Programmiersprache Perl umgehen kann, sollte erst mal meine Perl Zone inklusive Primer für MacPerl besuchen.

Die Datenbank

Unsere Datenbank kann z.B. in FoxPro, Claris Works oder Filemaker angelegt werden. Wir definieren folgende Felder:

Feld Bemerkung Beispiel

Datum

-

07.03.1998

Titel

-

Arsen und Spitzenhäubchen

Bemerkungen

darf leer sein

Premiere

Ort

-

Deutsches Schauspielhaus

Zeit

-

19.30

Sparte

Auswahlliste

Theater

Wir können uns jetzt eine nette Eingabemaske basteln und dann die Daten aller Veranstaltungen eingeben. Später können wir die Eingabe auch Internetgestützt mit Hilfe eines Webbrowser und eines Cgi-Skriptes realisieren.
Wir sortieren die Datensätze nach Datum, Sparte, Titel. Wir exportieren die Datensätze:

Die Ascii Datei

Die einzelnen Felder sollen durch Tabs getrennt sein, die Datensätze durch ein Neue-Zeile Zeichen. Unser obiger Datensatz sieht exportiert folgendermaßen aus:

07.03.1998	Arsen und Spitzenhäubchen	Premiere	Deutsches Schauspielhaus	19.30	Theater
 

Eine etwas größere Beispieldatei kann man sich hier anschauen und runterladen. (Vorsicht: je nach Browser kann es passieren, daß beim downloaden oder beim Copy&Paste die Tabs durch Leerzeichen ersetzt werden.)

Ascii Beispieldatei veranstaltungen.dat

Das Perl Skript

Innerhalb unseres Perl Skriptes müssen wir zunächst die Datei bestimmen, die wir verarbeiten wollen. Wir sehen dafür zwei Möglichkeiten vor: Zum einen können wir unser Skript als Droplet abspeichern. Wenn wir dann eine oder auch mehrere Dateien auf das Droplet ziehen, so startet das Skript und die Namen der Dateien stehen in der speziellen Variablen @ARGV. Die Variable $#ARGV enthält den Index des letzen Elementes der Liste @ARGV , wobei von 0 angefangen wird zu zählen. Gibt es also keine Eingabe, so ist $#ARGV nicht 0 sondern -1.

Wir wollen das Skript aber auch ganz normal starten können und die Eingabedatei dann mit Hilfe eines Datei-Auswahl-Dialoges bestimmen können. Der Skriptteil zu Bestimmung der Eingabedatei sieht damit folgendermaßen aus:

### Eingabedateien ermitteln ####
 
if($#ARGV  < 0)                     # Falls keine Eingabe
{                                   # Frage Benutzer nach Eingabedatei
 
	$inputfilename = &StandardFile::GetFile('TEXT');
	if(defined $inputfilename) {
		unshift(@ARGV, $inputfilename); # fuege Datei zur Liste hinzu
	} else {
		die "keine Eingabedatei";
	}
}
 
foreach $filename (@ARGV) {                   # für jede Datei:
	&processFile($filename);
}                                             #end foreach
 

Diesen Teil können wir für viele Skripte benutzen. Doch wie schreiben wir jetzt die Funktion processFile ? Sie muß auf die Eingabedatei zugreifen, sie zeilenweise lesen, umformen und das Ergebnis in eine Ausgabedatei schreiben. Das Gerüst für diese Funktion sieht folgendermaßen aus:

sub processFile{
	
    my($filename) = @_;                       # hole Funktionsparameter
	
    open( INPUT, $filename)                   # öffne Eingabedatei
	  or die "kann $filename nicht oeffnen";
    open( OUTPUT, ">$filename.xtags")         # erzeuge und öffne Ausgabedatei
	  or die "kann $filename.xtags nicht schreiben";
    
    print "ich konvertiere $filename\n";       # Statusmeldung
    
   # jetzt koennen wir mit der eigentlichen Konvertierung anfangen
    print OUTPUT $XTagsStart;                  # Anfangsheader
       
    while(<INPUT>)                             # für jede Eingabezeile
    {
       # verarbeite Zeile und gebe sie aus                                     
       # entferne letztes Zeichen
    }                                         # end while
         
    close( OUTPUT );
    close( INPUT );
    MacPerl::SetFileInfo("ALFA","TEXT","$filename.xtags");# set Filetype to Alpha Editor
}
 
Wir näheren uns der eigentlichen Arbeit: das Konvertieren in XPress Marken. Jede XPress Marken Datei sollte in der ersten Zeile einen Versionscode und den verwendeten Zeichensatz enthalten, für QuarkXPress 3.32 auf den Macintosh lautet Sie:
<v1.70><e0>

Danach kann man Stilvorlagen definieren. Es werden drei Stile benutzt: Einen für die Spartentitel (Musik, Kino, etc.), einen für den Titel der Veranstaltung und einen für den Text der Veranstaltung.

$XTagsStart = 
'<v1.70><e0>' . "\n"
. '@V-Sparte=[S"Normal"]<*C*ra(11.373,0,"Schwarz",100,0,0,-2.6279)$Pc"Weiß">'
. ' @V-Text=[S"Normal"]<*J*p(8,0,0,0,0,0,$)$Pz9>'
. ' @V-Titel=[S"Normal"]<*L$PBz9>' . "\n";
 

In einer Produktionsumgebung wird man meistens Musterseiten anlegen und die benötigten Stilvorlagen schon in diesen definieren. Falls Sie so vorgehen, sollten Sie den obigen Code durch folgenden ersetzen:

$XTagsStart = '<v1.70><e0>' . "\n";

Jetzt analysieren wir die Eingabedatei. Jede Zeile wird in Ihre Bestandteile aufgespaltet:

($vdate, $vtitle, $vremark, $vplace, $vtime, $vkat)
	     = split /\t/;
Die Variable $vkat enthält jetzt unsere Veranstaltungskategorie oder Sparte. Wir wollen jeweils eine Titel erzeugen, wenn sich die Sparte ändert:

if($oldKat ne $vkat) 			   # falls neue Kategorie
{										
    $oldKat = $vkat;                       # merke die Kategorie
                                           # und schreibe eine Zwischenüberschrift
     print OUTPUT '@V-Sparte:<$>' ."$vkat\n";
}
Danach geben wir die restliche Information über eine Veranstaltung aus. Zu beachten ist noch, daß wir kein überflüssiges Komma erzeugen, falls eine Veranstaltung keine besonderen Bemerkungen enthält:
print OUTPUT '@V-Titel:<$>'. "$vtitle\n";
print OUTPUT '@V-Text:<$>';
# verhindere das bei fehlender $vremark ein Komma übrigbleibt
print OUTPUT "$vremark, " unless $vremark eq ""; 
print OUTPUT "$vplace, $vtime\n";
 
Spätestens seit dem Auftauchen von Emailaddressen müssen wir bei XPressmarken noch etwas beachten: Falls ein "@" oder ein "<" oder "\" im Eingabetext auftaucht, müssen wir es speziell konvertieren, sonst kann es böse Überraschungen geben. Hierfür benutzen wir eine Funktion mit Namen specialXTagsChars. Sie sieht etwas komplizierter aus als man annehmen möchte, weil sie mit einigen Tücken zurechtkommen muß, an die man zuerst nicht denkt.
# Diese Funktion konvertiert die kritischen Sonderzeichen
# in Ihre XTags Interpretationen:
# <  -> <\<>
# \  -> <\\>
# @  -> <\@>
sub specialXTagsChars {
    $_[0] =~s|<|<\\<>|;
    $_[0] =~s|[~<]\\|<\\\\<>|;
    $_[0] =~s|\@|<\@>|;
}

Jetzt müssen wir aus diesen Bausteinen noch das ganze Skript zusammensetzen:

Anzeige des fertigen Skriptes.

Das Ergebnis

Screenshot der fertigen Veranstaltungskalendars

Ihr Kommentar


home - contact - dev-zone