⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rt2ps.c

📁 linux下的E_MAIL客户端源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: rt2ps.c,v 1.1.1.1 2000/04/25 13:49:02 fnevgeny Exp $ * * Copyright (c) 1994 HAL Computer Systems International, Ltd. *  *          HAL COMPUTER SYSTEMS INTERNATIONAL, LTD. *                  1315 Dell Avenue *                  Campbell, CA  95008 * * Author: Greg Hilton * Contributors: Tom Lang, Frank Bieser, and others * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * http://www.gnu.org/copyleft/gpl.html * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. *//* * Name: rt2ps * * Function: convert MIME Rich Text to PostScript * * Author: Tom Lang * * Date: 11/4/93 version 1 *	 02/1/94 version 2 - major rewrite, moving much function to the *				generated PostScript code. * * Data Format: 7-bit ASCII character strings formatted in accordance *	with RFC 1341. */#include <errno.h>#include <ctype.h>#include <stdio.h>#include <sys/types.h>#include <time.h>#include "prolog.h"/* number of keywords */#define MAXKEY 19/* length of longest keyword (RFC says allow 40 chars plus <,/, and > ) */#define MAXKEYLEN 43/* * this array represents all keywords recognized by this program, * but not necessarily all legal keywords.  * * the array is sorted by my perception of frequency of usage, in * an attempt to reduce search time. */#define K_NL		0#define K_LT		1#define K_BOLD		2#define K_ITALIC	3#define K_FIXED		4#define K_UNDERLINE	5#define K_CENTER	6#define K_SUPER		7#define K_SUB		8#define K_FL		9#define K_FR		10#define K_INDENT	11#define K_INDENTR	12#define K_OUTDENT	13#define K_OUTDENTR	14#define K_COMMENT	15#define K_NP		16#define K_BIGGER	17#define K_SMALLER	18static char *keys[MAXKEY] = { 	"nl>",			/* 0 */	"lt>",			/* 1 */	"bold>",		/* 2 */	"italic>",		/* 3 */	"fixed>",		/* 4 */	"underline>",		/* 5 */	"center>",		/* 6 */	"superscript>",		/* 7 */	"subscript>",		/* 8 */	"flushleft>",		/* 9 */	"flushright>",		/* 10 */	"indent>",		/* 11 */	"indentright>",		/* 12 */	"outdent>",		/* 13 */	"outdentright>",	/* 14 */	"comment>",		/* 15 */	"np>",			/* 16 */	"bigger>",		/* 17 */	"smaller>"		/* 18 */};/* * tokens are built up in "buff" * PostScript code and macros are built in code */static char buff[1024];static char code[1024];/* * place to save directory name from which program is launched */static char dir[255];/* * font attribute masks, designed so that they can OR together. * note that font change from default (Helvetica) to fixed (Courier) is * handled as an attribute change rather than a font change. this limits * us to two fonts, but that's all that's required by MIME. */#define BOLD 1#define ITALIC 2#define FIXED 4/* * table of font names, indexed by attribute mask, which is * an OR of bold, italic, and fixed font. * * when the prolog code is written to standard output, macros defining * short-hand names for the fonts are defined. */static char *font[8] = {	"f1",	"f1b",	"f1i",	"f1bi",	"f2",	"f2b",	"f2i",	"f2bi"	};/* * justifcation flags are used as bit flags, to allow nesting and also * allow more tolerance of syntax errors like unbalanced token pairs. * * left justifcation implies no special processing of the output. centering * and right justification require extra work. * * if both left and right justification are turned on, the output is fully * justified. note that this is more than what is requried in the RFC - may * be a problem, maybe a feature, maybe nobody cares... * * centering takes precedence over other values. * * if justification is turned on or off in the middle of * a line, the action applies to the whole line. the RFC is fuzzy on this, * but seems to imply this is how it should work. */#define L_JUST 1#define R_JUST 2#define CENTER 4/* * this table converts the justification bit flags to values for the * PostScript JU macro. JU 0 = left, JU 1 = center, JU 2 = right, JU 3 = full */static int jtab[8] = {	0,	/* no flags, default to left justify */	0,	/* L_JUST */	2,	/* R_JUST */	3,	/* L_JUST & R_JUST */	1,	/* CENTER */	1,	/* CENTER & anything else = CENTER */	1,	1};/* *  PostScript page coordinates *    measured in "points," where 72 points = 1 inch *    lower left page corner = 0,0 *    8.5" x 11" paper, portrait orientation assumed *    indentation unit is .5 inch, i.e. 36 points */#define Y_TOP 720#define Y_BOT 72#define X_LEFT 72#define X_RIGHT 540#define NORMAL_FONT_SIZE 10#define SMALL_FONT_SIZE 6#define LINE_HEIGHT 12#define INDENT 36/* * global static variables */struct {  char *n;		/* pointer to program name */  char *d;		/* pointer to program directory name */  int keyword;		/* flag: keyword just processed */  int c;		/* index into the token buffer */  int space;		/* flag: collecting white space. this is done to			   optimize the PostScript code - doing one command			   for multiple spaces rather than one each space */  int super;		/* flag: superscript */  int sub;		/* flag: subscript */  int scaled;		/* flag: font scaled for sub/super script */  int altFont;		/* flag: use alternate font, e.g. Times vs. Helvetica*/  int justify;		/* mask: justification attributes */  int justifyOff;	/* mask: justif. attrs to reset at <nl> */  int nl;		/* flag: <nl> processed for this line */  int fs;		/* current font size */  int pfs;		/* previous font size */  int ffs;		/* full font size */  int atMargin;		/* flag: at left margin now */  int prolog;		/* flag: pre-pend PostScript prolog to output */  int suppress;		/* flag: output suppressed (within a comment) */  int underline;	/* flag: underline attribute turned on/off */  int mask;		/* font mask: used to select from font array */  int pm;		/* previous font mask */  int box;		/* flag: draw box around each page */  int showTags;		/* flag: show unrecognized MIME tags */  int hdr;		/* flag: print running headers */  int pg;		/* running header page number */} g = {  NULL,			/* n */  &dir[0],		/* d */  0,			/* keyword */  0,			/* c */  0,			/* space */  0,			/* superscript */  0,			/* subscript */  0,			/* scaled */  0,			/* altFont */  0,			/* justify */  0,			/* justifyOff */  0,			/* nl */  NORMAL_FONT_SIZE,	/* fs */  0,			/* pfs */  NORMAL_FONT_SIZE,	/* ffs */  1,			/* atMargin */  1,			/* prolog */  0,			/* suppress */  0,			/* underline */  0,			/* mask */  -1,			/* pm */  0,			/* box */  0,			/* showTags */  0,			/* hdr */  1			/* pg */};/* * function prototypes */void prolog();void epilog();void tokenOutput( char * );void tab();int  keywordMatch( char * );void controlOutput( int );void foldLow( char * );int  getArgs( int, char ** );char *baseName( char *, char * );char *dirName( char *, char * );void showHelp();main(int argc, char **argv){	int c;			/* input stream character */	int key;		/* keyword index */	/*	 * process command line arguments, bail out if there's a problem	 */	if (getArgs( argc, argv ) != 0)		exit(1);	/*	 * output PostScript prolog code	 */	prolog();	/*	 * read data stream from standard input and filter to stdout	 */	while((c = getchar()) != EOF) {		switch ((char) c) {		/*		 * "newline" in the input stream is treated as white		 * space, or ignored if it immediately follows a keyword.		 */		case '\n' :			if(g.atMargin == 0) {				if(g.space == 0) {					tokenOutput(buff);					g.space = 1;				}				buff[g.c++] = ' ';				tokenOutput(buff);			}			break;		/*		 * tab character		 */		case '\t' :			tokenOutput(buff);			tab();			break;		/*		 * carriage returns are ignored		 */		case '\r' :			break;		/*		 * space character		 */		case ' ' :			if(g.space == 0) {				tokenOutput(buff);				g.space = 1;			}			buff[g.c++] = (char) c;			break;		case '<' :			tokenOutput(buff);			buff[g.c++] = (char) c;			g.keyword = 1;			break;		case '>':			if(g.space)				tokenOutput(buff);			buff[g.c++] = (char) c;			if(g.keyword) {				key = keywordMatch(buff);				if(key == 0) {					if(g.showTags)						tokenOutput(buff);					else {						g.c = 0;						g.space = 0;						g.keyword = 0;						g.atMargin = 0;					}				}				else					controlOutput(key);			}			break;		/*		 * characters which are special to the PostScript interpreter		 */		case '\\' :		case '(' :		case ')' :			if(g.space)				tokenOutput(buff);			buff[g.c++] = '\\';			buff[g.c++] = (char) c;			if(g.keyword == 0)				g.atMargin = 0;			break;		default:			/*			 * guard against extraneous stuff in the input			 */#if 0			if ( iscntrl( (char) c) ) {				c = (int) '.';			}#endif			/*			 * copy character to the buffer			 */			if(g.space)				tokenOutput(buff);			buff[g.c++] = (char) c;			if(g.keyword == 0)				g.atMargin = 0;		}	}	/*	 * wrap up the PostScript output	 */	epilog();	exit (0);}/* * output a 4-tuple token of the form: * [ (string) size font action ] C * * where: *	(string) is a character string to be output *	size is the font's point size, or 0 for no change *	font is the name of the font, or "x" for no change *	action is the action code for this token: *	0 = show character string *	1 = show underlined character string *	2 = show space(s) *	3 = show underlined space(s) *	4 = tab *	5 = underlined tab *	6 = show subscript *	7 = show underlined subscript *	8 = show superscript *	9 = show underlined superscript *	the trailing "C" is a macro which causes the token to be processed. * *	There are shortcut macros for spaces and tabs: *	S = single space character *	US = single underlined space *	T = tab character *	UT = underlined tab character */voidtokenOutput( char *b ){	int action;	int fontSize;	if(g.c == 0)		return;	if(g.suppress == 0) {		if((g.space) && (g.c == 1)) {			if(g.underline)				printf("US\n");			else				printf("S\n");		}		else {			buff[g.c] = (char)NULL;			/*			 * determine the "action code" for the "C" macro			 */			action = (g.super*8)+(g.sub*6)+(g.space*2)+g.underline;			/*			 * there's no checking for too many nested <smaller>			 * keywords, resulting in a 0 or negative font size.			 * we'll leave the global variable alone so that			 * corectly nested </smaller> keywords will eventually			 * restore it. however, a font size smaller than 6			 * will not be sent to the "C" macro.			 */			fontSize = (g.fs < 6) ? 6 : g.fs;#ifdef DONTCARE			if((g.fs == g.pfs) &&			   (g.mask == g.pm))				printf("[(%s) 0 x %i] C\n", buff, action);			else#endif				printf("[(%s) %i %s %i] C\n", buff, fontSize, font[g.mask], action);			g.pfs = g.fs;			g.pm = g.mask;		}	}	g.c = 0;	g.space = 0;	g.keyword = 0;	g.atMargin = 0;}/* * output a tab */voidtab(){	if(!g.suppress) {		if(g.underline)			printf("UT ");		else			printf("T ");	}}/* * a character string delimited by < > has been found. see if it matches a * known keyword. this is a case-insensitive compare. zero is returned if * no match. a positive integer is returned if a match is found, equal to * the keyword code + 1. if the keyword is an "off" keyword, e.g. </bold>, * the return code is negated. * * for example, the keyword code for <bold> is 2. this routine will return * 3 if the keyword is <bold> or -3 if the keyword is </bold>. */intkeywordMatch( char *buff ){	int i;	int off = 0;	int rc = 0;	buff[g.c] = (char)NULL;	foldLow(buff);	if(*++buff == '/') {		buff++;		off = 1;	}	for( i=0; i<MAXKEY; i++ ) {		if (strcmp(buff, keys[i]) == 0) {			rc = (off) ? -(i+1) : (i+1);			break;		}	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -