/*-*-Coding: latin-3;-*-*/
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define outBufLen 9000
#ifdef KL
#define goodlen 78
#else
#define goodlen 69
#endif
#define lf 10
#define ff 12
#define del 127
#define ns '\240'

#define Cx '\306'
#define cx '\346'
#define Gx '\330'
#define gx '\370'
#define Hx '\246'
#define hx '\266'
#define Jx '\254'
#define jx '\274'
#define Sx '\336'
#define sx '\376'
#define Vx '\335'
#define vx '\375'

#define Hstroke '\241'
#define Mo      '\244'
#define Ye      '\245'
#define tremao  '\250'
/*  #define Co      '\251' */
#define Gh      '\253'
#define gh      '\273'
#define gpunkto '\365'
#define Rg      '\256'
#define hstroke '\261'
#define acute   '\264'
#define zoeto   '\270'
#define dotlessi '\271'
#define duono   '\275'
#define tri4ons '\276'
#define Atildo  '\303'
#define acirc   '\342'
#define Cz      '\307'
#define cz      '\347'
#define Ecirc   '\312'
#define ecirc   '\352'
#define Eacute  '\311'
#define eacute  '\351'
#define Jo      '\313'
#define jo      '\353'
#define atildo  '\343'
#define Edo     '\320'
#define edo     '\360'
#define Oe      '\326'
#define oe      '\366'
#define Ucirc   '\333'
#define ucirc   '\373'
#define ntildo  '\361'
#define sozo    '\337'
#define superpunkto '\377'

#define ankrofermilo acute

#define eo3 "ÆØ¦¬ÞÝæø¶¼þý"
const char* bazaj_literoj = "CGHJSU" "cghjsu";
    
const char * SAMPA =
     "6AQ.OC...@.E3³.."
     ".g...H..1.I....."
     "..J...9........."
     "R..þ.....}.UV.LY"
     "..¼............."
     "....ø..æ";

#define tabuo "¡¢\245©ª«\256¯±¹º»\276¿\303Å\320Õ\343å\360õÿ"

enum {falso, vero};
typedef int Bulea;
#define askia(x) (!( (x) & 0x80 ))
typedef char* String;
typedef enum{ defavxlto, left, right, center, menuo, eqn } alignment;
typedef enum{ eo, IPA, lat1, lat2, rusa } lingva;

typedef enum{
    alg, anglete, bibref, bildego, centra, Cirile, cirilete, ccode, code,
    Detaloj, egale, evi, fon, fremda, grafiko, germane, greke, hname, html,
    inlineimg, kapvorta, l1, l3, lang, mat, name, nego, numero, quote,
    scope, sintakso, subkapa, subunit, tabelo, url, Url, verb, xref
} speco;

char bildvojo[255] = "BILDOJ";

char   linio[255], Name[20];
int    linipoz, outpos, out_linepos;
char   bannerNumber, ch, ento, kromelemento, mem1, mem2, parNro, erarnombro,
    *Html,
    *open_bold = "<b>",
    *close_bold = "</b>",
    *open_math_font = "<tt>",
    *close_math_font = "</tt>",
    signaro;
unsigned uch;                   /* Unicode Unsigned CHaracter */
static FILE   *fonto, *celo;
static Bulea
    A_E, clearall, dekume, dict, DOS, dosierfino, en_tabelo,
    fermaCitilo, finilo,
    graseto, jxus_ns, keep_in_buffer, kursivo, latex, lvert,
    make_depend, mmode,
    penda_spaceto, pendaIkso, pre, prev_putch,
    sintakse, TeX, texi, TomeRaider, uni, unutipare, verbatim, win;
char
    outBuf[outBufLen], stako[goodlen], cxeno[goodlen],
    nova_cxeno[goodlen], kviete,
    atributoj_de_elemento[goodlen];
int
    artikolnombrilo=0, difino=0, freshPar, makrooingado=0, outLen, stakind,
    sojla_linilongo=goodlen, tt_ingado=0, lininumero, ll, en_html_komando;
int angla_nombrilo = 0;
static alignment align;
static lingva lingvo = eo, lStako[9];

char *sekciindekso[9], menubufro[2000];
int ingonivelo = 0; /* ekz-e por {2,4,5} ingonivelo == 3; <h2> == 0*/
int menubufro_i = 0;

/*----- ANTAVXDEKLAROJ: -----*/

static speco elemento();
static void cxefciklo(const char);
const char* ensureMathTex(const char*);
static void hyperlink(char);
void presCxen(const char*);
void putHTMLsym(char);
void putStrL(const char*, lingva);
void putUni(int n);
void putUniSym(int, const char*);
void putUniTexSym(int, const char*, const char*);
void putUni4Sym(char*, int, const char*);
void skribu(char ch);
void skribuCxen(const char*);
static void subbanner();
static char tabela_trankodo(char, char*, char*, int);

/*================ T A B E L O J :  ======================*/
static char Lat1perLat3_1[] =
         " !C£¤Y|§¨C-<N­R¯"
         "°+²³´µ|·¸^->1½3?"
         "ÀÁÂAÄAAÇÈÉÊËÌÍÎÏ"
         "DÑÒÓÔOÖ×OÙÚÛÜYTß"
         "àáâaäaaçèéêëìíîï"
         "dñòóôoö÷oùúûüyty",
     Lat1perLat3_2[] =
         " `d  e   oa<E g "
         "-     P  1o>4 4`"
         "   ~ AE         "
         "H    ~  /    ´H "
         "   ~ ae         "
         "h    ~  /    ´h¨";

static short unikodo_el_latina3[] = {
   0x0A0, 0x126, 0x2D8, 0x0A3, 0x0A4,   del, 0x124, 0x0A7,
   0x0A8, 0x130, 0x15E, 0x11E, 0x134, 0x0AD,   del, 0x17B,
   0x0B0, 0x127, 0x0B2, 0x0B3, 0x0B4, 0x0B5, 0x125, 0x0B7,
   0x0B8, 0x131, 0x15F, 0x11F, 0x135, 0x0BD,   del, 0x17C,
   0x0C0, 0x0C1, 0x0C2,   del, 0x0C4, 0x10A, 0x108, 0x0C7,
   0x0C8, 0x0C9, 0x0CA, 0x0CB, 0x0CC, 0x0CD, 0x0CE, 0x0CF,
     del, 0x0D1, 0x0D2, 0x0D3, 0x0D4, 0x120, 0x0D6, 0x0D7,
   0x11C, 0x0D9, 0x0DA, 0x0DB, 0x0DC, 0x16C, 0x15C, 0x0DF,
   0x0E0, 0x0E1, 0x0E2,   del, 0x0E4, 0x10B, 0x109, 0x0E7,
   0x0E8, 0x0E9, 0x0EA, 0x0EB, 0x0EC, 0x0ED, 0x0EE, 0x0EF,
     del, 0x0F1, 0x0F2, 0x0F3, 0x0F4, 0x121, 0x0F6, 0x0F7,
   0x11D, 0x0F9, 0x0FA, 0x0FB, 0x0FC, 0x16D, 0x15D, 0x2D9};

short uni2Greka[] = {
/*    ¡  ¢  £  ¤     ¦     § ¨   ©     ª « ¬ ­  ¯ */
  ns, 0, 0, 0, 0, 0,0x3a7, 0,0, 0x397, 0,0,0,0,0,0,

/* ° ± ² ³  ´   µ  ¶    · ¸ ¹ º » ¼ ½  ¿ */
   0,0,0,0,0xb4,0,0x3c7,0,0,0,0,0,0,0,0,0

/*À     Á     Â      Ä Å Æ Ç  È     É     Ê     Ë     Ì     Í     Î     Ï */
,0x386,0x386,0x386,0,0,0,0,0,0x388,0x388,0x388,0x397,0x38a,0x38a,0x38a,0x3aa

/*Ñ  Ò     Ó     Ô    Õ  Ö    × Ø  Ù     Ú     Û     Ü    Ý Þ ß */
 ,0,0,0x38a,0x38a,0x38a,0,0x3a9,0,0,0x38e,0x38e,0x38e,0x3ab,0,0,0

/*à     á     â     ä å æ ç  è     é     ê     ë     ì     í     î     ï */
,0x3ac,0x3ac,0x3ac,0,0,0,0,0,0x3ad,0x3ad,0x3ad,0x3b7,0x3af,0x3af,0x3af,0x3ca
/*ñ  ò     ó     ô    õ  ö    ÷ ø  ù     ú     û     ü    ý þ ÿ */
,0,0,0x3cc,0x3cc,0x3cc,0,0x3c9,0,0,0x3cd,0x3cd,0x3cd,0x3cb };


/*================ T A B E L O J .  ======================*/

const char *strchr8(const char *s, int c) /*iuj strchr mistraktas 8-bita¼ojn*/
{
    const char *x = s, cc = c;
    do if(*x == cc) return x;
    while(*x++);
    return 0;
}

void eraro(String m){
   fprintf(stderr,
           "\n%s>%d %d <%c> uch=0x%x %s\n%s\n\a",
           Name, lininumero, linipoz, uch, ch, linio, m);
   if(erarnombro++ > 3) exit(-1);
}

void feraro(char *fmt, ...)
{
    char buf[99];
    int n;
    
    va_list args;
    va_start(args, fmt);
    n = vsprintf(buf, fmt, args);
    if(n >= sizeof(buf)) eraro("tro longa cxeno en fPutStr");
    eraro(buf);
    va_end(args);
}

int cxapelnumero(char x) {
    static const char y0[] = eo3;
    const char* y = y0;
    do if(*y == x) return x ? y - y0 : -1;
    while(*y++);
    return -1;
}

char minuskligu(char l){
    if(askia(l)) return tolower(l);
    switch(l){
        case Cx: return cx;
        case Gx: case Sx: case Vx: return l + 32;
        case Hx: case Jx: return l | 0xb0;
        default: return l;
    }
}

char majuskligu(char l) {
    int i;
    if(askia(l)) return toupper(l);
    i = cxapelnumero(l);
    if(i > 5) l = eo3[i - 6];
    return l;    
}

int litero(char x) {
  if(askia(x)) return isalpha(x);
  return cxapelnumero(x) >= 0;
}

void postaskiigu(char* b, char d, int n) {
    char buf[goodlen], c1;
    int i, j, k;

    if(n > goodlen) n = goodlen;

    for(i = j = 0; j < n; ){
        c1 = b[i++];
        if(!askia(c1)){
          if('h' == d && vx == c1) c1 = 'u';
          else{
            k = cxapelnumero(c1);
            if(k < 0) feraro("ne-Askia signo [%c]=x%x en ankro", c1, c1);
            else{
                buf[j++] = bazaj_literoj[k];
                c1 = d;
            }
          }
        }
        buf[j++] = c1;
        if(0 == c1){
            strcpy(b, buf);
            return;
        }
    }
    eraro("Tro longa cxeno por postmeta askiigo");
}

char krombufro[goodlen];
int kromkopiu = sizeof(krombufro);

void putch(char);
void putUniSym(int uniCode, const char *alt);

void getch1() {
    while(ch = linio[linipoz++]){ /* zorgu pri la linifiniloj: */
        if((unsigned)(ch & 0xff) >= ' ' || ff == ch) return;
    }
    dosierfino = (NULL == fgets(linio, sizeof(linio) - 1, fonto));
    if(dosierfino) linio[0] = 0;
    ++lininumero;
    ch = linipoz = 0;
}

void getch()
{
    int i;
L:  getch1();
    if('\t' == ch) ch = ' ';   /* horizontala tabo */
    uch = ch & 0xffu;
    if(uch < del){
        if(uch >= ' ' || ff == ch) return;
        uch = ch = 0;
        return;
    }
    if((uch >> 4) == 14){
        uch = (uch & 017) << 12;
        getch1();
        if((ch & 0300u) != 0200) feraro("La dua bajto: 0x%x=%d", ch, ch);
        uch |= (unsigned)(ch & 077) << 6;
        getch1();
    }else{
        if((uch >> 5) != 6) feraro("UTF-?: 0x%x=%d", ch, ch);
        uch = (uch & 077) << 6;
        getch1();
    }
    if(((unsigned)ch & 0300) != 0200)
	feraro("La lasta bajto: 0x%x=%d", ch, ch);
    assert(((unsigned)ch & 0300) == 0200);
    uch |= (077 & ch);
    {
        static char skipping = 0;
        if(0x404 == uch){
            char preter, trafo;
            getch1();
            preter = ch;             /* + aý - */
            getch1();
            if('(' == ch){
                getch1();
                for(trafo = 0; ch != ')' && !dosierfino; getch1())
                    if(ch == signaro) trafo = 1;
            }else trafo = ch == signaro;
            if(trafo && '-' == preter || !trafo && '+' == preter){
                if(skipping) eraro("nested skip");
                for(skipping++; (0x42d != uch) && !dosierfino;) getch();
                skipping--;  
            }
            goto L;            
        }
        if(!skipping && 0x42d == uch) goto L;
    }
    assert(uch != 0x405);
    if(uch <= 0x2D9){
        for(i = 0; i != sizeof(unikodo_el_latina3); i++){
            if(uch == unikodo_el_latina3[i]){
                ch = i + ns;
                return;
            }
        }
    }else if(0x2294 == uch){
        ch = ns;
        return;
    }
    ch = del;
}

void readch()
{
    getch();
    if(!ch) ch = ' ';
}

char get_low() {
    getch();
    return ch = minuskligu(ch);
}
    
void skip() {
    while((' ' == ch || 0 == ch) && !dosierfino)
        getch();
}

void skip_beyond(const char x) {
    while(x != ch && !dosierfino) getch();
    if(!dosierfino) getch();
}

static void get_skip() {
    getch();
    skip();
}

static void preterkontrolu(const char x) {
    if(x == ch) getch();
    else{
        char buf[30];
        sprintf(buf, "Mankas [%c]", x);
        eraro(buf);
    }
}

static void putStr(const char *s)
{
   while(*s){
       if(hstroke == *s) putStr(Html);
       else if(sozo == *s) putStr(bildvojo);
       else putch(*s);
       s++;
   }
}

static void putStrq(const char *s)
{
    int k = kviete;
    kviete = 1;
    while(*s) putUni(*s++);
    kviete = k;
}

static void escTexStr(const char *s)
{
    putch(texi? '@' : '\\');
    putStr(s);
}

static void fPutStr(char *fmt, ...)
{
    char buf[300];
    int n;
    va_list args;

    if(0 == fmt) return;
    va_start(args, fmt);
    n = vsprintf(buf, fmt, args);
    if(n >= sizeof(buf)) eraro("tro longa cxeno en fPutStr");
    presCxen(buf);
    va_end(args);
}

#define putChar(x) putch((char)(x))

void putq(char sg){
  int k = kviete;
  kviete = 1;
  putch(sg);
  kviete = k;
}

void enT1igu(unsigned int n) {
    fPutStr(eo < lingvo && lingvo < rusa ? "{\\char%d}" :
            "{\\TI\\char%d}", n);
}

int putLat1TeX(unsigned char z) {
    static const char L1[] = "¡¢¤\245¦§±©¹ªº«»×÷¶¬¼\256\276¯¿ßÿ";
    static const char *T[] = {
      "!`", "{\\textcent}", "{\\textcurrency}", "{\\textyen}",
      "{\\textbrokenbar}", "{\\S}",
      "\\textpm ", "\\copyright ", "{\\textonesuperior}",
      "\\textordfeminine ", "{\\textordmasculine}",
      "\\guillemotleft", "\\guillemotright",
      "\\texttimes ", "\\textdiv ", "\\P ", "\\textlnot ", "\\textonequarter ",
      "\\textregistered{}", "{\\textthreequarters}",
      "\\ensuremath{\\overline{\\phantom{x}}}", "{\\textquestiondown}",
      "{\\ss}", "\\\"y"
    };
    const char *zz = strchr8(L1, z);
    if(zz){
        putStr(T[zz - L1]);
        return 1;
    }
    if(z >= 0xc0){
        enT1igu(z);
        return 1;
    }
    return 0;    
}

short putEuroLatTex(const unsigned z){
    static const unsigned char tab[] = {
        'A', 'a', 0x80,0xa0,0x81,0xa1,0x82,0xa2,0,0,0,0,0x83,0xa3,0x84,0xa4,
        0xd0,0x9e,'E','e',0,0,0,0,0x86,0xa6,0x85,0xa5,0,0,0x87,0xa7,
        0,0,0,0,0,0,0,0,0,0,'I',0,0,0,0,0,
        0x9d,0x19,0x9c,0xbc,0,0,0,0,0,0x88,0xa8,0,0,0x89,0xa9,0,
        0,0x8a,0xaa,0x8b,0xab,0,0,0x8c,0xac,0,0x8d,0xad,'O','o',0,0,
        0x8e,0xae,0xd7,0xf7,0x8f,0xaf,0,0,0x90,0xb0,0x91,0xb1,0,0,0x93,0xb3,
        0x92,0xb2,0x95,0xb5,0x94,0xb4,0,0,0,0,0,0,'U','u',0x97,0xb7,
        0x96,0xb6,0,0,0,0,0,0,0x98,0x99,0xb9,0x9b,0xbb,0x9a,0xba
    };
    unsigned char x;
    if(z < 0x100 || z > 0x17e) return 0;
    x = tab[z - 0x100];
    if(0 == x) return 0;
    if(127 > x) fPutStr("\\=%c", (char)x);
    else enT1igu(x);
    return 1;
}

short putEuroLatAscii(int z){
    static const char asc_tab[] =
        "A=a=A(a(A,a,C'c'C>c>C.c.C<c<D<d'"
        "DjdjE=e=E(e(E.e.E,e,E<e<G>g>G(g("
        "G.g.G,g,H>h>H=h=I~i~I=i=I(i(I,i,"
        "I.i.IJijJ>j>K,k,k~L'l'L,l,L<l<L."
        "l.L/l/N'n'N,n,N<n<'nNGngO=o=O(o("
        "O\"o\"OEoeR'r'R,r,R<r<S's'S>s>S,s,"
        "S<s<T,t,T<t'T/t/U~u~U=u=U(u(Uouo"
        "U\"u\"U,u,W>w>Y>y>Y:Z'z'Z.z.Z<z<s~";
    if(z < 0x100 || z > 0x17e) return 0;
    putHTMLsym(asc_tab[z = (z - 0x100) * 2]);
    putHTMLsym(asc_tab[z + 1]);
    return 1;
}
    
int putIpaTex(const char z)
{
    static const  char fon3[] = "~¢%æ³ø{",
        *eo3perTex[] = {
            "\\accent3 ","\\accent8 ",
            "\"\"","\\textteshlig ","\\textrhookrevepsilon ","\\textdyoghlig ",
            "\\ae "
        };
    const char *x = strchr8(fon3, z);
    if(x) putStr(eo3perTex[x - fon3]);
    return 0 != x;
}    

void put3or1(char sg)
{
    int n;
    static char lat3_per_lat1[] =
        "  H~( £ ¤   Hx§ ¨ i S¸G(Jx­   Z."
        "° h~² ³ ´ µ hx· ¸ I s¸g(jx½   z."
        "À Á Â   Ä C.CxÇ È É Ê Ë Ì Í Î Ï "
        "  Ñ Ò Ó Ô O Ö × GxÙ Ú Û Ü UxSxß "
        "à á â   ä c.cxç è é ê ë ì í î ï "
        "  ñ ò ó ô o ö ÷ gxù ú û ü uxsx. ";
/*          "  ñ ò ó ô o ö ÷ gxù ú û ü ù sx. "; */
    if(askia(sg) || '3' == signaro || 't' == signaro) putHTMLsym(sg);
    else if(TomeRaider || '1' == signaro || '2' == signaro){
        putHTMLsym(lat3_per_lat1[n = ((sg & 255) - 0xa0) * 2]);
        sg = lat3_per_lat1[n + 1];
        if(' ' == sg) return;
        if('x' == sg) pendaIkso = 1;
        else putHTMLsym(sg);
    }else eraro("Nek LAT1 nek LAT3");
}

short putCyrillic(int z)
{
    static const char azbuko[] = "ABVGDE¬ZIJKLMNOPRSTUF¦CÆÞÇÌYÍÈÛÂ"
                                 "abvgde¼zijklmnoprstuf¶cæþçìyíèûâ",
        Slavono3[] = "ëËêÊúÚ";
    static const short
        SlavonoUni[] = {0x451, 0x401, 0x463, 0x462, 0x457, 0x456},
        SlavonoT2[] = {188, 156, 179, 147, 187, 155};
    int i;

    if(0x410 <= z && z < 0x450){
        if(strchr("13rt", signaro)) put3or1(azbuko[z - 0x410]);
        else enT1igu(z - 0x410 + 192);
        return 1;
    }
    for(i = 0; i != sizeof(SlavonoUni); i++)
        if(z == SlavonoUni[i]){
            if(strchr("13rt", signaro)) putch(Slavono3[i]);
            else enT1igu(SlavonoT2[i]);
            return 1;
        }
    return 0;
}

short putGreek(int z){
    static const char uni_bazgreka_al_lat[] =
        "Á · É Ë/Í ? Ó ? y Ö/ï/"  
        "A B G D E Z Ë THI K L M N X O P R ? S T U F ¦ PSÖ Ï Ü "
        "á é ë/í ü/"  
        "a b g d e z ë thi k l m n x o p r ç s t u f ¶ psö ï ü ó ú ö/";
    
    char c;

    if(0x386 <= z && z < 0x3cf){
        if(latex) eraro("Unicode to TeX is not implemented yet");
        put3or1(uni_bazgreka_al_lat[z = 2 * (z - 0x386)]);
        if(' ' != (c = uni_bazgreka_al_lat[z + 1])) putHTMLsym(c);
        return 1;
    }
    return 0;
}

void putTexAsc(char *tex, char *asc) {
    if(latex) putStr(tex);
    else{
        int c;
        if((penda_spaceto || jxus_ns) && ' ' == *asc) ++asc;
        if(!texi) putStr(TomeRaider?"<b>":"<strong>");
        while(c = *asc++){
            if(' ' == c){
                c = ns;
                if(0 == *asc){
                    if(!texi) putStr(TomeRaider?"</b>":"</strong>");
                    putHTMLsym(ns);
                    return;
                }
            }
/*              putHTMLsym(c); */
            skribu(c);
        }
        if(!texi) putStr(TomeRaider?"</b>":"</strong>");  
    }
}

void putMat(char *tex, char *asc) {
    if(latex) putStr(ensureMathTex(tex));
    else putTexAsc(tex,asc);
}

void putUni(int n) {
   unsigned nn = (n < 0 ? n & 255 : n);
   if(0 == n) eraro("0x0 en putUni");
   if(nn < 128){
       if(latex){
	   if('`' == n) putStr("{\\char18}");
	   else if('´' == n) putStr("{\\char19}");
	   else putChar(n);
       }else putChar(n);
       return;
   }
   if(nn > 0xffff) eraro("kodono > 0xffff");
   else if('2' == signaro){
       if(0x2013 == n){putStr ("--"); return;}
       if(0x2014 == n){putStr ("---"); return;}
       if(0x21d2 == n || 0x21d4 == n ||
	  0x2200 == n || 0x2203 == n || 0x2208 == n ||
	  0x2227 == n || 0x2228 == n || 0x2282 == n ||
	  0x2286 == n) goto next;
   }
   if(n > 0x2100 && '8' != signaro){
       if(0x2102 == n) putMat("\\mathbb{C}", "C");
       else if(0x2115 == n) putMat("\\mathbb{N}", "N");
       else if(0x211D == n) putMat("\\mathbb{R}", "R");
       else if(0x2124 == n) putMat("\\mathbb{Z}", "Z");
       else if(0x21a6 == n)
           if(uni) {nn = 0x2192; goto next;}
           else putMat("\\mapsto ", "->");
       else if(0x21d2 == n)
           if(uni){ nn = 0x2192; goto next;}
           else putMat("\\Rightarrow", "=>");
       else if(0x21d4 == n)
           if(uni){ nn = 0x2261; goto next;}
           else putMat("\\Leftrightarrow", "<=>");
       else if(0x2200 == n) putMat("\\forall ", "PORAJNA ");
       else if(0x2203 == n) putMat("\\exists ", "EKZISTAS ");
       else if(0x2205 == n) putMat("\\varnothing ", "{}");
       else if(0x2208 == n) putMat("\\in", " EN ");
       else if(0x2227 == n) putMat("\\land", " KAJ ");
       else if(0x2228 == n) putMat("\\lor", " AÝ ");
       else if(0x226b == n) putMat("\\gg", ">>");
       else if(0x227b == n) putMat("\\succ", " TUJPOST ");
       else if(0x2282 == n) putMat("\\subset", "<");
       else if(0x2286 == n) putMat("\\subseteq", "<=");
       else if(0x2295 == n) putMat("\\oplus", "(+)");
       else if(0x2296 == n) putMat("\\ominus", "(-)");
       else if(0x22a2 == n) putMat("\\vdash ", "|-");
       else if(0x22a8 == n) putMat("\\models ", "|=");
       else if(0x22bb == n) putMat("\\veebar ", "^");
       else if(0x22bc == n) putMat("\\barwedge ", " MALKAJ ");
       else if(0x22bd == n) putMat("\\malavx ", " MALAÝ ");
       else if(0x2329 == n)
           if(uni && '2' != signaro) { nn = 0x2039; goto next;}
           else putMat("\\langle ", "<");
       else if(0x232a == n)
           if(uni && '2' != signaro) { nn = 0x203a; goto next;}
           else putMat("\\rangle ", ">");
       else goto next;
       return;
   }
   next:
   if(uni){
       if(8704 == n && '4' == signaro){
           putch('A');
           return;
       }
       if(0xb7 == nn && '8' == signaro && mmode) nn = 0x22c5;  /*dot op.*/
       if(dekume) fPutStr("&#%u;", nn);
       else{
           int k = kviete;
           kviete = 1;

           if(nn <= 0x7ff){
               putChar( 0300 | (nn >> 6) );
               putChar( 0x80 | (nn & 077) );
           }else{
               putChar( 0340 | (nn >> 12) );
               putChar( 0x80 | ( (nn >> 6) & 077) );
               putChar( 0x80 | (nn & 077) );
           }
           kviete = k;
       }
       return;
          
   }
   if(nn < 256){
/*         static const char win1[] = */
/*  	   "\xa4\xa6§\xa9\xab\xac\xad\xae°\xb1µ\xb6·\xbb"; */
       if('1' == signaro || TomeRaider ||
          ('3'==signaro || TeX) && nn==unikodo_el_latina3[nn - 0xa0]){
           if(dekume) fPutStr("&#%u;", nn);
           else putq(nn);	/* hstroke estu \pm */
           return;
       }
       if('3' == signaro || texi){
           if(mmode && 0xac == n){
               putTexAsc(0, "NE ");
               return;
           }
           putHTMLsym(tabela_trankodo((char)nn,
                                      Lat1perLat3_1, Lat1perLat3_2,
                                      sizeof(Lat1perLat3_1)));
           return;
       }
       if(latex && putLat1TeX(n)) return;
/*         if(win && strchr8(win1, nn)) putq(nn); */
   }
   if(mmode){
       if(0x3bb == n){
           putTexAsc("\\hbox{\\textlambda}", "LAMBDO ");
           return;
       }else if(!latex && 0x39b == n){
/*             putStr("`'"); */
	   putUni(0x2018); putUni(0x2019); /* empty string, \lq\rq */
           return;
       }
   }
   if(putCyrillic(n) || putGreek(n)) return;
   if(win){
       if(0x201c == n) putch('\x93'); /* `` */
       else if(0x201d == n) putch('\x94'); /* '' */
       else if(0x2013 == n) putq('\226'); /* -- */
       else if(0x2014 == n) putq('\227'); /* --- */
       else if(0x2018 == n) putq('\221'); /* \lq */
       else if(0x2019 == n) putq('\222'); /* \rq */
       else if(0x2020 == n) putq(134); /* dagger */
       else if(0x2021 == n) putq(135); /* double dagger */
       else if(0x2030 == n) putq('\x89'); /* elmilsigno */
       else goto no_win;
       return;
   no_win:;
   }
   if     (0x00a9 == n) putTexAsc("\\copyright{}", "(C)");
/*     else if(0x02dd == n) putTexAsc("\\H ", "\""); */
   else if(0x02dd == n)
       if(latex) putStr("\\H ");
       else putch('"');
   else if(0x2013 == n) putStr("--");
   else if(0x2014 == n) putStr("---");
   else if(0x2018 == n) putch('`');
   else if(0x2019 == n) putch('\'');
   else if(0x201c == n) putStr("``");
   else if(0x201d == n) putStr("''");
   else if(0x2190 == n) putMat("\\leftarrow", "<-");
   else if(0x2192 == n) putMat("\\rightarrow", "->");
   else if(0x2229 == n) putMat("\\cap", "*");
   else if(0x222a == n) putMat("\\cup", "+");
   else if(0x2260 == n) putMat("\\neq", "<>");
   else if(0x2261 == n) putMat("\\equiv ", "==");
   else if(0x2264 == n){
       if(TomeRaider) putStr("<=");
       else putMat("\\leqslant", "<=");
   }else if(0x2265 == n) putMat("\\geqslant ", ">=");
   else goto lasta_sxanco;
   return;
 lasta_sxanco:
   if(latex){
       if(putEuroLatTex(n)) return;
       if(0x2018 == n) putch('`');
       else if(0x2019 == n) putch('\'');
       else if(0x201c == n) putStr("``");
       else if(0x201d == n) putStr("''");
       else if(0x2020 == n) putStr(mmode ? "\\dagger " : "\\dag{}");
       else if(0x2021 == n) putStr(mmode ? "\\ddagger " : "\\ddag{}");
       else if(0x2030 == n) putStr("\\textperthousand{}");
       else if(0x2193 == n) putStr(ensureMathTex("\\downarrow"));
       else if(0x220f == n) putStr(ensureMathTex("\\prod"));
       else if(0x221a == n) putStr(ensureMathTex("\\surd"));
       else if(0x2211 == n) putStr(ensureMathTex("\\sum"));
       else if(0x2216 == n) putStr(ensureMathTex("\\setminus"));
       else if(0x2225 == n) putStr(ensureMathTex("\\Vert"));
       else if(0x2422 == n) putStr("{\\tt\\rlap/b}");
       else if(0x2423 == n) putStr("\\hbox{\\verb*. .}");
       else goto ho_ve;
       return;
   }else if(putEuroLatAscii(n)) return;
 ho_ve: fPutStr("[Unikode: 16u%X]", n); 
}

void putUniTex(const int n, const char* ss)
{
    if(uni) putUni(n);
    else putStr(ss);
}

void ensureMath(char* su, int unic, const char* tex, const char* alt)
{
    if(!su || strchr8(su, signaro)){
        if(!mmode) putStr(open_math_font);
        if(uni) putUni(unic);
        else{
            putStr(tex);
            if(mmode) putch(' ');
        }
        if(!mmode) putStr(close_math_font);
    }else putStr(alt);
}

const char* ensureMathTex(const char* tex)
{
    static char buf[32];
    if(sizeof(buf) < sprintf(buf, mmode ? "%s " : "\\(%s\\)", tex))
        eraro("ensureMathTex");
    return buf;
}

void putHTMLsym(char x)
{
    if(texi){
         if(x && strchr("{}@", x)) putch('@');
    }else if(x && TeX){
         if(strchr("{}", x)){
           fPutStr(mmode || pre ? "\\%c" : "\\char%d ", x);
           return;
         }
         if(strchr("&%#_", x) ||
            strchr("$", x) && !mmode && !pre) putch('\\');
         else{
             if(strchr("\\~", x)) fPutStr("{\\char%d}", x);
             else if(-3 != pre && !mmode && '^' == x) putStr("{\\char94}");
             else if(mmode && '÷' == x) putStr("\\div ");
             else goto more;
             return;
         }
    }else if(TomeRaider){
/*  	if('<' == x){ */
/*  	    putStr("\240<\240"); */
/*  	    return; */
/*  	} */
	goto more;
    }else{ 
	if('<' == x) putStr("&lt;");
	else if('>' == x) putStr("&gt;");
	else if('&' == x) putStr("&amp;");
	else goto more;
	return;
    }
  more:
    if(ns == x){
        if(!texi) penda_spaceto = 0;        
        if(latex) x = (mmode ? ' ' : '~');
        else if(center == align) x = ' ';
        if(uni) putUni(x);
        else putch(x);
        jxus_ns = x != ' ';
    }else if(uni) putUni(x);
    else putch(x);
}

void elsxutu()
{
    if(!keep_in_buffer && outpos){
        if(texi) fwrite(outBuf, 1, outpos, celo);
        else if(!make_depend){
            int i;
            for(i = 0; i < outpos; ){
                char c = outBuf[i++];
                if(lf == c && (i == outpos || !strchr(" \n", outBuf[i])))
		    putc(' ', celo);
                putc(c, celo);
            }
        }
        outpos = 0;
    }
}

void PUTC(char x)
{
    outBuf[outpos++] = x;
    if(outpos >= outBufLen) eraro("Bufra troo");
    if(lf == x) elsxutu();
}

int jxusa_spaceto = 0;

void check_line()
{
    if(out_linepos >= sojla_linilongo){
        if(jxusa_spaceto){
            outBuf[jxusa_spaceto - 1] = lf;
            out_linepos = outpos - jxusa_spaceto;
            jxusa_spaceto = 0;
        }else{
            PUTC(lf);
            out_linepos = 0;
        }
        elsxutu();
    }
    if(out_linepos > 0){
        PUTC(' ');
        jxusa_spaceto = outpos;
        ++out_linepos;
    }
}

char *sbrosBuf(int copy)        /* copy<0 => discard outBuf */
{
    char * res = 0;
    keep_in_buffer = freshPar = 0;
    align = defavxlto;
    if(copy > 0){
        res = malloc(outpos);
        if(0 == res) eraro("malloc == 0");
        outBuf[outpos] = 0;
        memcpy(res, outBuf, outpos);
    }else if(0 == copy) elsxutu();
    else pendaIkso = 0;
    jxusa_spaceto = outpos = 0;
    return res;
}

void putch(char x)
{
  unsigned i;
  prev_putch = x;
  if(kromkopiu < sizeof(krombufro) && (kromkopiu || ' ' != x))
     krombufro[kromkopiu++] = x;
  if(pendaIkso){
      pendaIkso = falso;
      putChar(x > 0 && isupper(x) ? 'X' : 'x');
  }
  if(lf == x){
      if(0 == out_linepos) return;
      x = 0;
  }
  if(!x){
      penda_spaceto = 0;
      PUTC(lf);
      out_linepos = jxusa_spaceto = 0;
      return;
  }
  if(penda_spaceto){
      check_line();
      penda_spaceto = 0;
  }
  switch(x){
     case' ':
         if(pre) break;
         if(!jxus_ns) penda_spaceto = vero;
         return;
     case hstroke:
         if( !kviete ){
             putStr(Html);
             return;
         }
     default:
         jxus_ns = 0;
         i = x & 0xff;
         if(i < ' ' && !((lf == i || '\t' == i) && kviete)){
             feraro("fremda signo-2: x=0%o, <<%c>> (ch=x=0%o, <<%c>>)\n",
                    i, i, ch, ch);
         }
   }
   if( pre ){
       out_linepos++;
       PUTC(x);
   }else{
      if(freshPar){
          if(TeX){
             if(right == align){
                 align = defavxlto;
                 if(texi) putStrq("@end flushright\012");
             }else{
                 putch(lf);
                 putch(0); 
                 out_linepos = 0;
             }
         }else{
             PUTC('<');
             if(align != defavxlto) PUTC('/');
             PUTC('p');
             PUTC('>');
             out_linepos += 4;
         }
         freshPar = 0;
         align = defavxlto;
      }
      out_linepos++;
      PUTC(x);
   }
}

char tabela_trankodo(char ch, char *tab1, char *tab2, int sz)
{
    int i = (ch & 255) - 160;
    char x;
    if(i < 0) eraro("misa LAT12");
    if(i >= sz) eraro("misa LAT21");
    x = tab2[i];
    if(' ' == x) return tab1[i];
    putHTMLsym(tab1[i]);
    return x;
}

void skribu(char ch)
{
    if('"' == ch){
        if(en_html_komando) putch('"');
        else if(mmode){
	    if(TomeRaider) putch('"');
	    else putUniTexSym(0x2033, "''", "''");
        }else if(IPA == lingvo){
            if('8' == signaro) putUni(0x2c8);
            else putch('"');
        }else{
            if(pre || verbatim || tt_ingado) goto P;
            if(uni || '1' == signaro)
		putUni(fermaCitilo ? 0273 : 0253);
            else if(win) putq(fermaCitilo ? '\223' : '\204');
            else if(latex)
                putStr(eo == lingvo? (fermaCitilo? "^>" : "^<") :
                       fermaCitilo ? "\\frqq{}" : "\\flqq ");
            else goto P;
            fermaCitilo = !fermaCitilo;
        }
        return;
    }
    if('°' == ch && mmode && latex){
        putStr("^0");
        return;
    }
    if(IPA == lingvo){
       if('%' == ch && '8' == signaro){
           putUni(0x2cc);
           return;
       }
       if('!' == ch){
           if('8' == signaro){
               putUni(0x2c8);
               return;
           }else ch = '"';
       }else if(uni || '1' == signaro){
           if('{' == ch){
               putUni(0xe6);
               return;
           }else if('D' == ch){
               putUni(0xf0);
               return;
           }else if(uni){
               if('N' == ch){
                   putUni(0x14b); return;
               }else if('¹' == ch){
                   putUni(0x12d); return;
               }
	   }
       }else{
	   static const char cxap[] = "æøþ¼³";
	   const char *x = strchr8(cxap, ch);
	   if(x){
	       if('³' == ch) putch('3');
	       else{
		   unsigned n = x - cxap;
		   if(n < 2) putch(n & 1 ? 'd' : 't');
		   putch(n & 1 ? 'Z' : 'S');
	       }
	       return;
	   }
       }
   }
   switch (signaro){
      case'3': case't':
          if(!askia(ch)){
              if(lat1 == lingvo)
                  ch = tabela_trankodo(ch, Lat1perLat3_1, Lat1perLat3_2,
                                       sizeof(Lat1perLat3_1));
              else if(lat2 == lingvo) eraro("lat2");  
          }
      break;
      case'T':
          if(eo == lingvo) break;
          if(rusa == lingvo){
              static char azbuko[] = "ABVGDE¬ZIJKLMNOPRSTUF¦CÆÞÇÌYÍÈÛÂ"
                  "abvgde¼zijklmnoprstuf¶cæþçìyíèûâ",
                  Slavono3[] = "ëËêÊúÚ";
              static const short SlavonoT2[] = {188, 156, 179, 147, 187, 155};
              const char *x = strchr8(azbuko, ch);
              if(x){
                  fPutStr("{\\char%d}", x - azbuko + 192);
                  return;
              }else{
                  x = strchr8(Slavono3, ch);
                  if(x){
                      fPutStr("{\\char%d}", SlavonoT2[x - Slavono3]);
                      return;
                  }
              }   
          }else if(lingvo <= lat2){ /* ankaý signoj kiel á, kie lat1 == lat2 */
              if(IPA == lingvo){
                  static char kl3f[] = "¹RýV", tipa[] = "IKU2";
                  const char *x = strchr8(kl3f, ch);
                  if(x){
                      ch = tipa[x - kl3f];
                      break;
                  }
                  if(putIpaTex(ch)) return;
              }
              if(putLat1TeX(ch)) return;
          }
      break;
      case'8':
          if(IPA == lingvo){
              const char *x = strchr8(SAMPA, ch);
              if(x){
                  putUni((int)(x - SAMPA) + 0x250);
                  return;
              }
          }else if(rusa == lingvo && (ch & 0x80)){
              if('ê' == ch){
                  putUni(0x463); return;
              }else if('Ê' == ch){
                  putUni(0x462); return;
              }
          } /* no break */
      case'2':
      case'4':
          if(ch & 0x80){
              if(lat1 == lingvo) break;
	      if('2' == signaro && rusa != lingvo){
		  put3or1 (ch);
		  return;
	      }
              putUni(unikodo_el_latina3[(ch & 255) - 0xa0]);
              return;
          }
      break;
      case'1':case'r':
	  if(!askia(ch)){
	      if(A_E && TomeRaider && 'ö' == ch){ /* Gödel, Königs. */
		  putch('o');
		  return;
	      }
	      if(lat1 == lingvo) break;
	      put3or1(ch);
	      return;
	  }
      break;
      } /* switch */
  P:  putHTMLsym(ch);
}

void skribuCxen(const char *s)
{
   while(*s){
       if(del == *s){           /* unukodo == lat1, vd "filtru" */
           if(del == *++s){
               putUni((*(s+1) << 8) | *(s+2));
               s += 3;
           }else{               /* unikodo < 256 */
               lingva L0 = lingvo;
               lingvo = lat1;
               skribu(*s++);
               lingvo = L0;
           }
       }else if(uni && '-' == *s)
           if('-' == *++s)
               if('-' == *++s){
                   ++s;
/*                     putStr("&#x2014;"); */
/*                 }else putStr("&#x2013;"); */
                   putUni(0x2014);
               }else putUni(0x2013);
           else putch('-');    
       else skribu(*(s++));
   }
}

void putStrL(const char *s, lingva L1)
{
   lingva L0 = lingvo;
   lingvo = L1;
   skribuCxen(s);
   lingvo = L0;
}

void presCxen(const char *s)
{
    while(*s){
        if(askia(*s)) putch(*s);
        else skribu(*s);
        s++;
    }
}

void putUniSym(int uniCode, const char *alt)
{
   if(uni || uniCode < 256 && ('1' == signaro || TomeRaider) ||
      latex && (lat1 == lingvo || lat2 == lingvo)) putUni(uniCode);
   else putStrL(alt, eo);
}

void putUniTexSym(int uniCode, const char *tex, const char *alt)
{
    if(latex) putStr(tex);
    else putUniSym(uniCode, alt);
}

void putUniSimple(int uniCode, const char *alt){
   if(uni) putUni(uniCode);
   else putStr(alt);
}

void putUni4Sym(char* su, int uniCode, const char* alt)
{
    if(strchr8(su, signaro)) putUni(uniCode);
    else if(texi) putStrL(alt, lingvo != IPA ? eo : IPA);
    else{
        putStr(TomeRaider?"<b>":"<strong>");
        putStrL(alt, lingvo != IPA ? eo : IPA); /* povas enteni <, &... */
        putStr(TomeRaider?"</b>":"</strong>");
    }
}

void putUni4TexSym(char* su, int uniCode, char* tex, const char* alt)
{
    if(latex) putStr(tex);
    else putUni4Sym(su, uniCode, alt);
}

void kopiuGxis(char x)
{
   do{
       putChar(ch);
       getch();
   }while (ch != x);
}

void transskribuGxis(char x)
{
   do{
       skribu(ch);
       getch();
   }while (ch != x);
}

void redakteKopiuGxis(char x, char d){
    int k;
    while (ch != x){
        if(hstroke == ch) putStr(Html);
        else{
            if('X' == d) ch = majuskligu(ch);
            k = cxapelnumero(ch);
            if(k >= 0){
                putChar(bazaj_literoj[k]);
                ch = d;
            }
            putChar(x && 0 == ch ? ' ' : ch);
        }
        getch();
    }
}

void Tehxe_elbufrigu(char* buf)
{
    for (; *buf; buf++){
        int k = cxapelnumero(*buf);
        if(k >= 0){
            *buf = bazaj_literoj[k];
            if('j' == *buf){
                putStr("\\^\\j ");
                continue;
            }
            putStr('u' == *buf ? "\\u " : "\\^");
        }
        putChar(*buf);
    }
}

void fermuOL()
{
  if(kursivo){
      eraro("nefermita kursivo");
      kursivo = falso;
  }
  if(fermaCitilo){
      eraro("nefermita citilo");
      fermaCitilo = falso;
  }
  if(graseto){
      eraro("nefermita graseto");
      graseto = falso;
  }
  if(mmode){
      eraro("nefermita <$>");
      mmode = 0;
  }
  if(align != defavxlto){
     freshPar = 0;
     if(menuo == align){
         putStr(texi ? "\012@end menu\012" : "</ol>");
         if(texi){
             menubufro[menubufro_i] = 0;
             memcpy(sekciindekso[ingonivelo++] = malloc(menubufro_i),
                    menubufro, menubufro_i);
             menubufro_i = 0;
         }
     }else if(texi){
         if(right == align) putStrq("\n@end flushright\n");
     }else if(!TeX) putStr("</p><p>");
     align = defavxlto;     
  }
  if('#' == parNro){
      if(texi) freshPar = 1;
  }else{
     if(penda_spaceto) putch(0);
     if(freshPar > 1)
         if(TeX){
             if(texi) freshPar = 1;
             else putch(lf);
         }else{
             putStr("<p>");
             freshPar = 0;
         }
     parNro = '#';
/*      putStrq(texi ? "\n@end enumerate\n" : TeX ? "\\end{ls}" : "</ol>"); */
/*      putStrq(texi ? "\n@end enumerate\n" : TeX ? "\\par" : "</ol>"); */
     if(latex) freshPar = 1;
     else{
         putStrq(texi ? "\n@end enumerate\n" : "</ol>");
         putch(0);
     }
   }
}

void nivelado(String w, String h)
{
     fPutStr(" align=\"%s\"", bannerNumber ? "top" : "bottom");
  /* putStr("\" height="); putStr(h);  putStr(" width="); putStr(w); */
     putStr("></a>");
}

void img_src(String s){
    fPutStr("<img src=\"%s", bildvojo);
    presCxen(s);
}

int enbufrigu(char* buf, const char gxis0, const char gxis1)
{
    while(gxis0 != ch){
        if(gxis1 == ch){
            *buf = 0;
            return 1;
        }
        *(buf++) = ch;
        getch();
    }
    return *buf = 0;
}

#ifdef KL
static void Cxapitro(int);
#endif

char nodes[9][goodlen] = {"", "", "EO"};
int node_i = 0, node_up = 2, tenu_buf_post_cxap = 0;

void banner()
{
  if(latex || TomeRaider){
      while(ch) getch();
      return;
  }
  getch();
  if(0 == bannerNumber){
    if(Hstroke == ch){
        mem1 = Hstroke;
        getch();
    }else if(',' == ch){
        getch();
        enbufrigu(nodes[node_up], ',', 0);
        sekciindekso[ingonivelo] = nodes[node_up];
        if(texi){
            ++ingonivelo;
            if(ch){
                keep_in_buffer = tenu_buf_post_cxap = 1;
 /*                postaskiigu(nodes[node_up], 'x', goodlen); !!! */
                fPutStr("@node %s", nodes[node_up]);
                kopiuGxis(0);

                enbufrigu(nova_cxeno, 0, 0);
                postaskiigu(nova_cxeno, 'x', goodlen);
                putStr(nova_cxeno);
                putch(0);
            }else getch();
        }else{
            if(TeX) exit(EXIT_FAILURE);
            fPutStr("<html%s><head>\n", !uni ? " lang=\"eo\"" : "");
            postaskiigu(nodes[node_up], 'h', goodlen);
            fPutStr("<title>%s%s</title>\n", titolo, nodes[node_up]);
            if(strchr("1248", signaro)){
                fPutStr("<META HTTP-EQUIV=\"Content-Type\" "
                        "CONTENT=\"text/html; charset=%s\">\n",
                        '1' == signaro ? "ISO-8859-1" : "UTF-8");
                if(uni){
                    fPutStr("<link rel=\"stylesheet\" type=\"text/css\" href=\"%s/kl.css\">",
                           bildvojo);
                }
            }
            putStr("\012</head><body>\012");
        }
        subbanner();
        return;
    }
    if(!texi){
        fPutStr("<html%s><head>\n", '1' == signaro ? " lang=\"eo\"" : "");
        fPutStr("<title>%s", titolo);
        if(ch){
            kopiuGxis(';');
            getch();
        }
        putStr("</title> <");
        if('3' == signaro) putStr("!--"); 
        putStr("META HTTP-EQUIV=\"Content-Type\" CONTENT=\"text/html");
        switch(signaro){
            case'1': putStr(";charset=ISO-8859-1\""); break;
            case'3': putStr(";charset=ISO-8859-3\"--"); break;
/*              case'3': putStr(";charset=ISO-8859-3\""); break; */
            case'2':
            case'4':
            case'8': putStr(";charset=UTF-8\""); break;
            default: putch('"');
        }
        putch('>');
        if('8' == signaro){
            fPutStr("<link rel=\"stylesheet\" type=\"text/css\" "
                   "href=\"%s/kl.css\">", bildvojo);
        }
        while(Hstroke == ch){
            getch();
            kopiuGxis(';');
            getch();
        }
        if('-' != ch) putStr("\n</head><body>\n");
    }
  }else if(texi) while(ch) getch();
  subbanner();
}
  
void filtru(const char finilo, const int senuskligu){
  /* ------- finas POST la fino se finilo=0!!! -------- */
   int n, i, k;
   Bulea sub, verb;
   n = i = 0;
   sub = verb = falso;
   for(;;){
       if(finilo){
           if(ch == finilo) break;
       }else if(!(
                  litero(ch) ||
                  '0' <= ch && ch <= '9' ||
                  '©' == ch  || 'Ô' == ch)) break;
       if(n == goodlen){
           cxeno[n] = 0;
           printf("\n\t finilo=0%o=%c, cxeno=<%s>\n", finilo, finilo, cxeno);
           eraro("tro longa kapvorto");
           break;
       }
       cxeno[n++] = ch;
       if(TomeRaider){
	   if(strchr("·*", ch)){
	       n-- ;
	       readch();
	       continue;
	   }
       }else if(strchr("·!*:\"()\'/=&;{}?\\", ch)){
           readch();
           continue;
       }
       assert(ch);
       switch(ch){
/*             case'·': */
/*                 if(!latex){ */
/*                     cxeno[n-1] = '\\'; */
/*                     cxeno[n++] = '·'; */
/*                 } */
/*                 readch(); */
/*                 continue; */
/*             case'-': */
/*                 if(dict || i && '-' != nova_cxeno[i - 1]) break; */
/*                 readch(); */
/*                 continue; */
/*             case 0 : */
/*                 cxeno[n - 1] = ' '; */
           case' ': case ns:
               if(!finilo) break;
               if(!sub && !verb)
		   nova_cxeno[i++] = (texi||dict||TomeRaider ? ' ' : '-');
               do readch(); while(' ' == ch);
               continue;
           case'_': --n; sub = !sub; readch(); continue;
           case del:        /* unikoda¼oj, vd "skribuCxen" */
               k = n - 1;
               if(uch <= 255) cxeno[n++] = uch;
               else{
                   cxeno[n++] = del;
                   cxeno[n++] = uch >> 8;
                   cxeno[n++] = uch & 255;
               }
               if(texi||dict||TomeRaider){
                   strncpy(nova_cxeno + i, cxeno + k, n - k - 1);
                   i += (n - k - 1);
                   ch = cxeno[n - 1];
               }else ch = '-';
               break;
           case'©':
               --n; verb = vero; nova_cxeno[i++] = 'i'; break;
           case'Ô':
               --n; verb = vero; nova_cxeno[i++] = 'o'; break;
       }
       if(sub || verb){
          readch();
          continue;
      }
      nova_cxeno[i++] = ch;
      readch();
   }
   if(0 == i) eraro("fusxa referenco");
   if(finilo){
       if(ankrofermilo == finilo){
           getch();
           while(litero(ch)){
               cxeno[n++] = ch;
               getch();
           }
       }
   }else{
       if(nova_cxeno[i-1] == 'n') --i;
       if(nova_cxeno[i-1] == 'j') --i;
   }
   cxeno[n] = nova_cxeno[i] = 0;
/*     if(TomeRaider) return; */
   if(texi){
       if(1 == i) nova_cxeno[0] = majuskligu(nova_cxeno[0]);
       else if(senuskligu && nova_cxeno[0] != minuskligu(nova_cxeno[0]) &&
               nova_cxeno[1] == minuskligu(nova_cxeno[1]))
               nova_cxeno[0] = minuskligu(nova_cxeno[0]);
   }else{
       if(senuskligu) while(i--) nova_cxeno[i] = majuskligu(nova_cxeno[i]);
       if(!dict) postaskiigu(nova_cxeno, 'x', sizeof(nova_cxeno));
   }
}

static void ankro()
{
  int i = 0;
  while(nova_cxeno[i]) putUni(nova_cxeno[i++]);
}

static void encitiligu(char* s)
{
        int i, m = strlen(s);
        for(i = m; i; --i) s[i] = s[i - 1];
        if(m){
            s[0] = '`';
            s[m + 1] = '\'';
            s[m + 2] = 0;
        }
}
        

static const char* hh[] = 
    {"cxapitro", "sekcio", "subsekcio", "subsubsekcio", "paragrafo"};
char NAME_buf[goodlen] = {0};            /* por hyperlink kaj NAME */

void NAME()
{
    static int nivelo, kombinu = 0, sojlo;

    if(finilo){
        if(TeX){
            if(texi){
                if(nivelo) sojla_linilongo = sojlo;
            }else unutipare = 0;
        }else{
            if(!kombinu) putStr("</a>");
            if(nivelo) fPutStr("</h%c>", nivelo);
        }
        NAME_buf[0] = 0;
        putch(lf);
        return;
    }
    kombinu = 0;
    if('1' <= ch && ch <= '5'){
        if(keep_in_buffer) sbrosBuf(0);
        nivelo = ch;
        getch();
    }else nivelo = 0;
    
    if('"' != ch) eraro("mankas citilo");
    else getch();

    filtru('"', 0);
    if(nivelo){
        fermuOL();
        if(TeX){
            int n = nivelo - '0' - 1;
            if(A_E) encitiligu(nova_cxeno);
            if(texi){
                char *prev, *self, *next;
                if(A_E) encitiligu(cxeno);
/*                  postaskiigu(cxeno, 'x', goodlen); */
                sojlo = sojla_linilongo;
                sojla_linilongo = 240;
                if(n < 2) n = 2;
            
                if(n < ingonivelo) ingonivelo = n;
                prev = sekciindekso[ingonivelo - 1];
                self = prev + strlen(prev) + 1;
                if(strcmp(cxeno, self))
                    feraro("menue: <%s>, fakte: <%s>, ingonivelo:%d",
                           self, cxeno, ingonivelo);
                else sekciindekso[ingonivelo - 1] = self;
                fPutStr("@node %s, %s, %s, %s\n@%s ",
                        cxeno, next = self + strlen(self) + 1, prev,
                        sekciindekso[ingonivelo - 2], hh[n - 1]);
            }else{
                unutipare = 1;
                assert(n > 0);
                fPutStr("\\%s{", hh[n - 1]);
            }
        }else fPutStr("<h%c>", nivelo);
    }
    strcpy(NAME_buf, nova_cxeno);
    getch();
    if(';' == ch && !latex){
        kombinu = 1;
        getch();
    }else{
        if(':' == ch){
            get_skip();
            cxeno[0] = 0;
        }
        if(TeX){
            int sojlo = sojla_linilongo;
            sojla_linilongo = 240;
            if(texi) putStr(cxeno);
            else{
              Tehxe_elbufrigu(cxeno);
              fPutStr("} \\label{%s}", nova_cxeno);
              if(';' == ch) putStr("\n%"); /* forkomentu duobla¼on */
            }
            sojla_linilongo = sojlo;
        }else{
            fPutStr("<a name=\"%s\">", nova_cxeno);
            skribuCxen(cxeno);
            if (',' != ch){      /* <Ñ>2"Sepbitaj kodoj"</Ñ> */
/*                 putStr(cxeno); */
                return;
            }
        }
    }
    if(',' == ch) getch();
    else skip();
}

void etna_lingvo(lingva l, String s);

void uniGreka()
{
    static const short uni1Greka[] = {
/*A     B    C  D     E     F     G     H     I    J  K     L     M     N O */
 0x391,0x392,0,0x394,0x395,0x3a6,0x393,0x397,0x399,0,0x39a,0x39b,0x39c,0x39d
,0x39f
/*P    Q  R     S     T     U    V  W     X    Y  Z    [ \ ] ^ _ */
,0x3a0,0,0x3a1,0x3a3,0x3a4,0x3a5,0,0x3a9,0x39e,0,0x396,0,0,0,0,0
/*`   a     b     c     d     e     f     g     h     i    j  k     l     mno*/
,'`',0x3b1,0x3b2,0x3c2,0x3b4,0x3b5,0x3c6,0x3b3,0x3b7,0x3b9,0,0x3ba,0x3bb,0x3bc
,0x3bd,0x3bf
/*p    q  r     s     t     u    v w  x    y  z      {    | } ~  */
,0x3c0,0,0x3c1,0x3c3,0x3c4,0x3c5,0,0,0x3be,0,0x3b6,0x201b,0,0x2019  };

    static const short uni2Greka[] = {
/*    ¡  ¢  £  ¤  ¥  ¦     § ¨   ©     ª « ¬ ­ ® ¯ */
  ns, 0, 0, 0, 0, 0,0x3a7, 0,0, 0x397, 0,0,0,0,0,0,

/* ° ± ² ³  ´   µ  ¶    · ¸ ¹ º » ¼ ½ ¾ ¿ */
   0,0,0,0,0xb4,0,0x3c7,0,0,0,0,0,0,0,0,0

/*À     Á     Â     Ä Å Æ Ç  È     É     Ê     Ë     Ì     Í     Î     Ï */
,0x386,0x386,0x386,0,0,0,0,0,0x388,0x388,0x388,0x397,0x38a,0x38a,0x38a,0x3aa

/*Ð Ñ  Ò     Ó     Ô    Õ  Ö    × Ø  Ù     Ú     Û     Ü    Ý Þ ß */
 ,0,0,0x38a,0x38a,0x38a,0,0x3a9,0,0,0x38e,0x38e,0x38e,0x3ab,0,0,0x3b2

/*à     á     â     ä å æ ç  è     é     ê     ë     ì     í     î     ï */
,0x3ac,0x3ac,0x3ac,0,0,0,0,0,0x3ad,0x3ad,0x3ad,0x3b7,0x3af,0x3af,0x3af,0x3ca
/*ñ  ò     ó     ô    õ  ö    ÷ ø  ù     ú     û     ü    ý þ ÿ */
,0,0,0x3cc,0x3cc,0x3cc,0,0x3c9,0,0,0x3cd,0x3cd,0x3cd,0x3cb };

    static const char *Tex1Greka[] = {
        "A", "B", 0, "\\Delta ", "E", "\\Phi ", "\\Gamma ", "H",
        "I", 0, "K", "\\Lambda ", "M", "N", "O", "\\Pi ", 0, "P", "\\Sigma ",
        "T", "\\Upsilon ", 0, "\\Omega ", "\\Xi ", 0, "Z",0,0,0,0,0,
        "`", "\\alpha ", "\\beta ", 0, "\\delta ", "\\varepsilon ", "\\phi ",
        "\\gamma ", "\\eta ",
        "\\iota ", 0, "\\kappa ", "\\lambda ", "\\mu ", "\\nu ",
        "o", "\\pi ", 0, "\\varrho ", "\\sigma ", "\\tau ", "\\upsilon ", 0,
        "\\omega ", "\\xi ", 0, "\\zeta ",0,0,0};
    static const char duliterajxo1[] = "PRTprt", duliterajxo2[] = "shhshh";
    static const char *duTex[] = {
        "\\Psi ", "P", "\\Theta ", "\\psi ", "varrho ", "\\theta "
    };
    static const short duUni[] = {0x3a8, 0x3a1, 0x398, 0x3c8, 0x3c1, 0x3b8};
    static const char source_accent[] = "´^\\";

    char *cc, sia_mmode = 0, *i;
    
    if(uni || latex){
        if(sia_mmode = !mmode && latex) putStr("\\(");
        while(ch != '<'){
            if(i = strchr(source_accent, ch)){
                static const char* akcento[] = {"\\acute","\\grave","\\hat"};
                readch();
                if(latex) putStr(akcento[i - source_accent]);
                if(jo == ch) putUniTex(0x3ae, "\\eta ");
                else if(Jo == ch) putUniTex(0x389, "\\Eta ");
                else if(oe == ch) putUniTex(0x3ce, "\\omega ");
                else if(Oe == ch) putUniTex(0x38f, "\\Omega ");
                else eraro("nekonata greka diakritajxo");
                readch();
        }else if( askia(ch) ){
            if( isalpha(ch) || strchr("{}", ch) ){
                if(tolower(ch) == 'h' || '{' == ch){
                    if(uni) putUni(0x201b);
                    else putch('`');
                    readch();
                }else if(ch && (cc = strchr(duliterajxo1, ch))){
                    int i = cc - duliterajxo1;
                    getch();
                    if(duliterajxo2[i] == ch){
                        getch();
                        putUniTex(duUni[i], duTex[i]);
                    }else putUniTex(uni1Greka[*cc-'A'], Tex1Greka[*cc-'A']);
                }else{
                    putUniTex(uni1Greka[ch-'A'], Tex1Greka[ch-'A']);
                    readch();
                }
            }else{
                if(!strchr8("\\{}^´\'", ch)) putch(ch);
                readch();
            }
        }else{
            if(uni) putUni(uni2Greka[abs(ch - ns)]);
            else if(latex){
                static const char L3Greka[] = "áßëîóÖ";
                static const char *Tex1Greka[] = {
                    "\\acute{\\alpha}", "\\beta{}", "\\eta{}", "\\hat{\\iota}",
                    "\\acute{o}", "\\Omega{}"
                };
                const char *i = strchr8(L3Greka, ch);
                if(i) putStr(Tex1Greka[i - L3Greka]);
                else putch(ch);
            }else if(!strchr8("\\{}^´\'", ch)) putch(ch);
            readch();
        }
	  }
	}else{
	  etna_lingvo(eo, "el");
	  while(ch != '<'){
		if(!strchr8("\\{}^´\'", ch)) putch(ch);
		readch();
	  }
	}
    getch();
    elemento();
    if(sia_mmode) putStr("\\)");
	if(!uni && 'T' != signaro) etna_lingvo(eo, "el");	  
}

void getchup()
{
    getch();
    ch = toupper(ch);
}


int unikodono()
{
   int n = 0;
   getchup();
   if('X' == ch)
       for(;;){
           getchup();
           if(!isxdigit(ch)) break;
           n = n * 16 + ch - (isdigit(ch) ? '0' : 'A' - 10);
       }
   else if('O' == ch)
       for(;;){
           getch();           
           if(isdigit(ch) && ch < '8') n = n * 8 + ch - '0';
           else break;
       }
   else while( isdigit(ch) ){
       n = n * 10 + ch - '0';
       getch();
   }
   if(n > 0xffff) eraro("tro longa kodono");
   if('³' == ch){
       getch();
       if(0xa0 > n || 255 < n) eraro("misa Latin-3ajxo");
       else if('3' == signaro || latex){
           skribu( (char)n );
           return 0;
       }
       n = unikodo_el_latina3[n - 0xa0]; 
   }else preterkontrolu(';');
   return n;
}

void bibliografio()
{
    int surlinie = 0 != kromelemento;
    int difino = ':' == kromelemento;
    
    if(latex && !surlinie){
            penda_spaceto = 0;
            putStr("\\f");        
    }
    if(!difino && !TomeRaider) putch('[');
    for(;;){
        if('\\' == ch){         /*  no hyperlink  */
            if('T' != signaro) getch();
	    if(!difino && TomeRaider) putch('{');
            do{
                putch(ch);
                getch();
            }while(isalnum(ch));
	    if(!difino && TomeRaider) putch('}');
        }else{
            int asis = '=' == ch;
            if(asis) getch();
            filtru(0, 0);
            if(TeX){
                if(!asis && latex) putch('\\');
                putStr(cxeno);
            }else if(difino){
		if(TomeRaider) fPutStr("\n<new>{%s} ###",nova_cxeno);
		else fPutStr("<a name=\"%s\">%s</a>",nova_cxeno,cxeno);
            }else if(TomeRaider) fPutStr("<a>{%s}</a>",cxeno);
	    else fPutStr("<a href=\"BIB.%s#%s\">%s</a>",Html,nova_cxeno,cxeno);
        }
        if(',' == ch){
            getch();
            skip();
            if(surlinie || 'T' != signaro) putStr(", ");
            continue;
        }
        break;
    }
    if('<' == ch){
        getch(); elemento();
    }
    if(!difino && !TomeRaider) putch(']');
}    /* bibliografio */

void bildo(String dosiero, String alt, String align, int w, int h){
    img_src("/");
    fPutStr("%s\" align=\"%s\" alt=\"", dosiero, align);
    putStrL(alt, eo);
    putch('"');
/*     if(w && h) fPutStr(" width=%d height=%d", w, h); */
}

static void pikto(String dosiero, String alt, String align, int w, int h)
{
    if(TomeRaider) fPutStr("<i>%s</i>", alt);
    else if(texi) fPutStr("<%s>", alt);
    else{
        putStr("<I>");
        bildo(dosiero, alt, align, w, h);
        putStr("></I>");
    }
}

static int marko(String alt1, String dosiero, String alt2, String align,
                  int w, int h)
{
    if (TomeRaider){
	putStr("<b><a:#mll>");
	putStrL(alt1, eo);
	putStr("</a></b>");
    }else if(A_E || latex || !dosiero){
        if(TeX) fPutStr("{\\it %s}", alt1);
        else{
            putStr("<i>"); putStrL(alt1, eo); putStr("</i>");
        }
    }else pikto(dosiero, alt2, align, w, h);
    return 0;
}

static int texi_element()
{
    char X = ch, x = tolower(ch), noindent = 0;
    if('b' == x){
        if('r' == get_low()) putch(0);
        else if('>' == ch){
/*             if(!mmode)    */           /* tex?? */
                if(finilo) putch('}'); /* end bold */
                else putStr(texi ? "@b{" : "{\\bf ");
        }
    }else if('d' == x){
        if('l' == get_low()){
            putch(lf);
            if(finilo){
                putStr(texi ? "@end table\n" : (noindent = 1,"\\end{dl}"));
                putch(0);
            }else putStr(texi ? putch(0),"@table @asis\n" : "\n\\begin{dl}\n");
        }else if('t' == ch) putStr(texi ? "\n@item " : "\n\\dt{");
        else if('d' == ch){     /* <dd> */
            penda_spaceto = 0;
            putch(texi ? lf : '}');
        }else return 0;
    }else if('h' == x){
        static int sojlo_hh;
        putch(lf);
        if(finilo){
            sojla_linilongo = sojlo_hh;
            if(latex) putch('}');
        }else{
            sojlo_hh = sojla_linilongo;
            sojla_linilongo = 240;
            getch();
            if('1' <= ch && ch <= '5'){
                if('1' == ch) ch = '2';
                fPutStr(texi ? "\n@%s " : "\n\\%s{", hh[ch - '2']);
            }else eraro("misa <h");
        }
    }else if('i' == x){
        if(strchr("> ", get_low())){
            if(finilo) putch('}');
            else putStr(texi ? "@kbd{" : "\\textit{");
        }
    }else if('s' == ch){ /* S restu por "laývorta" trastreko */
        if('>' == get_low())
            if(finilo){
                putch('}');
                --makrooingado;
            }else{
                escTexStr("evi{");
                ++makrooingado;
            }
        else if('t' == ch); /* <strong> */
        else if('u' == ch){
            if(finilo) putch(texi ? ']' : '}');
            else{
                fPutStr("%s%c", 'b' == get_low() ? "_" : texi ? "^" : "\\SUP",
                       texi ? '[' : '{');
            }
        }else return 1;
    }else if('t' == x){
        if(strchr("hd", get_low())){
          if(texi) putStr("\n@tab ");
          else putch('&');
        }else if('t' == ch){
            if(finilo) putch('}');
            else putStr("@t{");
        }
    }else if('u' == x){
        if('l' == get_low()){
            putch(lf);
            if(finilo){
                if(texi){
                    putStr("@end itemize\n");
                    putch(0);
                }else putStr((noindent = 1,"\\end{ul}\n"));
            }else{
                if(texi){
                    putch(0);
                    putStr("@itemize @minus\n");
                }else putStr("\\begin{ul}\n");
            }
        }else if(finilo) putch('}'); /* end underline */
        else putStr(texi ? "@b{" :
                    'U' == X ? "\\underline{" :
                    mmode ? "\\boxed{" : "\\fbox{");
    }else if('v' == x){
        if(finilo) putch('}'); 
        else escTexStr("var{");
    }else return 0;
    while('>' != ch) getch();
    getch();
    if(noindent && ch) putStr("\\noindent ");
    return 1;
}

static int tr_element()
{
    char X = ch, x = tolower(ch), noindent = 0;
    if('#' != parNro && 'u' == x){
        if('l' == get_low()){	/* TR ne scipovas ingitajn listojn */
	    goto fermilo;
	}
	goto kopiu;
    }else if('d' == x){
        if('l' == get_low()){
            putch(lf);
            if(finilo){
                putStr("<p>");
            }else putStr("<p>\n");
	    goto fermilo;
        }
	if('t' == ch){
/*  	    putStr("\n<br>\x9b"); */
	    putStr("\n<br>");
	    goto fermilo;
	}
        if('d' == ch){     /* <dd> */
	    penda_spaceto = 0;
/*  	    putStr("\x8b \x97 "); */
	    putStr(" \x97 ");
	    goto fermilo;
        }
	return 0;
    }else if('s' == ch){ /* S restu por "laývorta" trastreko */
        if('>' == get_low()){
	    getch();
	    putStr(finilo ? "(?)</i>" : "<i>");
	    goto jes;
	}
	goto kopiu;
    }else return 0;
 fermilo:
    do getch();
    while(isalpha(ch) || ' ' == ch); preterkontrolu('>');
 jes:
    return 1;
 kopiu:
    putch('<');
    if(finilo) putch('/');
    putch(X);
    do{
	putch(ch);
	getch();
    }while('>' != ch);
    putch('>');
    getch();
    return 1;
}

static speco elemento()
{
    speco rez = html;
    int i;
    finilo = falso;
    atributoj_de_elemento[0] = 0;
    if('/' == ch){
        getch();
        finilo = vero;
    }
  kopiu:
    if(askia(ch) && isalpha(ch)){
        if(TeX && texi_element()) return rez;
        if(TomeRaider && tr_element()) return rez;
        putch('<');
        if(finilo) putch('/');
        while(ch != '>'){
            if(hstroke == ch) putStr(Html);
            else if(sozo == ch) putStr(bildvojo);
            else putChar(ch ? ch : ' ');
            getch();
        }
        putch('>');
    }else if('!' == ch){        /* komento */
        for (i = 2; i; i--){
            getch();
            if(ch != '-') eraro("misa komento");
        }
        for(i = 0; !dosierfino;){
            getch();
            if('>' == ch){
                if(i > 1) break;
            }else if(ch != '-') i = 0;
            else ++i;
        }
    }else {                     /* KL-direktivo */
        if(!finilo) stako[stakind++] = ch;
        else if(stakind < 1) eraro("stakmaltroo");
        else if(stako[--stakind] != ch) eraro("misa ingado");
        switch(ento = ch){
            case 'Õ'  : rez = alg; break;
            case acirc: rez = anglete; break;
            case '['  : rez = bibref; break;
            case '©'  : rez = bildego; break;
            case duono: rez = centra; break;
            case  Cz  : rez = Cirile; break;
            case  cz  : rez = cirilete; break;
            case 'å'  : rez = ccode; break;
            case 'Å'  : rez = code; break;
            case Mo   : rez = Detaloj; break;
            case '@'  : rez = egale; break;
            case '?'  : rez = evi; break;
            case ']'  : rez = fon; break;
            case  gx  : rez = germane; break;
            case gpunkto:rez = grafiko; break; /*  g.  */
            case gh   : rez = greke; break;   /*  g(  */
            case 'Ñ'  : rez = hname; break;
            case '¹'  : rez = inlineimg; break;
            case '\'' : rez = l1; break;
            case '³': rez = l3; break;
            case '£': rez = lang; break;
            case ':': rez = kapvorta; break;
            case '$': rez = mat; break;
            case 'ñ': rez = name; break;
            case '~': rez = nego; break;
            case '"': rez = quote; break;
            case '{': rez = scope; break;
            case 'ª': rez = sintakso; break;
            case ';': rez = subkapa; break;
            case '§': rez = subunit; break; /* subsection, for texi menu */
            case '#': rez = tabelo; break;
            case 'ù': rez = url; break;
            case 'Ù': rez = Url; break;
            case '×': rez = xref; break;
            default :
                if(isdigit(ch)) rez = numero;
                else eraro("nekonata elemento");
        }
        getch();
        kromelemento = 0;
        if('>' != ch){
            if(isalpha(ch) && askia(ch)) goto kopiu; /* por </²i> */
            if(!isspace(ch)){
                kromelemento = ch;
                getch();
            }
            if(isspace(ch)){        /* por <# bgcolor=white> */
                atributoj_de_elemento[0] = ' ';
                skip();
                for(i = 1; '>' != ch; i++){
                    atributoj_de_elemento[i] = ch;
                    getch();
                }
                atributoj_de_elemento[i] = 0;
            }
        }
        skip();
    }
    preterkontrolu('>');
    return rez;
}

Bulea kajo()                /* liveras 0 se restas cxe signo jam traktita */
{
   int n;
   getch();
   switch(ch){
   case'#' :
       n = unikodono();
       if(n) putUni(n);
       return vero;
   case Hstroke :
       banner();
       return vero;
   case'ª' : return marko("Arto", "beletro.gif","Beletro:", "bottom",16,16);
   case'µ' : pikto("b-v.gif","Bulgakova¼o:", "bottom",32,20); break;
   case Ecirc:
       if('8' == signaro) putUni(0x2607);
       else return marko("Elektro","elektro.gif","Elektro:","bottom",34,16);
       break;
   case sozo:  return beto;
   case'?' : return marko("Evi.", "evi.gif", "Evitinde", "middle",16,16);
   case'º' : return marko("Filoz.", "filoz.gif","Filozofio:", "bottom",16,16);
   case'¿' :
       if('8' == signaro){
	   putUni(0x2622);
	   break;
       }
       return marko("Fiz.", "fiziko.gif","Fiziko:", "bottom",32,32);
   case'»' :
       if(latex){
           putStr("\\GUI ");
           break;           
       }
       return marko("GUI", "gui.gif", "GUI:", "bottom",16,16);
   case Jx : return marko("Jur.", "juro.gif","Juro:", "middle",36,33);
   case Hx : pikto("kemio.gif","¦emio:", "bottom",32,32); break;
   case Cz : return marko("Kino","kino.gif","Kinarto:", "bottom",32,32);
   case Mo : fPutStr("%s¤ %s", latex ? "{\\bf" : open_bold, close_bold); break;
   case'%' : return marko("Komp.", "komput.gif","Komp.:", "bottom",32,32);
   case'£' : return marko("Lib.", "libroj.gif","Lib.:", "bottom",23,12);
   case'÷' :
       if(!A_E || strchr("3rt", signaro))
	   return marko("Mat.", "mat.gif", "Mat.:", "bottom", 32, 20);
       putUni(0xb1); break;
   case'*' : pikto("mit.gif","Mito:", "bottom",32,20); break;
   case'Ö' :
       if(uni){
           putStr("<b>"); putUni(0x2126); putStr("</b>");
       }else return marko("Op.", "op.gif", "Operaciume:", "bottom",16,12);
       break;
   case';' :
       if(uni || latex) putUni(0x220F);
       else return marko("(;)", "pascal.gif","Programlingve:","bottom",32,32);
       break;
   case'@' :
       if(TomeRaider) putStr("<a:#mll><b>@</b></a>");
       else if(A_E) putStr("<b>@</b>");
       else return marko("Ret.", "retoj.gif", "Retoj:", "bottom",32,28);
       break;
   case')' :
       if('8' == signaro) ensureMath(0, 0x263a, 0, 0);
       else if(TeX) putStr(texi ? ":-)" : "\\rideto{}");
       else pikto("ridm.gif",":-)", "bottom",15,15);
       break;
   case hstroke : return marko("Te¶n.", "tehx.gif","Te¶nike:", "bottom",32,32);
   case'©' :
       if('8' == signaro) putUni(0x2656);
       else return marko("His.", "turo.gif","Historio:", "bottom",24,24);
       break;  
   case'\\':                  /* kopiu sen redakti */
   {
       char gxis;
       int sojlo = sojla_linilongo;
       sojla_linilongo = 240;
       getch();
       gxis = ch;
       getch();
       kopiuGxis(gxis);
       sojla_linilongo = sojlo;
       break;
   }
   default :
       if( isdigit(ch) ){
           hyperlink(ch);
           return vero;
       }
       if((TeX || TomeRaider) && isalpha(ch)){
           char *i, *inicialoj = "aglq";
           if(i = strchr(inicialoj, ch)){
               ch = "&><\""[i - inicialoj];
               if(TomeRaider || texi) putch(ch);
               else if('&' == ch) putStr("\\&");
               else if('"' == ch) putch('"');
               else if(mmode || pre || tt_ingado) putch(ch);
               else fPutStr("$%c$", ch);
               do getch(); while(';' != ch);
               return 0;
           }
       }   
       putch('&'); putch(ch);
   }
   return 0;
}

void etna_lingvo(lingva l, String s)
{
    kviete = !finilo;
    if(kviete){
        if(!mmode){
            if(texi) putStr("@kbd{");
            else if(uni) putStr("<i>"); /*MSIE mistraktas ligaturojn kaj tiparojn*/
            else if(TomeRaider) putStr("<i>");
	    else fPutStr(TeX ? "\\%s{" : "<i lang=\"%s\">", s);
        }
        lStako[ll++] = lingvo;
        lingvo = l;
    }else{
        lingvo = lStako[--ll];
        if(!mmode) putStr(TeX ? "}" : "</i>");
    }
}

void kopiu_ref() {
        char gxis = ch;
        getch(); 
        if(TeX || TomeRaider) while (gxis != ch) getch();
        else redakteKopiuGxis(gxis, 'X');
        preterkontrolu(gxis);
}

void ref(char filter_delimiter, int mnemo) {
    int alt = 0;
    
    if(strchr("\"'", ch)){
        kopiu_ref();
        if(',' == ch) getch();
        else if(';' == ch){
            getch();
            alt = 1;
        }
    }
    skip();        /* Por komenci per citilo, ensxovu spaceton */
    if('|' == ch){
        getch();
        if(!TeX){
            while('<' != ch) getch();
            putStr("\">");
        }
        return;
    }
    filtru(filter_delimiter, 0);    
    if('<' != ch) getch();
    if(TeX || TomeRaider){
        if(latex) putStr(nova_cxeno);
	else{
            if(A_E) encitiligu(cxeno);
            skribuCxen(cxeno);
        } 
    }else{
        if(alt) putStr("\">");
        else fPutStr("#%s\">", nova_cxeno);
        if(mnemo) skribuCxen(cxeno);
    }
}

void SUBSECTION() {
    if(finilo){
        if(latex) sbrosBuf(-1);
        if(!TeX) putStr("</a>");
        return;
    }
    if(keep_in_buffer) sbrosBuf(0);
    if('@' == ch){
        A_E = 1;
        getch();
    }
    putch(lf);
    if(menuo != align){
        if(latex) keep_in_buffer = 1;
        fermuOL();
        putStr(texi ? menubufro[menubufro_i++] = 0,"@menu\012" : "<ol>");
        align = menuo;
    }    
    putStr(texi? "\012* " : "<li><a href=\"");
    ref(':', 1);    
    if(texi){
        int i;
        for(i = 0; menubufro_i < sizeof(menubufro);){
            if(0 == (menubufro[menubufro_i++] = cxeno[i++])) break;
        }
        putch(':');
        if('<' == ch) putch(':');
    }
}

void DETALOJ() {
    if(finilo){
        if(latex || TomeRaider) sbrosBuf(-1);
        else{
            if(TeX) putStr("}.");
            else{
                img_src("/detaloj.gif\" alt=\"Detaloj\" border=0></a>");
            }
            putch(lf);
            freshPar = 1;
            if(dict) putStr("-->");
        }
    }else{
        if(!TeX && !TomeRaider) freshPar = 1;
        fermuOL();
        if(dict) putStr("<!--");
        if(latex||TomeRaider){
          sbrosBuf(0);
          keep_in_buffer = 1;
        }
        putStr(texi? "Detalojn vd en @ref{" : TeX? "Vd \\ref{" : "<a href=\"");
        if('"' == ch) ref('<', 0);
        else{
            if(texi) eraro("malplena referenco");
            kopiu_ref();
            putStr("\">");
        }
    }
}

void XREF() {
    if(finilo)
        if(TeX) putch('}');
        else putStr("</a>");
    else{
	putStr(texi ? "@pxref{" : TeX ? "pø~\\pageref{"
	       : TomeRaider? "<a>§" : "<a href=\"");
	ref('<', 1);
    }
}
    

void tabelelemento(int open, char* texie,  char* htmle,  char* atr) {
    if(TeX || TomeRaider){
        if(texi) fPutStr(texie);
        else if(latex){
            if(open && '½' == ch){
                putStr("\\begin{center}");
                align = center;
            }
            putStr(open ? (en_tabelo = -1,"\\noindent\\begin{tabular}") : "&");
        }
        while(ch && strchr8("½+0", ch)){
/*             if('0' == ch && !open) return; */
            getch();
        }
    }else{
        fPutStr(htmle, atr);
        if(duono == ch){
            putStr(" align=\"center\"");
            getch();
        }else if('+' == ch){
            putStr(" align=\"right\"");
            getch();
        }
        if(open){
            if('0' == ch) getch();
            else putStr(" border=2");
        }
        putch('>');
    }
}


void URL(int fora)
{
    char buf[99];
    int i;
    static int title;
    

    if(finilo){
        if(TeX) putch('}');
	else if(TomeRaider){
	    if(title) putch(')');
	    else putStr("</i>");
        }else putStr("</a>");
        return;
    }
    title = 0;
    if('"' != ch) eraro("mankas citilo");
    else getch();

    if(TeX) escTexStr("url{");
    else if(TomeRaider) putStr("<i>");
    else putStr(fora? "<a class=\"fora\" target=\"_top\" href=\"" :
                "<a href=\"");
    
    for(i = 0; '"' != ch; i++){
        if(sizeof(buf) == i) eraro("longa url");
        if(hstroke == ch){
            putStr(Html);
        }else{
            buf[i] = ch;
            if(latex || TomeRaider) putch(ch);
            else skribu(ch);
        }
        getch();
    }
    buf[i] = 0;
    getch();
    if(!TeX && !TomeRaider) putStr("\" >");
    if(',' == ch){
	title = 1;
        get_skip();
        if(TeX) putStr(texi ? ", " : "} \\urlend{");
	else if(TomeRaider) putStr("</i> (");
        return;
    }
    if(!TeX && !TomeRaider) skribuCxen(buf);
}

void malfermu_celon(char* nomo)
{
    char buf[80], *r;

    for(r = nomo; *r; r++) *r = toupper(*r);
    mem1 = nomo[0];
    mem2 = nomo[1];
    if(!isalnum(mem2)) mem2 = '.';
    else if(r - nomo > 3) mem2 = '\377';
    
    if(make_depend) printf("%s ", nomo);
    else{
        sprintf(buf, "../%s/%s.%s", Html, nomo, Html);
        if(NULL == (celo = fopen(buf, "w"))){
            printf("mi ne sukcesis krei la celdosieron <%s>\n", buf);
            exit(EXIT_FAILURE);
        }
    }
}

int checkarg (int argc, char *argv[])
{
  int i;
  if (argc < 2) return 0;
  for(i = 1; i < argc; i++){
    if('/' == argv[i][0]) DOS = 1;
    else if('-' == argv[i][0]) DOS = 0;
    else{
      if (0 == strlen(argv[i])) return 0;
      strcpy(Name, argv[i]);
      continue;
    }
    switch (argv[i][1]){
    case '1': case '2': case '3': case '4': case '8':
    case 'T': case 't': case 'r':
      signaro = argv[i][1];
      break;
    case 'd':
      dekume = 1;
      break;
    case 'D':
      dict = 1;
      signaro = '8';
      break;      
    case 'M':
      make_depend = 1;
      signaro = '8';
      break;      
    case 'w':
      win = 1;
      break;
    case 'b':
      strcpy(bildvojo, argv[++i]);
      break;
    default:
      return 0;
    }
  }
  if(!signaro || !strchr("12348Ttr", signaro)) return 0;
  return 1;
}

main(int argc, char *argv[]){   /* ------------------------- */

    erarnombro = jxus_ns = uni = TomeRaider = 0;
    DOS = 0;
    signaro = 0;
    dekume = dict = win = texi = 0;
    if (!checkarg(argc,argv)) goto formato;

    latex = ('T' == signaro);
    texi = ('t' == signaro);    
    TeX = texi | latex;
    if(strchr("248", signaro)){
        uni = 1;
        open_math_font = "<em>";
        close_math_font = "</em>";
    }else if('r' == signaro){
/*  	signaro = '1'; */
	TomeRaider = 1;
        open_math_font = "";
        close_math_font = "";
#ifdef KL
            kv1egale = kv1evi = kv1 = kv1n = "\n<new>";
            kv2evi = " (?)###";
            kv2 = kv2egale = "###",
            kv2n = kv2sub = "###";
            kv1sub = "<new>";
#endif        
    }else if(TeX){
        if(texi){
            open_bold = "@b{";
            open_math_font = "@math{";
            close_math_font = "}";
#ifdef KL
            kv1egale = "@kveq{";
            kv1evi = "@kvevi{";
            kv1 = "@kv{";
            kv1n = "@kvn{";
            kv2n = ",";
            kv1sub = "@kvsub{";
#endif        
        }else{
            open_bold = "{\\bfseries ";
            open_math_font = "\\(";
            close_math_font = "\\)";
#ifdef KL
            kv1egale = "\\kveq{";
            kv1evi = "\\kvevi{";
            kv1 = "\\kv{";
            kv1n = "\\kvn%c{";
            kv2n = "}";
            kv1sub = "\\kvsub{";
#endif        
        }
#ifdef KL
        kv2 =  kv2sub = kv2egale = kv2evi = "}";
#endif        
        close_bold = "}";
    }
    
    Html = (texi? "texi": TeX? "ltx": TomeRaider? "txt": DOS? "htm": "html");
    if(NULL == (fonto = fopen(Name, "r"))){
        printf("mi ne sukcesis malfermi la fontdosieron <%s>\n", Name);
        goto halt99;
    }
    dosierfino = falso;
    lininumero = outpos = out_linepos = keep_in_buffer = 0;
    while (Name[lininumero] && Name[lininumero] != '.')
        for(;;lininumero++){
            ch = Name[lininumero];
            if(0 == ch || '.' == ch) break;
            Name[lininumero] = toupper(ch);
        }
    Name[lininumero] = 0;
    A_E = unutipare = !strcmp(Name, "AN-INDEX");
    malfermu_celon(Name);
    freshPar = ll = en_html_komando = 0;
    clearall = en_tabelo = fermaCitilo = graseto = pre = prev_putch =
        sintakse = kursivo = lvert = make_depend = mmode = kviete =
        pendaIkso = penda_spaceto = verbatim = 0;
    parNro = '#';
    align = defavxlto;
    linio[0] = 0;
    bannerNumber = lininumero = linipoz = outLen = stakind = 0;
    getch();
    cxefciklo('\004');

#ifdef KL
    Cxapitro(-1);
#endif        
    sbrosBuf(0);
    if(bannerNumber && !make_depend) fclose(celo);
    fclose(fonto);
    if(!make_depend){
        if(texi && angla_nombrilo)
            printf("\n%d terminoj anglaj\n",angla_nombrilo);
        else printf("%d\n", artikolnombrilo);
    }
 halt99:
    exit(erarnombro ? EXIT_FAILURE : EXIT_SUCCESS);
 formato:
    eraro(
 "komanda linio:\tkl [{-/}{dw}] [{-/}b bildvojo] {-/}{12348DMTtr} nomo.utf\n"
          "\t- = por Unikso (.html)\n"
          "\t/ = por DOS/Vindozo (.HTM)\n"
          "\n"
          "\td = dekumaj signonumeroj\n"
          "\tw = kun Vindozaj kromsignoj\n"
          "\n"
          "\t1 = Latina-1a\n"
	  "\t2 = UTF-x\n"
	  "\t3 = Latina-3a (ne plu uzebla)\n"
          "\t4 = UTF-8 por WGL4\n"
          "\t8 = UTF8 kun plena Unikodo\n"
          "\tD = por fabriki dict-version\n"
          "\tM = por make depend\n"
          "\tT = (La)TeX\n"
          "\tt = Texinfo\n" 
          "\tr = TomeRaider\n");
    return(EXIT_FAILURE);
}
