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

📄 html2ms.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <ctype.h>#include <bio.h>enum{	SSIZE = 10,	/* list types */	Lordered = 0,	Lunordered,	Lmenu,	Ldir,};Biobuf in, out;int lastc = '\n';int inpre = 0;/* stack for fonts */char *fontstack[SSIZE];char *font = "R";int fsp;/* stack for lists */struct{	int	type;	int	ord;} liststack[SSIZE];int lsp;int quoting;typedef struct Goobie Goobie;struct Goobie{	char *name;	void (*f)(Goobie*, char*);	void (*ef)(Goobie*, char*);};void	eatwhite(void);void	escape(void);typedef void Action(Goobie*, char*);Action	g_ignore;Action	g_unexpected;Action	g_title;Action	g_p;Action	g_h;Action	g_li;Action	g_list, g_listend;Action	g_pre;Action	g_fpush, g_fpop;Action	g_indent, g_exdent;Action	g_dt;Action	g_display;Action	g_displayend;Action	g_table, g_tableend, g_caption, g_captionend;Action	g_br, g_hr;Goobie gtab[] ={	"!--",		g_ignore,	g_unexpected,	"!doctype",	g_ignore,	g_unexpected,	"a",		g_ignore,	g_ignore,	"address",	g_display,	g_displayend,	"b",		g_fpush,	g_fpop,	"base",		g_ignore,	g_unexpected,	"blink",	g_ignore,	g_ignore,	"blockquote",	g_ignore,	g_ignore,	"body",		g_ignore,	g_ignore,	"br",		g_br,		g_unexpected,	"caption",	g_caption,	g_captionend,	"center",	g_ignore,	g_ignore,	"cite",		g_ignore,	g_ignore,	"code",		g_ignore,	g_ignore,	"dd",		g_ignore,	g_unexpected,	"dfn",		g_ignore,	g_ignore,	"dir",		g_list,		g_listend,	"dl",		g_indent,	g_exdent,	"dt",		g_dt,		g_unexpected,	"em",		g_ignore,	g_ignore,	"font",		g_ignore,	g_ignore,	"form",		g_ignore,	g_ignore,	"h1",		g_h,		g_p,	"h2",		g_h,		g_p,	"h3",		g_h,		g_p,	"h4",		g_h,		g_p,	"h5",		g_h,		g_p,	"h6",		g_h,		g_p,	"head",		g_ignore,	g_ignore,	"hr",		g_hr,		g_unexpected,	"html",		g_ignore,	g_ignore,	"i",		g_fpush,	g_fpop,	"input",	g_ignore,	g_unexpected,	"img",		g_ignore,	g_unexpected,	"isindex",	g_ignore,	g_unexpected,	"kbd",		g_fpush,	g_fpop,	"key",		g_ignore,	g_ignore,	"li",		g_li,		g_unexpected,	"link",		g_ignore,	g_unexpected,	"listing",	g_ignore,	g_ignore,	"menu",		g_list,		g_listend,	"meta",		g_ignore,	g_unexpected,	"nextid",	g_ignore,	g_unexpected,	"ol",		g_list,		g_listend,	"option",	g_ignore,	g_unexpected,	"p",		g_p,		g_ignore,	"plaintext",	g_ignore,	g_unexpected,	"pre",		g_pre,		g_displayend,	"samp",		g_ignore,	g_ignore,	"select",	g_ignore,	g_ignore,	"strong",	g_ignore,	g_ignore,	"table",	g_table,	g_tableend,	"textarea",	g_ignore,	g_ignore,	"title",	g_title,	g_ignore,	"tt",		g_fpush,	g_fpop,	"u",		g_ignore,	g_ignore,	"ul",		g_list,		g_listend,	"var",		g_ignore,	g_ignore,	"xmp",		g_ignore,	g_ignore,	0,		0,	0,};typedef struct Entity Entity;struct Entity{	char *name;	Rune value;};Entity pl_entity[]={"#SPACE", L' ', "#RS",   L'\n', "#RE",   L'\r', "quot",   L'"',"AElig",  L'Æ', "Aacute", L'Á', "Acirc",  L'Â', "Agrave", L'À', "Aring",  L'Å',"Atilde", L'Ã', "Auml",   L'Ä', "Ccedil", L'Ç', "ETH",    L'Ð', "Eacute", L'É',"Ecirc",  L'Ê', "Egrave", L'È', "Euml",   L'Ë', "Iacute", L'Í', "Icirc",  L'Î',"Igrave", L'Ì', "Iuml",   L'Ï', "Ntilde", L'Ñ', "Oacute", L'Ó', "Ocirc",  L'Ô',"Ograve", L'Ò', "Oslash", L'Ø', "Otilde", L'Õ', "Ouml",   L'Ö', "THORN",  L'Þ',"Uacute", L'Ú', "Ucirc",  L'Û', "Ugrave", L'Ù', "Uuml",   L'Ü', "Yacute", L'Ý',"aacute", L'á', "acirc",  L'â', "aelig",  L'æ', "agrave", L'à', "amp",    L'&',"aring",  L'å', "atilde", L'ã', "auml",   L'ä', "ccedil", L'ç', "eacute", L'é',"ecirc",  L'ê', "egrave", L'è', "eth",    L'ð', "euml",   L'ë', "gt",     L'>',"iacute", L'í', "icirc",  L'î', "igrave", L'ì', "iuml",   L'ï', "lt",     L'<',"ntilde", L'ñ', "oacute", L'ó', "ocirc",  L'ô', "ograve", L'ò', "oslash", L'ø',"otilde", L'õ', "ouml",   L'ö', "szlig",  L'ß', "thorn",  L'þ', "uacute", L'ú',"ucirc",  L'û', "ugrave", L'ù', "uuml",   L'ü', "yacute", L'ý', "yuml",   L'ÿ',0};intcistrcmp(char *a, char *b){	int c, d;	for(;; a++, b++){		d = tolower(*a);		c = d - tolower(*b);		if(c)			break;		if(d == 0)			break;	}	return c;}intreadupto(char *buf, int n, char d, char notme){	char *p;	int c;	buf[0] = 0;	for(p = buf;; p++){		c = Bgetc(&in);		if(c < 0){			*p = 0;			return -1;		}		if(c == notme){			Bungetc(&in);			return -1;		}		if(c == d){			*p = 0;			return 0;		}		*p = c;		if(p == buf + n){			*p = 0;			Bprint(&out, "<%s", buf);			return -1;		}	}}voiddogoobie(void){	char *arg, *type;	Goobie *g;	char buf[1024];	int closing;	if(readupto(buf, sizeof(buf), '>', '<') < 0){		Bprint(&out, "<%s", buf);		return;	}	type = buf;	if(*type == '/'){		type++;		closing = 1;	} else		closing = 0;	arg = strchr(type, ' ');	if(arg == 0)		arg = strchr(type, '\r');	if(arg == 0)		arg = strchr(type, '\n');	if(arg)		*arg++ = 0;	for(g = gtab; g->name; g++)		if(cistrcmp(type, g->name) == 0){			if(closing){				if(g->ef){					(*g->ef)(g, arg);					return;				}			} else {				if(g->f){					(*g->f)(g, arg);					return;				}			}		}	if(closing)		type--;	if(arg)		Bprint(&out, "<%s %s>\n", type, arg);	else		Bprint(&out, "<%s>\n", type);}voidmain(void){	int c;	Binit(&in, 0, OREAD);	Binit(&out, 1, OWRITE);	for(;;){		c = Bgetc(&in);		if(c < 0)			return;		switch(c){		case '<':			dogoobie();			break;		case '&':			escape();			break;		case '\r':			break;		case '\n':			if(quoting){				Bputc(&out, '"');				quoting = 0;			}			if(lastc != '\n')				Bputc(&out, '\n');			/* can't emit leading spaces in filled troff docs */			if (!inpre)				eatwhite();			lastc = c;			break;		default:			Bputc(&out, c);			lastc = c;			break;		}	}}voidescape(void){	Entity *e;	char buf[8];	if(readupto(buf, sizeof(buf), ';', '\n') < 0){		Bprint(&out, "&%s", buf);		return;	}	for(e = pl_entity; e->name; e++)		if(strcmp(buf, e->name) == 0){			Bprint(&out, "%C", e->value);			return;		}	Bprint(&out, "&%s;", buf);}/* * whitespace is not significant to HTML, but newlines * and leading spaces are significant to troff. */voideatwhite(void){	int c;	for(;;){		c = Bgetc(&in);		if(c < 0)			break;		if(!isspace(c)){			Bungetc(&in);			break;		}	}}/* *  print at start of line */voidprintsol(char *fmt, ...){	va_list arg;	if(quoting){		Bputc(&out, '"');		quoting = 0;	}	if(lastc != '\n')		Bputc(&out, '\n');	va_start(arg, fmt);	Bvprint(&out, fmt, arg);	va_end(arg);	lastc = '\n';}voidg_ignore(Goobie *g, char *arg){	USED(g, arg);}voidg_unexpected(Goobie *g, char *arg){	USED(arg);	fprint(2, "unexpected %s ending\n", g->name);}voidg_title(Goobie *g, char *arg){	USED(arg);	printsol(".TL\n", g->name);}voidg_p(Goobie *g, char *arg){	USED(arg);	printsol(".LP\n", g->name);}voidg_h(Goobie *g, char *arg){	USED(arg);	printsol(".SH %c\n", g->name[1]);}voidg_list(Goobie *g, char *arg){	USED(arg);	if(lsp != SSIZE){		switch(g->name[0]){		case 'o':			liststack[lsp].type  = Lordered;			liststack[lsp].ord = 0;			break;		default:			liststack[lsp].type = Lunordered;			break;		}	}	lsp++;}voidg_br(Goobie *g, char *arg){	USED(g, arg);	printsol(".br\n");}voidg_li(Goobie *g, char *arg){	USED(g, arg);	if(lsp <= 0 || lsp > SSIZE){		printsol(".IP \\(bu\n");		return;	}	switch(liststack[lsp-1].type){	case Lunordered:		printsol(".IP \\(bu\n");		break;	case Lordered:		printsol(".IP %d\n", ++liststack[lsp-1].ord);		break;	}}voidg_listend(Goobie *g, char *arg){	USED(g, arg);	if(--lsp < 0)		lsp = 0;	printsol(".LP\n");}voidg_display(Goobie *g, char *arg){	USED(g, arg);	printsol(".DS\n");}voidg_pre(Goobie *g, char *arg){	USED(g, arg);	printsol(".DS L\n");	inpre = 1;}voidg_displayend(Goobie *g, char *arg){	USED(g, arg);	printsol(".DE\n");	inpre = 0;}voidg_fpush(Goobie *g, char *arg){	USED(arg);	if(fsp < SSIZE)		fontstack[fsp] = font;	fsp++;	switch(g->name[0]){	case 'b':		font = "B";		break;	case 'i':		font = "I";		break;	case 'k':		/* kbd */	case 't':		/* tt */		font = "(CW";		break;	}	Bprint(&out, "\\f%s", font);}voidg_fpop(Goobie *g, char *arg){	USED(g, arg);	fsp--;	if(fsp < SSIZE)		font = fontstack[fsp];	else		font = "R";	Bprint(&out, "\\f%s", font);}voidg_indent(Goobie *g, char *arg){	USED(g, arg);	printsol(".RS\n");}voidg_exdent(Goobie *g, char *arg){	USED(g, arg);	printsol(".RE\n");}voidg_dt(Goobie *g, char *arg){	USED(g, arg);	printsol(".IP \"");	quoting = 1;}voidg_hr(Goobie *g, char *arg){	USED(g, arg);	printsol(".br\n");	printsol("\\l'5i'\n");}/*<table border><caption><font size="+1"><b>Cumulative Class Data</b></font></caption><tr><th rowspan=2>DOSE<br>mg/kg</th><th colspan=2>PARALYSIS</th><th colspan=2>DEATH</th></tr><tr><th width=80>Number</th><th width=80>Percent</th><th width=80>Number</th><th width=80>Percent</th></tr><tr align=center><td>0.1</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.2</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.3</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.4</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.5</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.6</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.7</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.8</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr><tr align=center><td>0.8 oral</td><td><br></td> <td><br></td> <td><br></td> <td><br></td></tr></table>*/voidg_table(Goobie *g, char *arg){	USED(g, arg);	printsol(".TS\ncenter ;\n");}voidg_tableend(Goobie *g, char *arg){	USED(g, arg);	printsol(".TE\n");}voidg_caption(Goobie *g, char *arg){	USED(g, arg);}voidg_captionend(Goobie *g, char *arg){	USED(g, arg);}

⌨️ 快捷键说明

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