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

📄 reader.c

📁 将rft格式文件转换成html格式文件
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (pushedClass >= 0)	{		rtfClass = pushedClass;		rtfMajor = pushedMajor;		rtfMinor = pushedMinor;		rtfParam = pushedParam;		(void) strcpy (rtfTextBuf, pushedTextBuf);		rtfTextLen = strlen (rtfTextBuf);		pushedClass = -1;		return;	}	/*	 * Beyond this point, no token is ever seen twice, which is	 * important, e.g., for making sure no "}" pops the font stack twice.	 */	_RTFGetToken2 ();	if (rtfClass == rtfText)	/* map RTF char to standard code */		rtfMinor = RTFMapChar (rtfMajor);	/*	 * If auto-charset stuff is activated, see if anything needs doing,	 * like reading the charset maps or switching between them.	 */	if (autoCharSetFlags == 0)		return;	if ((autoCharSetFlags & rtfReadCharSet)		&& RTFCheckCM (rtfControl, rtfCharSet))	{		ReadCharSetMaps ();	}	else if ((autoCharSetFlags & rtfSwitchCharSet)		&& RTFCheckCMM (rtfControl, rtfCharAttr, rtfFontNum))	{		if ((fp = RTFGetFont (rtfParam)) != (RTFFont *) NULL)		{			if (fp->rtfFName!=NULL&&strncmp (fp->rtfFName, "Symbol", 6) == 0)				curCharSet = rtfCSSymbol;			else				curCharSet = rtfCSGeneral;			RTFSetCharSet (curCharSet);		}	}	else if ((autoCharSetFlags & rtfSwitchCharSet) && rtfClass == rtfGroup)	{		switch (rtfMajor)		{		case rtfBeginGroup:			if (csTop >= maxCSStack)				RTFPanic ("_RTFGetToken: stack overflow");			csStack[csTop++] = curCharSet;			break;		case rtfEndGroup:			if (csTop <= 0)				RTFPanic ("_RTFGetToken: stack underflow");			curCharSet = csStack[--csTop];			RTFSetCharSet (curCharSet);			break;		}	}}/* this shouldn't be called anywhere but from _RTFGetToken() */void_RTFGetToken2 (){int	sign;int	c;	/* initialize token vars */	rtfClass = rtfUnknown;	rtfParam = rtfNoParam;	rtfTextBuf[rtfTextLen = 0] = '\0';	/* get first character, which may be a pushback from previous token */	if (pushedChar != EOF)	{		c = pushedChar;		rtfTextBuf[rtfTextLen++] = c;		rtfTextBuf[rtfTextLen] = '\0';		pushedChar = EOF;	}	else if ((c = GetChar ()) == EOF)	{		rtfClass = rtfEOF;		return;	}	if (c == '{')	{		rtfClass = rtfGroup;		rtfMajor = rtfBeginGroup;		return;	}	if (c == '}')	{		rtfClass = rtfGroup;		rtfMajor = rtfEndGroup;		return;	}	if (c != '\\')	{		/*		 * Two possibilities here:		 * 1) ASCII 9, effectively like \tab control symbol		 * 2) literal text char		 */		if (c == '\t')			/* ASCII 9 */		{			rtfClass = rtfControl;			rtfMajor = rtfSpecialChar;			rtfMinor = rtfTab;		}		else		{			rtfClass = rtfText;			rtfMajor = c;		}		return;	}	if ((c = GetChar ()) == EOF)	{		/* early eof, whoops (class is rtfUnknown) */		return;	}	if (!isalpha (c))	{		/*		 * Three possibilities here:		 * 1) hex encoded text char, e.g., \'d5, \'d3		 * 2) special escaped text char, e.g., \{, \}		 * 3) control symbol, e.g., \_, \-, \|, \<10>		 */		if (c == '\'')				/* hex char */		{		int	c2;			if ((c = GetChar ()) != EOF && (c2 = GetChar ()) != EOF)			{				/* should do isxdigit check! */				rtfClass = rtfText;				rtfMajor = RTFCharToHex (c) * 16						+ RTFCharToHex (c2);				return;			}			/* early eof, whoops (class is rtfUnknown) */			return;		}		/* escaped char */		/*if (index (":{}\\", c) != (char *) NULL) /* escaped char */		if (c == ':' || c == '{' || c == '}' || c == '\\')		{			rtfClass = rtfText;			rtfMajor = c;			return;		} 		/* control symbol */		Lookup (rtfTextBuf);	/* sets class, major, minor */		return;	}	/* control word */	while (isalpha (c))	{		if ((c = GetChar ()) == EOF)			break;	}	/*	 * At this point, the control word is all collected, so the	 * major/minor numbers are determined before the parameter	 * (if any) is scanned.  There will be one too many characters	 * in the buffer, though, so fix up before and restore after	 * looking up.	 */	if (c != EOF)		rtfTextBuf[rtfTextLen-1] = '\0';	Lookup (rtfTextBuf);	/* sets class, major, minor */	if (c != EOF)		rtfTextBuf[rtfTextLen-1] = c;	/*	 * Should be looking at first digit of parameter if there	 * is one, unless it's negative.  In that case, next char	 * is '-', so need to gobble next char, and remember sign.	 */	sign = 1;	if (c == '-')	{		sign = -1;		c = GetChar ();	}	if (c != EOF && isdigit (c))	{		rtfParam = 0;		while (isdigit (c))	/* gobble parameter */		{			rtfParam = rtfParam * 10 + c - '0';			if ((c = GetChar ()) == EOF)				break;		}		rtfParam *= sign;	}	/*	 * If control symbol delimiter was a blank, gobble it.	 * Otherwise the character is first char of next token, so	 * push it back for next call.  In either case, delete the	 * delimiter from the token buffer.	 */	if (c != EOF)	{		if (c != ' ')			pushedChar = c;		rtfTextBuf[--rtfTextLen] = '\0';	}}/* * Read the next character from the input.  This handles setting the * current line and position-within-line variables.  Those variable are * set correctly whether lines end with CR, LF, or CRLF (the last being * the tricky case). * * bumpLine indicates whether the line number should be incremented on * the *next* input character. */static intGetChar (){int	c;int	oldBumpLine;	if ((c = getc (rtffp)) != EOF)	{		rtfTextBuf[rtfTextLen++] = c;		rtfTextBuf[rtfTextLen] = '\0';	}	if (prevChar == EOF)		bumpLine = 1;	oldBumpLine = bumpLine;	/* non-zero if prev char was line ending */	bumpLine = 0;	if (c == '\r')		bumpLine = 1;	else if (c == '\n')	{		bumpLine = 1;		if (prevChar == '\r')		/* oops, previous \r wasn't */			oldBumpLine = 0;	/* really a line ending */	}	++rtfLinePos;	if (oldBumpLine)	/* were we supposed to increment the */	{			/* line count on this char? */		++rtfLineNum;		rtfLinePos = 1;	}	prevChar = c;	return (c);}/* * Synthesize a token by setting the global variables to the * values supplied.  Typically this is followed with a call * to RTFRouteToken(). * * If a param value other than rtfNoParam is passed, it becomes * part of the token text. */voidRTFSetToken (class, major, minor, param, text)int	class, major, minor, param;char	*text;{	rtfClass = class;	rtfMajor = major;	rtfMinor = minor;	rtfParam = param;	if (param == rtfNoParam)		(void) strcpy (rtfTextBuf, text);	else		sprintf (rtfTextBuf, "%s%d", text, param);	rtfTextLen = strlen (rtfTextBuf);}/* ---------------------------------------------------------------------- *//* * Routines to handle mapping of RTF character sets * onto standard characters. * * RTFStdCharCode(name)	given char name, produce numeric code * RTFStdCharName(code)	given char code, return name * RTFMapChar(c)	map input (RTF) char code to std code * RTFSetCharSet(id)	select given charset map * RTFGetCharSet()	get current charset map * * See ../h/README for more information about charset names and codes. *//* * Initialize charset stuff. */static voidCharSetInit (){	autoCharSetFlags = (rtfReadCharSet | rtfSwitchCharSet);	RTFFree (genCharSetFile);	genCharSetFile = (char *) NULL;	haveGenCharSet = 0;	RTFFree (symCharSetFile);	symCharSetFile = (char *) NULL;	haveSymCharSet = 0;	curCharSet = rtfCSGeneral;	curCharCode = genCharCode;}/* * Specify the name of a file to be read when auto-charset-file reading is * done. */voidRTFSetCharSetMap (name, csId)char	*name;int	csId;{	if ((name = RTFStrSave (name)) == (char *) NULL)	/* make copy */		RTFPanic ("RTFSetCharSetMap: out of memory");	switch (csId)	{	case rtfCSGeneral:		RTFFree (genCharSetFile);	/* free any previous value */		genCharSetFile = name;		break;	case rtfCSSymbol:		RTFFree (symCharSetFile);	/* free any previous value */		symCharSetFile = name;		break;	}}/* * Do auto-charset-file reading. */static voidReadCharSetMaps (){char	buf[rtfBufSiz];	if (genCharSetFile != (char *) NULL)		(void) strcpy (buf, genCharSetFile);	else		sprintf (buf, "%s-gen", &rtfTextBuf[1]);	if (RTFReadCharSetMap (buf, rtfCSGeneral) == 0)		RTFPanic ("ReadCharSetMaps: Cannot read charset map %s", buf);	if (symCharSetFile != (char *) NULL)		(void) strcpy (buf, symCharSetFile);	else		sprintf (buf, "%s-sym", &rtfTextBuf[1]);	if (RTFReadCharSetMap (buf, rtfCSSymbol) == 0)		RTFPanic ("ReadCharSetMaps: Cannot read charset map %s", buf);}/* * Read in a file describing an RTF character set map.  Lines consist of pairs * associating character names with character values. * * If the filename is an absolute pathname, look in the specified location * only.  Otherwise try to find the file in the current directory or library. */intRTFReadCharSetMap (file, csId)char	*file;int	csId;{FILE	*f;char	buf[rtfBufSiz];char	*name, *p;int	*stdCodeArray;int	stdCode;int	radix;int	value;int	i;TSScanner	scanner;char		*scanEscape;char	*fn = "RTFReadCharSetMap";	switch (csId)	{	default:		return (0);	/* illegal charset id */	case rtfCSGeneral:		stdCodeArray = genCharCode;		break;	case rtfCSSymbol:		stdCodeArray = symCharCode;		break;	}	if ((f = RTFOpenLibFile (file, "r")) == (FILE *) NULL)		return (0);	/* clobber current mapping */	for (i = 0; i < charSetSize; i++)	{		stdCodeArray[i] = rtfSC_nothing;	}	/*	 * Turn off scanner's backslash escape mechanism while reading	 * charset file.  Restore it later.	 */	TSGetScanner (&scanner);	scanEscape = scanner.scanEscape;	scanner.scanEscape = "";	TSSetScanner (&scanner);	/* read file */	while (fgets (buf, (int) sizeof (buf), f) != (char *) NULL)	{		if(buf[0] == '#')	/* skip comment lines */			continue;		TSScanInit (buf);		if ((name = TSScan ()) == (char *) NULL)			continue;	/* skip blank lines */		if ((stdCode = RTFStdCharCode (name)) < 0)		{			RTFPanic ("%s: unknown character name: %s", fn, name);			continue;		}		if ((p = TSScan ()) == (char *) NULL)		{			RTFPanic ("%s: malformed charset map line for character %s",								fn, name);			continue;		}		if (p[1] == '\0')	/* single char - use ascii value */			value = p[0];		else		{			radix = 10;			if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))			{				radix = 16;				p += 2;			}			value = 0;			while (*p != '\0')				value = value * radix + RTFCharToHex(*p++);		}		if (value >= charSetSize)		{			RTFMsg ("%s: character value %d for %s too high\n",							fn, value, name);			RTFPanic ("maximum value is %d", charSetSize - 1);		}		stdCodeArray[value] = stdCode;	}	scanner.scanEscape = scanEscape;	TSSetScanner (&scanner);	fclose(f);	switch (csId)	{	case rtfCSGeneral:		haveGenCharSet = 1;		break;	case rtfCSSymbol:		haveSymCharSet = 1;		break;	}	return (1);}/* * Given a standard character name (a string), find its code (a number). * Return -1 if name is unknown. */intRTFStdCharCode (name)char	*name;{int	i;	for (i = 0; i < rtfSC_MaxChar; i++)	{		if (strcmp (name, stdCharName[i]) == 0)			return (i);	}	return (-1);}/* * Given a standard character code (a number), find its name (a string). * Return NULL if code is unknown. */char *RTFStdCharName (code)int	code;{	if (code < 0 || code >= rtfSC_MaxChar)		return ((char *) NULL);	return (stdCharName[code]);}/* * Given an RTF input character code, find standard character code. * The translator should read the appropriate charset maps when it finds a * charset control.  However, the file might not contain one.  In this * case, no map will be available.  When the first attempt is made to * map a character under these circumstances, RTFMapChar() assumes ANSI * and reads the map as necessary. */intRTFMapChar (c)int	c;{	switch (curCharSet)	{	case rtfCSGeneral:		if (!haveGenCharSet)		{			if (RTFReadCharSetMap ("ansi-gen", rtfCSGeneral) == 0)				RTFPanic ("RTFMapChar: cannot read ansi-gen");		}		break;	case rtfCSSymbol:		if (!haveSymCharSet)		{			if (RTFReadCharSetMap ("ansi-sym", rtfCSSymbol) == 0)				RTFPanic ("RTFMapChar: cannot read ansi-sym");		}		break;	}	if (c < 0 || c >= charSetSize)		return (rtfSC_nothing);	return (curCharCode[c]);}/*

⌨️ 快捷键说明

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