home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / word2x0a.zip / source / latex-fmt.cc (.txt) < prev    next >
LaTeX Document  |  1998-08-08  |  12KB  |  398 lines

  1. /* $Id: latex-fmt.cc,v 1.15 1997/04/13 13:26:38 dps Exp dps $ */
  2. #include "config.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include <unistd.h>
  7. #include <ctype.h>
  8. #ifdef HAVE_SYS_STAT_H
  9. #include <sys/stat.h>
  10. #endif
  11. #include "interface.h"
  12. #include "lib.h"
  13. #include "latex-table.h"
  14. #include "fmt-latex.h"
  15. static const cmap tex_map[]=
  16.     { '\n', "\\\\\n" },             // Newline
  17.     { 0x1E, "-" },             // Unbreakable join
  18.     { 0x1F, "\\-" },             // Soft hypen
  19.     { '#', "{\\#}" },             // #
  20.     { '$', "{\\$}" },             // $
  21.     { '%', "{\\%}" },             // %  (5th element)
  22.     { '&', "{\\&}" },             // & 
  23.     { '@', "{\\@}" },             // @
  24.     { '\\', "$\\backslash$" },         // backslash
  25.     { '^', "{\\^}" },             // ^
  26.     { '_', "{\\_}" },             // _  (10th element)
  27.     { '{', "{\\{}" },             // {
  28.     { '}', "{\\}}" },             // }
  29.     { '~', "{\\~}" },             // ~
  30.     { CH_SUSPECT, "" },             // Delete suspect data markers
  31.     { 0x85, "\\unskip\\ldots" },     // Dots
  32.     { 0x91, "{`}" },             // 91 = left quote (15th element)
  33.     { 0x92, "{'}" },             // 92 = right quote
  34.     { 0x93, "``" },             // 93 = opening double quote
  35.     { 0x94, "''" },             // 94 = closing double quote
  36.     { 0x96, "--" },             // em-dash
  37.     { 0x97, "---" },             // en-dash (20th element)
  38.     { 0x99, "${}^{\\rm TM}$" },         // Trademark
  39.     { 0xA0, "~" },             // Unbreakable space
  40.     { 0xA3, "$\\leq$" },         // <= came out as A3, also pounds
  41.     { 0xA9, "{\\copyright}" },         // Copyright
  42.     { 0xAB, "$<\\!\\!<$" },         // Openning << quotes (25th element)
  43.     { 0xAE, "{\\reg}" },         // reserved sign
  44.     { 0xB3, "$\\geq$" },         // Greater than or = came out as B3
  45.     { 0xBB, "$>\\!\\!>$" },         // Closing >> quotes (28th element)
  46.     { 0xDF, "{\\ss}" },             // beta
  47.     { 0xE4, "\\\"a" },             // a with umlualt
  48.     { 0xE9, "\\'e" },             // e grave??
  49.     { 0xF1, "\\=n" },             // n bar
  50.     { 0xF6, "\\\"o" },             // o with umlualt
  51.     { 0xFA, "\\.u" },             // u with dot?
  52.     { 0xFC, "\\\"u" },             // u with umlualt.
  53. tblock *__latex_do_map(const char *s)
  54.     tblock *out;
  55.     out=map_string(s, tex_map);
  56.     return out;
  57. /* Preamble */
  58. static void preamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  59.             void *d)
  60.     time_t now;
  61. #ifdef HAVE_FSTAT
  62.     struct stat st;
  63. #endif
  64.     char *tnow, *tdoc;
  65.     t=t;
  66.     d=d;
  67.     now=time(NULL);
  68.     tnow=(fmt->date)(now);
  69. #ifdef HAVE_FSTAT
  70.     if (fstat(fileno(out), &st)==-1)
  71.     {
  72.     fprintf(stderr, "Warning: fstat failed\n");
  73.     st.st_mtime=now;
  74.     }
  75.     tdoc=fmt->date(st.st_mtime);
  76. #else
  77.     tdoc="date not known";
  78. #endif
  79.     fprintf(out,
  80.         "%% Generated by word2x on %s\n"
  81.         "%%\n"
  82.         "\\date{%s}\n"
  83.         "\\documentclass{article}\n"
  84.         "\\usepackage{amstext}\n"
  85.         "\\def\\reg{\\setbox0\\hbox{$\\mathchar\"20D$}%%\n"
  86.         "\\hbox to 0pt{\\hbox to \\wd0{\\hfill\\,\\rm R\\hfill}\\hss}%%\n"
  87.         "$\\mathchar\"20D$}\n"
  88.         "\\usepackage[latin1]{inputenc}\n"
  89.         "\\begin{document}\n",
  90.         tnow, tdoc);
  91.     free(tnow);
  92.     free(tdoc);
  93. /* Postamble */
  94. static void postamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  95.             void *d)
  96.     struct latex_data *dp;
  97.     fmt=fmt;
  98.     t=t;
  99.     dp=(struct latex_data *) d;
  100.     fputs("\\end{document}\n", out);
  101. /* Allocate local data */
  102. static void *allocate_latex(void)
  103.     struct latex_data *tdata;
  104.     int i;
  105.     tdata=new(struct latex_data);
  106.     tdata->tabl=NULL;
  107.     tdata->last_tc=NULL;
  108.     tdata->unit_d.unit_type=1;
  109.     tdata->list_flg=0;
  110.     for (i=0; i<4; i++)
  111.     tdata->unit_d.unit_number[i]=-1;
  112.     return tdata;
  113. /* Free local data */
  114. static void free_latex(void *d)
  115.     struct latex_data *tdata;
  116.     tdata=(struct latex_data *) d;
  117.     if (tdata->tabl!=NULL)
  118.     delete(tdata->tabl);
  119. static void ltx_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  120.              void *d)
  121.     d=d;
  122.     switch(*(t->data.d))
  123.     {
  124.     case CH_PAGE:
  125.     if (fmt->flags.new_pages)
  126.         fputs("%\n\\newpage%\n", out);
  127.     break;
  128.     default:
  129.     break;
  130.     }
  131. /* item */
  132. static void ltx_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  133.             void *d)
  134.     struct latex_data *dp;
  135.     fmt=fmt;
  136.     t=t;
  137.     out=out;
  138.     dp=(struct latex_data *) d;
  139.     dp->list_flg=1;
  140. /* start list */
  141. static void ltx_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  142.             void *d)
  143.     fmt=fmt;
  144.     d=d;
  145.     fprintf(out, "\n\\begin{%s}\n", t->data.d);    // Prior argement with reader
  146. /* end list */
  147. static void ltx_end_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  148.             void *d)
  149.     fmt=fmt;
  150.     d=d;
  151.     fprintf(out, "\n\\end{%s}\n", t->data.d);    // Prior argement with reader
  152. /* Find part number and return it or -1 if no number */
  153. int get_part_num(const char *st, const char *fence)
  154.     int n;
  155.     while (st<fence)
  156.     {
  157.     if (isspace(*st))
  158.         st++;
  159.         continue;
  160.     if (isdigit(*st))
  161.         n=0;
  162.         while (st<fence && isdigit(*st))
  163.         {
  164.         n=n*10+(*st)-'0';
  165.         st++;
  166.         }
  167.         if (!isspace(*st))
  168.         return -1;
  169.         else
  170.         return n;
  171.     if (isupper(*st) && isspace(*(st+1)))
  172.         return (*st)-'A'+1;
  173.     /* Nothing else understood at this time */
  174.     return -1;
  175.     }
  176.     return -1;
  177.  * Paragraphs are easy, but get complicated due to need to work out
  178.  * which things are actually chapter headings, etc
  179. static void fold_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
  180.               void *d)
  181.     tblock *b, *ts, op;
  182.     const char *s, *t, *pt;
  183.     struct latex_data *dp;
  184.     int do_add, has_num, i, j;
  185.     static const char *const sects[]=
  186.     {
  187.     "chapter", "section", "subsection", "subsubsection"
  188.     };
  189.     dp=(struct latex_data *) d;
  190.     do_add=0;
  191.     dp->par_flg=1;
  192.     /* Even this much is under 100%!! */
  193.     pt=(tok->data.d);
  194.     if (*pt=='\0')
  195.     return;
  196.     if (dp->last_tc!=NULL)
  197.     {
  198.     if (strcmp(dp->last_tc, pt)==0)
  199.         op.add("\\addcontentsline{toc}{");
  200.         op.add(sects[dp->unit_d.unit_type]); op.add("}{");
  201.         op.add(dp->last_tc); op.add("}\n\\");
  202.         op.add(sects[dp->unit_d.unit_type]);
  203.         op.add("*{");
  204.         do_add=1;
  205.     else
  206.         s=dp->last_tc+strlen(dp->last_tc)-strlen(pt);
  207.         if (strcmp(s, pt)==0)
  208.         {
  209.         /* Find type */
  210.         for (i=0; i< (int) N(sects)-1; i++)
  211.             if (strncasecmp(dp->last_tc, sects[i],
  212.                     strlen(sects[i]))==0)
  213.             break;
  214.         t=dp->last_tc+strlen(sects[i]);
  215.         has_num=get_part_num(t,s);
  216.         if (has_num==-1)
  217.             op.add("\\addcontentsline{toc}{");
  218.             op.add(sects[i]); op.add("}{");
  219.             op.add(dp->last_tc);
  220.             op.add("}\n");
  221.         op.add('\\');
  222.         op.add(sects[i]);
  223.         op.add((has_num!=-1) ? "{" : "*{");
  224.         if (dp->unit_d.unit_number[i]==-1)
  225.             dp->unit_d.unit_number[i]=(has_num==-1) ? 1 : has_num;
  226.             for (j=i+1; j< (int) N(sects); j++)
  227.             dp->unit_d.unit_number[j]=0;
  228.         if (i< (int) N(sects)-1)
  229.             dp->unit_d.unit_type=i+1;
  230.         else
  231.             dp->unit_d.unit_type=i;
  232.         do_add=1;
  233.         }
  234.     free((void *) dp->last_tc);
  235.     dp->last_tc=NULL;
  236.     }
  237.     else
  238.     {
  239.     if (dp->list_flg)
  240.         op.add("\\item ");
  241.     else
  242.         if (strlen(pt)>0 && strlen(pt)<PAR_TRESHOLD_LEN)
  243.         {
  244.         if (strcasecmp(pt,"Appendix")==0)
  245.             op.add("\\appendix\n\\");
  246.             dp->unit_d.unit_type=(dp->unit_d.unit_number[0]==-1) ? 1:0;
  247.             op.add(sects[dp->unit_d.unit_type]);
  248.             op.add("{");
  249.             do_add=1;
  250.             for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++)
  251.             dp->unit_d.unit_number[j]=0;
  252.         else if (strcasecmp(pt,"Bibliography")==0)
  253.             dp->unit_d.unit_type= (dp->unit_d.unit_number[0]==-1) ? 1:0;
  254.             op.add('\\');
  255.             op.add(sects[dp->unit_d.unit_type]);
  256.             op.add("*{");
  257.             do_add=1;
  258.             for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++)
  259.             dp->unit_d.unit_number[j]=0;
  260.         else
  261.             int i,n,c,l, unit;
  262.             
  263.             unit=dp->unit_d.unit_type-1;
  264.             l=strlen(pt);
  265.             i=0;
  266.             while(1)
  267.             {
  268.             n=0;
  269.             for (c=0; i<l && isdigit(pt[i]); i++, c++)
  270.                 n=n*10+pt[i]-'0';
  271.             if (c==0)
  272.                 break;
  273.             unit++;
  274.             if (unit>= (int) N(sects))
  275.                 unit=N(sects)-1;
  276.                 break;
  277.             if (dp->unit_d.unit_number[unit]==-1)
  278.                 if (n>MAX_START_NUM)
  279.                 goto out_normal;
  280.                 
  281.                 dp->unit_d.unit_number[unit]=n;
  282.                 for (j=unit+1; j< (int) N(sects); j++)
  283.                 dp->unit_d.unit_number[j]=0;
  284.             else if (dp->unit_d.unit_number[unit]+1==n)
  285.                 dp->unit_d.unit_number[unit]++;
  286.                 for (j=unit+1; j< (int) N(sects); j++)
  287.                 dp->unit_d.unit_number[j]=0;
  288.             else if (dp->unit_d.unit_number[unit]!=n)
  289.                 goto out_normal;
  290.             if (pt[i]!='.')
  291.                 break;
  292.             i++;
  293.             }
  294.             if (unit==dp->unit_d.unit_type-1)
  295.             goto out_normal;
  296.             op.add('\\');
  297.             op.add(sects[unit]);
  298.             op.add((i>0) ? "{" : "*{");
  299.             while(isspace(pt[i])) i++;
  300.             pt+=i;
  301.             do_add=1;
  302.         }
  303.     out_normal: ;
  304.     dp->list_flg=0;
  305.     }
  306.     ts=map_string(pt, tex_map);
  307.     op.add(*ts);
  308.     if (do_add)
  309.     op.add('}');
  310.     delete(ts);
  311.     b=word_wrap(op, "\n", "\n", fmt->maxline, 0);
  312.     fputs((*b), out);
  313.     delete(b);
  314. /* End of paragraph */
  315. static void end_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
  316.              void *d)
  317.     struct latex_data *dp;
  318.     tok=tok;
  319.     fmt=fmt;
  320.     dp=(struct latex_data *) d;
  321.     dp->par_flg=0;
  322.         
  323.     fputs("\n\n", out);
  324. /* Start a table === allocate table and initialise */
  325. static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  326.               void *d)
  327.     struct latex_data *tdata;
  328.     out=out;
  329.     fmt=fmt;
  330.     tdata=(struct latex_data *) d;
  331.     tdata->col=0;
  332.     tdata->row=0;
  333.     tdata->tabl=new(latex_table)(t->data.table.cols, t->data.table.rows);
  334.     tdata->par_flg=0;
  335. /* End of a table==print the table */
  336. static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  337.                void *d)
  338.     struct latex_data *tdata;
  339.     t=t;
  340.     tdata=(struct latex_data *) d;
  341.     tdata->tabl->print_table(fmt->maxline, out); // Print table
  342.     delete(tdata->tabl);
  343.     tdata->tabl=NULL;
  344. /* start row==set column to 0 */
  345. static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  346.               void *d)
  347.     struct latex_data *tdata;
  348.     out=out;
  349.     fmt=fmt;
  350.     t=t;
  351.     tdata=(struct latex_data *) d;
  352.     tdata->col=0;
  353. /* end row==add one to row */
  354. static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  355.             void *d)
  356.     struct latex_data *tdata;
  357.     fmt=fmt;
  358.     t=t;
  359.     out=out;
  360.     tdata=(struct latex_data *) d;
  361.     tdata->row++;
  362. /* Start field === set field */
  363. static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  364.               void *d)
  365.     struct latex_data *tdata;
  366.     tdata=(struct latex_data *) d;
  367.     out=out;
  368.     fmt=fmt;
  369.     tdata->tabl->set(tdata->col, tdata->row, t->data.d);
  370. /* end field==add one to col */
  371. static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
  372.             void *d)
  373.     struct latex_data *tdata;
  374.     out=out;
  375.     fmt=fmt;
  376.     t=t;
  377.     tdata=(struct latex_data *) d;
  378.     tdata->col++;
  379. /* pointers to the functions that do the work */
  380. docfmt latexfmt=
  381.     { 0 },                // Ignore page breaks
  382.     76,                    // Width
  383.     "\n",                // Use \n as line ends
  384.     allocate_latex,            // Allocate space
  385.     free_latex,                // Free text
  386.     {
  387.     { preamble, postamble },    // End and start of document---do nothing
  388.     { fold_para, end_para },    // Paragraph
  389.     { alloc_tbl, format_tbl },  // Start/end table
  390.     { set_field, inc_col },        // Start/end field
  391.     { start_row, inc_row },        // Start/end row
  392.     { ltx_embed, null_proc },   // Throw away embed messages
  393.     { ltx_list, ltx_end_list }, // Start/end list
  394.     { ltx_item, null_proc },    // Start/end item
  395.     { ltx_code, null_proc },    // Codes end do not happen
  396.     { null_proc, null_proc }    // Do not understanding anything else
  397.     }
  398.