Charles.Forsyth200612195f2b45819 years agoHistory
1328 lines · 27.0 KB · Brainfuck
RawDownload
implement Man2html; include "sys.m";	stderr: ref Sys->FD;	sys: Sys;	print, fprint, sprint: import sys;  include "bufio.m"; include "draw.m"; include "daytime.m";	dt: Daytime; include "string.m";	str: String; Man2html: module{	init:	fn(ctxt: ref Draw->Context, args: list of string);}; Runeself: con 16r80;false, true: con iota; Troffspec: adt {	name: string;	value: string;}; tspec := array [] of { Troffspec	("ff", "ff"),	("fi", "fi"),	("fl", "fl"),	("Fi", "ffi"),	("ru", "_"),	("em", "&#173;"),	("14", "&#188;"),	("12", "&#189;"),	("co", "&#169;"),	("de", "&#176;"),	("dg", "&#161;"),	("fm", "&#180;"),	("rg", "&#174;"),#	("bu", "*"),	("bu", "•"),	("sq", "&#164;"),	("hy", "-"),	("pl", "+"),	("mi", "-"),	("mu", "&#215;"),	("di", "&#247;"),	("eq", "="),	("==", "=="),	(">=", ">="),	("<=", "<="),	("!=", "!="),	("+-", "&#177;"),	("no", "&#172;"),	("sl", "/"),	("ap", "&"),	("~=", "~="),	("pt", "oc"),	("gr", "GRAD"),	("->", "->"),	("<-", "<-"),	("ua", "^"),	("da", "v"),	("is", "Integral"),	("pd", "DIV"),	("if", "oo"),	("sr", "-/"),	("sb", "(~"),	("sp", "~)"),	("cu", "U"),	("ca", "(^)"),	("ib", "(="),	("ip", "=)"),	("mo", "C"),	("es", "&Oslash;"),	("aa", "&#180;"),	("ga", "`"),	("ci", "O"),	("L1", "Lucent"),	("sc", "&#167;"),	("dd", "++"),	("lh", "<="),	("rh", "=>"),	("lt", "("),	("rt", ")"),	("lc", "|"),	("rc", "|"),	("lb", "("),	("rb", ")"),	("lf", "|"),	("rf", "|"),	("lk", "|"),	("rk", "|"),	("bv", "|"),	("ts", "s"),	("br", "|"),	("or", "|"),	("ul", "_"),	("rn", " "),	("*p", "PI"),	("**", "*"),}; 	Entity: adt {		 name: string;		 value: int;	};	Entities: array of Entity; Entities = array[] of {		Entity( "&#161;",	'¡' ),		Entity( "&#162;",	'¢' ),		Entity( "&#163;",	'£' ),		Entity( "&#164;",	'¤' ),		Entity( "&#165;",	'¥' ),		Entity( "&#166;",	'¦' ),		Entity( "&#167;",	'§' ),		Entity( "&#168;",	'¨' ),		Entity( "&#169;",	'©' ),		Entity( "&#170;",	'ª' ),		Entity( "&#171;",	'«' ),		Entity( "&#172;",	'¬' ),		Entity( "&#173;",	'­' ),		Entity( "&#174;",	'®' ),		Entity( "&#175;",	'¯' ),		Entity( "&#176;",	'°' ),		Entity( "&#177;",	'±' ),		Entity( "&#178;",	'²' ),		Entity( "&#179;",	'³' ),		Entity( "&#180;",	'´' ),		Entity( "&#181;",	'µ' ),		Entity( "&#182;",	'¶' ),		Entity( "&#183;",	'·' ),		Entity( "&#184;",	'¸' ),		Entity( "&#185;",	'¹' ),		Entity( "&#186;",	'º' ),		Entity( "&#187;",	'»' ),		Entity( "&#188;",	'¼' ),		Entity( "&#189;",	'½' ),		Entity( "&#190;",	'¾' ),		Entity( "&#191;",	'¿' ),		Entity( "&Agrave;",	'À' ),		Entity( "&Aacute;",	'Á' ),		Entity( "&Acirc;",	'Â' ),		Entity( "&Atilde;",	'Ã' ),		Entity( "&Auml;",	'Ä' ),		Entity( "&Aring;",	'Å' ),		Entity( "&AElig;",	'Æ' ),		Entity( "&Ccedil;",	'Ç' ),		Entity( "&Egrave;",	'È' ),		Entity( "&Eacute;",	'É' ),		Entity( "&Ecirc;",	'Ê' ),		Entity( "&Euml;",	'Ë' ),		Entity( "&Igrave;",	'Ì' ),		Entity( "&Iacute;",	'Í' ),		Entity( "&Icirc;",	'Î' ),		Entity( "&Iuml;",	'Ï' ),		Entity( "&ETH;",	'Ð' ),		Entity( "&Ntilde;",	'Ñ' ),		Entity( "&Ograve;",	'Ò' ),		Entity( "&Oacute;",	'Ó' ),		Entity( "&Ocirc;",	'Ô' ),		Entity( "&Otilde;",	'Õ' ),		Entity( "&Ouml;",	'Ö' ),		Entity( "&215;",	'×' ),		Entity( "&Oslash;",	'Ø' ),		Entity( "&Ugrave;",	'Ù' ),		Entity( "&Uacute;",	'Ú' ),		Entity( "&Ucirc;",	'Û' ),		Entity( "&Uuml;",	'Ü' ),		Entity( "&Yacute;",	'Ý' ),		Entity( "&THORN;",	'Þ' ),		Entity( "&szlig;",	'ß' ),		Entity( "&agrave;",	'à' ),		Entity( "&aacute;",	'á' ),		Entity( "&acirc;",	'â' ),		Entity( "&atilde;",	'ã' ),		Entity( "&auml;",	'ä' ),		Entity( "&aring;",	'å' ),		Entity( "&aelig;",	'æ' ),		Entity( "&ccedil;",	'ç' ),		Entity( "&egrave;",	'è' ),		Entity( "&eacute;",	'é' ),		Entity( "&ecirc;",	'ê' ),		Entity( "&euml;",	'ë' ),		Entity( "&igrave;",	'ì' ),		Entity( "&iacute;",	'í' ),		Entity( "&icirc;",	'î' ),		Entity( "&iuml;",	'ï' ),		Entity( "&eth;",	'ð' ),		Entity( "&ntilde;",	'ñ' ),		Entity( "&ograve;",	'ò' ),		Entity( "&oacute;",	'ó' ),		Entity( "&ocirc;",	'ô' ),		Entity( "&otilde;",	'õ' ),		Entity( "&ouml;",	'ö' ),		Entity( "&247;",	'÷' ),		Entity( "&oslash;",	'ø' ),		Entity( "&ugrave;",	'ù' ),		Entity( "&uacute;",	'ú' ),		Entity( "&ucirc;",	'û' ),		Entity( "&uuml;",	'ü' ),		Entity( "&yacute;",	'ý' ),		Entity( "&thorn;",	'þ' ),		Entity( "&yuml;",	'ÿ' ),		# &#255; 		Entity( "&#SPACE;",	' ' ),		Entity( "&#RS;",	'\n' ),		Entity( "&#RE;",	'\r' ),		Entity( "&quot;",	'"' ),		Entity( "&amp;",	'&' ),		Entity( "&lt;",	'<' ),		Entity( "&gt;",	'>' ), 		Entity( "CAP-DELTA",	'Δ' ),		Entity( "ALPHA",	'α' ),		Entity( "BETA",	'β' ),		Entity( "DELTA",	'δ' ),		Entity( "EPSILON",	'ε' ),		Entity( "THETA",	'θ' ),		Entity( "MU",		'μ' ),		Entity( "PI",		'π' ),		Entity( "TAU",	'τ' ),		Entity( "CHI",	'χ' ), 		Entity( "<-",		'←' ),		Entity( "^",		'↑' ),		Entity( "->",		'→' ),		Entity( "v",		'↓' ),		Entity( "!=",		'≠' ),		Entity( "<=",		'≤' ),		Entity( nil, 0 ),};  Hit: adt {	glob: string;	chap: string;	mtype: string;	page: string;}; Lnone, Lordered, Lunordered, Ldef, Lother: con iota;	# list types Chaps: adt {	name: string;	primary: int;}; Types: adt {	name: string;	desc: string;};  # having two separate flags here allows for inclusion of old-style formatted pages# under a new-style three-level treeOldstyle: adt {	names: int;	# two-level directory tree?	fmt: int;		# old internal formats: e.g., "B" font means "L"; name in .TH in all caps}; Href: adt {	title: string;	chap: string;	mtype: string;	man: string;}; # per-thread global dataGlobal: adt {	bufio: Bufio;	bin: ref Bufio->Iobuf;	bout: ref Bufio->Iobuf;	topname: string;		# name of the top level categories in the manual	chaps: array of Chaps;	# names of top-level partitions of this manual	types: array of Types;	# names of second-level partitions	oldstyle: Oldstyle;	mantitle: string;	mandir: string;	thisone: Hit;		# man page we're displaying	mtime: int;			# last modification time of thisone	href: Href;			# hrefs of components of this man page	hits: array of Hit;	nhits: int;	list_type: int;	pm: string;			# proprietary marking	def_goobie: string;	# deferred goobie	sop: int;			# output at start of paragraph?	sol: int;			# input at start of line?	broken: int;		# output at a break?	fill: int;			# in fill mode? 	pre: int;			# in PRE block?	example: int;		# an example active?	ipd: int;			# emit inter-paragraph distance?	indents: int;	hangingdt: int;	curfont: string;		# current font	prevfont: string;		# previous font	lastc: int;			# previous char from input scanner	def_sm: int;		# amount of deferred "make smaller" request 	mk_href_chap: fn(g: self ref Global, chap: string);	mk_href_man: fn(g: self ref Global, man: string, oldstyle: int);	mk_href_mtype: fn(g: self ref Global, chap, mtype: string);	dobreak: fn(g: self ref Global);	print: fn(g: self ref Global, s: string);	softbr: fn(g: self ref Global): string;	softp: fn(g: self ref Global): string;};  usage(){	sys->fprint(stderr, "Usage: man2html file [section]\n");	raise "fail:usage";}  init(nil: ref Draw->Context, args: list of string){	sys = load Sys Sys->PATH;	stderr = sys->fildes(2);	str = load String String->PATH;	dt = load Daytime Daytime->PATH;	g := Global_init();	if(args != nil)		args = tl args;	if(args == nil)		usage();	page := hd args;	args = tl args;	section := "1";	if(args != nil)		section = hd args;	hit := Hit ("", "man", section, page);	domanpage(g, hit);	g.bufio->g.bout.flush();} # remove markup from a string# doesn't handle nested/quoted delimitersdemark(s: string): string{	t: string;	clean := true;	for (i := 0; i < len s; i++) {		case s[i] {		'<' =>			clean = false;		'>' =>			clean = true;		* =>			if (clean)				t[len t] = s[i];		}			}	return t;}  ##  Convert an individual man page to HTML and output.#domanpage(g: ref Global, man: Hit){	file := man.page;	g.bin = g.bufio->open(file, Bufio->OREAD);	g.bout = g.bufio->fopen(sys->fildes(1), Bufio->OWRITE);	if (g.bin == nil) {		fprint(stderr, "Cannot open %s: %r\n", file);		return;	}	(err, info) := sys->fstat(g.bin.fd);	if (! err) {		g.mtime = info.mtime;	}	g.thisone = man;	while ((p := getnext(g)) != nil) {		c := p[0];		if (c == '.' && g.sol) {			if (g.pre) {				g.print("</PRE>");				g.pre = false;			}			dogoobie(g, false);			dohangingdt(g);		} else if (g.def_goobie != nil || g.def_sm != 0) {			g.bufio->g.bin.ungetc();			dogoobie(g, true);		} else if (c == '\n') {			g.print(p);			dohangingdt(g);		} else			g.print(p);	}	if (g.pm != nil) {		g.print("<BR><BR><BR><FONT SIZE=-2><CENTER>\n");		g.print(g.pm);		g.print("<BR></CENTER></FONT>\n");	}	closeall(g, 0);	rev(g, g.bin);} dogoobie(g: ref Global, deferred: int){	# read line, translate special chars	line: string;	while ((token := getnext(g)) != "\n") {		if (token == nil)			return;		line += token;	} 	# parse into arguments	argl, rargl: list of string;	# create reversed version, then invert	while ((line = str->drop(line, " \t")) != nil)		if (line[0] == '"') {			(token, line) = split(line[1:], '"');			rargl = token :: rargl;		} else {			(token, line) = str->splitl(line, " \t");			rargl = token :: rargl;		} 	if (rargl == nil && !deferred)		return;	for ( ; rargl != nil; rargl = tl rargl)		argl = hd rargl :: argl; 	def_sm := g.def_sm;	if (deferred && def_sm > 0) {		g.print(sprint("<FONT SIZE=-%d>", def_sm));		if (g.def_goobie == nil)			argl = "dS" :: argl;	# dS is our own local creation	} 	subgoobie(g, argl); 	if (deferred && def_sm > 0) {		g.def_sm = 0;		g.print("</FONT>");	}} subgoobie(g: ref Global, argl: list of string){	if (g.def_goobie != nil) {		argl = g.def_goobie :: argl;		g.def_goobie = nil;		if (tl argl == nil)			return;	} 	# the command part is at most two characters, but may be concatenated with the first arg	cmd := hd argl;	argl = tl argl;	if (len cmd > 2) {		cmd = cmd[0:2];		argl =  cmd[2:] :: argl;	} 	case cmd { 	"B" or "I" or "L" or "R" =>		font(g, cmd, argl);		# "R" macro implicitly generated by deferred R* macros 	"BI" or "BL" or "BR" or	"IB" or "IL" or	"LB" or "LI" or	"RB" or "RI" or "RL" =>		altfont(g, cmd[0:1], cmd[1:2], argl, true); 	"IR" or "LR" =>		anchor(g, cmd[0:1], cmd[1:2], argl);		# includes man page refs ("IR" is old style, "LR" is new) 	"dS" =>		printargs(g, argl);		g.print("\n"); 	"1C" or "2C" or "DT" or "TF" =>	 # ignore these		return; 	"P" or "PP" or "LP" =>			g_PP(g); 	"EE" =>	g_EE(g);	"EX" =>	g_EX(g);	"HP" =>	g_HP_TP(g, 1);	"IP" =>	g_IP(g, argl);	"PD" =>	g_PD(g, argl);	"PM" =>	g_PM(g, argl);	"RE" =>	g_RE(g);

Lines 1–500 of 1328.