xref: /plan9/sys/src/cmd/ms2html.c (revision 6f8e93f6894df6375fc490745e7cb8df51855166)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
36b6b9ac8SDavid du Colombier #include <ctype.h>
47dd7cddfSDavid du Colombier #include <bio.h>
57dd7cddfSDavid du Colombier 
67dd7cddfSDavid du Colombier enum
77dd7cddfSDavid du Colombier {
87dd7cddfSDavid du Colombier 	SSIZE = 10,
97dd7cddfSDavid du Colombier 
107dd7cddfSDavid du Colombier 	Maxnh=	8,		/* highest NH level */
117dd7cddfSDavid du Colombier 	HH=	4,		/* heading level used for SH and NH */
127dd7cddfSDavid du Colombier 	Maxmstack=	10,	/* deepest macro/string nesting */
137dd7cddfSDavid du Colombier 	Narg=	20,		/* max args to a macro */
147dd7cddfSDavid du Colombier 	Maxsstack=	5,	/* deepest nesting of .so's */
157dd7cddfSDavid du Colombier 	Nline=	1024,
167dd7cddfSDavid du Colombier 	Maxget= 10,
177dd7cddfSDavid du Colombier 	Maxif = 20,
18da51d93aSDavid du Colombier 	Maxfsp = 100,
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier 	/* list types */
217dd7cddfSDavid du Colombier 	Lordered = 1,
227dd7cddfSDavid du Colombier 	Lunordered,
237dd7cddfSDavid du Colombier 	Ldef,
247dd7cddfSDavid du Colombier 	Lother,
257dd7cddfSDavid du Colombier };
267dd7cddfSDavid du Colombier 
276b6b9ac8SDavid du Colombier char *delim = "$$";
2873e742d7SDavid du Colombier char *basename;
2973e742d7SDavid du Colombier char *title;
306b6b9ac8SDavid du Colombier int eqnmode;
316b6b9ac8SDavid du Colombier 
327dd7cddfSDavid du Colombier int 	quiet;
337dd7cddfSDavid du Colombier float	indent; /* from .in */
347dd7cddfSDavid du Colombier Biobuf	bout;
357dd7cddfSDavid du Colombier int	isup;
367dd7cddfSDavid du Colombier int	isdown;
377dd7cddfSDavid du Colombier int	debug;
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier int nh[Maxnh];
407dd7cddfSDavid du Colombier int ifwastrue[Maxif];
417dd7cddfSDavid du Colombier 
427dd7cddfSDavid du Colombier int list, listnum, example;
4373e742d7SDavid du Colombier int hangingau, hangingdt, hanginghead, hangingcenter;
447dd7cddfSDavid du Colombier int indirective, paragraph, sol, titleseen, ignore_nl, weBref;
4573e742d7SDavid du Colombier void dohangingcenter(void);
467dd7cddfSDavid du Colombier 
477dd7cddfSDavid du Colombier typedef struct Goobie Goobie;
487dd7cddfSDavid du Colombier typedef struct Goobieif Goobieif;
497dd7cddfSDavid du Colombier struct Goobie
507dd7cddfSDavid du Colombier {
517dd7cddfSDavid du Colombier 	char *name;
527dd7cddfSDavid du Colombier 	void (*f)(int, char**);
537dd7cddfSDavid du Colombier };
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier typedef void F(int, char**);
567dd7cddfSDavid du Colombier typedef void Fif(char*, char*);
577dd7cddfSDavid du Colombier 
587dd7cddfSDavid du Colombier struct Goobieif
597dd7cddfSDavid du Colombier {
607dd7cddfSDavid du Colombier 	char *name;
617dd7cddfSDavid du Colombier 	Fif *f;
627dd7cddfSDavid du Colombier };
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier /* if, ie */
657dd7cddfSDavid du Colombier Fif g_as, g_ds, g_el, g_ie, g_if;
667dd7cddfSDavid du Colombier Goobieif gtabif[] = {
677dd7cddfSDavid du Colombier 	{ "as", g_as },
687dd7cddfSDavid du Colombier 	{ "ds", g_ds },
697dd7cddfSDavid du Colombier 	{ "if", g_if },
707dd7cddfSDavid du Colombier 	{ "ie", g_ie },
717dd7cddfSDavid du Colombier 	{ "el", g_el },
727dd7cddfSDavid du Colombier 	{ nil, nil },
737dd7cddfSDavid du Colombier 	};
747dd7cddfSDavid du Colombier 
757dd7cddfSDavid du Colombier /* pseudo ops */
767dd7cddfSDavid du Colombier F g_notyet, g_ignore, g_hrule, g_startgif;
777dd7cddfSDavid du Colombier 
787dd7cddfSDavid du Colombier /* ms macros */
797dd7cddfSDavid du Colombier F g_AU, g_B, g_BI, g_CW, g_I, g_IP, g_LP, g_PP, g_SH, g_NH;
807dd7cddfSDavid du Colombier F g_P1, g_P2, g_TL, g_R, g_AB, g_AE, g_EQ, g_TS, g_TE, g_FS, g_FE;
817dd7cddfSDavid du Colombier F g_PY, g_IH, g_MH, g_HO, g_BX, g_QS, g_QE, g_RS, g_RE;
827dd7cddfSDavid du Colombier 
837dd7cddfSDavid du Colombier /* pictures macro */
847dd7cddfSDavid du Colombier F g_BP;
857dd7cddfSDavid du Colombier 
867dd7cddfSDavid du Colombier /* real troff */
877dd7cddfSDavid du Colombier F g_br, g_ft, g_sp, g_de, g_lf, g_so, g_rm, g_in;
887dd7cddfSDavid du Colombier F g_nr, g_ig, g_RT, g_BS, g_BE, g_LB, g_ta;
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier /* macros to include ML in output */
917dd7cddfSDavid du Colombier F g__H, g__T;
927dd7cddfSDavid du Colombier 
937dd7cddfSDavid du Colombier Goobie gtab[] =
947dd7cddfSDavid du Colombier {
957dd7cddfSDavid du Colombier 	{ "_T", g__T, },
967dd7cddfSDavid du Colombier 	{ "_H", g__H, },
977dd7cddfSDavid du Colombier 	{ "1C",	g_ignore, },
987dd7cddfSDavid du Colombier 	{ "2C",	g_ignore, },
997dd7cddfSDavid du Colombier 	{ "AB", g_AB, },
1007dd7cddfSDavid du Colombier 	{ "AE", g_AE, },
1017dd7cddfSDavid du Colombier 	{ "AI", g_ignore, },
1027dd7cddfSDavid du Colombier 	{ "AU", g_AU, },
1037dd7cddfSDavid du Colombier 	{ "B",	g_B, },
1047dd7cddfSDavid du Colombier 	{ "B1", g_hrule, },
1057dd7cddfSDavid du Colombier 	{ "B2", g_hrule, },
1067dd7cddfSDavid du Colombier 	{ "BI",	g_BI, },
1077dd7cddfSDavid du Colombier 	{ "BP",	g_BP, },
1087dd7cddfSDavid du Colombier 	{ "BT",	g_ignore, },
1097dd7cddfSDavid du Colombier 	{ "BX",	g_BX, },
1107dd7cddfSDavid du Colombier 	{ "CW",	g_CW, },
1117dd7cddfSDavid du Colombier 	{ "CT",	g_ignore, },
1127dd7cddfSDavid du Colombier 	{ "DA",	g_ignore, },
1137dd7cddfSDavid du Colombier 	{ "DE",	g_P2, },
1147dd7cddfSDavid du Colombier 	{ "DS",	g_P1, },
1157dd7cddfSDavid du Colombier 	{ "EG",	g_ignore, },
1167dd7cddfSDavid du Colombier 	{ "EN",	g_ignore, },
1177dd7cddfSDavid du Colombier 	{ "EQ",	g_startgif, },
1187dd7cddfSDavid du Colombier 	{ "FE",	g_FE, },
1197dd7cddfSDavid du Colombier 	{ "FP",	g_ignore, },
1207dd7cddfSDavid du Colombier 	{ "FS",	g_FS, },
1217dd7cddfSDavid du Colombier 	{ "HO",	g_HO, },
1227dd7cddfSDavid du Colombier 	{ "I",	g_I, },
1237dd7cddfSDavid du Colombier 	{ "IH",	g_IH, },
1247dd7cddfSDavid du Colombier 	{ "IM",	g_ignore, },
1257dd7cddfSDavid du Colombier 	{ "IP",	g_IP, },
1267dd7cddfSDavid du Colombier 	{ "KE",	g_ignore, },
1277dd7cddfSDavid du Colombier 	{ "KF",	g_ignore, },
1287dd7cddfSDavid du Colombier 	{ "KS",	g_ignore, },
1297dd7cddfSDavid du Colombier 	{ "LG",	g_ignore, },
1307dd7cddfSDavid du Colombier 	{ "LP",	g_LP, },
1317dd7cddfSDavid du Colombier 	{ "LT",	g_ignore, },
1327dd7cddfSDavid du Colombier 	{ "MF",	g_ignore, },
1337dd7cddfSDavid du Colombier 	{ "MH",	g_MH, },
1347dd7cddfSDavid du Colombier 	{ "MR",	g_ignore, },
1357dd7cddfSDavid du Colombier 	{ "ND",	g_ignore, },
1367dd7cddfSDavid du Colombier 	{ "NH",	g_NH, },
1377dd7cddfSDavid du Colombier 	{ "NL",	g_ignore, },
1387dd7cddfSDavid du Colombier 	{ "P1",	g_P1, },
1397dd7cddfSDavid du Colombier 	{ "P2",	g_P2, },
1407dd7cddfSDavid du Colombier 	{ "PE",	g_ignore, },
1417dd7cddfSDavid du Colombier 	{ "PF",	g_ignore, },
1427dd7cddfSDavid du Colombier 	{ "PP",	g_PP, },
1437dd7cddfSDavid du Colombier 	{ "PS",	g_startgif, },
1447dd7cddfSDavid du Colombier 	{ "PY",	g_PY, },
1457dd7cddfSDavid du Colombier 	{ "QE",	g_QE, },
1467dd7cddfSDavid du Colombier 	{ "QP",	g_QS, },
1477dd7cddfSDavid du Colombier 	{ "QS",	g_QS, },
1487dd7cddfSDavid du Colombier 	{ "R",		g_R, },
1497dd7cddfSDavid du Colombier 	{ "RE",	g_RE, },
1507dd7cddfSDavid du Colombier 	{ "RP",	g_ignore, },
1517dd7cddfSDavid du Colombier 	{ "RS",	g_RS, },
1527dd7cddfSDavid du Colombier 	{ "SG",	g_ignore, },
1537dd7cddfSDavid du Colombier 	{ "SH",	g_SH, },
1547dd7cddfSDavid du Colombier 	{ "SM",	g_ignore, },
1557dd7cddfSDavid du Colombier 	{ "TA",	g_ignore, },
1567dd7cddfSDavid du Colombier 	{ "TE",	g_ignore, },
1577dd7cddfSDavid du Colombier 	{ "TH",	g_TL, },
1587dd7cddfSDavid du Colombier 	{ "TL",	g_TL, },
1597dd7cddfSDavid du Colombier 	{ "TM",	g_ignore, },
1607dd7cddfSDavid du Colombier 	{ "TR",	g_ignore, },
1617dd7cddfSDavid du Colombier 	{ "TS",	g_startgif, },
1627dd7cddfSDavid du Colombier 	{ "UL",	g_I, },
1637dd7cddfSDavid du Colombier 	{ "UX",	g_ignore, },
1647dd7cddfSDavid du Colombier 	{ "WH",	g_ignore, },
1657dd7cddfSDavid du Colombier 	{ "RT", 	g_RT, },
1667dd7cddfSDavid du Colombier 
1677dd7cddfSDavid du Colombier 	{ "br",	g_br, },
1687dd7cddfSDavid du Colombier 	{ "ti",		g_br, },
1697dd7cddfSDavid du Colombier 	{ "nf",	g_P1, },
1707dd7cddfSDavid du Colombier 	{ "fi",		g_P2, },
1717dd7cddfSDavid du Colombier 	{ "ft",		g_ft, },
1727dd7cddfSDavid du Colombier 	{ "sp", 	g_sp, },
1737dd7cddfSDavid du Colombier 	{ "rm", 	g_rm, },
1747dd7cddfSDavid du Colombier 	{ "de", 	g_de, },
1757dd7cddfSDavid du Colombier 	{ "am", 	g_de, },
1767dd7cddfSDavid du Colombier 	{ "lf", 	g_lf, },
1777dd7cddfSDavid du Colombier 	{ "so", 	g_so, },
1787dd7cddfSDavid du Colombier 	{ "ps", 	g_ignore },
1797dd7cddfSDavid du Colombier 	{ "vs", 	g_ignore },
1807dd7cddfSDavid du Colombier 	{ "nr", 	g_nr },
1817dd7cddfSDavid du Colombier 	{ "in", 	g_in },
1827dd7cddfSDavid du Colombier 	{ "ne", 	g_ignore },
1837dd7cddfSDavid du Colombier 	{ "ig", 	g_ig },
1847dd7cddfSDavid du Colombier 	{ "BS", 	g_BS },
1857dd7cddfSDavid du Colombier 	{ "BE", 	g_BE },
1867dd7cddfSDavid du Colombier 	{ "LB", 	g_LB },
1877dd7cddfSDavid du Colombier 	{ nil, nil },
1887dd7cddfSDavid du Colombier };
1897dd7cddfSDavid du Colombier 
1907dd7cddfSDavid du Colombier typedef struct Entity Entity;
1917dd7cddfSDavid du Colombier struct Entity
1927dd7cddfSDavid du Colombier {
1937dd7cddfSDavid du Colombier 	char *name;
1947dd7cddfSDavid du Colombier 	int value;
1957dd7cddfSDavid du Colombier };
1967dd7cddfSDavid du Colombier 
1977dd7cddfSDavid du Colombier Entity entity[] =
1987dd7cddfSDavid du Colombier {
1997dd7cddfSDavid du Colombier 	{ "&#SPACE;",	L' ', },
2007dd7cddfSDavid du Colombier 	{ "&#RS;",		L'\n', },
2017dd7cddfSDavid du Colombier 	{ "&#RE;",		L'\r', },
2027dd7cddfSDavid du Colombier 	{ "&quot;",		L'"', },
2037dd7cddfSDavid du Colombier 	{ "&AElig;",	L'Æ', },
2047dd7cddfSDavid du Colombier 	{ "&Aacute;",	L'Á', },
2057dd7cddfSDavid du Colombier 	{ "&Acirc;",	L'Â', },
2067dd7cddfSDavid du Colombier 	{ "&Agrave;",	L'À', },
2077dd7cddfSDavid du Colombier 	{ "&Aring;",	L'Å', },
2087dd7cddfSDavid du Colombier 	{ "&Atilde;",	L'Ã', },
2097dd7cddfSDavid du Colombier 	{ "&Auml;",	L'Ä', },
2107dd7cddfSDavid du Colombier 	{ "&Ccedil;",	L'Ç', },
2117dd7cddfSDavid du Colombier 	{ "&ETH;",		L'Ð', },
2127dd7cddfSDavid du Colombier 	{ "&Eacute;",	L'É', },
2137dd7cddfSDavid du Colombier 	{ "&Ecirc;",	L'Ê', },
2147dd7cddfSDavid du Colombier 	{ "&Egrave;",	L'È', },
2157dd7cddfSDavid du Colombier 	{ "&Euml;",	L'Ë', },
2167dd7cddfSDavid du Colombier 	{ "&Iacute;",	L'Í', },
2177dd7cddfSDavid du Colombier 	{ "&Icirc;",		L'Î', },
2187dd7cddfSDavid du Colombier 	{ "&Igrave;",	L'Ì', },
2197dd7cddfSDavid du Colombier 	{ "&Iuml;",		L'Ï', },
2207dd7cddfSDavid du Colombier 	{ "&Ntilde;",	L'Ñ', },
2217dd7cddfSDavid du Colombier 	{ "&Oacute;",	L'Ó', },
2227dd7cddfSDavid du Colombier 	{ "&Ocirc;",	L'Ô', },
2237dd7cddfSDavid du Colombier 	{ "&Ograve;",	L'Ò', },
2247dd7cddfSDavid du Colombier 	{ "&Oslash;",	L'Ø', },
2257dd7cddfSDavid du Colombier 	{ "&Otilde;",	L'Õ', },
2267dd7cddfSDavid du Colombier 	{ "&Ouml;",	L'Ö', },
2277dd7cddfSDavid du Colombier 	{ "&THORN;",	L'Þ', },
2287dd7cddfSDavid du Colombier 	{ "&Uacute;",	L'Ú', },
2297dd7cddfSDavid du Colombier 	{ "&Ucirc;",	L'Û', },
2307dd7cddfSDavid du Colombier 	{ "&Ugrave;",	L'Ù', },
2317dd7cddfSDavid du Colombier 	{ "&Uuml;",	L'Ü', },
2327dd7cddfSDavid du Colombier 	{ "&Yacute;",	L'Ý', },
2337dd7cddfSDavid du Colombier 	{ "&aacute;",	L'á', },
2347dd7cddfSDavid du Colombier 	{ "&acirc;",	L'â', },
2357dd7cddfSDavid du Colombier 	{ "&aelig;",	L'æ', },
2367dd7cddfSDavid du Colombier 	{ "&agrave;",	L'à', },
2377dd7cddfSDavid du Colombier 	{ "&amp;",		L'&', },
2387dd7cddfSDavid du Colombier 	{ "&aring;",	L'å', },
2397dd7cddfSDavid du Colombier 	{ "&atilde;",	L'ã', },
2407dd7cddfSDavid du Colombier 	{ "&auml;",	L'ä', },
2417dd7cddfSDavid du Colombier 	{ "&ccedil;",	L'ç', },
2427dd7cddfSDavid du Colombier 	{ "&eacute;",	L'é', },
2437dd7cddfSDavid du Colombier 	{ "&ecirc;",	L'ê', },
2447dd7cddfSDavid du Colombier 	{ "&egrave;",	L'è', },
2457dd7cddfSDavid du Colombier 	{ "&eth;",		L'ð', },
2467dd7cddfSDavid du Colombier 	{ "&euml;",	L'ë', },
2477dd7cddfSDavid du Colombier 	{ "&gt;",		L'>', },
2487dd7cddfSDavid du Colombier 	{ "&iacute;",	L'í', },
2497dd7cddfSDavid du Colombier 	{ "&icirc;",		L'î', },
2507dd7cddfSDavid du Colombier 	{ "&igrave;",	L'ì', },
2517dd7cddfSDavid du Colombier 	{ "&iuml;",		L'ï', },
2527dd7cddfSDavid du Colombier 	{ "&lt;",		L'<', },
2537dd7cddfSDavid du Colombier 	{ "&ntilde;",	L'ñ', },
2547dd7cddfSDavid du Colombier 	{ "&oacute;",	L'ó', },
2557dd7cddfSDavid du Colombier 	{ "&ocirc;",	L'ô', },
2567dd7cddfSDavid du Colombier 	{ "&ograve;",	L'ò', },
2577dd7cddfSDavid du Colombier 	{ "&oslash;",	L'ø', },
2587dd7cddfSDavid du Colombier 	{ "&otilde;",	L'õ', },
2597dd7cddfSDavid du Colombier 	{ "&ouml;",	L'ö', },
2607dd7cddfSDavid du Colombier 	{ "&szlig;",		L'ß', },
2617dd7cddfSDavid du Colombier 	{ "&thorn;",	L'þ', },
2627dd7cddfSDavid du Colombier 	{ "&uacute;",	L'ú', },
2637dd7cddfSDavid du Colombier 	{ "&ucirc;",	L'û', },
2647dd7cddfSDavid du Colombier 	{ "&ugrave;",	L'ù', },
2657dd7cddfSDavid du Colombier 	{ "&uuml;",	L'ü', },
2667dd7cddfSDavid du Colombier 	{ "&yacute;",	L'ý', },
2677dd7cddfSDavid du Colombier 	{ "&yuml;",	L'ÿ', },
2687dd7cddfSDavid du Colombier 	{ "&#161;",	L'¡', },
2697dd7cddfSDavid du Colombier 	{ "&#162;",	L'¢', },
2707dd7cddfSDavid du Colombier 	{ "&#163;",	L'£', },
2717dd7cddfSDavid du Colombier 	{ "&#164;",	L'¤', },
2727dd7cddfSDavid du Colombier 	{ "&#165;",	L'¥', },
2737dd7cddfSDavid du Colombier 	{ "&#166;",	L'¦', },
2747dd7cddfSDavid du Colombier 	{ "&#167;",	L'§', },
2757dd7cddfSDavid du Colombier 	{ "&#168;",	L'¨', },
2767dd7cddfSDavid du Colombier 	{ "&#169;",	L'©', },
2777dd7cddfSDavid du Colombier 	{ "&#170;",	L'ª', },
2787dd7cddfSDavid du Colombier 	{ "&#171;",	L'«', },
2797dd7cddfSDavid du Colombier 	{ "&#172;",	L'¬', },
2807dd7cddfSDavid du Colombier 	{ "&#173;",	L'­', },
2817dd7cddfSDavid du Colombier 	{ "&#174;",	L'®', },
2827dd7cddfSDavid du Colombier 	{ "&#175;",	L'¯', },
2837dd7cddfSDavid du Colombier 	{ "&#176;",	L'°', },
2847dd7cddfSDavid du Colombier 	{ "&#177;",	L'±', },
2857dd7cddfSDavid du Colombier 	{ "&#178;",	L'²', },
2867dd7cddfSDavid du Colombier 	{ "&#179;",	L'³', },
2877dd7cddfSDavid du Colombier 	{ "&#180;",	L'´', },
2887dd7cddfSDavid du Colombier 	{ "&#181;",	L'µ', },
2897dd7cddfSDavid du Colombier 	{ "&#182;",	L'¶', },
2907dd7cddfSDavid du Colombier 	{ "&#183;",	L'·', },
2917dd7cddfSDavid du Colombier 	{ "&#184;",	L'¸', },
2927dd7cddfSDavid du Colombier 	{ "&#185;",	L'¹', },
2937dd7cddfSDavid du Colombier 	{ "&#186;",	L'º', },
2947dd7cddfSDavid du Colombier 	{ "&#187;",	L'»', },
2957dd7cddfSDavid du Colombier 	{ "&#188;",	L'¼', },
2967dd7cddfSDavid du Colombier 	{ "&#189;",	L'½', },
2977dd7cddfSDavid du Colombier 	{ "&#190;",	L'¾', },
2987dd7cddfSDavid du Colombier 	{ "&#191;",	L'¿', },
2997dd7cddfSDavid du Colombier 
3007dd7cddfSDavid du Colombier 	{ "*",			L'•', },
3017dd7cddfSDavid du Colombier 	{ "&#164;",	L'□', },
3027dd7cddfSDavid du Colombier 	{ "&#186;",	L'◊', },
3037dd7cddfSDavid du Colombier 	{ "(tm)",		L'™', },
3046b6b9ac8SDavid du Colombier 	{"&#913;",		L'Α',},
3056b6b9ac8SDavid du Colombier 	{"&#914;",		L'Β',},
3066b6b9ac8SDavid du Colombier 	{"&#915;",		L'Γ',},
3076b6b9ac8SDavid du Colombier 	{"&#916;",		L'Δ',},
3086b6b9ac8SDavid du Colombier 	{"&#917;",		L'Ε',},
3096b6b9ac8SDavid du Colombier 	{"&#918;",		L'Ζ',},
3106b6b9ac8SDavid du Colombier 	{"&#919;",		L'Η',},
3116b6b9ac8SDavid du Colombier 	{"&#920;",		L'Θ',},
3126b6b9ac8SDavid du Colombier 	{"&#921;",		L'Ι',},
3136b6b9ac8SDavid du Colombier 	{"&#922;",		L'Κ',},
3146b6b9ac8SDavid du Colombier 	{"&#923;",		L'Λ',},
3156b6b9ac8SDavid du Colombier 	{"&#924;",		L'Μ',},
3166b6b9ac8SDavid du Colombier 	{"&#925;",		L'Ν',},
3176b6b9ac8SDavid du Colombier 	{"&#926;",		L'Ξ',},
3186b6b9ac8SDavid du Colombier 	{"&#927;",		L'Ο',},
3196b6b9ac8SDavid du Colombier 	{"&#928;",		L'Π',},
3206b6b9ac8SDavid du Colombier 	{"&#929;",		L'Ρ',},
3216b6b9ac8SDavid du Colombier 	{"&#930;",		L'΢',},
3226b6b9ac8SDavid du Colombier 	{"&#931;",		L'Σ',},
3236b6b9ac8SDavid du Colombier 	{"&#932;",		L'Τ',},
3246b6b9ac8SDavid du Colombier 	{"&#933;",		L'Υ',},
3256b6b9ac8SDavid du Colombier 	{"&#934;",		L'Φ',},
3266b6b9ac8SDavid du Colombier 	{"&#935;",		L'Χ',},
3276b6b9ac8SDavid du Colombier 	{"&#936;",		L'Ψ',},
3286b6b9ac8SDavid du Colombier 	{"&#937;",		L'Ω',},
3296b6b9ac8SDavid du Colombier 	{"&#945;",		L'α',},
3306b6b9ac8SDavid du Colombier 	{"&#946;",		L'β',},
3316b6b9ac8SDavid du Colombier 	{"&#947;",		L'γ',},
3326b6b9ac8SDavid du Colombier 	{"&#948;",		L'δ',},
3336b6b9ac8SDavid du Colombier 	{"&#949;",		L'ε',},
3346b6b9ac8SDavid du Colombier 	{"&#950;",		L'ζ',},
3356b6b9ac8SDavid du Colombier 	{"&#951;",		L'η',},
3366b6b9ac8SDavid du Colombier 	{"&#952;",		L'θ',},
3376b6b9ac8SDavid du Colombier 	{"&#953;",		L'ι',},
3386b6b9ac8SDavid du Colombier 	{"&#954;",		L'κ',},
3396b6b9ac8SDavid du Colombier 	{"&#955;",		L'λ',},
3406b6b9ac8SDavid du Colombier 	{"&#956;",		L'μ',},
3416b6b9ac8SDavid du Colombier 	{"&#957;",		L'ν',},
3426b6b9ac8SDavid du Colombier 	{"&#958;",		L'ξ',},
3436b6b9ac8SDavid du Colombier 	{"&#959;",		L'ο',},
3446b6b9ac8SDavid du Colombier 	{"&#960;",		L'π',},
3456b6b9ac8SDavid du Colombier 	{"&#961;",		L'ρ',},
3466b6b9ac8SDavid du Colombier 	{"&#962;",		L'ς',},
3476b6b9ac8SDavid du Colombier 	{"&#963;",		L'σ',},
3486b6b9ac8SDavid du Colombier 	{"&#964;",		L'τ',},
3496b6b9ac8SDavid du Colombier 	{"&#965;",		L'υ',},
3506b6b9ac8SDavid du Colombier 	{"&#966;",		L'φ',},
3516b6b9ac8SDavid du Colombier 	{"&#967;",		L'χ',},
3526b6b9ac8SDavid du Colombier 	{"&#968;",		L'ψ',},
3536b6b9ac8SDavid du Colombier 	{"&#969;",		L'ω',},
3547dd7cddfSDavid du Colombier 
3556b6b9ac8SDavid du Colombier 	{ "<-",		L'←', },
3566b6b9ac8SDavid du Colombier 	{ "^",			L'↑', },
3576b6b9ac8SDavid du Colombier 	{ "->",		L'→', },
3586b6b9ac8SDavid du Colombier 	{ "v",			L'↓', },
3596b6b9ac8SDavid du Colombier 	{ "!=",		L'≠', },
3606b6b9ac8SDavid du Colombier 	{ "<=",		L'≤', },
3616b6b9ac8SDavid du Colombier 	{ "...",		L'⋯', },
3626b6b9ac8SDavid du Colombier 	{"&isin;",		L'∈', },
3636b6b9ac8SDavid du Colombier 
3646b6b9ac8SDavid du Colombier 	{"&#8211;",	L'–', },
3656b6b9ac8SDavid du Colombier 	{"&#8212;",	L'—', },
3667dd7cddfSDavid du Colombier 
3677dd7cddfSDavid du Colombier 	{ "CYRILLIC XYZZY",	L'й', },
3687dd7cddfSDavid du Colombier 	{ "CYRILLIC XYZZY",	L'ъ', },
3697dd7cddfSDavid du Colombier 	{ "CYRILLIC Y",		L'ь', },
3707dd7cddfSDavid du Colombier 	{ "CYRILLIC YA",	L'я', },
3717dd7cddfSDavid du Colombier 	{ "CYRILLIC YA",	L'ё', },
3727dd7cddfSDavid du Colombier 	{ "&#191;",		L'ℱ', },
3737dd7cddfSDavid du Colombier 
3747dd7cddfSDavid du Colombier 	{ nil, 0 },
3757dd7cddfSDavid du Colombier };
3767dd7cddfSDavid du Colombier 
3777dd7cddfSDavid du Colombier typedef struct Troffspec Troffspec;
3787dd7cddfSDavid du Colombier struct Troffspec
3797dd7cddfSDavid du Colombier {
3807dd7cddfSDavid du Colombier 	char *name;
3817dd7cddfSDavid du Colombier 	char *value;
3827dd7cddfSDavid du Colombier };
3837dd7cddfSDavid du Colombier 
3847dd7cddfSDavid du Colombier Troffspec tspec[] =
3857dd7cddfSDavid du Colombier {
3867dd7cddfSDavid du Colombier 	{ "A*", "&Aring;", },
3877dd7cddfSDavid du Colombier 	{ "o\"", "&ouml;", },
3887dd7cddfSDavid du Colombier 	{ "ff", "ff", },
3897dd7cddfSDavid du Colombier 	{ "fi", "fi", },
3907dd7cddfSDavid du Colombier 	{ "fl", "fl", },
3917dd7cddfSDavid du Colombier 	{ "Fi", "ffi", },
3927dd7cddfSDavid du Colombier 	{ "ru", "_", },
3937dd7cddfSDavid du Colombier 	{ "em", "&#173;", },
3947dd7cddfSDavid du Colombier 	{ "14", "&#188;", },
3957dd7cddfSDavid du Colombier 	{ "12", "&#189;", },
3967dd7cddfSDavid du Colombier 	{ "co", "&#169;", },
3977dd7cddfSDavid du Colombier 	{ "de", "&#176;", },
3987dd7cddfSDavid du Colombier 	{ "dg", "&#161;", },
3997dd7cddfSDavid du Colombier 	{ "fm", "&#180;", },
4007dd7cddfSDavid du Colombier 	{ "rg", "&#174;", },
4017dd7cddfSDavid du Colombier 	{ "bu", "*", },
4027dd7cddfSDavid du Colombier 	{ "sq", "&#164;", },
4037dd7cddfSDavid du Colombier 	{ "hy", "-", },
4047dd7cddfSDavid du Colombier 	{ "pl", "+", },
4057dd7cddfSDavid du Colombier 	{ "mi", "-", },
4067dd7cddfSDavid du Colombier 	{ "mu", "&#215;", },
4077dd7cddfSDavid du Colombier 	{ "di", "&#247;", },
4087dd7cddfSDavid du Colombier 	{ "eq", "=", },
4097dd7cddfSDavid du Colombier 	{ "==", "==", },
4107dd7cddfSDavid du Colombier 	{ ">=", ">=", },
4117dd7cddfSDavid du Colombier 	{ "<=", "<=", },
4127dd7cddfSDavid du Colombier 	{ "!=", "!=", },
4137dd7cddfSDavid du Colombier 	{ "+-", "&#177;", },
4147dd7cddfSDavid du Colombier 	{ "no", "&#172;", },
4157dd7cddfSDavid du Colombier 	{ "sl", "/", },
4167dd7cddfSDavid du Colombier 	{ "ap", "&", },
4177dd7cddfSDavid du Colombier 	{ "~=", "~=", },
4187dd7cddfSDavid du Colombier 	{ "pt", "oc", },
4197dd7cddfSDavid du Colombier 	{ "gr", "GRAD", },
4207dd7cddfSDavid du Colombier 	{ "->", "->", },
4217dd7cddfSDavid du Colombier 	{ "<-", "<-", },
4227dd7cddfSDavid du Colombier 	{ "ua", "^", },
4237dd7cddfSDavid du Colombier 	{ "da", "v", },
4247dd7cddfSDavid du Colombier 	{ "is", "Integral", },
4257dd7cddfSDavid du Colombier 	{ "pd", "DIV", },
4267dd7cddfSDavid du Colombier 	{ "if", "oo", },
4277dd7cddfSDavid du Colombier 	{ "sr", "-/", },
4287dd7cddfSDavid du Colombier 	{ "sb", "(~", },
4297dd7cddfSDavid du Colombier 	{ "sp", "~)", },
4307dd7cddfSDavid du Colombier 	{ "cu", "U", },
4317dd7cddfSDavid du Colombier 	{ "ca", "(^)", },
4327dd7cddfSDavid du Colombier 	{ "ib", "(=", },
4337dd7cddfSDavid du Colombier 	{ "ip", "=)", },
4347dd7cddfSDavid du Colombier 	{ "mo", "C", },
4357dd7cddfSDavid du Colombier 	{ "es", "&Oslash;", },
4367dd7cddfSDavid du Colombier 	{ "aa", "&#180;", },
4377dd7cddfSDavid du Colombier 	{ "ga", "`", },
4387dd7cddfSDavid du Colombier 	{ "ci", "O", },
4397dd7cddfSDavid du Colombier 	{ "L1", "DEATHSTAR", },
4407dd7cddfSDavid du Colombier 	{ "sc", "&#167;", },
4417dd7cddfSDavid du Colombier 	{ "dd", "++", },
4427dd7cddfSDavid du Colombier 	{ "lh", "<=", },
4437dd7cddfSDavid du Colombier 	{ "rh", "=>", },
4447dd7cddfSDavid du Colombier 	{ "lt", "(", },
4457dd7cddfSDavid du Colombier 	{ "rt", ")", },
4467dd7cddfSDavid du Colombier 	{ "lc", "|", },
4477dd7cddfSDavid du Colombier 	{ "rc", "|", },
4487dd7cddfSDavid du Colombier 	{ "lb", "(", },
4497dd7cddfSDavid du Colombier 	{ "rb", ")", },
4507dd7cddfSDavid du Colombier 	{ "lf", "|", },
4517dd7cddfSDavid du Colombier 	{ "rf", "|", },
4527dd7cddfSDavid du Colombier 	{ "lk", "|", },
4537dd7cddfSDavid du Colombier 	{ "rk", "|", },
4547dd7cddfSDavid du Colombier 	{ "bv", "|", },
4557dd7cddfSDavid du Colombier 	{ "ts", "s", },
4567dd7cddfSDavid du Colombier 	{ "br", "|", },
4577dd7cddfSDavid du Colombier 	{ "or", "|", },
4587dd7cddfSDavid du Colombier 	{ "ul", "_", },
4597dd7cddfSDavid du Colombier 	{ "rn", " ", },
4607dd7cddfSDavid du Colombier 	{ "**", "*", },
4616b6b9ac8SDavid du Colombier 	{ "tm", "&#153", },
4627dd7cddfSDavid du Colombier 	{ nil, nil, },
4637dd7cddfSDavid du Colombier };
4647dd7cddfSDavid du Colombier 
4657dd7cddfSDavid du Colombier typedef struct Font Font;
4667dd7cddfSDavid du Colombier struct Font
4677dd7cddfSDavid du Colombier {
4687dd7cddfSDavid du Colombier 	char	*start;
4697dd7cddfSDavid du Colombier 	char	*end;
4707dd7cddfSDavid du Colombier };
4717dd7cddfSDavid du Colombier Font bfont = { "<B>", "</B>" };
4727dd7cddfSDavid du Colombier Font ifont = { "<I>", "</I>" };
4737dd7cddfSDavid du Colombier Font bifont = { "<B><I>", "</I></B>" };
4747dd7cddfSDavid du Colombier Font cwfont = { "<TT>", "</TT>" };
475da51d93aSDavid du Colombier Font *fstack[Maxfsp];
476da51d93aSDavid du Colombier int fsp = -1;
4777dd7cddfSDavid du Colombier 
4787dd7cddfSDavid du Colombier typedef struct String String;
4797dd7cddfSDavid du Colombier struct String
4807dd7cddfSDavid du Colombier {
4817dd7cddfSDavid du Colombier 	String *next;
4827dd7cddfSDavid du Colombier 	char *name;
4837dd7cddfSDavid du Colombier 	char *val;
4847dd7cddfSDavid du Colombier };
4857dd7cddfSDavid du Colombier String *numregs, *strings;
4867dd7cddfSDavid du Colombier char *strstack[Maxmstack];
4877dd7cddfSDavid du Colombier char *mustfree[Maxmstack];
4887dd7cddfSDavid du Colombier int strsp = -1;
4897dd7cddfSDavid du Colombier int elsetop = -1;
4907dd7cddfSDavid du Colombier 
4917dd7cddfSDavid du Colombier typedef struct Mstack Mstack;
4927dd7cddfSDavid du Colombier struct Mstack
4937dd7cddfSDavid du Colombier {
4947dd7cddfSDavid du Colombier 	char *ptr;
4957dd7cddfSDavid du Colombier 	char *argv[Narg+1];
4967dd7cddfSDavid du Colombier };
4977dd7cddfSDavid du Colombier String *macros;
4987dd7cddfSDavid du Colombier Mstack mstack[Maxmstack];
4997dd7cddfSDavid du Colombier int msp = -1;
5007dd7cddfSDavid du Colombier 
5017dd7cddfSDavid du Colombier typedef struct Srcstack Srcstack;
5027dd7cddfSDavid du Colombier struct Srcstack
5037dd7cddfSDavid du Colombier {
5047dd7cddfSDavid du Colombier 	char	filename[256];
5057dd7cddfSDavid du Colombier 	int	fd;
5067dd7cddfSDavid du Colombier 	int	lno;
5077dd7cddfSDavid du Colombier 	int	rlno;
5087dd7cddfSDavid du Colombier 	Biobuf	in;
5097dd7cddfSDavid du Colombier };
5107dd7cddfSDavid du Colombier Srcstack sstack[Maxsstack];
5117dd7cddfSDavid du Colombier Srcstack *ssp = &sstack[-1];
5127dd7cddfSDavid du Colombier 
5137dd7cddfSDavid du Colombier char token[128];
5147dd7cddfSDavid du Colombier 
5157dd7cddfSDavid du Colombier void	closel(void);
5167dd7cddfSDavid du Colombier void	closefont(void);
5177dd7cddfSDavid du Colombier 
5187dd7cddfSDavid du Colombier void*
emalloc(uint n)5197dd7cddfSDavid du Colombier emalloc(uint n)
5207dd7cddfSDavid du Colombier {
5217dd7cddfSDavid du Colombier 	void *p;
5227dd7cddfSDavid du Colombier 
5237dd7cddfSDavid du Colombier 	p = mallocz(n, 1);
5247dd7cddfSDavid du Colombier 	if(p == nil){
5257dd7cddfSDavid du Colombier 		fprint(2, "ms2html: malloc failed: %r\n");
5267dd7cddfSDavid du Colombier 		exits("malloc");
5277dd7cddfSDavid du Colombier 	}
5287dd7cddfSDavid du Colombier 	return p;
5297dd7cddfSDavid du Colombier }
5307dd7cddfSDavid du Colombier 
5317dd7cddfSDavid du Colombier 
5327dd7cddfSDavid du Colombier /* define a string variable */
5337dd7cddfSDavid du Colombier void
dsnr(char * name,char * val,String ** l)5347dd7cddfSDavid du Colombier dsnr(char *name, char *val, String **l)
5357dd7cddfSDavid du Colombier {
5367dd7cddfSDavid du Colombier 	String *s;
5377dd7cddfSDavid du Colombier 
5387dd7cddfSDavid du Colombier 	for(s = *l; s != nil; s = *l){
5397dd7cddfSDavid du Colombier 		if(strcmp(s->name, name) == 0)
5407dd7cddfSDavid du Colombier 			break;
5417dd7cddfSDavid du Colombier 		l = &s->next;
5427dd7cddfSDavid du Colombier 	}
5437dd7cddfSDavid du Colombier 	if(s == nil){
5447dd7cddfSDavid du Colombier 		s = emalloc(sizeof(String));
5457dd7cddfSDavid du Colombier 		*l = s;
5467dd7cddfSDavid du Colombier 		s->name = strdup(name);
5477dd7cddfSDavid du Colombier 	} else
5487dd7cddfSDavid du Colombier 		free(s->val);
5497dd7cddfSDavid du Colombier 	s->val = strdup(val);
5507dd7cddfSDavid du Colombier }
5517dd7cddfSDavid du Colombier 
5527dd7cddfSDavid du Colombier void
ds(char * name,char * val)5537dd7cddfSDavid du Colombier ds(char *name, char *val)
5547dd7cddfSDavid du Colombier {
5557dd7cddfSDavid du Colombier 	dsnr(name, val, &strings);
5567dd7cddfSDavid du Colombier }
5577dd7cddfSDavid du Colombier 
5587dd7cddfSDavid du Colombier /* look up a defined string */
5597dd7cddfSDavid du Colombier char*
getds(char * name)5607dd7cddfSDavid du Colombier getds(char *name)
5617dd7cddfSDavid du Colombier {
5627dd7cddfSDavid du Colombier 	String *s;
5637dd7cddfSDavid du Colombier 
5647dd7cddfSDavid du Colombier 	for(s = strings; s != nil; s = s->next)
5657dd7cddfSDavid du Colombier 		if(strcmp(name, s->name) == 0)
5667dd7cddfSDavid du Colombier 			break;
5677dd7cddfSDavid du Colombier 	if(s != nil)
5687dd7cddfSDavid du Colombier 		return s->val;
5697dd7cddfSDavid du Colombier 	return "";
5707dd7cddfSDavid du Colombier }
5717dd7cddfSDavid du Colombier 
5727dd7cddfSDavid du Colombier char *
getnr(char * name)5737dd7cddfSDavid du Colombier getnr(char *name)
5747dd7cddfSDavid du Colombier {
5757dd7cddfSDavid du Colombier 	String *s;
5767dd7cddfSDavid du Colombier 
5777dd7cddfSDavid du Colombier 	for(s = numregs; s != nil; s = s->next)
5787dd7cddfSDavid du Colombier 		if(strcmp(name, s->name) == 0)
5797dd7cddfSDavid du Colombier 			break;
5807dd7cddfSDavid du Colombier 	if(s != nil)
5817dd7cddfSDavid du Colombier 		return s->val;
5827dd7cddfSDavid du Colombier 	return "0";
5837dd7cddfSDavid du Colombier }
5847dd7cddfSDavid du Colombier 
5857dd7cddfSDavid du Colombier void
pushstr(char * p)5867dd7cddfSDavid du Colombier pushstr(char *p)
5877dd7cddfSDavid du Colombier {
5887dd7cddfSDavid du Colombier 	if(p == nil)
5897dd7cddfSDavid du Colombier 		return;
5907dd7cddfSDavid du Colombier 	if(strsp >= Maxmstack - 1)
5917dd7cddfSDavid du Colombier 		return;
5927dd7cddfSDavid du Colombier 	strstack[++strsp] = p;
5937dd7cddfSDavid du Colombier }
5947dd7cddfSDavid du Colombier 
5957dd7cddfSDavid du Colombier 
5967dd7cddfSDavid du Colombier /* lookup a defined macro */
5977dd7cddfSDavid du Colombier char*
getmacro(char * name)5987dd7cddfSDavid du Colombier getmacro(char *name)
5997dd7cddfSDavid du Colombier {
6007dd7cddfSDavid du Colombier 	String *s;
6017dd7cddfSDavid du Colombier 
6027dd7cddfSDavid du Colombier 	for(s = macros; s != nil; s = s->next)
6037dd7cddfSDavid du Colombier 		if(strcmp(name, s->name) == 0)
6047dd7cddfSDavid du Colombier 			return s->val;
6057dd7cddfSDavid du Colombier 	return nil;
6067dd7cddfSDavid du Colombier }
6077dd7cddfSDavid du Colombier 
6087dd7cddfSDavid du Colombier enum
6097dd7cddfSDavid du Colombier {
6107dd7cddfSDavid du Colombier 	Dstring,
6117dd7cddfSDavid du Colombier 	Macro,
6127dd7cddfSDavid du Colombier 	Input,
6137dd7cddfSDavid du Colombier };
6147dd7cddfSDavid du Colombier int lastsrc;
6157dd7cddfSDavid du Colombier 
6167dd7cddfSDavid du Colombier void
pushsrc(char * name)6177dd7cddfSDavid du Colombier pushsrc(char *name)
6187dd7cddfSDavid du Colombier {
6199a747e4fSDavid du Colombier 	Dir *d;
6207dd7cddfSDavid du Colombier 	int fd;
6217dd7cddfSDavid du Colombier 
6227dd7cddfSDavid du Colombier 	if(ssp == &sstack[Maxsstack-1]){
6237dd7cddfSDavid du Colombier 		fprint(2, "ms2html: .so's too deep\n");
6247dd7cddfSDavid du Colombier 		return;
6257dd7cddfSDavid du Colombier 	}
6269a747e4fSDavid du Colombier 	d = nil;
6277dd7cddfSDavid du Colombier 	if(name == nil){
6289a747e4fSDavid du Colombier 		d = dirfstat(0);
6299a747e4fSDavid du Colombier 		if(d == nil){
6309a747e4fSDavid du Colombier 			fprint(2, "ms2html: can't stat %s: %r\n", name);
6319a747e4fSDavid du Colombier 			return;
6329a747e4fSDavid du Colombier 		}
6339a747e4fSDavid du Colombier 		name = d->name;
6347dd7cddfSDavid du Colombier 		fd = 0;
6357dd7cddfSDavid du Colombier 	} else {
6367dd7cddfSDavid du Colombier 		fd = open(name, OREAD);
6377dd7cddfSDavid du Colombier 		if(fd < 0){
6389a747e4fSDavid du Colombier 			fprint(2, "ms2html: can't open %s: %r\n", name);
6397dd7cddfSDavid du Colombier 			return;
6407dd7cddfSDavid du Colombier 		}
6417dd7cddfSDavid du Colombier 	}
6427dd7cddfSDavid du Colombier 	ssp++;
6437dd7cddfSDavid du Colombier 	ssp->fd = fd;
6447dd7cddfSDavid du Colombier 	Binit(&ssp->in, fd, OREAD);
6457dd7cddfSDavid du Colombier 	snprint(ssp->filename, sizeof(ssp->filename), "%s", name);
6467dd7cddfSDavid du Colombier 	ssp->lno = ssp->rlno = 1;
6479a747e4fSDavid du Colombier 	free(d);
6487dd7cddfSDavid du Colombier }
6497dd7cddfSDavid du Colombier 
6507dd7cddfSDavid du Colombier /* get next logical byte.  from stdin or a defined string */
6517dd7cddfSDavid du Colombier int
getrune(void)6527dd7cddfSDavid du Colombier getrune(void)
6537dd7cddfSDavid du Colombier {
6547dd7cddfSDavid du Colombier 	int i;
6557dd7cddfSDavid du Colombier 	Rune r;
6567dd7cddfSDavid du Colombier 	int c;
6577dd7cddfSDavid du Colombier 	Mstack *m;
6587dd7cddfSDavid du Colombier 
6597dd7cddfSDavid du Colombier 	while(strsp >= 0){
6607dd7cddfSDavid du Colombier 		i = chartorune(&r, strstack[strsp]);
6617dd7cddfSDavid du Colombier 		if(r != 0){
6627dd7cddfSDavid du Colombier 			strstack[strsp] += i;
6637dd7cddfSDavid du Colombier 			lastsrc = Dstring;
6647dd7cddfSDavid du Colombier 			return r;
6657dd7cddfSDavid du Colombier 		}
6667dd7cddfSDavid du Colombier 		if (mustfree[strsp]) {
6677dd7cddfSDavid du Colombier 			free(mustfree[strsp]);
6687dd7cddfSDavid du Colombier 			mustfree[strsp] = nil;
6697dd7cddfSDavid du Colombier 		}
6707dd7cddfSDavid du Colombier 		strsp--;
6717dd7cddfSDavid du Colombier  	}
6727dd7cddfSDavid du Colombier 	while(msp >= 0){
6737dd7cddfSDavid du Colombier 		m = &mstack[msp];
6747dd7cddfSDavid du Colombier 		i = chartorune(&r, m->ptr);
6757dd7cddfSDavid du Colombier 		if(r != 0){
6767dd7cddfSDavid du Colombier 			m->ptr += i;
6777dd7cddfSDavid du Colombier 			lastsrc = Macro;
6787dd7cddfSDavid du Colombier 			return r;
6797dd7cddfSDavid du Colombier 		}
6807dd7cddfSDavid du Colombier 		for(i = 0; m->argv[i] != nil; i++)
6817dd7cddfSDavid du Colombier 			free(m->argv[i]);
6827dd7cddfSDavid du Colombier 		msp--;
6837dd7cddfSDavid du Colombier  	}
6847dd7cddfSDavid du Colombier 
6857dd7cddfSDavid du Colombier 	lastsrc = Input;
686c93608ccSDavid du Colombier 	for(;;) {
6877dd7cddfSDavid du Colombier 		if(ssp < sstack)
6887dd7cddfSDavid du Colombier 			return -1;
6897dd7cddfSDavid du Colombier 		c = Bgetrune(&ssp->in);
6907dd7cddfSDavid du Colombier 		if(c >= 0){
6917dd7cddfSDavid du Colombier 			r = c;
6927dd7cddfSDavid du Colombier 			break;
6937dd7cddfSDavid du Colombier 		}
6947dd7cddfSDavid du Colombier 		close(ssp->fd);
6957dd7cddfSDavid du Colombier 		ssp--;
696c93608ccSDavid du Colombier 	}
6977dd7cddfSDavid du Colombier 
6987dd7cddfSDavid du Colombier 	return r;
6997dd7cddfSDavid du Colombier }
7007dd7cddfSDavid du Colombier 
7017dd7cddfSDavid du Colombier void
ungetrune(void)7027dd7cddfSDavid du Colombier ungetrune(void)
7037dd7cddfSDavid du Colombier {
7047dd7cddfSDavid du Colombier 	switch(lastsrc){
7057dd7cddfSDavid du Colombier 	case Dstring:
7067dd7cddfSDavid du Colombier 		if(strsp >= 0)
7077dd7cddfSDavid du Colombier 			strstack[strsp]--;
7087dd7cddfSDavid du Colombier 		break;
7097dd7cddfSDavid du Colombier 	case Macro:
7107dd7cddfSDavid du Colombier 		if(msp >= 0)
7117dd7cddfSDavid du Colombier 			mstack[msp].ptr--;
7127dd7cddfSDavid du Colombier 		break;
7137dd7cddfSDavid du Colombier 	case Input:
7147dd7cddfSDavid du Colombier 		if(ssp >= sstack)
7157dd7cddfSDavid du Colombier 			Bungetrune(&ssp->in);
7167dd7cddfSDavid du Colombier 		break;
7177dd7cddfSDavid du Colombier 	}
7187dd7cddfSDavid du Colombier }
7197dd7cddfSDavid du Colombier 
7207dd7cddfSDavid du Colombier int vert;
7217dd7cddfSDavid du Colombier 
7227dd7cddfSDavid du Colombier char*
changefont(Font * f)7237dd7cddfSDavid du Colombier changefont(Font *f)
7247dd7cddfSDavid du Colombier {
7257dd7cddfSDavid du Colombier 	token[0] = 0;
726da51d93aSDavid du Colombier 	if(fsp == Maxfsp)
727da51d93aSDavid du Colombier 		return token;
728da51d93aSDavid du Colombier 	if(fsp >= 0 && fstack[fsp])
729da51d93aSDavid du Colombier 		strcpy(token, fstack[fsp]->end);
7307dd7cddfSDavid du Colombier 	if(f != nil)
7317dd7cddfSDavid du Colombier 		strcat(token, f->start);
732da51d93aSDavid du Colombier 	fstack[++fsp] = f;
733da51d93aSDavid du Colombier 	return token;
734da51d93aSDavid du Colombier }
735da51d93aSDavid du Colombier 
736da51d93aSDavid du Colombier char*
changebackfont(void)737da51d93aSDavid du Colombier changebackfont(void)
738da51d93aSDavid du Colombier {
739da51d93aSDavid du Colombier 	token[0] = 0;
740da51d93aSDavid du Colombier 	if(fsp >= 0){
741da51d93aSDavid du Colombier 		if(fstack[fsp])
742da51d93aSDavid du Colombier 			strcpy(token, fstack[fsp]->end);
743da51d93aSDavid du Colombier 		fsp--;
744da51d93aSDavid du Colombier 	}
745da51d93aSDavid du Colombier 	if(fsp >= 0 && fstack[fsp])
746da51d93aSDavid du Colombier 		strcat(token, fstack[fsp]->start);
7477dd7cddfSDavid du Colombier 	return token;
7487dd7cddfSDavid du Colombier }
7497dd7cddfSDavid du Colombier 
7506b6b9ac8SDavid du Colombier char*
changesize(int amount)7516b6b9ac8SDavid du Colombier changesize(int amount)
7526b6b9ac8SDavid du Colombier {
7536b6b9ac8SDavid du Colombier 	static int curamount;
7546b6b9ac8SDavid du Colombier 	static char buf[200];
7556b6b9ac8SDavid du Colombier 	int i;
7566b6b9ac8SDavid du Colombier 
7576b6b9ac8SDavid du Colombier 	buf[0] = 0;
7586b6b9ac8SDavid du Colombier 	if (curamount >= 0)
7596b6b9ac8SDavid du Colombier 		for (i = 0; i < curamount; i++)
7606b6b9ac8SDavid du Colombier 			strcat(buf, "</big>");
7616b6b9ac8SDavid du Colombier 	else
7626b6b9ac8SDavid du Colombier 		for (i = 0; i < -curamount; i++)
7636b6b9ac8SDavid du Colombier 			strcat(buf, "</small>");
7646b6b9ac8SDavid du Colombier 	curamount = 0;
7656b6b9ac8SDavid du Colombier 	if (amount >= 0)
7666b6b9ac8SDavid du Colombier 		for (i = 0; i < amount; i++)
7676b6b9ac8SDavid du Colombier 			strcat(buf, "<big>");
7686b6b9ac8SDavid du Colombier 	else
7696b6b9ac8SDavid du Colombier 		for (i = 0; i < -amount; i++)
7706b6b9ac8SDavid du Colombier 			strcat(buf, "<small>");
7716b6b9ac8SDavid du Colombier 	curamount = amount;
7726b6b9ac8SDavid du Colombier 	return buf;
7736b6b9ac8SDavid du Colombier }
7746b6b9ac8SDavid du Colombier 
7759a747e4fSDavid du Colombier /* get next logical character.  expand it with escapes */
7767dd7cddfSDavid du Colombier char*
getnext(void)7777dd7cddfSDavid du Colombier getnext(void)
7787dd7cddfSDavid du Colombier {
7799a747e4fSDavid du Colombier 	int r;
7807dd7cddfSDavid du Colombier 	Entity *e;
7817dd7cddfSDavid du Colombier 	Troffspec *t;
7827dd7cddfSDavid du Colombier 	Rune R;
7837dd7cddfSDavid du Colombier 	char str[4];
7846b6b9ac8SDavid du Colombier 	static char buf[8];
7857dd7cddfSDavid du Colombier 
7867dd7cddfSDavid du Colombier 	r = getrune();
7877dd7cddfSDavid du Colombier 	if(r < 0)
7887dd7cddfSDavid du Colombier 		return nil;
7899a747e4fSDavid du Colombier 	if(r > 128 || r == '<' || r == '>'){
7907dd7cddfSDavid du Colombier 		for(e = entity; e->name; e++)
7917dd7cddfSDavid du Colombier 			if(e->value == r)
7927dd7cddfSDavid du Colombier 				return e->name;
7936b6b9ac8SDavid du Colombier 		sprint(buf, "&#%d;", r);
7946b6b9ac8SDavid du Colombier 		return buf;
7957dd7cddfSDavid du Colombier 	}
7967dd7cddfSDavid du Colombier 
7976b6b9ac8SDavid du Colombier 	if (r == delim[eqnmode]){
7986b6b9ac8SDavid du Colombier 		if (eqnmode == 0){
7996b6b9ac8SDavid du Colombier 			eqnmode = 1;
8006b6b9ac8SDavid du Colombier 			return changefont(&ifont);
8016b6b9ac8SDavid du Colombier 		}
8026b6b9ac8SDavid du Colombier 		eqnmode = 0;
803da51d93aSDavid du Colombier 		return changebackfont();
8046b6b9ac8SDavid du Colombier 	}
8057dd7cddfSDavid du Colombier 	switch(r){
8067dd7cddfSDavid du Colombier 	case '\\':
8077dd7cddfSDavid du Colombier 		r = getrune();
8087dd7cddfSDavid du Colombier 		if(r < 0)
8097dd7cddfSDavid du Colombier 			return nil;
8107dd7cddfSDavid du Colombier 		switch(r){
8117dd7cddfSDavid du Colombier 		case ' ':
8127dd7cddfSDavid du Colombier 			return " ";
8137dd7cddfSDavid du Colombier 
8147dd7cddfSDavid du Colombier 		/* chars to ignore */
8157dd7cddfSDavid du Colombier 		case '&':
8167dd7cddfSDavid du Colombier 		case '|':
8177dd7cddfSDavid du Colombier 		case '%':
8187dd7cddfSDavid du Colombier 			return "";
8197dd7cddfSDavid du Colombier 
8207dd7cddfSDavid du Colombier 		/* small space in troff, nothing in nroff */
8217dd7cddfSDavid du Colombier 		case '^':
8227dd7cddfSDavid du Colombier 			return getnext();
8237dd7cddfSDavid du Colombier 
8247dd7cddfSDavid du Colombier 		/* ignore arg */
8257dd7cddfSDavid du Colombier 		case 'k':
8267dd7cddfSDavid du Colombier 			getrune();
8277dd7cddfSDavid du Colombier 			return getnext();
8287dd7cddfSDavid du Colombier 
8297dd7cddfSDavid du Colombier 		/* comment */
8307dd7cddfSDavid du Colombier 		case '"':
8317dd7cddfSDavid du Colombier 			while(getrune() != '\n')
8327dd7cddfSDavid du Colombier 				;
8337dd7cddfSDavid du Colombier 			return "\n";
8347dd7cddfSDavid du Colombier 		/* ignore line */
8357dd7cddfSDavid du Colombier 		case '!':
8367dd7cddfSDavid du Colombier 			while(getrune() != '\n')
8377dd7cddfSDavid du Colombier 				;
8387dd7cddfSDavid du Colombier 			ungetrune();
8397dd7cddfSDavid du Colombier 			return getnext();
8407dd7cddfSDavid du Colombier 
8417dd7cddfSDavid du Colombier 		/* defined strings */
8427dd7cddfSDavid du Colombier 		case '*':
8437dd7cddfSDavid du Colombier 			r = getrune();
8447dd7cddfSDavid du Colombier 			if(r == '('){
8457dd7cddfSDavid du Colombier 				str[0] = getrune();
8467dd7cddfSDavid du Colombier 				str[1] = getrune();
8477dd7cddfSDavid du Colombier 				str[2] = 0;
8487dd7cddfSDavid du Colombier 			} else {
8497dd7cddfSDavid du Colombier 				str[0] = r;
8507dd7cddfSDavid du Colombier 				str[1] = 0;
8517dd7cddfSDavid du Colombier 			}
8527dd7cddfSDavid du Colombier 			pushstr(getds(str));
8537dd7cddfSDavid du Colombier 			return getnext();
8547dd7cddfSDavid du Colombier 
8557dd7cddfSDavid du Colombier 		/* macro args */
8567dd7cddfSDavid du Colombier 		case '$':
8577dd7cddfSDavid du Colombier 			r = getrune();
8587dd7cddfSDavid du Colombier 			if(r < '1' || r > '9'){
8597dd7cddfSDavid du Colombier 				token[0] = '\\';
8607dd7cddfSDavid du Colombier 				token[1] = '$';
8617dd7cddfSDavid du Colombier 				token[2] = r;
8627dd7cddfSDavid du Colombier 				token[3] = 0;
8637dd7cddfSDavid du Colombier 				return token;
8647dd7cddfSDavid du Colombier 			}
8657dd7cddfSDavid du Colombier 			r -= '0';
8667dd7cddfSDavid du Colombier 			if(msp >= 0)
8677dd7cddfSDavid du Colombier 				pushstr(mstack[msp].argv[r]);
8687dd7cddfSDavid du Colombier 			return getnext();
8697dd7cddfSDavid du Colombier 
8707dd7cddfSDavid du Colombier 		/* special chars */
8717dd7cddfSDavid du Colombier 		case '(':
8727dd7cddfSDavid du Colombier 			token[0] = getrune();
8737dd7cddfSDavid du Colombier 			token[1] = getrune();
8747dd7cddfSDavid du Colombier 			token[2] = 0;
8757dd7cddfSDavid du Colombier 			for(t = tspec; t->name; t++)
8767dd7cddfSDavid du Colombier 				if(strcmp(token, t->name) == 0)
8777dd7cddfSDavid du Colombier 					return t->value;
8787dd7cddfSDavid du Colombier 			return "&#191;";
8797dd7cddfSDavid du Colombier 
8807dd7cddfSDavid du Colombier 		/* ignore immediately following newline */
8817dd7cddfSDavid du Colombier 		case 'c':
8827dd7cddfSDavid du Colombier 			r = getrune();
8837dd7cddfSDavid du Colombier 			if (r == '\n') {
8847dd7cddfSDavid du Colombier 				sol = ignore_nl = 1;
8857dd7cddfSDavid du Colombier 				if (indirective)
8867dd7cddfSDavid du Colombier 					break;
8877dd7cddfSDavid du Colombier 				}
8887dd7cddfSDavid du Colombier 			else
8897dd7cddfSDavid du Colombier 				ungetrune();
8907dd7cddfSDavid du Colombier 			return getnext();
8917dd7cddfSDavid du Colombier 
8927dd7cddfSDavid du Colombier 		/* escape backslash */
8937dd7cddfSDavid du Colombier 		case 'e':
8947dd7cddfSDavid du Colombier 			return "\\";
8957dd7cddfSDavid du Colombier 
8967dd7cddfSDavid du Colombier 		/* font change */
8977dd7cddfSDavid du Colombier 		case 'f':
8987dd7cddfSDavid du Colombier 			r = getrune();
8997dd7cddfSDavid du Colombier 			switch(r){
9007dd7cddfSDavid du Colombier 			case '(':
9017dd7cddfSDavid du Colombier 				str[0] = getrune();
9027dd7cddfSDavid du Colombier 				str[1] = getrune();
9037dd7cddfSDavid du Colombier 				str[2] = 0;
9047dd7cddfSDavid du Colombier 				token[0] = 0;
9057dd7cddfSDavid du Colombier 				if(strcmp("BI", str) == 0)
9067dd7cddfSDavid du Colombier 					return changefont(&bifont);
9077dd7cddfSDavid du Colombier 				else if(strcmp("CW", str) == 0)
9087dd7cddfSDavid du Colombier 					return changefont(&cwfont);
9097dd7cddfSDavid du Colombier 				else
9107dd7cddfSDavid du Colombier 					return changefont(nil);
9117dd7cddfSDavid du Colombier 			case '3':
9127dd7cddfSDavid du Colombier 			case 'B':
9137dd7cddfSDavid du Colombier 				return changefont(&bfont);
9147dd7cddfSDavid du Colombier 			case '2':
9157dd7cddfSDavid du Colombier 			case 'I':
9167dd7cddfSDavid du Colombier 				return changefont(&ifont);
9177dd7cddfSDavid du Colombier 			case '4':
9187dd7cddfSDavid du Colombier 				return changefont(&bifont);
9197dd7cddfSDavid du Colombier 			case '5':
9207dd7cddfSDavid du Colombier 				return changefont(&cwfont);
9217dd7cddfSDavid du Colombier 			case 'P':
922da51d93aSDavid du Colombier 				return changebackfont();
9237dd7cddfSDavid du Colombier 			case 'R':
9247dd7cddfSDavid du Colombier 			default:
9257dd7cddfSDavid du Colombier 				return changefont(nil);
9267dd7cddfSDavid du Colombier 			}
9277dd7cddfSDavid du Colombier 
9287dd7cddfSDavid du Colombier 		/* number register */
9297dd7cddfSDavid du Colombier 		case 'n':
9307dd7cddfSDavid du Colombier 			r = getrune();
9317dd7cddfSDavid du Colombier 			if (r == '(') /*)*/ {
9327dd7cddfSDavid du Colombier 				r = getrune();
9337dd7cddfSDavid du Colombier 				if (r < 0)
9347dd7cddfSDavid du Colombier 					return nil;
9357dd7cddfSDavid du Colombier 				str[0] = r;
9367dd7cddfSDavid du Colombier 				r = getrune();
9377dd7cddfSDavid du Colombier 				if (r < 0)
9387dd7cddfSDavid du Colombier 					return nil;
9397dd7cddfSDavid du Colombier 				str[1] = r;
9407dd7cddfSDavid du Colombier 				str[2] = 0;
9417dd7cddfSDavid du Colombier 				}
9427dd7cddfSDavid du Colombier 			else {
9437dd7cddfSDavid du Colombier 				str[0] = r;
9447dd7cddfSDavid du Colombier 				str[1] = 0;
9457dd7cddfSDavid du Colombier 				}
9467dd7cddfSDavid du Colombier 			pushstr(getnr(str));
9477dd7cddfSDavid du Colombier 			return getnext();
9487dd7cddfSDavid du Colombier 
9497dd7cddfSDavid du Colombier 		/* font size */
9507dd7cddfSDavid du Colombier 		case 's':
9516b6b9ac8SDavid du Colombier 			r = getrune();
9526b6b9ac8SDavid du Colombier 			switch(r){
9536b6b9ac8SDavid du Colombier 			case '0':
9546b6b9ac8SDavid du Colombier 				return changesize(0);
9556b6b9ac8SDavid du Colombier 			case '-':
9566b6b9ac8SDavid du Colombier 				r = getrune();
9576b6b9ac8SDavid du Colombier 				if (!isdigit(r))
9587dd7cddfSDavid du Colombier 					return getnext();
9596b6b9ac8SDavid du Colombier 				return changesize(-(r - '0'));
9606b6b9ac8SDavid du Colombier 			case '+':
9616b6b9ac8SDavid du Colombier 				r = getrune();
9626b6b9ac8SDavid du Colombier 				if (!isdigit(r))
9636b6b9ac8SDavid du Colombier 					return getnext();
9646b6b9ac8SDavid du Colombier 				return changesize(r - '0');
9656b6b9ac8SDavid du Colombier 			}
9666b6b9ac8SDavid du Colombier 			return getnext();
9677dd7cddfSDavid du Colombier 		/* vertical movement */
9687dd7cddfSDavid du Colombier 		case 'v':
9697dd7cddfSDavid du Colombier 			r = getrune();
9707dd7cddfSDavid du Colombier 			if(r != '\''){
9717dd7cddfSDavid du Colombier 				ungetrune();
9727dd7cddfSDavid du Colombier 				return getnext();
9737dd7cddfSDavid du Colombier 			}
9747dd7cddfSDavid du Colombier 			r = getrune();
9757dd7cddfSDavid du Colombier 			if(r != '-')
9767dd7cddfSDavid du Colombier 				vert--;
9777dd7cddfSDavid du Colombier 			else
9787dd7cddfSDavid du Colombier 				vert++;
9797dd7cddfSDavid du Colombier 			while(r != '\'' && r != '\n')
9807dd7cddfSDavid du Colombier 				r = getrune();
9817dd7cddfSDavid du Colombier 			if(r != '\'')
9827dd7cddfSDavid du Colombier 				ungetrune();
9837dd7cddfSDavid du Colombier 
9847dd7cddfSDavid du Colombier 			if(vert > 0)
9857dd7cddfSDavid du Colombier 				return "^";
9867dd7cddfSDavid du Colombier 			return getnext();
9877dd7cddfSDavid du Colombier 
9887dd7cddfSDavid du Colombier 
9897dd7cddfSDavid du Colombier 		/* horizontal line */
9907dd7cddfSDavid du Colombier 		case 'l':
9917dd7cddfSDavid du Colombier 			r = getrune();
9927dd7cddfSDavid du Colombier 			if(r != '\''){
9937dd7cddfSDavid du Colombier 				ungetrune();
9947dd7cddfSDavid du Colombier 				return "<HR>";
9957dd7cddfSDavid du Colombier 			}
9967dd7cddfSDavid du Colombier 			while(getrune() != '\'')
9977dd7cddfSDavid du Colombier 				;
9987dd7cddfSDavid du Colombier 			return "<HR>";
9997dd7cddfSDavid du Colombier 
10007dd7cddfSDavid du Colombier 		/* character height and slant */
10017dd7cddfSDavid du Colombier 		case 'S':
10027dd7cddfSDavid du Colombier 		case 'H':
10037dd7cddfSDavid du Colombier 			r = getrune();
10047dd7cddfSDavid du Colombier 			if(r != '\''){
10057dd7cddfSDavid du Colombier 				ungetrune();
10067dd7cddfSDavid du Colombier 				return "<HR>";
10077dd7cddfSDavid du Colombier 			}
10087dd7cddfSDavid du Colombier 			while(getrune() != '\'')
10097dd7cddfSDavid du Colombier 				;
10107dd7cddfSDavid du Colombier 			return getnext();
10117dd7cddfSDavid du Colombier 
10127dd7cddfSDavid du Colombier 		/* digit-width space */
10137dd7cddfSDavid du Colombier 		case '0':
10147dd7cddfSDavid du Colombier 			return " ";
10157dd7cddfSDavid du Colombier 
10167dd7cddfSDavid du Colombier 		/*for .if, .ie, .el */
10177dd7cddfSDavid du Colombier 		case '{':
10187dd7cddfSDavid du Colombier 			return "\\{"; /*}*/
10197dd7cddfSDavid du Colombier 		case '}':
10207dd7cddfSDavid du Colombier 			return "";
10217dd7cddfSDavid du Colombier 		/* up and down */
10227dd7cddfSDavid du Colombier 		case 'u':
10237dd7cddfSDavid du Colombier 			if (isdown) {
10247dd7cddfSDavid du Colombier 				isdown = 0;
10257dd7cddfSDavid du Colombier 				return "</sub>";
10267dd7cddfSDavid du Colombier 			}
10277dd7cddfSDavid du Colombier 			isup = 1;
10287dd7cddfSDavid du Colombier 			return "<sup>";
10297dd7cddfSDavid du Colombier 		case 'd':
10307dd7cddfSDavid du Colombier 			if (isup) {
10317dd7cddfSDavid du Colombier 				isup = 0;
10327dd7cddfSDavid du Colombier 				return "</sup>";
10337dd7cddfSDavid du Colombier 			}
10347dd7cddfSDavid du Colombier 			isdown = 1;
10357dd7cddfSDavid du Colombier 			return "<sub>";
10367dd7cddfSDavid du Colombier 		}
10377dd7cddfSDavid du Colombier 		break;
10387dd7cddfSDavid du Colombier 	case '&':
10397dd7cddfSDavid du Colombier 		if(msp >= 0 || strsp >= 0)
10407dd7cddfSDavid du Colombier 			return "&";
10417dd7cddfSDavid du Colombier 		return "&amp;";
10427dd7cddfSDavid du Colombier 	case '<':
10437dd7cddfSDavid du Colombier 		if(msp >= 0 || strsp >= 0)
10447dd7cddfSDavid du Colombier 			return "<";
10457dd7cddfSDavid du Colombier 		return "&#60;";
10467dd7cddfSDavid du Colombier 	case '>':
10477dd7cddfSDavid du Colombier 		if(msp >= 0 || strsp >= 0)
10487dd7cddfSDavid du Colombier 			return ">";
10497dd7cddfSDavid du Colombier 		return "&#62;";
10507dd7cddfSDavid du Colombier 	}
10517dd7cddfSDavid du Colombier 	if (r < Runeself) {
10527dd7cddfSDavid du Colombier 		token[0] = r;
10537dd7cddfSDavid du Colombier 		token[1] = 0;
10547dd7cddfSDavid du Colombier 		}
10557dd7cddfSDavid du Colombier 	else {
10567dd7cddfSDavid du Colombier 		R = r;
10577dd7cddfSDavid du Colombier 		token[runetochar(token,&R)] = 0;
10587dd7cddfSDavid du Colombier 	}
10597dd7cddfSDavid du Colombier 	return token;
10607dd7cddfSDavid du Colombier }
10617dd7cddfSDavid du Colombier 
1062da51d93aSDavid du Colombier /* if arg0 is set, read up to (and expand) to the next whitespace, else to the end of line */
10637dd7cddfSDavid du Colombier char*
copyline(char * p,char * e,int arg0)10647dd7cddfSDavid du Colombier copyline(char *p, char *e, int arg0)
10657dd7cddfSDavid du Colombier {
10667dd7cddfSDavid du Colombier 	int c;
10677dd7cddfSDavid du Colombier 	Rune r;
10687dd7cddfSDavid du Colombier 	char *p1;
10697dd7cddfSDavid du Colombier 
10707dd7cddfSDavid du Colombier 	while((c = getrune()) == ' ' || c == '\t')
10717dd7cddfSDavid du Colombier 		;
10727dd7cddfSDavid du Colombier 	for(indirective = 1; p < e; c = getrune()) {
10737dd7cddfSDavid du Colombier 		if (c < 0)
10747dd7cddfSDavid du Colombier 			goto done;
10757dd7cddfSDavid du Colombier 		switch(c) {
10767dd7cddfSDavid du Colombier 		case '\\':
10777dd7cddfSDavid du Colombier 			break;
10787dd7cddfSDavid du Colombier 		case '\n':
10797dd7cddfSDavid du Colombier 			if (arg0)
10807dd7cddfSDavid du Colombier 				ungetrune();
10817dd7cddfSDavid du Colombier 			goto done;
10827dd7cddfSDavid du Colombier 		case ' ':
10837dd7cddfSDavid du Colombier 		case '\t':
10847dd7cddfSDavid du Colombier 			if (arg0)
10857dd7cddfSDavid du Colombier 				goto done;
10867dd7cddfSDavid du Colombier 		default:
10877dd7cddfSDavid du Colombier 			r = c;
10887dd7cddfSDavid du Colombier 			p += runetochar(p,&r);
10897dd7cddfSDavid du Colombier 			continue;
10907dd7cddfSDavid du Colombier 		}
10917dd7cddfSDavid du Colombier 		ungetrune();
10927dd7cddfSDavid du Colombier 		p1 = getnext();
10937dd7cddfSDavid du Colombier 		if (p1 == nil)
10947dd7cddfSDavid du Colombier 			goto done;
10957dd7cddfSDavid du Colombier 		if (*p1 == '\n') {
10967dd7cddfSDavid du Colombier 			if (arg0)
10977dd7cddfSDavid du Colombier 				ungetrune();
10987dd7cddfSDavid du Colombier 			break;
10997dd7cddfSDavid du Colombier 		}
11007dd7cddfSDavid du Colombier 		while((*p = *p1++) && p < e)
11017dd7cddfSDavid du Colombier 			p++;
11027dd7cddfSDavid du Colombier 	}
11037dd7cddfSDavid du Colombier done:
11047dd7cddfSDavid du Colombier 	indirective = 0;
11057dd7cddfSDavid du Colombier 	*p++ = 0;
11067dd7cddfSDavid du Colombier 	return p;
11077dd7cddfSDavid du Colombier }
11087dd7cddfSDavid du Colombier 
11097dd7cddfSDavid du Colombier char*
copyarg(char * p,char * e,int * nullarg)11107dd7cddfSDavid du Colombier copyarg(char *p, char *e, int *nullarg)
11117dd7cddfSDavid du Colombier {
1112da51d93aSDavid du Colombier 	int c, quoted, last;
11137dd7cddfSDavid du Colombier 	Rune r;
11147dd7cddfSDavid du Colombier 
11157dd7cddfSDavid du Colombier 	*nullarg = 0;
11167dd7cddfSDavid du Colombier 	quoted = 0;
11177dd7cddfSDavid du Colombier 	do{
11187dd7cddfSDavid du Colombier 		c = getrune();
11197dd7cddfSDavid du Colombier 	} while(c == ' ' || c == '\t');
11207dd7cddfSDavid du Colombier 
11217dd7cddfSDavid du Colombier 	if(c == '"'){
11227dd7cddfSDavid du Colombier 		quoted = 1;
11237dd7cddfSDavid du Colombier 		*nullarg = 1;
11247dd7cddfSDavid du Colombier 		c = getrune();
11257dd7cddfSDavid du Colombier 	}
11267dd7cddfSDavid du Colombier 
11277dd7cddfSDavid du Colombier 	if(c == '\n')
11287dd7cddfSDavid du Colombier 		goto done;
11297dd7cddfSDavid du Colombier 
1130da51d93aSDavid du Colombier 	last = 0;
11317dd7cddfSDavid du Colombier 	for(; p < e; c = getrune()) {
11327dd7cddfSDavid du Colombier 		if (c < 0)
11337dd7cddfSDavid du Colombier 			break;
11347dd7cddfSDavid du Colombier 		switch(c) {
11357dd7cddfSDavid du Colombier 		case '\n':
11367dd7cddfSDavid du Colombier 			ungetrune();
11377dd7cddfSDavid du Colombier 			goto done;
1138da51d93aSDavid du Colombier 		case '\\':
1139da51d93aSDavid du Colombier 			r = c;
1140da51d93aSDavid du Colombier 			p += runetochar(p,&r);
1141da51d93aSDavid du Colombier 			if(last == '\\')
1142da51d93aSDavid du Colombier 				r = 0;
1143da51d93aSDavid du Colombier 			break;
11447dd7cddfSDavid du Colombier 		case ' ':
11457dd7cddfSDavid du Colombier 		case '\t':
1146da51d93aSDavid du Colombier 			if(!quoted && last != '\\')
11477dd7cddfSDavid du Colombier 				goto done;
11487dd7cddfSDavid du Colombier 			r = c;
11497dd7cddfSDavid du Colombier 			p += runetochar(p,&r);
1150da51d93aSDavid du Colombier 			break;
11517dd7cddfSDavid du Colombier 		case '"':
1152da51d93aSDavid du Colombier 			if(quoted && last != '\\')
11537dd7cddfSDavid du Colombier 				goto done;
11547dd7cddfSDavid du Colombier 			r = c;
11557dd7cddfSDavid du Colombier 			p += runetochar(p,&r);
1156da51d93aSDavid du Colombier 			break;
11577dd7cddfSDavid du Colombier 		default:
11587dd7cddfSDavid du Colombier 			r = c;
11597dd7cddfSDavid du Colombier 			p += runetochar(p,&r);
1160da51d93aSDavid du Colombier 			break;
11617dd7cddfSDavid du Colombier 		}
1162da51d93aSDavid du Colombier 		last = r;
11637dd7cddfSDavid du Colombier 	}
11647dd7cddfSDavid du Colombier done:
11657dd7cddfSDavid du Colombier 	*p++ = 0;
11667dd7cddfSDavid du Colombier 	return p;
11677dd7cddfSDavid du Colombier 
11687dd7cddfSDavid du Colombier }
11697dd7cddfSDavid du Colombier 
11707dd7cddfSDavid du Colombier int
parseargs(char * p,char * e,char ** argv)11717dd7cddfSDavid du Colombier parseargs(char *p, char *e, char **argv)
11727dd7cddfSDavid du Colombier {
11737dd7cddfSDavid du Colombier 	int argc;
11747dd7cddfSDavid du Colombier 	char *np;
11757dd7cddfSDavid du Colombier 	int nullarg;
11767dd7cddfSDavid du Colombier 
11777dd7cddfSDavid du Colombier 	indirective = 1;
11787dd7cddfSDavid du Colombier 	*p++ = 0;
11797dd7cddfSDavid du Colombier 	for(argc = 1; argc < Narg; argc++){
11807dd7cddfSDavid du Colombier 		np = copyarg(p, e, &nullarg);
11817dd7cddfSDavid du Colombier 		if(nullarg==0 && np == p+1)
11827dd7cddfSDavid du Colombier 			break;
11837dd7cddfSDavid du Colombier 		argv[argc] = p;
11847dd7cddfSDavid du Colombier 		p = np;
11857dd7cddfSDavid du Colombier 	}
11867dd7cddfSDavid du Colombier 	argv[argc] = nil;
11877dd7cddfSDavid du Colombier 	indirective = 0;
11887dd7cddfSDavid du Colombier 
11897dd7cddfSDavid du Colombier 
11907dd7cddfSDavid du Colombier 	return argc;
11917dd7cddfSDavid du Colombier }
11927dd7cddfSDavid du Colombier 
11937dd7cddfSDavid du Colombier void
dodirective(void)11947dd7cddfSDavid du Colombier dodirective(void)
11957dd7cddfSDavid du Colombier {
11967dd7cddfSDavid du Colombier 	char *p, *e;
11977dd7cddfSDavid du Colombier 	Goobie *g;
11987dd7cddfSDavid du Colombier 	Goobieif *gif;
11997dd7cddfSDavid du Colombier 	char line[Nline], *line1;
12007dd7cddfSDavid du Colombier 	int i, argc;
12017dd7cddfSDavid du Colombier 	char *argv[Narg];
12027dd7cddfSDavid du Colombier 	Mstack *m;
12037dd7cddfSDavid du Colombier 
12047dd7cddfSDavid du Colombier 	/* read line, translate special bytes */
12057dd7cddfSDavid du Colombier 	e = line + sizeof(line) - UTFmax - 1;
12067dd7cddfSDavid du Colombier 	line1 = copyline(line, e, 1);
12077dd7cddfSDavid du Colombier 	if (!line[0])
12087dd7cddfSDavid du Colombier 		return;
12097dd7cddfSDavid du Colombier 	argv[0] = line;
12107dd7cddfSDavid du Colombier 
12117dd7cddfSDavid du Colombier 	/* first look through user defined macros */
12127dd7cddfSDavid du Colombier 	p = getmacro(argv[0]);
12137dd7cddfSDavid du Colombier 	if(p != nil){
12147dd7cddfSDavid du Colombier 		if(msp == Maxmstack-1){
12157dd7cddfSDavid du Colombier 			fprint(2, "ms2html: macro stack overflow\n");
12167dd7cddfSDavid du Colombier 			return;
12177dd7cddfSDavid du Colombier 		}
12187dd7cddfSDavid du Colombier 		argc = parseargs(line1, e, argv);
12197dd7cddfSDavid du Colombier 		m = &mstack[++msp];
12207dd7cddfSDavid du Colombier 		m->ptr = p;
12217dd7cddfSDavid du Colombier 		memset(m->argv, 0, sizeof(m->argv));
12227dd7cddfSDavid du Colombier 		for(i = 0; i < argc; i++)
12237dd7cddfSDavid du Colombier 			m->argv[i] = strdup(argv[i]);
12247dd7cddfSDavid du Colombier 		return;
12257dd7cddfSDavid du Colombier 	}
12267dd7cddfSDavid du Colombier 
12277dd7cddfSDavid du Colombier 	/* check for .if or .ie */
12287dd7cddfSDavid du Colombier 	for(gif = gtabif; gif->name; gif++)
12297dd7cddfSDavid du Colombier 		if(strcmp(gif->name, argv[0]) == 0){
12307dd7cddfSDavid du Colombier 			(*gif->f)(line1, e);
12317dd7cddfSDavid du Colombier 			return;
12327dd7cddfSDavid du Colombier 		}
12337dd7cddfSDavid du Colombier 
12347dd7cddfSDavid du Colombier 	argc = parseargs(line1, e, argv);
12357dd7cddfSDavid du Colombier 
12367dd7cddfSDavid du Colombier 	/* try standard ms macros */
12377dd7cddfSDavid du Colombier 	for(g = gtab; g->name; g++)
12387dd7cddfSDavid du Colombier 		if(strcmp(g->name, argv[0]) == 0){
12397dd7cddfSDavid du Colombier 			(*g->f)(argc, argv);
12407dd7cddfSDavid du Colombier 			return;
12417dd7cddfSDavid du Colombier 		}
12427dd7cddfSDavid du Colombier 
12437dd7cddfSDavid du Colombier 	if(debug)
12447dd7cddfSDavid du Colombier 		fprint(2, "stdin %d(%s:%d): unknown directive %s\n",
12457dd7cddfSDavid du Colombier 			ssp->lno, ssp->filename, ssp->rlno, line);
12467dd7cddfSDavid du Colombier }
12477dd7cddfSDavid du Colombier 
12487dd7cddfSDavid du Colombier void
printarg(char * a)12497dd7cddfSDavid du Colombier printarg(char *a)
12507dd7cddfSDavid du Colombier {
12517dd7cddfSDavid du Colombier 	char *e, *p;
12527dd7cddfSDavid du Colombier 
12537dd7cddfSDavid du Colombier 	e = a + strlen(a);
12547dd7cddfSDavid du Colombier 	pushstr(a);
12557dd7cddfSDavid du Colombier 	while(strsp >= 0 && strstack[strsp] >= a && strstack[strsp] < e){
12567dd7cddfSDavid du Colombier 		p = getnext();
12577dd7cddfSDavid du Colombier 		if(p == nil)
12587dd7cddfSDavid du Colombier 			return;
12597dd7cddfSDavid du Colombier 		Bprint(&bout, "%s", p);
12607dd7cddfSDavid du Colombier 	}
12617dd7cddfSDavid du Colombier }
12627dd7cddfSDavid du Colombier 
12637dd7cddfSDavid du Colombier void
printargs(int argc,char ** argv)12647dd7cddfSDavid du Colombier printargs(int argc, char **argv)
12657dd7cddfSDavid du Colombier {
12667dd7cddfSDavid du Colombier 	argc--;
12677dd7cddfSDavid du Colombier 	argv++;
12687dd7cddfSDavid du Colombier 	while(--argc > 0){
12697dd7cddfSDavid du Colombier 		printarg(*argv++);
12707dd7cddfSDavid du Colombier 		Bprint(&bout, " ");
12717dd7cddfSDavid du Colombier 	}
12727dd7cddfSDavid du Colombier 	if(argc == 0)
12737dd7cddfSDavid du Colombier 		printarg(*argv);
12747dd7cddfSDavid du Colombier }
12757dd7cddfSDavid du Colombier 
12767dd7cddfSDavid du Colombier void
dohangingdt(void)12777dd7cddfSDavid du Colombier dohangingdt(void)
12787dd7cddfSDavid du Colombier {
12797dd7cddfSDavid du Colombier 	switch(hangingdt){
12807dd7cddfSDavid du Colombier 	case 3:
12817dd7cddfSDavid du Colombier 		hangingdt--;
12827dd7cddfSDavid du Colombier 		break;
12837dd7cddfSDavid du Colombier 	case 2:
12847dd7cddfSDavid du Colombier 		Bprint(&bout, "<dd>");
12857dd7cddfSDavid du Colombier 		hangingdt = 0;
12867dd7cddfSDavid du Colombier 		break;
12877dd7cddfSDavid du Colombier 	}
12887dd7cddfSDavid du Colombier 
12897dd7cddfSDavid du Colombier }
12907dd7cddfSDavid du Colombier 
12917dd7cddfSDavid du Colombier void
dohangingau(void)12927dd7cddfSDavid du Colombier dohangingau(void)
12937dd7cddfSDavid du Colombier {
12947dd7cddfSDavid du Colombier 	if(hangingau == 0)
12957dd7cddfSDavid du Colombier 		return;
12967dd7cddfSDavid du Colombier 	Bprint(&bout, "</I></DL>\n");
12977dd7cddfSDavid du Colombier 	hangingau = 0;
12987dd7cddfSDavid du Colombier }
12997dd7cddfSDavid du Colombier 
13007dd7cddfSDavid du Colombier void
dohanginghead(void)13017dd7cddfSDavid du Colombier dohanginghead(void)
13027dd7cddfSDavid du Colombier {
13037dd7cddfSDavid du Colombier 	if(hanginghead == 0)
13047dd7cddfSDavid du Colombier 		return;
13057dd7cddfSDavid du Colombier 	Bprint(&bout, "</H%d>\n", hanginghead);
13067dd7cddfSDavid du Colombier 	hanginghead = 0;
13077dd7cddfSDavid du Colombier }
13087dd7cddfSDavid du Colombier 
13097dd7cddfSDavid du Colombier /*
13107dd7cddfSDavid du Colombier  *  convert a man page to html and output
13117dd7cddfSDavid du Colombier  */
13127dd7cddfSDavid du Colombier void
doconvert(void)13137dd7cddfSDavid du Colombier doconvert(void)
13147dd7cddfSDavid du Colombier {
13157dd7cddfSDavid du Colombier 	char c, *p;
13167dd7cddfSDavid du Colombier 	Tm *t;
13177dd7cddfSDavid du Colombier 
13187dd7cddfSDavid du Colombier 	pushsrc(nil);
13197dd7cddfSDavid du Colombier 
13207dd7cddfSDavid du Colombier 	sol = 1;
13217dd7cddfSDavid du Colombier 	Bprint(&bout, "<html>\n");
13227dd7cddfSDavid du Colombier 	Bflush(&bout);
13237dd7cddfSDavid du Colombier 	for(;;){
13247dd7cddfSDavid du Colombier 		p = getnext();
13257dd7cddfSDavid du Colombier 		if(p == nil)
13267dd7cddfSDavid du Colombier 			break;
13277dd7cddfSDavid du Colombier 		c = *p;
13287dd7cddfSDavid du Colombier 		if(c == '.' && sol){
13297dd7cddfSDavid du Colombier 			dodirective();
13307dd7cddfSDavid du Colombier 			dohangingdt();
13317dd7cddfSDavid du Colombier 			ssp->lno++;
13327dd7cddfSDavid du Colombier 			ssp->rlno++;
13337dd7cddfSDavid du Colombier 			sol = 1;
13347dd7cddfSDavid du Colombier 		} else if(c == '\n'){
13357dd7cddfSDavid du Colombier 			if (ignore_nl)
13367dd7cddfSDavid du Colombier 				ignore_nl = 0;
13377dd7cddfSDavid du Colombier 			else {
13387dd7cddfSDavid du Colombier 				if(hangingau)
13397dd7cddfSDavid du Colombier 					Bprint(&bout, "<br>\n");
13407dd7cddfSDavid du Colombier 				else
13417dd7cddfSDavid du Colombier 					Bprint(&bout, "%s", p);
13427dd7cddfSDavid du Colombier 				dohangingdt();
13437dd7cddfSDavid du Colombier 				}
13447dd7cddfSDavid du Colombier 			ssp->lno++;
13457dd7cddfSDavid du Colombier 			ssp->rlno++;
13467dd7cddfSDavid du Colombier 			sol = 1;
13477dd7cddfSDavid du Colombier 		} else{
13487dd7cddfSDavid du Colombier 			Bprint(&bout, "%s", p);
13497dd7cddfSDavid du Colombier 			ignore_nl = sol = 0;
13507dd7cddfSDavid du Colombier 		}
13517dd7cddfSDavid du Colombier 	}
13527dd7cddfSDavid du Colombier 	dohanginghead();
13537dd7cddfSDavid du Colombier 	dohangingdt();
13547dd7cddfSDavid du Colombier 	closel();
1355da51d93aSDavid du Colombier 	if(fsp >= 0 && fstack[fsp])
1356da51d93aSDavid du Colombier 		Bprint(&bout, "%s", fstack[fsp]->end);
13577dd7cddfSDavid du Colombier 	Bprint(&bout, "<br>&#32;<br>\n");
13587dd7cddfSDavid du Colombier 	Bprint(&bout, "<A href=http://www.lucent.com/copyright.html>\n");
13597dd7cddfSDavid du Colombier 	t = localtime(time(nil));
1360b09c09c5SDavid du Colombier 	Bprint(&bout, "Copyright</A> &#169; %d Alcatel-Lucent Inc.  All rights reserved.\n",
13617dd7cddfSDavid du Colombier 			t->year+1900);
13627dd7cddfSDavid du Colombier 	Bprint(&bout, "</body></html>\n");
13637dd7cddfSDavid du Colombier }
13647dd7cddfSDavid du Colombier 
13656b6b9ac8SDavid du Colombier static void
usage(void)13666b6b9ac8SDavid du Colombier usage(void)
13676b6b9ac8SDavid du Colombier {
136814cc0f53SDavid du Colombier 	sysfatal("usage: ms2html [-q] [-b basename] [-d '$$'] [-t title]");
13696b6b9ac8SDavid du Colombier }
13706b6b9ac8SDavid du Colombier 
13717dd7cddfSDavid du Colombier void
main(int argc,char ** argv)13727dd7cddfSDavid du Colombier main(int argc, char **argv)
13737dd7cddfSDavid du Colombier {
13747dd7cddfSDavid du Colombier 	quiet = 1;
13756b6b9ac8SDavid du Colombier 	ARGBEGIN {
137673e742d7SDavid du Colombier 	case 't':
137773e742d7SDavid du Colombier 		title = EARGF(usage());
137873e742d7SDavid du Colombier 		break;
137973e742d7SDavid du Colombier 	case 'b':
138073e742d7SDavid du Colombier 		basename = EARGF(usage());
138173e742d7SDavid du Colombier 		break;
13826b6b9ac8SDavid du Colombier 	case 'q':
13837dd7cddfSDavid du Colombier 		quiet = 0;
13846b6b9ac8SDavid du Colombier 		break;
13856b6b9ac8SDavid du Colombier 	case 'd':
13866b6b9ac8SDavid du Colombier 		delim = EARGF(usage());
13876b6b9ac8SDavid du Colombier 		break;
13886b6b9ac8SDavid du Colombier 	case '?':
13896b6b9ac8SDavid du Colombier 	default:
13906b6b9ac8SDavid du Colombier 		usage();
13916b6b9ac8SDavid du Colombier 	} ARGEND;
13927dd7cddfSDavid du Colombier 
13937dd7cddfSDavid du Colombier 	Binit(&bout, 1, OWRITE);
13947dd7cddfSDavid du Colombier 
13957dd7cddfSDavid du Colombier 	ds("R", "&#174;");
13967dd7cddfSDavid du Colombier 
13977dd7cddfSDavid du Colombier 	doconvert();
13987dd7cddfSDavid du Colombier 	exits(nil);
13997dd7cddfSDavid du Colombier }
14007dd7cddfSDavid du Colombier 
14017dd7cddfSDavid du Colombier void
g_notyet(int,char ** argv)14027dd7cddfSDavid du Colombier g_notyet(int, char **argv)
14037dd7cddfSDavid du Colombier {
14047dd7cddfSDavid du Colombier 	fprint(2, "ms2html: .%s not yet supported\n", argv[0]);
14057dd7cddfSDavid du Colombier }
14067dd7cddfSDavid du Colombier 
14077dd7cddfSDavid du Colombier void
g_ignore(int,char ** argv)14087dd7cddfSDavid du Colombier g_ignore(int, char **argv)
14097dd7cddfSDavid du Colombier {
14107dd7cddfSDavid du Colombier 	if(quiet)
14117dd7cddfSDavid du Colombier 		return;
14127dd7cddfSDavid du Colombier 	fprint(2, "ms2html: line %d: ignoring .%s\n", ssp->lno, argv[0]);
14137dd7cddfSDavid du Colombier }
14147dd7cddfSDavid du Colombier 
14157dd7cddfSDavid du Colombier void
g_PP(int,char **)14167dd7cddfSDavid du Colombier g_PP(int, char**)
14177dd7cddfSDavid du Colombier {
14187dd7cddfSDavid du Colombier 	dohanginghead();
14197dd7cddfSDavid du Colombier 	closel();
14207dd7cddfSDavid du Colombier 	closefont();
14217dd7cddfSDavid du Colombier 	Bprint(&bout, "<P>\n");
14227dd7cddfSDavid du Colombier 	paragraph = 1;
14237dd7cddfSDavid du Colombier }
14247dd7cddfSDavid du Colombier 
14257dd7cddfSDavid du Colombier void
g_LP(int,char **)14267dd7cddfSDavid du Colombier g_LP(int, char**)
14277dd7cddfSDavid du Colombier {
14287dd7cddfSDavid du Colombier 	dohanginghead();
14297dd7cddfSDavid du Colombier 	closel();
14307dd7cddfSDavid du Colombier 	closefont();
14317dd7cddfSDavid du Colombier 	Bprint(&bout, "<br>&#32;<br>\n");
14327dd7cddfSDavid du Colombier }
14337dd7cddfSDavid du Colombier 
14347dd7cddfSDavid du Colombier /* close a list */
14357dd7cddfSDavid du Colombier void
closel(void)14367dd7cddfSDavid du Colombier closel(void)
14377dd7cddfSDavid du Colombier {
14387dd7cddfSDavid du Colombier 	g_P2(1, nil);
14397dd7cddfSDavid du Colombier 	dohangingau();
14407dd7cddfSDavid du Colombier 	if(paragraph){
14417dd7cddfSDavid du Colombier 		Bprint(&bout, "</P>\n");
14427dd7cddfSDavid du Colombier 		paragraph = 0;
14437dd7cddfSDavid du Colombier 	}
14447dd7cddfSDavid du Colombier 	switch(list){
14457dd7cddfSDavid du Colombier 	case Lordered:
14467dd7cddfSDavid du Colombier 		Bprint(&bout, "</ol>\n");
14477dd7cddfSDavid du Colombier 		break;
14487dd7cddfSDavid du Colombier 	case Lunordered:
14497dd7cddfSDavid du Colombier 		Bprint(&bout, "</ul>\n");
14507dd7cddfSDavid du Colombier 		break;
14517dd7cddfSDavid du Colombier 	case Lother:
14527dd7cddfSDavid du Colombier 	case Ldef:
14537dd7cddfSDavid du Colombier 		Bprint(&bout, "</dl>\n");
14547dd7cddfSDavid du Colombier 		break;
14557dd7cddfSDavid du Colombier 	}
14567dd7cddfSDavid du Colombier 	list = 0;
14577dd7cddfSDavid du Colombier 
14587dd7cddfSDavid du Colombier }
14597dd7cddfSDavid du Colombier 
14607dd7cddfSDavid du Colombier 
14617dd7cddfSDavid du Colombier void
g_IP(int argc,char ** argv)14627dd7cddfSDavid du Colombier g_IP(int argc, char **argv)
14637dd7cddfSDavid du Colombier {
1464*6f8e93f6SDavid du Colombier 	dohanginghead();
14657dd7cddfSDavid du Colombier 	switch(list){
14667dd7cddfSDavid du Colombier 	default:
14677dd7cddfSDavid du Colombier 		closel();
14687dd7cddfSDavid du Colombier 		if(argc > 1){
14697dd7cddfSDavid du Colombier 			if(strcmp(argv[1], "1") == 0){
14707dd7cddfSDavid du Colombier 				list = Lordered;
14717dd7cddfSDavid du Colombier 				listnum = 1;
14727dd7cddfSDavid du Colombier 				Bprint(&bout, "<OL>\n");
14737dd7cddfSDavid du Colombier 			} else if(strcmp(argv[1], "\\(bu") == 0){
14747dd7cddfSDavid du Colombier 				list = Lunordered;
14757dd7cddfSDavid du Colombier 				Bprint(&bout, "<UL>\n");
14767dd7cddfSDavid du Colombier 			} else {
14777dd7cddfSDavid du Colombier 				list = Lother;
14787dd7cddfSDavid du Colombier 				Bprint(&bout, "<DL COMPACT>\n");
14797dd7cddfSDavid du Colombier 			}
14807dd7cddfSDavid du Colombier 		} else {
14817dd7cddfSDavid du Colombier 			list = Lother;
14827dd7cddfSDavid du Colombier 			Bprint(&bout, "<DL>\n");
14837dd7cddfSDavid du Colombier 		}
14847dd7cddfSDavid du Colombier 		break;
14857dd7cddfSDavid du Colombier 	case Lother:
14867dd7cddfSDavid du Colombier 	case Lordered:
14877dd7cddfSDavid du Colombier 	case Lunordered:
14887dd7cddfSDavid du Colombier 		break;
14897dd7cddfSDavid du Colombier 	}
14907dd7cddfSDavid du Colombier 
14917dd7cddfSDavid du Colombier 	switch(list){
14927dd7cddfSDavid du Colombier 	case Lother:
14937dd7cddfSDavid du Colombier 		Bprint(&bout, "<DT>");
14947dd7cddfSDavid du Colombier 		if(argc > 1)
14957dd7cddfSDavid du Colombier 			printarg(argv[1]);
14967dd7cddfSDavid du Colombier 		else
14977dd7cddfSDavid du Colombier 			Bprint(&bout, "<DT>&#32;");
14987dd7cddfSDavid du Colombier 		Bprint(&bout, "<DD>\n");
14997dd7cddfSDavid du Colombier 		break;
15007dd7cddfSDavid du Colombier 	case Lordered:
15017dd7cddfSDavid du Colombier 	case Lunordered:
15027dd7cddfSDavid du Colombier 		Bprint(&bout, "<LI>\n");
15037dd7cddfSDavid du Colombier 		break;
15047dd7cddfSDavid du Colombier 	}
15057dd7cddfSDavid du Colombier }
15067dd7cddfSDavid du Colombier 
15077dd7cddfSDavid du Colombier /*
15087dd7cddfSDavid du Colombier  *  .5i is one <DL><DT><DD>
15097dd7cddfSDavid du Colombier  */
15107dd7cddfSDavid du Colombier void
g_in(int argc,char ** argv)15117dd7cddfSDavid du Colombier g_in(int argc, char **argv)
15127dd7cddfSDavid du Colombier {
15137dd7cddfSDavid du Colombier 	float	f;
15147dd7cddfSDavid du Colombier 	int	delta, x;
15157dd7cddfSDavid du Colombier 	char	*p;
15167dd7cddfSDavid du Colombier 
15177dd7cddfSDavid du Colombier 	f = indent/0.5;
15187dd7cddfSDavid du Colombier 	delta = f;
15197dd7cddfSDavid du Colombier 	if(argc <= 1){
15207dd7cddfSDavid du Colombier 		indent = 0.0;
15217dd7cddfSDavid du Colombier 	} else {
15227dd7cddfSDavid du Colombier 		f = strtod(argv[1], &p);
15237dd7cddfSDavid du Colombier 		switch(*p){
15247dd7cddfSDavid du Colombier 		case 'i':
15257dd7cddfSDavid du Colombier 			break;
15267dd7cddfSDavid du Colombier 		case 'c':
15277dd7cddfSDavid du Colombier 			f = f / 2.54;
15287dd7cddfSDavid du Colombier 			break;
15297dd7cddfSDavid du Colombier 		case 'P':
15307dd7cddfSDavid du Colombier 			f = f / 6;
15317dd7cddfSDavid du Colombier 			break;
15327dd7cddfSDavid du Colombier 		default:
15337dd7cddfSDavid du Colombier 		case 'u':
15347dd7cddfSDavid du Colombier 		case 'm':
15357dd7cddfSDavid du Colombier 			f = f * (12 / 72);
15367dd7cddfSDavid du Colombier 			break;
15377dd7cddfSDavid du Colombier 		case 'n':
15387dd7cddfSDavid du Colombier 			f = f * (6 / 72);
15397dd7cddfSDavid du Colombier 			break;
15407dd7cddfSDavid du Colombier 		case 'p':
15417dd7cddfSDavid du Colombier 			f = f / 72.0;
15427dd7cddfSDavid du Colombier 			break;
15437dd7cddfSDavid du Colombier 		}
15447dd7cddfSDavid du Colombier 		switch(argv[1][0]){
15457dd7cddfSDavid du Colombier 		case '+':
15467dd7cddfSDavid du Colombier 		case '-':
15477dd7cddfSDavid du Colombier 			indent += f;
15487dd7cddfSDavid du Colombier 			break;
15497dd7cddfSDavid du Colombier 		default:
15507dd7cddfSDavid du Colombier 			indent = f;
15517dd7cddfSDavid du Colombier 			break;
15527dd7cddfSDavid du Colombier 		}
15537dd7cddfSDavid du Colombier 	}
15547dd7cddfSDavid du Colombier 	if(indent < 0.0)
15557dd7cddfSDavid du Colombier 		indent = 0.0;
15567dd7cddfSDavid du Colombier 	f = (indent/0.5);
15577dd7cddfSDavid du Colombier 	x = f;
15587dd7cddfSDavid du Colombier 	delta = x - delta;
15597dd7cddfSDavid du Colombier 	while(delta < 0){
15607dd7cddfSDavid du Colombier 		Bprint(&bout, "</DL>\n");
15617dd7cddfSDavid du Colombier 		delta++;
15627dd7cddfSDavid du Colombier 	}
15637dd7cddfSDavid du Colombier 	while(delta > 0){
15647dd7cddfSDavid du Colombier 		Bprint(&bout, "<DL><DT><DD>\n");
15657dd7cddfSDavid du Colombier 		delta--;
15667dd7cddfSDavid du Colombier 	}
15677dd7cddfSDavid du Colombier }
15687dd7cddfSDavid du Colombier 
15697dd7cddfSDavid du Colombier void
g_HP(int,char **)15707dd7cddfSDavid du Colombier g_HP(int, char**)
15717dd7cddfSDavid du Colombier {
15727dd7cddfSDavid du Colombier 	switch(list){
15737dd7cddfSDavid du Colombier 	default:
15747dd7cddfSDavid du Colombier 		closel();
15757dd7cddfSDavid du Colombier 		list = Ldef;
15767dd7cddfSDavid du Colombier 		hangingdt = 1;
15777dd7cddfSDavid du Colombier 		Bprint(&bout, "<DL><DT>\n");
15787dd7cddfSDavid du Colombier 		break;
15797dd7cddfSDavid du Colombier 	case Ldef:
15807dd7cddfSDavid du Colombier 		if(hangingdt)
15817dd7cddfSDavid du Colombier 			Bprint(&bout, "<DD>");
15827dd7cddfSDavid du Colombier 		Bprint(&bout, "<DT>");
15837dd7cddfSDavid du Colombier 		hangingdt = 1;
15847dd7cddfSDavid du Colombier 		break;
15857dd7cddfSDavid du Colombier 	}
15867dd7cddfSDavid du Colombier }
15877dd7cddfSDavid du Colombier 
15887dd7cddfSDavid du Colombier void
g_SH(int,char **)15897dd7cddfSDavid du Colombier g_SH(int, char**)
15907dd7cddfSDavid du Colombier {
15917dd7cddfSDavid du Colombier 	dohanginghead();
159273e742d7SDavid du Colombier 	dohangingcenter();
15937dd7cddfSDavid du Colombier 	closel();
15947dd7cddfSDavid du Colombier 	closefont();
15957dd7cddfSDavid du Colombier 	Bprint(&bout, "<H%d>", HH);
15967dd7cddfSDavid du Colombier 	hanginghead = HH;
15977dd7cddfSDavid du Colombier }
15987dd7cddfSDavid du Colombier 
15997dd7cddfSDavid du Colombier void
g_NH(int argc,char ** argv)16007dd7cddfSDavid du Colombier g_NH(int argc, char **argv)
16017dd7cddfSDavid du Colombier {
16027dd7cddfSDavid du Colombier 	int i, level;
16037dd7cddfSDavid du Colombier 
16047dd7cddfSDavid du Colombier 	closel();
16057dd7cddfSDavid du Colombier 	closefont();
16067dd7cddfSDavid du Colombier 
1607*6f8e93f6SDavid du Colombier 	dohanginghead();
160873e742d7SDavid du Colombier 	dohangingcenter();
16097dd7cddfSDavid du Colombier 	if(argc == 1)
16107dd7cddfSDavid du Colombier 		level = 0;
16117dd7cddfSDavid du Colombier 	else {
16127dd7cddfSDavid du Colombier 		level = atoi(argv[1])-1;
16137dd7cddfSDavid du Colombier 		if(level < 0 || level >= Maxnh)
16147dd7cddfSDavid du Colombier 			level = Maxnh - 1;
16157dd7cddfSDavid du Colombier 	}
16167dd7cddfSDavid du Colombier 	nh[level]++;
16177dd7cddfSDavid du Colombier 
16187dd7cddfSDavid du Colombier 	Bprint(&bout, "<H%d>", HH);
16197dd7cddfSDavid du Colombier 	hanginghead = HH;
16207dd7cddfSDavid du Colombier 
16217dd7cddfSDavid du Colombier 	Bprint(&bout, "%d", nh[0]);
16227dd7cddfSDavid du Colombier 	for(i = 1; i <= level; i++)
16237dd7cddfSDavid du Colombier 		Bprint(&bout, ".%d", nh[i]);
16247dd7cddfSDavid du Colombier 	Bprint(&bout, " ");
16257dd7cddfSDavid du Colombier 
16267dd7cddfSDavid du Colombier 	for(i = level+1; i < Maxnh; i++)
16277dd7cddfSDavid du Colombier 		nh[i] = 0;
16287dd7cddfSDavid du Colombier }
16297dd7cddfSDavid du Colombier 
16307dd7cddfSDavid du Colombier void
g_TL(int,char **)16317dd7cddfSDavid du Colombier g_TL(int, char**)
16327dd7cddfSDavid du Colombier {
16337dd7cddfSDavid du Colombier 	char *p, *np;
16347dd7cddfSDavid du Colombier 	char name[128];
16357dd7cddfSDavid du Colombier 
16367dd7cddfSDavid du Colombier 	closefont();
16377dd7cddfSDavid du Colombier 
16387dd7cddfSDavid du Colombier 	if(!titleseen){
163973e742d7SDavid du Colombier 		if(!title){
16407dd7cddfSDavid du Colombier 			/* get base part of filename */
16417dd7cddfSDavid du Colombier 			p = strrchr(ssp->filename, '/');
16427dd7cddfSDavid du Colombier 			if(p == nil)
16437dd7cddfSDavid du Colombier 				p = ssp->filename;
16447dd7cddfSDavid du Colombier 			else
16457dd7cddfSDavid du Colombier 				p++;
16467dd7cddfSDavid du Colombier 			strncpy(name, p, sizeof(name));
16477dd7cddfSDavid du Colombier 			name[sizeof(name)-1] = 0;
16487dd7cddfSDavid du Colombier 
16497dd7cddfSDavid du Colombier 			/* dump any extensions */
16507dd7cddfSDavid du Colombier 			np = strchr(name, '.');
16517dd7cddfSDavid du Colombier 			if(np)
16527dd7cddfSDavid du Colombier 				*np = 0;
165373e742d7SDavid du Colombier 			title = p;
165473e742d7SDavid du Colombier 		}
16557dd7cddfSDavid du Colombier 		Bprint(&bout, "<title>\n");
165673e742d7SDavid du Colombier 		Bprint(&bout, "%s\n", title);
16577dd7cddfSDavid du Colombier 		Bprint(&bout, "</title>\n");
16587dd7cddfSDavid du Colombier 		Bprint(&bout, "<body BGCOLOR=\"#FFFFFF\" TEXT=\"#000000\" LINK=\"#0000FF\" VLINK=\"#330088\" ALINK=\"#FF0044\">\n");
16597dd7cddfSDavid du Colombier 		titleseen = 1;
16607dd7cddfSDavid du Colombier 	}
16617dd7cddfSDavid du Colombier 
166273e742d7SDavid du Colombier 	Bprint(&bout, "<center>");
166373e742d7SDavid du Colombier 	hangingcenter = 1;
16647dd7cddfSDavid du Colombier 	Bprint(&bout, "<H%d>", 1);
16657dd7cddfSDavid du Colombier 	hanginghead = 1;
16667dd7cddfSDavid du Colombier }
16677dd7cddfSDavid du Colombier 
16687dd7cddfSDavid du Colombier void
dohangingcenter(void)166973e742d7SDavid du Colombier dohangingcenter(void)
167073e742d7SDavid du Colombier {
167173e742d7SDavid du Colombier 	if(hangingcenter){
167273e742d7SDavid du Colombier 		Bprint(&bout, "</center>");
167373e742d7SDavid du Colombier 		hangingcenter = 1;
167473e742d7SDavid du Colombier 	}
167573e742d7SDavid du Colombier }
167673e742d7SDavid du Colombier 
167773e742d7SDavid du Colombier void
g_AU(int,char **)16787dd7cddfSDavid du Colombier g_AU(int, char**)
16797dd7cddfSDavid du Colombier {
16807dd7cddfSDavid du Colombier 	closel();
16817dd7cddfSDavid du Colombier 	dohanginghead();
16827dd7cddfSDavid du Colombier 	Bprint(&bout, "<DL><DD><I>");
16837dd7cddfSDavid du Colombier 	hangingau = 1;
16847dd7cddfSDavid du Colombier }
16857dd7cddfSDavid du Colombier 
16867dd7cddfSDavid du Colombier void
pushfont(Font * f)1687da51d93aSDavid du Colombier pushfont(Font *f)
16887dd7cddfSDavid du Colombier {
1689da51d93aSDavid du Colombier 	if(fsp == Maxfsp)
1690da51d93aSDavid du Colombier 		return;
1691da51d93aSDavid du Colombier 	if(fsp >= 0 && fstack[fsp])
1692da51d93aSDavid du Colombier 		Bprint(&bout, "%s", fstack[fsp]->end);
16937dd7cddfSDavid du Colombier 	if(f != nil)
16947dd7cddfSDavid du Colombier 		Bprint(&bout, "%s", f->start);
1695da51d93aSDavid du Colombier 	fstack[++fsp] = f;
1696da51d93aSDavid du Colombier }
1697da51d93aSDavid du Colombier 
1698da51d93aSDavid du Colombier void
popfont(void)1699da51d93aSDavid du Colombier popfont(void)
1700da51d93aSDavid du Colombier {
1701da51d93aSDavid du Colombier 	if(fsp >= 0){
1702da51d93aSDavid du Colombier 		if(fstack[fsp])
1703da51d93aSDavid du Colombier 			Bprint(&bout, "%s", fstack[fsp]->end);
1704da51d93aSDavid du Colombier 		fsp--;
1705da51d93aSDavid du Colombier 	}
17067dd7cddfSDavid du Colombier }
17077dd7cddfSDavid du Colombier 
17087dd7cddfSDavid du Colombier /*
17097dd7cddfSDavid du Colombier  *  for 3 args print arg3 \fxarg1\fP arg2
17107dd7cddfSDavid du Colombier  *  for 2 args print arg1 \fxarg2\fP
17117dd7cddfSDavid du Colombier  *  for 1 args print \fxarg1\fP
17127dd7cddfSDavid du Colombier  */
17137dd7cddfSDavid du Colombier void
font(Font * f,int argc,char ** argv)17147dd7cddfSDavid du Colombier font(Font *f, int argc, char **argv)
17157dd7cddfSDavid du Colombier {
17167dd7cddfSDavid du Colombier 	if(argc == 1){
1717da51d93aSDavid du Colombier 		pushfont(nil);
17187dd7cddfSDavid du Colombier 		return;
17197dd7cddfSDavid du Colombier 	}
17207dd7cddfSDavid du Colombier 	if(argc > 3)
17217dd7cddfSDavid du Colombier 		printarg(argv[3]);
1722da51d93aSDavid du Colombier 	pushfont(f);
17237dd7cddfSDavid du Colombier 	printarg(argv[1]);
1724da51d93aSDavid du Colombier 	popfont();
17257dd7cddfSDavid du Colombier 	if(argc > 2)
17267dd7cddfSDavid du Colombier 		printarg(argv[2]);
17277dd7cddfSDavid du Colombier 	Bprint(&bout, "\n");
17287dd7cddfSDavid du Colombier }
17297dd7cddfSDavid du Colombier 
17307dd7cddfSDavid du Colombier void
closefont(void)17317dd7cddfSDavid du Colombier closefont(void)
17327dd7cddfSDavid du Colombier {
1733da51d93aSDavid du Colombier 	if(fsp >= 0 && fstack[fsp])
1734da51d93aSDavid du Colombier 		Bprint(&bout, "%s", fstack[fsp]->end);
1735da51d93aSDavid du Colombier 	fsp = -1;
17367dd7cddfSDavid du Colombier }
17377dd7cddfSDavid du Colombier 
17387dd7cddfSDavid du Colombier void
g_B(int argc,char ** argv)17397dd7cddfSDavid du Colombier g_B(int argc, char **argv)
17407dd7cddfSDavid du Colombier {
17417dd7cddfSDavid du Colombier 	font(&bfont, argc, argv);
17427dd7cddfSDavid du Colombier }
17437dd7cddfSDavid du Colombier 
17447dd7cddfSDavid du Colombier void
g_R(int argc,char ** argv)17457dd7cddfSDavid du Colombier g_R(int argc, char **argv)
17467dd7cddfSDavid du Colombier {
17477dd7cddfSDavid du Colombier 	font(nil, argc, argv);
17487dd7cddfSDavid du Colombier }
17497dd7cddfSDavid du Colombier 
17507dd7cddfSDavid du Colombier void
g_BI(int argc,char ** argv)17517dd7cddfSDavid du Colombier g_BI(int argc, char **argv)
17527dd7cddfSDavid du Colombier {
17537dd7cddfSDavid du Colombier 	font(&bifont, argc, argv);
17547dd7cddfSDavid du Colombier }
17557dd7cddfSDavid du Colombier 
17567dd7cddfSDavid du Colombier void
g_CW(int argc,char ** argv)17577dd7cddfSDavid du Colombier g_CW(int argc, char **argv)
17587dd7cddfSDavid du Colombier {
17597dd7cddfSDavid du Colombier 	font(&cwfont, argc, argv);
17607dd7cddfSDavid du Colombier }
17617dd7cddfSDavid du Colombier 
17627dd7cddfSDavid du Colombier char*
lower(char * p)17637dd7cddfSDavid du Colombier lower(char *p)
17647dd7cddfSDavid du Colombier {
17657dd7cddfSDavid du Colombier 	char *x;
17667dd7cddfSDavid du Colombier 
17677dd7cddfSDavid du Colombier 	for(x = p; *x; x++)
17687dd7cddfSDavid du Colombier 		if(*x >= 'A' && *x <= 'Z')
17697dd7cddfSDavid du Colombier 			*x -= 'A' - 'a';
17707dd7cddfSDavid du Colombier 	return p;
17717dd7cddfSDavid du Colombier }
17727dd7cddfSDavid du Colombier 
17737dd7cddfSDavid du Colombier void
g_I(int argc,char ** argv)17747dd7cddfSDavid du Colombier g_I(int argc, char **argv)
17757dd7cddfSDavid du Colombier {
17767dd7cddfSDavid du Colombier 	int anchor;
17777dd7cddfSDavid du Colombier 	char *p;
17787dd7cddfSDavid du Colombier 
17797dd7cddfSDavid du Colombier 	anchor = 0;
17807dd7cddfSDavid du Colombier 	if(argc > 2){
17817dd7cddfSDavid du Colombier 		p = argv[2];
17827dd7cddfSDavid du Colombier 		if(p[0] == '(')
17837dd7cddfSDavid du Colombier 		if(p[1] >= '0' && p[1] <= '9')
17847dd7cddfSDavid du Colombier 		if(p[2] == ')'){
17857dd7cddfSDavid du Colombier 			anchor = 1;
17867dd7cddfSDavid du Colombier 			Bprint(&bout, "<A href=\"/magic/man2html/%c/%s\">",
17877dd7cddfSDavid du Colombier 				p[1], lower(argv[1]));
17887dd7cddfSDavid du Colombier 		}
17897dd7cddfSDavid du Colombier 	}
17907dd7cddfSDavid du Colombier 	font(&ifont, argc, argv);
17917dd7cddfSDavid du Colombier 	if(anchor)
17927dd7cddfSDavid du Colombier 		Bprint(&bout, "</A>");
17937dd7cddfSDavid du Colombier }
17947dd7cddfSDavid du Colombier 
17957dd7cddfSDavid du Colombier void
g_br(int,char **)17967dd7cddfSDavid du Colombier g_br(int, char**)
17977dd7cddfSDavid du Colombier {
17987dd7cddfSDavid du Colombier 	if(hangingdt){
17997dd7cddfSDavid du Colombier 		Bprint(&bout, "<dd>");
18007dd7cddfSDavid du Colombier 		hangingdt = 0;
18017dd7cddfSDavid du Colombier 	}else
18027dd7cddfSDavid du Colombier 		Bprint(&bout, "<br>\n");
18037dd7cddfSDavid du Colombier }
18047dd7cddfSDavid du Colombier 
18057dd7cddfSDavid du Colombier void
g_P1(int,char **)18067dd7cddfSDavid du Colombier g_P1(int, char**)
18077dd7cddfSDavid du Colombier {
18087dd7cddfSDavid du Colombier 	if(example == 0){
18097dd7cddfSDavid du Colombier 		example = 1;
18107dd7cddfSDavid du Colombier 		Bprint(&bout, "<DL><DT><DD><TT><PRE>\n");
18117dd7cddfSDavid du Colombier 	}
18127dd7cddfSDavid du Colombier }
18137dd7cddfSDavid du Colombier 
18147dd7cddfSDavid du Colombier void
g_P2(int,char **)18157dd7cddfSDavid du Colombier g_P2(int, char**)
18167dd7cddfSDavid du Colombier {
18177dd7cddfSDavid du Colombier 	if(example){
18187dd7cddfSDavid du Colombier 		example = 0;
18197dd7cddfSDavid du Colombier 		Bprint(&bout, "</PRE></TT></DL>\n");
18207dd7cddfSDavid du Colombier 	}
18217dd7cddfSDavid du Colombier }
18227dd7cddfSDavid du Colombier 
18237dd7cddfSDavid du Colombier void
g_SM(int,char ** argv)18247dd7cddfSDavid du Colombier g_SM(int, char **argv)
18257dd7cddfSDavid du Colombier {
18267dd7cddfSDavid du Colombier 	Bprint(&bout, "%s", argv[1]);
18277dd7cddfSDavid du Colombier }
18287dd7cddfSDavid du Colombier 
18297dd7cddfSDavid du Colombier void
g_ft(int argc,char ** argv)18307dd7cddfSDavid du Colombier g_ft(int argc, char **argv)
18317dd7cddfSDavid du Colombier {
18327dd7cddfSDavid du Colombier 	if(argc < 2){
1833da51d93aSDavid du Colombier 		pushfont(nil);
18347dd7cddfSDavid du Colombier 		return;
18357dd7cddfSDavid du Colombier 	}
18367dd7cddfSDavid du Colombier 
18377dd7cddfSDavid du Colombier 	switch(argv[1][0]){
18387dd7cddfSDavid du Colombier 	case '3':
18397dd7cddfSDavid du Colombier 	case 'B':
1840da51d93aSDavid du Colombier 		pushfont(&bfont);
18417dd7cddfSDavid du Colombier 		break;
18427dd7cddfSDavid du Colombier 	case '2':
18437dd7cddfSDavid du Colombier 	case 'I':
1844da51d93aSDavid du Colombier 		pushfont(&ifont);
18457dd7cddfSDavid du Colombier 		break;
18467dd7cddfSDavid du Colombier 	case '4':
1847da51d93aSDavid du Colombier 		pushfont(&bifont);
18487dd7cddfSDavid du Colombier 		break;
18497dd7cddfSDavid du Colombier 	case '5':
1850da51d93aSDavid du Colombier 		pushfont(&cwfont);
18517dd7cddfSDavid du Colombier 		break;
18527dd7cddfSDavid du Colombier 	case 'P':
1853da51d93aSDavid du Colombier 		popfont();
18547dd7cddfSDavid du Colombier 		break;
18557dd7cddfSDavid du Colombier 	case 'R':
18567dd7cddfSDavid du Colombier 	default:
1857da51d93aSDavid du Colombier 		pushfont(nil);
18587dd7cddfSDavid du Colombier 		break;
18597dd7cddfSDavid du Colombier 	}
18607dd7cddfSDavid du Colombier }
18617dd7cddfSDavid du Colombier 
18627dd7cddfSDavid du Colombier void
g_sp(int argc,char ** argv)18637dd7cddfSDavid du Colombier g_sp(int argc, char **argv)
18647dd7cddfSDavid du Colombier {
18657dd7cddfSDavid du Colombier 	int n;
18667dd7cddfSDavid du Colombier 
18677dd7cddfSDavid du Colombier 	n = 1;
18687dd7cddfSDavid du Colombier 	if(argc > 1){
18697dd7cddfSDavid du Colombier 		n = atoi(argv[1]);
18707dd7cddfSDavid du Colombier 		if(n < 1)
18717dd7cddfSDavid du Colombier 			n = 1;
18727dd7cddfSDavid du Colombier 		if(argv[1][strlen(argv[1])-1] == 'i')
18737dd7cddfSDavid du Colombier 			n *= 4;
18747dd7cddfSDavid du Colombier 	}
18757dd7cddfSDavid du Colombier 	if(n > 5){
18767dd7cddfSDavid du Colombier 		Bprint(&bout, "<br>&#32;<br>\n");
18777dd7cddfSDavid du Colombier 		Bprint(&bout, "<HR>\n");
18787dd7cddfSDavid du Colombier 		Bprint(&bout, "<br>&#32;<br>\n");
18797dd7cddfSDavid du Colombier 	} else
18807dd7cddfSDavid du Colombier 		for(; n > 0; n--)
18817dd7cddfSDavid du Colombier 			Bprint(&bout, "<br>&#32;<br>\n");
18827dd7cddfSDavid du Colombier }
18837dd7cddfSDavid du Colombier 
18847dd7cddfSDavid du Colombier  void
rm_loop(char * name,String ** l)18857dd7cddfSDavid du Colombier rm_loop(char *name, String **l)
18867dd7cddfSDavid du Colombier {
18877dd7cddfSDavid du Colombier 	String *s;
18887dd7cddfSDavid du Colombier 	for(s = *l; s != nil; s = *l){
18897dd7cddfSDavid du Colombier 		if(strcmp(name, s->name) == 0){
18907dd7cddfSDavid du Colombier 			*l = s->next;
18917dd7cddfSDavid du Colombier 			free(s->name);
18927dd7cddfSDavid du Colombier 			free(s->val);
18937dd7cddfSDavid du Colombier 			free(s);
18947dd7cddfSDavid du Colombier 			break;
18957dd7cddfSDavid du Colombier 			}
18967dd7cddfSDavid du Colombier 		l = &s->next;
18977dd7cddfSDavid du Colombier 		}
18987dd7cddfSDavid du Colombier 	}
18997dd7cddfSDavid du Colombier 
19007dd7cddfSDavid du Colombier void
g_rm(int argc,char ** argv)19017dd7cddfSDavid du Colombier g_rm(int argc, char **argv)
19027dd7cddfSDavid du Colombier {
19037dd7cddfSDavid du Colombier 	Goobie *g;
19047dd7cddfSDavid du Colombier 	char *name;
19057dd7cddfSDavid du Colombier 	int i;
19067dd7cddfSDavid du Colombier 
19077dd7cddfSDavid du Colombier 	for(i = 1; i < argc; i++) {
19087dd7cddfSDavid du Colombier 		name = argv[i];
19097dd7cddfSDavid du Colombier 		rm_loop(name, &strings);
19107dd7cddfSDavid du Colombier 		rm_loop(name, &macros);
19117dd7cddfSDavid du Colombier 		for(g = gtab; g->name; g++)
19127dd7cddfSDavid du Colombier 			if (strcmp(g->name, name) == 0) {
19137dd7cddfSDavid du Colombier 				g->f = g_ignore;
19147dd7cddfSDavid du Colombier 				break;
19157dd7cddfSDavid du Colombier 				}
19167dd7cddfSDavid du Colombier 		}
19177dd7cddfSDavid du Colombier 	}
19187dd7cddfSDavid du Colombier 
19197dd7cddfSDavid du Colombier void
g_AB(int,char **)19207dd7cddfSDavid du Colombier g_AB(int, char**)
19217dd7cddfSDavid du Colombier {
19227dd7cddfSDavid du Colombier 	closel();
192373e742d7SDavid du Colombier 	dohangingcenter();
192473e742d7SDavid du Colombier 	Bprint(&bout, "<center><H4>ABSTRACT</H4></center><DL><DD>\n");
19257dd7cddfSDavid du Colombier }
19267dd7cddfSDavid du Colombier 
19277dd7cddfSDavid du Colombier void
g_AE(int,char **)19287dd7cddfSDavid du Colombier g_AE(int, char**)
19297dd7cddfSDavid du Colombier {
19307dd7cddfSDavid du Colombier 	Bprint(&bout, "</DL>\n");
19317dd7cddfSDavid du Colombier }
19327dd7cddfSDavid du Colombier 
19337dd7cddfSDavid du Colombier void
g_FS(int,char **)19347dd7cddfSDavid du Colombier g_FS(int, char **)
19357dd7cddfSDavid du Colombier {
19367dd7cddfSDavid du Colombier 	char *argv[3];
19377dd7cddfSDavid du Colombier 
19387dd7cddfSDavid du Colombier 	argv[0] = "IP";
19397dd7cddfSDavid du Colombier 	argv[1] = nil;
19407dd7cddfSDavid du Colombier 	argv[2] = nil;
19417dd7cddfSDavid du Colombier 	g_IP(1, argv);
19427dd7cddfSDavid du Colombier 	Bprint(&bout, "NOTE:<I> ");
19437dd7cddfSDavid du Colombier }
19447dd7cddfSDavid du Colombier 
19457dd7cddfSDavid du Colombier void
g_FE(int,char **)19467dd7cddfSDavid du Colombier g_FE(int, char **)
19477dd7cddfSDavid du Colombier {
19487dd7cddfSDavid du Colombier 	Bprint(&bout, "</I><DT>&#32;<DD>");
19497dd7cddfSDavid du Colombier 	closel();
19507dd7cddfSDavid du Colombier 	Bprint(&bout, "<br>\n");
19517dd7cddfSDavid du Colombier }
19527dd7cddfSDavid du Colombier 
19537dd7cddfSDavid du Colombier void
g_de(int argc,char ** argv)19547dd7cddfSDavid du Colombier g_de(int argc, char **argv)
19557dd7cddfSDavid du Colombier {
19567dd7cddfSDavid du Colombier 	int r;
19577dd7cddfSDavid du Colombier 	char *p, *cp;
19587dd7cddfSDavid du Colombier 	String *m;
19597dd7cddfSDavid du Colombier 	int len;
19607dd7cddfSDavid du Colombier 
19617dd7cddfSDavid du Colombier 	if(argc < 2)
19627dd7cddfSDavid du Colombier 		return;
19637dd7cddfSDavid du Colombier 
19647dd7cddfSDavid du Colombier 	m = nil;
19657dd7cddfSDavid du Colombier 	len = 0;
19667dd7cddfSDavid du Colombier 	if(strcmp(argv[0], "am") == 0){
19677dd7cddfSDavid du Colombier 		for(m = macros; m != nil; m = m->next)
19687dd7cddfSDavid du Colombier 			if(strcmp(argv[1], m->name) == 0){
19697dd7cddfSDavid du Colombier 				len = strlen(m->val);
19707dd7cddfSDavid du Colombier 				break;
19717dd7cddfSDavid du Colombier 			}
19727dd7cddfSDavid du Colombier 
19737dd7cddfSDavid du Colombier 		if(m == nil){
19747dd7cddfSDavid du Colombier 			/* nothing to append to */
19757dd7cddfSDavid du Colombier 			for(;;){
19767dd7cddfSDavid du Colombier 				p = Brdline(&ssp->in, '\n');
19777dd7cddfSDavid du Colombier 				if(p == nil)
19787dd7cddfSDavid du Colombier 					break;
19797dd7cddfSDavid du Colombier 				p[Blinelen(&ssp->in)-1] = 0;
19807dd7cddfSDavid du Colombier 				if(strcmp(p, "..") == 0)
19817dd7cddfSDavid du Colombier 					break;
19827dd7cddfSDavid du Colombier 			}
19837dd7cddfSDavid du Colombier 			return;
19847dd7cddfSDavid du Colombier 		}
19857dd7cddfSDavid du Colombier 	}
19867dd7cddfSDavid du Colombier 
19877dd7cddfSDavid du Colombier 	if(m == nil){
19887dd7cddfSDavid du Colombier 		m = emalloc(sizeof(*m));
19897dd7cddfSDavid du Colombier 		m->next = macros;
19907dd7cddfSDavid du Colombier 		macros = m;
19917dd7cddfSDavid du Colombier 		m->name = strdup(argv[1]);
19927dd7cddfSDavid du Colombier 		m->val = nil;
19937dd7cddfSDavid du Colombier 		len = 0;
19947dd7cddfSDavid du Colombier 	}
19957dd7cddfSDavid du Colombier 
19967dd7cddfSDavid du Colombier 	/* read up to a .. removing double backslashes */
19977dd7cddfSDavid du Colombier 	for(;;){
19987dd7cddfSDavid du Colombier 		p = Brdline(&ssp->in, '\n');
19997dd7cddfSDavid du Colombier 		if(p == nil)
20007dd7cddfSDavid du Colombier 			break;
20017dd7cddfSDavid du Colombier 		p[Blinelen(&ssp->in)-1] = 0;
20027dd7cddfSDavid du Colombier 		if(strcmp(p, "..") == 0)
20037dd7cddfSDavid du Colombier 			break;
20047dd7cddfSDavid du Colombier 		m->val = realloc(m->val, len + Blinelen(&ssp->in)+1);
20057dd7cddfSDavid du Colombier 		cp = m->val + len;
20067dd7cddfSDavid du Colombier 		while(*p){
20077dd7cddfSDavid du Colombier 			r = *p++;
20087dd7cddfSDavid du Colombier 			if(r == '\\' && *p == '\\')
20097dd7cddfSDavid du Colombier 				p++;
20107dd7cddfSDavid du Colombier 			*cp++ = r;
20117dd7cddfSDavid du Colombier 		}
20127dd7cddfSDavid du Colombier 		*cp++ = '\n';
20137dd7cddfSDavid du Colombier 		len = cp - m->val;
20147dd7cddfSDavid du Colombier 		*cp = 0;
20157dd7cddfSDavid du Colombier 	}
20167dd7cddfSDavid du Colombier }
20177dd7cddfSDavid du Colombier 
20187dd7cddfSDavid du Colombier void
g_hrule(int,char **)20197dd7cddfSDavid du Colombier g_hrule(int, char**)
20207dd7cddfSDavid du Colombier {
20217dd7cddfSDavid du Colombier 	Bprint(&bout, "<HR>\n");
20227dd7cddfSDavid du Colombier }
20237dd7cddfSDavid du Colombier 
20247dd7cddfSDavid du Colombier void
g_BX(int argc,char ** argv)20257dd7cddfSDavid du Colombier g_BX(int argc, char **argv)
20267dd7cddfSDavid du Colombier {
20277dd7cddfSDavid du Colombier 	Bprint(&bout, "<HR>\n");
20287dd7cddfSDavid du Colombier 	printargs(argc, argv);
20297dd7cddfSDavid du Colombier 	Bprint(&bout, "<HR>\n");
20307dd7cddfSDavid du Colombier }
20317dd7cddfSDavid du Colombier 
20327dd7cddfSDavid du Colombier void
g_IH(int,char **)20337dd7cddfSDavid du Colombier g_IH(int, char**)
20347dd7cddfSDavid du Colombier {
20357dd7cddfSDavid du Colombier 	Bprint(&bout, "Bell Laboratories, Naperville, Illinois, 60540\n");
20367dd7cddfSDavid du Colombier }
20377dd7cddfSDavid du Colombier 
20387dd7cddfSDavid du Colombier void
g_MH(int,char **)20397dd7cddfSDavid du Colombier g_MH(int, char**)
20407dd7cddfSDavid du Colombier {
20417dd7cddfSDavid du Colombier 	Bprint(&bout, "Bell Laboratories, Murray Hill, NJ, 07974\n");
20427dd7cddfSDavid du Colombier }
20437dd7cddfSDavid du Colombier 
20447dd7cddfSDavid du Colombier void
g_PY(int,char **)20457dd7cddfSDavid du Colombier g_PY(int, char**)
20467dd7cddfSDavid du Colombier {
20477dd7cddfSDavid du Colombier 	Bprint(&bout, "Bell Laboratories, Piscataway, NJ, 08854\n");
20487dd7cddfSDavid du Colombier }
20497dd7cddfSDavid du Colombier 
20507dd7cddfSDavid du Colombier void
g_HO(int,char **)20517dd7cddfSDavid du Colombier g_HO(int, char**)
20527dd7cddfSDavid du Colombier {
20537dd7cddfSDavid du Colombier 	Bprint(&bout, "Bell Laboratories, Holmdel, NJ, 07733\n");
20547dd7cddfSDavid du Colombier }
20557dd7cddfSDavid du Colombier 
20567dd7cddfSDavid du Colombier void
g_QS(int,char **)20577dd7cddfSDavid du Colombier g_QS(int, char**)
20587dd7cddfSDavid du Colombier {
20597dd7cddfSDavid du Colombier 	Bprint(&bout, "<BLOCKQUOTE>\n");
20607dd7cddfSDavid du Colombier }
20617dd7cddfSDavid du Colombier 
20627dd7cddfSDavid du Colombier void
g_QE(int,char **)20637dd7cddfSDavid du Colombier g_QE(int, char**)
20647dd7cddfSDavid du Colombier {
20657dd7cddfSDavid du Colombier 	Bprint(&bout, "</BLOCKQUOTE>\n");
20667dd7cddfSDavid du Colombier }
20677dd7cddfSDavid du Colombier 
20687dd7cddfSDavid du Colombier void
g_RS(int,char **)20697dd7cddfSDavid du Colombier g_RS(int, char**)
20707dd7cddfSDavid du Colombier {
20717dd7cddfSDavid du Colombier 	Bprint(&bout, "<DL><DD>\n");
20727dd7cddfSDavid du Colombier }
20737dd7cddfSDavid du Colombier 
20747dd7cddfSDavid du Colombier void
g_RE(int,char **)20757dd7cddfSDavid du Colombier g_RE(int, char**)
20767dd7cddfSDavid du Colombier {
20777dd7cddfSDavid du Colombier 	Bprint(&bout, "</DL>\n");
20787dd7cddfSDavid du Colombier }
20797dd7cddfSDavid du Colombier 
20807dd7cddfSDavid du Colombier int gif;
20817dd7cddfSDavid du Colombier 
20827dd7cddfSDavid du Colombier void
g_startgif(int,char ** argv)20837dd7cddfSDavid du Colombier g_startgif(int, char **argv)
20847dd7cddfSDavid du Colombier {
20857dd7cddfSDavid du Colombier 	int fd;
20867dd7cddfSDavid du Colombier 	int pfd[2];
20877dd7cddfSDavid du Colombier 	char *e, *p;
20887dd7cddfSDavid du Colombier 	char name[32];
20899a747e4fSDavid du Colombier 	Dir *d;
20907dd7cddfSDavid du Colombier 
20917dd7cddfSDavid du Colombier 	if(strcmp(argv[0], "EQ") == 0)
20927dd7cddfSDavid du Colombier 		e = ".EN";
20937dd7cddfSDavid du Colombier 	else if(strcmp(argv[0], "TS") == 0)
20947dd7cddfSDavid du Colombier 		e = ".TE";
20957dd7cddfSDavid du Colombier 	else if(strcmp(argv[0], "PS") == 0)
20967dd7cddfSDavid du Colombier 		e = ".PE";
20977dd7cddfSDavid du Colombier 	else
20987dd7cddfSDavid du Colombier 		return;
20997dd7cddfSDavid du Colombier 
210073e742d7SDavid du Colombier 	if(basename)
210173e742d7SDavid du Colombier 		p = basename;
210273e742d7SDavid du Colombier 	else{
21037dd7cddfSDavid du Colombier 		p = strrchr(sstack[0].filename, '/');
21047dd7cddfSDavid du Colombier 		if(p != nil)
21057dd7cddfSDavid du Colombier 			p++;
21067dd7cddfSDavid du Colombier 		else
21077dd7cddfSDavid du Colombier 			p = sstack[0].filename;
210873e742d7SDavid du Colombier 	}
210973e742d7SDavid du Colombier 	snprint(name, sizeof(name), "%s.%d.gif", p, gif++);
21107dd7cddfSDavid du Colombier 	fd = create(name, OWRITE, 0664);
21117dd7cddfSDavid du Colombier 	if(fd < 0){
21127dd7cddfSDavid du Colombier 		fprint(2, "ms2html: can't create %s: %r\n", name);
21137dd7cddfSDavid du Colombier 		return;
21147dd7cddfSDavid du Colombier 	}
21157dd7cddfSDavid du Colombier 
21167dd7cddfSDavid du Colombier 	if(pipe(pfd) < 0){
21177dd7cddfSDavid du Colombier 		fprint(2, "ms2html: can't create pipe: %r\n");
21187dd7cddfSDavid du Colombier 		close(fd);
21197dd7cddfSDavid du Colombier 		return;
21207dd7cddfSDavid du Colombier 	}
21217dd7cddfSDavid du Colombier 	switch(rfork(RFFDG|RFPROC)){
21227dd7cddfSDavid du Colombier 	case -1:
21237dd7cddfSDavid du Colombier 		fprint(2, "ms2html: can't fork: %r\n");
21247dd7cddfSDavid du Colombier 		close(fd);
21257dd7cddfSDavid du Colombier 		return;
21267dd7cddfSDavid du Colombier 	case 0:
21277dd7cddfSDavid du Colombier 		dup(fd, 1);
21287dd7cddfSDavid du Colombier 		close(fd);
21297dd7cddfSDavid du Colombier 		dup(pfd[0], 0);
21307dd7cddfSDavid du Colombier 		close(pfd[0]);
21317dd7cddfSDavid du Colombier 		close(pfd[1]);
2132f19e7b74SDavid du Colombier 		execl("/bin/troff2gif", "troff2gif", nil);
21337dd7cddfSDavid du Colombier 		fprint(2, "ms2html: couldn't exec troff2gif: %r\n");
21347dd7cddfSDavid du Colombier 		_exits(nil);
21357dd7cddfSDavid du Colombier 	default:
21367dd7cddfSDavid du Colombier 		close(fd);
21377dd7cddfSDavid du Colombier 		close(pfd[0]);
21387dd7cddfSDavid du Colombier 		fprint(pfd[1], ".ll 7i\n");
213973e742d7SDavid du Colombier 	/*	fprint(pfd[1], ".EQ\ndelim %s\n.EN\n", delim); */
214073e742d7SDavid du Colombier 	/*	fprint(pfd[1], ".%s\n", argv[0]); */
21417dd7cddfSDavid du Colombier 		for(;;){
21427dd7cddfSDavid du Colombier 			p = Brdline(&ssp->in, '\n');
21437dd7cddfSDavid du Colombier 			if(p == nil)
21447dd7cddfSDavid du Colombier 				break;
21457dd7cddfSDavid du Colombier 			ssp->lno++;
21467dd7cddfSDavid du Colombier 			ssp->rlno++;
21477dd7cddfSDavid du Colombier 			if(write(pfd[1], p, Blinelen(&ssp->in)) < 0)
21487dd7cddfSDavid du Colombier 				break;
21496b6b9ac8SDavid du Colombier 			if(strncmp(p, e, 3) == 0)
21506b6b9ac8SDavid du Colombier 				break;
21517dd7cddfSDavid du Colombier 		}
21527dd7cddfSDavid du Colombier 		close(pfd[1]);
21539a747e4fSDavid du Colombier 		waitpid();
21549a747e4fSDavid du Colombier 		d = dirstat(name);
21559a747e4fSDavid du Colombier 		if(d == nil)
21567dd7cddfSDavid du Colombier 			break;
21579a747e4fSDavid du Colombier 		if(d->length == 0){
21587dd7cddfSDavid du Colombier 			remove(name);
21599a747e4fSDavid du Colombier 			free(d);
21607dd7cddfSDavid du Colombier 			break;
21617dd7cddfSDavid du Colombier 		}
21629a747e4fSDavid du Colombier 		free(d);
21637dd7cddfSDavid du Colombier 		fprint(2, "ms2html: created auxiliary file %s\n", name);
21647dd7cddfSDavid du Colombier 		Bprint(&bout, "<br><img src=\"%s\"><br>\n", name);
21657dd7cddfSDavid du Colombier 		break;
21667dd7cddfSDavid du Colombier 	}
21677dd7cddfSDavid du Colombier }
21687dd7cddfSDavid du Colombier 
21697dd7cddfSDavid du Colombier void
g_lf(int argc,char ** argv)21707dd7cddfSDavid du Colombier g_lf(int argc, char **argv)
21717dd7cddfSDavid du Colombier {
21727dd7cddfSDavid du Colombier 	if(argc > 2)
21737dd7cddfSDavid du Colombier 		snprint(ssp->filename, sizeof(ssp->filename), argv[2]);
21747dd7cddfSDavid du Colombier 	if(argc > 1)
21757dd7cddfSDavid du Colombier 		ssp->rlno = atoi(argv[1]);
21767dd7cddfSDavid du Colombier }
21777dd7cddfSDavid du Colombier 
21787dd7cddfSDavid du Colombier void
g_so(int argc,char ** argv)21797dd7cddfSDavid du Colombier g_so(int argc, char **argv)
21807dd7cddfSDavid du Colombier {
21817dd7cddfSDavid du Colombier 	ssp->lno++;
21827dd7cddfSDavid du Colombier 	ssp->rlno++;
21837dd7cddfSDavid du Colombier 	if(argc > 1)
21847dd7cddfSDavid du Colombier 		pushsrc(argv[1]);
21857dd7cddfSDavid du Colombier }
21867dd7cddfSDavid du Colombier 
21877dd7cddfSDavid du Colombier 
21887dd7cddfSDavid du Colombier void
g_BP(int argc,char ** argv)21897dd7cddfSDavid du Colombier g_BP(int argc, char **argv)
21907dd7cddfSDavid du Colombier {
21917dd7cddfSDavid du Colombier 	int fd;
21927dd7cddfSDavid du Colombier 	char *p, *ext;
21937dd7cddfSDavid du Colombier 	char name[32];
21949a747e4fSDavid du Colombier 	Dir *d;
21957dd7cddfSDavid du Colombier 
21967dd7cddfSDavid du Colombier 	if(argc < 2)
21977dd7cddfSDavid du Colombier 		return;
21987dd7cddfSDavid du Colombier 
21997dd7cddfSDavid du Colombier 	p = strrchr(argv[1], '/');
22007dd7cddfSDavid du Colombier 	if(p != nil)
22017dd7cddfSDavid du Colombier 		p++;
22027dd7cddfSDavid du Colombier 	else
22037dd7cddfSDavid du Colombier 		p = argv[1];
22047dd7cddfSDavid du Colombier 
22057dd7cddfSDavid du Colombier 
22067dd7cddfSDavid du Colombier 	ext = strrchr(p, '.');
22077dd7cddfSDavid du Colombier 	if(ext){
22087dd7cddfSDavid du Colombier 		if(strcmp(ext, ".jpeg") == 0
22097dd7cddfSDavid du Colombier 		|| strcmp(ext, ".gif") == 0){
22107dd7cddfSDavid du Colombier 			Bprint(&bout, "<br><img src=\"%s\"><br>\n", argv[1]);
22117dd7cddfSDavid du Colombier 			return;
22127dd7cddfSDavid du Colombier 		}
22137dd7cddfSDavid du Colombier 	}
22147dd7cddfSDavid du Colombier 
22157dd7cddfSDavid du Colombier 
22167dd7cddfSDavid du Colombier 	snprint(name, sizeof(name), "%s.%d%d.gif", p, getpid(), gif++);
22177dd7cddfSDavid du Colombier 	fd = create(name, OWRITE, 0664);
22187dd7cddfSDavid du Colombier 	if(fd < 0){
22197dd7cddfSDavid du Colombier 		fprint(2, "ms2html: can't create %s: %r\n", name);
22207dd7cddfSDavid du Colombier 		return;
22217dd7cddfSDavid du Colombier 	}
22227dd7cddfSDavid du Colombier 
22237dd7cddfSDavid du Colombier 	switch(rfork(RFFDG|RFPROC)){
22247dd7cddfSDavid du Colombier 	case -1:
22257dd7cddfSDavid du Colombier 		fprint(2, "ms2html: can't fork: %r\n");
22267dd7cddfSDavid du Colombier 		close(fd);
22277dd7cddfSDavid du Colombier 		return;
22287dd7cddfSDavid du Colombier 	case 0:
22297dd7cddfSDavid du Colombier 		dup(fd, 1);
22307dd7cddfSDavid du Colombier 		close(fd);
2231f19e7b74SDavid du Colombier 		execl("/bin/ps2gif", "ps2gif", argv[1], nil);
22327dd7cddfSDavid du Colombier 		fprint(2, "ms2html: couldn't exec ps2gif: %r\n");
22337dd7cddfSDavid du Colombier 		_exits(nil);
22347dd7cddfSDavid du Colombier 	default:
22357dd7cddfSDavid du Colombier 		close(fd);
22369a747e4fSDavid du Colombier 		waitpid();
22379a747e4fSDavid du Colombier 		d = dirstat(name);
22389a747e4fSDavid du Colombier 		if(d == nil)
22397dd7cddfSDavid du Colombier 			break;
22409a747e4fSDavid du Colombier 		if(d->length == 0){
22417dd7cddfSDavid du Colombier 			remove(name);
22429a747e4fSDavid du Colombier 			free(d);
22437dd7cddfSDavid du Colombier 			break;
22447dd7cddfSDavid du Colombier 		}
22459a747e4fSDavid du Colombier 		free(d);
22467dd7cddfSDavid du Colombier 		fprint(2, "ms2html: created auxiliary file %s\n", name);
22477dd7cddfSDavid du Colombier 		Bprint(&bout, "<br><img src=\"%s\"><br>\n", name);
22487dd7cddfSDavid du Colombier 		break;
22497dd7cddfSDavid du Colombier 	}
22507dd7cddfSDavid du Colombier }
22517dd7cddfSDavid du Colombier 
22527dd7cddfSDavid du Colombier /* insert straight HTML into output */
22537dd7cddfSDavid du Colombier void
g__H(int argc,char ** argv)22547dd7cddfSDavid du Colombier g__H(int argc, char **argv)
22557dd7cddfSDavid du Colombier {
22567dd7cddfSDavid du Colombier 	int i;
22577dd7cddfSDavid du Colombier 
22587dd7cddfSDavid du Colombier 	for(i = 1; i < argc; i++)
22597dd7cddfSDavid du Colombier 		Bprint(&bout, "%s ", argv[i]);
22607dd7cddfSDavid du Colombier 	Bprint(&bout, "\n");
22617dd7cddfSDavid du Colombier }
22627dd7cddfSDavid du Colombier 
22637dd7cddfSDavid du Colombier /* HTML page title */
22647dd7cddfSDavid du Colombier void
g__T(int argc,char ** argv)22657dd7cddfSDavid du Colombier g__T(int argc, char **argv)
22667dd7cddfSDavid du Colombier {
22677dd7cddfSDavid du Colombier 	if(titleseen)
22687dd7cddfSDavid du Colombier 		return;
22697dd7cddfSDavid du Colombier 
22707dd7cddfSDavid du Colombier 	Bprint(&bout, "<title>\n");
22717dd7cddfSDavid du Colombier 	printargs(argc, argv);
22727dd7cddfSDavid du Colombier 	Bprint(&bout, "</title></head><body>\n");
22737dd7cddfSDavid du Colombier 	titleseen = 1;
22747dd7cddfSDavid du Colombier }
22757dd7cddfSDavid du Colombier 
22767dd7cddfSDavid du Colombier void
g_nr(int argc,char ** argv)22777dd7cddfSDavid du Colombier g_nr(int argc, char **argv)
22787dd7cddfSDavid du Colombier {
22797dd7cddfSDavid du Colombier 	char *val;
22807dd7cddfSDavid du Colombier 
22817dd7cddfSDavid du Colombier 	if (argc > 1) {
22827dd7cddfSDavid du Colombier 		if (argc == 2)
22837dd7cddfSDavid du Colombier 			val = "0";
22847dd7cddfSDavid du Colombier 		else
22857dd7cddfSDavid du Colombier 			val = argv[2];
22867dd7cddfSDavid du Colombier 		dsnr(argv[1], val, &numregs);
22877dd7cddfSDavid du Colombier 	}
22887dd7cddfSDavid du Colombier }
22897dd7cddfSDavid du Colombier 
22907dd7cddfSDavid du Colombier void
zerodivide(void)22917dd7cddfSDavid du Colombier zerodivide(void)
22927dd7cddfSDavid du Colombier {
22937dd7cddfSDavid du Colombier 	fprint(2, "stdin %d(%s:%d): division by 0\n",
22947dd7cddfSDavid du Colombier 		ssp->lno, ssp->filename, ssp->rlno);
22957dd7cddfSDavid du Colombier }
22967dd7cddfSDavid du Colombier 
22977dd7cddfSDavid du Colombier int
numval(char ** pline,int recur)22987dd7cddfSDavid du Colombier numval(char **pline, int recur)
22997dd7cddfSDavid du Colombier {
23007dd7cddfSDavid du Colombier 	char *p;
23017dd7cddfSDavid du Colombier 	int neg, x, y;
23027dd7cddfSDavid du Colombier 
23037dd7cddfSDavid du Colombier 	x = neg = 0;
23047dd7cddfSDavid du Colombier 	p = *pline;
23057dd7cddfSDavid du Colombier 	while(*p == '-') {
23067dd7cddfSDavid du Colombier 		neg = 1 - neg;
23077dd7cddfSDavid du Colombier 		p++;
23087dd7cddfSDavid du Colombier 	}
23097dd7cddfSDavid du Colombier 	if (*p == '(') {
23107dd7cddfSDavid du Colombier 		p++;
23117dd7cddfSDavid du Colombier 		x = numval(&p, 1);
23127dd7cddfSDavid du Colombier 		if (*p != ')')
23137dd7cddfSDavid du Colombier 			goto done;
23147dd7cddfSDavid du Colombier 		p++;
23157dd7cddfSDavid du Colombier 	}
23167dd7cddfSDavid du Colombier 	else while(*p >= '0' && *p <= '9')
23177dd7cddfSDavid du Colombier 		x = 10*x + *p++ - '0';
23187dd7cddfSDavid du Colombier 	if (neg)
23197dd7cddfSDavid du Colombier 		x = -x;
23207dd7cddfSDavid du Colombier 	if (recur)
23217dd7cddfSDavid du Colombier 	    for(;;) {
23227dd7cddfSDavid du Colombier 		switch(*p++) {
23237dd7cddfSDavid du Colombier 		case '+':
23247dd7cddfSDavid du Colombier 			x += numval(&p, 0);
23257dd7cddfSDavid du Colombier 			continue;
23267dd7cddfSDavid du Colombier 		case '-':
23277dd7cddfSDavid du Colombier 			x -= numval(&p, 0);
23287dd7cddfSDavid du Colombier 			continue;
23297dd7cddfSDavid du Colombier 		case '*':
23307dd7cddfSDavid du Colombier 			x *= numval(&p, 0);
23317dd7cddfSDavid du Colombier 			continue;
23327dd7cddfSDavid du Colombier 		case '/':
23337dd7cddfSDavid du Colombier 			y = numval(&p, 0);
23347dd7cddfSDavid du Colombier 			if (y == 0) {
23357dd7cddfSDavid du Colombier 				zerodivide();
23367dd7cddfSDavid du Colombier 				x = 0;
23377dd7cddfSDavid du Colombier 				goto done;
23387dd7cddfSDavid du Colombier 			}
23397dd7cddfSDavid du Colombier 			x /= y;
23407dd7cddfSDavid du Colombier 			continue;
23417dd7cddfSDavid du Colombier 		case '<':
23427dd7cddfSDavid du Colombier 			if (*p == '=') {
23437dd7cddfSDavid du Colombier 				p++;
23447dd7cddfSDavid du Colombier 				x = x <= numval(&p, 0);
23457dd7cddfSDavid du Colombier 				continue;
23467dd7cddfSDavid du Colombier 			}
23477dd7cddfSDavid du Colombier 			x = x < numval(&p, 0);
23487dd7cddfSDavid du Colombier 			continue;
23497dd7cddfSDavid du Colombier 		case '>':
23507dd7cddfSDavid du Colombier 			if (*p == '=') {
23517dd7cddfSDavid du Colombier 				p++;
23527dd7cddfSDavid du Colombier 				x = x >= numval(&p, 0);
23537dd7cddfSDavid du Colombier 				continue;
23547dd7cddfSDavid du Colombier 			}
23557dd7cddfSDavid du Colombier 			x = x > numval(&p, 0);
23567dd7cddfSDavid du Colombier 			continue;
23577dd7cddfSDavid du Colombier 		case '=':
23587dd7cddfSDavid du Colombier 			if (*p == '=')
23597dd7cddfSDavid du Colombier 				p++;
23607dd7cddfSDavid du Colombier 			x = x == numval(&p, 0);
23617dd7cddfSDavid du Colombier 			continue;
23627dd7cddfSDavid du Colombier 		case '&':
23637dd7cddfSDavid du Colombier 			x &= numval(&p, 0);
23647dd7cddfSDavid du Colombier 			continue;
23657dd7cddfSDavid du Colombier 		case ':':
23667dd7cddfSDavid du Colombier 			x |= numval(&p, 0);
23677dd7cddfSDavid du Colombier 			continue;
23687dd7cddfSDavid du Colombier 		case '%':
23697dd7cddfSDavid du Colombier 			y = numval(&p, 0);
23707dd7cddfSDavid du Colombier 			if (!y) {
23717dd7cddfSDavid du Colombier 				zerodivide();
23727dd7cddfSDavid du Colombier 				goto done;
23737dd7cddfSDavid du Colombier 			}
23747dd7cddfSDavid du Colombier 			x %= y;
23757dd7cddfSDavid du Colombier 			continue;
23767dd7cddfSDavid du Colombier 		}
23777dd7cddfSDavid du Colombier 		--p;
23787dd7cddfSDavid du Colombier 		break;
23797dd7cddfSDavid du Colombier 	}
23807dd7cddfSDavid du Colombier  done:
23817dd7cddfSDavid du Colombier 	*pline = p;
23827dd7cddfSDavid du Colombier 	return x;
23837dd7cddfSDavid du Colombier }
23847dd7cddfSDavid du Colombier 
23857dd7cddfSDavid du Colombier int
iftest(char * p,char ** bp)23867dd7cddfSDavid du Colombier iftest(char *p, char **bp)
23877dd7cddfSDavid du Colombier {
23887dd7cddfSDavid du Colombier 	char *p1;
23897dd7cddfSDavid du Colombier 	int c, neg, rv;
23907dd7cddfSDavid du Colombier 
23917dd7cddfSDavid du Colombier 	rv = neg = 0;
23927dd7cddfSDavid du Colombier 	if (*p == '!') {
23937dd7cddfSDavid du Colombier 		neg = 1;
23947dd7cddfSDavid du Colombier 		p++;
23957dd7cddfSDavid du Colombier 	}
23967dd7cddfSDavid du Colombier 	c = *p;
23977dd7cddfSDavid du Colombier 	if (c >= '0' && c <= '9' || c == '+' || c == '-' || c == '('/*)*/) {
23987dd7cddfSDavid du Colombier 		if (numval(&p,1) >= 1)
23997dd7cddfSDavid du Colombier 			rv = 1;
24007dd7cddfSDavid du Colombier 		goto done;
24017dd7cddfSDavid du Colombier 	}
24027dd7cddfSDavid du Colombier 	switch(c) {
24037dd7cddfSDavid du Colombier 	case 't':
24047dd7cddfSDavid du Colombier 	case 'o':
24057dd7cddfSDavid du Colombier 		rv = 1;
24067dd7cddfSDavid du Colombier 	case 'n':
24077dd7cddfSDavid du Colombier 	case 'e':
24087dd7cddfSDavid du Colombier 		p++;
24097dd7cddfSDavid du Colombier 		goto done;
24107dd7cddfSDavid du Colombier 	}
24117dd7cddfSDavid du Colombier 	for(p1 = ++p; *p != c; p++)
24127dd7cddfSDavid du Colombier 		if (!*p)
24137dd7cddfSDavid du Colombier 			goto done;
24147dd7cddfSDavid du Colombier 	for(p++;;) {
24157dd7cddfSDavid du Colombier 		if (*p != *p1++) {
24167dd7cddfSDavid du Colombier 			while(*p && *p++ != c);
24177dd7cddfSDavid du Colombier 			goto done;
24187dd7cddfSDavid du Colombier 		}
24197dd7cddfSDavid du Colombier 		if (*p++ == c)
24207dd7cddfSDavid du Colombier 			break;
24217dd7cddfSDavid du Colombier 	}
24227dd7cddfSDavid du Colombier 	rv = 1;
24237dd7cddfSDavid du Colombier  done:
24247dd7cddfSDavid du Colombier 	if (neg)
24257dd7cddfSDavid du Colombier 		rv = 1 - rv;
24267dd7cddfSDavid du Colombier 	while(*p == ' ' || *p == '\t')
24277dd7cddfSDavid du Colombier 		p++;
24287dd7cddfSDavid du Colombier 	*bp = p;
24297dd7cddfSDavid du Colombier 	return rv;
24307dd7cddfSDavid du Colombier }
24317dd7cddfSDavid du Colombier 
24327dd7cddfSDavid du Colombier void
scanline(char * p,char * e,int wantnl)24337dd7cddfSDavid du Colombier scanline(char *p, char *e, int wantnl)
24347dd7cddfSDavid du Colombier {
24357dd7cddfSDavid du Colombier 	int c;
24367dd7cddfSDavid du Colombier 	Rune r;
24377dd7cddfSDavid du Colombier 
24387dd7cddfSDavid du Colombier 	while((c = getrune()) == ' ' || c == '\t') ;
24397dd7cddfSDavid du Colombier 	while(p < e) {
24407dd7cddfSDavid du Colombier 		if (c < 0)
24417dd7cddfSDavid du Colombier 			break;
24427dd7cddfSDavid du Colombier 		if (c < Runeself) {
24437dd7cddfSDavid du Colombier 			if (c == '\n') {
24447dd7cddfSDavid du Colombier 				if (wantnl)
24457dd7cddfSDavid du Colombier 					*p++ = c;
24467dd7cddfSDavid du Colombier 				break;
24477dd7cddfSDavid du Colombier 			}
24487dd7cddfSDavid du Colombier 			*p++ = c;
24497dd7cddfSDavid du Colombier 		}
24507dd7cddfSDavid du Colombier 		else {
24517dd7cddfSDavid du Colombier 			r = c;
24527dd7cddfSDavid du Colombier 			p += runetochar(p, &r);
24537dd7cddfSDavid du Colombier 		}
24547dd7cddfSDavid du Colombier 		c = getrune();
24557dd7cddfSDavid du Colombier 	}
24567dd7cddfSDavid du Colombier 	*p = 0;
24577dd7cddfSDavid du Colombier }
24587dd7cddfSDavid du Colombier 
24597dd7cddfSDavid du Colombier void
pushbody(char * line)24607dd7cddfSDavid du Colombier pushbody(char *line)
24617dd7cddfSDavid du Colombier {
24627dd7cddfSDavid du Colombier 	char *b;
24637dd7cddfSDavid du Colombier 
24647dd7cddfSDavid du Colombier 	if (line[0] == '\\' && line[1] == '{' /*}*/ )
24657dd7cddfSDavid du Colombier 		line += 2;
24667dd7cddfSDavid du Colombier 	if (strsp < Maxmstack - 1) {
24677dd7cddfSDavid du Colombier 		pushstr(b = strdup(line));
24687dd7cddfSDavid du Colombier 		mustfree[strsp] = b;
24697dd7cddfSDavid du Colombier 	}
24707dd7cddfSDavid du Colombier }
24717dd7cddfSDavid du Colombier 
24727dd7cddfSDavid du Colombier void
skipbody(char * line)24737dd7cddfSDavid du Colombier skipbody(char *line)
24747dd7cddfSDavid du Colombier {
24757dd7cddfSDavid du Colombier 	int c, n;
24767dd7cddfSDavid du Colombier 
24777dd7cddfSDavid du Colombier 	if (line[0] != '\\' || line[1] != '{' /*}*/ )
24787dd7cddfSDavid du Colombier 		return;
24797dd7cddfSDavid du Colombier 	for(n = 1;;) {
24807dd7cddfSDavid du Colombier 		while((c = getrune()) != '\\')
24817dd7cddfSDavid du Colombier 			if (c < 0)
24827dd7cddfSDavid du Colombier 				return;
24837dd7cddfSDavid du Colombier 		c = getrune();
24847dd7cddfSDavid du Colombier 		if (c == '{')
24857dd7cddfSDavid du Colombier 			n++;
24867dd7cddfSDavid du Colombier 		else if ((c == '}' && (c = getrune()) == '\n' && !--n)
24877dd7cddfSDavid du Colombier 			|| c < 0)
24887dd7cddfSDavid du Colombier 			return;
24897dd7cddfSDavid du Colombier 	}
24907dd7cddfSDavid du Colombier }
24917dd7cddfSDavid du Colombier 
24927dd7cddfSDavid du Colombier int
ifstart(char * line,char * e,char ** bp)24937dd7cddfSDavid du Colombier ifstart(char *line, char *e, char **bp)
24947dd7cddfSDavid du Colombier {
24957dd7cddfSDavid du Colombier 	int it;
24967dd7cddfSDavid du Colombier 	char *b;
24977dd7cddfSDavid du Colombier 
24987dd7cddfSDavid du Colombier 	b = copyline(line, e, 1);
24997dd7cddfSDavid du Colombier 	ungetrune();
25007dd7cddfSDavid du Colombier 	b[-1] = getrune();
25017dd7cddfSDavid du Colombier 	scanline(b, e, 1);
25027dd7cddfSDavid du Colombier 	it = iftest(line, bp);
25037dd7cddfSDavid du Colombier 	return it;
25047dd7cddfSDavid du Colombier }
25057dd7cddfSDavid du Colombier 
25067dd7cddfSDavid du Colombier void
g_ie(char * line,char * e)25077dd7cddfSDavid du Colombier g_ie(char *line, char *e)
25087dd7cddfSDavid du Colombier {
25097dd7cddfSDavid du Colombier 	char *b;
25107dd7cddfSDavid du Colombier 
25117dd7cddfSDavid du Colombier 	if (elsetop >= Maxif-1) {
25127dd7cddfSDavid du Colombier 		fprint(2, "ms2html: .ie's too deep\n");
25137dd7cddfSDavid du Colombier 		return;
25147dd7cddfSDavid du Colombier 	}
25157dd7cddfSDavid du Colombier 	if (ifwastrue[++elsetop] = ifstart(line, e, &b))
25167dd7cddfSDavid du Colombier 		pushbody(b);
25177dd7cddfSDavid du Colombier 	else
25187dd7cddfSDavid du Colombier 		skipbody(b);
25197dd7cddfSDavid du Colombier }
25207dd7cddfSDavid du Colombier 
25217dd7cddfSDavid du Colombier void
g_if(char * line,char * e)25227dd7cddfSDavid du Colombier g_if(char *line, char *e)
25237dd7cddfSDavid du Colombier {
25247dd7cddfSDavid du Colombier 	char *b;
25257dd7cddfSDavid du Colombier 
25267dd7cddfSDavid du Colombier 	if (ifstart(line, e, &b))
25277dd7cddfSDavid du Colombier 		pushbody(b);
25287dd7cddfSDavid du Colombier 	else
25297dd7cddfSDavid du Colombier 		skipbody(b);
25307dd7cddfSDavid du Colombier }
25317dd7cddfSDavid du Colombier 
25327dd7cddfSDavid du Colombier void
g_el(char * line,char * e)25337dd7cddfSDavid du Colombier g_el(char *line, char *e)
25347dd7cddfSDavid du Colombier {
25357dd7cddfSDavid du Colombier 	if (elsetop < 0)
25367dd7cddfSDavid du Colombier 		return;
25377dd7cddfSDavid du Colombier 	scanline(line, e, 1);
25387dd7cddfSDavid du Colombier 	if (ifwastrue[elsetop--])
25397dd7cddfSDavid du Colombier 		skipbody(line);
25407dd7cddfSDavid du Colombier 	else
25417dd7cddfSDavid du Colombier 		pushbody(line);
25427dd7cddfSDavid du Colombier }
25437dd7cddfSDavid du Colombier 
25447dd7cddfSDavid du Colombier void
g_ig(int argc,char ** argv)25457dd7cddfSDavid du Colombier g_ig(int argc, char **argv)
25467dd7cddfSDavid du Colombier {
25477dd7cddfSDavid du Colombier 	char *p, *s;
25487dd7cddfSDavid du Colombier 
25497dd7cddfSDavid du Colombier 	s = "..";
25507dd7cddfSDavid du Colombier 	if (argc > 1)
25517dd7cddfSDavid du Colombier 		s = argv[1];
25527dd7cddfSDavid du Colombier 	for(;;) {
25537dd7cddfSDavid du Colombier 		p = Brdline(&ssp->in, '\n');
25547dd7cddfSDavid du Colombier 		if(p == nil)
25557dd7cddfSDavid du Colombier 			break;
25567dd7cddfSDavid du Colombier 		p[Blinelen(&ssp->in)-1] = 0;
25577dd7cddfSDavid du Colombier 		if(strcmp(p, s) == 0)
25587dd7cddfSDavid du Colombier 			break;
25597dd7cddfSDavid du Colombier 	}
25607dd7cddfSDavid du Colombier }
25617dd7cddfSDavid du Colombier 
25627dd7cddfSDavid du Colombier void
g_ds(char * line,char * e)25637dd7cddfSDavid du Colombier g_ds(char *line, char *e)
25647dd7cddfSDavid du Colombier {
25657dd7cddfSDavid du Colombier 	char *b;
25667dd7cddfSDavid du Colombier 
25677dd7cddfSDavid du Colombier 	b = copyline(line, e, 1);
25687dd7cddfSDavid du Colombier 	if (b > line) {
25697dd7cddfSDavid du Colombier 		copyline(b, e, 0);
25707dd7cddfSDavid du Colombier 		if (*b == '"')
25717dd7cddfSDavid du Colombier 			b++;
25727dd7cddfSDavid du Colombier 		ds(line, b);
25737dd7cddfSDavid du Colombier 	}
25747dd7cddfSDavid du Colombier }
25757dd7cddfSDavid du Colombier 
25767dd7cddfSDavid du Colombier void
g_as(char * line,char * e)25777dd7cddfSDavid du Colombier g_as(char *line, char *e)
25787dd7cddfSDavid du Colombier {
25797dd7cddfSDavid du Colombier 	String *s;
25807dd7cddfSDavid du Colombier 	char *b;
25817dd7cddfSDavid du Colombier 
25827dd7cddfSDavid du Colombier 	b = copyline(line, e, 1);
25837dd7cddfSDavid du Colombier 	if (b == line)
25847dd7cddfSDavid du Colombier 		return;
25857dd7cddfSDavid du Colombier 	copyline(b, e, 0);
25867dd7cddfSDavid du Colombier 	if (*b == '"')
25877dd7cddfSDavid du Colombier 		b++;
25887dd7cddfSDavid du Colombier 	for(s = strings; s != nil; s = s->next)
25897dd7cddfSDavid du Colombier 		if(strcmp(line, s->name) == 0)
25907dd7cddfSDavid du Colombier 			break;
25917dd7cddfSDavid du Colombier 
25927dd7cddfSDavid du Colombier 	if(s == nil){
25937dd7cddfSDavid du Colombier 		ds(line, b);
25947dd7cddfSDavid du Colombier 		return;
25957dd7cddfSDavid du Colombier 	}
25967dd7cddfSDavid du Colombier 
25977dd7cddfSDavid du Colombier 	s->val = realloc(s->val, strlen(s->val) + strlen(b) + 1);
25987dd7cddfSDavid du Colombier 	strcat(s->val, b);
25997dd7cddfSDavid du Colombier }
26007dd7cddfSDavid du Colombier 
26017dd7cddfSDavid du Colombier void
g_BS(int argc,char ** argv)26027dd7cddfSDavid du Colombier g_BS(int argc, char **argv)
26037dd7cddfSDavid du Colombier {
26047dd7cddfSDavid du Colombier 	int i;
26057dd7cddfSDavid du Colombier 
26067dd7cddfSDavid du Colombier 	if (argc > 1 && !weBref) {
26077dd7cddfSDavid du Colombier 		Bprint(&bout, "<a href=\"%s\"", argv[1]);
26087dd7cddfSDavid du Colombier 		for(i = 2; i < argc; i++)
26097dd7cddfSDavid du Colombier 			Bprint(&bout, " %s", argv[i]);
26107dd7cddfSDavid du Colombier 		Bprint(&bout, ">");
26117dd7cddfSDavid du Colombier 		weBref = 1;
26127dd7cddfSDavid du Colombier 	}
26137dd7cddfSDavid du Colombier }
26147dd7cddfSDavid du Colombier 
26157dd7cddfSDavid du Colombier void
g_BE(int,char **)26167dd7cddfSDavid du Colombier g_BE(int, char**)
26177dd7cddfSDavid du Colombier {
26187dd7cddfSDavid du Colombier 	if (weBref) {
26197dd7cddfSDavid du Colombier 		Bprint(&bout, "</a>");
26207dd7cddfSDavid du Colombier 		weBref = 0;
26217dd7cddfSDavid du Colombier 	}
26227dd7cddfSDavid du Colombier }
26237dd7cddfSDavid du Colombier 
26247dd7cddfSDavid du Colombier void
g_LB(int argc,char ** argv)26257dd7cddfSDavid du Colombier g_LB(int argc, char **argv)
26267dd7cddfSDavid du Colombier {
26277dd7cddfSDavid du Colombier 	if (argc > 1) {
26287dd7cddfSDavid du Colombier 		if (weBref)
26297dd7cddfSDavid du Colombier 			g_BE(0,nil);
26307dd7cddfSDavid du Colombier 		Bprint(&bout, "<a name=\"%s\"></a>", argv[1]);
26317dd7cddfSDavid du Colombier 	}
26327dd7cddfSDavid du Colombier }
26337dd7cddfSDavid du Colombier 
26347dd7cddfSDavid du Colombier void
g_RT(int,char **)26357dd7cddfSDavid du Colombier g_RT(int, char**)
26367dd7cddfSDavid du Colombier {
26377dd7cddfSDavid du Colombier 	g_BE(0,nil);
26387dd7cddfSDavid du Colombier 	dohanginghead();
26397dd7cddfSDavid du Colombier 	closel();
26407dd7cddfSDavid du Colombier 	closefont();
26417dd7cddfSDavid du Colombier }
2642