/*
	WARNING: This file was generated by dkct.
	Changes you make here will be lost if dkct is run again!
	You should modify the original source and run dkct on it.
	Original source: dkt-html.ctr
*/

/*
Copyright (C) 2011-2013, Dirk Krause

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above opyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.
* Neither the name of the author nor the names of contributors may be used
  to endorse or promote products derived from this software without specific
  prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**	@file dkt-html.c The dkt-html module.
*/


#line 10 "dkt-html.ctr"

#include "dk3all.h"
#include "dkt.h"





#line 17 "dkt-html.ctr"



/**	Job structure.
*/
typedef struct {
  dk3_app_t		*app;	/**< Application. */
  dk3_option_set_t	*opt;	/**< Option set. */
  dkChar const * const	*msg;	/**< Localized messages. */
  dkChar const * const	*kwnl;	/**< Keywords, not localized. */
  dkChar const		*title;	/**< Page title for full page. */
  int			 exval;	/**< Exit status code. */
  int			 enc_s;	/**< Encoding for stdin. */
  int			 enc_f;	/**< Encoding for files. */
  int			 f_fp;	/**< Flag: Produce full page. */
  int			 f_em;	/**< Flag: Echo mode. */
  int			 f_nl;	/**< Flag: Last was newline. */
} DKT_HTML_J;



/**	Long options / configuration file keywords.
*/
static dkChar const * const	dkt_html_long_opt[] = {
dkT("stdin-encoding"),
dkT("file-encoding"),
dkT("reset"),
NULL
};



/**	Data for the option set.
*/
static dk3_option_t const dkt_html_options[] = {
  { dkT('R'), dkT("reset"), 0 },
  { dkT('t'), dkT("title"), 1 },
  { dkT('f'), dkT("full"), 0 },
  { dkT('i'), dkT("input-encoding"), 1 },
  { dkT('p'), dkT("plain"), 0 },
  { dkT('e'), dkT("echo"), 0 }
};

/**	Number of options in the dkt_html_options array.
*/
static size_t const dkt_html_szoptions =
sizeof(dkt_html_options)/sizeof(dk3_option_t);



/**	Translation table for ASCII characters.
*/
static char const * const dkt_html_translation_table[] = {
/*   0 00 */	 NULL,
/*   1 01 */	 NULL,
/*   2 02 */	 NULL,
/*   3 03 */	 NULL,
/*   4 04 */	 NULL,
/*   5 05 */	 NULL,
/*   6 06 */	 NULL,
/*   7 07 */	 NULL,
/*   8 08 */	 NULL,
/*   9 09 */	"\t",
/*  10 0a */	 NULL,
/*  11 0b */	 NULL,
/*  12 0c */	 NULL,
/*  13 0d */	 NULL,
/*  14 0e */	 NULL,
/*  15 0f */	 NULL,
/*  16 10 */	 NULL,
/*  17 11 */	 NULL,
/*  18 12 */	 NULL,
/*  19 13 */	 NULL,
/*  20 14 */	 NULL,
/*  21 15 */	 NULL,
/*  22 16 */	 NULL,
/*  23 17 */	 NULL,
/*  24 18 */	 NULL,
/*  25 19 */	 NULL,
/*  26 1a */	 NULL,
/*  27 1b */	 NULL,
/*  28 1c */	 NULL,
/*  29 1d */	 NULL,
/*  30 1e */	 NULL,
/*  31 1f */	 NULL,
/*  32 20 */	" ",
/*  33 21 */	"!",
/*  34 22 */	"\"",
/*  35 23 */	"#",
/*  36 24 */	"$",
/*  37 25 */	"%",
/*  38 26 */	"&amp;",
/*  39 27 */	"'",
/*  40 28 */	"(",
/*  41 29 */	")",
/*  42 2a */	"*",
/*  43 2b */	"+",
/*  44 2c */	",",
/*  45 2d */	"-",
/*  46 2e */	".",
/*  47 2f */	"/",
/*  48 30 */	"0",
/*  49 31 */	"1",
/*  50 32 */	"2",
/*  51 33 */	"3",
/*  52 34 */	"4",
/*  53 35 */	"5",
/*  54 36 */	"6",
/*  55 37 */	"7",
/*  56 38 */	"8",
/*  57 39 */	"9",
/*  58 3a */	":",
/*  59 3b */	";",
/*  60 3c */	"&lt;",
/*  61 3d */	"=",
/*  62 3e */	"&gt;",
/*  63 3f */	"?",
/*  64 40 */	"@",
/*  65 41 */	"A",
/*  66 42 */	"B",
/*  67 43 */	"C",
/*  68 44 */	"D",
/*  69 45 */	"E",
/*  70 46 */	"F",
/*  71 47 */	"G",
/*  72 48 */	"H",
/*  73 49 */	"I",
/*  74 4a */	"J",
/*  75 4b */	"K",
/*  76 4c */	"L",
/*  77 4d */	"M",
/*  78 4e */	"N",
/*  79 4f */	"O",
/*  80 50 */	"P",
/*  81 51 */	"Q",
/*  82 52 */	"R",
/*  83 53 */	"S",
/*  84 54 */	"T",
/*  85 55 */	"U",
/*  86 56 */	"V",
/*  87 57 */	"W",
/*  88 58 */	"X",
/*  89 59 */	"Y",
/*  90 5a */	"Z",
/*  91 5b */	"[",
/*  92 5c */	"\\",
/*  93 5d */	"]",
/*  94 5e */	"^",
/*  95 5f */	"_",
/*  96 60 */	"`",
/*  97 61 */	"a",
/*  98 62 */	"b",
/*  99 63 */	"c",
/* 100 64 */	"d",
/* 101 65 */	"e",
/* 102 66 */	"f",
/* 103 67 */	"g",
/* 104 68 */	"h",
/* 105 69 */	"i",
/* 106 6a */	"j",
/* 107 6b */	"k",
/* 108 6c */	"l",
/* 109 6d */	"m",
/* 110 6e */	"n",
/* 111 6f */	"o",
/* 112 70 */	"p",
/* 113 71 */	"q",
/* 114 72 */	"r",
/* 115 73 */	"s",
/* 116 74 */	"t",
/* 117 75 */	"u",
/* 118 76 */	"v",
/* 119 77 */	"w",
/* 120 78 */	"x",
/* 121 79 */	"y",
/* 122 7a */	"z",
/* 123 7b */	"{",
/* 124 7c */	"|",
/* 125 7d */	"}",
/* 126 7e */	"~",
/* 127 7f */	 NULL,
/* 128 80 */	 NULL,
/* 129 81 */	 NULL,
/* 130 82 */	 NULL,
/* 131 83 */	 NULL,
/* 132 84 */	 NULL,
/* 133 85 */	 NULL,
/* 134 86 */	 NULL,
/* 135 87 */	 NULL,
/* 136 88 */	 NULL,
/* 137 89 */	 NULL,
/* 138 8a */	 NULL,
/* 139 8b */	 NULL,
/* 140 8c */	 NULL,
/* 141 8d */	 NULL,
/* 142 8e */	 NULL,
/* 143 8f */	 NULL,
/* 144 90 */	 NULL,
/* 145 91 */	 NULL,
/* 146 92 */	 NULL,
/* 147 93 */	 NULL,
/* 148 94 */	 NULL,
/* 149 95 */	 NULL,
/* 150 96 */	 NULL,
/* 151 97 */	 NULL,
/* 152 98 */	 NULL,
/* 153 99 */	 NULL,
/* 154 9a */	 NULL,
/* 155 9b */	 NULL,
/* 156 9c */	 NULL,
/* 157 9d */	 NULL,
/* 158 9e */	 NULL,
/* 159 9f */	 NULL,
/* 160 a0 */	"&nbsp;",
/* 161 a1 */	"&iexcl;",
/* 162 a2 */	"&cent;",
/* 163 a3 */	"&pound;",
/* 164 a4 */	"&curren;",
/* 165 a5 */	"&yen;",
/* 166 a6 */	"&brvbar;",
/* 167 a7 */	"&sect;",
/* 168 a8 */	"&uml;",
/* 169 a9 */	"&copy;",
/* 170 aa */	"&ordf;",
/* 171 ab */	"&laquo;",
/* 172 ac */	"&not;",
/* 173 ad */	"&shy;",
/* 174 ae */	"&reg;",
/* 175 af */	"&macr;",
/* 176 b0 */	"&deg;",
/* 177 b1 */	"&plusmn;",
/* 178 b2 */	"&sup2;",
/* 179 b3 */	"&sup3;",
/* 180 b4 */	"&acute;",
/* 181 b5 */	"&micro;",
/* 182 b6 */	"&para;",
/* 183 b7 */	"&middot;",
/* 184 b8 */	"&cedil;",
/* 185 b9 */	"&sup1;",
/* 186 ba */	"&ordm;",
/* 187 bb */	"&raquo;",
/* 188 bc */	"&frac14;",
/* 189 bd */	"&frac12;",
/* 190 be */	"&frac34;",
/* 191 bf */	"&iquest;",
/* 192 c0 */	"&Agrave;",
/* 193 c1 */	"&Aacute;",
/* 194 c2 */	"&Acirc;",
/* 195 c3 */	"&Atilde;",
/* 196 c4 */	"&Auml;",
/* 197 c5 */	"&Aring;",
/* 198 c6 */	"&AElig;",
/* 199 c7 */	"&Ccedil;",
/* 200 c8 */	"&Egrave;",
/* 201 c9 */	"&Eacute;",
/* 202 ca */	"&Ecirc;",
/* 203 cb */	"&Euml;",
/* 204 cc */	"/Igrave;",
/* 205 cd */	"&Iacute;",
/* 206 ce */	"&Icirc;",
/* 207 cf */	"&Iuml;",
/* 208 d0 */	"&ETH;",
/* 209 d1 */	"&Ntilde;",
/* 210 d2 */	"&Ograve;",
/* 211 d3 */	"&Oacute;",
/* 212 d4 */	"&Ocirc;",
/* 213 d5 */	"&Otilde;",
/* 214 d6 */	"&Ouml;",
/* 215 d7 */	"&times;",
/* 216 d8 */	"&Oslash;",
/* 217 d9 */	"&Ugrave;",
/* 218 da */	"&Uacute;",
/* 219 db */	"&Ucirc;",
/* 220 dc */	"&Uuml;",
/* 221 dd */	"&Yacute;",
/* 222 de */	"&THORN;",
/* 223 df */	"&szlig;",
/* 224 e0 */	"&agrave;",
/* 225 e1 */	"&aacute;",
/* 226 e2 */	"&acirc;",
/* 227 e3 */	"&atilde;",
/* 228 e4 */	"&auml;",
/* 229 e5 */	"&aring;",
/* 230 e6 */	"&aelig;",
/* 231 e7 */	"&ccedil;",
/* 232 e8 */	"&egrave;",
/* 233 e9 */	"&eacute;",
/* 234 ea */	"&ecirc;",
/* 235 eb */	"&euml;",
/* 236 ec */	"&igrave;",
/* 237 ed */	"&iacute;",
/* 238 ee */	"&icirc;",
/* 239 ef */	"&iuml;",
/* 240 f0 */	"&eth;",
/* 241 f1 */	"&ntilde;",
/* 242 f2 */	"&ograve;",
/* 243 f3 */	"&oacute;",
/* 244 f4 */	"&ocirc;",
/* 245 f5 */	"&otilde;",
/* 246 f6 */	"&ouml;",
/* 247 f7 */	"&divide;",
/* 248 f8 */	"&oslash;",
/* 249 f9 */	"&ugrave;",
/* 250 fa */	"&uacute;",
/* 251 fb */	"&ucirc;",
/* 252 fc */	"&uuml;",
/* 253 fd */	"&yacute;",
/* 254 fe */	"&thorn;",
/* 255 ff */	"&yuml;"
};



/**	First part of a full HTML file.
*/
static char const * const dkt_html_part1[] = {
"<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">",
"<html>",
"<head>",
"<meta name=\"generator\" content=\"dkt, see http://dktools.sourceforge.net\">",
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=us-ascii\">",
NULL
};



/**	Last part of a full HTML file.
*/
static char const * const dkt_html_part2[] = {
"</p>",
"</body>",
"</html>",
NULL
};



/**	End of HTML header.
*/
static char const * const dkt_html_part3[] = {
"<!--	style sheet	-->",
"<!-- link rel=\"StyleSheet\" type=\"text/css\" href=\"__URL__\" -->",
"<!--	Parent node of current document node	-->",
"<!-- link rel=\"Parent\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Document author	-->",
"<!-- link rel=\"Made\" title=\"\" rev=\"\" href=\"mailto:__MAIL__\" -->",
"<!--	Link to homepage	-->",
"<!-- link rel=\"Home\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to table of contents	-->",
"<!-- link rel=\"ToC\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to index	-->",
"<!-- link rel=\"Index\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to glossary	-->",
"<!-- link rel=\"Glossary\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to copyright	-->",
"<!-- link rel=\"Copyright\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to upper document node (same as parent?)	-->",
"<!-- link rel=\"Up\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to next document	-->",
"<!-- link rel=\"Next\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to previous document	-->",
"<!-- link rel=\"Previous\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to help page	-->",
"<!-- link rel=\"Help\" title=\"\" rev=\"\" href=\"__URL__\" -->",
"<!--	Link to a document node serving as bookmark	-->",
"<!-- link rel=\"Bookmark\" title=\"\" rev=\"\" href=\"\" -->",
"</head>",
"<body>",
"<p>",
NULL
};



/**	Strings to construct the title tag.
*/
static char const * const dkt_html_title[] = {
"<title>",
"</title>\n",
"__TITLE__",
"</p><p>\n",
};



/**	Reset the job structure.
	@param	j	Job structure.
*/
static
void
dkt_html_job_reset(DKT_HTML_J *j)
{
  

#line 410 "dkt-html.ctr"
  j->enc_f = dk3app_get_default_file_encoding(j->app); 

#line 411 "dkt-html.ctr"
  j->enc_s = dk3app_get_default_stdin_encoding(j->app); 

#line 412 "dkt-html.ctr"
  j->f_fp  = 0;
  j->f_em  = 0;
  j->title = NULL;
  

#line 416 "dkt-html.ctr"
}



/**	Initialize job structure.
	@param	j	Job structure.
*/
static
void
dkt_html_job_init(DKT_HTML_J *j)
{
  

#line 428 "dkt-html.ctr"
  j->exval = DKT_RESULT_ERR_UNSPECIFIC;
  j->opt = NULL;
  dkt_html_job_reset(j);
  j->enc_f = dk3app_get_input_file_encoding(j->app);  

#line 432 "dkt-html.ctr"
  j->enc_s = dk3app_get_input_stdin_encoding(j->app); 

#line 433 "dkt-html.ctr"
  j->f_nl = 0;
  

#line 435 "dkt-html.ctr"
}



/**	Clean up job structure.
	@param	j	Job structure.
*/
static
void
dkt_html_job_cleanup(DKT_HTML_J *j)
{
  

#line 447 "dkt-html.ctr"
  /* Release option set. */
  if(j->opt) {
    dk3opt_close(j->opt);
  } j->opt = NULL;
  j->title = NULL;
  

#line 453 "dkt-html.ctr"
}



/**	Process one key/value pair, either long option or config file line.
	@param	job	Job structure.
	@param	key	Key (option name).
	@param	val	Value.
	@param	ori	Original text.
	@param	verb	Flag: Verbose.
	@return	1 on success, 0 on error.
*/
static
int
dkt_html_long_opt_handler(
  DKT_HTML_J *job,
  dkChar const *key,
  dkChar const *val,
  dkChar const *ori,
  int		verb
)
{
  int back = 0;
  int i = 0;	/* Index of long option keyword in array. */
  

#line 478 "dkt-html.ctr"
  if((job) && (key) && (ori)) {
    i = dk3str_array_index(dkt_html_long_opt, key, 0);
    switch(i) {
      case 0: {
        back = dkt_tool_set_encoding(
	  job->app, &(job->enc_s), val,
	  dk3app_get_input_stdin_encoding(job->app)
	); 

#line 486 "dkt-html.ctr"
      } break;
      case 1: {
        back = dkt_tool_set_encoding(
	  job->app, &(job->enc_f), val,
	  dk3app_get_input_file_encoding(job->app)
	); 

#line 492 "dkt-html.ctr"
      } break;
      case 2: {
        dkt_html_job_reset(job);
        back = 1;
      } break;
      default: {
        if(verb) {
	  /* ERROR: Unknown option */
	  dk3app_log_i3(job->app, DK3_LL_ERROR, 139, 140, key);
	}
      } break;
    }
  } 

#line 505 "dkt-html.ctr"
  return back;
}



/**	Process one key/value pair.
	@param	jv	Pointer to job structure casted to void *.
	@param	k	Key.
	@param	v	Value.
	@return	1 to indicate success.
*/
static
int
dkt_html_conf_line(void *jv, dkChar const *k, dkChar const *v)
{
  

#line 521 "dkt-html.ctr"
  (void)dkt_html_long_opt_handler((DKT_HTML_J *)jv, k, v, k, 0);
  

#line 523 "dkt-html.ctr"
  return 1;
}



/**	Process command line arguments.
	@param	j	Job structure.
	@return	1 on success, 0 on error.
*/
static
int
dkt_html_process_arguments(DKT_HTML_J *j)
{
  int back = 0;
  int			 xargc	= 0;	/* Number of command line arguments. */
  dkChar const * const	*xargv	= NULL;	/* Command line arguments array. */
  dkChar const		*x	= NULL;	/* Option argument. */
  int			 res	= 0;	/* Result of set encoding operation. */
  

#line 542 "dkt-html.ctr"
  xargc = dk3app_get_argc(j->app);
  xargv = dk3app_get_argv(j->app);
  xargv++; xargv++; xargc--; xargc--;
  j->opt = dk3opt_open_app(
    dkt_html_options,
    dkt_html_szoptions,
    dkT('\0'),
    NULL,
    xargc,
    xargv,
    j->app
  );
  if(j->opt) {
    if(dk3opt_get_error_code(j->opt) == 0) {
      back = 1;
      if(dk3opt_is_set(j->opt, dkT('R'))) {
        dkt_html_job_reset(j);
      }
      if(dk3opt_is_set(j->opt, dkT('f'))) {
        j->f_fp = 1;
        if(dk3opt_is_set(j->opt, dkT('t'))) {
          j->title = dk3opt_get_short_arg(j->opt, dkT('t'));
        }
      }
      if(dk3opt_is_set(j->opt, dkT('i'))) {
        x = dk3opt_get_short_arg(j->opt, dkT('i'));
        if(x) {
          res = dkt_tool_set_encoding(
	    j->app, &(j->enc_s), x,
	    dk3app_get_input_stdin_encoding(j->app)
	  ); 

#line 573 "dkt-html.ctr"
	  if(res) {
	    j->enc_f = j->enc_s;
	  } else {
	    back = 0; j->exval = DKT_RESULT_ERR_OPTION;
	  }
        } else {
          back = 0; j->exval = DKT_RESULT_ERR_OPTION;
        }
      } else {
        if(dk3opt_is_set(j->opt, dkT('p'))) {
          j->enc_f = j->enc_s = DK3_FILE_ENCODING_ASCII;
        }
      }
      if(dk3opt_is_set(j->opt, dkT('e'))) {
        j->f_em = 1;
      }
    } else {
      j->exval = DKT_RESULT_ERR_OPTION;
    }
  } else {
    j->exval = DKT_RESULT_ERR_MEMORY;
  } 

#line 595 "dkt-html.ctr"
  return back;
}



/**	Write one 32-bit character to output.
	@param	j	Job structure.
	@param	c32	Character to write.
*/
static
void
dkt_html_out_c32(DKT_HTML_J *j, dk3_c32_t c32)
{
  int		done	= 0;	/* Flag: Character already handled. */
  size_t	sz	= 0;	/* Index into fixed decodings array. */

  if((unsigned long)c32 < 0x00000100UL) {
    sz = (size_t)c32;
    sz &= 0x00FFU;
    if(dkt_html_translation_table[sz]) {
      fputs(dkt_html_translation_table[sz], stdout);
      done = 1;
    }
  }
  if(!done) {
#if DK3_SIZEOF_WCHAR_T == 4
    if((unsigned long)c32 > 0x000000FFUL) {
      if((unsigned long)c32 > 0x0000FFFFUL) {
        if((unsigned long)c32 > 0x00FFFFFFUL) {
	  fprintf(stdout, "&#x%08lx;", (unsigned long)c32);
	} else {
	  fprintf(stdout, "&#x%06lx;", (unsigned long)c32);
	}
      } else {
        fprintf(stdout, "&#x%04lx;", (unsigned long)c32);
      }
    } else {
      fprintf(stdout, "&#x%02lx;", (unsigned long)c32);
    }
#else
    if((unsigned long)c32 > 0x000000FFUL) {
      if((unsigned long)c32 > 0x0000FFFFUL) {
        if((unsigned long)c32 > 0x00FFFFFFUL) {
	  fprintf(stdout, "&#x%08lx;", c32);
	} else {
	  fprintf(stdout, "&#x%06lx;", c32);
	}
      } else {
        fprintf(stdout, "&#x%04lx;", c32);
      }
    } else {
      fprintf(stdout, "&#x%02lx;", c32);
    }
#endif
  }
}



/**	Handler function to process one 32-bit character.
	@param	vj	Job structure, casted to void *.
	@param	c32	The character to write.
	@return	1 to indicate success.
*/
static
int
dkt_html_char_handler(void *vj, dk3_c32_t c32)
{
  DKT_HTML_J *j;

  j = (DKT_HTML_J *)vj;
  if(c32 == 0x0000000DUL) {
    j->f_nl = 0;
  } else {
    if(c32 == 0x0000000AUL) {
      fputc('\n', stdout);
      j->f_nl = 1;
    } else {
      j->f_nl = 0;
      dkt_html_out_c32((DKT_HTML_J *)vj, c32);
    }
  }
  return 1;
}



/**	Write a dkChar string to HTML, used to write page title.
	@param	j	Job structure.
	@param	tx	Text to write.
*/
static
void
dkt_html_print_text(DKT_HTML_J *j, dkChar const *tx)
{
  dk3_c32_t		c32	= 0UL;	/* 32-bit character. */
#if DK3_CHAR_SIZE > 1
  dk3_c16_t const	*sp	= NULL;	/* Source pointer. */
  size_t		 sl	= 0;	/* Remaining source length. */
  size_t		 used	= 0;	/* Number of bytes used. */
  

#line 696 "dkt-html.ctr"
  sp = (dk3_c16_t const *)tx;
  sl = dk3str_c16_len(sp);
  while(sl > 0) {
    used = 0;
    if(dk3enc_utf162uc(&c32, sp, sl, &used)) {
      dkt_html_out_c32(j, c32);
      if(used > 0) {
        if(sl >= used) {
	  sl = sl - used;
	  sp = &(sp[used]);
	} else {
	  sl = 0;
	  /* ERROR: Decoding! */
	  dk3app_log_i1(j->app, DK3_LL_ERROR, 119);
	}
      } else {
        sl = 0;
	/* ERROR: Decoding! */
	dk3app_log_i1(j->app, DK3_LL_ERROR, 119);
      }
    } else {
      sl = 0;
      /* ERROR: Decoding! */
      dk3app_log_i1(j->app, DK3_LL_ERROR, 119);
    }
  }
#else
  unsigned char const	*sp	= NULL;	/* Source pointer. */
  unsigned char		c	= 0x00;	/* Current character. */
  size_t		sl	= 0;	/* Remaining source length. */
  size_t		used	= 0;	/* Number of bytes used. */
  

#line 728 "dkt-html.ctr"
  if(dk3app_get_encoding(j->app) == DK3_ENCODING_UTF8) {
    sp = (unsigned char const *)tx;
    sl = dk3str_c8_len(tx);
    while(sl > 0) {
      used = 0;
      if(dk3enc_utf82uc(&c32, sp, sl, &used)) {
        dkt_html_out_c32(j, c32);
	if(used > 0) {
	  if(sl >= used) {
	    sl = sl - used;
	    sp = &(sp[used]);
	  } else {
	    sl = 0;
	    /* Decoding problem! */
	    dk3app_log_i1(j->app, DK3_LL_ERROR, 118);
	  }
	} else {
	  sl = 0;
	  /* Decoding problem! */
	  dk3app_log_i1(j->app, DK3_LL_ERROR, 118);
	}
      } else {
        sl = 0;
	/* Decoding problem! */
	dk3app_log_i1(j->app, DK3_LL_ERROR, 118);
      }
    }
  } else {
    sp = (unsigned char const *)tx;
    while(*sp) {
      c = *(sp++);
      c32 = (dk3_c32_t)c;
      c32 &= 0x000000FFUL;
      dkt_html_out_c32(j, c32);
    }
  }
#endif
}



/**	Write one text paragraph.
	@param	j	Job structure.
	@param	t	Text.
*/
static
void
dkt_html_write_paragraph(DKT_HTML_J *j, char const * const *t)
{
  char const * const *ptr = NULL;	/* Current source line. */
  ptr = t;
  while(*ptr) {
    fputs(*(ptr++), stdout);
    fputc('\n', stdout);
  }
}



/**	Print start of HTML page.
	@param	j	Job structure.
*/
static
void
dkt_html_start_page(DKT_HTML_J *j)
{
  dkt_html_write_paragraph(j, dkt_html_part1);
  fputs(dkt_html_title[0], stdout);
  if(j->title) {
    dkt_html_print_text(j, j->title);
  } else {
    fputs(dkt_html_title[2], stdout);
  }
  fputs(dkt_html_title[1], stdout);
  dkt_html_write_paragraph(j, dkt_html_part3);
}



/**	Print HTML page end.
	@param	j	Job structure.
*/
static
void
dkt_html_end_page(DKT_HTML_J *j)
{
  dkt_html_write_paragraph(j, dkt_html_part2);
}



/**	Process one file name (correction and expansion is already done).
	@param	j	Job structure.
	@param	fn	File name.
	@param	de	Default encoding if no BOM found at start of file.
*/
static
void
dkt_html_process_one_file(DKT_HTML_J *j, dkChar const *fn, int de)
{
  int back;
  

#line 830 "dkt-html.ctr"
  j->f_nl = 0;
  back = dk3stream_process_filename_chars_app(
    (void *)j,
    dkt_html_char_handler,
    fn,
    de,
    j->app
  );
  if(!(j->f_nl)) {
    fputc('\n', stdout);
  }
  if(!back) {
    j->exval = DKT_RESULT_ERR_FOPEN;
  } 

#line 844 "dkt-html.ctr"
}



/**	Process the file names.
	@param	j	Job structure.
	@param	nfn	Number of file names.
*/
static
void
dkt_html_process_files(DKT_HTML_J *j, int nfn)
{
  dkChar	fnb[DK3_MAX_PATH];	/* File name buffer for correction. */
  dkChar const	*fn	= NULL;		/* Current file name as specified. */
  dkChar const	*en	= NULL;		/* Current expander result. */
  int		i	= 0;		/* Index of current file name. */
  dk3_dir_t	*fne	= NULL;		/* File name expander. */
  

#line 862 "dkt-html.ctr"
  for(i = 0; i < nfn; i++) {
    fn = dk3opt_get_arg(j->opt, i);
    if(fn) {
      if(dk3str_len(fn) < DK3_SIZEOF(fnb,dkChar)) {
        dk3str_cpy(fnb, fn);
	dk3str_correct_filename(fnb);
	if(dk3sf_must_expand(fnb)) {
	  fne = dk3dir_fne_open_app(fnb, j->app);
	  if(fne) {
	    if(dk3dir_get_number_of_files(fne)) {
	      while(dk3dir_get_next_file(fne)) {
	        en = dk3dir_get_fullname(fne);
		if(en) {
		  dkt_html_process_one_file(j, en, j->enc_f);
		}
	      }
	    } else {
	      j->exval = DKT_RESULT_ERR_FILENAME;
	      /* ERROR: No such file! */
	      dk3app_log_i3(j->app, DK3_LL_ERROR, 215, 216, fn);
	    }
	    dk3dir_close(fne);
	  } else {
	    j->exval = DKT_RESULT_ERR_MEMORY;
	  }
	} else {
	  dkt_html_process_one_file(j, fnb, j->enc_f);
	}
      } else {
        j->exval = DKT_RESULT_ERR_FILENAME;
        /* ERROR: File name too long! */
	dk3app_log_i3(j->app, DK3_LL_ERROR, 65, 66, fn);
      }
    }
  } 

#line 897 "dkt-html.ctr"
}



/**	Process arguments in echo mode.
	@param	j	Job structure.
	@param	nfn	Number of command line arguments.
*/
static
void
dkt_html_process_echo_arguments(DKT_HTML_J *j, int nfn)
{
  int i;
  dkChar const	*arg = NULL;	/* Current argument to process. */
  for(i = 0; i < nfn; i++) {
    arg = dk3opt_get_arg(j->opt, i);
    if(arg) {
      if(i > 0) { fputc(' ', stdout); }
      dkt_html_print_text(j, arg);
    }
  }
  fputc('\n', stdout);
}



/**	Do processing.
	@param	j	Job structure.
*/
static
void
dkt_html_run(DKT_HTML_J *j)
{
  int nfn;		/* Number of file names. */
  

#line 932 "dkt-html.ctr"
  nfn = dk3opt_get_num_args(j->opt);
  /* Write HTML page start */
  if(j->f_fp) {
    dkt_html_start_page(j);
  }
  /* Process input */
  if(nfn > 0) {
    if(j->f_em) {
      dkt_html_process_echo_arguments(j, nfn);
    } else {
      dkt_html_process_files(j, nfn);
    }
  } else {
    j->f_nl = 0;
    dk3app_process_stdin_chars(j->app,(void *)j,dkt_html_char_handler,j->enc_s);
    if(!(j->f_nl)) { fputc('\n', stdout); }
  }
  /* Write HTML page end */
  if(j->f_fp) {
    dkt_html_end_page(j);
  }
  

#line 954 "dkt-html.ctr"
}



int
dkt_html(
  dk3_app_t		*app,
  dkChar const		*sn,
  dkChar const * const	*msg,
  dkChar const * const	*kwnl
)
{
  int back = DKT_RESULT_ERR_UNSPECIFIC;
  DKT_HTML_J	j;
  

#line 969 "dkt-html.ctr"
  j.app = app; j.msg = msg; j.kwnl = kwnl;
  dkt_html_job_init(&j);
  dkt_tool_read_conf(app, sn, (void *)(&j), dkt_html_conf_line);
  

#line 973 "dkt-html.ctr"
  if(dkt_html_process_arguments(&j)) {
    j.exval = DKT_RESULT_OK;
    dkt_html_run(&j);
  }
  back = j.exval;
  dkt_html_job_cleanup(&j);
  

#line 980 "dkt-html.ctr"
  return back;
}



/* vim: set ai sw=2 : */

