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

📄 ms2html.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <u.h>#include <libc.h>#include <ctype.h>#include <bio.h>enum{	SSIZE = 10,	Maxnh=	8,		/* highest NH level */	HH=	4,		/* heading level used for SH and NH */	Maxmstack=	10,	/* deepest macro/string nesting */	Narg=	20,		/* max args to a macro */	Maxsstack=	5,	/* deepest nesting of .so's */	Nline=	1024,	Maxget= 10,	Maxif = 20,	Maxfsp = 100,	/* list types */	Lordered = 1,	Lunordered,	Ldef,	Lother,};char *delim = "$$";char *basename;char *title;int eqnmode;int 	quiet;float	indent; /* from .in */Biobuf	bout;int	isup;int	isdown;int	debug;int nh[Maxnh];int ifwastrue[Maxif];int list, listnum, example;int hangingau, hangingdt, hanginghead, hangingcenter;int indirective, paragraph, sol, titleseen, ignore_nl, weBref;void dohangingcenter(void);typedef struct Goobie Goobie;typedef struct Goobieif Goobieif;struct Goobie{	char *name;	void (*f)(int, char**);};typedef void F(int, char**);typedef void Fif(char*, char*);struct Goobieif{	char *name;	Fif *f;};/* if, ie */Fif g_as, g_ds, g_el, g_ie, g_if;Goobieif gtabif[] = {	{ "as", g_as },	{ "ds", g_ds },	{ "if", g_if },	{ "ie", g_ie },	{ "el", g_el },	{ nil, nil },	};/* pseudo ops */F g_notyet, g_ignore, g_hrule, g_startgif;/* ms macros */F g_AU, g_B, g_BI, g_CW, g_I, g_IP, g_LP, g_PP, g_SH, g_NH;F g_P1, g_P2, g_TL, g_R, g_AB, g_AE, g_EQ, g_TS, g_TE, g_FS, g_FE;F g_PY, g_IH, g_MH, g_HO, g_BX, g_QS, g_QE, g_RS, g_RE;/* pictures macro */F g_BP;/* real troff */F g_br, g_ft, g_sp, g_de, g_lf, g_so, g_rm, g_in;F g_nr, g_ig, g_RT, g_BS, g_BE, g_LB, g_ta;/* macros to include ML in output */F g__H, g__T;Goobie gtab[] ={	{ "_T", g__T, },	{ "_H", g__H, },	{ "1C",	g_ignore, },	{ "2C",	g_ignore, },	{ "AB", g_AB, },	{ "AE", g_AE, },	{ "AI", g_ignore, },	{ "AU", g_AU, },	{ "B",	g_B, },	{ "B1", g_hrule, },	{ "B2", g_hrule, },	{ "BI",	g_BI, },	{ "BP",	g_BP, },	{ "BT",	g_ignore, },	{ "BX",	g_BX, },	{ "CW",	g_CW, },	{ "CT",	g_ignore, },	{ "DA",	g_ignore, },	{ "DE",	g_P2, },	{ "DS",	g_P1, },	{ "EG",	g_ignore, },	{ "EN",	g_ignore, },	{ "EQ",	g_startgif, },	{ "FE",	g_FE, },	{ "FP",	g_ignore, },	{ "FS",	g_FS, },	{ "HO",	g_HO, },	{ "I",	g_I, },	{ "IH",	g_IH, },	{ "IM",	g_ignore, },	{ "IP",	g_IP, },	{ "KE",	g_ignore, },	{ "KF",	g_ignore, },	{ "KS",	g_ignore, },	{ "LG",	g_ignore, },	{ "LP",	g_LP, },	{ "LT",	g_ignore, },	{ "MF",	g_ignore, },	{ "MH",	g_MH, },	{ "MR",	g_ignore, },	{ "ND",	g_ignore, },	{ "NH",	g_NH, },	{ "NL",	g_ignore, },	{ "P1",	g_P1, },	{ "P2",	g_P2, },	{ "PE",	g_ignore, },	{ "PF",	g_ignore, },	{ "PP",	g_PP, },	{ "PS",	g_startgif, },	{ "PY",	g_PY, },	{ "QE",	g_QE, },	{ "QP",	g_QS, },	{ "QS",	g_QS, },	{ "R",		g_R, },	{ "RE",	g_RE, },	{ "RP",	g_ignore, },	{ "RS",	g_RS, },	{ "SG",	g_ignore, },	{ "SH",	g_SH, },	{ "SM",	g_ignore, },	{ "TA",	g_ignore, },	{ "TE",	g_ignore, },	{ "TH",	g_TL, },	{ "TL",	g_TL, },	{ "TM",	g_ignore, },	{ "TR",	g_ignore, },	{ "TS",	g_startgif, },	{ "UL",	g_I, },	{ "UX",	g_ignore, },	{ "WH",	g_ignore, },	{ "RT", 	g_RT, },	{ "br",	g_br, },	{ "ti",		g_br, },	{ "nf",	g_P1, },	{ "fi",		g_P2, },	{ "ft",		g_ft, },	{ "sp", 	g_sp, },	{ "rm", 	g_rm, },	{ "de", 	g_de, },	{ "am", 	g_de, },	{ "lf", 	g_lf, },	{ "so", 	g_so, },	{ "ps", 	g_ignore },	{ "vs", 	g_ignore },	{ "nr", 	g_nr },	{ "in", 	g_in },	{ "ne", 	g_ignore },	{ "ig", 	g_ig },	{ "BS", 	g_BS },	{ "BE", 	g_BE },	{ "LB", 	g_LB },	{ nil, nil },};typedef struct Entity Entity;struct Entity{	char *name;	int value;};Entity 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'ÿ', },	{ "&#161;",	L'¡', },	{ "&#162;",	L'¢', },	{ "&#163;",	L'£', },	{ "&#164;",	L'¤', },	{ "&#165;",	L'¥', },	{ "&#166;",	L'¦', },	{ "&#167;",	L'§', },	{ "&#168;",	L'¨', },	{ "&#169;",	L'©', },	{ "&#170;",	L'ª', },	{ "&#171;",	L'«', },	{ "&#172;",	L'¬', },	{ "&#173;",	L'­', },	{ "&#174;",	L'®', },	{ "&#175;",	L'¯', },	{ "&#176;",	L'°', },	{ "&#177;",	L'±', },	{ "&#178;",	L'²', },	{ "&#179;",	L'³', },	{ "&#180;",	L'´', },	{ "&#181;",	L'µ', },	{ "&#182;",	L'¶', },	{ "&#183;",	L'·', },	{ "&#184;",	L'¸', },	{ "&#185;",	L'¹', },	{ "&#186;",	L'º', },	{ "&#187;",	L'»', },	{ "&#188;",	L'¼', },	{ "&#189;",	L'½', },	{ "&#190;",	L'¾', },	{ "&#191;",	L'¿', },	{ "*",			L'•', },	{ "&#164;",	L'□', },	{ "&#186;",	L'◊', },	{ "(tm)",		L'™', },	{"&#913;",		L'Α',},	{"&#914;",		L'Β',},	{"&#915;",		L'Γ',},	{"&#916;",		L'Δ',},	{"&#917;",		L'Ε',},	{"&#918;",		L'Ζ',},	{"&#919;",		L'Η',},	{"&#920;",		L'Θ',},	{"&#921;",		L'Ι',},	{"&#922;",		L'Κ',},	{"&#923;",		L'Λ',},	{"&#924;",		L'Μ',},	{"&#925;",		L'Ν',},	{"&#926;",		L'Ξ',},	{"&#927;",		L'Ο',},	{"&#928;",		L'Π',},	{"&#929;",		L'Ρ',},	{"&#930;",		L'΢',},	{"&#931;",		L'Σ',},	{"&#932;",		L'Τ',},	{"&#933;",		L'Υ',},	{"&#934;",		L'Φ',},	{"&#935;",		L'Χ',},	{"&#936;",		L'Ψ',},	{"&#937;",		L'Ω',},	{"&#945;",		L'α',},	{"&#946;",		L'β',},	{"&#947;",		L'γ',},	{"&#948;",		L'δ',},	{"&#949;",		L'ε',},	{"&#950;",		L'ζ',},	{"&#951;",		L'η',},	{"&#952;",		L'θ',},	{"&#953;",		L'ι',},	{"&#954;",		L'κ',},	{"&#955;",		L'λ',},	{"&#956;",		L'μ',},	{"&#957;",		L'ν',},	{"&#958;",		L'ξ',},	{"&#959;",		L'ο',},	{"&#960;",		L'π',},	{"&#961;",		L'ρ',},	{"&#962;",		L'ς',},	{"&#963;",		L'σ',},	{"&#964;",		L'τ',},	{"&#965;",		L'υ',},	{"&#966;",		L'φ',},	{"&#967;",		L'χ',},	{"&#968;",		L'ψ',},	{"&#969;",		L'ω',},	{ "<-",		L'←', },	{ "^",			L'↑', },	{ "->",		L'→', },	{ "v",			L'↓', },	{ "!=",		L'≠', },	{ "<=",		L'≤', },	{ "...",		L'⋯', },	{"&isin;",		L'∈', },	{"&#8211;",	L'–', },	{"&#8212;",	L'—', },	{ "CYRILLIC XYZZY",	L'й', },	{ "CYRILLIC XYZZY",	L'ъ', },	{ "CYRILLIC Y",		L'ь', },	{ "CYRILLIC YA",	L'я', },	{ "CYRILLIC YA",	L'ё', },	{ "&#191;",		L'ℱ', },	{ nil, 0 },};typedef struct Troffspec Troffspec;struct Troffspec{	char *name;	char *value;};Troffspec tspec[] ={	{ "A*", "&Aring;", },	{ "o\"", "&ouml;", },	{ "ff", "ff", },	{ "fi", "fi", },	{ "fl", "fl", },	{ "Fi", "ffi", },	{ "ru", "_", },	{ "em", "&#173;", },	{ "14", "&#188;", },	{ "12", "&#189;", },	{ "co", "&#169;", },	{ "de", "&#176;", },	{ "dg", "&#161;", },	{ "fm", "&#180;", },	{ "rg", "&#174;", },	{ "bu", "*", },	{ "sq", "&#164;", },	{ "hy", "-", },	{ "pl", "+", },	{ "mi", "-", },	{ "mu", "&#215;", },	{ "di", "&#247;", },	{ "eq", "=", },	{ "==", "==", },	{ ">=", ">=", },	{ "<=", "<=", },	{ "!=", "!=", },	{ "+-", "&#177;", },	{ "no", "&#172;", },	{ "sl", "/", },	{ "ap", "&", },	{ "~=", "~=", },	{ "pt", "oc", },	{ "gr", "GRAD", },	{ "->", "->", },	{ "<-", "<-", },	{ "ua", "^", },	{ "da", "v", },	{ "is", "Integral", },	{ "pd", "DIV", },	{ "if", "oo", },	{ "sr", "-/", },	{ "sb", "(~", },	{ "sp", "~)", },	{ "cu", "U", },	{ "ca", "(^)", },	{ "ib", "(=", },	{ "ip", "=)", },	{ "mo", "C", },	{ "es", "&Oslash;", },	{ "aa", "&#180;", },	{ "ga", "`", },	{ "ci", "O", },	{ "L1", "DEATHSTAR", },	{ "sc", "&#167;", },	{ "dd", "++", },	{ "lh", "<=", },	{ "rh", "=>", },	{ "lt", "(", },	{ "rt", ")", },	{ "lc", "|", },	{ "rc", "|", },	{ "lb", "(", },	{ "rb", ")", },	{ "lf", "|", },	{ "rf", "|", },	{ "lk", "|", },	{ "rk", "|", },	{ "bv", "|", },	{ "ts", "s", },	{ "br", "|", },	{ "or", "|", },	{ "ul", "_", },	{ "rn", " ", },	{ "**", "*", },	{ "tm", "&#153", },	{ nil, nil, },};typedef struct Font Font;struct Font{	char	*start;	char	*end;};Font bfont = { "<B>", "</B>" };Font ifont = { "<I>", "</I>" };Font bifont = { "<B><I>", "</I></B>" };Font cwfont = { "<TT>", "</TT>" };Font *fstack[Maxfsp];int fsp = -1;typedef struct String String;struct String{	String *next;	char *name;	char *val;};String *numregs, *strings;char *strstack[Maxmstack];char *mustfree[Maxmstack];int strsp = -1;int elsetop = -1;typedef struct Mstack Mstack;struct Mstack{	char *ptr;	char *argv[Narg+1];};String *macros;Mstack mstack[Maxmstack];int msp = -1;typedef struct Srcstack Srcstack;struct Srcstack{	char	filename[256];	int	fd;	int	lno;	int	rlno;	Biobuf	in;};Srcstack sstack[Maxsstack];Srcstack *ssp = &sstack[-1];char token[128];void	closel(void);void	closefont(void);void*emalloc(uint n){	void *p;	p = mallocz(n, 1);	if(p == nil){		fprint(2, "ms2html: malloc failed: %r\n");		exits("malloc");	}	return p;}/* define a string variable */voiddsnr(char *name, char *val, String **l){	String *s;	for(s = *l; s != nil; s = *l){		if(strcmp(s->name, name) == 0)			break;		l = &s->next;	}	if(s == nil){		s = emalloc(sizeof(String));		*l = s;		s->name = strdup(name);	} else		free(s->val);	s->val = strdup(val);}voidds(char *name, char *val){	dsnr(name, val, &strings);}/* look up a defined string */char*getds(char *name){	String *s;	for(s = strings; s != nil; s = s->next)		if(strcmp(name, s->name) == 0)			break;	if(s != nil)		return s->val;	return "";}char *getnr(char *name){	String *s;	for(s = numregs; s != nil; s = s->next)		if(strcmp(name, s->name) == 0)			break;	if(s != nil)		return s->val;	return "0";}voidpushstr(char *p){	if(p == nil)		return;	if(strsp >= Maxmstack - 1)		return;	strstack[++strsp] = p;}/* lookup a defined macro */char*getmacro(char *name){	String *s;	for(s = macros; s != nil; s = s->next)		if(strcmp(name, s->name) == 0)			return s->val;	return nil;}enum{	Dstring,	Macro,	Input,};int lastsrc;voidpushsrc(char *name){	Dir *d;	int fd;	if(ssp == &sstack[Maxsstack-1]){		fprint(2, "ms2html: .so's too deep\n");		return;	}	d = nil;	if(name == nil){		d = dirfstat(0);		if(d == nil){			fprint(2, "ms2html: can't stat %s: %r\n", name);			return;		}		name = d->name;		fd = 0;	} else {		fd = open(name, OREAD);		if(fd < 0){			fprint(2, "ms2html: can't open %s: %r\n", name);			return;		}	}	ssp++;	ssp->fd = fd;	Binit(&ssp->in, fd, OREAD);	snprint(ssp->filename, sizeof(ssp->filename), "%s", name);	ssp->lno = ssp->rlno = 1;	free(d);}/* get next logical byte.  from stdin or a defined string */intgetrune(void){	int i;	Rune r;	int c;	Mstack *m;	while(strsp >= 0){		i = chartorune(&r, strstack[strsp]);		if(r != 0){			strstack[strsp] += i;			lastsrc = Dstring;			return r;		}		if (mustfree[strsp]) {			free(mustfree[strsp]);			mustfree[strsp] = nil;		}		strsp--; 	}	while(msp >= 0){		m = &mstack[msp];		i = chartorune(&r, m->ptr);		if(r != 0){			m->ptr += i;			lastsrc = Macro;			return r;		}		for(i = 0; m->argv[i] != nil; i++)			free(m->argv[i]);		msp--; 	}	lastsrc = Input;	do {		if(ssp < sstack)			return -1;		c = Bgetrune(&ssp->in);		if(c >= 0){			r = c;			break;		}		close(ssp->fd);		ssp--;	} while(r < 0);	return r;}voidungetrune(void){	switch(lastsrc){	case Dstring:		if(strsp >= 0)			strstack[strsp]--;		break;	case Macro:		if(msp >= 0)			mstack[msp].ptr--;		break;	case Input:		if(ssp >= sstack)			Bungetrune(&ssp->in);		break;	}}int vert;char*changefont(Font *f){	token[0] = 0;	if(fsp == Maxfsp)		return token;	if(fsp >= 0 && fstack[fsp])		strcpy(token, fstack[fsp]->end);	if(f != nil)		strcat(token, f->start);	fstack[++fsp] = f;	return token;}char*changebackfont(void){	token[0] = 0;	if(fsp >= 0){		if(fstack[fsp])			strcpy(token, fstack[fsp]->end);		fsp--;	}	if(fsp >= 0 && fstack[fsp])		strcat(token, fstack[fsp]->start);	return token;}char*changesize(int amount){	static int curamount;	static char buf[200];	int i;	buf[0] = 0;	if (curamount >= 0)		for (i = 0; i < curamount; i++)			strcat(buf, "</big>");	else		for (i = 0; i < -curamount; i++)			strcat(buf, "</small>");	curamount = 0;	if (amount >= 0)		for (i = 0; i < amount; i++)			strcat(buf, "<big>");	else		for (i = 0; i < -amount; i++)			strcat(buf, "<small>");	curamount = amount;	return buf;}/* get next logical character.  expand it with escapes */char*getnext(void){	int r;	Entity *e;	Troffspec *t;	Rune R;	char str[4];	static char buf[8];	r = getrune();	if(r < 0)		return nil;	if(r > 128 || r == '<' || r == '>'){		for(e = entity; e->name; e++)			if(e->value == r)				return e->name;		sprint(buf, "&#%d;", r);		return buf;	}	if (r == delim[eqnmode]){		if (eqnmode == 0){			eqnmode = 1;			return changefont(&ifont);		}		eqnmode = 0;		return changebackfont();	}	switch(r){	case '\\':		r = getrune();		if(r < 0)			return nil;		switch(r){		case ' ':			return " ";		/* chars to ignore */		case '&':		case '|':		case '%':			return "";		/* small space in troff, nothing in nroff */		case '^':			return getnext();		/* ignore arg */		case 'k':			getrune();			return getnext();		/* comment */		case '"':			while(getrune() != '\n')				;			return "\n";		/* ignore line */		case '!':			while(getrune() != '\n')				;			ungetrune();			return getnext();		/* defined strings */		case '*':			r = getrune();			if(r == '('){				str[0] = getrune();				str[1] = getrune();				str[2] = 0;			} else {				str[0] = r;				str[1] = 0;			}			pushstr(getds(str));			return getnext();		/* macro args */		case '$':			r = getrune();			if(r < '1' || r > '9'){				token[0] = '\\';				token[1] = '$';				token[2] = r;				token[3] = 0;				return token;			}			r -= '0';			if(msp >= 0) 				pushstr(mstack[msp].argv[r]);			return getnext();		/* special chars */		case '(':			token[0] = getrune();			token[1] = getrune();			token[2] = 0;			for(t = tspec; t->name; t++)				if(strcmp(token, t->name) == 0)					return t->value;			return "&#191;";		/* ignore immediately following newline */

⌨️ 快捷键说明

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