#include <u.h>
#include <libc.h>
#include <draw.h>
#include <ctype.h>
#include <html.h>
#include "impl.h"

// A stack for holding integer values
enum {
	Nestmax = 40	// max nesting level of lists, font styles, etc.
};

struct Stack {
	int		n;				// next available slot (top of stack is stack[n-1])
	int		slots[Nestmax];	// stack entries
};

// Parsing state
struct Pstate
{
	Pstate*	next;			// in stack of Pstates
	int		skipping;		// true when we shouldn't add items
	int		skipwhite;		// true when we should strip leading space
	int		curfont;		// font index for current font
	int		curfg;		// current foreground color
	Background	curbg;	// current background
	int		curvoff;		// current baseline offset
	uchar	curul;		// current underline/strike state
	uchar	curjust;		// current justify state
	int		curanchor;	// current (href) anchor id (if in one), or 0
	int		curstate;		// current value of item state
	int		literal;		// current literal state
	int		inpar;		// true when in a paragraph-like construct
	int		adjsize;		// current font size adjustment
	Item*	items;		// dummy head of item list we're building
	Item*	lastit;		// tail of item list we're building
	Item*	prelastit;		// item before lastit
	Stack	fntstylestk;	// style stack
	Stack	fntsizestk;		// size stack
	Stack	fgstk;		// text color stack
	Stack	ulstk;		// underline stack
	Stack	voffstk;		// vertical offset stack
	Stack	listtypestk;	// list type stack
	Stack	listcntstk;		// list counter stack
	Stack	juststk;		// justification stack
	Stack	hangstk;		// hanging stack
};

struct ItemSource
{
	Docinfo*		doc;
	Pstate*		psstk;
	int			nforms;
	int			ntables;
	int			nanchors;
	int			nframes;
	Form*		curform;
	Map*		curmap;
	Table*		tabstk;
	Kidinfo*		kidstk;
};

// Some layout parameters
enum {
	FRKIDMARGIN = 6,	// default margin around kid frames
	IMGHSPACE = 0,	// default hspace for images (0 matches IE, Netscape)
	IMGVSPACE = 0,	// default vspace for images
	FLTIMGHSPACE = 2,	// default hspace for float images
	TABSP = 5,		// default cellspacing for tables
	TABPAD = 1,		// default cell padding for tables
	LISTTAB = 1,		// number of tabs to indent lists
	BQTAB = 1,		// number of tabs to indent blockquotes
	HRSZ = 2,			// thickness of horizontal rules
	SUBOFF = 4,		// vertical offset for subscripts
	SUPOFF = 6,		// vertical offset for superscripts
	NBSP = 160		// non-breaking space character
};

// These tables must be sorted
static StringInt *align_tab;
static AsciiInt _align_tab[] = {
	{"baseline",	ALbaseline},
	{"bottom",	ALbottom},
	{"center",	ALcenter},
	{"char",		ALchar},
	{"justify",	ALjustify},
	{"left",		ALleft},
	{"middle",	ALmiddle},
	{"right",		ALright},
	{"top",		ALtop}
};
#define NALIGNTAB (sizeof(align_tab)/sizeof(StringInt))

static StringInt *input_tab;
static AsciiInt _input_tab[] = {
	{"button",	Fbutton},
	{"checkbox",	Fcheckbox},
	{"file",		Ffile},
	{"hidden",	Fhidden},
	{"image",	Fimage},
	{"password",	Fpassword},
	{"radio",		Fradio},
	{"reset",		Freset},
	{"submit",	Fsubmit},
	{"text",		Ftext}
};
#define NINPUTTAB (sizeof(input_tab)/sizeof(StringInt))

static StringInt *clear_tab;
static AsciiInt _clear_tab[] = {
	{"all",	IFcleft|IFcright},
	{"left",	IFcleft},
	{"right",	IFcright}
};
#define NCLEARTAB (sizeof(clear_tab)/sizeof(StringInt))

static StringInt *fscroll_tab;
static AsciiInt _fscroll_tab[] = {
	{"auto",	FRhscrollauto|FRvscrollauto},
	{"no",	FRnoscroll},
	{"yes",	FRhscroll|FRvscroll},
};
#define NFSCROLLTAB (sizeof(fscroll_tab)/sizeof(StringInt))

static StringInt *shape_tab;
static AsciiInt _shape_tab[] = {
	{"circ",		SHcircle},
	{"circle",		SHcircle},
	{"poly",		SHpoly},
	{"polygon",	SHpoly},
	{"rect",		SHrect},
	{"rectangle",	SHrect}
};
#define NSHAPETAB (sizeof(shape_tab)/sizeof(StringInt))

static StringInt *method_tab;
static AsciiInt _method_tab[] = {
	{"get",		HGet},
	{"post",		HPost}
};
#define NMETHODTAB (sizeof(method_tab)/sizeof(StringInt))

static Rune** roman;
static char* _roman[15]= {
	"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X",
	"XI", "XII", "XIII", "XIV", "XV"
};
#define NROMAN 15

// List number types
enum {
	LTdisc, LTsquare, LTcircle, LT1, LTa, LTA, LTi, LTI
};

enum {
	SPBefore = 2,
	SPAfter = 4,
	BL = 1,
	BLBA = (BL|SPBefore|SPAfter)
};

// blockbrk[tag] is break info for a block level element, or one
// of a few others that get the same treatment re ending open paragraphs
// and requiring a line break / vertical space before them.
// If we want a line of space before the given element, SPBefore is OR'd in.
// If we want a line of space after the given element, SPAfter is OR'd in.

static uchar blockbrk[Numtags]= {
	[Taddress] BLBA, [Tblockquote] BLBA, [Tcenter] BL,
	[Tdir] BLBA, [Tdiv] BL, [Tdd] BL, [Tdl] BLBA,
	[Tdt] BL, [Tform] BLBA,
	// headings and tables get breaks added manually
	[Th1] BL, [Th2] BL, [Th3] BL,
	[Th4] BL, [Th5] BL, [Th6] BL,
	[Thr] BL, [Tisindex] BLBA, [Tli] BL, [Tmenu] BLBA,
	[Tol] BLBA, [Tp] BLBA, [Tpre] BLBA,
	[Tul] BLBA
};

enum {
	AGEN = 1
};

// attrinfo is information about attributes.
// The AGEN value means that the attribute is generic (applies to almost all elements)
static uchar attrinfo[Numattrs]= {
	[Aid] AGEN, [Aclass] AGEN, [Astyle] AGEN, [Atitle] AGEN,
	[Aonblur] AGEN, [Aonchange] AGEN, [Aonclick] AGEN,
	[Aondblclick] AGEN, [Aonfocus] AGEN, [Aonkeypress] AGEN,
	[Aonkeyup] AGEN, [Aonload] AGEN, [Aonmousedown] AGEN,
	[Aonmousemove] AGEN, [Aonmouseout] AGEN, [Aonmouseover] AGEN,
	[Aonmouseup] AGEN, [Aonreset] AGEN, [Aonselect] AGEN,
	[Aonsubmit] AGEN, [Aonunload] AGEN
};

static uchar scriptev[Numattrs]= {
	[Aonblur] SEonblur, [Aonchange] SEonchange, [Aonclick] SEonclick,
	[Aondblclick] SEondblclick, [Aonfocus] SEonfocus, [Aonkeypress] SEonkeypress,
	[Aonkeyup] SEonkeyup, [Aonload] SEonload, [Aonmousedown] SEonmousedown,
	[Aonmousemove] SEonmousemove, [Aonmouseout] SEonmouseout, [Aonmouseover] SEonmouseover,
	[Aonmouseup] SEonmouseup, [Aonreset] SEonreset, [Aonselect] SEonselect,
	[Aonsubmit] SEonsubmit, [Aonunload] SEonunload
};

// Color lookup table
static StringInt *color_tab;
static AsciiInt _color_tab[] = {
	{"aqua", 0x00FFFF},
	{"black",  0x000000},
	{"blue", 0x0000CC},
	{"fuchsia", 0xFF00FF},
	{"gray", 0x808080},
	{"green", 0x008000},
	{"lime", 0x00FF00},
	{"maroon", 0x800000},
	{"navy", 0x000080,},
	{"olive", 0x808000},
	{"purple", 0x800080},
	{"red", 0xFF0000},
	{"silver", 0xC0C0C0},
	{"teal", 0x008080},
	{"white", 0xFFFFFF},
	{"yellow", 0xFFFF00}
};
#define NCOLORS (sizeof(color_tab)/sizeof(StringInt))

static StringInt 		*targetmap;
static int			targetmapsize;
static int			ntargets;

static int buildinited = 0;

#define SMALLBUFSIZE 240
#define BIGBUFSIZE 2000

int	dbgbuild = 0;
int	warn = 0;

static Align		aalign(Token* tok);
static int			acolorval(Token* tok, int attid, int dflt);
static void			addbrk(Pstate* ps, int sp, int clr);
static void			additem(Pstate* ps, Item* it, Token* tok);
static void			addlinebrk(Pstate* ps, int clr);
static void			addnbsp(Pstate* ps);
static void			addtext(Pstate* ps, Rune* s);
static Dimen		adimen(Token* tok, int attid);
static int			aflagval(Token* tok, int attid);
static int			aintval(Token* tok, int attid, int dflt);
static Rune*		astrval(Token* tok, int attid, Rune* dflt);
static int			atabval(Token* tok, int attid, StringInt* tab, int ntab, int dflt);
static int			atargval(Token* tok, int dflt);
static int			auintval(Token* tok, int attid, int dflt);
static Rune*		aurlval(Token* tok, int attid, Rune* dflt, Rune* base);
static Rune*		aval(Token* tok, int attid);
static void			buildinit(void);
static Pstate*		cell_pstate(Pstate* oldps, int ishead);
static void			changehang(Pstate* ps, int delta);
static void			changeindent(Pstate* ps, int delta);
static int			color(Rune* s, int dflt);
static void			copystack(Stack* tostk, Stack* fromstk);
static int			dimprint(char* buf, int nbuf, Dimen d);
static Pstate*		finishcell(Table* curtab, Pstate* psstk);
static void			finish_table(Table* t);
static void			freeanchor(Anchor* a);
static void			freedestanchor(DestAnchor* da);
static void			freeform(Form* f);
static void			freeformfield(Formfield* ff);
static void			freeitem(Item* it);
static void			freepstate(Pstate* p);
static void			freepstatestack(Pstate* pshead);
static void			freescriptevents(SEvent* ehead);
static void			freetable(Table* t);
static Map*		getmap(Docinfo* di, Rune* name);
static Rune*		getpcdata(Token* toks, int tokslen, int* ptoki);
static Pstate*		lastps(Pstate* psl);
static Rune*		listmark(uchar ty, int n);
static int			listtyval(Token* tok, int dflt);
static Align		makealign(int halign, int valign);
static Background	makebackground(Rune* imgurl, int color);
static Dimen		makedimen(int kind, int spec);
static Anchor*		newanchor(int index, Rune* name, Rune* href, int target, Anchor* link);
static Area*		newarea(int shape, Rune* href, int target, Area* link);
static DestAnchor*	newdestanchor(int index, Rune* name, Item* item, DestAnchor* link);
static Docinfo*		newdocinfo(void);
static Genattr*		newgenattr(Rune* id, Rune* class, Rune* style, Rune* title, SEvent* events);
static Form*		newform(int formid, Rune* name, Rune* action,
					int target, int method, Form* link);
static Formfield*	newformfield(int ftype, int fieldid, Form* form, Rune* name,
					Rune* value, int size, int maxlength, Formfield* link);
static Item*		newifloat(Item* it, int side);
static Item*		newiformfield(Formfield* ff);
static Item*		newiimage(Rune* src, Rune* altrep, int align, int width, int height,
					int hspace, int vspace, int border, int ismap, Map* map);
static Item*		newirule(int align, int size, int noshade, Dimen wspec);
static Item*		newispacer(int spkind);
static Item*		newitable(Table* t);
static ItemSource*	newitemsource(Docinfo* di);
static Item*		newitext(Rune* s, int fnt, int fg, int voff, int ul);
static Kidinfo*		newkidinfo(int isframeset, Kidinfo* link);
static Option*		newoption(int selected, Rune* value, Rune* display, Option* link);
static Pstate*		newpstate(Pstate* link);
static SEvent*		newscriptevent(int type, Rune* script, SEvent* link);
static Table*		newtable(int tableid, Align align, Dimen width, int border,
					int cellspacing, int cellpadding, Background bg, Token* tok, Table* link);
static Tablecell*	newtablecell(int cellid, int rowspan, int colspan, Align align, Dimen wspec,
					int hspec, Background bg, int flags, Tablecell* link);
static Tablerow*	newtablerow(Align align, Background bg, int flags, Tablerow* link);
static Dimen		parsedim(Rune* s, int ns);
static void			pop(Stack* stk);
static void			popfontsize(Pstate* ps);
static void			popfontstyle(Pstate* ps);
static void			popjust(Pstate* ps);
static int			popretnewtop(Stack* stk, int dflt);
static int			push(Stack* stk, int val);
static void			pushfontsize(Pstate* ps, int sz);
static void			pushfontstyle(Pstate* ps, int sty);
static void			pushjust(Pstate* ps, int j);
static Item*		textit(Pstate* ps, Rune* s);
static Rune*		removeallwhite(Rune* s);
static void			resetdocinfo(Docinfo* d);
static void			setcurfont(Pstate* ps);
static void			setcurjust(Pstate* ps);
static void			setdimarray(Token* tok, int attid, Dimen** pans, int* panslen);
static Rune*		stringalign(int a);
static void			targetmapinit(void);
static int			toint(Rune* s);
static int			top(Stack* stk, int dflt);
static void			trim_cell(Tablecell* c);
static int			validalign(Align a);
static int			validdimen(Dimen d);
static int			validformfield(Formfield* f);
static int			validhalign(int a);
static int			validptr(void* p);
static int			validStr(Rune* s);
static int			validtable(Table* t);
static int			validtablerow(Tablerow* r);
static int			validtablecol(Tablecol* c);
static int			validtablecell(Tablecell* c);
static int			validvalign(int a);
static int			Iconv(Fmt *f);

static void
buildinit(void)
{
	runetabinit();
	roman = cvtstringtab(_roman, nelem(_roman));
	color_tab = cvtstringinttab(_color_tab, nelem(_color_tab));
	method_tab = cvtstringinttab(_method_tab, nelem(_method_tab));
	shape_tab = cvtstringinttab(_shape_tab, nelem(_shape_tab));
	fscroll_tab = cvtstringinttab(_fscroll_tab, nelem(_fscroll_tab));
	clear_tab = cvtstringinttab(_clear_tab, nelem(_clear_tab));
	input_tab = cvtstringinttab(_input_tab, nelem(_input_tab));
	align_tab = cvtstringinttab(_align_tab, nelem(_align_tab));

	fmtinstall('I', Iconv);
	targetmapinit();
	buildinited = 1;
}

static ItemSource*
newitemsource(Docinfo* di)
{
	ItemSource*	is;
	Pstate*	ps;

	ps = newpstate(nil);
	if(di->mediatype != TextHtml) {
		ps->curstate &= ~IFwrap;
		ps->literal = 1;
		pushfontstyle(ps, FntT);
	}
	is = (ItemSource*)emalloc(sizeof(ItemSource));
	is->doc = di;
	is->psstk = ps;
	is->nforms = 0;
	is->ntables = 0;
	is->nanchors = 0;
	is->nframes = 0;
	is->curform = nil;
	is->curmap = nil;
	is->tabstk = nil;
	is->kidstk = nil;
	return is;
}

static Item *getitems(ItemSource* is, uchar* data, int datalen);

// Parse an html document and create a list of layout items.
// Allocate and return document info in *pdi.
// When caller is done with the items, it should call
// freeitems on the returned result, and then
// freedocinfo(*pdi).
Item*
parsehtml(uchar* data, int datalen, Rune* pagesrc, int mtype, int chset, Docinfo** pdi)
{
	Item *it;
	Docinfo*	di;
	ItemSource*	is;

	di = newdocinfo();
	di->src = _Strdup(pagesrc);
	di->base = _Strdup(pagesrc);
	di->mediatype = mtype;
	di->chset = chset;
	*pdi = di;
	is = newitemsource(di);
	it = getitems(is, data, datalen);
	freepstatestack(is->psstk);
	free(is);
	return it;
}

// Get a group of tokens for lexer, parse them, and create
// a list of layout items.
// When caller is done with the items, it should call
// freeitems on the returned result.
static Item*
getitems(ItemSource* is, uchar* data, int datalen)
{
	int	i;
	int	j;
	int	nt;
	int	pt;
	int	doscripts;
	int	tokslen;
	int	toki;
	int	h;
	int	sz;
	int	method;
	int	n;
	int	nblank;
	int	norsz;
	int	bramt;
	int	sty;
	int	nosh;
	int	oldcuranchor;
	int	dfltbd;
	int	v;
	int	hang;
	int	isempty;
	int	tag;
	int	brksp;
	int	target;
	uchar	brk;
	uchar	flags;
	uchar	align;
	uchar	al;
	uchar	ty;
	uchar	ty2;
	Pstate*	ps;
	Pstate*	nextps;
	Pstate*	outerps;
	Table*	curtab;
	Token*	tok;
	Token*	toks;
	Docinfo*	di;
	Item*	ans;
	Item*	img;
	Item*	ffit;
	Item*	tabitem;
	Rune*	s;
	Rune*	t;
	Rune*	name;
	Rune*	enctype;
	Rune*	usemap;
	Rune*	prompt;
	Rune*	equiv;
	Rune*	val;
	Rune*	nsz;
	Rune*	script;
	Map*	map;
	Form*	frm;
	Iimage*	ii;
	Kidinfo*	kd;
	Kidinfo*	ks;
	Kidinfo*	pks;
	Dimen	wd;
	Option*	option;
	Table*	tab;
	Tablecell*	c;
	Tablerow*	tr;
	Formfield*	field;
	Formfield*	ff;
	Rune*	href;
	Rune*	src;
	Rune*	scriptsrc;
	Rune*	bgurl;
	Rune*	action;
	Background	bg;

	if(!buildinited)
		buildinit();
	doscripts = 0;	// for now
	ps = is->psstk;
	curtab = is->tabstk;
	di = is->doc;
	toks = _gettoks(data, datalen, di->chset, di->mediatype, &tokslen);
	toki = 0;
	for(; toki < tokslen; toki++) {
		tok = &toks[toki];
		if(dbgbuild > 1)
			fprint(2, "build: curstate %ux, token %T\n", ps->curstate, tok);
		tag = tok->tag;
		brk = 0;
		brksp = 0;
		if(tag < Numtags) {
			brk = blockbrk[tag];
			if(brk&SPBefore)
				brksp = 1;
		}
		else if(tag < Numtags + RBRA) {
			brk = blockbrk[tag - RBRA];
			if(brk&SPAfter)
				brksp = 1;
		}
		if(brk) {
			addbrk(ps, brksp, 0);
			if(ps->inpar) {
				popjust(ps);
				ps->inpar = 0;
			}
		}
		// check common case first (Data), then switch statement on tag
		if(tag == Data) {
			// Lexing didn't pay attention to SGML record boundary rules:
			// \n after start tag or before end tag to be discarded.
			// (Lex has already discarded all \r's).
			// Some pages assume this doesn't happen in <PRE> text,
			// so we won't do it if literal is true.
			// BUG: won't discard \n before a start tag that begins
			// the next bufferful of tokens.
			s = tok->text;
			n = _Strlen(s);
			if(!ps->literal) {
				i = 0;
				j = n;
				if(toki > 0) {
					pt = toks[toki - 1].tag;
					// IE and Netscape both ignore this rule (contrary to spec)
					// if previous tag was img
					if(pt < Numtags && pt != Timg && j > 0 && s[0] == '\n')
						i++;
				}
				if(toki < tokslen - 1) {
					nt = toks[toki + 1].tag;
					if(nt >= RBRA && nt < Numtags + RBRA && j > i && s[j - 1] == '\n')
						j--;
				}
				if(i > 0 || j < n) {
					t = s;
					s = _Strsubstr(s, i, j);
					free(t);
					n = j-i;
				}
			}
			if(ps->skipwhite) {
				_trimwhite(s, n, &t, &nt);
				if(t == nil) {
					free(s);
					s = nil;
				}
				else if(t != s) {
					t = _Strndup(t, nt);
					free(s);
					s = t;
				}
				if(s != nil)
					ps->skipwhite = 0;
			}
			tok->text = nil;		// token doesn't own string anymore
			if(s != nil)
				addtext(ps, s);
		}
		else
			switch(tag) {
			// Some abbrevs used in following DTD comments
			// %text = 	#PCDATA
			//		| TT | I | B | U | STRIKE | BIG | SMALL | SUB | SUP
			//		| EM | STRONG | DFN | CODE | SAMP | KBD | VAR | CITE
			//		| A | IMG | APPLET | FONT | BASEFONT | BR | SCRIPT | MAP
			//		| INPUT | SELECT | TEXTAREA
			// %block = P | UL | OL | DIR | MENU | DL | PRE | DL | DIV | CENTER
			//		| BLOCKQUOTE | FORM | ISINDEX | HR | TABLE
			// %flow = (%text | %block)*
			// %body.content = (%heading | %text | %block | ADDRESS)*

			// <!ELEMENT A - - (%text) -(A)>
			// Anchors are not supposed to be nested, but you sometimes see
			// href anchors inside destination anchors.
			case Ta:
				if(ps->curanchor != 0) {
					if(warn)
						fprint(2, "warning: nested <A> or missing </A>\n");
					ps->curanchor = 0;
				}
				name = aval(tok, Aname);
				href = aurlval(tok, Ahref, nil, di->base);
				// ignore rel, rev, and title attrs
				if(href != nil) {
					target = atargval(tok, di->target);
					di->anchors = newanchor(++is->nanchors, name, href, target, di->anchors);
					if(name != nil)
						name = _Strdup(name);	// for DestAnchor construction, below
					ps->curanchor = is->nanchors;
					ps->curfg = push(&ps->fgstk, di->link);
					ps->curul = push(&ps->ulstk, ULunder);
				}
				if(name != nil) {
					// add a null item to be destination
					additem(ps, newispacer(ISPnull), tok);
					di->dests = newdestanchor(++is->nanchors, name, ps->lastit, di->dests);
				}
				break;

			case Ta+RBRA :
				if(ps->curanchor != 0) {
					ps->curfg = popretnewtop(&ps->fgstk, di->text);
					ps->curul = popretnewtop(&ps->ulstk, ULnone);
					ps->curanchor = 0;
				}
				break;

			// <!ELEMENT APPLET - - (PARAM | %text)* >
			// We can't do applets, so ignore PARAMS, and let
			// the %text contents appear for the alternative rep
			case Tapplet:
			case Tapplet+RBRA:
				if(warn && tag == Tapplet)
					fprint(2, "warning: <APPLET> ignored\n");
				break;

			// <!ELEMENT AREA - O EMPTY>
			case Tarea:
				map = di->maps;
				if(map == nil) {
					if(warn)
						fprint(2, "warning: <AREA> not inside <MAP>\n");
					continue;
				}
				map->areas = newarea(atabval(tok, Ashape, shape_tab, NSHAPETAB, SHrect),
					aurlval(tok, Ahref, nil, di->base),
					atargval(tok, di->target),
					map->areas);
				setdimarray(tok, Acoords, &map->areas->coords, &map->areas->ncoords);
				break;

			// <!ELEMENT (B|STRONG) - - (%text)*>
			case Tb:
			case Tstrong:
				pushfontstyle(ps, FntB);
				break;

			case Tb+RBRA:
			case Tcite+RBRA:
			case Tcode+RBRA:
			case Tdfn+RBRA:
			case Tem+RBRA:
			case Tkbd+RBRA:
			case Ti+RBRA:
			case Tsamp+RBRA:
			case Tstrong+RBRA:
			case Ttt+RBRA:
			case Tvar+RBRA :
			case Taddress+RBRA:
				popfontstyle(ps);
				break;

			// <!ELEMENT BASE - O EMPTY>
			case Tbase:
				t = di->base;
				di->base = aurlval(tok, Ahref, di->base, di->base);
				if(t != nil)
					free(t);
				di->target = atargval(tok, di->target);
				break;

			// <!ELEMENT BASEFONT - O EMPTY>
			case Tbasefont:
				ps->adjsize = aintval(tok, Asize, 3) - 3;
				break;

			// <!ELEMENT (BIG|SMALL) - - (%text)*>
			case Tbig:
			case Tsmall:
				sz = ps->adjsize;
				if(tag == Tbig)
					sz += Large;
				else
					sz += Small;
				pushfontsize(ps, sz);
				break;

			case Tbig+RBRA:
			case Tsmall+RBRA:
				popfontsize(ps);
				break;

			// <!ELEMENT BLOCKQUOTE - - %body.content>
			case Tblockquote:
				changeindent(ps, BQTAB);
				break;

			case Tblockquote+RBRA:
				changeindent(ps, -BQTAB);
				break;

			// <!ELEMENT BODY O O %body.content>
			case Tbody:
				ps->skipping = 0;
				bg = makebackground(nil, acolorval(tok, Abgcolor, di->background.color));
				bgurl = aurlval(tok, Abackground, nil, di->base);
				if(bgurl != nil) {
					if(di->backgrounditem != nil)
						freeitem((Item*)di->backgrounditem);
						// really should remove old item from di->images list,
						// but there should only be one BODY element ...
					di->backgrounditem = (Iimage*)newiimage(bgurl, nil, ALnone, 0, 0, 0, 0, 0, 0, nil);
					di->backgrounditem->nextimage = di->images;
					di->images = di->backgrounditem;
				}
				ps->curbg = bg;
				di->background = bg;
				di->text = acolorval(tok, Atext, di->text);
				di->link = acolorval(tok, Alink, di->link);
				di->vlink = acolorval(tok, Avlink, di->vlink);
				di->alink = acolorval(tok, Aalink, di->alink);
				if(di->text != ps->curfg) {
					ps->curfg = di->text;
					ps->fgstk.n = 0;
				}
				break;

			case Tbody+RBRA:
				// HTML spec says ignore things after </body>,
				// but IE and Netscape don't
				// ps.skipping = 1;
				break;

			// <!ELEMENT BR - O EMPTY>
			case Tbr:
				addlinebrk(ps, atabval(tok, Aclear, clear_tab, NCLEARTAB, 0));
				break;

			// <!ELEMENT CAPTION - - (%text;)*>
			case Tcaption:
				if(curtab == nil) {
					if(warn)
						fprint(2, "warning: <CAPTION> outside <TABLE>\n");
					continue;
				}
				if(curtab->caption != nil) {
					if(warn)
						fprint(2, "warning: more than one <CAPTION> in <TABLE>\n");
					continue;
				}
				ps = newpstate(ps);
				curtab->caption_place = atabval(tok, Aalign, align_tab, NALIGNTAB, ALtop);
				break;

			case Tcaption+RBRA:
				nextps = ps->next;
				if(curtab == nil || nextps == nil) {
					if(warn)
						fprint(2, "warning: unexpected </CAPTION>\n");
					continue;
				}
				curtab->caption = ps->items->next;
				free(ps);
				ps = nextps;
				break;

			case Tcenter:
			case Tdiv:
				if(tag == Tcenter)
					al = ALcenter;
				else
					al = atabval(tok, Aalign, align_tab, NALIGNTAB, ps->curjust);
				pushjust(ps, al);
				break;

			case Tcenter+RBRA:
			case Tdiv+RBRA:
				popjust(ps);
				break;

			// <!ELEMENT DD - O  %flow >
			case Tdd:
				if(ps->hangstk.n == 0) {
					if(warn)
						fprint(2, "warning: <DD> not inside <DL\n");
					continue;
				}
				h = top(&ps->hangstk, 0);
				if(h != 0)
					changehang(ps, -10*LISTTAB);
				else
					addbrk(ps, 0, 0);
				push(&ps->hangstk, 0);
				break;

			//<!ELEMENT (DIR|MENU) - - (LI)+ -(%block) >
			//<!ELEMENT (OL|UL) - - (LI)+>
			case Tdir:
			case Tmenu:
			case Tol:
			case Tul:
				changeindent(ps, LISTTAB);
				push(&ps->listtypestk, listtyval(tok, (tag==Tol)? LT1 : LTdisc));
				push(&ps->listcntstk, aintval(tok, Astart, 1));
				break;

			case Tdir+RBRA:
			case Tmenu+RBRA:
			case Tol+RBRA:
			case Tul+RBRA:
				if(ps->listtypestk.n == 0) {
					if(warn)
						fprint(2, "warning: %T ended no list\n", tok);
					continue;
				}
				addbrk(ps, 0, 0);
				pop(&ps->listtypestk);
				pop(&ps->listcntstk);
				changeindent(ps, -LISTTAB);
				break;

			// <!ELEMENT DL - - (DT|DD)+ >
			case Tdl:
				changeindent(ps, LISTTAB);
				push(&ps->hangstk, 0);
				break;

			case Tdl+RBRA:
				if(ps->hangstk.n == 0) {
					if(warn)
						fprint(2, "warning: unexpected </DL>\n");
					continue;
				}
				changeindent(ps, -LISTTAB);
				if(top(&ps->hangstk, 0) != 0)
					changehang(ps, -10*LISTTAB);
				pop(&ps->hangstk);
				break;

			// <!ELEMENT DT - O (%text)* >
			case Tdt:
				if(ps->hangstk.n == 0) {
					if(warn)
						fprint(2, "warning: <DT> not inside <DL>\n");
					continue;
				}
				h = top(&ps->hangstk, 0);
				pop(&ps->hangstk);
				if(h != 0)
					changehang(ps, -10*LISTTAB);
				changehang(ps, 10*LISTTAB);
				push(&ps->hangstk, 1);
				break;

			// <!ELEMENT FONT - - (%text)*>
			case Tfont:
				sz = top(&ps->fntsizestk, Normal);
				if(_tokaval(tok, Asize, &nsz, 0)) {
					if(_prefix(L(Lplus), nsz))
						sz = Normal + _Strtol(nsz+1, nil, 10) + ps->adjsize;
					else if(_prefix(L(Lminus), nsz))
						sz = Normal - _Strtol(nsz+1, nil, 10) + ps->adjsize;
					else if(nsz != nil)
						sz = Normal + (_Strtol(nsz, nil, 10) - 3);
				}
				ps->curfg = push(&ps->fgstk, acolorval(tok, Acolor, ps->curfg));
				pushfontsize(ps, sz);
				break;

			case Tfont+RBRA:
				if(ps->fgstk.n == 0) {
					if(warn)
						fprint(2, "warning: unexpected </FONT>\n");
					continue;
				}
				ps->curfg = popretnewtop(&ps->fgstk, di->text);
				popfontsize(ps);
				break;

			// <!ELEMENT FORM - - %body.content -(FORM) >
			case Tform:
				if(is->curform != nil) {
					if(warn)
						fprint(2, "warning: <FORM> nested inside another\n");
					continue;
				}
				action = aurlval(tok, Aaction, di->base, di->base);
				s = aval(tok, Aid);
				name = astrval(tok, Aname, s);
				if(s)
					free(s);
				target = atargval(tok, di->target);
				method = atabval(tok, Amethod, method_tab, NMETHODTAB, HGet);
				if(warn && _tokaval(tok, Aenctype, &enctype, 0) &&
						_Strcmp(enctype, L(Lappl_form)))
					fprint(2, "form enctype %S not handled\n", enctype);
				frm = newform(++is->nforms, name, action, target, method, di->forms);
				di->forms = frm;
				is->curform = frm;
				break;

			case Tform+RBRA:
				if(is->curform == nil) {
					if(warn)
						fprint(2, "warning: unexpected </FORM>\n");
					continue;
				}
				// put fields back in input order
				is->curform->fields = (Formfield*)_revlist((List*)is->curform->fields);
				is->curform = nil;
				break;

			// <!ELEMENT FRAME - O EMPTY>
			case Tframe:
				ks = is->kidstk;
				if(ks == nil) {
					if(warn)
						fprint(2, "warning: <FRAME> not in <FRAMESET>\n");
					continue;
				}
				ks->kidinfos = kd = newkidinfo(0, ks->kidinfos);
				kd->src = aurlval(tok, Asrc, nil, di->base);
				kd->name = aval(tok, Aname);
				if(kd->name == nil) {
					s = _ltoStr(++is->nframes);
					kd->name = _Strdup2(L(Lfr), s);
					free(s);
				}
				kd->marginw = auintval(tok, Amarginwidth, 0);
				kd->marginh = auintval(tok, Amarginheight, 0);
				kd->framebd = auintval(tok, Aframeborder, 1);
				kd->flags = atabval(tok, Ascrolling, fscroll_tab, NFSCROLLTAB, kd->flags);
				norsz = aflagval(tok, Anoresize);
				if(norsz)
					kd->flags |= FRnoresize;
				break;

			// <!ELEMENT FRAMESET - - (FRAME|FRAMESET)+>
			case Tframeset:
				ks = newkidinfo(1, nil);
				pks = is->kidstk;
				if(pks == nil)
					di->kidinfo = ks;
				else  {
					ks->next = pks->kidinfos;
					pks->kidinfos = ks;
				}
				ks->nextframeset = pks;
				is->kidstk = ks;
				setdimarray(tok, Arows, &ks->rows, &ks->nrows);
				if(ks->nrows == 0) {
					ks->rows = (Dimen*)emalloc(sizeof(Dimen));
					ks->nrows = 1;
					ks->rows[0] = makedimen(Dpercent, 100);
				}
				setdimarray(tok, Acols, &ks->cols, &ks->ncols);
				if(ks->ncols == 0) {
					ks->cols = (Dimen*)emalloc(sizeof(Dimen));
					ks->ncols = 1;
					ks->cols[0] = makedimen(Dpercent, 100);
				}
				break;

			case Tframeset+RBRA:
				if(is->kidstk == nil) {
					if(warn)
						fprint(2, "warning: unexpected </FRAMESET>\n");
					continue;
				}
				ks = is->kidstk;
				// put kids back in original order
				// and add blank frames to fill out cells
				n = ks->nrows*ks->ncols;
				nblank = n - _listlen((List*)ks->kidinfos);
				while(nblank-- > 0)
					ks->kidinfos = newkidinfo(0, ks->kidinfos);
				ks->kidinfos = (Kidinfo*)_revlist((List*)ks->kidinfos);
				is->kidstk = is->kidstk->nextframeset;
				if(is->kidstk == nil) {
					// end input
					ans = nil;
					goto return_ans;
				}
				break;

			// <!ELEMENT H1 - - (%text;)*>, etc.
			case Th1:
			case Th2:
			case Th3:
			case Th4:
			case Th5:
			case Th6:
				bramt = 1;
				if(ps->items == ps->lastit)
					bramt = 0;
				addbrk(ps, bramt, IFcleft|IFcright);
				sz = Verylarge - (tag - Th1);
				if(sz < Tiny)
					sz = Tiny;
				pushfontsize(ps, sz);
				sty = top(&ps->fntstylestk, FntR);
				if(tag == Th1)
					sty = FntB;
				pushfontstyle(ps, sty);
				pushjust(ps, atabval(tok, Aalign, align_tab, NALIGNTAB, ps->curjust));
				ps->skipwhite = 1;
				break;

			case Th1+RBRA:
			case Th2+RBRA:
			case Th3+RBRA:
			case Th4+RBRA:
			case Th5+RBRA:
			case Th6+RBRA:
				addbrk(ps, 1, IFcleft|IFcright);
				popfontsize(ps);
				popfontstyle(ps);
				popjust(ps);
				break;

			case Thead:
				// HTML spec says ignore regular markup in head,
				// but Netscape and IE don't
				// ps.skipping = 1;
				break;

			case Thead+RBRA:
				ps->skipping = 0;
				break;

			// <!ELEMENT HR - O EMPTY>
			case Thr:
				al = atabval(tok, Aalign, align_tab, NALIGNTAB, ALcenter);
				sz = auintval(tok, Asize, HRSZ);
				wd = adimen(tok, Awidth);
				if(dimenkind(wd) == Dnone)
					wd = makedimen(Dpercent, 100);
				nosh = aflagval(tok, Anoshade);
				additem(ps, newirule(al, sz, nosh, wd), tok);
				addbrk(ps, 0, 0);
				break;

			case Ti:
			case Tcite:
			case Tdfn:
			case Tem:
			case Tvar:
			case Taddress:
				pushfontstyle(ps, FntI);
				break;

			// <!ELEMENT IMG - O EMPTY>
			case Timg:
				map = nil;
				oldcuranchor = ps->curanchor;
				if(_tokaval(tok, Ausemap, &usemap, 0)) {
					if(!_prefix(L(Lhash), usemap)) {
						if(warn)
							fprint(2, "warning: can't handle non-local map %S\n", usemap);
					}
					else {
						map = getmap(di, usemap+1);
						if(ps->curanchor == 0) {
							di->anchors = newanchor(++is->nanchors, nil, nil, di->target, di->anchors);
							ps->curanchor = is->nanchors;
						}
					}
				}
				align = atabval(tok, Aalign, align_tab, NALIGNTAB, ALbottom);
				dfltbd = 0;
				if(ps->curanchor != 0)
					dfltbd = 2;
				src = aurlval(tok, Asrc, nil, di->base);
				if(src == nil) {
					if(warn)
						fprint(2, "warning: <img> has no src attribute\n");
					ps->curanchor = oldcuranchor;
					continue;
				}
				img = newiimage(src,
						aval(tok, Aalt),
						align,
						auintval(tok, Awidth, 0),
						auintval(tok, Aheight, 0),
						auintval(tok, Ahspace, IMGHSPACE),
						auintval(tok, Avspace, IMGVSPACE),
						auintval(tok, Aborder, dfltbd),
						aflagval(tok, Aismap),
						map);
				if(align == ALleft || align == ALright) {
					additem(ps, newifloat(img, align), tok);
					// if no hspace specified, use FLTIMGHSPACE
					if(!_tokaval(tok, Ahspace, &val, 0))
						((Iimage*)img)->hspace = FLTIMGHSPACE;
				}
				else {
					ps->skipwhite = 0;
					additem(ps, img, tok);
				}
				if(!ps->skipping) {
					((Iimage*)img)->nextimage = di->images;
					di->images = (Iimage*)img;
				}
				ps->curanchor = oldcuranchor;
				break;

			// <!ELEMENT INPUT - O EMPTY>
			case Tinput:
				ps->skipwhite = 0;
				if(is->curform == nil) {
					if(warn)
						fprint(2, "<INPUT> not inside <FORM>\n");
					continue;
				}
				is->curform->fields = field = newformfield(
						atabval(tok, Atype, input_tab, NINPUTTAB, Ftext),
						++is->curform->nfields,
						is->curform,
						aval(tok, Aname),
						aval(tok, Avalue),
						auintval(tok, Asize, 0),
						auintval(tok, Amaxlength, 1000),
						is->curform->fields);
				if(aflagval(tok, Achecked))
					field->flags = FFchecked;

				switch(field->ftype) {
				case Ftext:
				case Fpassword:
				case Ffile:
					if(field->size == 0)
						field->size = 20;
					break;

				case Fcheckbox:
					if(field->name == nil) {
						if(warn)
							fprint(2, "warning: checkbox form field missing name\n");
						continue;
					}
					if(field->value == nil)
						field->value = _Strdup(L(Lone));
					break;

				case Fradio:
					if(field->name == nil || field->value == nil) {
						if(warn)
							fprint(2, "warning: radio form field missing name or value\n");
						continue;
					}
					break;

				case Fsubmit:
					if(field->value == nil)
						field->value = _Strdup(L(Lsubmit));
					if(field->name == nil)
						field->name = _Strdup(L(Lnoname));
					break;

				case Fimage:
					src = aurlval(tok, Asrc, nil, di->base);
					if(src == nil) {
						if(warn)
							fprint(2, "warning: image form field missing src\n");
						continue;
					}
					// width and height attrs aren't specified in HTML 3.2,
					// but some people provide them and they help avoid
					// a relayout
					field->image = newiimage(src,
						astrval(tok, Aalt, L(Lsubmit)),
						atabval(tok, Aalign, align_tab, NALIGNTAB, ALbottom),
						auintval(tok, Awidth, 0), auintval(tok, Aheight, 0),
						0, 0, 0, 0, nil);
					ii = (Iimage*)field->image;
					ii->nextimage = di->images;
					di->images = ii;
					break;

				case Freset:
					if(field->value == nil)
						field->value = _Strdup(L(Lreset));
					break;

				case Fbutton:
					if(field->value == nil)
						field->value = _Strdup(L(Lspace));
					break;
				}
				ffit = newiformfield(field);
				additem(ps, ffit, tok);
				if(ffit->genattr != nil)
					field->events = ffit->genattr->events;
				break;

			// <!ENTITY ISINDEX - O EMPTY>
			case Tisindex:
				ps->skipwhite = 0;
				prompt = astrval(tok, Aprompt, L(Lindex));
				target = atargval(tok, di->target);
				additem(ps, textit(ps, prompt), tok);
				frm = newform(++is->nforms,
						nil,
						di->base,
						target,
						HGet,
						di->forms);
				di->forms = frm;
				ff = newformfield(Ftext,
						1,
						frm,
						_Strdup(L(Lisindex)),
						nil,
						50,
						1000,
						nil);
				frm->fields = ff;
				frm->nfields = 1;
				additem(ps, newiformfield(ff), tok);
				addbrk(ps, 1, 0);
				break;

			// <!ELEMENT LI - O %flow>
			case Tli:
				if(ps->listtypestk.n == 0) {
					if(warn)
						fprint(2, "<LI> not in list\n");
					continue;
				}
				ty = top(&ps->listtypestk, 0);
				ty2 = listtyval(tok, ty);
				if(ty != ty2) {
					ty = ty2;
					push(&ps->listtypestk, ty2);
				}
				v = aintval(tok, Avalue, top(&ps->listcntstk, 1));
				if(ty == LTdisc || ty == LTsquare || ty == LTcircle)
					hang = 10*LISTTAB - 3;
				else
					hang = 10*LISTTAB - 1;
				changehang(ps, hang);
				addtext(ps, listmark(ty, v));
				push(&ps->listcntstk, v + 1);
				changehang(ps, -hang);
				ps->skipwhite = 1;
				break;

			// <!ELEMENT MAP - - (AREA)+>
			case Tmap:
				if(_tokaval(tok, Aname, &name, 0))
					is->curmap = getmap(di, name);
				break;

			case Tmap+RBRA:
				map = is->curmap;
				if(map == nil) {
					if(warn)
						fprint(2, "warning: unexpected </MAP>\n");
					continue;
				}
				map->areas = (Area*)_revlist((List*)map->areas);
				break;

			case Tmeta:
				if(ps->skipping)
					continue;
				if(_tokaval(tok, Ahttp_equiv, &equiv, 0)) {
					val = aval(tok, Acontent);
					n = _Strlen(equiv);
					if(!_Strncmpci(equiv, n, L(Lrefresh)))
						di->refresh = val;
					else if(!_Strncmpci(equiv, n, L(Lcontent))) {
						n = _Strlen(val);
						if(!_Strncmpci(val, n, L(Ljavascript))
						   || !_Strncmpci(val, n, L(Ljscript1))
						   || !_Strncmpci(val, n, L(Ljscript)))
							di->scripttype = TextJavascript;
						else {
							if(warn)
								fprint(2, "unimplemented script type %S\n", val);
							di->scripttype = UnknownType;
						}
					}
				}
				break;

			// Nobr is NOT in HMTL 4.0, but it is ubiquitous on the web
			case Tnobr:
				ps->skipwhite = 0;
				ps->curstate &= ~IFwrap;
				break;

			case Tnobr+RBRA:
				ps->curstate |= IFwrap;
				break;

			// We do frames, so skip stuff in noframes
			case Tnoframes:
				ps->skipping = 1;
				break;

			case Tnoframes+RBRA:
				ps->skipping = 0;
				break;

			// We do scripts (if enabled), so skip stuff in noscripts
			case Tnoscript:
				if(doscripts)
					ps->skipping = 1;
				break;

			case Tnoscript+RBRA:
				if(doscripts)
					ps->skipping = 0;
				break;

			// <!ELEMENT OPTION - O (	//PCDATA)>
			case Toption:
				if(is->curform == nil || is->curform->fields == nil) {
					if(warn)
						fprint(2, "warning: <OPTION> not in <SELECT>\n");
					continue;
				}
				field = is->curform->fields;
				if(field->ftype != Fselect) {
					if(warn)
						fprint(2, "warning: <OPTION> not in <SELECT>\n");
					continue;
				}
				val = aval(tok, Avalue);
				option = newoption(aflagval(tok, Aselected), val, nil, field->options);
				field->options = option;
				option->display =  getpcdata(toks, tokslen, &toki);
				if(val == nil)
					option->value = _Strdup(option->display);
				break;

			// <!ELEMENT P - O (%text)* >
			case Tp:
				pushjust(ps, atabval(tok, Aalign, align_tab, NALIGNTAB, ps->curjust));
				ps->inpar = 1;
				ps->skipwhite = 1;
				break;

			case Tp+RBRA:
				break;

			// <!ELEMENT PARAM - O EMPTY>
			// Do something when we do applets...
			case Tparam:
				break;

			// <!ELEMENT PRE - - (%text)* -(IMG|BIG|SMALL|SUB|SUP|FONT) >
			case Tpre:
				ps->curstate &= ~IFwrap;
				ps->literal = 1;
				ps->skipwhite = 0;
				pushfontstyle(ps, FntT);
				break;

			case Tpre+RBRA:
				ps->curstate |= IFwrap;
				if(ps->literal) {
					popfontstyle(ps);
					ps->literal = 0;
				}
				break;

			// <!ELEMENT SCRIPT - - CDATA>
			case Tscript:
				if(doscripts) {
					if(!di->hasscripts) {
						if(di->scripttype == TextJavascript) {
							// TODO: initialize script if nec.
							// initjscript(di);
							di->hasscripts = 1;
						}
					}
				}
				if(!di->hasscripts) {
					if(warn)
						fprint(2, "warning: <SCRIPT> ignored\n");
					ps->skipping = 1;
				}
				else {
					scriptsrc = aurlval(tok, Asrc, nil, di->base);
					script = nil;
					if(scriptsrc != nil) {
						if(warn)
							fprint(2, "warning: non-local <SCRIPT> ignored\n");
						free(scriptsrc);
					}
					else {
						script = getpcdata(toks, tokslen, &toki);
					}
					if(script != nil) {
						if(warn)
							fprint(2, "script ignored\n");
						free(script);
					}
				}
				break;

			case Tscript+RBRA:
				ps->skipping = 0;
				break;

			// <!ELEMENT SELECT - - (OPTION+)>
			case Tselect:
				if(is->curform == nil) {
					if(warn)
						fprint(2, "<SELECT> not inside <FORM>\n");
					continue;
				}
				field = newformfield(Fselect,
					++is->curform->nfields,
					is->curform,
					aval(tok, Aname),
					nil,
					auintval(tok, Asize, 0),
					0,
					is->curform->fields);
				is->curform->fields = field;
				if(aflagval(tok, Amultiple))
					field->flags = FFmultiple;
				ffit = newiformfield(field);
				additem(ps, ffit, tok);
				if(ffit->genattr != nil)
					field->events = ffit->genattr->events;
				// throw away stuff until next tag (should be <OPTION>)
				s = getpcdata(toks, tokslen, &toki);
				if(s != nil)
					free(s);
				break;

			case Tselect+RBRA:
				if(is->curform == nil || is->curform->fields == nil) {
					if(warn)
						fprint(2, "warning: unexpected </SELECT>\n");
					continue;
				}
				field = is->curform->fields;
				if(field->ftype != Fselect)
					continue;
				// put options back in input order
				field->options = (Option*)_revlist((List*)field->options);
				break;

			// <!ELEMENT (STRIKE|U) - - (%text)*>
			case Tstrike:
			case Tu:
				ps->curul = push(&ps->ulstk, (tag==Tstrike)? ULmid : ULunder);
				break;

			case Tstrike+RBRA:
			case Tu+RBRA:
				if(ps->ulstk.n == 0) {
					if(warn)
						fprint(2, "warning: unexpected %T\n", tok);
					continue;
				}
				ps->curul = popretnewtop(&ps->ulstk, ULnone);
				break;

			// <!ELEMENT STYLE - - CDATA>
			case Tstyle:
				if(warn)
					fprint(2, "warning: unimplemented <STYLE>\n");
				ps->skipping = 1;
				break;

			case Tstyle+RBRA:
				ps->skipping = 0;
				break;

			// <!ELEMENT (SUB|SUP) - - (%text)*>
			case Tsub:
			case Tsup:
				if(tag == Tsub)
					ps->curvoff += SUBOFF;
				else
					ps->curvoff -= SUPOFF;
				push(&ps->voffstk, ps->curvoff);
				sz = top(&ps->fntsizestk, Normal);
				pushfontsize(ps, sz - 1);
				break;

			case Tsub+RBRA:
			case Tsup+RBRA:
				if(ps->voffstk.n == 0) {
					if(warn)
						fprint(2, "warning: unexpected %T\n", tok);
					continue;
				}
				ps->curvoff = popretnewtop(&ps->voffstk, 0);
				popfontsize(ps);
				break;

			// <!ELEMENT TABLE - - (CAPTION?, TR+)>
			case Ttable:
				ps->skipwhite = 0;
				tab = newtable(++is->ntables,
						aalign(tok),
						adimen(tok, Awidth),
						aflagval(tok, Aborder), 
						auintval(tok, Acellspacing, TABSP),
						auintval(tok, Acellpadding, TABPAD),
						makebackground(nil, acolorval(tok, Abgcolor, ps->curbg.color)),
						tok,
						is->tabstk);
				is->tabstk = tab;
				curtab = tab;
				break;

			case Ttable+RBRA:
				if(curtab == nil) {
					if(warn)
						fprint(2, "warning: unexpected </TABLE>\n");
					continue;
				}
				isempty = (curtab->cells == nil);
				if(isempty) {
					if(warn)
						fprint(2, "warning: <TABLE> has no cells\n");
				}
				else {
					ps = finishcell(curtab, ps);
					if(curtab->rows != nil)
						curtab->rows->flags = 0;
					finish_table(curtab);
				}
				ps->skipping = 0;
				if(!isempty) {
					tabitem = newitable(curtab);
					al = curtab->align.halign;
					switch(al) {
					case ALleft:
					case ALright:
						additem(ps, newifloat(tabitem, al), tok);
						break;
					default:
						if(al == ALcenter)
							pushjust(ps, ALcenter);
						addbrk(ps, 0, 0);
						if(ps->inpar) {
							popjust(ps);
							ps->inpar = 0;
						}
						additem(ps, tabitem, curtab->tabletok);
						if(al == ALcenter)
							popjust(ps);
						break;
					}
				}
				if(is->tabstk == nil) {
					if(warn)
						fprint(2, "warning: table stack is wrong\n");
				}
				else
					is->tabstk = is->tabstk->next;
				curtab->next = di->tables;
				di->tables = curtab;
				curtab = is->tabstk;
				if(!isempty)
					addbrk(ps, 0, 0);
				break;

			// <!ELEMENT (TH|TD) - O %body.content>
			// Cells for a row are accumulated in reverse order.
			// We push ps on a stack, and use a new one to accumulate
			// the contents of the cell.
			case Ttd:
			case Tth:
				if(curtab == nil) {
					if(warn)
						fprint(2, "%T outside <TABLE>\n", tok);
					continue;
				}
				if(ps->inpar) {
					popjust(ps);
					ps->inpar = 0;
				}
				ps = finishcell(curtab, ps);
				tr = nil;
				if(curtab->rows != nil)
					tr = curtab->rows;
				if(tr == nil || !tr->flags) {
					if(warn)
						fprint(2, "%T outside row\n", tok);
					tr = newtablerow(makealign(ALnone, ALnone),
							makebackground(nil, curtab->background.color),
							TFparsing,
							curtab->rows);
					curtab->rows = tr;
				}
				ps = cell_pstate(ps, tag == Tth);
				flags = TFparsing;
				if(aflagval(tok, Anowrap)) {
					flags |= TFnowrap;
					ps->curstate &= ~IFwrap;
				}
				if(tag == Tth)
					flags |= TFisth;
				c = newtablecell(curtab->cells==nil? 1 : curtab->cells->cellid+1,
						auintval(tok, Arowspan, 1),
						auintval(tok, Acolspan, 1), 
						aalign(tok), 
						adimen(tok, Awidth),
						auintval(tok, Aheight, 0),
						makebackground(nil, acolorval(tok, Abgcolor, tr->background.color)),
						flags,
						curtab->cells);
				curtab->cells = c;
				ps->curbg = c->background;
				if(c->align.halign == ALnone) {
					if(tr->align.halign != ALnone)
						c->align.halign = tr->align.halign;
					else if(tag == Tth)
						c->align.halign = ALcenter;
					else
						c->align.halign = ALleft;
				}
				if(c->align.valign == ALnone) {
					if(tr->align.valign != ALnone)
						c->align.valign = tr->align.valign;
					else
						c->align.valign = ALmiddle;
				}
				c->nextinrow = tr->cells;
				tr->cells = c;
				break;

			case Ttd+RBRA:
			case Tth+RBRA:
				if(curtab == nil || curtab->cells == nil) {
					if(warn)
						fprint(2, "unexpected %T\n", tok);
					continue;
				}
				ps = finishcell(curtab, ps);
				break;

			// <!ELEMENT TEXTAREA - - (	//PCDATA)>
			case Ttextarea:
				if(is->curform == nil) {
					if(warn)
						fprint(2, "<TEXTAREA> not inside <FORM>\n");
					continue;
				}
				field = newformfield(Ftextarea,
					++is->curform->nfields,
					is->curform,
					aval(tok, Aname),
					nil,
					0,
					0,
					is->curform->fields);
				is->curform->fields = field;
				field->rows = auintval(tok, Arows, 3);
				field->cols = auintval(tok, Acols, 50);
				field->value = getpcdata(toks, tokslen, &toki);
				if(warn && toki < tokslen - 1 && toks[toki + 1].tag != Ttextarea + RBRA)
					fprint(2, "warning: <TEXTAREA> data ended by %T\n", &toks[toki + 1]);
				ffit = newiformfield(field);
				additem(ps, ffit, tok);
				if(ffit->genattr != nil)
					field->events = ffit->genattr->events;
				break;

			// <!ELEMENT TITLE - - (	//PCDATA)* -(%head.misc)>
			case Ttitle:
				di->doctitle = getpcdata(toks, tokslen, &toki);
				if(warn && toki < tokslen - 1 && toks[toki + 1].tag != Ttitle + RBRA)
					fprint(2, "warning: <TITLE> data ended by %T\n", &toks[toki + 1]);
				break;

			// <!ELEMENT TR - O (TH|TD)+>
			// rows are accumulated in reverse order in curtab->rows
			case Ttr:
				if(curtab == nil) {
					if(warn)
						fprint(2, "warning: <TR> outside <TABLE>\n");
					continue;
				}
				if(ps->inpar) {
					popjust(ps);
					ps->inpar = 0;
				}
				ps = finishcell(curtab, ps);
				if(curtab->rows != nil)
					curtab->rows->flags = 0;
				curtab->rows = newtablerow(aalign(tok),
					makebackground(nil, acolorval(tok, Abgcolor, curtab->background.color)),
					TFparsing,
					curtab->rows);
				break;

			case Ttr+RBRA:
				if(curtab == nil || curtab->rows == nil) {
					if(warn)
						fprint(2, "warning: unexpected </TR>\n");
					continue;
				}
				ps = finishcell(curtab, ps);
				tr = curtab->rows;
				if(tr->cells == nil) {
					if(warn)
						fprint(2, "warning: empty row\n");
					curtab->rows = tr->next;
					tr->next = nil;
				}
				else
					tr->flags = 0;
				break;

			// <!ELEMENT (TT|CODE|KBD|SAMP) - - (%text)*>
			case Ttt:
			case Tcode:
			case Tkbd:
			case Tsamp:
				pushfontstyle(ps, FntT);
				break;

			// Tags that have empty action
			case Tabbr:
			case Tabbr+RBRA:
			case Tacronym:
			case Tacronym+RBRA:
			case Tarea+RBRA:
			case Tbase+RBRA:
			case Tbasefont+RBRA:
			case Tbr+RBRA:
			case Tdd+RBRA:
			case Tdt+RBRA:
			case Tframe+RBRA:
			case Thr+RBRA:
			case Thtml:
			case Thtml+RBRA:
			case Timg+RBRA:
			case Tinput+RBRA:
			case Tisindex+RBRA:
			case Tli+RBRA:
			case Tlink:
			case Tlink+RBRA:
			case Tmeta+RBRA:
			case Toption+RBRA:
			case Tparam+RBRA:
			case Ttextarea+RBRA:
			case Ttitle+RBRA:
				break;


			// Tags not implemented
			case Tbdo:
			case Tbdo+RBRA:
			case Tbutton:
			case Tbutton+RBRA:
			case Tdel:
			case Tdel+RBRA:
			case Tfieldset:
			case Tfieldset+RBRA:
			case Tiframe:
			case Tiframe+RBRA:
			case Tins:
			case Tins+RBRA:
			case Tlabel:
			case Tlabel+RBRA:
			case Tlegend:
			case Tlegend+RBRA:
			case Tobject:
			case Tobject+RBRA:
			case Toptgroup:
			case Toptgroup+RBRA:
			case Tspan:
			case Tspan+RBRA:
				if(warn) {
					if(tag > RBRA)
						tag -= RBRA;
					fprint(2, "warning: unimplemented HTML tag: %S\n", tagnames[tag]);
				}
				break;

			default:
				if(warn)
					fprint(2, "warning: unknown HTML tag: %S\n", tok->text);
				break;
			}
	}
	// some pages omit trailing </table>
	while(curtab != nil) {
		if(warn)
			fprint(2, "warning: <TABLE> not closed\n");
		if(curtab->cells != nil) {
			ps = finishcell(curtab, ps);
			if(curtab->cells == nil) {
				if(warn)
					fprint(2, "warning: empty table\n");
			}
			else {
				if(curtab->rows != nil)
					curtab->rows->flags = 0;
				finish_table(curtab);
				ps->skipping = 0;
				additem(ps, newitable(curtab), curtab->tabletok);
				addbrk(ps, 0, 0);
			}
		}
		if(is->tabstk != nil)
			is->tabstk = is->tabstk->next;
		curtab->next = di->tables;
		di->tables = curtab;
		curtab = is->tabstk;
	}
	outerps = lastps(ps);
	ans = outerps->items->next;
	// note: ans may be nil and di->kids not nil, if there's a frameset!
	outerps->items = newispacer(ISPnull);
	outerps->lastit = outerps->items;
	is->psstk = ps;
	if(ans != nil && di->hasscripts) {
		// TODO evalscript(nil);
		;
	}

return_ans:
	if(dbgbuild) {
		assert(validitems(ans));
		if(ans == nil)
			fprint(2, "getitems returning nil\n");
		else
			printitems(ans, "getitems returning:");
	}
	return ans;
}

// Concatenate together maximal set of Data tokens, starting at toks[toki+1].
// Lexer has ensured that there will either be a following non-data token or
// we will be at eof.
// Return emallocd trimmed concatenation, and update *ptoki to last used toki
static Rune*
getpcdata(Token* toks, int tokslen, int* ptoki)
{
	Rune*	ans;
	Rune*	p;
	Rune*	trimans;
	int	anslen;
	int	trimanslen;
	int	toki;
	Token*	tok;

	ans = nil;
	anslen = 0;
	// first find length of answer
	toki = (*ptoki) + 1;
	while(toki < tokslen) {
		tok = &toks[toki];
		if(tok->tag == Data) {
			toki++;
			anslen += _Strlen(tok->text);
		}
		else
			break;
	}
	// now make up the initial answer
	if(anslen > 0) {
		ans = _newstr(anslen);
		p = ans;
		toki = (*ptoki) + 1;
		while(toki < tokslen) {
			tok = &toks[toki];
			if(tok->tag == Data) {
				toki++;
				p = _Stradd(p, tok->text, _Strlen(tok->text));
			}
			else
				break;
		}
		*p = 0;
		_trimwhite(ans, anslen, &trimans, &trimanslen);
		if(trimanslen != anslen) {
			p = ans;
			ans = _Strndup(trimans, trimanslen);
			free(p);
		}
	}
	*ptoki = toki-1;
	return ans;
}

// If still parsing head of curtab->cells list, finish it off
// by transferring the items on the head of psstk to the cell.
// Then pop the psstk and return the new psstk.
static Pstate*
finishcell(Table* curtab, Pstate* psstk)
{
	Tablecell*	c;
	Pstate* psstknext;

	c = curtab->cells;
	if(c != nil) {
		if((c->flags&TFparsing)) {
			psstknext = psstk->next;
			if(psstknext == nil) {
				if(warn)
					fprint(2, "warning: parse state stack is wrong\n");
			}
			else {
				c->content = psstk->items->next;
				c->flags &= ~TFparsing;
				freepstate(psstk);
				psstk = psstknext;
			}
		}
	}
	return psstk;
}

// Make a new Pstate for a cell, based on the old pstate, oldps.
// Also, put the new ps on the head of the oldps stack.
static Pstate*
cell_pstate(Pstate* oldps, int ishead)
{
	Pstate*	ps;
	int	sty;

	ps = newpstate(oldps);
	ps->skipwhite = 1;
	ps->curanchor = oldps->curanchor;
	copystack(&ps->fntstylestk, &oldps->fntstylestk);
	copystack(&ps->fntsizestk, &oldps->fntsizestk);
	ps->curfont = oldps->curfont;
	ps->curfg = oldps->curfg;
	ps->curbg = oldps->curbg;
	copystack(&ps->fgstk, &oldps->fgstk);
	ps->adjsize = oldps->adjsize;
	if(ishead) {
		sty = ps->curfont%NumSize;
		ps->curfont = FntB*NumSize + sty;
	}
	return ps;
}

// Return a new Pstate with default starting state.
// Use link to add it to head of a list, if any.
static Pstate*
newpstate(Pstate* link)
{
	Pstate*	ps;

	ps = (Pstate*)emalloc(sizeof(Pstate));
	ps->curfont = DefFnt;
	ps->curfg = Black;
	ps->curbg.image = nil;
	ps->curbg.color = White;
	ps->curul = ULnone;
	ps->curjust = ALleft;
	ps->curstate = IFwrap;
	ps->items = newispacer(ISPnull);
	ps->lastit = ps->items;
	ps->prelastit = nil;
	ps->next = link;
	return ps;
}

// Return last Pstate on psl list
static Pstate*
lastps(Pstate* psl)
{
	assert(psl != nil);
	while(psl->next != nil)
		psl = psl->next;
	return psl;
}

// Add it to end of ps item chain, adding in current state from ps.
// Also, if tok is not nil, scan it for generic attributes and assign
// the genattr field of the item accordingly.
static void
additem(Pstate* ps, Item* it, Token* tok)
{
	int	aid;
	int	any;
	Rune*	i;
	Rune*	c;
	Rune*	s;
	Rune*	t;
	Attr*	a;
	SEvent*	e;

	if(ps->skipping) {
		if(warn)
			fprint(2, "warning: skipping item: %I\n", it);
		return;
	}
	it->anchorid = ps->curanchor;
	it->state |= ps->curstate;
	if(tok != nil) {
		any = 0;
		i = nil;
		c = nil;
		s = nil;
		t = nil;
		e = nil;
		for(a = tok->attr; a != nil; a = a->next) {
			aid = a->attid;
			if(!attrinfo[aid])
				continue;
			switch(aid) {
			case Aid:
				i = a->value;
				break;

			case Aclass:
				c = a->value;
				break;

			case Astyle:
				s = a->value;
				break;

			case Atitle:
				t = a->value;
				break;

			default:
				assert(aid >= Aonblur && aid <= Aonunload);
				e = newscriptevent(scriptev[a->attid], a->value, e);
				break;
			}
			a->value = nil;
			any = 1;
		}
		if(any)
			it->genattr = newgenattr(i, c, s, t, e);
	}
	ps->curstate &= ~(IFbrk|IFbrksp|IFnobrk|IFcleft|IFcright);
	ps->prelastit = ps->lastit;
	ps->lastit->next = it;
	ps->lastit = it;
}

// Make a text item out of s,
// using current font, foreground, vertical offset and underline state.
static Item*
textit(Pstate* ps, Rune* s)
{
	assert(s != nil);
	return newitext(s, ps->curfont, ps->curfg, ps->curvoff + Voffbias, ps->curul);
}

// Add text item or items for s, paying attention to
// current font, foreground, baseline offset, underline state,
// and literal mode.  Unless we're in literal mode, compress
// whitespace to single blank, and, if curstate has a break,
// trim any leading whitespace.  Whether in literal mode or not,
// turn nonbreaking spaces into spacer items with IFnobrk set.
//
// In literal mode, break up s at newlines and add breaks instead.
// Also replace tabs appropriate number of spaces.
// In nonliteral mode, break up the items every 100 or so characters
// just to make the layout algorithm not go quadratic.
//
// addtext assumes ownership of s.
static void
addtext(Pstate* ps, Rune* s)
{
	int	n;
	int	i;
	int	j;
	int	k;
	int	col;
	int	c;
	int	nsp;
	Item*	it;
	Rune*	ss;
	Rune*	p;
	Rune	buf[SMALLBUFSIZE];

	assert(s != nil);
	n = runestrlen(s);
	i = 0;
	j = 0;
	if(ps->literal) {
		col = 0;
		while(i < n) {
			if(s[i] == '\n') {
				if(i > j) {
					// trim trailing blanks from line
					for(k = i; k > j; k--)
						if(s[k - 1] != ' ')
							break;
					if(k > j)
						additem(ps, textit(ps, _Strndup(s+j, k-j)), nil);
				}
				addlinebrk(ps, 0);
				j = i + 1;
				col = 0;
			}
			else {
				if(s[i] == '\t') {
					col += i - j;
					nsp = 8 - (col%8);
					// make ss = s[j:i] + nsp spaces
					ss = _newstr(i-j+nsp);
					p = _Stradd(ss, s+j, i-j);
					p = _Stradd(p, L(Ltab2space), nsp);
					*p = 0;
					additem(ps, textit(ps, ss), nil);
					col += nsp;
					j = i + 1;
				}
				else if(s[i] == NBSP) {
					if(i > j)
						additem(ps, textit(ps, _Strndup(s+j, i-j)), nil);
					addnbsp(ps);
					col += (i - j) + 1;
					j = i + 1;
				}
			}
			i++;
		}
		if(i > j) {
			if(j == 0 && i == n) {
				// just transfer s over
				additem(ps, textit(ps, s), nil);
			}
			else {
				additem(ps, textit(ps, _Strndup(s+j, i-j)), nil);
				free(s);
			}
		}
	}
	else {	// not literal mode
		if((ps->curstate&IFbrk) || ps->lastit == ps->items)
			while(i < n) {
				c = s[i];
				if(c >= 256 || !isspace(c))
					break;
				i++;
			}
		p = buf;
		for(j = i; i < n; i++) {
			assert(p+i-j < buf+SMALLBUFSIZE-1);
			c = s[i];
			if(c == NBSP) {
				if(i > j)
					p = _Stradd(p, s+j, i-j);
				if(p > buf)
					additem(ps, textit(ps, _Strndup(buf, p-buf)), nil);
				p = buf;
				addnbsp(ps);
				j = i + 1;
				continue;
			}
			if(c < 256 && isspace(c)) {
				if(i > j)
					p = _Stradd(p, s+j, i-j);
				*p++ = ' ';
				while(i < n - 1) {
					c = s[i + 1];
					if(c >= 256 || !isspace(c))
						break;
					i++;
				}
				j = i + 1;
			}
			if(i - j >= 100) {
				p = _Stradd(p, s+j, i+1-j);
				j = i + 1;
			}
			if(p-buf >= 100) {
				additem(ps, textit(ps, _Strndup(buf, p-buf)), nil);
				p = buf;
			}
		}
		if(i > j && j < n) {
			assert(p+i-j < buf+SMALLBUFSIZE-1);
			p = _Stradd(p, s+j, i-j);
		}
		// don't add a space if previous item ended in a space
		if(p-buf == 1 && buf[0] == ' ' && ps->lastit != nil) {
			it = ps->lastit;
			if(it->tag == Itexttag) {
				ss = ((Itext*)it)->s;
				k = _Strlen(ss);
				if(k > 0 && ss[k] == ' ')
					p = buf;
			}
		}
		if(p > buf)
			additem(ps, textit(ps, _Strndup(buf, p-buf)), nil);
		free(s);
	}
}

// Add a break to ps->curstate, with extra space if sp is true.
// If there was a previous break, combine this one's parameters
// with that to make the amt be the max of the two and the clr
// be the most general. (amt will be 0 or 1)
// Also, if the immediately preceding item was a text item,
// trim any whitespace from the end of it, if not in literal mode.
// Finally, if this is at the very beginning of the item list
// (the only thing there is a null spacer), then don't add the space.
static void
addbrk(Pstate* ps, int sp, int clr)
{
	int	state;
	Rune*	l;
	int		nl;
	Rune*	r;
	int		nr;
	Itext*	t;
	Rune*	s;

	state = ps->curstate;
	clr = clr|(state&(IFcleft|IFcright));
	if(sp && !(ps->lastit == ps->items))
		sp = IFbrksp;
	else
		sp = 0;
	ps->curstate = IFbrk|sp|(state&~(IFcleft|IFcright))|clr;
	if(ps->lastit != ps->items) {
		if(!ps->literal && ps->lastit->tag == Itexttag) {
			t = (Itext*)ps->lastit;
			_splitr(t->s, _Strlen(t->s), notwhitespace, &l, &nl, &r, &nr);
			// try to avoid making empty items
			// but not crucial f the occasional one gets through
			if(nl == 0 && ps->prelastit != nil) {
				ps->lastit = ps->prelastit;
				ps->lastit->next = nil;
				ps->prelastit = nil;
			}
			else {
				s = t->s;
				if(nl == 0) {
					// need a non-nil pointer to empty string
					// (_Strdup(L(Lempty)) returns nil)
					t->s = emalloc(sizeof(Rune));
					t->s[0] = 0;
				}
				else
					t->s = _Strndup(l, nl);
				if(s)
					free(s);
			}
		}
	}
}

// Add break due to a <br> or a newline within a preformatted section.
// We add a null item first, with current font's height and ascent, to make
// sure that the current line takes up at least that amount of vertical space.
// This ensures that <br>s on empty lines cause blank lines, and that
// multiple <br>s in a row give multiple blank lines.
// However don't add the spacer if the previous item was something that
// takes up space itself.
static void
addlinebrk(Pstate* ps, int clr)
{
	int	obrkstate;
	int	b;
	int	addit;

	// don't want break before our null item unless the previous item
	// was also a null item for the purposes of line breaking
	obrkstate = ps->curstate&(IFbrk|IFbrksp);
	b = IFnobrk;
	addit = 0;
	if(ps->lastit != nil) {
		if(ps->lastit->tag == Ispacertag) {
			if(((Ispacer*)ps->lastit)->spkind == ISPvline)
				b = IFbrk;
			addit = 1;
		}
		else if(ps->lastit->tag == Ifloattag)
			addit = 1;
	}
	if(addit) {
		ps->curstate = (ps->curstate&~(IFbrk|IFbrksp))|b;
		additem(ps, newispacer(ISPvline), nil);
		ps->curstate = (ps->curstate&~(IFbrk|IFbrksp))|obrkstate;
	}
	addbrk(ps, 0, clr);
}

// Add a nonbreakable space
static void
addnbsp(Pstate* ps)
{
	// if nbsp comes right where a break was specified,
	// do the break anyway (nbsp is being used to generate undiscardable
	// space rather than to prevent a break)
	if((ps->curstate&IFbrk) == 0)
		ps->curstate |= IFnobrk;
	additem(ps, newispacer(ISPhspace), nil);
	// but definitely no break on next item
	ps->curstate |= IFnobrk;
}

// Change hang in ps.curstate by delta.
// The amount is in 1/10ths of tabs, and is the amount that
// the current contiguous set of items with a hang value set
// is to be shifted left from its normal (indented) place.
static void
changehang(Pstate* ps, int delta)
{
	int	amt;

	amt = (ps->curstate&IFhangmask) + delta;
	if(amt < 0) {
		if(warn)
			fprint(2, "warning: hang went negative\n");
		amt = 0;
	}
	ps->curstate = (ps->curstate&~IFhangmask)|amt;
}

// Change indent in ps.curstate by delta.
static void
changeindent(Pstate* ps, int delta)
{
	int	amt;

	amt = ((ps->curstate&IFindentmask) >> IFindentshift) + delta;
	if(amt < 0) {
		if(warn)
			fprint(2, "warning: indent went negative\n");
		amt = 0;
	}
	ps->curstate = (ps->curstate&~IFindentmask)|(amt << IFindentshift);
}

// Push val on top of stack, and also return value pushed
static int
push(Stack* stk, int val)
{
	if(stk->n == Nestmax) {
		if(warn)
			fprint(2, "warning: build stack overflow\n");
	}
	else
		stk->slots[stk->n++] = val;
	return val;
}

// Pop top of stack
static void
pop(Stack* stk)
{
	if(stk->n > 0)
		--stk->n;
}

//Return top of stack, using dflt if stack is empty
static int
top(Stack* stk, int dflt)
{
	if(stk->n == 0)
		return dflt;
	return stk->slots[stk->n-1];
}

// pop, then return new top, with dflt if empty
static int
popretnewtop(Stack* stk, int dflt)
{
	if(stk->n == 0)
		return dflt;
	stk->n--;
	if(stk->n == 0)
		return dflt;
	return stk->slots[stk->n-1];
}

// Copy fromstk entries into tostk
static void
copystack(Stack* tostk, Stack* fromstk)
{
	int n;

	n = fromstk->n;
	tostk->n = n;
	memmove(tostk->slots, fromstk->slots, n*sizeof(int));
}

static void
popfontstyle(Pstate* ps)
{
	pop(&ps->fntstylestk);
	setcurfont(ps);
}

static void
pushfontstyle(Pstate* ps, int sty)
{
	push(&ps->fntstylestk, sty);
	setcurfont(ps);
}

static void
popfontsize(Pstate* ps)
{
	pop(&ps->fntsizestk);
	setcurfont(ps);
}

static void
pushfontsize(Pstate* ps, int sz)
{
	push(&ps->fntsizestk, sz);
	setcurfont(ps);
}

static void
setcurfont(Pstate* ps)
{
	int	sty;
	int	sz;

	sty = top(&ps->fntstylestk, FntR);
	sz = top(&ps->fntsizestk, Normal);
	if(sz < Tiny)
		sz = Tiny;
	if(sz > Verylarge)
		sz = Verylarge;
	ps->curfont = sty*NumSize + sz;
}

static void
popjust(Pstate* ps)
{
	pop(&ps->juststk);
	setcurjust(ps);
}

static void
pushjust(Pstate* ps, int j)
{
	push(&ps->juststk, j);
	setcurjust(ps);
}

static void
setcurjust(Pstate* ps)
{
	int	j;
	int	state;

	j = top(&ps->juststk, ALleft);
	if(j != ps->curjust) {
		ps->curjust = j;
		state = ps->curstate;
		state &= ~(IFrjust|IFcjust);
		if(j == ALcenter)
			state |= IFcjust;
		else if(j == ALright)
			state |= IFrjust;
		ps->curstate = state;
	}
}

// Do final rearrangement after table parsing is finished
// and assign cells to grid points
static void
finish_table(Table* t)
{
	int	ncol;
	int	nrow;
	int	r;
	Tablerow*	rl;
	Tablecell*	cl;
	int*	rowspancnt;
	Tablecell**	rowspancell;
	int	ri;
	int	ci;
	Tablecell*	c;
	Tablecell*	cnext;
	Tablerow*	row;
	Tablerow*	rownext;
	int	rcols;
	int	newncol;
	int	k;
	int	j;
	int	cspan;
	int	rspan;
	int	i;

	rl = t->rows;
	t->nrow = nrow = _listlen((List*)rl);
	t->rows = (Tablerow*)emalloc(nrow * sizeof(Tablerow));
	ncol = 0;
	r = nrow - 1;
	for(row = rl; row != nil; row = rownext) {
		// copy the data from the allocated Tablerow into the array slot
		t->rows[r] = *row;
		rownext = row->next;
		row = &t->rows[r];
		r--;
		rcols = 0;
		c = row->cells;

		// If rowspan is > 1 but this is the last row,
		// reset the rowspan
		if(c != nil && c->rowspan > 1 && r == nrow-2)
				c->rowspan = 1;

		// reverse row->cells list (along nextinrow pointers)
		row->cells = nil;
		while(c != nil) {
			cnext = c->nextinrow;
			c->nextinrow = row->cells;
			row->cells = c;
			rcols += c->colspan;
			c = cnext;
		}
		if(rcols > ncol)
			ncol = rcols;
	}
	t->ncol = ncol;
	t->cols = (Tablecol*)emalloc(ncol * sizeof(Tablecol));

	// Reverse cells just so they are drawn in source order.
	// Also, trim their contents so they don't end in whitespace.
	t->cells = (Tablecell*)_revlist((List*)t->cells);
	for(c = t->cells; c != nil; c= c->next)
		trim_cell(c);
	t->grid = (Tablecell***)emalloc(nrow * sizeof(Tablecell**));
	for(i = 0; i < nrow; i++)
		t->grid[i] = (Tablecell**)emalloc(ncol * sizeof(Tablecell*));

	// The following arrays keep track of cells that are spanning
	// multiple rows;  rowspancnt[i] is the number of rows left
	// to be spanned in column i.
	// When done, cell's (row,col) is upper left grid point.
	rowspancnt = (int*)emalloc(ncol * sizeof(int));
	rowspancell = (Tablecell**)emalloc(ncol * sizeof(Tablecell*));
	for(ri = 0; ri < nrow; ri++) {
		row = &t->rows[ri];
		cl = row->cells;
		ci = 0;
		while(ci < ncol || cl != nil) {
			if(ci < ncol && rowspancnt[ci] > 0) {
				t->grid[ri][ci] = rowspancell[ci];
				rowspancnt[ci]--;
				ci++;
			}
			else {
				if(cl == nil) {
					ci++;
					continue;
				}
				c = cl;
				cl = cl->nextinrow;
				cspan = c->colspan;
				rspan = c->rowspan;
				if(ci + cspan > ncol) {
					// because of row spanning, we calculated
					// ncol incorrectly; adjust it
					newncol = ci + cspan;
					t->cols = (Tablecol*)erealloc(t->cols, newncol * sizeof(Tablecol));
					rowspancnt = (int*)erealloc(rowspancnt, newncol * sizeof(int));
					rowspancell = (Tablecell**)erealloc(rowspancell, newncol * sizeof(Tablecell*));
					k = newncol-ncol;
					memset(t->cols+ncol, 0, k*sizeof(Tablecol));
					memset(rowspancnt+ncol, 0, k*sizeof(int));
					memset(rowspancell+ncol, 0, k*sizeof(Tablecell*));
					for(j = 0; j < nrow; j++) {
						t->grid[j] = (Tablecell**)erealloc(t->grid[j], newncol * sizeof(Tablecell*));
						memset(t->grid[j], 0, k*sizeof(Tablecell*));
					}
					t->ncol = ncol = newncol;
				}
				c->row = ri;
				c->col = ci;
				for(i = 0; i < cspan; i++) {
					t->grid[ri][ci] = c;
					if(rspan > 1) {
						rowspancnt[ci] = rspan - 1;
						rowspancell[ci] = c;
					}
					ci++;
				}
			}
		}
	}
}

// Remove tail of cell content until it isn't whitespace.
static void
trim_cell(Tablecell* c)
{
	int	dropping;
	Rune*	s;
	Rune*	x;
	Rune*	y;
	int		nx;
	int		ny;
	Item*	p;
	Itext*	q;
	Item*	pprev;

	dropping = 1;
	while(c->content != nil && dropping) {
		p = c->content;
		pprev = nil;
		while(p->next != nil) {
			pprev = p;
			p = p->next;
		}
		dropping = 0;
		if(!(p->state&IFnobrk)) {
			if(p->tag == Itexttag) {
				q = (Itext*)p;
				s = q->s;
				_splitr(s, _Strlen(s), notwhitespace, &x, &nx, &y, &ny);
				if(nx != 0 && ny != 0) {
					q->s = _Strndup(x, nx);
					free(s);
				}
				break;
			}
		}
		if(dropping) {
			if(pprev == nil)
				c->content = nil;
			else
				pprev->next = nil;
			freeitem(p);
		}
	}
}

// Caller must free answer (eventually).
static Rune*
listmark(uchar ty, int n)
{
	Rune*	s;
	Rune*	t;
	int	n2;
	int	i;

	s = nil;
	switch(ty) {
	case LTdisc:
	case LTsquare:
	case LTcircle:
		s = _newstr(1);
		s[0] = (ty == LTdisc)? 0x2022		// bullet
			: ((ty == LTsquare)? 0x220e	// filled square
			    : 0x2218);				// degree
		s[1] = 0;
		break;

	case LT1:
		t = _ltoStr(n);
		n2 = _Strlen(t);
		s = _newstr(n2+1);
		t = _Stradd(s, t, n2);
		*t++ = '.';
		*t = 0;
		break;

	case LTa:
	case LTA:
		n--;
		i = 0;
		if(n < 0)
			n = 0;
		s = _newstr((n <= 25)? 2 : 3);
		if(n > 25) {
			n2 = n%26;
			n /= 26;
			if(n2 > 25)
				n2 = 25;
			s[i++] = n2 + (ty == LTa)? 'a' : 'A';
		}
		s[i++] = n + (ty == LTa)? 'a' : 'A';
		s[i++] = '.';
		s[i] = 0;
		break;

	case LTi:
	case LTI:
		if(n >= NROMAN) {
			if(warn)
				fprint(2, "warning: unimplemented roman number > %d\n", NROMAN);
			n = NROMAN;
		}
		t = roman[n - 1];
		n2 = _Strlen(t);
		s = _newstr(n2+1);
		for(i = 0; i < n2; i++)
			s[i] = (ty == LTi)? tolower(t[i]) : t[i];
		s[i++] = '.';
		s[i] = 0;
		break;
	}
	return s;
}

// Find map with given name in di.maps.
// If not there, add one, copying name.
// Ownership of map remains with di->maps list.
static Map*
getmap(Docinfo* di, Rune* name)
{
	Map*	m;

	for(m = di->maps; m != nil; m = m->next) {
		if(!_Strcmp(name, m->name))
			return m;
	}
	m = (Map*)emalloc(sizeof(Map));
	m->name = _Strdup(name);
	m->areas = nil;
	m->next = di->maps;
	di->maps = m;
	return m;
}

// Transfers ownership of href to Area
static Area*
newarea(int shape, Rune* href, int target, Area* link)
{
	Area* a;

	a = (Area*)emalloc(sizeof(Area));
	a->shape = shape;
	a->href = href;
	a->target = target;
	a->next = link;
	return a;
}

// Return string value associated with attid in tok, nil if none.
// Caller must free the result (eventually).
static Rune*
aval(Token* tok, int attid)
{
	Rune*	ans;

	_tokaval(tok, attid, &ans, 1);	// transfers string ownership from token to ans
	return ans;
}

// Like aval, but use dflt if there was no such attribute in tok.
// Caller must free the result (eventually).
static Rune*
astrval(Token* tok, int attid, Rune* dflt)
{
	Rune*	ans;

	if(_tokaval(tok, attid, &ans, 1))
		return ans;	// transfers string ownership from token to ans
	else
		return _Strdup(dflt);
}

// Here we're supposed to convert to an int,
// and have a default when not found
static int
aintval(Token* tok, int attid, int dflt)
{
	Rune*	ans;

	if(!_tokaval(tok, attid, &ans, 0) || ans == nil)
		return dflt;
	else
		return toint(ans);
}

// Like aintval, but result should be >= 0
static int
auintval(Token* tok, int attid, int dflt)
{
	Rune* ans;
	int v;

	if(!_tokaval(tok, attid, &ans, 0) || ans == nil)
		return dflt;
	else {
		v = toint(ans);
		return v >= 0? v : 0;
	}
}

// int conversion, but with possible error check (if warning)
static int
toint(Rune* s)
{
	int ans;
	Rune* eptr;

	ans = _Strtol(s, &eptr, 10);
	if(warn) {
		if(*eptr != 0) {
			eptr = _Strclass(eptr, notwhitespace);
			if(eptr != nil)
				fprint(2, "warning: expected integer, got %S\n", s);
		}
	}
	return ans;
}

// Attribute value when need a table to convert strings to ints
static int
atabval(Token* tok, int attid, StringInt* tab, int ntab, int dflt)
{
	Rune*	aval;
	int	ans;

	ans = dflt;
	if(_tokaval(tok, attid, &aval, 0)) {
		if(!_lookup(tab, ntab, aval, _Strlen(aval), &ans)) {
			ans = dflt;
			if(warn)
				fprint(2, "warning: name not found in table lookup: %S\n", aval);
		}
	}
	return ans;
}

// Attribute value when supposed to be a color
static int
acolorval(Token* tok, int attid, int dflt)
{
	Rune*	aval;
	int	ans;

	ans = dflt;
	if(_tokaval(tok, attid, &aval, 0))
		ans = color(aval, dflt);
	return ans;
}

// Attribute value when supposed to be a target frame name
static int
atargval(Token* tok, int dflt)
{
	int	ans;
	Rune*	aval;

	ans = dflt;
	if(_tokaval(tok, Atarget, &aval, 0)){
		ans = targetid(aval);
	}
	return ans;
}

// special for list types, where "i" and "I" are different,
// but "square" and "SQUARE" are the same
static int
listtyval(Token* tok, int dflt)
{
	Rune*	aval;
	int	ans;
	int	n;

	ans = dflt;
	if(_tokaval(tok, Atype, &aval, 0)) {
		n = _Strlen(aval);
		if(n == 1) {
			switch(aval[0]) {
			case '1':
				ans = LT1;
				break;
			case 'A':
				ans = LTA;
				break;
			case 'I':
				ans = LTI;
				break;
			case 'a':
				ans = LTa;
				break;
			case 'i':
				ans = LTi;
			default:
				if(warn)
					fprint(2, "warning: unknown list element type %c\n", aval[0]);
			}
		}
		else {
			if(!_Strncmpci(aval, n, L(Lcircle)))
				ans = LTcircle;
			else if(!_Strncmpci(aval, n, L(Ldisc)))
				ans = LTdisc;
			else if(!_Strncmpci(aval, n, L(Lsquare)))
				ans = LTsquare;
			else {
				if(warn)
					fprint(2, "warning: unknown list element type %S\n", aval);
			}
		}
	}
	return ans;
}

// Attribute value when value is a URL, possibly relative to base.
// FOR NOW: leave the url relative.
// Caller must free the result (eventually).
static Rune*
aurlval(Token* tok, int attid, Rune* dflt, Rune* base)
{
	Rune*	ans;
	Rune*	url;

	USED(base);
	ans = nil;
	if(_tokaval(tok, attid, &url, 0) && url != nil)
		ans = removeallwhite(url);
	if(ans == nil)
		ans = _Strdup(dflt);
	return ans;
}

// Return copy of s but with all whitespace (even internal) removed.
// This fixes some buggy URL specification strings.
static Rune*
removeallwhite(Rune* s)
{
	int	j;
	int	n;
	int	i;
	int	c;
	Rune*	ans;

	j = 0;
	n = _Strlen(s);
	for(i = 0; i < n; i++) {
		c = s[i];
		if(c >= 256 || !isspace(c))
			j++;
	}
	if(j < n) {
		ans = _newstr(j);
		j = 0;
		for(i = 0; i < n; i++) {
			c = s[i];
			if(c >= 256 || !isspace(c))
				ans[j++] = c;
		}
		ans[j] = 0;
	}
	else
		ans = _Strdup(s);
	return ans;
}

// Attribute value when mere presence of attr implies value of 1,
// but if there is an integer there, return it as the value.
static int
aflagval(Token* tok, int attid)
{
	int	val;
	Rune*	sval;

	val = 0;
	if(_tokaval(tok, attid, &sval, 0)) {
		val = 1;
		if(sval != nil)
			val = toint(sval);
	}
	return val;
}

static Align
makealign(int halign, int valign)
{
	Align	al;

	al.halign = halign;
	al.valign = valign;
	return al;
}

// Make an Align (two alignments, horizontal and vertical)
static Align
aalign(Token* tok)
{
	return makealign(
		atabval(tok, Aalign, align_tab, NALIGNTAB, ALnone),
		atabval(tok, Avalign, align_tab, NALIGNTAB, ALnone));
}

// Make a Dimen, based on value of attid attr
static Dimen
adimen(Token* tok, int attid)
{
	Rune*	wd;

	if(_tokaval(tok, attid, &wd, 0))
		return parsedim(wd, _Strlen(wd));
	else
		return makedimen(Dnone, 0);
}

// Parse s[0:n] as num[.[num]][unit][%|*]
static Dimen
parsedim(Rune* s, int ns)
{
	int	kind;
	int	spec;
	Rune*	l;
	int	nl;
	Rune*	r;
	int	nr;
	int	mul;
	int	i;
	Rune*	f;
	int	nf;
	int	Tkdpi;
	Rune*	units;

	kind = Dnone;
	spec = 0;
	_splitl(s, ns, L(Lnot0to9), &l, &nl, &r, &nr);
	if(nl != 0) {
		spec = 1000*_Strtol(l, nil, 10);
		if(nr > 0 && r[0] == '.') {
			_splitl(r+1, nr-1, L(Lnot0to9), &f, &nf, &r, &nr);
			if(nf != 0) {
				mul = 100;
				for(i = 0; i < nf; i++) {
					spec = spec + mul*(f[i]-'0');
					mul = mul/10;
				}
			}
		}
		kind = Dpixels;
		if(nr != 0) {
			if(nr >= 2) {
				Tkdpi = 100;
				units = r;
				r = r+2;
				nr -= 2;
				if(!_Strncmpci(units, 2, L(Lpt)))
					spec = (spec*Tkdpi)/72;
				else if(!_Strncmpci(units, 2, L(Lpi)))
					spec = (spec*12*Tkdpi)/72;
				else if(!_Strncmpci(units, 2, L(Lin)))
					spec = spec*Tkdpi;
				else if(!_Strncmpci(units, 2, L(Lcm)))
					spec = (spec*100*Tkdpi)/254;
				else if(!_Strncmpci(units, 2, L(Lmm)))
					spec = (spec*10*Tkdpi)/254;
				else if(!_Strncmpci(units, 2, L(Lem)))
					spec = spec*15;
				else {
					if(warn)
						fprint(2, "warning: unknown units %C%Cs\n", units[0], units[1]);
				}
			}
			if(nr >= 1) {
				if(r[0] == '%')
					kind = Dpercent;
				else if(r[0] == '*')
					kind = Drelative;
			}
		}
		spec = spec/1000;
	}
	else if(nr == 1 && r[0] == '*') {
		spec = 1;
		kind = Drelative;
	}
	return makedimen(kind, spec);
}

static void
setdimarray(Token* tok, int attid, Dimen** pans, int* panslen)
{
	Rune*	s;
	Dimen*	d;
	int	k;
	int	nc;
	Rune* a[SMALLBUFSIZE];
	int	an[SMALLBUFSIZE];

	if(_tokaval(tok, attid, &s, 0)) {
		nc = _splitall(s, _Strlen(s), L(Lcommaspace), a, an, SMALLBUFSIZE);
		if(nc > 0) {
			d = (Dimen*)emalloc(nc * sizeof(Dimen));
			for(k = 0; k < nc; k++) {
				d[k] = parsedim(a[k], an[k]);
			}
			*pans = d;
			*panslen = nc;
			return;
		}
	}
	*pans = nil;
	*panslen = 0;
}

static Background
makebackground(Rune* imageurl, int color)
{
	Background bg;

	bg.image = imageurl;
	bg.color = color;
	return bg;
}

static Item*
newitext(Rune* s, int fnt, int fg, int voff, int ul)
{
	Itext* t;

	assert(s != nil);
	t = (Itext*)emalloc(sizeof(Itext));
	t->item.tag = Itexttag;
	t->s = s;
	t->fnt = fnt;
	t->fg = fg;
	t->voff = voff;
	t->ul = ul;
	return (Item*)t;
}

static Item*
newirule(int align, int size, int noshade, Dimen wspec)
{
	Irule* r;

	r = (Irule*)emalloc(sizeof(Irule));
	r->item.tag = Iruletag;
	r->align = align;
	r->size = size;
	r->noshade = noshade;
	r->wspec = wspec;
	return (Item*)r;
}

// Map is owned elsewhere.
static Item*
newiimage(Rune* src, Rune* altrep, int align, int width, int height,
		int hspace, int vspace, int border, int ismap, Map* map)
{
	Iimage* i;
	int	state;

	state = 0;
	if(ismap)
		state = IFsmap;
	i = (Iimage*)emalloc(sizeof(Iimage));
	i->item.tag = Iimagetag;
	i->item.state = state;
	i->imsrc = src;
	i->altrep = altrep;
	i->align = align;
	i->imwidth = width;
	i->imheight = height;
	i->hspace = hspace;
	i->vspace = vspace;
	i->border = border;
	i->map = map;
	i->ctlid = -1;
	return (Item*)i;
}

static Item*
newiformfield(Formfield* ff)
{
	Iformfield* f;

	f = (Iformfield*)emalloc(sizeof(Iformfield));
	f->item.tag = Iformfieldtag;
	f->formfield = ff;
	return (Item*)f;
}

static Item*
newitable(Table* tab)
{
	Itable* t;

	t = (Itable*)emalloc(sizeof(Itable));
	t->item.tag = Itabletag;
	t->table = tab;
	return (Item*)t;
}

static Item*
newifloat(Item* it, int side)
{
	Ifloat* f;

	f = (Ifloat*)emalloc(sizeof(Ifloat));
	f->_item.tag = Ifloattag;
	f->_item.state = IFwrap;
	f->item = it;
	f->side = side;
	return (Item*)f;
}

static Item*
newispacer(int spkind)
{
	Ispacer* s;

	s = (Ispacer*)emalloc(sizeof(Ispacer));
	s->item.tag = Ispacertag;
	s->spkind = spkind;
	return (Item*)s;
}

// Free one item (caller must deal with next pointer)
static void
freeitem(Item* it)
{
	Iimage* ii;
	Genattr* ga;

	if(it == nil)
		return;

	switch(it->tag) {
	case Itexttag:
		free(((Itext*)it)->s);
		break;
	case Iimagetag:
		ii = (Iimage*)it;
		free(ii->imsrc);
		free(ii->altrep);
		break;
	case Iformfieldtag:
		freeformfield(((Iformfield*)it)->formfield);
		break;
	case Itabletag:
		freetable(((Itable*)it)->table);
		break;
	case Ifloattag:
		freeitem(((Ifloat*)it)->item);
		break;
	}
	ga = it->genattr;
	if(ga != nil) {
		free(ga->id);
		free(ga->class);
		free(ga->style);
		free(ga->title);
		freescriptevents(ga->events);
	}
	free(it);
}

// Free list of items chained through next pointer
void
freeitems(Item* ithead)
{
	Item* it;
	Item* itnext;

	it = ithead;
	while(it != nil) {
		itnext = it->next;
		freeitem(it);
		it = itnext;
	}
}

static void
freeformfield(Formfield* ff)
{
	Option* o;
	Option* onext;

	if(ff == nil)
		return;

	free(ff->name);
	free(ff->value);
	for(o = ff->options; o != nil; o = onext) {
		onext = o->next;
		free(o->value);
		free(o->display);
	}
	free(ff);
}

static void
freetable(Table* t)
{
	int i;
	Tablecell* c;
	Tablecell* cnext;

	if(t == nil)
		return;

	// We'll find all the unique cells via t->cells and next pointers.
	// (Other pointers to cells in the table are duplicates of these)
	for(c = t->cells; c != nil; c = cnext) {
		cnext = c->next;
		freeitems(c->content);
	}
	if(t->grid != nil) {
		for(i = 0; i < t->nrow; i++)
			free(t->grid[i]);
		free(t->grid);
	}
	free(t->rows);
	free(t->cols);
	freeitems(t->caption);
	free(t);
}

static void
freeform(Form* f)
{
	if(f == nil)
		return;

	free(f->name);
	free(f->action);
	// Form doesn't own its fields (Iformfield items do)
	free(f);
}

static void
freeforms(Form* fhead)
{
	Form* f;
	Form* fnext;

	for(f = fhead; f != nil; f = fnext) {
		fnext = f->next;
		freeform(f);
	}
}

static void
freeanchor(Anchor* a)
{
	if(a == nil)
		return;

	free(a->name);
	free(a->href);
	free(a);
}

static void
freeanchors(Anchor* ahead)
{
	Anchor* a;
	Anchor* anext;

	for(a = ahead; a != nil; a = anext) {
		anext = a->next;
		freeanchor(a);
	}
}

static void
freedestanchor(DestAnchor* da)
{
	if(da == nil)
		return;

	free(da->name);
	free(da);
}

static void
freedestanchors(DestAnchor* dahead)
{
	DestAnchor* da;
	DestAnchor* danext;

	for(da = dahead; da != nil; da = danext) {
		danext = da->next;
		freedestanchor(da);
	}
}

static void
freearea(Area* a)
{
	if(a == nil)
		return;
	free(a->href);
	free(a->coords);
}

static void freekidinfos(Kidinfo* khead);

static void
freekidinfo(Kidinfo* k)
{
	if(k->isframeset) {
		free(k->rows);
		free(k->cols);
		freekidinfos(k->kidinfos);
	}
	else {
		free(k->src);
		free(k->name);
	}
	free(k);
}

static void
freekidinfos(Kidinfo* khead)
{
	Kidinfo* k;
	Kidinfo* knext;

	for(k = khead; k != nil; k = knext) {
		knext = k->next;
		freekidinfo(k);
	}
}

static void
freemap(Map* m)
{
	Area* a;
	Area* anext;

	if(m == nil)
		return;

	free(m->name);
	for(a = m->areas; a != nil; a = anext) {
		anext = a->next;
		freearea(a);
	}
	free(m);
}

static void
freemaps(Map* mhead)
{
	Map* m;
	Map* mnext;

	for(m = mhead; m != nil; m = mnext) {
		mnext = m->next;
		freemap(m);
	}
}

void
freedocinfo(Docinfo* d)
{
	if(d == nil)
		return;
	free(d->src);
	free(d->base);
	freeitem((Item*)d->backgrounditem);
	free(d->refresh);
	freekidinfos(d->kidinfo);
	freeanchors(d->anchors);
	freedestanchors(d->dests);
	freeforms(d->forms);
	freemaps(d->maps);
	// tables, images, and formfields are freed when
	// the items pointing at them are freed
	free(d);
}

// Currently, someone else owns all the memory
// pointed to by things in a Pstate.
static void
freepstate(Pstate* p)
{
	free(p);
}

static void
freepstatestack(Pstate* pshead)
{
	Pstate* p;
	Pstate* pnext;

	for(p = pshead; p != nil; p = pnext) {
		pnext = p->next;
		free(p);
	}
}

static int
Iconv(Fmt *f)
{
	Item*	it;
	Itext*	t;
	Irule*	r;
	Iimage*	i;
	Ifloat*	fl;
	int	state;
	Formfield*	ff;
	Rune*	ty;
	Tablecell*	c;
	Table*	tab;
	char*	p;
	int	cl;
	int	hang;
	int	indent;
	int	bi;
	int	nbuf;
	char	buf[BIGBUFSIZE];

	it = va_arg(f->args, Item*);
	bi = 0;
	nbuf = sizeof(buf);
	state = it->state;
	nbuf = nbuf-1;
	if(state&IFbrk) {
		cl = state&(IFcleft|IFcright);
		p = "";
		if(cl) {
			if(cl == (IFcleft|IFcright))
				p = " both";
			else if(cl == IFcleft)
				p = " left";
			else
				p = " right";
		}
		bi = snprint(buf, nbuf, "brk(%d%s)", (state&IFbrksp)? 1 : 0, p);
	}
	if(state&IFnobrk)
		bi += snprint(buf+bi, nbuf-bi, " nobrk");
	if(!(state&IFwrap))
		bi += snprint(buf+bi, nbuf-bi, " nowrap");
	if(state&IFrjust)
		bi += snprint(buf+bi, nbuf-bi, " rjust");
	if(state&IFcjust)
		bi += snprint(buf+bi, nbuf-bi, " cjust");
	if(state&IFsmap)
		bi += snprint(buf+bi, nbuf-bi, " smap");
	indent = (state&IFindentmask) >> IFindentshift;
	if(indent > 0)
		bi += snprint(buf+bi, nbuf-bi, " indent=%d", indent);
	hang = state&IFhangmask;
	if(hang > 0)
		bi += snprint(buf+bi, nbuf-bi, " hang=%d", hang);

	switch(it->tag) {
	case Itexttag:
		t = (Itext*)it;
		bi += snprint(buf+bi, nbuf-bi, " Text '%S', fnt=%d, fg=%x", t->s, t->fnt, t->fg);
		break;

	case Iruletag:
		r = (Irule*)it;
		bi += snprint(buf+bi, nbuf-bi, "Rule size=%d, al=%S, wspec=", r->size, stringalign(r->align));
		bi += dimprint(buf+bi, nbuf-bi, r->wspec);
		break;

	case Iimagetag:
		i = (Iimage*)it;
		bi += snprint(buf+bi, nbuf-bi,
			"Image src=%S, alt=%S, al=%S, w=%d, h=%d hsp=%d, vsp=%d, bd=%d, map=%S",
			i->imsrc, i->altrep? i->altrep : L(Lempty), stringalign(i->align), i->imwidth, i->imheight,
			i->hspace, i->vspace, i->border, i->map?i->map->name : L(Lempty));
		break;

	case Iformfieldtag:
		ff = ((Iformfield*)it)->formfield;
		if(ff->ftype == Ftextarea)
			ty = L(Ltextarea);
		else if(ff->ftype == Fselect)
			ty = L(Lselect);
		else {
			ty = _revlookup(input_tab, NINPUTTAB, ff->ftype);
			if(ty == nil)
				ty = L(Lnone);
		}
		bi += snprint(buf+bi, nbuf-bi, "Formfield %S, fieldid=%d, formid=%d, name=%S, value=%S",
			ty, ff->fieldid, ff->form->formid, ff->name?  ff->name : L(Lempty),
			ff->value? ff->value : L(Lempty));
		break;

	case Itabletag:
		tab = ((Itable*)it)->table;
		bi += snprint(buf+bi, nbuf-bi, "Table tableid=%d, width=", tab->tableid);
		bi += dimprint(buf+bi, nbuf-bi, tab->width);
		bi += snprint(buf+bi, nbuf-bi, ", nrow=%d, ncol=%d, ncell=%d, totw=%d, toth=%d\n",
			tab->nrow, tab->ncol, tab->ncell, tab->totw, tab->toth);
		for(c = tab->cells; c != nil; c = c->next)
			bi += snprint(buf+bi, nbuf-bi, "Cell %d.%d, at (%d,%d) ",
					tab->tableid, c->cellid, c->row, c->col);
		bi += snprint(buf+bi, nbuf-bi, "End of Table %d", tab->tableid);
		break;

	case Ifloattag:
		fl = (Ifloat*)it;
		bi += snprint(buf+bi, nbuf-bi, "Float, x=%d y=%d, side=%S, it=%I",
			fl->x, fl->y, stringalign(fl->side), fl->item);
		bi += snprint(buf+bi, nbuf-bi, "\n\t");
		break;

	case Ispacertag:
		p = "";
		switch(((Ispacer*)it)->spkind) {
		case ISPnull:
			p = "null";
			break;
		case ISPvline:
			p = "vline";
			break;
		case ISPhspace:
			p = "hspace";
			break;
		}
		bi += snprint(buf+bi, nbuf-bi, "Spacer %s ", p);
		break;
	}
	bi += snprint(buf+bi, nbuf-bi, " w=%d, h=%d, a=%d, anchor=%d\n",
			it->width, it->height, it->ascent, it->anchorid);
	buf[bi] = 0;
	return fmtstrcpy(f, buf);
}

// String version of alignment 'a'
static Rune*
stringalign(int a)
{
	Rune*	s;

	s = _revlookup(align_tab, NALIGNTAB, a);
	if(s == nil)
		s = L(Lnone);
	return s;
}

// Put at most nbuf chars of representation of d into buf,
// and return number of characters put
static int
dimprint(char* buf, int nbuf, Dimen d)
{
	int	n;
	int	k;

	n = 0;
	n += snprint(buf, nbuf, "%d", dimenspec(d));
	k = dimenkind(d);
	if(k == Dpercent)
		buf[n++] = '%';
	if(k == Drelative)
		buf[n++] = '*';
	return n;
}

void
printitems(Item* items, char* msg)
{
	Item*	il;

	fprint(2, "%s\n", msg);
	il = items;
	while(il != nil) {
		fprint(2, "%I", il);
		il = il->next;
	}
}

static Genattr*
newgenattr(Rune* id, Rune* class, Rune* style, Rune* title, SEvent* events)
{
	Genattr* g;

	g = (Genattr*)emalloc(sizeof(Genattr));
	g->id = id;
	g->class = class;
	g->style = style;
	g->title = title;
	g->events = events;
	return g;
}

static Formfield*
newformfield(int ftype, int fieldid, Form* form, Rune* name,
		Rune* value, int size, int maxlength, Formfield* link)
{
	Formfield* ff;

	ff = (Formfield*)emalloc(sizeof(Formfield));
	ff->ftype = ftype;
	ff->fieldid = fieldid;
	ff->form = form;
	ff->name = name;
	ff->value = value;
	ff->size = size;
	ff->maxlength = maxlength;
	ff->ctlid = -1;
	ff->next = link;
	return ff;
}

// Transfers ownership of value and display to Option.
static Option*
newoption(int selected, Rune* value, Rune* display, Option* link)
{
	Option *o;

	o = (Option*)emalloc(sizeof(Option));
	o->selected = selected;
	o->value = value;
	o->display = display;
	o->next = link;
	return o;
}

static Form*
newform(int formid, Rune* name, Rune* action, int target, int method, Form* link)
{
	Form* f;

	f = (Form*)emalloc(sizeof(Form));
	f->formid = formid;
	f->name = name;
	f->action = action;
	f->target = target;
	f->method = method;
	f->nfields = 0;
	f->fields = nil;
	f->next = link;
	return f;
}

static Table*
newtable(int tableid, Align align, Dimen width, int border,
	int cellspacing, int cellpadding, Background bg, Token* tok, Table* link)
{
	Table* t;

	t = (Table*)emalloc(sizeof(Table));
	t->tableid = tableid;
	t->align = align;
	t->width = width;
	t->border = border;
	t->cellspacing = cellspacing;
	t->cellpadding = cellpadding;
	t->background = bg;
	t->caption_place = ALbottom;
	t->caption_lay = nil;
	t->tabletok = tok;
	t->tabletok = nil;
	t->next = link;
	return t;
}

static Tablerow*
newtablerow(Align align, Background bg, int flags, Tablerow* link)
{
	Tablerow* tr;

	tr = (Tablerow*)emalloc(sizeof(Tablerow));
	tr->align = align;
	tr->background = bg;
	tr->flags = flags;
	tr->next = link;
	return tr;
}

static Tablecell*
newtablecell(int cellid, int rowspan, int colspan, Align align, Dimen wspec, int hspec,
		Background bg, int flags, Tablecell* link)
{
	Tablecell* c;

	c = (Tablecell*)emalloc(sizeof(Tablecell));
	c->cellid = cellid;
	c->lay = nil;
	c->rowspan = rowspan;
	c->colspan = colspan;
	c->align = align;
	c->flags = flags;
	c->wspec = wspec;
	c->hspec = hspec;
	c->background = bg;
	c->next = link;
	return c;
}

static Anchor*
newanchor(int index, Rune* name, Rune* href, int target, Anchor* link)
{
	Anchor* a;

	a = (Anchor*)emalloc(sizeof(Anchor));
	a->index = index;
	a->name = name;
	a->href = href;
	a->target = target;
	a->next = link;
	return a;
}

static DestAnchor*
newdestanchor(int index, Rune* name, Item* item, DestAnchor* link)
{
	DestAnchor* d;

	d = (DestAnchor*)emalloc(sizeof(DestAnchor));
	d->index = index;
	d->name = name;
	d->item = item;
	d->next = link;
	return d;
}

static SEvent*
newscriptevent(int type, Rune* script, SEvent* link)
{
	SEvent* ans;

	ans = (SEvent*)emalloc(sizeof(SEvent));
	ans->type = type;
	ans->script = script;
	ans->next = link;
	return ans;
}

static void
freescriptevents(SEvent* ehead)
{
	SEvent* e;
	SEvent* nexte;

	e = ehead;
	while(e != nil) {
		nexte = e->next;
		free(e->script);
		free(e);
		e = nexte;
	}
}

static Dimen
makedimen(int kind, int spec)
{
	Dimen d;

	if(spec&Dkindmask) {
		if(warn)
			fprint(2, "warning: dimension spec too big: %d\n", spec);
		spec = 0;
	}
	d.kindspec = kind|spec;
	return d;
}

int
dimenkind(Dimen d)
{
	return (d.kindspec&Dkindmask);
}

int
dimenspec(Dimen d)
{
	return (d.kindspec&Dspecmask);
}

static Kidinfo*
newkidinfo(int isframeset, Kidinfo* link)
{
	Kidinfo*	ki;

	ki = (Kidinfo*)emalloc(sizeof(Kidinfo));
	ki->isframeset = isframeset;
	if(!isframeset) {
		ki->flags = FRhscrollauto|FRvscrollauto;
		ki->marginw = FRKIDMARGIN;
		ki->marginh = FRKIDMARGIN;
		ki->framebd = 1;
	}
	ki->next = link;
	return ki;
}

static Docinfo*
newdocinfo(void)
{
	Docinfo*	d;

	d = (Docinfo*)emalloc(sizeof(Docinfo));
	resetdocinfo(d);
	return d;
}

static void
resetdocinfo(Docinfo* d)
{
	memset(d, 0, sizeof(Docinfo));
	d->background = makebackground(nil, White);
	d->text = Black;
	d->link = Blue;
	d->vlink = Blue;
	d->alink = Blue;
	d->target = FTself;
	d->chset = ISO_8859_1;
	d->scripttype = TextJavascript;
	d->frameid = -1;
}

// Use targetmap array to keep track of name <-> targetid mapping.
// Use real malloc(), and never free
static void
targetmapinit(void)
{
	targetmapsize = 10;
	targetmap = (StringInt*)emalloc(targetmapsize*sizeof(StringInt));
	memset(targetmap, 0, targetmapsize*sizeof(StringInt));
	targetmap[0].key = _Strdup(L(L_top));
	targetmap[0].val = FTtop;
	targetmap[1].key = _Strdup(L(L_self));
	targetmap[1].val = FTself;
	targetmap[2].key = _Strdup(L(L_parent));
	targetmap[2].val = FTparent;
	targetmap[3].key = _Strdup(L(L_blank));
	targetmap[3].val = FTblank;
	ntargets = 4;
}

int
targetid(Rune* s)
{
	int i;
	int n;

	n = _Strlen(s);
	if(n == 0)
		return FTself;
	for(i = 0; i < ntargets; i++)
		if(_Strcmp(s, targetmap[i].key) == 0)
			return targetmap[i].val;
	if(i >= targetmapsize) {
		targetmapsize += 10;
		targetmap = (StringInt*)erealloc(targetmap, targetmapsize*sizeof(StringInt));
	}
	targetmap[i].key = (Rune*)emalloc((n+1)*sizeof(Rune));
	memmove(targetmap[i].key, s, (n+1)*sizeof(Rune));
	targetmap[i].val = i;
	ntargets++;
	return i;
}

Rune*
targetname(int targid)
{
	int i;

	for(i = 0; i < ntargets; i++)
		if(targetmap[i].val == targid)
			return targetmap[i].key;
	return L(Lquestion);
}

// Convert HTML color spec to RGB value, returning dflt if can't.
// Argument is supposed to be a valid HTML color, or "".
// Return the RGB value of the color, using dflt if s
// is nil or an invalid color.
static int
color(Rune* s, int dflt)
{
	int v;
	Rune* rest;

	if(s == nil)
		return dflt;
	if(_lookup(color_tab, NCOLORS, s, _Strlen(s), &v))
		return v;
	if(s[0] == '#')
		s++;
	v = _Strtol(s, &rest, 16);
	if(*rest == 0)
		return v;
	return dflt;
}

// Debugging

#define HUGEPIX 10000

// A "shallow" validitem, that doesn't follow next links
// or descend into tables.
static int
validitem(Item* i)
{
	int ok;
	Itext* ti;
	Irule* ri;
	Iimage* ii;
	Ifloat* fi;
	int a;

	ok = (i->tag >= Itexttag && i->tag <= Ispacertag) &&
		(i->next == nil || validptr(i->next)) &&
		(i->width >= 0 && i->width < HUGEPIX) &&
		(i->height >= 0 && i->height < HUGEPIX) &&
		(i->ascent > -HUGEPIX && i->ascent < HUGEPIX) &&
		(i->anchorid >= 0) &&
		(i->genattr == nil || validptr(i->genattr));
	// also, could check state for ridiculous combinations
	// also, could check anchorid for within-doc-range
	if(ok)
		switch(i->tag) {
		case Itexttag:
			ti = (Itext*)i;
			ok = validStr(ti->s) &&
				(ti->fnt >= 0 && ti->fnt < NumStyle*NumSize) &&
				(ti->ul == ULnone || ti->ul == ULunder || ti->ul == ULmid);
			break;
		case Iruletag:
			ri = (Irule*)i;
			ok = (validvalign(ri->align) || validhalign(ri->align)) &&
				(ri->size >=0 && ri->size < HUGEPIX);
			break;
		case Iimagetag:
			ii = (Iimage*)i;
			ok = (ii->imsrc == nil || validptr(ii->imsrc)) &&
				(ii->item.width >= 0 && ii->item.width < HUGEPIX) &&
				(ii->item.height >= 0 && ii->item.height < HUGEPIX) &&
				(ii->imwidth >= 0 && ii->imwidth < HUGEPIX) &&
				(ii->imheight >= 0 && ii->imheight < HUGEPIX) &&
				(ii->altrep == nil || validStr(ii->altrep)) &&
				(ii->map == nil || validptr(ii->map)) &&
				(validvalign(ii->align) || validhalign(ii->align)) &&
				(ii->nextimage == nil || validptr(ii->nextimage));
			break;
		case Iformfieldtag:
			ok = validformfield(((Iformfield*)i)->formfield);
			break;
		case Itabletag:
			ok = validptr((Itable*)i);
			break;
		case Ifloattag:
			fi = (Ifloat*)i;
			ok = (fi->side == ALleft || fi->side == ALright) &&
				validitem(fi->item) &&
				(fi->item->tag == Iimagetag || fi->item->tag == Itabletag);
			break;
		case Ispacertag:
			a = ((Ispacer*)i)->spkind;
			ok = a==ISPnull || a==ISPvline || a==ISPhspace || a==ISPgeneral;
			break;
		default:
			ok = 0;
		}
	return ok;
}

// "deep" validation, that checks whole list of items,
// and descends into tables and floated tables.
// nil is ok for argument.
int
validitems(Item* i)
{
	int ok;
	Item* ii;

	ok = 1;
	while(i != nil && ok) {
		ok = validitem(i);
		if(ok) {
			if(i->tag == Itabletag) {
				ok = validtable(((Itable*)i)->table);
			}
			else if(i->tag == Ifloattag) {
				ii = ((Ifloat*)i)->item;
				if(ii->tag == Itabletag)
					ok = validtable(((Itable*)ii)->table);
			}
		}
		if(!ok) {
			fprint(2, "invalid item: %I\n", i);
		}
		i = i->next;
	}
	return ok;
}

static int
validformfield(Formfield* f)
{
	int ok;

	ok = (f->next == nil || validptr(f->next)) &&
		(f->ftype >= 0 && f->ftype <= Ftextarea) &&
		f->fieldid >= 0 &&
		(f->form == nil || validptr(f->form)) &&
		(f->name == nil || validStr(f->name)) &&
		(f->value == nil || validStr(f->value)) &&
		(f->options == nil || validptr(f->options)) &&
		(f->image == nil || validitem(f->image)) &&
		(f->events == nil || validptr(f->events));
	// when all built, should have f->fieldid < f->form->nfields,
	// but this may be called during build...
	return ok;
}

// "deep" validation -- checks cell contents too
static int
validtable(Table* t)
{
	int ok;
	int i, j;
	Tablecell* c;

	ok = (t->next == nil || validptr(t->next)) &&
		t->nrow >= 0 &&
		t->ncol >= 0 &&
		t->ncell >= 0 &&
		validalign(t->align) &&
		validdimen(t->width) &&
		(t->border >= 0 && t->border < HUGEPIX) &&
		(t->cellspacing >= 0 && t->cellspacing < HUGEPIX) &&
		(t->cellpadding >= 0 && t->cellpadding < HUGEPIX) &&
		validitems(t->caption) &&
		(t->caption_place == ALtop || t->caption_place == ALbottom) &&
		(t->totw >= 0 && t->totw < HUGEPIX) &&
		(t->toth >= 0 && t->toth < HUGEPIX) &&
		(t->tabletok == nil || validptr(t->tabletok));
	// during parsing, t->rows has list;
	// only when parsing is done is t->nrow set > 0
	if(ok && t->nrow > 0 && t->ncol > 0) {
		// table is "finished"
		for(i = 0; i < t->nrow && ok; i++) 
			ok = validtablerow(t->rows+i);
		for(j = 0; j < t->ncol && ok; j++)
			ok = validtablecol(t->cols+j);
		for(c = t->cells; c != nil && ok; c = c->next)
			ok = validtablecell(c);
		for(i = 0; i < t->nrow && ok; i++)
			for(j = 0; j < t->ncol && ok; j++)
				ok = validptr(t->grid[i][j]);
	}
	return ok;
}

static int
validvalign(int a)
{
	return a == ALnone || a == ALmiddle || a == ALbottom || a == ALtop || a == ALbaseline;
}

static int
validhalign(int a)
{
	return a == ALnone || a == ALleft || a == ALcenter || a == ALright ||
			a == ALjustify || a == ALchar;
}

static int
validalign(Align a)
{
	return validhalign(a.halign) && validvalign(a.valign);
}

static int
validdimen(Dimen d)
{
	int ok;
	int s;

	ok = 0;
	s = d.kindspec&Dspecmask;
	switch(d.kindspec&Dkindmask) {
	case Dnone:
		ok = s==0;
		break;
	case Dpixels:
		ok = s < HUGEPIX;
		break;
	case Dpercent:
	case Drelative:
		ok = 1;
		break;
	}
	return ok;
}

static int
validtablerow(Tablerow* r)
{
	return (r->cells == nil || validptr(r->cells)) &&
		(r->height >= 0 && r->height < HUGEPIX) &&
		(r->ascent > -HUGEPIX && r->ascent < HUGEPIX) &&
		validalign(r->align);
}

static int
validtablecol(Tablecol* c)
{
	return c->width >= 0 && c->width < HUGEPIX
		&& validalign(c->align);
}

static int
validtablecell(Tablecell* c)
{
	int ok;

	ok = (c->next == nil || validptr(c->next)) &&
		(c->nextinrow == nil || validptr(c->nextinrow)) &&
		(c->content == nil || validptr(c->content)) &&
		(c->lay == nil || validptr(c->lay)) &&
		c->rowspan >= 0 &&
		c->colspan >= 0 &&
		validalign(c->align) &&
		validdimen(c->wspec) &&
		c->row >= 0 &&
		c->col >= 0;
	if(ok) {
		if(c->content != nil)
			ok = validitems(c->content);
	}
	return ok;
}

static int
validptr(void* p)
{
	// TODO: a better job of this.
	// For now, just dereference, which cause a bomb
	// if not valid
	static char c;

	c = *((char*)p);
	return 1;
}

static int
validStr(Rune* s)
{
	return s != nil && validptr(s);
}
