#############################################################################
##
#A  genVprpr             CHEVIE library                         Frank L"ubeck
##
#Y  Copyright 1992--1993,  Lehrstuhl D f"ur Mathematik,    RWTH Aachen,   and
#Y                         IWR   der   Universit"at    Heidelberg,   Germany.
##
#############################################################
##
##  Programme zum Anzeigen von Charaktertafeln im TeX-Format
##
#H 1994/08/05  FL
#H ClassParamString and CharParamString changed to print the parameters
#H correctly.
#H
#H PREVIEWNAME can be set to `` to avoid the automatic call of a 
#H previewer.

# Ist die Variable PREVIEWNAME gesetzt, so wird ihr Inhalt
# zum automatischen Aufruf der erstellten dvi-Datei benutzt.

# Einige allgemeine Parameter:
Buchstabenbreite:=1.82:
FaktorexBr:=0.81:
Seitenbreite:=150:
Allgbreite:=10:
SpaltenAbst:=5:
MaxSpBr:=Seitenbreite-Allgbreite-SpaltenAbst:
ParIndent:=10:
MinSpBr:=7:
ArrayStretch:=1.4:
MaxZeilen:=32:

# Hier sind Zeichenbreiten in mm eingetragen. Dies wird
# fuer die Berechnung von Umbruechen benutzt.
# Default-Werte sind `Buchstabenbreite` und fuer
# Exponenten `Buchstabenbreite*FaktorexBr`.
ZBr:=table():
ZBr[q]:=1.71:
ZBr["+"]:=4.27:
ZBr[`()`]:=2.69:
ZBr[EW2]:=8.00:
ZBr[EW3]:=1.63:
ZBr[EW4]:=1.63:
for iiii to 4 do
  ZBr[GEWZ||iiii]:=1.78;
  ZBr[GEW2Z||iiii]:=1.81;
  ZBr[GEWY||iiii]:=1.70;
  ZBr[GEWZ1Y||iiii]:=1.87;
od:
for iiii to 9 do
  ZBr[phi||iiii]:=3.55;
od:
for iiii from 10 to 30 do
  ZBr[phi||iiii]:=5.00;
od:


EZBr:=table():
EZBr[aA]:=1.52:
EZBr[bB]:=1.25:
EZBr[iI]:=1.01:
EZBr[jJ]:=1.30:
EZBr[kK]:=1.56:
EZBr[lL]:=0.89:
EZBr[mM]:=2.47:
EZBr[nN]:=1.72:
EZBr[q]:=1.36:
EZBr[`()`]:=2.21:
EZBr["+"]:=2.15:
for iiii to 4 do
  EZBr[iI||iiii]:=2.51;
  EZBr[jJ||iiii]:=2.70;
  EZBr[kK||iiii]:=3.08;
  EZBr[lL||iiii]:=2.40;
od:

# Definition von TeX-strings fuer Parameternamen:
TeXstringtable:=table():

for iiii to 9 do
  TeXstringtable[iI||iiii]:=`i_`||iiii;
  TeXstringtable[jJ||iiii]:=`j_`||iiii;
  TeXstringtable[kK||iiii]:=`k_`||iiii;
  TeXstringtable[lL||iiii]:=`l_`||iiii;
od:
for iiii to 9 do
  TeXstringtable[phi||iiii]:=`\\phi_`||iiii;
od:
for iiii from 10 to 30 do
  TeXstringtable[phi||iiii]:=`\\phi_{`||iiii||`}`;
od:


TeXstringtable[aA]:=` a`:
TeXstringtable[bB]:=` b`:
TeXstringtable[cC]:=` c`:
TeXstringtable[dD]:=` d`:
TeXstringtable[eE]:=` e`:
TeXstringtable[fF]:=` f`:
TeXstringtable[gG]:=` g`:
TeXstringtable[hH]:=` h`:
TeXstringtable[iI]:=` i`:
TeXstringtable[jJ]:=` j`:
TeXstringtable[kK]:=` k`:
TeXstringtable[lL]:=` l`:
TeXstringtable[mM]:=` m`:
TeXstringtable[nN]:=` n`:
TeXstringtable[oO]:=` o`:
TeXstringtable[pP]:=` p`:
TeXstringtable[rR]:=` r`:
TeXstringtable[sS]:=` s`:
TeXstringtable[tT]:=` t`:
TeXstringtable[uU]:=` u`:
TeXstringtable[vV]:=` v`:
TeXstringtable[wW]:=` w`:
TeXstringtable[xX]:=` x`:
TeXstringtable[yY]:=` y`:
TeXstringtable[zZ]:=` z`:
TeXstringtable[DELTA]:=`\\delta`:

# Einlesen der Namen fuer generische Einheitswurzeln
# (aus der Liste konvertGEWlist)
for iiii to nops(konvertGEWlist) do
  TeXstringtable[konvertGEWlist[iiii][1]]:=konvertGEWlist[iiii][3];
od:
iiii:='iiii':


# TeX-strings fuer haeufig auftretende Polynome in q:

PolysqListe:=[
[q, `q`],
[q-1, `q-1`], [q+1, `q+1`], [q^2+q+1, `q^2+q+1`],
[q^2-1, `q^2-1`], [q^2+1, `q^2+1`], [q^2-q+1, `q^2-q+1`], 
 [q^2-sqrt(3)*q+1, `q^2-\\sqrt{3}q+1`], 
 [q^2+sqrt(3)*q+1, `q^2+\\sqrt{3}q+1`], 
[q^3-1, `q^3-1`],[q^3+1, `q^3+1`],
[q^4+q^3+q^2+q+1, `q^4+q^3+q^2+q+1`], 
[q^4-1, `q^4-1`], [q^4+1, `q^4+1`], 
[q^4-q^3+q^2-q+1, `q^4-q^3+q^2-q+1`], 
[q^4-q^2+1, `q^4-q^2+1`], 
[q^6-1, `q^6-1`], [q^6+1, `q^6+1`] 
]:

# Umwandlung von Polynomen in q in Liste von strings
polyqlat:=proc(p)
  local c, pp, f, ef, l, ll, s, sl, erg, i, d, ka, kz, sh, dpp;
  option remember;
  c:=lcoeff(expand(p), q);
  pp:=normal(p/c);
  dpp:=denom(pp);
  if dpp<>1 then 
    c:=normal(c/dpp);
    pp:=normal(pp*dpp);
  fi;
  c:=normal(c*content(pp, q));
  pp:=normal(pp/content(pp, q));
  pp:=normal(p/c);
  if type(pp, monomial) then
    c:=c*lcoeff(pp, q);
    pp:=normal(p/c);
  fi;
  if abs(c)<>1 then
    erg:=mylat(c);
  elif c=-1 then
    erg:=[`-`];
  else
    erg:=[];
  fi;
  if pp=q then
    RETURN([op(erg),`q`]);
  elif type(pp, monomial) then
### W5ARNING: degree(0,x) now returns -infinity
### W5ARNING: semantics of type `string` have changed
    if degree(pp)=-infinity then
      print("this is probably handled incorrectly line 177 genVprpr");
    fi;
		ef:=convert(degree(pp), symbol);
    RETURN([op(erg),`q^{`,ef,`}`]);
  fi;
  if type(pp, `+`) or type(pp, `^`) then
    l:=[pp];
  else 
    l:=convert(pp, list);
  fi;
  s:=[];sl:=[];
  for i to nops(l) do
    if type(l[i], `+`) then
      s:=[op(s), l[i]]; 
      sl:=[op(sl), 1];
    elif l[i]=q then 
      s:=[op(s), q]; 
      sl:=[op(sl), 1];
    else
      s:=[op(s), op(1,l[i])]; 
      sl:=[op(sl), op(2,l[i])];
    fi;
  od;
  for f in PolysqListe do
    for i to nops(s) do
      if s[i]=f[1] then
        l:=subsop(i=1, l);
        if f[1]=q then 
          ka:=``; kz:=``;
        else
          ka:=`(`; kz:=`)`;
        fi;
        erg:=[op(erg),ka,f[2],kz];
        if sl[i]>1 then
### W5ARNING: semantics of type `string` have changed
          erg:=[op(erg),`^{`,convert(sl[i], symbol),`}`];
        fi;
      fi;
    od;
  od;
  pp:=convert(l, `*`);
  if nops(erg)=3 and erg[1]=`(` and erg[3]=`)` and pp=1 then
    erg:=[op(2,erg)];
  fi; 
  # Restterme
  if pp<>1 then
    l:=[];
    if type(pp, `+`) then
      l:=[pp];
      if erg=[] then 
        ka:=``; kz:=``;
      else
        ka:=`(`; kz:=`)`;
      fi;
    elif type(pp,`*`) then
      l:=convert(pp, list); 
      ka:=`(`; kz:=`)`;
    else 
      l:=[pp];
      ka:=`(`; kz:=`)`;
    fi;
    s:=[];sl:=[];
    for i to nops(l) do
      if type(l[i], `+`) then
        s:=[op(s), l[i]]; 
        sl:=[op(sl), 1];
      elif type(l[i], `^`) then
        s:=[op(s), op(1,l[i])]; 
        sl:=[op(sl), op(2,l[i])];
      else
        s:=[op(s), l[i]];
        sl:=[op(sl), 1];
      fi;
    od;
    for i to nops(l) do
      f:=s[i];
      erg:=[op(erg),ka];
      ll:=lcoeff(f);
### W5ARNING: degree(0,x) now returns -infinity
      if degree(f)=-infinity then
        print("oergs: genVprpr 256");
      fi; 
			d:=degree(f);
      f:=f-ll*q^d;
      if ll=1 then
        ll:=``;
      elif ll=-1 then
        ll:=`-`;
      else
        ll:=op(mylat(ll));
      fi;
      if d=1 then 
        d:=``;
      else
### W5ARNING: semantics of type `string` have changed
        d:=convert(d, symbol);
        d:=`^{`||d||`}`;
      fi;
      erg:=[op(erg),ll,`q`||d];
      while f<>0 do
        ll:=lcoeff(f);
### W5ARNING: degree(0,x) now returns -infinity
        if degree(f)=-infinity then
          print("oergs: genVprpr 279");
        fi; 
        d:=degree(f);
        f:=f-ll*q^d;
        if ll=1 then 
          if d<>0 then
            ll:="+";
          else
            ll:=`+1`;
          fi;
        elif ll=-1 then
          if d<>0 then
            ll:=`-`;
          else
            ll:=`-1`;
          fi;
        else
          ll:=mylat(ll);
          sh:=substring(ll[1],1..1);
          if not member(sh, {`+`,`-`}) then
            ll:=["+",op(ll)];
          fi;
        fi;
        if d>0 then
          if d=1 then 
            d:=``;
          else
### W5ARNING: semantics of type `string` have changed
            d:=convert(d, symbol);
            d:=`^{`||d||`}`;
          fi;
          erg:=[op(erg),op(ll),`q`||d];
        else
          erg:=[op(erg),op(ll)];
        fi;
      od;
      erg:=[op(erg),kz];
      if sl[i]>1 then
### W5ARNING: semantics of type `string` have changed
        erg:=[op(erg),`^{`,convert(sl[i], symbol),`}`];
      fi;
    od;
  fi;
  erg;
end:



# Ersatz fuer Maples `latex`-Prozedur:
# `mylat` erzeugt Liste mit Stuecken von TeX-strings.
mylat:=proc(x)
  local erg, a, b, c, i, l, la, erg2;
  option remember;
### W5ARNING: semantics of type `string` have changed
  if type(x, symbol) then
    if assigned(TeXstringtable[x]) then
      erg:=[TeXstringtable[x]];
    else
      erg:=[x];
    fi;
  elif type(x, rational) then
    if type(x, integer) then
### W5ARNING: semantics of type `string` have changed
      erg:=[convert(x, symbol)];
    else
      if x<0 then
        a:=`-`;
      else
        a:=``;
      fi;
### W5ARNING: semantics of type `string` have changed
      b:=convert(numer(abs(x)), symbol);
### W5ARNING: semantics of type `string` have changed
      c:=convert(denom(x), symbol);
      erg:=[``||a||`\\frac{`||b||`}{`||c||`}`];
    fi;
  elif type(x, polynom) and indets(x)={q} then
    erg:=polyqlat(x);
  elif type(x, `+`) then
    l:=convert(normal(x), list);  
    l:=map(mylat, l);
    erg:=l[1];
    for i from 2 to nops(l) do
      a:=substring(l[i][1], 1..1);
      b:=op(l[i]);
      if not member(a, {`+`,`-`}) then
        erg:=[op(erg),"+",b];
      else
        erg:=[op(erg),b];
      fi;
    od;
  elif type(x, `*`) then
    l:=convert(x, list);
    la:=map(whattype, l);
    i:=0;
    for a in la do
### W5ARNING: semantics of type `string` have changed
      if a<>symbol then
        i:=i+1;
      fi;
    od;
    if i<2 then
      a:=x;
      b:=sort([op(indets(a))]);
      b:=[q,op(b)];
      sort(a, b);
      l:=convert(a, list);
    fi;
    if l[1]=-1 then
      c:=`-`;
      l:=l[2..nops(l)]; #u34: was l:=[l[2..nops(l)]]
    else
      c:=``;
    fi;
    la:=map(a->type(a, `+`), l);
    l:=map(mylat, l);
    erg:=[c];
    for i  to nops(l) do
      if la[i]=true then
        erg:=[op(erg),`(`,op(l[i]),`)`];
      else
        erg:=[op(erg),op(l[i])];
      fi;
    od;
  elif type(x, sqrt) then
    erg:=[`\\sqrt{`,op(mylat(op(1, x))),`}`];
  elif type(x, `^`) then
    erg:=[op(mylat(op(1,x))),`^{`,op(mylat(op(2,x))),`}`];
    if type(op(1,x), `+`) then
      a:=erg[1];
      b:=``||`(`||a||`)`;
      #TEST erg:=subsop(1=b, erg);
      erg:=subsop(1=bAAAA, erg);
    fi;
  else
    printf("Don\'t know what to do with (in mylat):\n");
    print(a);
    printf("Type: %a\n",whattype(a));
    erg:=[];
  fi;
  erg2:=[]; a:=``;
  for i to nops(erg) do
    if length(a)+length(erg[i])>70 then
      erg2:=[op(erg2),a];
      a:=erg[i];
    else
      b:=erg[i];
      a:=``||a||b;
    fi;
  od;
  erg2:=[op(erg2),a];
  erg2;
end:
# Dies wird statt `latex` benutzt.
prmylat:=proc(x)
  local i, l;
  l:=mylat(x);
  for i to nops(l) do
    printf("%a\n",l[i]);
  od;
  NULL;
end:


# Prozeduren zur Abschaetzung der Druckbreite von Tafeleintraegen:


# Stellenanzahl eines Integer:
AnzDig:=proc(i) 
  local erg;
  if i=0 then RETURN(1); fi;
  erg:=trunc(evalf(log10(abs(i))))+1;
  erg;
end:
mysign:=proc(x)
  if  traperror(sign(x)) = lasterror  then
    RETURN(1);
  fi;
  sign(x);
end:
latbreit:=proc(x)
  local a, b, p, c, n;
  option remember;
  a:=x;
  if type(a,integer) then
    RETURN(AnzDig(a)*Buchstabenbreite);
### W5ARNING: semantics of type `string` have changed
  elif type(a,symbol) then
    if assigned(ZBr[a]) then
      RETURN(ZBr[a]);
    else
      RETURN(Buchstabenbreite);
    fi;
  elif type(a,`+`) then
    b:=convert(a,list);
    p:=nops(b);
    if mysign(b[1])=-1 then p:=p+1; fi;
    b:=map(latbreit,b);
    b:=convert(b,`+`);
    RETURN(b+p*ZBr["+"]);
  elif type(a,`*`) then
    b:=convert(a,list);
    p:=map(x->type(x,`+`), b);
    n:=0;
    for c in p do
      if c=true then n:=n+1; fi;
    od;
    b:=map(latbreit,b);
    b:=convert(b,`+`);
    RETURN(b+n*ZBr[`()`]);
  elif type(a,`^`) then
    RETURN(latbreit(op(1,a))+latbreitexp(op(2,a)));
  elif type(a,sqrt) then
    RETURN(Buchstabenbreite+latbreit(op(1,a)));
  elif type(a,fraction) then
    RETURN(max(latbreit(denom(a),numer(a)))*FaktorexBr);
  else
    printf("Don\'t know what to do with (in latbreit):\n");
    print(a);
    printf("Type: %a\n",whattype(a));
  fi;
  10000;
end:
latbreitexp:=proc(x)
  local a, b, p, c, n;
  option remember;
  a:=x;
  if type(a,integer) then
    RETURN(AnzDig(a)*Buchstabenbreite*FaktorexBr);
### W5ARNING: semantics of type `string` have changed
  elif type(a,symbol) then
    if assigned(EZBr[a]) then
      RETURN(EZBr[a]);
    else
      RETURN(Buchstabenbreite*FaktorexBr);
    fi;
  elif type(a,`+`) then
    b:=convert(a,list);
    p:=nops(b);
    if mysign(b[1])=-1 then p:=p+1; fi;
    b:=map(latbreitexp,b);
    b:=convert(b,`+`);
    RETURN(b+p*EZBr["+"]);
  elif type(a,`*`) then
    b:=convert(a,list);
    p:=map(x->type(x,`+`), b);
    n:=0;
    for c in p do
      if c=true then n:=n+1; fi;
    od;
    b:=map(latbreitexp,b);
    b:=convert(b,`+`);
    RETURN(b+n*EZBr[`()`]);
  elif type(a,`^`) then
    RETURN(latbreitexp(op(1,a))+latbreitexp(op(2,a)));
  elif type(a,sqrt) then
    RETURN(Buchstabenbreite*FaktorexBr+latbreitexp(op(1,a)));
  elif type(a,fraction) then
    RETURN(max(latbreitexp(denom(a),numer(a)))*FaktorexBr);
  else
    printf("Don\'t know what to do with (in latbreitexp):\n");
    print(a);
    printf("Type: %a\n",whattype(a));
  fi;
  10000;
end:
# Aufteilung grosser Ausdruecke in eine \parbox
machpar:=proc(x,wd)
   local l, l1, auft, br, teil, i, spbr, aps, lbr,
         spbr1, ll, j, parbr, sf, pos, w, lli, s, par, zpar;
   if type(x,`+`) then
     l1:=convert(x,list);
     spbr1:=map(y->latbreit(y)+ZBr["+"], l1);
     sf:=proc(a,b)
       evalb(a>b);
     end;
     spbr:=sort(spbr1,sf);
     l:=[];
     for i to nops(l1) do
       pos:='pos';
       member(spbr[i],spbr1,pos);
       l:=[op(l),l1[pos]];
       spbr1:=subsop(pos=-1, spbr1);
     od;
     auft:=[];br:=0;teil:=[];lbr:=[];w:=wd;
     for i to nops(l) do
       if br+spbr[i]>w and i>1 then
         auft:=[op(auft),teil];
         lbr:=[op(lbr), br];
         br:=spbr[i];teil:=[i];
         w:=lbr[1];
       else
         br:=br+spbr[i];
         teil:=[op(teil),i];
       fi;
     od;
     auft:=[op(auft),teil];
     lbr:=[op(lbr), br];
### W5ARNING: semantics of type `string` have changed
     parbr:=convert(w, symbol);

     ll:=array(1..nops(auft));
     for i to nops(auft) do
       ll[i]:=0;
       for j in auft[i] do
         ll[i]:=ll[i]+l[j];
       od;
     od;
     par:=[`\\parbox{`,``||parbr||`mm`,`}{\\centering `,
           `\\mbox{}\\\\ $`];
     par:=[op(par), op(mylat(ll[1])), `$ `];
     for i from 2 to nops(auft) do
       par:=[op(par), ` \\\\  $ `];
       lli:=mylat(ll[i]);
       s:=substring(lli[1], 1..1);
       if not member(s, {`+`,`-`}) then
         par:=[op(par), "+"];
       fi;
       par:=[op(par), op(lli), `$`];
     od;
     par:=[op(par), ` \\\\[1mm] }`];
     zpar:=nops(auft);
   else
     par:=[`\\parbox{`,``||wd||`mm`,`}{\\centering `,
           `\\mbox{} \\\\ $`];
     par:=[op(par), op(mylat(x)), `$ \\\\[1mm]  }`];
     zpar:=ceil(latbreit(x)/wd);
   fi;
   [zpar, par];
end:

# Strings mit Parameternamen fuer Charaktere und Klassen
ClassParamString:=proc(t,j)
  local erg,a,b,i,n;
  n:=op(Klassen||t||Parameter);
  if n=evaln(Klassen||t||Parameter) then
    RETURN([``]);
  fi;
  a:=Klassen||t||Parameter[j];
  a:=map(b->op(1,b),a[1]);
  if a=[] or (not type(a,list)) then
    RETURN([``]);
  fi;
  erg:=[`(`,op(mylat(a[1]))];
  for i from 2 to nops(a) do
    erg:=[op(erg),`,`,op(mylat(a[i]))];
  od;
  erg:=[op(erg),`)`];
end:
CharParamString:=proc(t,j)
  local erg,a,b,i,n;
  n:=op(Char||t||Parameter); 
  if n=evaln(Char||t||Parameter) then 
    RETURN([``]); 
  fi; 
  a:=Char||t||Parameter[j];
  a:=map(b->op(1,b),a[1]);
  if a=[] or (not type(a,list)) then
    RETURN([``]);
  fi;
  erg:=[`(`,op(mylat(a[1]))];
  for i from 2 to nops(a) do
    erg:=[op(erg),`,`,op(mylat(a[i]))];
  od;
  erg:=[op(erg),`)`];
end:
  
# Das eigentliche PrintToTeX-Programm:
pttmach:=proc(t,l1,l2)
   local len1,len2,i,j,n1,n2,ll1,ll2,ch,cl,
         cut,brcut,spbr,nnargs,file,tempptt,
         ii,jj,auft,teil,br,cees,c,tabkopf,tabz,
         zeile,zh,hi,a,quietmerk,erklaer;
### W5ARNING: semantics of type `string` have changed
   if nargs>1 and type(args[nargs], symbol) then
     file:=args[nargs];
     nnargs:=nargs-1;
   else
     file:=`tempptt`;
     nnargs:=nargs;
   fi;
   if nnargs = 1 then 
     ll1 := [$ 1..t[-2,2]];
     ll2 := [$ 1..t[-2,4]];
   elif nnargs = 2 then
     ll1 := makelist(args[2]);
     ll2 := [$ 1..t[-2,4]];
   else 
     ll1 := makelist(args[2]);
     ll2 := makelist(args[3]);
   fi;
   len1:=nops(ll1);
   len2:=nops(ll2);
   ch:=t[-2,2];
   cl:=t[-2,4];
   if max(op(ll1))>ch then
     ERROR(`maximal tablename[-2,2] charactertypes`);
   elif max(op(ll2))>cl then
     ERROR(`maximal tablename[-2,4] classtypes`);
   fi;
   cut:=array(1..len1,1..len2);
   for i to len1 do
     for j to len2 do
       cut[i,j]:=t[ll1[i],ll2[j]];
     od;
   od;
   # Suchen der GEW-Namen, die zum Schluss erklaert werden
   # muessen:
   erklaer:=[];
   for i from 2 to nops(konvertGEWlist) do
     if has(op(cut),konvertGEWlist[i][1]) then
       erklaer:=[op(erklaer),i];
     fi;
   od;
   brcut:=map(latbreit,cut);
   spbr:=array([max(brcut[ii,jj]$ii=1..len1)$jj=1..len2]);
   for i to len2 do
     if spbr[i]>MaxSpBr then
       spbr[i]:=MaxSpBr;
     elif spbr[i]<MinSpBr then
       spbr[i]:=MinSpBr;
     fi;
   od;
   auft:=[];br:=Allgbreite+SpaltenAbst;teil:=[];
   for i to len2 do
     if br+spbr[i]>Seitenbreite then
       auft:=[op(auft),teil];
       br:=Allgbreite+SpaltenAbst+spbr[i];teil:=[i];
     else
       br:=br+spbr[i]+SpaltenAbst;
       teil:=[op(teil),i];
     fi;
   od;
   auft:=[op(auft),teil];
   
   printf("%a\n",auft);
   printf("Writing table in file %a.tex\n", file);   
   
   # Vorbereitung:
   quietmerk:=interface(quiet);
   interface(quiet=true);
### W5ARNING: semantics of type `string` have changed
   hi:=convert(ArrayStretch, symbol);
   writeto(``||file||`.tex`);
   printf("\\batchmode\n");
   printf("\\documentstyle{article}\n");
   printf("\\setlength{\\textwidth}{%dmm}\n",Seitenbreite);
   printf("\\setlength{\\parindent}{0pt}\n");
   printf("\\setlength{\\oddsidemargin}{0pt}\n");
   printf("\\setlength{\\evensidemargin}{0pt}\n");
   printf("\\begin{document}\n");
   printf("\\begin{center}\n");
   printf("\\renewcommand{\\arraystretch}{%s}\n",hi);
   printf("\\nopagebreak\n");
   for teil in auft do
     printf("\n");
     tabz:=0;
     tabkopf:=["","$"];
     cees:="|c|":
     for i to nops(teil) do cees:=""||cees||"c|"; od:
     tabkopf:=[op(tabkopf),"\\begin{array}{",cees,"} \\hline "];
     tabkopf:=[op(tabkopf),t[-2,-1]];  #Hier noch was besser machen !
     for j in teil do       
       tabkopf:=[op(tabkopf),"&C_{",ll2[j],"}",op(ClassParamString(t,ll2[j]))];
     od;
  # Wenn es noch Bezeichnungen fuer die Klassen gibt: 
     if t[-1,0]=[] then
       tabkopf:=[op(tabkopf), "\\\\ "];
       for j in teil do
         tabkopf:=[op(tabkopf), "&", t[-1,ll2[j]][1]];
       od;
       tabz:=tabz+1;
     fi;
     tabkopf:=[op(tabkopf),"\\\\ \\hline "]; #\\\\[`||ZZwRaum||`mm]?
     tabz:=tabz+3;
     printlist(tabkopf);
		 for i to len1 do
       zeile:=["\\chi_{",convert(ll1[i],string),"}",op(CharParamString(t,ll1[i]))];
       zh:=1;
       for j in teil do
         zeile:=[op(zeile), "&"];
         if brcut[i,j]<=spbr[j] then
           zeile:=[op(zeile), op(mylat(cut[i,j]))];
         else
           hi:=machpar(cut[i,j],MaxSpBr);
           if hi[1]>zh then
             zh:=hi[1];
           fi;
           zeile:=[op(zeile), op(hi[2])];
         fi;
       od;
       zeile:=[op(zeile), "\\\\ "];
       if tabz+zh>MaxZeilen then
         printf("\\end{array}$ \\bigskip\n");
				 printlist(tabkopf);
				 printlist(zeile);
         printf( "\\hline\n" );
         tabz:=3+zh;
       else
         tabz:=tabz+zh;
         printlist(zeile);
				 printf( "\\hline\n" );
       fi;            
     od;
     printf("\\end{array}$ \\bigskip\n");
   od;
   printf("\\end{center}\\bigskip\\mbox{}\\\\ \n");
   #Erklaerungen fuer die GEW-Namen:
   for i in erklaer do
     zeile:=["$",convert(konvertGEWlist[i][3], string),
             ":=\\mbox{exp}(\\frac{2\\pi \\sqrt{-1}}{",
             op(mylat(konvertGEWlist[i][2])),"})$\\\\"];
     printlist(zeile);
   od;
   printf("\\end{document}\n");
   writeto(terminal);
   interface(quiet=quietmerk);
   system(``||LATEXCOMMAND||` `||file):
   if PREVIEWNAME<>`` then
     system(``||PREVIEWNAME||` `||file||LATEXSUFFIX||` &`):
   fi;
end:

# Die Aufrufprozedur fuer das PrintToTeX:
PrintToTeX :=proc()
  local erg;
  erg:=traperror(pttmach(args));
  if erg=lasterror then
    writeto(terminal);
    olprint(erg);
    RETURN(NULL);
  fi;
  NULL;
end:

PrintToTeXPhi:=proc()
  local hi,t,ll1,ll2,i,j,off;
  t:=args[1];
  tablenumber(t);
### W5ARNING: semantics of type `string` have changed
  if nargs = 1 or (nargs=2 and type(args[2],symbol)) then 
    ll1 := [`$`(1 .. t[-2,2])]; 
    ll2 := [`$`(1 .. t[-2,4])];
    off:=2;
### W5ARNING: semantics of type `string` have changed
  elif nargs = 2 or (nargs=3 and type(args[3],symbol)) then
    ll1 := makelist(args[2]); 
    ll2 := [`$`(1 .. t[-2,4])];
    off:=3;
  else 
    ll1 := makelist(args[2]); 
    ll2 := makelist(args[3]);
    off:=4;
  fi;
  printf("Substituting cyclotomic polynomials.\n");
  Copy(t,hi);
  for i in ll1 do
    for j in ll2 do
      hi[i,j]:=PolyMitPhi(t[i,j]);
    od;
  od;
  PrintToTeX(hi,ll1,ll2,op(off..nargs,[args]));
end:
