Select Git revision
-
Fredrik Hübinette (Hubbe) authored
Rev: tutorial/Html.pmod:1.1 Rev: tutorial/Sgml.pmod:1.1 Rev: tutorial/Wmml.pmod:1.1 Rev: tutorial/html.pike:1.1 Rev: tutorial/html_onepage.pike:1.1 Rev: tutorial/types.h:1.1 Rev: tutorial/wmmltohtml2:1.1
Fredrik Hübinette (Hubbe) authoredRev: tutorial/Html.pmod:1.1 Rev: tutorial/Sgml.pmod:1.1 Rev: tutorial/Wmml.pmod:1.1 Rev: tutorial/html.pike:1.1 Rev: tutorial/html_onepage.pike:1.1 Rev: tutorial/types.h:1.1 Rev: tutorial/wmmltohtml2:1.1
Sgml.pmod 3.06 KiB
string *from=({" ","&","<",">"});
string *to=({"","&","<",">"});
string unquote(string x) { return replace(x,from,to); }
string quote(string x) { return replace(x,to,from); }
class Tag
{
string tag;
int pos;
mapping(string:mixed) params=([]);
// array(Tag) data;
array(object) data;
varargs void create(string t, mapping p, int po, array(object) d)
{
tag=t; pos=po; params=p||([]); data=d;
}
};
#define TAG object(Tag)|string
#define SGML array(TAG)
SGML lex(string data)
{
mixed foo=data/"<";
SGML ret=({ unquote(foo[0]) });
int pos=strlen(foo[0]);
for(int e=1;e<sizeof(foo);e++)
{
string tag;
string s=foo[e];
pos++;
if(s[0..2]=="!--")
{
pos+=strlen(foo[e]);
while(sscanf(s,"%*s-->%s",s)!=2)
{
e++;
s+="<"+foo[e];
pos+=strlen(foo[e])+1;
}
ret[-1]+=unquote(s);
continue;
}
if(sscanf(s,"%[^ \t\n\r>]%s",tag,s)!=2)
werror(sprintf("Missing end > (around pos %d)\n",pos));
tag=lower_case(tag);
mapping params=([]);
while(1)
{
sscanf(s,"%*[ \t\r\n]%s",s);
if(!strlen(s))
{
write(sprintf("Missing end > (around pos %d)\n",pos));
break;
}
if(s[0]=='>')
{
s=s[1..];
break;
}
if(sscanf(s,"%[^ \t\r\n>=]%s",string key,s) && strlen(key))
{
key=lower_case(key);
if(s[0]=='=')
{
string val;
switch(s[1])
{
case '\'':
while(sscanf(s,"='%s'%s",val,s)!=2)
{
e++;
s+="<"+foo[e];
pos+=strlen(foo[e])+1;
}
break;
case '\"':
while(sscanf(s,"=\"%s\"%s",val,s)!=2)
{
e++;
s+="<"+foo[e];
pos+=strlen(foo[e])+1;
}
break;
default:
sscanf(s,"=%[^ \t\r\n>]%s",val,s);
break;
}
if(!val)
{
werror("Missing end quote parameter\n");
}
params[key]=val;
}else{
params[key]=1;
}
}
}
ret+=({ Tag(tag,params,pos), unquote(s) });
pos+=sizeof(foo[e]);
}
return ret;
}
SGML group(SGML data)
{
SGML ret=({});
foreach(data,TAG foo)
{
if(objectp(foo))
{
if(strlen(foo->tag) && foo->tag[0]=='/')
{
string tag=foo->tag[1..];
for(int d=sizeof(ret)-1;d>=0;d--)
{
if(objectp(ret[d]) && !ret[d]->data && ret[d]->tag==tag)
{
ret[d]->data=ret[d+1..];
ret=ret[..d];
break;
}
}
if(d>=0) continue;
}
}
ret+=({foo});
}
return ret;
}
string generate(SGML data)
{
string ret="";
foreach(data, TAG foo)
{
if(stringp(foo))
{
ret+=quote(foo);
}else{
ret+="<"+foo->tag;
foreach(indices(foo->params), string name)
ret+=" "+name+"="+foo->params[name];
ret+=">";
if(foo->data)
{
ret+=generate(foo->data);
ret+="</"+foo->tag+">";
}
}
}
return ret;
}
SGML copy(SGML data)
{
if(!data) return 0;
SGML ret=({});
foreach(data,TAG t)
{
if(stringp(t))
{
ret+=({t});
}else{
ret+=({Tag(t->tag,t->params+([]),t->pos,copy(t->data))});
}
}
return ret;
}
#ifdef TEST
int main()
{
write(sprintf("%O\n",group(lex(Stdio.read_file("tutorial.wmml")))));
}
#endif