 /******************************************************************************
 * program:     wp2latex                                                      *
 * function:    module with XML support functions for HTML, AbiWord ans Accent*
 * modul:       pass1xml.cc                                                   *
 * description: 							      *
 * licency:     GPL		                                              *
 ******************************************************************************/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

#include<stringa.h>
#include<lists.h>
#include<dbllist.h>

#include"wp2latex.h"
#include"pass1xml.h"
#include "cp_lib/cptran.h"


void TconvertedPass1_XML::SelectTranslator(const char *CharSet)
{
string translator;
  while(*CharSet==' ') CharSet++;

  if(!strcmp(CharSet,"utf8") || !strcmp(CharSet,"utf-8") || 
     !strcmp(CharSet,"UTF8") || !strcmp(CharSet,"UTF-8"))
    {
    ConvertCpg = GetTranslator("unicodeTOinternal");
    CharReader = &utf8_fgetc;
    goto Finish;
    }
  
  if(!strncmp(CharSet,"iso-8859-",9) || !strncmp(CharSet,"ISO-8859-",9))
  {
    translator = "iso_8859_";
    translator += CharSet+9;
  }
  else if(!stricmp(CharSet,"windows-1250")) translator="cp1250";
  else if(!stricmp(CharSet,"windows-1251")) translator="cp1251";
  else if(!stricmp(CharSet,"windows-1252")) translator="cp1252";
  else translator=CharSet;

  translator += "TOinternal";
  ConvertCpg = GetTranslator(translator);
  CharReader = &ch_fgetc;

Finish:
  if(ConvertCpg==NULL || ConvertCpg->number()==0)
    if(err != NULL)
      {
      perc.Hide();
      fprintf(err,_("\nError: Cannot initialize charset converter %s!"),translator());
      }
}


/// Read one XML object from wpd stream.
/// cq->by = 0 (normal char), 1 (extended char &xxx;), 2 (tag <>), 3 (end tag </>), 4 comment, 5 unfinished &xxx, 
///          6 expanded unicode, 7 CDATA block, 127 fail
void TconvertedPass1_XML::ReadXMLTag(bool MakeUpper)
{
#ifdef DEBUG
  fprintf(log,"\n#ReadXMLTag() ");fflush(log);
#endif
int c;
string Attribute, Value;

erase(TAG_Args);
c = CharReader(wpd);
if((unsigned)c==0xFFFF)
  {by=XML_fail;erase(TAG);return;}

if(c>=0x100)	//Handle unicode character
	{
	TAG=Ext_chr_str(c,this,ConvertCpg);
	by = XML_unicode;
	return;
	}

if(c=='<')	//Handle HTML tag
   {
   by = XML_tag;
   TAG = '<';
   c=fgetc(wpd);
   if(c=='/') by=XML_closetag;

   while(!feof(wpd))
	{
	if(c=='>') {TAG += MakeUpper?toupper(c):c; return;}
	if(isspace(c))
	    {
	    if(TAG[1]=='!')
		{		
		do {
		   if( (c=fgetc(wpd)) == EOF) return;
                   if(c==0) return;			 //illegal 0 char
		   TAG+=c;		//read all comment
		   } while (c!='>');
		by = XML_comment;
		return;
		}
	    TAG += '>';
	    while(!feof(wpd))	// read arg list
		{
		Attribute.erase();
	        Value.erase();
		do {
		   c=fgetc(wpd);
		   } while (c==' ' || c=='\r' || c=='\n');
		if(c=='>') break;
		while(c!='=' && c!='>')
		   {
		   Attribute+=c;
		   if( (c=fgetc(wpd)) == EOF) return;
		   if(c==0) return;			 //illegal 0 char
		   }
		if(c!='>')		//Attribute without value <x aaa>
		   {
		   do {
		      c = fgetc(wpd);
		      } while (isspace(c));
		   if(c=='"')		//read "value" in double quotation mark
		     {
		     c=fgetc(wpd);
		     while(c!='\"')
		       {
		       Value+=c;
		       if( (c=fgetc(wpd)) == EOF) break;
		       if(c==0) {c='>';break;}			//illegal 0 char
		       }
		     }
		  else			//read "value" without double quotation mark
		     {
		     while(c!='>' && !isspace(c))
			{
			Value+=c;
			if( (c=fgetc(wpd)) == EOF) break;
			if(c==0) {c='>';break;}			//illegal 0 char
			}
		     }
		  }
		TAG_Args.Add(Attribute(),Value());
		if(c=='>') break;
		}
	    return;
	    }

	TAG += MakeUpper ? toupper(c) : c;

        if(c=='[' && !strncmp(TAG(),"<![CDATA[",9))
          {
          char c2;
          do {
             c2 = c;
             if( (c=fgetc(wpd)) == EOF)
               {by=XML_fail; return;}
             if(c==0) continue;			 //illegal 0 char
	     TAG += c;		//read all CDATA
	     } while (c2!=']' || c!='>');
          by = XML_CDATA;
          return;
          }

	c = fgetc(wpd);
	}

   TAG += '>';			//EOF reached
   return;
   }

if(c=='&')
   {
   by = XML_extchar;

   TAG = c;
   while(!feof(wpd))
       {
       c=fgetc(wpd);
       if(c==';') break;
       if(isspace(c) || c==0)	//unterminated & sequence
	   {			//space also terminates &xx; section (CR, LF, TAB and ' ')
	   by = XML_badextchar;
	   break;
	   }

       TAG+=c;
       }
   TAG+=';';
   return;
   }

by = XML_char;
subby = c;
TAG = c;
}


/** This function converts comment inside HTML. */
void TconvertedPass1_XML::CommentXML(void)
{
#ifdef DEBUG
  fprintf(log,"\n#CommentXML() ");fflush(log);
#endif
  signed char Old_char_on_line;
  unsigned char OldFlag;
  attribute OldAttr;
  int i,maxi,commentchars;


  OldFlag = flag;
  OldAttr = attr;
  Old_char_on_line = char_on_line;
  flag = CharsOnly;
  recursion++;
  attr.InitAttr();		//Turn all attributes in the comment off

  fputc('%',strip);

  maxi = length(TAG);
  i = 0;
  commentchars = 0;

  if(!strncmp(TAG(),"<![CDATA[",9))
    {
    i += 9;
    if(TAG[maxi-1]=='>')
      {
      maxi--;
      if(TAG[maxi-1]==']')
        {
        maxi--;
        if(TAG[maxi-1]==']') maxi--;
        }
      }
    }
  else
    {
    if(TAG[i]=='<' && TAG[i+1]=='!' && TAG[maxi-1]=='>') {i+=2;maxi--;}
    if(TAG[i]=='-' && TAG[maxi-1]=='-' && i<maxi) {i++;maxi--;}
    if(TAG[i]=='-' && TAG[maxi-1]=='-' && i<maxi) {i++;maxi--;}
    }
  while(TAG[i]==' ' && TAG[maxi-1]==' ' && i<maxi) {i++;maxi--;}

  while (i<maxi)
       {
       by=TAG[i++];
       if(by==0) break;

       if(by==0xA || by==0xD)	//New comment line
		{
		if(commentchars)
		  {
		  line_term = 's';    	//Soft return
		  Make_tableentry_envir_extra_end(this);
		  fprintf(strip, "\n");
		  rownum++;
		  Make_tableentry_attr(this);

		  fputc('%',strip);
		  commentchars=0;
		  }
		continue;
		}

       fputc(by,strip);
       commentchars++;
       continue;
       }

  line_term = 's';    	//Soft return
  Make_tableentry_envir_extra_end(this);
  fprintf(strip, "\n");
  rownum++;
  Make_tableentry_attr(this);


  recursion--;
  strcpy(ObjType, "Comment");
  attr = OldAttr;
  flag = OldFlag;
  if(Old_char_on_line==true || Old_char_on_line==-1) char_on_line = -1;
	else char_on_line = false;
}
