/* The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Alternatively, the contents of this file may be used under the terms of the GNU Lesser General Public license version 2 or later (LGPL2+), in which case the provisions of LGPL License are applicable instead of those above. For feedback and questions about my Files and Projects please mail me, Alexander Matthes (Ziz) , ziz_at_mailbox.org */ #include #include #include #include "../../src/www_tree.h" extern void unmangle_ansi(char *body, int len, char **body_out, int *body_len); typedef struct selem *pelem; typedef struct selem { unsigned char digit[8]; unsigned char digitcount; pelem next; } telem; pelem parseInsert(char* s) { pelem firstelem=NULL; pelem momelem=NULL; unsigned char digit[8]; unsigned char digitcount=0; int pos=0; for (pos=0;pos<1024;pos++) { if (s[pos]=='[') continue; if (s[pos]==';' || s[pos]==0) { if (digitcount==0) { digit[0]=0; digitcount=1; } pelem newelem=(pelem)malloc(sizeof(telem)); for (unsigned char a=0;a<8;a++) newelem->digit[a]=digit[a]; newelem->digitcount=digitcount; newelem->next=NULL; if (momelem==NULL) firstelem=newelem; else momelem->next=newelem; momelem=newelem; digitcount=0; memset(digit,0,8); if (s[pos]==0) break; } else if (digitcount<8) { digit[digitcount]=s[pos]-'0'; digitcount++; } } return firstelem; } void deleteParse(pelem elem) { while (elem!=NULL) { pelem temp=elem->next; free(elem); elem=temp; } } struct www_tag * aha(char *input, struct www_tag *parent) { //Searching Parameters char *unmangle_out; int unmangle_out_len; unmangle_ansi(input, strlen(input), &unmangle_out, &unmangle_out_len); unmangle_out[unmangle_out_len] = '\0'; //Begin of Conversion unsigned int c; int fc = -1; //Standard Foreground Color //IRC-Color+8 int bc = -1; //Standard Background Color //IRC-Color+8 int ul = 0; //Not underlined int bo = 0; //Not bold int bl = 0; //No Blinking int ofc,obc,oul,obo,obl; //old values int line=0; int momline=0; int newline=-1; int temp; char *ptr = unmangle_out; int size = 256; int outat = 0; char minibuf[2]; struct www_tag *child = NULL; stralloc data = EMPTY_STRALLOC; while (*ptr != '\0') { c = *ptr++; if (c=='\033') { //Saving old values ofc=fc; obc=bc; oul=ul; obo=bo; obl=bl; //Searching the end (a letter) and safe the insert: c= *ptr++; if (c == '\0') { return parent; } if ( c == '[' ) // CSI code, see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors { char buffer[1024]; buffer[0] = '['; int counter=1; while ((c<'A') || ((c>'Z') && (c<'a')) || (c>'z')) { c=*ptr++; if (c == '\0') { return parent; } buffer[counter]=c; if (c=='>') //end of htop break; counter++; if (counter>1022) break; } buffer[counter-1]=0; pelem elem; switch (c) { case 'm': //printf("\n%s\n",buffer); //DEBUG elem=parseInsert(buffer); pelem momelem=elem; while (momelem!=NULL) { //jump over zeros int mompos=0; while (momposdigitcount && momelem->digit[mompos]==0) mompos++; if (mompos==momelem->digitcount) //only zeros => delete all { bo=0;ul=0;bl=0;fc=-1;bc=-1; } else { switch (momelem->digit[mompos]) { case 1: if (mompos+1==momelem->digitcount) // 1, 1X not supported bo=1; break; case 2: if (mompos+1digitcount) // 2X, 2 not supported switch (momelem->digit[mompos+1]) { case 1: //Reset and double underline (which aha doesn't support) case 2: //Reset bold bo=0; break; case 4: //Reset underline ul=0; break; case 5: //Reset blink bl=0; break; case 7: //Reset Inverted if (bc == -1) bc = 8; if (fc == -1) fc = 9; temp = bc; bc = fc; fc = temp; break; } break; case 3: if (mompos+1digitcount) // 3X, 3 not supported fc=momelem->digit[mompos+1]; break; case 4: if (mompos+1==momelem->digitcount) // 4 ul=1; else // 4X bc=momelem->digit[mompos+1]; break; case 5: if (mompos+1==momelem->digitcount) //5, 5X not supported bl=1; break; //6 and 6X not supported at all case 7: if (bc == -1) //7, 7X is mot defined (and supported) bc = 8; if (fc == -1) fc = 9; temp = bc; bc = fc; fc = temp; break; //8 and 9 not supported } } momelem=momelem->next; } deleteParse(elem); break; } //Checking the differences if ((fc!=ofc) || (bc!=obc) || (ul!=oul) || (bo!=obo) || (bl!=obl)) //ANY Change { if ((fc!=-1) || (bc!=-1) || (ul!=0) || (bo!=0) || (bl!=0)) { if (data.len > 0) { stralloc_0(&data); struct www_tag *datatag = www_tag_new(NULL, data.s); free(data.s); data = EMPTY_STRALLOC; if (child == NULL) { www_tag_add_child(parent, datatag); } else { www_tag_add_child(child, datatag); www_tag_add_child(parent, child); } } child = www_tag_new("span", NULL); stralloc output = EMPTY_STRALLOC; switch (fc) { case 0: if (bo) { stralloc_cats(&output, "color:dimgray;"); } else { stralloc_cats(&output, "color:dimgray;"); } break; //Black case 1: if (bo) { stralloc_cats(&output, "color:#FF8888;"); } else { stralloc_cats(&output, "color:red;"); } break; //Red case 2: if (bo) { stralloc_cats(&output, "color:lime;"); } else { stralloc_cats(&output, "color:#00FF00;"); } break; //Green case 3: if (bo) { stralloc_cats(&output, "color:yellow;"); } else { stralloc_cats(&output, "color:olive;"); } break; //Yellow case 4: if (bo) { stralloc_cats(&output, "color:#8888FF;"); } else { stralloc_cats(&output, "color:#0000FF;"); } break; //Blue case 5: if (bo) { stralloc_cats(&output, "color:fuchsia;"); } else { stralloc_cats(&output, "color:#FF00FF;"); } break; //Purple case 6: if (bo) { stralloc_cats(&output, "color:aqua;"); } else { stralloc_cats(&output, "color:#008888;"); } break; //Cyan case 7: if (bo) { stralloc_cats(&output, "color:white;"); } else { stralloc_cats(&output, "color:grey;"); } break; //White case 8: stralloc_cats(&output, "color:black;"); break; //Background Colour case 9: stralloc_cats(&output, "color:white;"); break; //Foreground Color } switch (bc) { case 0: stralloc_cats(&output, "background-color:black;"); break; //Black case 1: stralloc_cats(&output, "background-color:red;"); break; //Red case 2: stralloc_cats(&output, "background-color:lime;"); break; //Green case 3: stralloc_cats(&output, "background-color:yellow;"); break; //Yellow case 4: stralloc_cats(&output, "background-color:#3333FF;"); break; //Blue case 5: stralloc_cats(&output, "background-color:fuchsia;"); break; //Purple case 6: stralloc_cats(&output, "background-color:aqua;"); break; //Cyan case 7: stralloc_cats(&output, "background-color:white;"); break; //White case 8: stralloc_cats(&output, "background-color:black;"); break; //Background Colour case 9: stralloc_cats(&output, "background-color:white;"); break; //Foreground Colour } if (ul) { stralloc_cats(&output, "text-decoration:underline;"); } if (bl) { stralloc_cats(&output, "text-decoration:blink;"); } stralloc_0(&output); www_tag_add_attrib(child, "style", output.s); free(output.s); } } } } else if (c!=8) { line++; switch (c) { case '\n': case 13: momline++; line=0; struct www_tag *brtag = www_tag_new("br", NULL); if (data.len > 0) { if (child != NULL) { stralloc_0(&data); struct www_tag *datatag = www_tag_new(NULL, data.s); free(data.s); data = EMPTY_STRALLOC; www_tag_add_child(child, datatag); www_tag_add_child(child, brtag); www_tag_add_child(parent, child); child = www_tag_duplicate(child); } else { stralloc_0(&data); struct www_tag *datatag = www_tag_new(NULL, data.s); free(data.s); data = EMPTY_STRALLOC; www_tag_add_child(parent, datatag); www_tag_add_child(parent, brtag); } } else { if (child != NULL) { www_tag_add_child(child, brtag); www_tag_add_child(parent, child); child = www_tag_duplicate(child); } else { www_tag_add_child(parent, brtag); } } break; default: { stralloc_append1(&data, c); break; } } } } if (data.len > 0) { stralloc_0(&data); struct www_tag *datatag = www_tag_new(NULL, data.s); free(data.s); data = EMPTY_STRALLOC; if (child == NULL) { www_tag_add_child(parent, datatag); } else { www_tag_add_child(child, datatag); www_tag_add_child(parent, child); } } free(unmangle_out); return parent; }