home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
223.lha
/
AsciiToPostScriptII
/
a2ps.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-03-29
|
11KB
|
445 lines
/************************************************************************/
/* */
/* Description: Ascii to PostScript printer program. */
/* File: imag:/users/local/a2ps/a2ps.c */
/* Created: Mon Nov 28 15:22:15 1988 by miguel@imag (Miguel Santana) */
/* Version: 2.0 */
/* */
/* Edit history: */
/* 1) Derived of shell program written by evan@csli (Evan Kirshenbaum). */
/* Written in C for improve speed execution and portability. Many */
/* improvements have been added. */
/* 2) Ported to the Amiga Jan 24, 1989 (Samuel Paolucci) */
/* */
/************************************************************************/
/*
* Copyright (c) 1988, Miguel Santana, miguel@imag.imag.fr
*
* Permission is granted to copy and distribute this file in modified
* or unmodified form, for noncommercial use, provided (a) this copyright
* notice is preserved, (b) no attempt is made to restrict redistribution
* of this file, and (c) this file is not distributed as part of any
* collection whose redistribution is restricted by a compilation copyright.
*/
#include <stdio.h>
#ifdef ANSIC
#include <time.h>
#else
#ifdef UNIX
#include <sys/time.h>
#else
#ifdef SYSV
#include <sys/types.h>
#include <sys/timeb.h>
#include <time.h>
#else
error !
#endif
#endif
#endif
#ifndef HEADER_PS
#define HEADER_PS "./header.ps"
#endif
#define LINESPERPAGE 66
#define COLUMNSPERLINE 86
#define FALSE 0
#define TRUE 1
#define PS_EOF 04
int fold_line();
void print_file();
char cut_line();
int column = 0; /* Column number (in current line) */
int line = 0; /* Line number (in current page) */
int line_number = 0; /* Source line number */
int first_page; /* First page for a file */
int nonprinting_chars, chars; /* Number of nonprinting and total chars */
int prefix_width; /* Width in characters for line prefix */
int numbering = TRUE; /* Line numbering option */
int folding = TRUE; /* Line folding option */
int restart = TRUE; /* Restart page number at each file option */
int only_printable = FALSE; /* Replace non printable char by space option */
int interpret = TRUE; /* Interpret TAB, FF and BS chars option */
int print_binaries = FALSE; /* Force printing for binary files */
main(argc, argv)
int argc;
char *argv[];
{
int narg;
char *arg;
/* Option processing */
arg = argv[narg = 1];
while (narg < argc && arg[0] == '-')
{
switch (arg[1])
{
case 'b':
if (arg[2] != NULL)
goto usage;
print_binaries = TRUE;
break;
case 'f':
if (arg[2] != NULL)
goto usage;
folding = TRUE;
break;
case 'i':
if (arg[2] != NULL)
goto usage;
interpret = TRUE;
break;
case 'n':
if (arg[2] == NULL)
{
numbering = TRUE;
break;
}
if (arg[3] != NULL)
goto usage;
switch (arg[2])
{
case 'b':
print_binaries = FALSE;
break;
case 'f':
folding = FALSE;
break;
case 'i':
interpret = FALSE;
break;
case 'n':
numbering = FALSE;
break;
case 'r':
restart = FALSE;
break;
case 'v':
only_printable = TRUE;
break;
default:
goto usage;
}
break;
case 'r':
if (arg[2] != NULL)
goto usage;
restart = TRUE;
break;
case 'v':
if (arg[2] != NULL)
goto usage;
only_printable = FALSE;
break;
default:
usage:
fprintf(stderr,
"usage: a2ps [-n{bfinrv}] [-b] [-f] [-i] [-n] [-r] [-v] [f1 f2 ... fn]\n");
exit(1);
}
arg = argv[++narg];
}
if (narg >= argc)
goto usage;
/* Header printing (postcript prolog) */
print_header();
/* Print files designated or standard input */
prefix_width = numbering ? 6 : 1;
if (narg >= argc)
print_file("stdin");
else
{
while (narg < argc)
{
if (freopen(arg, "r", stdin) == NULL)
{
fprintf(stderr, "Error opening %s\n", arg);
printf("cleanup\n");
exit(1);
}
print_file(arg);
arg = argv[++narg];
}
}
printf("cleanup\n");
putchar(PS_EOF);
}
void print_file(name)
char *name;
{
register int c;
int start_line, continue_exit;
int char_width;
/*
* Printing binary files is not very useful. We stop printing
* if we detect one of these files. Our heuristic to detect them:
* if 50% characters of first page are non-printing characters,
* the file is a binary file.
* Option -b force binary files impression.
*/
first_page = TRUE;
nonprinting_chars = chars = 0;
/*
* Preprocessing (before printing):
* - TABs expansion (see interpret option)
* - FF and BS interpretation
* - replace non printable characters by a space or a char sequence
* like:
* ^X for ascii codes < 0x20 (X = [@, A, B, ...])
* ^? for del char
* M-c for ascii codes > 0x3f
* - prefix parents and backslash ['(', ')', '\'] by backslash
* (escape character in postcript)
*/
column = 0;
line = line_number = 0;
start_line = TRUE;
printf("(%s) newfile\n", name);
if (restart)
printf("/sheet 1 def\n");
printf("startpage\n");
c = getchar();
while (c != EOF)
{
/* Form feed */
if (c == '\f' && interpret)
{
if (!start_line)
printf(") s\n");
start_line = TRUE;
printf("endpage startpage\n");
if (first_page && is_binaryfile(name))
return;
line = 0;
if ((c = getchar()) == EOF)
break;
}
/* Start a new line? */
if (start_line)
{
if (numbering)
printf("(%-5d ", ++line_number);
else
printf("( ");
start_line = FALSE;
}
/* Interpret each character */
switch (c)
{
case '\b':
if (!interpret)
goto print;
if (column)
column--;
putchar(c);
break;
case '\n':
column = 0;
start_line = TRUE;
printf(") s\n");
if (++line >= LINESPERPAGE)
{
printf("endpage startpage\n");
if (first_page && is_binaryfile(name))
return;
line = 0;
}
break;
case '\t':
if (interpret)
{
continue_exit = FALSE;
do
{
if (++column + prefix_width > COLUMNSPERLINE)
if (folding)
{
if (fold_line(name) == FALSE)
return;
}
else
{
c = cut_line();
continue_exit = TRUE;
break;
}
putchar(' ');
} while (column & 0x7);
if (continue_exit)
continue;
break;
}
default:
print:
if (only_printable)
char_width = 1;
else
{
char_width = c > 0177 ? 2 : 0;
char_width += c < ' ' || c == 0177 ? 2 : 1;
}
if (prefix_width + (column += char_width) > COLUMNSPERLINE)
if (folding)
{
if (fold_line(name) == FALSE)
return;
}
else
{
c = cut_line();
continue;
}
if (c == '(' || c == ')' || c == '\\')
putchar('\\');
if (c >= ' ' && c < 0177)
putchar(c);
else
{
nonprinting_chars++;
if (only_printable)
putchar(' ');
else
{
if (c > 0177)
{
printf("M-");
c &= 0177;
}
if (c < ' ')
printf("^%c", c+'@');
else if (c == 0177)
printf("^?");
else
putchar(c);
}
}
chars++;
break;
}
c = getchar();
}
if (!start_line)
printf(") s\n");
printf("endpage\n");
}
int fold_line(name)
char *name;
{
column = 0;
printf(") s\n");
if (++line >= LINESPERPAGE)
{
printf("endpage startpage\n");
if (first_page && is_binaryfile(name))
return FALSE;
line = 0;
}
if (numbering)
printf("( ");
else
printf("( ");
return TRUE;
}
char cut_line()
{
char c;
while ((c = getchar()) != EOF && c != '\n' && c != '\f');
return c;
}
is_binaryfile(name)
char *name;
{
first_page = FALSE;
if (!print_binaries && (nonprinting_chars*100 / chars) >= 75)
{
fprintf(stderr, "%s is a binary file: printing aborted\n", name);
return TRUE;
}
return FALSE;
}
print_header()
{
register int c;
FILE *f;
char *string;
#ifdef ANSIC
time_t date;
#else
#ifdef UNIX
struct timeval date;
struct tm *p;
#else
#ifdef SYSV
struct timeb date;
#endif
#endif
#endif
if ((f = fopen(HEADER_PS, "r")) == NULL)
{
fprintf(stderr, "Postcript header missing\n");
exit(1);
}
/* Header file printing */
while ((c = getc(f)) != EOF)
putchar(c);
/* Retrieve date and hour */
#ifdef ANSIC
if (time(&date) == -1)
{
fprintf(stderr, "Error calculing time\n");
exit(1);
}
string = ctime(&date);
/* and print them */
printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
#else
#ifdef UNIX
(void) gettimeofday(&date, (struct timezone *)0);
p = localtime(&date.tv_sec);
string = asctime(p);
/* and print them */
printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
#else
#ifdef SYSV
(void)ftime(&date);
string = ctime(&date.time);
printf("/date (%.6s %.4s %.8s) def\n", string+4, string+20, string+11);
#endif
#endif
#endif
/* Go on */
printf("startdoc\n");
}