Manchmal schreibe ich Briefe. So richtig altmodisch, mit dem Fueller auf Papier. Aber ich bin trotzdem ein praktisch denkenden Mensch. Deshalb mag ich Umschlaege mit Adressfenster. Und weil ich es nicht blind schaffe, die Adresse auf dem Papier intuitiv an die richtige Stelle zu schreiben, habe ich mir ein kleines Perlskript geschrieben, dass zumindest diese Aufgabe uebernimmt.

Ich lege mich also mal wieder mit Perl an. Aber davor ist die Idee: Eine Vorlage in Postscript, in der Auslassungen sind und ein kleines Skript, dass an den richtigen Stellen Daten einfuegt. Hoechst simpel, so an sich.
Natuerlich kann man das Problem in einer noch archaischerien Sprache loesen... z.B. in M4 (http://de.wikipedia.org/wiki/M4_(Programmiersprache)) -- aber Perl ist zumindest einigermassen eine Hochsprache.
Dazu kommt ein wenig mehr Komfort. Das, was das Programm macht ist natuerlich denkbar simpel: Es durchsucht die Poscript-Datei (die ja gluecklicherweise auch eine Textdatei -- streng genommen ein Programm) ist, nach zu ersetzenden Symbolen und Kommentaren, die beschreiben, was das Symbol tut -- damit man es den Nutzer fragen kann und er vor einem Prompt steht, etwas Aussagekraft hat.

Also erstmal ein kleines Perlskript (das geht sicher eleganter):

#! /usr/local/bin/perl

use strict;

if ($ARGV[0] eq "") {
        print "Call:\n\t$0 templatefile\n";
        exit 1;
}

my @farr;

print "reading template...";
open(f, '<', $ARGV[0]);
@farr = ;
close(f);
print "done.\n";

my $inside;
my @descrs;

$inside = 0;
for (@farr) {
        chomp($_);
        if ($inside == 1) {
                if ($_ =~ m|^%--/vars--$|) {
                        last;
                }
                # print $_ . "\n";
                if (m|^%(.*)$|) {
                        $_ =~ s/^%(.*)$/$1/;
                        push(@descrs, $_);
                }
        }
        if ($_ =~ m/^%--vars--$/) {
                $inside = 1;
        }
}

my @answers;
my $ans;
for (@descrs) {
        print $_ . ":\n";
        $ans = ;
        chomp($ans);
        push(@answers, $ans);
}

open (in, '<', $ARGV[0]);
open (out, '>', "out.ps");
my $i;
$i = 0;
while () {
        if (m/.*%-TEMPLATE-%.*/) {
                $i++;
        }
        $_ =~ s/%-TEMPLATE-%/$answers[$i - 1]/;
        print out $_;
}

close(out);
close(in);

Nachdem das Skript zur Ersetzung der Platzhalter fertig ist, fehlt jetzt nur noch was zum Bearbeiten. Postscript ist an sich eine stackbasierte Programmiersprache. Soll heissen: Man programmiert eher, als dass man die Seite beschreibt. Auch in Postscript bin ich kein Grossmeister, es ist eher so, dass ich meine ersten Schritte hier mache. Entsprechend wirkt das Ergebnis wahrscheinlich auch eher tollpatschig denn elegant, aber es funktioniert:
%!PS-Adobe-2.0
/absender {(Meinname, MeineStrasse n, PLZOrt) show} def
%--vars--
%Erste Namenszeile
/b_name1 {(%-TEMPLATE-%) show} def
%Zweite Namenszeile
/b_name2 {(%-TEMPLATE-%) show} def
%Strasse/Anschrift
/b_str {(%-TEMPLATE-%) show} def
%Postleitzahl und Ort
/b_ort {(%-TEMPLATE-%) show} def
%--/vars--

/ISOvec [
  8#304/Adieresis% Umlaut A196
  8#326/Odieresis% Umlaut O214
  8#334/Udieresis% Umlaut U220
  8#337/germandbls% scharf-s223
  8#344 /adieresis% Umlaut a228
  8#366 /odieresis% Umlaut o246
  8#374 /udieresis% Umlaut u252
  ] def

/ReEncode {% font newfont vector ReEncode -
  3 2 roll findfont% newfont vector font auf Stack
    dup length dict%   leere Kopie auf Stack
    begin%   auf DStack
      {%   fuer alle key/value in Courier
        1 index /FID eq%     if key == /FID
          { pop pop }%       ignorieren
          { 1 index /Encoding eq%     else if key == /Encoding
            { dup length array copy def%kopieren
      dup aload%       vector Elemente auf Stack
      length 2 idiv%fuer jedes Paar
      { currentdict /Encoding get %  Encoding auf Stack
3 1 roll put%  Encoding[index] name
      } repeat
            }
            { def } ifelse%     else key/value kopieren
          } ifelse
      } forall
      pop%   vector entfernen
      currentdict%   neuer Font auf Stack
    end
    definefont%   neuer Font heisst newfont
    pop%   newfont entfernen
} bind def

90 rotate
440 -980 translate


0.9 1 scale

47 800 moveto

/Courier /ISOfont ISOvec ReEncode
/ISOfont findfont 8 scalefont setfont% einschalten


absender
1 1 scale

0.1 setlinewidth
40 795 moveto
320 795 lineto
stroke

/Courier /ISOfont ISOvec ReEncode
/ISOfont findfont 10 scalefont setfont

45 780 moveto
b_name1

45 766 moveto
b_name2

45 752 moveto
b_str

/CourierBold /ISOfont ISOvec ReEncode
/ISOfont findfont 13 scalefont setfont
45 730 moveto
b_ort



-485 980 translate
-90 rotate

180 rotate

-540 -118 translate

0.9 1 scale


/Courier /ISOfont ISOvec ReEncode
/ISOfont findfont 8 scalefont setfont% einschalten
10 0 moveto
absender

1 1 scale

0.1 setlinewidth
0 -5 moveto
280 -5 lineto
stroke

/Courier /ISOfont ISOvec ReEncode
/ISOfont findfont 10 scalefont setfont

8 -20 moveto
b_name1

8 -35 moveto
b_name2

8 -50 moveto
b_str


/CourierBold /ISOfont ISOvec ReEncode
/ISOfont findfont 13 scalefont setfont

8 -72 moveto
b_ort


showpage

Diese Postscriptdatei beginnt mit ein paar Definitionen -- und in diese wird spaeter einfach eingesetzt. In der Ursprungsfassung sollte die Datei von Hand editiert werden, aber fuer sowas sind kleine Skripte eigentlich ganz hilfreich.
Danach wird versucht, die deutschen Umlaute einzubinden (der Teil ist nicht von mir, sondern aus deinem PS-Buch) und die Fonts daraufhin zu trimmen und schliesslich wird das Blatt gewendet, das Koordinatensystem verschoben und schliesslich die Texte geschrieben. Im Anschluss wird das Blatt nochmal wild umhergedreht und ein neues Koordinatensystem angelegt -- und die zweite Adressaufschrift angelegt. Nun hat man ein Blatt mit einem Addressfeld fuer beide populaeren Faltungen von A4-Briefen :)
Fuer diejenigen, die gerade keinen PS-Viewer zur Hand haben: Das Ergebnis sieht dann wie folgt aus: down/addr-out.pdf.

Was in dem Skript noch fehlt ist nun ein Befehl, der die Seite direkt zum Drucker schickt.

Stichworte:


Impressum