add
This commit is contained in:
parent
49a1496cbb
commit
c42a1d3d61
31 changed files with 4745 additions and 2 deletions
287
src/cmd/htmlroff/html.c
Normal file
287
src/cmd/htmlroff/html.c
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue