Ejemplo n.º 1
0
void
process(Biobuf *b, char *name)
{
	int c, r, v, i;
	char *p;

	cno = 0;
	prevlineH = res;
	filename = name;
	for(;;){
		c = getc(b);
		switch(c){
		case Beof:
			/* go to ground state */
			attr = 0;
			emit('\n');
			return;
		case '\n':
			break;
		case '0': case '1': case '2': case '3': case '4':
		case '5': case '6': case '7': case '8': case '9':
			v = c-'0';
			c = getc(b);
			if(c<'0' || '9'<c)
				sysfatal("illegal character motion at %s:#%d", filename, cno);
			v = v*10 + (c-'0');
			hp += v;
			/* fall through to character case */
		case 'c':
			indent();
			r = getc(b);
			emithtmlchar(r);
			break;
		case 'D':
			/* draw line; ignore */
			do
				c = getc(b);
			while(c!='\n' && c!= Beof);
			break;
		case 'f':
			v = setnum(b, "font", 0, Nfont);
			switchfont(v);
			break;
		case 'h':
			v = setnum(b, "hpos", -20000, 20000);
			/* generate spaces if motion is large and within a line */
			if(!atnewline && v>2*72)
				for(i=0; i<v; i+=72)
					emitstr("&nbsp;");
			hp += v;
			break;
		case 'n':
			setnum(b, "n1", -10000, 10000);
			//Bprint(&bout, " N1=%d", v);
			getc(b);	/* space separates */
			setnum(b, "n2", -10000, 10000);
			atnewline = 1;
			if(!didP && hp < (Wid-1)*res)	/* if line is less than 19" long, probably need a line break */
				emitstr("<br>");
			emit('\n');
			break;
		case 'p':
			page = setnum(b, "ps", -10000, 10000);
			break;
		case 's':
			ps = setnum(b, "ps", 1, 1000);
			break;
		case 'v':
			vp += setnum(b, "vpos", -10000, 10000);
			/* BUG: ignore motion */
			break;
		case 'x':
			xcmd(b);
			break;
		case 'w':
			emit(' ');
			break;
		case 'C':
			indent();
			p = getstr(b);
			emitstr(troffchar(p));
			break;
		case 'H':
			hp = setnum(b, "hpos", 0, 20000);
			//Bprint(&bout, " H=%d ", hp);
			break;
		case 'V':
			vp = setnum(b, "vpos", 0, 10000);
			break;
		default:
			fprint(2, "dhtml: unknown directive %c(0x%.2ux) at %s:#%d\n", c, c, filename, cno);
			return;
		}
	}
}
Ejemplo n.º 2
0
/* This assumes there is a font active when it starts
 *
 * Note: \overline causes it to construct the path for the chars to measure
 *  how much space they take up.  This eats printer memory - our printer
 *  has a limit of about 30 characters.
 */
static char *outputobj(std::ostream &out, char *textptr, char *fontname, double fontsize, int pathonly)
	{
	int idx, length, cnt;
	char *newtextptr;
	char *endptr;
	char newfontname[1024];

	if (*textptr == '\\')
		{
		++textptr;
		endptr = textptr;
		while (isalpha(*endptr))
			++endptr;
		length = endptr - textptr;
		   /* First, handle special control sequences - they
		    * are picked up by the "if" and "else if" parts.
		    * Anything that isn't handled in this part is handled in the
				* "else" which assumes anything in the table should be 
				* translated into the Symbol font.  Stuff not in the table is
				* sent "as-is".
		    */
		if (length == 5 && strncmp(textptr,"prime",length) == 0)
			{
			   /* Make the prime large (like TeX) by rescaling
			    * the font & shifting the coords.
			    */
			endfont(out,pathonly);
			out << "0 " << -.46*PRIMESCALE * fontsize << " RM2\n";
			startfont(out,SYMBOLFONT,PRIMESCALE*fontsize);
			out << "\\242";
			endfont(out,pathonly);
			out << "0 " << .46*PRIMESCALE * fontsize << " RM2\n";
			startfont(out,fontname,fontsize);
			return endptr;
			}
		else if (length == 5 && strncmp(textptr,"minus",length) == 0)
			{
			switchfont(out,fontname,SYMBOLFONT,fontsize,pathonly);
			out << '-';
			switchfont(out,SYMBOLFONT,fontname,fontsize,pathonly);
			return endptr;
			}
		else if (length == 3 && strncmp(textptr,"dag",length) == 0)
			{
			switchfont(out,fontname,"Times-Roman",fontsize,pathonly);
			out << "\\262";
			switchfont(out,"Times-Roman",fontname,fontsize,pathonly);
			return endptr;
			}
		else if (length == 4 && strncmp(textptr,"font",length) == 0)
			{
			if (*endptr != '{')
				{
				std::cerr << ERRSTR << "Expect '{fontname}' after \\font, but found ";
				std::cerr << '\'' << endptr << "'\n";
				exit(1);
				}
			++endptr;
			cnt = 0;
			while (*endptr != '}' && *endptr != '\0')
				{
				newfontname[cnt] = *endptr;
				++endptr;
				++cnt;
				}
			newfontname[cnt] = '\0';
			if (*endptr != '}')
				{
				std::cerr << ERRSTR << "Missing '}' in \\font{fontname}\n";
				exit(1);
				}
			switchfont(out,fontname,newfontname,fontsize,pathonly);
			endptr = outputobj(out,endptr+1,newfontname,fontsize,pathonly);
			switchfont(out,newfontname,fontname,fontsize,pathonly);
			return endptr;
			}	
		else if (length == 8 && strncmp(textptr,"overline",length) == 0)
			{
			   /* Do the overline by first constructing path for the text
			    * we are going to overline, then get bounding box and use
			    * to position the line.  Then re-create the text (yes,
			    * all text is generated twice - once for sizing, once
			    * for output).
					*
					* WARNING:  If already have pathonly==true, just don't output
					* anything - this is done because if we put the overbar in
					* the path, using "PBX" will pick up info about earlier
					* parts of the path & will screw things up.  The upshot of this
					* is that if you overline an object which contains an overline,
					* the contained overline is not included when the position of
					* the overline is calculated - this is a bug which probably
					* won't hurt much...
			    */
			if (!pathonly)
				{
				get_overline_coords(out, endptr, fontname, fontsize , pathonly);
				out << "NP M2 " ;
				out << OVERLINE_THICKNESS * fontsize << " SLW\n";
				out << "L2 ST\n";
				out << "M2\n";  // Now move back & draw the text under the overline
				startfont(out,fontname,fontsize);
				return outputobj(out,endptr,fontname,fontsize,pathonly);
				}
			return endptr;
			}
		else if (length == 9 && strncmp(textptr,"widetilde",length) == 0)
			{
			   /* The above comments for overline apply here too.
			    */
			if (!pathonly)
				{
				get_overline_coords(out, endptr, fontname, fontsize , pathonly);
				out << TILDE_HEIGHT * fontsize << " tilde fill\n";
				out << "M2\n";  // Now move back & draw the text under the overline
				startfont(out,fontname,fontsize);
				return outputobj(out,endptr,fontname,fontsize,pathonly);
				}
			return endptr;
			}
		else if (length == 14 && strncmp(textptr,"overrightarrow",length) == 0)
			{
			   /* The above comments for overline apply here too.
			    */
			if (!pathonly)
				{
				get_overline_coords(out, endptr, fontname, fontsize , pathonly);
				 // Draw the arrow head
				out << "2 copy 2 copy 4 -1 roll " << -ARROW_LENGTH*fontsize << " add\n";
				out << "4 1 roll " << ARROW_ANGLE << " arrow fill\n";
				 // Draw the stem of the arrow
				out << "2 1 roll " << -ARROW_LENGTH*fontsize << " add 2 1 roll\n";
				out << "NP M2 " ;
				out << OVERLINE_THICKNESS * fontsize << " SLW\n";
				out << "L2 ST\n";
				out << "M2\n";  // Now move back & draw the text under the overline
				startfont(out,fontname,fontsize);
				return outputobj(out,endptr,fontname,fontsize,pathonly);
				}
			return endptr;
			}
		else if (length == 8 && strncmp(textptr,"tildebar",length) == 0)
			{
			   /* The above comments for overline apply here too.
			    */
			if (!pathonly)
				{
				get_overline_coords(out, endptr, fontname, fontsize , pathonly);
				out << "4 copy\n";  // Copy coords for the tilde
				 // Make the overline
				out << "NP M2 " ; 
				out << OVERLINE_THICKNESS * fontsize << " SLW\n";
				out << "L2 ST\n";
				 // Make the tilde
				out << OVERLINE_SHIFT * fontsize << " add\n";
				out << "3 -1 roll " << OVERLINE_SHIFT * fontsize << " add 3 1 roll\n";
				out << TILDE_HEIGHT * fontsize << " tilde fill\n";
				out << "M2\n";  // Now move back & draw the text under the overline
				startfont(out,fontname,fontsize);
				return outputobj(out,endptr,fontname,fontsize,pathonly);
				}
			return endptr;
			}
		else  
			{  
			for (idx = sizeof(text2PS_syms)
			   /sizeof(struct text2PS_symbol_translation) - 1
			   ; idx >= 0 ; --idx)
				{
				if (strncmp(textptr,text2PS_syms[idx].insym,length) == 0
				   && (strlen(text2PS_syms[idx].insym) == length))
					break;
				}
			if (idx >= 0)  // have a match - map to something in Symbol font
				{
				endfont(out,pathonly);
				startfont(out,SYMBOLFONT,fontsize);
				out << text2PS_syms[idx].outsym;
				endfont(out,pathonly);
				startfont(out,fontname,fontsize);
				return endptr;
				}
			else  // no match (not in table) - send "as is"
				{
				outputchar(out,*textptr);
				return textptr + 1;
				}
			}
		}
	else if (*textptr == '{')
		{
		++textptr;
		while (*textptr != '}' && *textptr != '\0')
			textptr = outputobj(out,textptr,fontname,fontsize,pathonly);
		return textptr + 1;
		}
	else if (*textptr == '_')
		{
		endfont(out,pathonly);
		out << "CPT\n";
		newtextptr = outputsubscript(out,textptr+1,fontname,fontsize,pathonly);
		if (*newtextptr == '^')
			{
			out << "CPT pop\n"; // save x value
			out << "3 1 roll\n";  // push the x value to the bottom
			out << "M2\n";
			out << "CPT exch pop exch\n"; // save the y value & put before x
			newtextptr = outputsuperscript(out,newtextptr+1,fontname,fontsize,pathonly);
			   // move to start of normal text - compare x's & fetch y, then move
			out << "CPT pop max exch M2\n";  // now stack is empty
			}
		else
				// use old y & new x value
			out << "exch pop CPT pop exch M2\n";  // now stack is empty
		startfont(out,fontname,fontsize);
		return newtextptr;
		}
	else if (*textptr == '^')
		{
		endfont(out,pathonly);
		out << "CPT\n";
		newtextptr = outputsuperscript(out,textptr+1,fontname,fontsize,pathonly);
		if (*newtextptr == '_')
			{
			out << "CPT pop\n"; // save x value
			out << "3 1 roll\n";  // push the x value to the bottom
			out << "M2\n";
			out << "CPT exch pop exch\n"; // save the y value & put before x
			newtextptr = outputsubscript(out,newtextptr+1,fontname,fontsize,pathonly);
			   // move to start of normal text - compare x's & fetch y, then move
			out << "CPT pop max exch M2\n";  // now stack is empty
			}
		else
				// use old y & new x value
			out << "exch pop CPT pop exch M2\n";  // now stack is empty
		startfont(out,fontname,fontsize);
		return newtextptr;
		}
	else 
		{
		outputchar(out,*textptr);
		return textptr + 1;
		}
	}