]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/html2ms.c
webfs(4): document -d and -D flags
[plan9front.git] / sys / src / cmd / html2ms.c
index ee314b281771541da43b6729f0eece5634771a00..7f6e0825bc9781236c6d310d63e7bed59062f0ec 100644 (file)
@@ -33,7 +33,6 @@ struct Text {
        int     pos;
        int     space;
        int     output;
-       int     aftertag;
 
        char    *bp;
        char    *wp;
@@ -41,13 +40,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 +114,12 @@ ongarbage(Text *text, Tag *tag)
        text->output = 0;
 }
 
+void
+onmeta(Text *, Tag *tag)
+{
+       tag->closing = 1;
+}
+
 void
 onp(Text *text, Tag *)
 {
@@ -209,6 +216,71 @@ onb(Text *text, Tag *tag)
        fontstyle(text, "B");
 }
 
+void onsmall(Text *text, Tag *tag);
+void onsup(Text *text, Tag *tag);
+
+void
+onsub(Text *text, Tag *tag)
+{
+       emit(text, "\\v\'0.5\'");
+       if(cistrcmp(tag->tag, "sub") == 0){
+               emit(text, "\\x\'0.5\'");
+               onsmall(text, tag);
+       } else
+               restorefontsize(text, tag);
+       tag->close = onsup;
+}
+
+void
+onsup(Text *text, Tag *tag)
+{
+       emit(text, "\\v\'-0.5\'");
+       if(cistrcmp(tag->tag, "sup") == 0){
+               emit(text, "\\x\'-0.5\'");
+               onsmall(text, tag);
+       }else
+               restorefontsize(text, tag);
+       tag->close = onsub;
+}
+
+/*
+ * this is poor mans CSS handler.
+ */
+void
+onspan(Text *text, Tag *tag)
+{
+       Attr *a;
+
+       if(!tag->opening)
+               return;
+
+       for(a=tag->attr; a < tag->attr+tag->nattr; a++){
+               if(cistrcmp(a->attr, "class") != 0)
+                       continue;
+
+               if(cistrcmp(a->val, "bold") == 0){
+                       onb(text, tag);
+                       return;
+               }
+               if(cistrcmp(a->val, "italic") == 0){
+                       oni(text, tag);
+                       return;
+               }
+               if(cistrcmp(a->val, "subscript") == 0){
+                       strcpy(tag->tag, "sub");
+                       onsub(text, tag);
+                       strcpy(tag->tag, "span");
+                       return;
+               }
+               if(cistrcmp(a->val, "superscript") == 0){
+                       strcpy(tag->tag, "sup");
+                       onsup(text, tag);
+                       strcpy(tag->tag, "span");
+                       return;
+               }
+       }
+}
+
 void
 ontt(Text *text, Tag *tag)
 {
@@ -254,8 +326,6 @@ onquote(Text *text, Tag *tag)
 typedef struct Table Table;
 struct Table
 {
-       char    *fmt;
-
        char    *bp;
        int     nb;
 
@@ -264,6 +334,8 @@ struct Table
        int     enclose;
        int     brk;
 
+       char    fmt[4];
+
        Text    save;
 };
 
@@ -341,7 +413,7 @@ endtable(Text *text, Tag *tag)
                if(t->brk){
                        while(i < cols){
                                s = mallocz(sizeof(Table), 1);
-                               s->fmt = "L";
+                               strcpy(s->fmt, "L");
                                s->brk = t->brk;
                                t->brk = 0;
                                s->next = t->next;
@@ -424,9 +496,11 @@ endcell(Text *text, Tag *tag)
                        t->enclose = 1;
                }
                if(gotstyle(tag, "text-align", "center") || gotstyle(tt, "text-align", "center"))
-                       t->fmt = "c";
+                       strcpy(t->fmt, "C");
                else
-                       t->fmt = "L";
+                       strcpy(t->fmt, "L");
+               if(strcmp(tag->tag, "th") == 0)
+                       strcpy(t->fmt+1, "B");
                t->prev = tt->aux;
                tt->aux = t;
                *text = t->save;
@@ -436,11 +510,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 +533,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 +559,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 +572,15 @@ struct {
        "small",        onsmall,
        "strong",       onb,
        "style",        ongarbage,
-       "tt",           ontt,
-       "var",          oni,
        "table",        ontable,
-       "tr",           oncell,
        "td",           oncell,
        "th",           oncell,
+       "tr",           oncell,
+       "sub",          onsub,
+       "sup",          onsup,
+       "span",         onspan,
+       "tt",           ontt,
+       "var",          oni,
 };
 
 void
@@ -659,6 +749,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. */
@@ -694,7 +786,11 @@ substrune(Rune r)
 void
 debugtag(Tag *tag, char *dbg)
 {
-       if(1) return;
+       if(1){
+               USED(tag);
+               USED(dbg);
+               return;
+       }
 
        if(tag == nil)
                return;
@@ -745,43 +841,67 @@ 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;
@@ -792,8 +912,6 @@ parsetext(Text *text, Tag *tag)
                        switch(r){
                        case '\n':
                        case '\r':
-                               if(text->pre == 0 && text->aftertag)
-                                       break;
                        case ' ':
                        case '\t':
                                if(text->pre == 0){
@@ -814,15 +932,19 @@ parsetext(Text *text, Tag *tag)
                                if(r == 0xA0)
                                        r = ' ';
                                emitrune(text, r);
-                               text->aftertag = 0;
                                text->space = 0;
                        }
                }
        }
-       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