HTTeXGen.c
上传用户:zlh9724
上传日期:2007-01-04
资源大小:1991k
文件大小:16k
源码类别:

浏览器

开发平台:

Unix_Linux

  1. /*      HTTeXGen.c
  2. ** HTML -> LaTeX CONVERTER
  3. **
  4. ** (c) COPYRIGHT MIT 1995.
  5. ** Please first read the full copyright statement in the file COPYRIGH.
  6. **
  7. **  This version of the HTML object sends LaTeX to the output stream.
  8. **  No attributes are considered in the translation!
  9. **  The module uses simple 1:1 table-conversions, but this COULD be
  10. ** expanded to a stack-machine. This would then be in start_element and
  11. ** end_element...
  12. ** Henrik 07/03-94
  13. **
  14. ** HISTORY:
  15. **  8 Jul 94  FM Insulate free() from _free structure element.
  16. **
  17. */
  18. #define BUFFER_SIZE 80 /* Line buffer attempts to make neat breaks */
  19. #define WORD_DELIMITERS ",;:[]()"
  20. /* Library include files */
  21. #include "tcp.h"
  22. #include "HTUtils.h"
  23. #include "HTTeXGen.h"
  24. #include "HTMLPDTD.h"
  25. #include "HTStruct.h"
  26. #include "HTFormat.h"
  27. /* HTML Object
  28. ** -----------
  29. */
  30. struct _HTStream {
  31. CONST HTStreamClass * isa;
  32. HTStream *  target;
  33. HTStreamClass targetClass;    /* COPY for speed */
  34. };
  35. struct _HTStructured {
  36. CONST HTStructuredClass * isa;
  37. HTStream *  target;
  38. HTStreamClass targetClass;    /* COPY for speed */
  39. CONST SGML_dtd * dtd;
  40. char buffer[2*BUFFER_SIZE];   /* See note */
  41. char * write_pointer;
  42. char * line_break;
  43. BOOL sensitive;          /* Can we put n */
  44. BOOL preformatted;     /* Is it verbatim? */
  45. BOOL markup;     /* If doing LaTeX markup */
  46. BOOL startup;      /* To skip MIME header */
  47. };
  48. /* The buffer has to be bigger than 80 as latex markup might make the line
  49.    longer before we get to flush it. */
  50. PRIVATE char *TeX_names[HTMLP_ELEMENTS][2] = {
  51.     { "",        "" }, /* HTML_A */
  52.     { "", "" }, /* HTML_ABBREV */
  53.     { "n\begin{abstract}n","n\end{abstract}n"},  /* HTML_ABSTRACT */
  54.     { "", "" }, /* HTML_ACRONYM */
  55.     { "", "" }, /* HTML_ADDED */
  56.     { "{\it ", "}" }, /* HTML_ADDRESS */
  57.     { "", "" }, /* HTML_ARG */
  58.     { "{\bf ", "}" }, /* HTML_B */
  59.     { "", "" }, /* HTML_BASE */
  60.     { "{\sf ", "}" }, /* HTML_BLOCKQUOTE  */
  61.     { "",  "" }, /* HTML_BODY      */
  62.     { "", "" }, /* HTML_BOX */
  63.     { "", "" }, /* HTML_BR */
  64.     { "", "" }, /* HTML_BYLINE */
  65.     { "", "" }, /* HTML_CAPTION */
  66.     { "", "" }, /* HTML_CHANGED */
  67.     { "\cite{",       "}" }, /* HTML_CITE */
  68.     { "", "" }, /* HTML_CMD */
  69.     { "{\tt ", "}" }, /* HTML_CODE */
  70.     { "n\typeout{", "}n" }, /* HTML_COMMENT */
  71.     { "]", "" }, /* HTML_DD */
  72.     { "", "" }, /* HTML_DFN */
  73.     { "", "" }, /* HTML_DIR */
  74.     { "n\begin{description}","n\end{description}n"}, /* HTML_DL  */
  75.     { "n\item[", "" }, /* HTML_DT */
  76.     { "{\em ", "}" }, /* HTML_EM */
  77.     { "", "" }, /* HTML_FIG */
  78.     { "n\footnote{", "}n"         }, /* HTML_FOOTNOTE */
  79.     { "", ""  }, /* HTML_FORM */
  80.     { "n\chapter{", "}n" }, /* HTML_H1 */
  81.     { "n\section{", "}n" }, /* HTML_H2 */
  82.     { "n\subsection{","}n"   }, /* HTML_H3 */
  83.     { "n\subsubsection{","}n" }, /* HTML_H4 */
  84.     { "n\paragraph{", "}n" }, /* HTML_H5 */
  85.     { "n\subparagraph{","}n" }, /* HTML_H6 */
  86.     { "", "n" }, /* HTML_H7 */
  87.     { "", "" }, /* HTML_HEAD */
  88.     { "", "" }, /* HTML_HR */
  89.     { "", "" },  /* HTML_HTML */
  90.     { "", "" },     /* HTML_HTMLPLUS */
  91.     { "{\it ", "}" }, /* HTML_I */
  92.     { "", "" }, /* HTML_IMAGE */
  93.     { "_FIGUR_", "" }, /* HTML_IMG */
  94.     { "", "" }, /* HTML_INPUT */
  95.     { "", "" }, /* HTML_ISINDEX */
  96.     { "{\tt ", "}" }, /* HTML_KBD */
  97.     { "", "" }, /* HTML_L */
  98.     { "n\item ",      ""          }, /* HTML_LI */
  99.     { "", "" }, /* HTML_LINK */
  100.     { "", "" }, /* HTML_LISTING */
  101.     { "", "" }, /* HTML_LIT */
  102.     { "", "" }, /* HTML_MARGIN */
  103.     { "", "" }, /* HTML_MATH */
  104.     { "", "" }, /* HTML_MENU */
  105.     { "", "" }, /* HTML_NEXTID */
  106.     { "", "" }, /* HTML_NOTE */
  107.     { "n\begin{enumerate}n","n\end{enumerate}n"}, /* HTML_OL      */
  108.     { "", "" }, /* HTML_OPTION */
  109.     { "", "" }, /* HTML_OVER */
  110.     { "nn", "" }, /* HTML_P */
  111.     { "", "" }, /* HTML_PERSON */
  112.     { "", "" }, /* HTML_PLAINTEXT */
  113.     { "n\begin{verbatim}"," \end{verbatim}n"},  /* HTML_PRE        */
  114.     { "", "" }, /* HTML_Q */
  115.     { "\begin{quote}", "\end{quote}"},  /* HTML_QUOTE */
  116.     { "", "" }, /* HTML_RENDER */
  117.     { "", "" }, /* HTML_REMOVED */
  118.     { "", "" }, /* HTML_S */
  119.     { "", "" }, /* HTML_SAMP */
  120.     { "",  "" }, /* HTML_SELECT */
  121.     { "{\bf ", "}" }, /* HTML_STRONG */
  122.     { "",  "" }, /* HTML_SUB */
  123.     { "", "" }, /* HTML_SUP */
  124.     { "", "" }, /* HTML_TAB */
  125.     { "", "" }, /* HTML_TABLE */
  126.     { "", "" }, /* HTML_TD */
  127.     { "", "" }, /* HTML_TEXTAREA */
  128.     { "", "" }, /* HTML_TH */
  129.     { "n\title{", "}n\author{}n\maketitlen"},  /* HTML_TITLE */
  130.     { "", "" }, /* HTML_TR */
  131.     { "", "" }, /* HTML_TT */
  132.     { "", "" }, /* HTML_U */
  133.     { "n\begin{itemize}","n\end{itemize}n"},   /* HTML_UL */
  134.     { "", "" }, /* HTML_VAR */
  135.     { "{\sf ", "}" } /* HTML_XMP */
  136. };
  137. PRIVATE char *TeX_entities[HTML_ENTITIES] = {
  138.     "\AE ", /*"AElig",  capital AE diphthong (ligature) */ 
  139.     "\'{A}", /*"Aacute",  capital A, acute accent */ 
  140.     "\^{A}", /*"Acirc",  capital A, circumflex accent */ 
  141.     "\`{A}", /*"Agrave",  capital A, grave accent */ 
  142.     "\AA",      /*"Aring",  capital A, ring */ 
  143.     "\~{A}",  /*"Atilde",  capital A, tilde */ 
  144.     "\"{A}", /*"Auml",  capital A, dieresis or umlaut mark */ 
  145.     "\c{C}", /*"Ccedil",  capital C, cedilla */ 
  146.     "\OE ", /*"ETH",  capital Eth, Icelandic */ 
  147.     "\'{E}", /*"Eacute",  capital E, acute accent */ 
  148.     "\^{E}", /*"Ecirc",  capital E, circumflex accent */ 
  149.     "\`{E}", /*"Egrave",  capital E, grave accent */ 
  150.     "\"{E}", /*"Euml",  capital E, dieresis or umlaut mark */ 
  151.     "\'{I}", /*"Iacute",  capital I, acute accent */ 
  152.     "\^{I}", /*"Icirc",  capital I, circumflex accent */ 
  153.     "\`{I}", /*"Igrave",  capital I, grave accent */ 
  154.     "\"{I}", /*"Iuml",  capital I, dieresis or umlaut mark */ 
  155.     "\~{N}", /*"Ntilde",  capital N, tilde */ 
  156.     "\'{O}", /*"Oacute",  capital O, acute accent */ 
  157.     "\^{O}", /*"Ocirc",  capital O, circumflex accent */ 
  158.     "\`{O}", /*"Ograve",  capital O, grave accent */ 
  159.     "\O ",             /*"Oslash",  capital O, slash */ 
  160.     "\~{O}", /*"Otilde",  capital O, tilde */ 
  161.     "\"{O}",         /*"Ouml",  capital O, dieresis or umlaut mark */ 
  162.     " ",       /*"THORN",  capital THORN, Icelandic */ 
  163.     "\'{U}", /*"Uacute",  capital U, acute accent */ 
  164.     "\^{U}", /*"Ucirc",  capital U, circumflex accent */ 
  165.     "\`{U}", /*"Ugrave",  capital U, grave accent */ 
  166.     "\"{U}", /*"Uuml",  capital U, dieresis or umlaut mark */ 
  167.     "\'{Y}", /*"Yacute",  capital Y, acute accent */ 
  168.     "\'{a}", /*"aacute",  small a, acute accent */ 
  169.     "\^{a}", /*"acirc",  small a, circumflex accent */ 
  170.     "\ae ", /*"aelig",  small ae diphthong (ligature) */ 
  171.     "\`{a}", /*"agrave",  small a, grave accent */ 
  172.     "&",             /*"amp",  ampersand */ 
  173.     "\aa ", /*"aring",  small a, ring */ 
  174.     "\~{a}", /*"atilde",  small a, tilde */ 
  175.     "\"{a}", /*"auml",  small a, dieresis or umlaut mark */ 
  176.     "\c{c}", /*"ccedil",  small c, cedilla */ 
  177.     "\'{e}", /*"eacute",  small e, acute accent */ 
  178.     "\^{c}", /*"ecirc",  small e, circumflex accent */ 
  179.     "\`{c}", /*"egrave",  small e, grave accent */ 
  180.     "\oe ", /*"eth",  small eth, Icelandic */ 
  181.     "\"{e}", /*"euml",  small e, dieresis or umlaut mark */ 
  182.     ">", /*"gt",  greater than */ 
  183.     "\'{\i}",       /*"iacute",  small i, acute accent */ 
  184.     "\^{\i}",        /*"icirc",  small i, circumflex accent */ 
  185.     "\`{\i}",        /*"igrave",  small i, grave accent */ 
  186.     "\"{\i}",      /*"iuml",  small i, dieresis or umlaut mark */ 
  187.     "<", /*"lt",  less than */ 
  188.     "\~{n}", /*"ntilde",  small n, tilde */ 
  189.     "\'{o}", /*"oacute",  small o, acute accent */ 
  190.     "\~{o}", /*"ocirc",  small o, circumflex accent */ 
  191.     "\`{o}", /*"ograve",  small o, grave accent */ 
  192.     "\o ",             /*"oslash",  small o, slash */ 
  193.     "\~{o}",          /*"otilde",  small o, tilde */ 
  194.     "\"{o}",     /*"ouml",  small o, dieresis or umlaut mark */ 
  195.     """,     /*"quot",  double quote sign - June 1994 */ 
  196.     "\ss ", /*"szlig",  small sharp s, German (sz ligature)*/ 
  197.     " ",        /*"thorn",  small thorn, Icelandic */ 
  198.     "\'{u}",         /*"uacute",  small u, acute accent */ 
  199.     "\^{u}",         /*"ucirc",  small u, circumflex accent */ 
  200.     "\`{u}",          /*"ugrave",  small u, grave accent */ 
  201.     "\"{u}",         /*"uuml",  small u, dieresis or umlaut mark */ 
  202.     "\'{y}", /*"yacute",  small y, acute accent */ 
  203.     "\"{y}"      /*"yuml",  small y, dieresis or umlaut mark */ 
  204. };
  205. /* Flush Buffer
  206. ** ------------
  207. */
  208. PRIVATE int HTTeXGen_flush (HTStructured * me)
  209. {
  210.     int status;
  211.     if ((status =
  212.  (*me->targetClass.put_block)(me->target, me->buffer,
  213.       me->write_pointer-me->buffer)) != HT_OK)
  214. return status;
  215.     me->write_pointer = me->buffer;
  216.     me->line_break = me->buffer;
  217.     return (*me->targetClass.flush)(me->target);
  218. }
  219. /* Character handling
  220. ** ------------------
  221. **
  222. */
  223. PRIVATE int HTTeXGen_put_character (HTStructured * me, char c)
  224. {
  225.     if (!me->startup)                       /* To skip MIME header */
  226. return HT_OK;
  227.     if (c=='n') {
  228. if (me->markup || me->preformatted) {     /* Put out as is and flush */
  229.     *me->write_pointer++ = c;
  230.     HTTeXGen_flush(me);
  231.     return HT_OK;
  232. } else if (me->sensitive || *(me->write_pointer-1)==' ') {
  233.     return HT_OK;
  234.         } else
  235.     *me->write_pointer++ = ' ';       /* Try to pretty print */
  236.     } else if (me->markup || me->preformatted) {
  237. *me->write_pointer++ = c;
  238.     } else if (c==' ' || c=='t') {               /* Skip space and tabs */
  239. if (*(me->write_pointer-1) != ' ')
  240.     *me->write_pointer++ = ' ';
  241. else
  242.     return HT_OK;
  243.     } else {
  244. if (c=='$' || c=='&' || c=='%' || c=='#' ||         /* Special chars */
  245.     c=='{' || c=='}' || c=='_') {
  246.     *me->write_pointer++ = '\';
  247.     *me->write_pointer++ = c;
  248. } else if (c=='\') {             /* Special names */
  249.     char *temp = "$\backslash$";
  250.     strcpy(me->write_pointer, temp);
  251.     me->write_pointer += strlen(temp);
  252. } else if (c=='^') {
  253.     char *temp = "$\hat{ }$";
  254.     strcpy(me->write_pointer, temp);
  255.     me->write_pointer += strlen(temp);     
  256. } else if (c=='~') {
  257.     char *temp = "$\tilde{ }$";
  258.     strcpy(me->write_pointer, temp);
  259.     me->write_pointer += strlen(temp);
  260. } else if (c=='|' || c=='<' || c=='>') {                /* Math mode */
  261.     *me->write_pointer++ = '$';
  262.     *me->write_pointer++ = c;
  263.     *me->write_pointer++ = '$';
  264. } else
  265.     *me->write_pointer++ = c;                /* Char seems normal */
  266.     }
  267.     if (c==' ')    /* Find delimiter */
  268. me->line_break = me->write_pointer;
  269.     else if (strchr(WORD_DELIMITERS, c))
  270. me->line_break = me->write_pointer-1;
  271.     /* Flush buffer out when full */
  272.     if (me->write_pointer >= me->buffer+BUFFER_SIZE-3) {
  273. #ifdef OLD_CODE
  274. if (me->markup || me->preformatted) {
  275. #endif /* OLD_CODE */
  276. if (me->preformatted) {
  277.     *me->write_pointer = 'n';
  278.     (*me->targetClass.put_block)(me->target,
  279.  me->buffer,
  280.  me->write_pointer-me->buffer+1);
  281.     me->write_pointer = me->buffer;
  282. } else {                   /* Use break-point */
  283.     char line_break_char = *me->line_break;
  284.     char *saved = me->line_break;
  285.     *me->line_break = 'n';
  286.     (*me->targetClass.put_block)(me->target,
  287.  me->buffer,
  288.  me->line_break-me->buffer+1);
  289.     *me->line_break = line_break_char;
  290.     {                                           /* move next line in */
  291. char *p = saved;
  292. char *q;
  293. for(q=me->buffer; p<me->write_pointer; )
  294.     *q++ = *p++;
  295.     }
  296.     me->write_pointer = me->buffer + (me->write_pointer-saved);
  297. }     
  298. me->line_break = me->buffer;
  299.     }
  300.     return HT_OK;
  301. }
  302. /* String handling
  303. ** ---------------
  304. */
  305. PRIVATE int HTTeXGen_put_string (HTStructured * me, CONST char* s)
  306. {
  307.     while (*s)
  308. HTTeXGen_put_character(me, *s++);
  309.     return HT_OK;
  310. }
  311. PRIVATE int HTTeXGen_write (HTStructured * me, CONST char* b, int l)
  312. {
  313.     while (l-- > 0)
  314. HTTeXGen_put_character(me, *b++);
  315.     return HT_OK;
  316. }
  317. /* Start Element
  318. ** -------------
  319. **
  320. **      No attributes are put to the output Henrik 07/03-94
  321. ** Does no assumptions of WHAT element is started...
  322. */
  323. PRIVATE void HTTeXGen_start_element (HTStructured *  me,
  324.      int element_number,
  325.      CONST BOOL * present,
  326.      CONST char ** value)
  327. {
  328.     me->startup = YES;         /* Now, let's get down to it */
  329.     if (me->preformatted == YES) {        /* Don't start markup in here */
  330. if (WWWTRACE)
  331.     TTYPrint(TDEST, "LaTeX....... No Markup in verbatim moden");
  332. return;
  333.     }
  334.     if (element_number == HTML_PRE)
  335. me->preformatted = YES;
  336.     if (element_number == HTML_CITE ||               /* No n here, please! */
  337. element_number == HTML_DT ||
  338. element_number == HTML_H1 ||
  339. element_number == HTML_H2 ||
  340. element_number == HTML_H3 ||
  341. element_number == HTML_H4 ||
  342. element_number == HTML_H5 ||
  343. element_number == HTML_H6 ||
  344. element_number == HTML_H7 ||
  345. element_number == HTML_TITLE)
  346. me->sensitive = YES;
  347.     else if (element_number == HTML_DD)         /* Only way to turn <DT> off */
  348. me->sensitive = NO;
  349.     me->markup = element_number == HTML_A ? NO : YES;
  350.     HTTeXGen_put_string(me, *TeX_names[element_number]);
  351.     me->markup = NO;
  352. }
  353. /* End Element
  354. ** -----------
  355. **
  356. ** Ends an markup element Henrik 07/03-94
  357. ** Does no assumptions of WHAT element is ended...
  358. */
  359. PRIVATE void HTTeXGen_end_element (HTStructured * me, int element_number)
  360. {
  361.     if (me->preformatted && element_number != HTML_PRE) {
  362. if (WWWTRACE)
  363.     TTYPrint(TDEST, "LaTeX....... No markup in verbatim moden");
  364. return;
  365.     }
  366.     me->preformatted = NO;
  367.     me->markup = YES;
  368.     HTTeXGen_put_string(me, *(TeX_names[element_number]+1));
  369.     me->markup = NO;
  370.     if (element_number == HTML_CITE ||
  371. element_number == HTML_DL ||
  372. element_number == HTML_H1 ||
  373. element_number == HTML_H2 ||
  374. element_number == HTML_H3 ||
  375. element_number == HTML_H4 ||
  376. element_number == HTML_H5 ||
  377. element_number == HTML_H6 ||
  378. element_number == HTML_H7 ||
  379. element_number == HTML_TITLE)
  380. me->sensitive = NO;
  381. }
  382. /* Expanding entities
  383. ** ------------------
  384. **
  385. */
  386. PRIVATE void HTTeXGen_put_entity (HTStructured * me, int entity_number)
  387. {
  388.     BOOL mark = me->markup;
  389.     if (*TeX_entities[entity_number] != '&' && /* Theese are converted later */
  390. *TeX_entities[entity_number] != '<' &&
  391. *TeX_entities[entity_number] != '>')
  392. me->markup = YES;
  393.     HTTeXGen_put_string(me, TeX_entities[entity_number]);
  394.     me->markup = mark;
  395. }
  396. /* Free an HTML object
  397. ** -------------------
  398. **
  399. */
  400. PRIVATE int HTTeXGen_free (HTStructured * me)
  401. {
  402.     HTTeXGen_flush(me);
  403.     (*me->targetClass.put_string)(me->target, "n\end{document}n");
  404.     HTTeXGen_flush(me);
  405.     (*me->targetClass._free)(me->target); /* ripple through */
  406.     HT_FREE(me);
  407.     return HT_OK;
  408. }
  409. PRIVATE int HTTeXGen_abort (HTStructured * me, HTList * e)
  410. {
  411.     HTTeXGen_free(me);
  412.     return HT_ERROR;
  413. }
  414. /* Structured Object Class
  415. ** -----------------------
  416. */
  417. PRIVATE CONST HTStructuredClass HTTeXGeneration = /* As opposed to print etc */
  418. {
  419. "HTMLToTeX",
  420. HTTeXGen_flush,
  421. HTTeXGen_free,
  422. HTTeXGen_abort,
  423. HTTeXGen_put_character,         HTTeXGen_put_string, HTTeXGen_write,
  424. HTTeXGen_start_element,  HTTeXGen_end_element,
  425. HTTeXGen_put_entity
  426. }; 
  427. /* HTConverter from HTML to TeX Stream
  428. ** ------------------------------------------
  429. **
  430. */
  431. PUBLIC HTStream* HTMLToTeX (HTRequest * request,
  432.     void * param,
  433.     HTFormat input_format,
  434.     HTFormat output_format,
  435.     HTStream * output_stream)
  436. {
  437.     HTStructured* me;
  438.     if ((me = (HTStructured *) HT_CALLOC(1, sizeof(*me))) == NULL)
  439.         HT_OUTOFMEM("HTMLToTeX");
  440.     me->isa = (HTStructuredClass*) &HTTeXGeneration;
  441.     me->dtd = &HTMLP_dtd;
  442.     me->target = output_stream;
  443.     me->targetClass = *me->target->isa;/* Copy pointers to routines for speed*/
  444.     me->write_pointer = me->buffer;
  445.     me->line_break =  me->buffer;
  446.     (*me->targetClass.put_string)(me->target,
  447.         "\documentstyle[11pt]{report}n\begin{document}n");
  448.     return SGML_new(&HTMLP_dtd, me);
  449. }