exp-html.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /* Copyright 1999 by Paul Ortyl <ortylp@from.pl> */
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "lang.h"
  5. #include "export.h"
  6. static int html_open(struct export *e);
  7. static int html_option(struct export *e, int opt, char *arg);
  8. static int html_output(struct export *e, char *name, struct fmt_page *pg);
  9. static char *html_opts[] = // module options
  10. {
  11. "gfx-chr=<char>", // substitute <char> for gfx-symbols
  12. "bare", // no headers
  13. 0
  14. };
  15. struct html_data // private data in struct export
  16. {
  17. u8 gfx_chr;
  18. u8 bare;
  19. };
  20. struct export_module export_html = // exported module definition
  21. {
  22. "html", // id
  23. "html", // extension
  24. html_opts, // options
  25. sizeof(struct html_data), // size
  26. html_open, // open
  27. 0, // close
  28. html_option, // option
  29. html_output // output
  30. };
  31. #define D ((struct html_data *)e->data)
  32. static int html_open(struct export *e)
  33. {
  34. D->gfx_chr = '#';
  35. D->bare = 0;
  36. //e->reveal=1; // the default should be the same for all formats.
  37. return 0;
  38. }
  39. static int html_option(struct export *e, int opt, char *arg)
  40. {
  41. switch (opt)
  42. {
  43. case 1: // gfx-chr=
  44. D->gfx_chr = *arg ?: ' ';
  45. break;
  46. case 2: // bare (no headers)
  47. D->bare=1;
  48. break;
  49. }
  50. return 0;
  51. }
  52. #define HTML_BLACK "#000000"
  53. #define HTML_RED "#FF0000"
  54. #define HTML_GREEN "#00FF00"
  55. #define HTML_YELLOW "#FFFF00"
  56. #define HTML_BLUE "#0000FF"
  57. #define HTML_MAGENTA "#FF00FF"
  58. #define HTML_CYAN "#00FFFF"
  59. #define HTML_WHITE "#FFFFFF"
  60. #undef UNREADABLE_HTML //no '\n'
  61. #define STRIPPED_HTML //only necessary fields in header
  62. static int html_output(struct export *e, char *name, struct fmt_page *pg)
  63. {
  64. const char* html_colours[]={ HTML_BLACK,
  65. HTML_RED,
  66. HTML_GREEN,
  67. HTML_YELLOW,
  68. HTML_BLUE,
  69. HTML_MAGENTA,
  70. HTML_CYAN,
  71. HTML_WHITE};
  72. FILE *fp;
  73. int x, y;
  74. #ifdef UNREADABLE_HTML
  75. #define HTML_NL
  76. #else
  77. #define HTML_NL fputc('\n',fp);
  78. #endif
  79. if (not(fp = fopen(name, "w")))
  80. {
  81. export_error("cannot create file");
  82. return -1;
  83. }
  84. if (!D->bare)
  85. {
  86. #ifndef STRIPPED_HTML
  87. fputs("<!doctype html public \"-//w3c//dtd html 4.0 transitional//en\">",fp);
  88. HTML_NL
  89. #endif
  90. fputs("<html><head>",fp);
  91. HTML_NL
  92. #ifndef STRIPPED_HTML
  93. fputs("<meta http-equiv=\"Content-Type\" content=\"text/html;",fp);
  94. switch(latin1) {
  95. case LATIN1: fprintf(fp,"charset=iso-8859-1\">"); break;
  96. case LATIN2: fprintf(fp,"charset=iso-8859-2\">"); break;
  97. case KOI8: fprintf(fp,"charset=koi8-r\">"); break;
  98. case GREEK: fprintf(fp,"charset=iso-8859-7\">"); break;
  99. }
  100. HTML_NL
  101. fputs("<meta name=\"GENERATOR\" content=\"alevt-cap\">",fp);
  102. HTML_NL
  103. #else
  104. switch(latin1) {
  105. case LATIN1: fprintf(fp,"<meta charset=iso-8859-1\">"); break;
  106. case LATIN2: fprintf(fp,"<meta charset=iso-8859-2\">"); break;
  107. case KOI8: fprintf(fp,"<meta charset=koi8-r\">"); break;
  108. case GREEK: fprintf(fp,"<meta charset=iso-8859-7\">"); break;
  109. }
  110. HTML_NL
  111. #endif
  112. fputs("</head>",fp);
  113. fputs("<body text=\"#FFFFFF\" bgcolor=\"#000000\">",fp);
  114. HTML_NL
  115. } //bare
  116. fputs("<tt><b>",fp);
  117. HTML_NL
  118. // write tables in form of HTML format
  119. for (y = 0; y < 25; ++y)
  120. {
  121. int last_nonblank=0;
  122. int first_unprinted=0;
  123. int last_space=1;
  124. // previous char was &nbsp;
  125. // is used for deciding to put semicolon or not
  126. int nbsp=0;
  127. // for output filled with ' ' up to 40 chars
  128. // set last_nonblank=39
  129. for (x = 0 ; x < 40; ++x)
  130. {
  131. if (pg->data[y][x].attr & EA_GRAPHIC)
  132. {pg->data[y][x].ch= D->gfx_chr;}
  133. if (pg->data[y][x].ch!=' ')
  134. {
  135. last_nonblank=x;
  136. }
  137. }
  138. for (x = 0 ; x <= last_nonblank ; ++x)
  139. {
  140. if (pg->data[y][x].ch==' ')
  141. {
  142. // if single space between blinking/colour words
  143. // then make the space blinking/colour too
  144. if ((x)&&(x<39))
  145. {
  146. if ((pg->data[y][x-1].ch!=' ')
  147. &&(pg->data[y][x+1].ch!=' ')
  148. &&(pg->data[y][x-1].attr & EA_BLINK)
  149. &&(pg->data[y][x+1].attr & EA_BLINK))
  150. {pg->data[y][x].attr |= EA_BLINK;}
  151. else
  152. {pg->data[y][x].attr &= ~EA_BLINK;}
  153. if ((pg->data[y][x-1].ch!=' ')
  154. &&(pg->data[y][x+1].ch!=' ')
  155. &&(pg->data[y][x-1].fg==pg->data[y][x+1].fg))
  156. {pg->data[y][x].fg=pg->data[y][x-1].fg;}
  157. else
  158. pg->data[y][x].fg=7;
  159. }
  160. else
  161. {
  162. pg->data[y][x].attr &= ~EA_BLINK;
  163. pg->data[y][x].fg=7;
  164. }
  165. }
  166. else
  167. {
  168. // if foreground is black set the foreground to previous
  169. // background colour to let it be visible
  170. if (!pg->data[y][x].fg)
  171. {pg->data[y][x].fg=pg->data[y][x].bg;}
  172. }
  173. //check if attributes changed,
  174. //if yes then print chars and update first_unprinted
  175. //if not then go to next char
  176. if (x)
  177. {
  178. if (((
  179. (pg->data[y][x].attr & EA_BLINK)
  180. ==
  181. (pg->data[y][x-1].attr & EA_BLINK)
  182. )
  183. &&
  184. (
  185. pg->data[y][x].fg == pg->data[y][x-1].fg
  186. ))
  187. &&(x!=last_nonblank))
  188. { continue; }
  189. }
  190. else continue;
  191. {
  192. int z=first_unprinted;
  193. for(;(pg->data[y][z].ch==' ') && (z<x);z++)
  194. {
  195. if (last_space)
  196. {
  197. fprintf(fp,"&nbsp");
  198. last_space=0;
  199. nbsp=1;
  200. }
  201. else
  202. {
  203. fputc(' ',fp);
  204. last_space=1;
  205. nbsp=0;
  206. }
  207. }
  208. first_unprinted=z;
  209. if (z==x) continue;
  210. if (pg->data[y][first_unprinted].attr & EA_BLINK)
  211. {
  212. fprintf(fp,"<blink>");
  213. nbsp=0;
  214. }
  215. if (pg->data[y][first_unprinted].fg!=7)
  216. {
  217. fprintf(fp,"<font color=\"%s\">",
  218. html_colours[pg->data[y][first_unprinted].fg]);
  219. nbsp=0;
  220. }
  221. for(;(z<x)||(z==last_nonblank);z++)
  222. {
  223. if (pg->data[y][z].ch==' ')
  224. {
  225. for(;(pg->data[y][z].ch==' ') && (z<x);z++)
  226. {
  227. if (last_space)
  228. {
  229. fprintf(fp,"&nbsp");
  230. last_space=0;
  231. nbsp=1;
  232. }
  233. else
  234. {
  235. fputc(' ',fp);
  236. last_space=1;
  237. nbsp=0;
  238. }
  239. }
  240. z--;
  241. }
  242. else
  243. {
  244. //if previous nbsp --> put semicolon!!!
  245. if (nbsp) fputc(';',fp);
  246. fputc(pg->data[y][z].ch,fp);
  247. last_space=0;
  248. nbsp=0;
  249. }
  250. }
  251. if (pg->data[y][first_unprinted].fg!=7)
  252. {
  253. fprintf(fp,"</font>");
  254. }
  255. if (pg->data[y][first_unprinted].attr & EA_BLINK)
  256. fprintf(fp,"</blink>");
  257. first_unprinted=z;
  258. }
  259. }
  260. fputs("<br>",fp);
  261. HTML_NL
  262. }
  263. fputs("</b></tt>",fp);
  264. if (!D->bare)
  265. fputs("</body></html>",fp);
  266. fclose(fp);
  267. return 0;
  268. }