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

📄 reader.c

📁 将rft格式文件转换成html格式文件
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * - Need to document error code meanings. * - Need to do something with \* on destinations. * - Make the parameter a long? * * reader.c - RTF file reader.  Release 1.11. * * ASCII 10 (\n) and 13 (\r) are ignored and silently discarded. * Nulls are also discarded. * (although the read hook will still get a look at them.) * * "\:" is not a ":", it's a control symbol.  But some versions of * Word seem to write "\:" for ":".  This reader treats "\:" as a * plain text ":" * * 19 Mar 93 * - Add hack to skip "{\*\keycode ... }" group in stylesheet. * This is probably the wrong thing to do, but it's simple. * 13 Jul 93 * - Add THINK C awareness to malloc() declaration.  Necessary so * compiler knows the malloc argument is 4 bytes.  Ugh. * 07 Sep 93 * - Text characters are mapped onto standard codes, which are placed * in rtfMinor. * - Eliminated use of index() function. * 05 Mar 94 * - Added zillions of new symbols (those defined in RTF spec 1.2). * 14 Mar 94 * - Public functions RTFMsg() and RTFPanic() now take variable arguments. * This means RTFPanic() now is used in place of what was formerly the * internal function Error(). * - 8-bit characters are now legal, so they're not converted to \'xx * hex char representation now. * 01 Apr 94 * - Added public variables rtfLineNum and rtfLinePos. * - #include string.h or strings.h, avoiding strncmp() problem where * last argument is treated as zero when prototype isn't available. * 04 Apr 94 * - Treat style numbers 222 and 0 properly as "no style" and "normal". * 08 Apr 94 * - Control symbol table is no longer compiled in.  It's read in the * first time that RTFInit() is called from the library file rtf-ctrl. * This shrinks all the translator binaries.  rtf-ctrl is built by * mkrtf-ctrl.c. */# ifndef STRING_H# define STRING_H <string.h># endif# include	<stdio.h># include	<ctype.h># include	STRING_H# ifdef STDARG# include	<stdarg.h># else# ifdef	VARARGS# include	<varargs.h># endif	/* VARARGS */# endif	/* STDARG */# include	"tokenscan.h"# define	rtfInternal# include	"rtf.h"# undef		rtfInternal/* * Return pointer to new element of type t, or NULL * if no memory available. */# define	New(t)	((t *) RTFAlloc (sizeof (t)))/* maximum number of character values representable in a byte */# define	charSetSize		256/* charset stack size */# define	maxCSStack		40#ifndef THINK_Cextern char	*malloc ();#elseextern void	*malloc(size_t);#endifstatic void	_RTFGetToken (); void	_RTFGetToken2 ();static int	GetChar ();static void	ReadFontTbl ();static void	ReadColorTbl ();static void	ReadStyleSheet ();static void	ReadInfoGroup ();static void	ReadPictGroup ();static void	ReadObjGroup ();static void	LookupInit ();static void	Lookup ();static int	Hash ();static void	CharSetInit ();static void	ReadCharSetMaps ();/* * Public variables (listed in rtf.h) */int	rtfClass;int	rtfMajor;int	rtfMinor;int	rtfParam;char	*rtfTextBuf = (char *) NULL;int	rtfTextLen;long	rtfLineNum;int	rtfLinePos;/* * Private stuff */static int	pushedChar;	/* pushback char if read too far */static int	pushedClass;	/* pushed token info for RTFUngetToken() */static int	pushedMajor;static int	pushedMinor;static int	pushedParam;static char	*pushedTextBuf = (char *) NULL;static int	prevChar;static int	bumpLine;static RTFFont	*fontList = (RTFFont *) NULL;	/* these lists MUST be */static RTFColor	*colorList = (RTFColor *) NULL;	/* initialized to NULL */static RTFStyle	*styleList = (RTFStyle *) NULL;static FILE	*rtffp = stdin;static char	*inputName = (char *) NULL;static char	*outputName = (char *) NULL;/* * This array is used to map standard character names onto their numeric codes. * The position of the name within the array is the code. * stdcharnames.h is generated in the ../h directory. */static char	*stdCharName[] ={# include	"stdcharnames.h"	(char *) NULL};/* * These arrays are used to map RTF input character values onto the standard * character names represented by the values.  Input character values are * used as indices into the arrays to produce standard character codes. */static char	*genCharSetFile = (char *) NULL;static int	genCharCode[charSetSize];	/* general */static int	haveGenCharSet = 0;static char	*symCharSetFile = (char *) NULL;static int	symCharCode[charSetSize];	/* symbol */static int	haveSymCharSet = 0;static int	curCharSet = rtfCSGeneral;static int	*curCharCode = genCharCode;/* * By default, the reader is configured to handle charset mapping invisibly, * including reading the charset files and switching charset maps as necessary * for Symbol font. */static int	autoCharSetFlags;/* * Stack for keeping track of charset map on group begin/end.  This is * necessary because group termination reverts the font to the previous * value, which may implicitly change it. */static int	csStack[maxCSStack];int	csTop = 0;/* * Initialize the reader.  This may be called multiple times, * to read multiple files.  The only thing not reset is the input * stream; that must be done with RTFSetStream(). */voidRTFInit (){int	i;RTFColor	*cp;RTFFont		*fp;RTFStyle	*sp;RTFStyleElt	*eltList, *ep;	rtfClass = -1;	pushedClass = -1;	pushedChar = EOF;	rtfLineNum = 0;	rtfLinePos = 0;	prevChar = EOF;	bumpLine = 0;	if (rtfTextBuf == (char *) NULL)	/* initialize text buffers */	{		rtfTextBuf = RTFAlloc (rtfBufSiz);		pushedTextBuf = RTFAlloc (rtfBufSiz);		if (rtfTextBuf == (char *) NULL			|| pushedTextBuf == (char *) NULL)			RTFPanic ("Cannot allocate text buffers.");		rtfTextBuf[0] = pushedTextBuf[0] = '\0';	}	RTFFree (inputName);	RTFFree (outputName);	inputName = outputName = (char *) NULL;				/* initialize control symbol lookup table */	LookupInit ();		for (i = 0; i < rtfMaxClass; i++)		RTFSetClassCallback (i, (RTFFuncPtr) NULL);	for (i = 0; i < rtfMaxDestination; i++)		RTFSetDestinationCallback (i, (RTFFuncPtr) NULL);	/* install built-in destination readers */	RTFSetDestinationCallback (rtfFontTbl, ReadFontTbl);	RTFSetDestinationCallback (rtfColorTbl, ReadColorTbl);	RTFSetDestinationCallback (rtfStyleSheet, ReadStyleSheet);	RTFSetDestinationCallback (rtfInfo, ReadInfoGroup);	RTFSetDestinationCallback (rtfPict, ReadPictGroup);	RTFSetDestinationCallback (rtfObject, ReadObjGroup);	RTFSetReadHook ((RTFFuncPtr) NULL);	/* dump old lists if necessary */	while (fontList != (RTFFont *) NULL)	{		fp = fontList->rtfNextFont;		RTFFree (fontList->rtfFName);		RTFFree ((char *) fontList);		fontList = fp;	}	while (colorList != (RTFColor *) NULL)	{		cp = colorList->rtfNextColor;		RTFFree ((char *) colorList);		colorList = cp;	}	while (styleList != (RTFStyle *) NULL)	{		sp = styleList->rtfNextStyle;		eltList = styleList->rtfSSEList;		while (eltList != (RTFStyleElt *) NULL)		{			ep = eltList->rtfNextSE;			RTFFree (eltList->rtfSEText);			RTFFree ((char *) eltList);			eltList = ep;		}		RTFFree (styleList->rtfSName);		RTFFree ((char *) styleList);		styleList = sp;	}	CharSetInit ();	csTop = 0;}/* * Set the reader's input stream to the given stream.  Can * be used to redirect to other than the default (stdin). */voidRTFSetStream (stream)FILE	*stream;{	rtffp = stream;}/* * Set or get the input or output file name.  These are never guaranteed * to be accurate, only insofar as the calling program makes them so. */voidRTFSetInputName (name)char	*name;{	if ((inputName = RTFStrSave (name)) == (char *) NULL)		RTFPanic ("RTFSetInputName: out of memory");}char *RTFGetInputName (){	return (inputName);}voidRTFSetOutputName (name)char	*name;{	if ((outputName = RTFStrSave (name)) == (char *) NULL)		RTFPanic ("RTFSetOutputName: out of memory");}char *RTFGetOutputName (){	return (outputName);}/* ---------------------------------------------------------------------- *//* * Callback table manipulation routines *//* * Install or return a writer callback for a token class */static RTFFuncPtr	ccb[rtfMaxClass];		/* class callbacks */voidRTFSetClassCallback (class, callback)int		class;RTFFuncPtr	callback;{	if (class >= 0 && class < rtfMaxClass)		ccb[class] = callback;}RTFFuncPtrRTFGetClassCallback (class)int	class;{	if (class >= 0 && class < rtfMaxClass)		return (ccb[class]);	return ((RTFFuncPtr) NULL);}/* * Install or return a writer callback for a destination type */static RTFFuncPtr	dcb[rtfMaxDestination];	/* destination callbacks */voidRTFSetDestinationCallback (dest, callback)int		dest;RTFFuncPtr	callback;{	if (dest >= 0 && dest < rtfMaxDestination)		dcb[dest] = callback;}RTFFuncPtrRTFGetDestinationCallback (dest)int	dest;{	if (dest >= 0 && dest < rtfMaxDestination)		return (dcb[dest]);	return ((RTFFuncPtr) NULL);}/* ---------------------------------------------------------------------- *//* * Token reading routines *//* * Read the input stream, invoking the writer's callbacks * where appropriate. */voidRTFRead (){	while (RTFGetToken () != rtfEOF)		RTFRouteToken ();}/* * Route a token.  If it's a destination for which a reader is * installed, process the destination internally, otherwise * pass the token to the writer's class callback. */voidRTFRouteToken (){RTFFuncPtr	p;	if (rtfClass < 0 || rtfClass >= rtfMaxClass)	/* watchdog */	{		RTFPanic ("Unknown class %d: %s (reader malfunction)",							rtfClass, rtfTextBuf);	}	if (RTFCheckCM (rtfControl, rtfDestination))	{		/* invoke destination-specific callback if there is one */		if ((p = RTFGetDestinationCallback (rtfMinor))							!= (RTFFuncPtr) NULL)		{			(*p) ();			return;		}	}	/* invoke class callback if there is one */	if ((p = RTFGetClassCallback (rtfClass)) != (RTFFuncPtr) NULL)		(*p) ();}/* * Skip to the end of the current group.  When this returns, * writers that maintain a state stack may want to call their * state unstacker; global vars will still be set to the group's * closing brace. */voidRTFSkipGroup (){int	level = 1;int savecsTop;	if(csTop>0)savecsTop=csTop-1;	else savecsTop=0;	RTFGetToken ();	while (1)	{		if (rtfClass == rtfEOF)			break;		if (rtfClass == rtfGroup)		{			if (rtfMajor == rtfBeginGroup)				++level;			else if (rtfMajor == rtfEndGroup)			{				if (--level < 1)					break;	/* end of initial group */			}		}		_RTFGetToken2();	}	csTop=savecsTop;}/* * Read one token.  Call the read hook if there is one.  The * token class is the return value.  Returns rtfEOF when there * are no more tokens. */intRTFGetToken (){RTFFuncPtr	p;	for (;;)	{		_RTFGetToken ();		if ((p = RTFGetReadHook ()) != (RTFFuncPtr) NULL)			(*p) ();	/* give read hook a look at token */		/* Silently discard newlines, carriage returns, nulls.  */		if (!(rtfClass == rtfText			&& (rtfMajor == '\n' || rtfMajor == '\r'						|| rtfMajor == '\0')))			break;	}	return (rtfClass);}/* * Install or return a token reader hook. */static RTFFuncPtr	readHook;voidRTFSetReadHook (f)RTFFuncPtr	f;{	readHook = f;}RTFFuncPtrRTFGetReadHook (){	return (readHook);}voidRTFUngetToken (){	if (pushedClass >= 0)	/* there's already an ungotten token */		RTFPanic ("cannot unget two tokens");	if (rtfClass < 0)		RTFPanic ("no token to unget");	pushedClass = rtfClass;	pushedMajor = rtfMajor;	pushedMinor = rtfMinor;	pushedParam = rtfParam;	(void) strcpy (pushedTextBuf, rtfTextBuf);}intRTFPeekToken (){	_RTFGetToken ();	RTFUngetToken ();	return (rtfClass);}static void_RTFGetToken (){RTFFont	*fp;	/* first check for pushed token from RTFUngetToken() */

⌨️ 快捷键说明

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