]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/html2ms.c
fix filetype detecton by suffix so that multiple dots dont confuse it. (thanks kvik)
[plan9front.git] / sys / src / cmd / html2ms.c
index 77cb85d754cdd9b90f59ce07916361647fea283d..7f6e0825bc9781236c6d310d63e7bed59062f0ec 100644 (file)
@@ -33,7 +33,6 @@ struct Text {
        int     pos;
        int     space;
        int     output;
-       int     aftertag;
 
        char    *bp;
        char    *wp;
@@ -217,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)
 {
@@ -262,8 +326,6 @@ onquote(Text *text, Tag *tag)
 typedef struct Table Table;
 struct Table
 {
-       char    *fmt;
-
        char    *bp;
        int     nb;
 
@@ -272,6 +334,8 @@ struct Table
        int     enclose;
        int     brk;
 
+       char    fmt[4];
+
        Text    save;
 };
 
@@ -285,23 +349,6 @@ tabletag(Tag *tag)
        return tabletag(tag->up);
 }
 
-void
-reparent(Text *text, Tag *tag, Tag *up)
-{
-       Tag *old;
-
-       old = tag->up;
-       while(old != up){
-               if(old->close){
-                       debugtag(old, "reparent close");
-                       old->close(text, old);
-                       old->close = nil;
-               }
-               old = old->up;
-       }
-       tag->up = up;
-}
-
 void
 dumprows(Text *text, Table *s, Table *e)
 {
@@ -366,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;
@@ -449,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;
@@ -510,6 +559,7 @@ struct {
        "head",         ongarbage,
        "hr",           onbr,
        "i",            oni,
+       "img",          onmeta,
        "kbd",          ontt,
        "li",           onli,
        "link",         onmeta,
@@ -526,6 +576,9 @@ struct {
        "td",           oncell,
        "th",           oncell,
        "tr",           oncell,
+       "sub",          onsub,
+       "sup",          onsup,
+       "span",         onspan,
        "tt",           ontt,
        "var",          oni,
 };
@@ -696,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. */
@@ -731,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;
@@ -782,14 +841,33 @@ gotstyle(Tag *tag, char *style, char *val)
        return 1;
 }
 
+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 t, *p;
+       Tag t, *up;
        Rune r;
 
        if(tag){
+               up = tag->up;
                debugtag(tag, "open");
                for(c = 0; c < nelem(ontag); c++){
                        if(cistrcmp(tag->tag, ontag[c].tag) == 0){
@@ -798,25 +876,32 @@ parsetext(Text *text, Tag *tag)
                        }
                }
                hidden = getattr(tag, "hidden") || gotstyle(tag, "display", "none");
-       } else
+       } else {
+               up = nil;
                hidden = 0;
+       }
        if(tag == nil || tag->closing == 0){
                while((c = Bgetc(&in)) > 0){
                        if(c == '<'){
                                memset(&t, 0, sizeof(t));
                                if(parsetag(&t)){
-                                       text->aftertag = 1;
                                        if(t.opening){
                                                t.up = tag;
                                                parsetext(text, &t);
-                                               if(t.up != tag)
+                                               if(t.up != tag){
+                                                       debugtag(tag, "skip");
+                                                       up = t.up;
                                                        break;
+                                               }
+                                               debugtag(tag, "back");
                                        } else if(t.closing){
-                                               p = tag;
-                                               while(p && cistrcmp(p->tag, t.tag))
-                                                       p = p->up;
-                                               if(p)
+                                               up = tag;
+                                               while(up && cistrcmp(up->tag, t.tag))
+                                                       up = up->up;
+                                               if(up){
+                                                       up = up->up;
                                                        break;
+                                               }
                                        }
                                }
                                continue;
@@ -827,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){
@@ -849,15 +932,18 @@ parsetext(Text *text, Tag *tag)
                                if(r == 0xA0)
                                        r = ' ';
                                emitrune(text, r);
-                               text->aftertag = 0;
                                text->space = 0;
                        }
                }
        }
        if(tag){
                debugtag(tag, "close");
-               if(tag->close)
+               if(tag->close){
                        tag->close(text, tag);
+                       tag->close = nil;
+               }
+               if(up)
+                       tag->up = up;
        }
 }