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 >
Wrap
LaTeX Document
|
1998-08-08
|
12KB
|
398 lines
/* $Id: latex-fmt.cc,v 1.15 1997/04/13 13:26:38 dps Exp dps $ */
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include "interface.h"
#include "lib.h"
#include "latex-table.h"
#include "fmt-latex.h"
static const cmap tex_map[]=
{ '\n', "\\\\\n" }, // Newline
{ 0x1E, "-" }, // Unbreakable join
{ 0x1F, "\\-" }, // Soft hypen
{ '#', "{\\#}" }, // #
{ '$', "{\\$}" }, // $
{ '%', "{\\%}" }, // % (5th element)
{ '&', "{\\&}" }, // &
{ '@', "{\\@}" }, // @
{ '\\', "$\\backslash$" }, // backslash
{ '^', "{\\^}" }, // ^
{ '_', "{\\_}" }, // _ (10th element)
{ '{', "{\\{}" }, // {
{ '}', "{\\}}" }, // }
{ '~', "{\\~}" }, // ~
{ CH_SUSPECT, "" }, // Delete suspect data markers
{ 0x85, "\\unskip\\ldots" }, // Dots
{ 0x91, "{`}" }, // 91 = left quote (15th element)
{ 0x92, "{'}" }, // 92 = right quote
{ 0x93, "``" }, // 93 = opening double quote
{ 0x94, "''" }, // 94 = closing double quote
{ 0x96, "--" }, // em-dash
{ 0x97, "---" }, // en-dash (20th element)
{ 0x99, "${}^{\\rm TM}$" }, // Trademark
{ 0xA0, "~" }, // Unbreakable space
{ 0xA3, "$\\leq$" }, // <= came out as A3, also pounds
{ 0xA9, "{\\copyright}" }, // Copyright
{ 0xAB, "$<\\!\\!<$" }, // Openning << quotes (25th element)
{ 0xAE, "{\\reg}" }, // reserved sign
{ 0xB3, "$\\geq$" }, // Greater than or = came out as B3
{ 0xBB, "$>\\!\\!>$" }, // Closing >> quotes (28th element)
{ 0xDF, "{\\ss}" }, // beta
{ 0xE4, "\\\"a" }, // a with umlualt
{ 0xE9, "\\'e" }, // e grave??
{ 0xF1, "\\=n" }, // n bar
{ 0xF6, "\\\"o" }, // o with umlualt
{ 0xFA, "\\.u" }, // u with dot?
{ 0xFC, "\\\"u" }, // u with umlualt.
tblock *__latex_do_map(const char *s)
tblock *out;
out=map_string(s, tex_map);
return out;
/* Preamble */
static void preamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
time_t now;
#ifdef HAVE_FSTAT
struct stat st;
#endif
char *tnow, *tdoc;
t=t;
d=d;
now=time(NULL);
tnow=(fmt->date)(now);
#ifdef HAVE_FSTAT
if (fstat(fileno(out), &st)==-1)
{
fprintf(stderr, "Warning: fstat failed\n");
st.st_mtime=now;
}
tdoc=fmt->date(st.st_mtime);
#else
tdoc="date not known";
#endif
fprintf(out,
"%% Generated by word2x on %s\n"
"%%\n"
"\\date{%s}\n"
"\\documentclass{article}\n"
"\\usepackage{amstext}\n"
"\\def\\reg{\\setbox0\\hbox{$\\mathchar\"20D$}%%\n"
"\\hbox to 0pt{\\hbox to \\wd0{\\hfill\\,\\rm R\\hfill}\\hss}%%\n"
"$\\mathchar\"20D$}\n"
"\\usepackage[latin1]{inputenc}\n"
"\\begin{document}\n",
tnow, tdoc);
free(tnow);
free(tdoc);
/* Postamble */
static void postamble(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *dp;
fmt=fmt;
t=t;
dp=(struct latex_data *) d;
fputs("\\end{document}\n", out);
/* Allocate local data */
static void *allocate_latex(void)
struct latex_data *tdata;
int i;
tdata=new(struct latex_data);
tdata->tabl=NULL;
tdata->last_tc=NULL;
tdata->unit_d.unit_type=1;
tdata->list_flg=0;
for (i=0; i<4; i++)
tdata->unit_d.unit_number[i]=-1;
return tdata;
/* Free local data */
static void free_latex(void *d)
struct latex_data *tdata;
tdata=(struct latex_data *) d;
if (tdata->tabl!=NULL)
delete(tdata->tabl);
static void ltx_code(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
d=d;
switch(*(t->data.d))
{
case CH_PAGE:
if (fmt->flags.new_pages)
fputs("%\n\\newpage%\n", out);
break;
default:
break;
}
/* item */
static void ltx_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *dp;
fmt=fmt;
t=t;
out=out;
dp=(struct latex_data *) d;
dp->list_flg=1;
/* start list */
static void ltx_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
fmt=fmt;
d=d;
fprintf(out, "\n\\begin{%s}\n", t->data.d); // Prior argement with reader
/* end list */
static void ltx_end_list(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
fmt=fmt;
d=d;
fprintf(out, "\n\\end{%s}\n", t->data.d); // Prior argement with reader
/* Find part number and return it or -1 if no number */
int get_part_num(const char *st, const char *fence)
int n;
while (st<fence)
{
if (isspace(*st))
st++;
continue;
if (isdigit(*st))
n=0;
while (st<fence && isdigit(*st))
{
n=n*10+(*st)-'0';
st++;
}
if (!isspace(*st))
return -1;
else
return n;
if (isupper(*st) && isspace(*(st+1)))
return (*st)-'A'+1;
/* Nothing else understood at this time */
return -1;
}
return -1;
* Paragraphs are easy, but get complicated due to need to work out
* which things are actually chapter headings, etc
static void fold_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
void *d)
tblock *b, *ts, op;
const char *s, *t, *pt;
struct latex_data *dp;
int do_add, has_num, i, j;
static const char *const sects[]=
{
"chapter", "section", "subsection", "subsubsection"
};
dp=(struct latex_data *) d;
do_add=0;
dp->par_flg=1;
/* Even this much is under 100%!! */
pt=(tok->data.d);
if (*pt=='\0')
return;
if (dp->last_tc!=NULL)
{
if (strcmp(dp->last_tc, pt)==0)
op.add("\\addcontentsline{toc}{");
op.add(sects[dp->unit_d.unit_type]); op.add("}{");
op.add(dp->last_tc); op.add("}\n\\");
op.add(sects[dp->unit_d.unit_type]);
op.add("*{");
do_add=1;
else
s=dp->last_tc+strlen(dp->last_tc)-strlen(pt);
if (strcmp(s, pt)==0)
{
/* Find type */
for (i=0; i< (int) N(sects)-1; i++)
if (strncasecmp(dp->last_tc, sects[i],
strlen(sects[i]))==0)
break;
t=dp->last_tc+strlen(sects[i]);
has_num=get_part_num(t,s);
if (has_num==-1)
op.add("\\addcontentsline{toc}{");
op.add(sects[i]); op.add("}{");
op.add(dp->last_tc);
op.add("}\n");
op.add('\\');
op.add(sects[i]);
op.add((has_num!=-1) ? "{" : "*{");
if (dp->unit_d.unit_number[i]==-1)
dp->unit_d.unit_number[i]=(has_num==-1) ? 1 : has_num;
for (j=i+1; j< (int) N(sects); j++)
dp->unit_d.unit_number[j]=0;
if (i< (int) N(sects)-1)
dp->unit_d.unit_type=i+1;
else
dp->unit_d.unit_type=i;
do_add=1;
}
free((void *) dp->last_tc);
dp->last_tc=NULL;
}
else
{
if (dp->list_flg)
op.add("\\item ");
else
if (strlen(pt)>0 && strlen(pt)<PAR_TRESHOLD_LEN)
{
if (strcasecmp(pt,"Appendix")==0)
op.add("\\appendix\n\\");
dp->unit_d.unit_type=(dp->unit_d.unit_number[0]==-1) ? 1:0;
op.add(sects[dp->unit_d.unit_type]);
op.add("{");
do_add=1;
for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++)
dp->unit_d.unit_number[j]=0;
else if (strcasecmp(pt,"Bibliography")==0)
dp->unit_d.unit_type= (dp->unit_d.unit_number[0]==-1) ? 1:0;
op.add('\\');
op.add(sects[dp->unit_d.unit_type]);
op.add("*{");
do_add=1;
for (j=dp->unit_d.unit_type+1; j< (int) N(sects); j++)
dp->unit_d.unit_number[j]=0;
else
int i,n,c,l, unit;
unit=dp->unit_d.unit_type-1;
l=strlen(pt);
i=0;
while(1)
{
n=0;
for (c=0; i<l && isdigit(pt[i]); i++, c++)
n=n*10+pt[i]-'0';
if (c==0)
break;
unit++;
if (unit>= (int) N(sects))
unit=N(sects)-1;
break;
if (dp->unit_d.unit_number[unit]==-1)
if (n>MAX_START_NUM)
goto out_normal;
dp->unit_d.unit_number[unit]=n;
for (j=unit+1; j< (int) N(sects); j++)
dp->unit_d.unit_number[j]=0;
else if (dp->unit_d.unit_number[unit]+1==n)
dp->unit_d.unit_number[unit]++;
for (j=unit+1; j< (int) N(sects); j++)
dp->unit_d.unit_number[j]=0;
else if (dp->unit_d.unit_number[unit]!=n)
goto out_normal;
if (pt[i]!='.')
break;
i++;
}
if (unit==dp->unit_d.unit_type-1)
goto out_normal;
op.add('\\');
op.add(sects[unit]);
op.add((i>0) ? "{" : "*{");
while(isspace(pt[i])) i++;
pt+=i;
do_add=1;
}
out_normal: ;
dp->list_flg=0;
}
ts=map_string(pt, tex_map);
op.add(*ts);
if (do_add)
op.add('}');
delete(ts);
b=word_wrap(op, "\n", "\n", fmt->maxline, 0);
fputs((*b), out);
delete(b);
/* End of paragraph */
static void end_para(const tok_seq::tok *tok, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *dp;
tok=tok;
fmt=fmt;
dp=(struct latex_data *) d;
dp->par_flg=0;
fputs("\n\n", out);
/* Start a table === allocate table and initialise */
static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *tdata;
out=out;
fmt=fmt;
tdata=(struct latex_data *) d;
tdata->col=0;
tdata->row=0;
tdata->tabl=new(latex_table)(t->data.table.cols, t->data.table.rows);
tdata->par_flg=0;
/* End of a table==print the table */
static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *tdata;
t=t;
tdata=(struct latex_data *) d;
tdata->tabl->print_table(fmt->maxline, out); // Print table
delete(tdata->tabl);
tdata->tabl=NULL;
/* start row==set column to 0 */
static void start_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *tdata;
out=out;
fmt=fmt;
t=t;
tdata=(struct latex_data *) d;
tdata->col=0;
/* end row==add one to row */
static void inc_row(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *tdata;
fmt=fmt;
t=t;
out=out;
tdata=(struct latex_data *) d;
tdata->row++;
/* Start field === set field */
static void set_field(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *tdata;
tdata=(struct latex_data *) d;
out=out;
fmt=fmt;
tdata->tabl->set(tdata->col, tdata->row, t->data.d);
/* end field==add one to col */
static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
struct latex_data *tdata;
out=out;
fmt=fmt;
t=t;
tdata=(struct latex_data *) d;
tdata->col++;
/* pointers to the functions that do the work */
docfmt latexfmt=
{ 0 }, // Ignore page breaks
76, // Width
"\n", // Use \n as line ends
allocate_latex, // Allocate space
free_latex, // Free text
{
{ preamble, postamble }, // End and start of document---do nothing
{ fold_para, end_para }, // Paragraph
{ alloc_tbl, format_tbl }, // Start/end table
{ set_field, inc_col }, // Start/end field
{ start_row, inc_row }, // Start/end row
{ ltx_embed, null_proc }, // Throw away embed messages
{ ltx_list, ltx_end_list }, // Start/end list
{ ltx_item, null_proc }, // Start/end item
{ ltx_code, null_proc }, // Codes end do not happen
{ null_proc, null_proc } // Do not understanding anything else
}