#!/usr/bin/perl -s
#
# ELTEX -- ELvalaszto TEX preprocesszor (copyleft) G. Toth 1997-2002
#
# Az ELTEX a $ekmgh-ban definialt ekezetjelolest Tex ekezetjelolesre alakitja,
# tovabba a magyar nyelv elvalasztasi szabalyai szerint \- elvalaszto
# jeleket helyez el a TeX szovegben. 
#
# Hasznalat:
#
#     eltex [-pc]  < filename.hun > filename.tex
#
# illetve ezzel ekvivalens az
#
#     eltex [-pc] filename
#
# parancs, mely esetben a .hun illetve .tex kiegeszitesek automatikusan
# hozzairodnak a filename-hez. A -pc kapcsolo eseten az ekezetes betuket a
# Windows karakterkeszletevel jeloljuk, egyebkent pedig az 123-s jelolessel.
#
# A $ $ jelek, tovabba a \begin{eq..} es \end{eq..} illetve a $$ es $$-ral
# KEZDODO sorok kozti szovegeket (matematikai mod), valamint a \ -sel kezdodo 
# (La)TeX parancsokat ezek opcionalis [argument]-jeivel egyetemben 
# megkimeli mind az elvalasztastol, mind az ekezestol.
#
# A {nincsszokoz} tipusu argumentumokba, illetve a \begin{verbatim} es
# \end{verbatim}-mal KEZDODO sorok kozti szovegekbe nem ir elvalaszto jeleket, 
# es az ekezeteket sem TeX-esiti.
#
# Az elvalasztas es az ekezetes maganhangzok csereje explicite kikapcsolhato
# a \EKKI paranccsal, illetve visszakapcsolhato a \EKBE -vel.
# Az elvalasztas onmagaban ki- es bekapcsolhato a \ELKI es \ELBE parancsokkal.
# Ezeket az ELTEX parancsokat nem kovetheti betu kozvetlenul, viszont az 
# esetleges mogottes szokozzel egyutt toroltetnek a TeX szovegbol.
#
############################################################################

# File-k megnyitasa ha nem STDIN --> STDOUT
if($#ARGV>=0){
    $file=$ARGV[0]; $file=~s/\.hun$//;
    die "$file.hun does not exist!\n" unless -e "$file.hun";
    @ARGV=("$file.hun");
    open(STDOUT,">$file.tex");
    print STDERR "eltex < $file.hun > $file.tex\n";
}

### Inicializalas: halmazok es asszociativ tombok  definialasa ###

# Kapcsolo stringek definialasa, ezeket az ELTEX kiveszi a szovegbol
# Ugyanugy hasznalandok  mint a TeX commandok, azaz mogottes szokozzel
$ekki='^\\\\EKKI'; $ekbe='^\\\\EKBE'; $elki='^\\\\ELKI'; $elbe='^\\\\ELBE';

# Default viselkedes: ekezes es elvalasztas bekapcsolva
$ekez=1; $elva=1;

# $minelo  ill. $minveg hosszu (vagy annal rovidebb) darabot a szo
# elejerol ill. vegerol mar nem valasztunk el
$minelo=1;
$minveg=1;

# Ekezetes magyar maganhangzok jelolese es a megfelelo TeX stringek
# Itt allhat barmilyen kod, esetleg beolvashato egy file-bol is

if($pc){
    $ekmgh=<<VEGE;
á
é
í
ó
ö
õ
ú
ü
û
Á
É
Í
Ó
Ö
Õ
Ú
Ü
Û
VEGE
}else{
    $ekmgh=<<VEGE;
a1
e1
i1
o1
o2
o3
u1
u2
u3
A1
E1
I1
O1
O2
O3
U1
U2
U3
VEGE
}

$ektex=<<VEGE;
\\'a
\\'e
\\'{\\i}
\\'o
\\"o
\\H o
\\'u
\\"u
\\H u
\\'A
\\'E
\\'I
\\'O
\\"O
\\H O
\\'U
\\"U
\\H U
VEGE

# Tombok definialasa

@ekmgh=split(/\n/,$ekmgh);
@ektex=split(/\n/,$ektex);

@msh23=('cs','dz','dzs','gy','ly','ny','qu','sz','ty','zs',
        'CS','DZ','DZS','GY','LY','NY','QU','SZ','TY','ZS');

# Tokenek az ASCII 127-tol felfele levo karakterek
$kod=127;

# Az elvalasztojel szinten token, ugyanis a \ nehezen hasznalhato
# regular expression-ben.
$kod++; $el=pack("c",$kod); $tex{$el}='\-'; $toke=$el;

# A \$,\%,\{,\} tokenizalando, hogy ne keveredjen a valodi $,%,{,} jelekkel
foreach $k ('$','%','{','}'){
   $kod++; 
   $s=pack("c",$kod); 
   $tex{$s}="\\$k"; 
   $spec{$k}=$s; 
   $spec.="$s|";
}
chop($spec);

# A maganhagzok, ekezetesek tokenizalva, %token es %tex transzformal
$mg="aeiouAEIOU";
for($i=0;$i<=$#ekmgh;$i++){
   $kod++;
   $b=$ekmgh[$i];
   $t=pack("c",$kod);             # Token karakter
   $token{$b}=$t;                 # Tokenre konvertalas
   $ektex{$b}=$ektex[$i];         # Az ekezetes mgh-k TeX-re konvertalasa
   $tex{$t}=$ektex[$i];           # A tokenek TeX-re konvertalasa
   $ekorig.="$b|";                # Az ekezetes mgh-k template-je cserehez
   $mg.=$t;                       # A (tokenizalt) maganhangzok stringje
   $toke.=$t;                     # Az osszes tokenek stringje
}
$orig=$ekorig; chop($ekorig);

# A massalhangzok, 2 es 3 betusek tokenizalva, %token es %tex konvertal
$ms="bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ";
foreach $b (@msh23){
   $kod++;
   $t=pack("c",$kod);             # Token karakter
   $token{$b}=$t;                 # Tokenekre konvertalas
   $tex{$t}=$b;                   # Visszakonvertalas a tokenekrol
   $orig.="$b|";                  # A 3 es 2 betus msh-k template-je cserehez. 
   $ms.=$t;                       # A (tokenizalt) msh-k stringje
   $toke.=$t;                     # Az osszes tokenek stringje
}
chop($orig);

# Elvalasztott hosszu kettos msh-k transzformalasahoz $mshelorig es %msheltex
foreach $b (split(',',
            'cs,dzs,dz,gy,ly,ny,sz,ty,zs,CS,DZS,DZ,GY,LY,NY,SZ,TY,ZS')){
   $a=substr($b,0,1);
   $mshelorig.="$a\\\\-$b|";
   $msheltex{"$a\\-$b"}="{$b-}{$b}{$a$b}";
}
chop($mshelorig);

die "Tul sok token, kodmax=$kod\n" if $kod>255;

# Karakter halmazok definialasa
$bet="$mg$ms";
$mgh="[$mg]"; $msh="[$ms]"; $betu="[$bet]"; $token="[$toke]";
$szokoz="[^$bet$el]";

############################################################################

### Szoveg feldolgozas ###

while(<>){
   if(/^\s*$/ || /^\s*%/){print;next}      # ures sor vagy % comment sor

   if(/^\$\$/ and not $verbatim){$math=1-$math;print;next}   # $$-ral kezdodo sor (TeX)

   if    (/^\\begin\{verbatim\}/){$verbatim=1; print; next}
   elsif (/^\\end\{verbatim\}/)  {$verbatim=0; print; next}
   elsif (/^\\begin\{eq/)        {$math=1; print; next}
   elsif (/^\\end\{eq/)          {$math=0; print; next}

   # Megszabadulunk a zavaro specialis karakterektol: \$,\%,\{,\}
   s/\\([\$\%\{\}])/$spec{$1}/g;

   # felvagas \command[options], \command, %comment es $ alaku stringenkent
   split(/(\\[a-zA-Z]+\[[^[]*\] ?|\\[a-zA-Z]+ ?|%.*\n|\\\$|\$)/);

   # print STDERR join('|',@_); ###TEST

   foreach $_ (@_){
      if(/$ekki/o){$ekez=0; $_=''; next}            # \EKKI
      if(/$ekbe/o){$ekez=1; $_=''; next}            # \EKBE
      if(/$elki/o){$elva=0; $_=''; next}            # \ELKI
      if(/$elbe/o){$elva=1; $_=''; next}            # \ELBE
      next if /^\\[a-zA-Z]/ || /^%/;                # \command vagy %comment

      next if $verbatim;                            # verbatim mod
      if($_ eq '$'){$math=1-$math; next}            # $ valtja a matek modot
      next if $math;                                # matematikai mod
      next unless $ekez;                            # ekezes kikapcsolva

      if(!$elva){                                   # Ha nincs elvalasztas
          s/($ekorig)/$ektex{$1}/go;                # akkor csak az ekezetes
          next;                                     # mgh-kat kell cserelni
      }

      if(s/(^\{[^\s\}]*\})//){                      # {argument} kezdetu
         $arg=$1;                                   # darabokban csak az
         $arg=~s/($ekorig)/$ektex{$1}/go;           # ekezeteket csereljuk
      }else{$arg=''};

      s/($orig)/$token{$1}/go;                      # tokenizal

      while(s/($mgh)($mgh)/$1$el$2/go){};           # elvalaszt mgh-mgh kozott
      while(s/($mgh$msh*)($msh$mgh)/$1$el$2/go){};  # elvalaszt -mshmgh elott

      # Szo elejehez illetve vegehez tul kozeli elvalasztojelek kiszedese
      while(s/((^|$szokoz)${betu}{1,$minelo})$el/$1/go && $minelo>1){};
      while(s/$el(${betu}{1,$minveg}$szokoz)/$1/go     && $minveg>1){};

      # Tokenek visszacserelese
      s/($token)/$tex{$1}/go;

      # Elvalasztott hosszu msh-k csereje \discretionary{sz-}{sz}{ssz} -re
      s/($mshelorig)/\\discretionary$msheltex{$1}/go;

      $_=$arg.$_ if length($arg); # visszatesszuk az {\'ekezett} argumentumot
   }
   $_=join('',@_);             # osszerakjuk a sort

   # Visszarakjuk a specialis karaktereket: \$,\%,\{,\}
   s/($spec)/$tex{$1}/go;

   print;   
}
#############################################################################
