home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
word2x0a.zip
/
source
/
text-fmt.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1998-08-08
|
7KB
|
317 lines
/* $Id: text-fmt.cc,v 1.13 1997/04/13 04:15:33 dps Exp $ */
/* Everything is declared as static to avoid namespace polution but */
/* is reachable externally via the exported table (and this it the */
/* only way they get called). */
#ifdef __GNUC__
#define alloca __builtin_alloca
#else
#if HAVE_ALLOCA_H
#include <alloca.h>
#else /* Do not have alloca.h */
#ifdef _AIX
#pragma alloca
#else /* not _AIX */
char *alloca();
#endif /* _AIX */
#endif /* HAVE_ALLOCA_H */
#endif /* __GNUC__ */
#include <stdio.h>
#include <stdlib.h>
#include "interface.h"
#include "lib.h"
#include "text-table.h"
/* Local data */
struct text_data
{
text_table *tabl;
int col;
int row;
int margin;
int l_indent;
};
/* Most of these values are thanks to catdoc by
* Victor B. Wagner <vitus@agropc.msk.su> et al */
static const cmap char_map[]=
{
{ 0x1E, "-" }, // Unbreakable join
{ 0x1F, "" }, // Soft hypen
{ 0x7f, "" }, // Delete 127s
{ 0x85, "..." }, // Dots
{ 0x91, "`" }, // 91 = left quote
{ 0x92, "'" }, // 92 = right quote
{ 0x93, "\"" }, // 93 = opening double quote
{ 0x94, "\"" }, // 94 = closing double quote
{ 0x95, "o" }, // 95 = Bullet
{ 0x96, "-" }, // em-dash
{ 0x97, "-" }, // en-dash
{ 0x99, "(tm)" }, // Trademark
{ 0xA0, " " }, // Unbreakable space
{ 0xA3, "<=" }, // Less than or = came out as A3
{ 0xA9, "(c)" }, // Copyright
{ 0xAB, "<<" }, // Openning << quotes
{ 0xAE, "(R)" }, // Reserved sign
{ 0xB3, ">=" }, // Greater than or = came out as B3
{ 0xBB, ">>" }, // Closing >> quotes
/* german stuff (jk) */
/* missing are: The paragraph sign (⌡) and the euro (???) plus more */
/* let me know if you find it out joerg@gmx.de */
#ifdef OUTPUT_CHARSET_GERMAN_X /* define for 7bit german umlaut */
/* transscription */
{ 0xC4, "Ae" }, // big a umlault
{ 0xD6, "Oe" }, // big o umlault
{ 0xDC, "Ue" }, // big u umlault
{ 0xDF, "sz" }, // sz
{ 0xE4, "ae" }, // small a umlault
{ 0xF6, "oe" }, // small o umlault
{ 0xFC, "ue" }, // small u umlault
#endif
#ifdef OUTPUT_CHARSET_IBM850 /* define this for use under OS/2 */
{ 0xC4, "Ä" }, // big a umlault
{ 0xD6, "Ö" }, // big o umlault
{ 0xDC, "Ü" }, // big u umlault
{ 0xDF, "ß" }, // sz
{ 0xE4, "ä" }, // small a umlault
{ 0xF6, "ö" }, // small o umlault
{ 0xFC, "ü" }, // small u umlault
#endif
/* end of german stuff */
};
/* Allocate local data */
static void *allocate_txt(void)
{
struct text_data *tdata;
tdata=new(struct text_data);
tdata->tabl=NULL;
tdata->margin=0;
tdata->l_indent=0;
return tdata;
}
static void txt_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)
fputc('\014', out);
break;
default:
break;
}
}
/* Free local data */
static void free_txt(void *d)
{
struct text_data *tdata;
tdata=(struct text_data *) d;
if (tdata->tabl!=NULL)
delete(tdata->tabl);
}
/* list start increases margin */
static void inc_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
struct text_data *tdata;
t=t;
fmt=fmt;
out=out;
tdata=(struct text_data *) d;
tdata->margin+=4;
}
/* list start decreases margin */
static void dec_margin(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
struct text_data *tdata;
t=t;
fmt=fmt;
out=out;
tdata=(struct text_data *) d;
tdata->margin-=4;
}
/* items are easy */
static void txt_item(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
tblock *ts;
const char *s;
int i, m;
struct text_data *dp;
fmt=fmt; // No need for fmt
dp=(struct text_data *) d;
ts=map_string(t->data.d, char_map);
s=*ts;
fputc('\n', out);
m=dp->margin-strlen(s)-1;
for (i=0; i<m; i++)
fputc(' ', out);
fputs(s, out);
fputc(' ', out);
dp->l_indent=dp->margin;
delete(ts);
}
/* Paragraphs are easy */
static void fold_para(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
tblock *b, *ts;
const char *s;
char *nl;
struct text_data *dp;
int i;
dp=(struct text_data *) d;
if (dp->margin==0 || (nl=(char *) alloca(dp->margin+2))==NULL)
nl="\n";
else
{
*nl='\n';
for (i=1; i<=dp->margin; i++)
*(nl+i)=' ';
*(nl+dp->margin+1)='\0';
}
ts=map_string(t->data.d, char_map);
b=word_wrap((*ts), nl, nl, fmt->maxline-(dp->margin), 0);
delete(ts);
s=*b;
for (i=dp->l_indent; i<dp->margin; i++)
fputc(' ', out);
fputs(s, out);
fputs("\n\n", out);
dp->l_indent=0;
delete(b);
}
/* Start a table === allocate table and initialise */
static void alloc_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
struct text_data *tdata;
out=out;
fmt=fmt;
tdata=(struct text_data *) d;
tdata->col=0;
tdata->row=0;
tdata->tabl=new(text_table)(t->data.table.cols, t->data.table.rows);
}
/* End of a table==print the table */
static void format_tbl(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
struct text_data *tdata;
t=t;
tdata=(struct text_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 text_data *tdata;
out=out;
fmt=fmt;
t=t;
tdata=(struct text_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 text_data *tdata;
out=out;
fmt=fmt;
t=t;
tdata=(struct text_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 tblock *ts;
struct text_data *tdata;
out=out;
fmt=fmt;
ts=map_string(t->data.d, char_map);
tdata=(struct text_data *) d;
tdata->tabl->set(tdata->col, tdata->row, (*ts));
delete(ts);
}
/* end field==add one to col */
static void inc_col(const tok_seq::tok *t, const docfmt *fmt, FILE *out,
void *d)
{
struct text_data *tdata;
out=out;
fmt=fmt;
t=t;
tdata=(struct text_data *) d;
tdata->col++;
}
/* pointers to the functions that do the work */
docfmt txtfmt=
{
{ 0 }, // No page breaks
76, // Width
"\n", // Use \n as line ends
allocate_txt, // Allocate space
free_txt, // Free text
{
{ null_proc, null_proc }, // End and start of document---do nothing
{ fold_para, null_proc }, // Paragraph
{ alloc_tbl, format_tbl }, // Start/end table
{ set_field, inc_col }, // Start/end field
{ start_row, inc_row }, // Start/end row
{ null_proc, null_proc }, // Throw away embed messages
{ inc_margin, dec_margin }, // list start and end
{ txt_item, null_proc}, // Items
{ txt_code, null_proc}, // Code
{ null_proc, null_proc } // Do not understanding anything else
}
};