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

📄 reader.c

📁 将rft格式文件转换成html格式文件
💻 C
📖 第 1 页 / 共 4 页
字号:
 * Set the current character set.  If csId is illegal, uses general charset. */voidRTFSetCharSet (csId)int	csId;{	switch (csId)	{	default:		/* use general if csId unknown */	case rtfCSGeneral:		curCharCode = genCharCode;		curCharSet = csId;		break;	case rtfCSSymbol:		curCharCode = symCharCode;		curCharSet = csId;		break;	}}intRTFGetCharSet (){	return (curCharSet);}/* ---------------------------------------------------------------------- *//* * Special destination readers.  They gobble the destination so the * writer doesn't have to deal with them.  That's wrong for any * translator that wants to process any of these itself.  In that * case, these readers should be overridden by installing a different * destination callback. * * NOTE: The last token read by each of these reader will be the * destination's terminating '}', which will then be the current token. * That '}' token is passed to RTFRouteToken() - the writer has already * seen the '{' that began the destination group, and may have pushed a * state; it also needs to know at the end of the group that a state * should be popped. * * It's important that rtf.h and the control token lookup table list * as many symbols as possible, because these destination readers * unfortunately make strict assumptions about the input they expect, * and a token of class rtfUnknown will throw them off easily. *//* * Read { \fonttbl ... } destination.  Old font tables don't have * braces around each table entry; try to adjust for that. */static voidReadFontTbl (){RTFFont	*fp;char	buf[rtfBufSiz], *bp;int	old = -1;char	*fn = "ReadFontTbl";	for (;;)	{		(void) RTFGetToken ();		if (RTFCheckCM (rtfGroup, rtfEndGroup))			break;		if (old < 0)		/* first entry - determine tbl type */		{			if (RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum))				old = 1;	/* no brace */			else if (RTFCheckCM (rtfGroup, rtfBeginGroup))				old = 0;	/* brace */			else			/* can't tell! */				RTFPanic ("%s: Cannot determine format", fn);		}		if (old == 0)		/* need to find "{" here */		{			if (!RTFCheckCM (rtfGroup, rtfBeginGroup))				RTFPanic ("%s: missing \"{\"", fn);			(void) RTFGetToken ();	/* yes, skip to next token */		}		if ((fp = New (RTFFont)) == (RTFFont *) NULL)			RTFPanic ("%s: cannot allocate font entry", fn);		fp->rtfNextFont = fontList;		fontList = fp;		fp->rtfFName = (char *) NULL;		fp->rtfFAltName = (char *) NULL;		fp->rtfFNum = -1;		fp->rtfFFamily = 0;		fp->rtfFCharSet = 0;		fp->rtfFPitch = 0;		fp->rtfFType = 0;		fp->rtfFCodePage = 0;		while (rtfClass != rtfEOF && !RTFCheckCM (rtfText, ';'))		{			if (rtfClass == rtfControl)			{				switch (rtfMajor)				{				default:					/* ignore token but announce it */					RTFMsg ("%s: unknown token \"%s\"\n",							fn, rtfTextBuf);				case rtfFontFamily:					fp->rtfFFamily = rtfMinor;					break;				case rtfCharAttr:					switch (rtfMinor)					{					default:						break;	/* ignore unknown? */					case rtfFontNum:						fp->rtfFNum = rtfParam;						break;					}					break;				case rtfFontAttr:					switch (rtfMinor)					{					default:						break;	/* ignore unknown? */					case rtfFontCharSet:						fp->rtfFCharSet = rtfParam;						break;					case rtfFontPitch:						fp->rtfFPitch = rtfParam;						break;					case rtfFontCodePage:						fp->rtfFCodePage = rtfParam;						break;					case rtfFTypeNil:					case rtfFTypeTrueType:						fp->rtfFType = rtfParam;						break;					}					break;				}			}			else if (RTFCheckCM (rtfGroup, rtfBeginGroup))	/* dest */			{				RTFSkipGroup ();	/* ignore for now */			}			else if (rtfClass == rtfText)	/* font name */			{				bp = buf;				while (rtfClass != rtfEOF					&& !RTFCheckCM (rtfText, ';'))				{					*bp++ = rtfMajor;					(void) RTFGetToken ();				}				*bp = '\0';				fp->rtfFName = RTFStrSave (buf);				if (fp->rtfFName == (char *) NULL)					RTFPanic ("%s: cannot allocate font name", fn);				/* already have next token; don't read one */				/* at bottom of loop */				continue;			}			else			{				/* ignore token but announce it */				RTFMsg ("%s: unknown token \"%s\"\n",							fn, rtfTextBuf);			}			(void) RTFGetToken ();		}		if (old == 0)	/* need to see "}" here */		{			(void) RTFGetToken ();			if (!RTFCheckCM (rtfGroup, rtfEndGroup))				RTFPanic ("%s: missing \"}\"", fn);		}	}	if (fp->rtfFNum == -1)		RTFPanic ("%s: missing font number", fn);/* * Could check other pieces of structure here, too, I suppose. */	RTFRouteToken ();	/* feed "}" back to router */}/* * The color table entries have color values of -1 if * the default color should be used for the entry (only * a semi-colon is given in the definition, no color values). * There will be a problem if a partial entry (1 or 2 but * not 3 color values) is given.  The possibility is ignored * here. */static voidReadColorTbl (){RTFColor	*cp;int		cnum = 0;char		*fn = "ReadColorTbl";	for (;;)	{		(void) RTFGetToken ();		if (RTFCheckCM (rtfGroup, rtfEndGroup))			break;		if ((cp = New (RTFColor)) == (RTFColor *) NULL)			RTFPanic ("%s: cannot allocate color entry", fn);		cp->rtfCNum = cnum++;		cp->rtfCRed = cp->rtfCGreen = cp->rtfCBlue = -1;		cp->rtfNextColor = colorList;		colorList = cp;		while (RTFCheckCM (rtfControl, rtfColorName))		{			switch (rtfMinor)			{			case rtfRed:	cp->rtfCRed = rtfParam; break;			case rtfGreen:	cp->rtfCGreen = rtfParam; break;			case rtfBlue:	cp->rtfCBlue = rtfParam; break;			}			RTFGetToken ();		}		if (!RTFCheckCM (rtfText, (int) ';'))			RTFPanic ("%s: malformed entry", fn);	}	RTFRouteToken ();	/* feed "}" back to router */}/* * The "Normal" style definition doesn't contain any style number, * all others do.  Normal style is given style rtfNormalStyleNum. */static voidReadStyleSheet (){RTFStyle	*sp;RTFStyleElt	*sep, *sepLast;char		buf[rtfBufSiz], *bp;char		*fn = "ReadStyleSheet";	for (;;)	{		(void) RTFGetToken ();		if (RTFCheckCM (rtfGroup, rtfEndGroup))			break;		if ((sp = New (RTFStyle)) == (RTFStyle *) NULL)			RTFPanic ("%s: cannot allocate stylesheet entry", fn);		sp->rtfSName = (char *) NULL;		sp->rtfSNum = -1;		sp->rtfSType = rtfParStyle;		sp->rtfSAdditive = 0;		sp->rtfSBasedOn = rtfNoStyleNum;		sp->rtfSNextPar = -1;		sp->rtfSSEList = sepLast = (RTFStyleElt *) NULL;		sp->rtfNextStyle = styleList;		sp->rtfExpanding = 0;		styleList = sp;		if (!RTFCheckCM (rtfGroup, rtfBeginGroup))			RTFPanic ("%s: missing \"{\"", fn);		for (;;)		{			(void) RTFGetToken ();			if (rtfClass == rtfEOF				|| RTFCheckCM (rtfText, ';'))				break;			if (rtfClass == rtfControl)			{				if (RTFCheckMM (rtfSpecialChar, rtfOptDest))					continue;	/* ignore "\*" */				if (RTFCheckMM (rtfParAttr, rtfStyleNum))				{					sp->rtfSNum = rtfParam;					sp->rtfSType = rtfParStyle;					continue;				}				if (RTFCheckMM (rtfCharAttr, rtfCharStyleNum))				{					sp->rtfSNum = rtfParam;					sp->rtfSType = rtfCharStyle;					continue;				}				if (RTFCheckMM (rtfSectAttr, rtfSectStyleNum))				{					sp->rtfSNum = rtfParam;					sp->rtfSType = rtfSectStyle;					continue;				}				if (RTFCheckMM (rtfStyleAttr, rtfBasedOn))				{					sp->rtfSBasedOn = rtfParam;					continue;				}				if (RTFCheckMM (rtfStyleAttr, rtfAdditive))				{					sp->rtfSAdditive = 1;					continue;				}				if (RTFCheckMM (rtfStyleAttr, rtfNext))				{					sp->rtfSNextPar = rtfParam;					continue;				}				if ((sep = New (RTFStyleElt)) == (RTFStyleElt *) NULL)					RTFPanic ("%s: cannot allocate style element", fn);				sep->rtfSEClass = rtfClass;				sep->rtfSEMajor = rtfMajor;				sep->rtfSEMinor = rtfMinor;				sep->rtfSEParam = rtfParam;				if ((sep->rtfSEText = RTFStrSave (rtfTextBuf))								== (char *) NULL)					RTFPanic ("%s: cannot allocate style element text", fn);				if (sepLast == (RTFStyleElt *) NULL)					sp->rtfSSEList = sep;	/* first element */				else				/* add to end */					sepLast->rtfNextSE = sep;				sep->rtfNextSE = (RTFStyleElt *) NULL;				sepLast = sep;			}			else if (RTFCheckCM (rtfGroup, rtfBeginGroup))			{				/*				 * This passes over "{\*\keycode ... }, among				 * other things. A temporary (perhaps) hack.				 */				RTFSkipGroup ();				continue;			}			else if (rtfClass == rtfText)	/* style name */			{				bp = buf;				while (rtfClass == rtfText)				{					if (rtfMajor == ';')					{						/* put back for "for" loop */						(void) RTFUngetToken ();						break;					}					*bp++ = rtfMajor;					(void) RTFGetToken ();				}				*bp = '\0';				if ((sp->rtfSName = RTFStrSave (buf)) == (char *) NULL)					RTFPanic ("%s: cannot allocate style name", fn);			}			else		/* unrecognized */			{				/* ignore token but announce it */				RTFMsg ("%s: unknown token \"%s\"\n",							fn, rtfTextBuf);			}		}		(void) RTFGetToken ();		if (!RTFCheckCM (rtfGroup, rtfEndGroup))			RTFPanic ("%s: missing \"}\"", fn);		/*		 * Check over the style structure.  A name is a must.		 * If no style number was specified, check whether it's the		 * Normal style (in which case it's given style number		 * rtfNormalStyleNum).  Note that some "normal" style names		 * just begin with "Normal" and can have other stuff following,		 * e.g., "Normal,Times 10 point".  Ugh.		 *		 * Some German RTF writers use "Standard" instead of "Normal".		 */		if (sp->rtfSName == (char *) NULL)			RTFPanic ("%s: missing style name", fn);		if (sp->rtfSNum < 0)		{			if (strncmp (buf, "Normal", 6) != 0				&& strncmp (buf, "Standard", 8) != 0)				RTFPanic ("%s: missing style number", fn);			sp->rtfSNum = rtfNormalStyleNum;		}		if (sp->rtfSNextPar == -1)	/* if \snext not given, */			sp->rtfSNextPar = sp->rtfSNum;	/* next is itself */	}	RTFRouteToken ();	/* feed "}" back to router */}static voidReadInfoGroup (){	RTFSkipGroup ();	RTFRouteToken ();	/* feed "}" back to router */}static voidReadPictGroup (){	RTFSkipGroup ();	RTFRouteToken ();	/* feed "}" back to router */}static voidReadObjGroup (){	RTFSkipGroup ();	RTFRouteToken ();	/* feed "}" back to router */}/* ---------------------------------------------------------------------- *//* * Routines to return pieces of stylesheet, or font or color tables. * References to style 0 are mapped onto the Normal style. */RTFStyle *RTFGetStyle (num)int	num;{RTFStyle	*s;	if (num == -1)		return (styleList);	for (s = styleList; s != (RTFStyle *) NULL; s = s->rtfNextStyle)	{		if (s->rtfSNum == num)			break;	}	return (s);		/* NULL if not found */}RTFFont *RTFGetFont (num)int	num;{RTFFont	*f;	if (num == -1)		return (fontList);	for (f = fontList; f != (RTFFont *) NULL; f = f->rtfNextFont)	{		if (f->rtfFNum == num)			break;	}	return (f);		/* NULL if not found */}RTFColor *RTFGetColor (num)int	num;{RTFColor	*c;	if (num == -1)		return (colorList);	for (c = colorList; c != (RTFColor *) NULL; c = c->rtfNextColor)	{		if (c->rtfCNum == num)			break;	}	return (c);		/* NULL if not found */}/* ---------------------------------------------------------------------- *//* * Expand style n, if there is such a style. */voidRTFExpandStyle (n)int	n;{RTFStyle	*s;RTFStyleElt	*se;	if (n == -1 || (s = RTFGetStyle (n)) == (RTFStyle *) NULL)		return;	if (s->rtfExpanding != 0)		RTFPanic ("Style expansion loop, style %d", n);	s->rtfExpanding = 1;	/* set expansion flag for loop detection */	/*	 * Expand "based-on" style (unless it's the same as the current	 * style -- Normal style usually gives itself as its own based-on	 * style).  Based-on style expansion is done by synthesizing	 * the token that the writer needs to see in order to trigger	 * another style expansion, and feeding to token back through	 * the router so the writer sees it.	 */	if (n != s->rtfSBasedOn)	{		RTFSetToken (rtfControl, rtfParAttr, rtfStyleNum,							s->rtfSBasedOn, "\\s");		RTFRouteToken ();	}	/*	 * Now route the tokens unique to this style.  RTFSetToken()	 * isn't used because it would add the param value to the end	 * of the token text, which already has it in.	 */	for (se = s->rtfSSEList; se != (RTFStyleElt *) NULL; se = se->rtfNextSE)	{		rtfClass = se->rtfSEClass;		rtfMajor = se->rtfSEMajor;		rtfMinor = se->rtfSEMinor;		rtfParam = se->rtfSEParam;		(void) strcpy (rtfTextBuf, se->rtfSEText);		rtfTextLen = strlen (rtfTextBuf);		RTFRouteToken ();	}	s->rtfExpanding = 0;	/* done - clear expansion flag */}/* ---------------------------------------------------------------------- *//* * Control symbol lookup routines */typedef struct RTFCtrl	RTFCtrl;struct RTFCtrl{	int	major;	/* major number */	int	minor;	/* minor number */	char	*str;	/* symbol name */	int	hash;	/* symbol name hash value */};/* * A minor number of -1 means the token has no minor number * (all valid minor numbers are >= 0). */static RTFCtrl	**rtfCtrl = (RTFCtrl **) NULL;static int	nKeys;/* * Initialize lookup table hash values.  Only need to do this once. */# define        ctrlFileName    "rtf-ctrl"static voidLookupInit (){FILE    *f;RTFCtrl *rp;char    buf[rtfBufSiz];int     line = 0, i;char    *p1, *p2, *p3, c;TSScanner       scanner;char            *scanEscape;char    *fn = "LookupInit";        if (rtfCtrl != (RTFCtrl **) NULL)       /* already initialized */                return;        if ((f = RTFOpenLibFile (ctrlFileName, "r")) == (FILE *) NULL)

⌨️ 快捷键说明

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