]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/html2ms.c
kernel: keep segment locked for data2txt
[plan9front.git] / sys / src / cmd / html2ms.c
index ee314b281771541da43b6729f0eece5634771a00..770882858ecdced07c0b1566005b2e3bacb5fd50 100644 (file)
@@ -41,13 +41,15 @@ struct Text {
 };
 
 void eatwhite(void);
-Tag *parsetext(Text *, Tag *);
+void parsetext(Text *, Tag *);
 int parsetag(Tag *);
 int parseattr(Attr *);
 void flushtext(Text *);
 char* getattr(Tag *, char *);
 int gotattr(Tag *, char *, char *);
 int gotstyle(Tag *, char *, char *);
+void reparent(Text *, Tag *, Tag *);
+void debugtag(Tag *, char *);
 
 Biobuf in;
 
@@ -113,6 +115,12 @@ ongarbage(Text *text, Tag *tag)
        text->output = 0;
 }
 
+void
+onmeta(Text *, Tag *tag)
+{
+       tag->closing = 1;
+}
+
 void
 onp(Text *text, Tag *)
 {
@@ -436,11 +444,20 @@ endcell(Text *text, Tag *tag)
 void
 oncell(Text *text, Tag *tag)
 {
-       if(tabletag(tag) == nil)
+       Tag *tt;
+
+       if((tt = tabletag(tag)) == nil)
                return;
        if(cistrcmp(tag->tag, "tr")){
                Table *t;
 
+               tt = tag->up;
+               while(tt && cistrcmp(tt->tag, "tr"))
+                       tt = tt->up;
+               if(tt == nil)
+                       return;
+               reparent(text, tag, tt);
+
                t = mallocz(sizeof(*t), 1);
                t->save = *text;
                tag->aux = t;
@@ -450,7 +467,8 @@ oncell(Text *text, Tag *tag)
                text->nb = 0;
                text->pos = 0;
                text->space = 0;
-       }
+       } else
+               reparent(text, tag, tt);
        tag->close = endcell;
 }
 
@@ -475,8 +493,11 @@ struct {
        "head",         ongarbage,
        "hr",           onbr,
        "i",            oni,
+       "img",          onmeta,
        "kbd",          ontt,
        "li",           onli,
+       "link",         onmeta,
+       "meta",         onmeta,
        "p",            onp,
        "pre",          onpre,
        "q",            onquote,
@@ -485,12 +506,12 @@ struct {
        "small",        onsmall,
        "strong",       onb,
        "style",        ongarbage,
-       "tt",           ontt,
-       "var",          oni,
        "table",        ontable,
-       "tr",           oncell,
        "td",           oncell,
        "th",           oncell,
+       "tr",           oncell,
+       "tt",           ontt,
+       "var",          oni,
 };
 
 void
@@ -659,6 +680,8 @@ parserune(int c)
                        return '>';
                if(strcmp(buf, "quot") == 0)
                        return '"';
+               if(strcmp(buf, "apos") == 0)
+                       return '\'';
                if(strcmp(buf, "amp") == 0)
                        return '&';
                /* use tcs -f html to handle the rest. */
@@ -745,43 +768,68 @@ gotstyle(Tag *tag, char *style, char *val)
        return 1;
 }
 
-Tag*
+void
+reparent(Text *text, Tag *tag, Tag *up)
+{
+       Tag *old;
+
+       old = tag->up;
+       while(old != up){
+               debugtag(old, "reparent");
+               if(old->close){
+                       old->close(text, old);
+                       old->close = nil;
+               }
+               old = old->up;
+       }
+       tag->up = up;
+}
+
+
+void
 parsetext(Text *text, Tag *tag)
 {
        int hidden, c;
-       Tag *rtag;
+       Tag t, *up;
        Rune r;
 
-       rtag = tag;
-       debugtag(tag, "open");
-       hidden = tag ? (getattr(tag, "hidden") || gotstyle(tag, "display", "none")) : 0;
+       if(tag){
+               up = tag->up;
+               debugtag(tag, "open");
+               for(c = 0; c < nelem(ontag); c++){
+                       if(cistrcmp(tag->tag, ontag[c].tag) == 0){
+                               ontag[c].open(text, tag);
+                               break;
+                       }
+               }
+               hidden = getattr(tag, "hidden") || gotstyle(tag, "display", "none");
+       } else {
+               up = nil;
+               hidden = 0;
+       }
        if(tag == nil || tag->closing == 0){
                while((c = Bgetc(&in)) > 0){
                        if(c == '<'){
-                               Tag t;
-
                                memset(&t, 0, sizeof(t));
                                if(parsetag(&t)){
                                        text->aftertag = 1;
                                        if(t.opening){
                                                t.up = tag;
-                                               for(c = 0; c < nelem(ontag); c++){
-                                                       if(cistrcmp(t.tag, ontag[c].tag) == 0){
-                                                               ontag[c].open(text, &t);
-                                                               break;
-                                                       }
-                                               }
-                                               rtag = parsetext(text, &t);
-                                               if(rtag == &t)
-                                                       rtag = tag;
-                                               else
+                                               parsetext(text, &t);
+                                               if(t.up != tag){
+                                                       debugtag(tag, "skip");
+                                                       up = t.up;
                                                        break;
+                                               }
+                                               debugtag(tag, "back");
                                        } else if(t.closing){
-                                               while(rtag && cistrcmp(rtag->tag, t.tag))
-                                                       rtag = rtag->up;
-                                               if(rtag == nil)
-                                                       rtag = tag;
-                                               break;
+                                               up = tag;
+                                               while(up && cistrcmp(up->tag, t.tag))
+                                                       up = up->up;
+                                               if(up){
+                                                       up = up->up;
+                                                       break;
+                                               }
                                        }
                                }
                                continue;
@@ -819,10 +867,15 @@ parsetext(Text *text, Tag *tag)
                        }
                }
        }
-       debugtag(tag, "close");
-       if(tag && tag->close)
-               tag->close(text, tag);
-       return rtag;
+       if(tag){
+               debugtag(tag, "close");
+               if(tag->close){
+                       tag->close(text, tag);
+                       tag->close = nil;
+               }
+               if(up)
+                       tag->up = up;
+       }
 }
 
 void