forsyth20121205-174063a80cc13 years agoHistory
1924 lines · 39.0 KB · Brainfuck
RawDownload
implement Cook; include "sys.m";	sys: Sys;	FD: import Sys; include "draw.m";	draw: Draw; include "bufio.m";	B: Bufio;	Iobuf: import B; include "string.m";	S: String;	splitl, splitr, splitstrl, drop, take, in, prefix, tolower : import S; include "brutus.m";	Size6, Size8, Size10, Size12, Size16, NSIZE,	Roman, Italic, Bold, Type, NFONT, NFONTTAG,	Example, Caption, List, Listelem, Label, Labelref,	Exercise, Heading, Nofill, Author, Title,	Index, Indextopic,	DefFont, DefSize, TitleFont, TitleSize, HeadingFont, HeadingSize: import Brutus; # following are needed for types in brutusext.minclude "tk.m";	tk: Tk;include "tkclient.m"; include "brutusext.m";	SGML, Text, Par, Extension, Float, Special, Celem,	FLatex, FLatexProc, FLatexBook, FLatexPart, FLatexSlides, FHtml: import Brutusext; include "strinttab.m";	T: StringIntTab; Cook: module{	init:	fn(ctxt: ref Draw->Context, args: list of string);}; # keep this sorted by nametagstringtab := array[] of { T->StringInt	("Author", Author),	("Bold.10", Bold*NSIZE + Size10),	("Bold.12", Bold*NSIZE + Size12),	("Bold.16", Bold*NSIZE + Size16),	("Bold.6", Bold*NSIZE + Size6),	("Bold.8", Bold*NSIZE + Size8),	("Caption", Caption),	("Example", Example),	("Exercise", Exercise),	("Extension", Extension),	("Float", Float),	("Heading", Heading),	("Index", Index),	("Index-topic", Indextopic),	("Italic.10", Italic*NSIZE + Size10),	("Italic.12", Italic*NSIZE + Size12),	("Italic.16", Italic*NSIZE + Size16),	("Italic.6", Italic*NSIZE + Size6),	("Italic.8", Italic*NSIZE + Size8),	("Label", Label),	("Label-ref", Labelref),	("List", List),	("List-elem", Listelem),	("No-fill", Nofill),	("Par", Par),	("Roman.10", Roman*NSIZE + Size10),	("Roman.12", Roman*NSIZE + Size12),	("Roman.16", Roman*NSIZE + Size16),	("Roman.6", Roman*NSIZE + Size6),	("Roman.8", Roman*NSIZE + Size8),	("SGML", SGML),	("Title", Title),	("Type.10", Type*NSIZE + Size10),	("Type.12", Type*NSIZE + Size12),	("Type.16", Type*NSIZE + Size16),	("Type.6", Type*NSIZE + Size6),	("Type.8", Type*NSIZE + Size8),}; # This table must be sortedfmtstringtab := array[] of { T->StringInt	("html", FHtml),	("latex", FLatex),	("latexbook", FLatexBook),	("latexpart", FLatexPart),	("latexproc", FLatexProc),	("latexslides", FLatexSlides),}; Transtab: adt{	ch:		int;	trans:	string;}; # Order doesn't matter for these table ltranstab := array[] of { Transtab	('$', "\\textdollar{}"),	('&', "\\&"),	('%', "\\%"),	('#', "\\#"),	('_', "\\textunderscore{}"),	('{', "\\{"),	('}', "\\}"),	('~', "\\textasciitilde{}"),	('^', "\\textasciicircum{}"),	('\\', "\\textbackslash{}"),	('+', "\\textplus{}"),	('=', "\\textequals{}"),	('|', "\\textbar{}"),	('<', "\\textless{}"),	('>', "\\textgreater{}"),	(' ', "~"),	('-', "-"),  # needs special case ligature treatment	('\t', " "),   # needs special case treatment}; htranstab := array[] of { Transtab	('α', "&alpha;"),	('Æ', "&AElig;"),	('Á', "&Aacute;"),	('Â', "&Acirc;"),	('À', "&Agrave;"),	('Å', "&Aring;"),	('Ã', "&Atilde;"),	('Ä', "&Auml;"),	('Ç', "&Ccedil;"),	('Ð', "&ETH;"),	('É', "&Eacute;"),	('Ê', "&Ecirc;"),	('È', "&Egrave;"),	('Ë', "&Euml;"),	('Í', "&Iacute;"),	('Î', "&Icirc;"),	('Ì', "&Igrave;"),	('Ï', "&Iuml;"),	('Ñ', "&Ntilde;"),	('Ó', "&Oacute;"),	('Ô', "&Ocirc;"),	('Ò', "&Ograve;"),	('Ø', "&Oslash;"),	('Õ', "&Otilde;"),	('Ö', "&Ouml;"),	('Þ', "&THORN;"),	('Ú', "&Uacute;"),	('Û', "&Ucirc;"),	('Ù', "&Ugrave;"),	('Ü', "&Uuml;"),	('Ý', "&Yacute;"),	('æ', "&aElig;"),	('á', "&aacute;"),	('â', "&acirc;"),	('à', "&agrave;"),	('α', "&alpha;"),	('&', "&amp;"),	('å', "&aring;"),	('ã', "&atilde;"),	('ä', "&auml;"),	('β', "&beta;"),	('ç', "&ccedil;"),	('⋯', "&cdots;"),	('χ', "&chi;"),	('©', "&copy;"),	('⋱', "&ddots;"),	('δ', "&delta;"),	('é', "&eacute;"),	('ê', "&ecirc;"),	('è', "&egrave;"),	('—', "&emdash;"),	(' ', "&emsp;"),	('–', "&endash;"),	('ε', "&epsilon;"),	('η', "&eta;"),	('ð', "&eth;"),	('ë', "&euml;"),	('γ', "&gamma;"),	('>', "&gt;"),	('í', "&iacute;"),	('î', "&icirc;"),	('ì', "&igrave;"),	('ι', "&iota;"),	('ï', "&iuml;"),	('κ', "&kappa;"),	('λ', "&lambda;"),	('…', "&ldots;"),	('<', "&lt;"),	('μ', "&mu;"),	(' ', "&nbsp;"),	('ñ', "&ntilde;"),	('ν', "&nu;"),	('ó', "&oacute;"),	('ô', "&ocirc;"),	('ò', "&ograve;"),	('ω', "&omega;"),	('ο', "&omicron;"),	('ø', "&oslash;"),	('õ', "&otilde;"),	('ö', "&ouml;"),	('φ', "&phi;"),	('π', "&pi;"),	('ψ', "&psi;"),	(' ', "&quad;"),	('"', "&quot;"),	('®', "&reg;"),	('ρ', "&rho;"),	('­', "&shy;"),	('σ', "&sigma;"),	('ß', "&szlig;"),	('τ', "&tau;"),	('θ', "&theta;"),	(' ', "&thinsp;"),	('þ', "&thorn;"),	('™', "&trade;"),	('ú', "&uacute;"),	('û', "&ucirc;"),	('ù', "&ugrave;"),	('υ', "&upsilon;"),	('ü', "&uuml;"),	('∈', "&varepsilon;"),	('ϕ', "&varphi;"),	('ϖ', "&varpi;"),	('ϱ', "&varrho;"),	('⋮', "&vdots;"),	('ς', "&vsigma;"),	('ϑ', "&vtheta;"),	('ξ', "&xi;"),	('ý', "&yacute;"),	('ÿ', "&yuml;"),	('ζ', "&zeta;"),	('−', "-"),}; # For speedy lookups of ascii char translation, use asciitrans.# It should be initialized by ascii elements from one of above tablesasciitrans := array[128] of string; stderr: ref FD;infilename := "";outfilename := "";linenum := 0;fin : ref Iobuf = nil;fout : ref Iobuf = nil;debug := 0;fmt := FLatex; init(nil: ref Draw->Context, argv: list of string){	sys = load Sys Sys->PATH;	S = load String String->PATH;	B = load Bufio Bufio->PATH;	draw = load Draw Draw->PATH;	tk = load Tk Tk->PATH;	T = load StringIntTab StringIntTab->PATH;	stderr = sys->fildes(2); 	for(argv = tl argv; argv != nil; ) {		s := hd argv;		tlargv := tl argv;		case s {		"-f" =>			if(tlargv == nil)				usage();			fnd: int;			(fnd, fmt) = T->lookup(fmtstringtab, hd(tlargv));			if(!fnd) {				sys->fprint(stderr, "unknown format: %s\n", hd(tlargv));				exit;			}			argv = tlargv;		"-o" =>			if(tlargv == nil)				usage();			outfilename = hd(tlargv);			argv = tlargv;		"-d" =>			debug = 1;		"-dd" =>			debug = 2;		* =>			if(tlargv == nil)				infilename = s;			else				usage();		}		argv = tl argv;	}	if(infilename == "") {		fin = B->fopen(sys->fildes(0), sys->OREAD);		infilename = "<stdin>";	}	else		fin = B->open(infilename, sys->OREAD);	if(fin == nil) {		sys->fprint(stderr, "cook: error opening %s: %r\n", infilename);		exit;	}	if(outfilename == "") {		fout = B->fopen(sys->fildes(1), sys->OWRITE);		outfilename = "<stdout>";	}	else		fout = B->create(outfilename, sys->OWRITE, 8r664);	if(fout == nil) {		sys->fprint(stderr, "cook: error creating %s: %r\n", outfilename);		exit;	}	line0 := fin.gets('\n');	if(line0 != "<SGML>\n") {		parse_err("not an SGML file\n");		exit;	}	linenum = 1;	e := parse(SGML);	findpars(e, 1, nil);	e = delemptystrs(e);	(e, nil) = canonfonts(e, DefFont*NSIZE+DefSize, DefFont*NSIZE+DefSize);	mergeadjs(e);	findfloats(e);	cleanexts(e);	cleanpars(e);	if(debug) {		fout.puts("After Initial transformations:\n");		printelem(e, "", 1);		fout.flush();	}	case fmt {	FLatex or FLatexProc or FLatexBook or FLatexPart or FLatexSlides =>		latexconv(e);	FHtml =>		htmlconv(e);	}	fin.close();	fout.close();} usage(){	sys->fprint(stderr, "Usage: cook [-f (latex|html)] [-o outfile] [infile]\n");	exit;} parse_err(msg: string){	sys->fprint(stderr, "%s:%d: %s\n", infilename, linenum, msg);} # Parse into elements.# Assumes tags are balanced.# String elements are split so that there is never an internal newline.parse(id: int) : ref Celem{	els : ref Celem = nil;	elstail : ref Celem = nil;	for(;;) {		c := fin.getc();		if(c == Bufio->EOF) {			if(id == SGML)				break;			else {				parse_err(sys->sprint("EOF while parsing %s", tagname(id)));				return nil;			}		}		if(c == '<') {			tag := "";			start := 1;			i := 0;			for(;;) {				c = fin.getc();				if(c == Bufio->EOF) {					parse_err("EOF in middle of tag");					return nil;				}				if(c == '\n') {					linenum++;					parse_err("newline in middle of tag");					break;				}				if(c == '>')					break;				if(i == 0 && c == '/')					start = 0;				else					tag[i++] = c;			}			(fnd, tid) := T->lookup(tagstringtab, tag);			if(!fnd) {				if(prefix("Extension ", tag)) {					el := ref Celem(Extension, tag[10:], nil, nil, nil, nil);					if(els == nil) {						els = el;						elstail = el;					}					else {						el.prev = elstail;						elstail.next = el;						elstail = el;					}				}				else					parse_err(sys->sprint("unknown tag <%s>\n", tag));				continue;			}			if(start) {				el := parse(tid);				if(el == nil)					return nil;				if(els == nil) {					els = el;					elstail = el;				}				else {					el.prev = elstail;					elstail.next = el;					elstail = el;				}			}			else {				if(tid != id) {					parse_err(sys->sprint("<%s> ended by </%s>",						tagname(id), tag));					continue;				}				break;			}		}		else {			s := "";			i := 0;			for(;;) {				if(c == Bufio->EOF)					break;				if(c == '<') {					fin.ungetc();					break;				}				if(c == ';' && i >=3 && s[i-1] == 't' && s[i-2] == 'l' && s[i-3] == '&') {					i -= 2;					s[i-1] = '<';					s = s[0:i];				}				else					s[i++] = c;				if(c == '\n') {					linenum++;					break;				}				else					c = fin.getc();			}			if(s != "") {				el := ref Celem(Text, s, nil, nil, nil, nil);				if(els == nil) {					els = el;					elstail = el;				}				else {					el.prev = elstail;					elstail.next = el;					elstail = el;				}			}		}	}	ans := ref Celem(id, "", els, nil, nil, nil);	if(els != nil)		els.parent = ans;	return ans;} # Modify tree e so that blank lines become Par elements.# Only do it if parize is set, and unset parize when descending into TExample's.# Pass in most recent TString or TPar element, and return updated most-recent-TString/TPar.# This function may set some TString strings to ""findpars(e: ref Celem, parize: int, prevspe: ref Celem) : ref Celem{	while(e != nil) {		prevnl := 0;		prevpar := 0;		if(prevspe != nil) {			if(prevspe.tag == Text && len prevspe.s != 0			   && prevspe.s[(len prevspe.s)-1] == '\n')				prevnl = 1;			else if(prevspe.tag == Par)				prevpar = 1;		}		if(e.tag == Text) {			if(parize && (prevnl || prevpar) && e.s[0] == '\n') {				if(prevnl)					prevspe.s = prevspe.s[0 : (len prevspe.s)-1];				e.tag = Par;				e.s = nil;			}			prevspe = e;		}

Lines 1–500 of 1924.