/*
 * Emit html.  Keep track of tags so that user doesn't have to.
 */

#include "a.h"

typedef struct Tag Tag;
struct Tag
{
	Tag *next;
	Rune *id;
	Rune *open;
	Rune *close;
};

Tag *tagstack;
Tag *tagset;
int hidingset;

static Rune*
closingtag(Rune *s)
{
	Rune *t;
	Rune *p0, *p;
	
	t = runemalloc(sizeof(Rune));
	if(s == nil)
		return t;
	for(p=s; *p; p++){
		if(*p == Ult){
			p++;
			if(*p == '/'){
				while(*p && *p != Ugt)
					p++;
				goto close;
			}
			p0 = p;
			while(*p && !isspacerune(*p) && *p != Uspace && *p != Ugt)
				p++;
			t = runerealloc(t, 1+(p-p0)+2+runestrlen(t)+1);
			runemove(t+(p-p0)+3, t, runestrlen(t)+1);
			t[0] = Ult;
			t[1] = '/';
			runemove(t+2, p0, p-p0);
			t[2+(p-p0)] = Ugt;
		}
		
		if(*p == Ugt && p>s && *(p-1) == '/'){
		close:
			for(p0=t+1; *p0 && *p0 != Ult; p0++)
				;
			runemove(t, p0, runestrlen(p0)+1);
		}
	}
	return t;	
}

void
html(Rune *id, Rune *s)
{
	Rune *es;
	Tag *t, *tt, *next;

	br();
	hideihtml();	/* br already did, but be paranoid */
	for(t=tagstack; t; t=t->next){
		if(runestrcmp(t->id, id) == 0){
			for(tt=tagstack;; tt=next){
				next = tt->next;
				free(tt->id);
				free(tt->open);
				out(tt->close);
				outrune('\n');
				free(tt->close);
				free(tt);
				if(tt == t){
					tagstack = next;
					goto cleared;
				}
			}
		}
	}

cleared:
	if(s == nil || s[0] == 0)
		return;
	out(s);
	outrune('\n');
	es = closingtag(s);
	if(es[0] == 0){
		free(es);
		return;
	}
	if(runestrcmp(id, L("-")) == 0){
		out(es);
		outrune('\n');
		free(es);
		return;
	}
	t = emalloc(sizeof *t);
	t->id = erunestrdup(id);
	t->close = es;
	t->next = tagstack;
	tagstack = t;
}

void
closehtml(void)
{
	Tag *t, *next;
	
	br();
	hideihtml();
	for(t=tagstack; t; t=next){
		next = t->next;
		out(t->close);
		outrune('\n');
		free(t->id);
		free(t->close);
		free(t);
	}
}

static void
rshow(Tag *t, Tag *end)
{
	if(t == nil || t == end)
		return;
	rshow(t->next, end);
	out(t->open);
}

void
ihtml(Rune *id, Rune *s)
{
	Tag *t, *tt, **l;

	for(t=tagset; t; t=t->next){
		if(runestrcmp(t->id, id) == 0){
			if(s && t->open && runestrcmp(t->open, s) == 0)
				return;
			for(l=&tagset; (tt=*l); l=&tt->next){
				if(!hidingset)
					out(tt->close);
				if(tt == t)
					break;
			}
			*l = t->next;
			free(t->id);
			free(t->close);
			free(t->open);
			free(t);
			if(!hidingset)
				rshow(tagset, *l);
			goto cleared;
		}
	}

cleared:
	if(s == nil || s[0] == 0)
		return;
	t = emalloc(sizeof *t);
	t->id = erunestrdup(id);
	t->open = erunestrdup(s);
	t->close = closingtag(s);
	if(!hidingset)
		out(s);
	t->next = tagset;
	tagset = t;
}

void
hideihtml(void)
{
	Tag *t;

	if(hidingset)
		return;
	hidingset = 1;
	for(t=tagset; t; t=t->next)
		out(t->close);
}

void
showihtml(void)
{
	if(!hidingset)
		return;
	hidingset = 0;
	rshow(tagset, nil);
}

int
e_lt(void)
{
	return Ult;
}

int
e_gt(void)
{
	return Ugt;
}

int
e_at(void)
{
	return Uamp;
}

int
e_tick(void)
{
	return Utick;
}

int
e_btick(void)
{
	return Ubtick;
}

int
e_minus(void)
{
	return Uminus;
}

void
r_html(Rune *name)
{
	Rune *id, *line, *p;
	
	id = copyarg();
	line = readline(HtmlMode);
	for(p=line; *p; p++){
		switch(*p){
		case '<':
			*p = Ult;
			break;
		case '>':
			*p = Ugt;
			break;
		case '&':
			*p = Uamp;
			break;
		case ' ':
			*p = Uspace;
			break;
		}
	}
	if(name[0] == 'i')
		ihtml(id, line);
	else
		html(id, line);
	free(id);
	free(line);
}

char defaultfont[] =
	".ihtml f1\n"
	".ihtml f\n"
	".ihtml f <span style=\"font-size: \\n(.spt\">\n"
	".if \\n(.f==2 .ihtml f1 <i>\n"
	".if \\n(.f==3 .ihtml f1 <b>\n"
	".if \\n(.f==4 .ihtml f1 <b><i>\n"
	".if \\n(.f==5 .ihtml f1 <tt>\n"
	".if \\n(.f==6 .ihtml f1 <tt><i>\n"
	"..\n"
;

void
htmlinit(void)
{
	addraw(L("html"), r_html);
	addraw(L("ihtml"), r_html);

	addesc('<', e_lt, CopyMode);
	addesc('>', e_gt, CopyMode);
	addesc('\'', e_tick, CopyMode);
	addesc('`', e_btick, CopyMode);
	addesc('-', e_minus, CopyMode);
	addesc('@', e_at, CopyMode);
	
	ds(L("font"), L(defaultfont));
}

