Hello community, here is the log from the commit of package aha for openSUSE:Factory checked in at 2019-03-14 15:03:54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/aha (Old) and /work/SRC/openSUSE:Factory/.aha.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "aha" Thu Mar 14 15:03:54 2019 rev:3 rq:684981 version:0.5 Changes: -------- --- /work/SRC/openSUSE:Factory/aha/aha.changes 2017-05-20 14:32:17.411400388 +0200 +++ /work/SRC/openSUSE:Factory/.aha.new.28833/aha.changes 2019-03-14 15:04:00.959624948 +0100 @@ -1,0 +2,27 @@ +Thu Mar 14 10:54:07 UTC 2019 - Jan Engelhardt <[email protected]> + +- Use %make_install + +------------------------------------------------------------------- +Wed Mar 13 20:23:13 UTC 2019 - Matthias Eliasson <[email protected]> + +- Update to version 0.5 + * Added support for ansi vt220 character set using utf8 characters, useful for tables + * Added support for italic text (thanks to suve) + * Added support for crossed out text (thanks to suve) + * Added support for 8 bit colours (thanks to John Poole and suve) + * Added support for 24 bit colours + * Added rudimentary support for highlighting + * Fixed behaviour of ESC[7m "negative image" + * Fixed charset information in head based on used encoding (thanks to suve) + * Fixed ESC[27m "revert off" (thanks to suve) + * Escaping html special characters in title (thanks to suve) + * Not returning zero at unknown option error (thanks to suve) + * Refactored used colour scheme from int to enum (thanks to suve) + * Refactored error report using errstr (thanks to suve) + * Refactored code to avoid warnings (thanks to suve) + * Refactored options to an own struct (thanks to suve) + * Refactored color printing switch to an array (thanks to suve) + * Refactored application state to an own struct (thanks to suve) +- Run spec-cleaner +------------------------------------------------------------------- Old: ---- aha-0.4.10.6.tar.gz New: ---- aha-0.5.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ aha.spec ++++++ --- /var/tmp/diff_new_pack.d69Ntf/_old 2019-03-14 15:04:01.631624549 +0100 +++ /var/tmp/diff_new_pack.d69Ntf/_new 2019-03-14 15:04:01.631624549 +0100 @@ -1,7 +1,7 @@ # # spec file for package aha # -# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # Copyright (c) 2017, Martin Hauke <[email protected]> # # All modifications and additions to the file contributed by third parties @@ -13,19 +13,18 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: aha -Version: 0.4.10.6 +Version: 0.5 Release: 0 Summary: ANSI color to HTML converter -License: MPL-1.1 or LGPL-2.1+ +License: MPL-1.1 OR LGPL-2.1-or-later Group: System/Console -Url: https://github.com/theZiz/aha/ +URL: https://github.com/theZiz/aha/ Source: https://github.com/theZiz/aha/archive/%{version}.tar.gz#/%{name}-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-build %description aha (ANSI HTML Adapter) converts ANSI colors to HTML, e.g. if you @@ -40,12 +39,11 @@ make %{?_smp_mflags} %install -make install DESTDIR=%{buildroot} PREFIX=/usr %{?_smp_mflags} +%make_install PREFIX=%{_prefix} %files -%defattr(-,root,root) %doc CHANGELOG README.md %{_bindir}/aha -%{_mandir}/man1/aha.1%{ext_man} +%{_mandir}/man1/aha.1%{?ext_man} %changelog ++++++ aha-0.4.10.6.tar.gz -> aha-0.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aha-0.4.10.6/CHANGELOG new/aha-0.5/CHANGELOG --- old/aha-0.4.10.6/CHANGELOG 2017-03-28 09:26:15.000000000 +0200 +++ new/aha-0.5/CHANGELOG 2018-10-26 23:23:55.000000000 +0200 @@ -1,7 +1,26 @@ -Version 0.4.10.6 (recent): +Version 0.5 (recent): +- Added support for ansi vt220 character set using utf8 characters, useful for tables +- Added support for italic text (thanks to suve) +- Added support for crossed out text (thanks to suve) +- Added support for 8 bit colours (thanks to John Poole and suve) +- Added support for 24 bit colours +- Added rudimentary support for highlighting +- Fixed behaviour of ESC[7m "negative image" +- Fixed charset information in head based on used encoding (thanks to suve) +- Fixed ESC[27m "revert off" (thanks to suve) +- Escaping html special characters in title (thanks to suve) +- Not returning zero at unknown option error (thanks to suve) +- Refactored used colour scheme from int to enum (thanks to suve) +- Refactored error report using errstr (thanks to suve) +- Refactored code to avoid warnings (thanks to suve) +- Refactored options to an own struct (thanks to suve) +- Refactored color printing switch to an array (thanks to suve) +- Refactored application state to an own struct (thanks to suve) + +Version 0.4.10.6: - Fixed MANDIR according to the GNU Coding standards, the man file is now installed to $(PREFIX)/share/man instead of $(PREFIX)/man (thanks to Eddie Antonio Santos) -Version 0.4.10.5 (recent): +Version 0.4.10.5: - Fixed reset of blinking text Version 0.4.10.4: @@ -25,7 +44,7 @@ - Fixed urls (thanks to Jeroen Wiert Pluimers) - Fixed behaviour for non CSI codes (thanks to Jack Brear) -Version 0.4.8 (recent): +Version 0.4.8: - Fixed the behaviour of 1;30, which should be darkgray instead of black (thanks to Vincent Pelletier) Version 0.4.7.3: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aha-0.4.10.6/Makefile new/aha-0.5/Makefile --- old/aha-0.4.10.6/Makefile 2017-03-28 09:26:15.000000000 +0200 +++ new/aha-0.5/Makefile 2018-10-26 23:23:55.000000000 +0200 @@ -8,6 +8,8 @@ BINMODE?=0755 MANMODE?=644 +CFLAGS += -Wall -Wextra + all: aha aha: aha.c diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aha-0.4.10.6/aha.1 new/aha-0.5/aha.1 --- old/aha-0.4.10.6/aha.1 2017-03-28 09:26:15.000000000 +0200 +++ new/aha-0.5/aha.1 2018-10-26 23:23:55.000000000 +0200 @@ -1,4 +1,4 @@ -.TH aha 1 "March 28, 2017" "" "Ansi HTML Adapter" +.TH aha 1 "October 26, 2018" "" "Ansi HTML Adapter" .SH NAME @@ -65,10 +65,9 @@ This is not really a bug, but neither \fB<blink>\fP nor the css setting \fBtext-decoration:blink\fP work on modern browsers, so if one wants to see blinking text one has to use \fB\-\-stylesheet\fP and to redefine \fB.blink\fP to make it visible. But maybe we should just accept the death of blinking text... .SH AUTHOR -Copyleft Alexander Matthes aka Ziz 2017 +Copyleft Alexander Matthes aka Ziz 2018 .br [email protected] .SH SEE ALSO https://github.com/theZiz/aha - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/aha-0.4.10.6/aha.c new/aha-0.5/aha.c --- old/aha-0.4.10.6/aha.c 2017-03-28 09:26:15.000000000 +0200 +++ new/aha-0.5/aha.c 2018-10-26 23:23:55.000000000 +0200 @@ -17,25 +17,66 @@ For feedback and questions about my Files and Projects please mail me, Alexander Matthes (Ziz) , ziz_at_mailbox.org */ -#define AHA_VERSION "0.4.10.6" -#define AHA_YEAR "2017" +#define AHA_VERSION "0.5" +#define AHA_YEAR "2018" +#include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> +// table for vt220 character set, see also +// https://whitefiles.org/b1_s/1_free_guides/fg2cd/pgs/c03b.htm +const char ansi_vt220_character_set[256][16] = +{ + "␀","␁","␂","␃","␄","␅","␆","␇", //00..07 + "␈","␉","␊","␋","␌","␍","␎","␏", //08..0f + "␐","␑","␒","␓","␔","␕","␖","␗", //10..17 + "␘","␙","␚","␛","␜","␝","␞","␟", //18..1f + " " ,"!" ,"\"" ,"#" ,"$" ,"%" ,"&" ,"'" , //20..27 + "(" ,")" ,"*" ,"+" ,"," ,"-" ,"." ,"/" , //28..2f + "0" ,"1" ,"2" ,"3" ,"4" ,"5" ,"6" ,"7" , //30..37 + "8" ,"9" ,":" ,";" ,"<" ,"=" ,">" ,"?" , //38..3f + "@" ,"A" ,"B" ,"C" ,"D" ,"E" ,"F" ,"G" , //40..47 + "H" ,"I" ,"J" ,"K" ,"L" ,"M" ,"N" ,"O" , //48..4f + "P" ,"Q" ,"R" ,"S" ,"T" ,"U" ,"V" ,"W" , //50..57 + "X" ,"Y" ,"Z" ,"[" ,"\\" ,"]" ,"^" ,"_" , //58..5f + "`" ,"a" ,"b" ,"c" ,"d" ,"e" ,"f" ,"g" , //60..67 + "h" ,"i" ,"j" ,"k" ,"l" ,"m" ,"n" ,"o" , //68..6f + "p" ,"q" ,"r" ,"s" ,"t" ,"u" ,"v" ,"w" , //70..77 + "x" ,"y" ,"z" ,"{" ,"|" ,"}" ,"~" ,"␡", //78..7f + "◆","▒","␉","␌","␍","␊","°","±", //80..87 + "␀","␋","┘","┐","┌","└","┼","⎺", //88..8f + "⎻","─","⎼","⎽","├","┤","┴","┬", //90..97 + "│","≤","≥","π ","≠","£" ,"•","␡", //98..9f + "█","¡","¢","£"," " ,"¥" ," " ,"§", //a0..a7 + "¤","©","º","�qb;"," " ," " ," " ," " , //a8..af + "⎼","⎽","²","³","´","µ","¶","·", //b0..b7 + "¸","¹","º","»","¼","½","¾","¿", //b8..bf + "À","Á","Â","Ã","Ä","Å","Æ","Ç", //c0..c7 + "È","É","Ê","Ë","Ì","Í","Î","Ï", //c8..cf + " " ,"Ñ","Ò","Ó","Ô","Õ","Ö","Œ", //d0..d7 + "Ø","Ù","Ú","Û","Ü","Ÿ"," " ,"ß", //d8..df + "à","á","â","ã","ä","å","æ","ç", //e0..e7 + "è","é","ê","ë","ì","í","î","ï", //e8..ef + " " ,"ñ","ò","ó","ô","õ","ö","œ", //f0..f7 + "ø","ù","ú","û","ü","ÿ"," " ,"█", //f8..ff +}; + int getNextChar(register FILE* fp) { int c; if ((c = fgetc(fp)) != EOF) return c; - fprintf(stderr,"Unknown Error in File Parsing!\n"); - exit(1); + + perror("Error while parsing input"); + exit(EXIT_FAILURE); } typedef struct selem *pelem; typedef struct selem { unsigned char digit[8]; unsigned char digitcount; + long int value; pelem next; } telem; @@ -43,14 +84,17 @@ { pelem firstelem=NULL; pelem momelem=NULL; + unsigned char digit[8]; unsigned char digitcount=0; + long int value=0; + int pos=0; for (pos=0;pos<1024;pos++) { if (s[pos]=='[') continue; - if (s[pos]==';' || s[pos]==0) + if (s[pos]==';' || s[pos]==':' || s[pos]==0) { if (digitcount==0) { @@ -59,24 +103,35 @@ } pelem newelem=(pelem)malloc(sizeof(telem)); - for (unsigned char a=0;a<8;a++) - newelem->digit[a]=digit[a]; + if (newelem==NULL) + { + perror("Failed to allocate memory for parseInsert()"); + exit(EXIT_FAILURE); + } + + memcpy(newelem->digit, digit, sizeof(digit)); newelem->digitcount=digitcount; + newelem->value=value; newelem->next=NULL; + if (momelem==NULL) firstelem=newelem; else momelem->next=newelem; momelem=newelem; + digitcount=0; - memset(digit,0,8); + memset(digit,0,sizeof(digit)); + value=0; + if (s[pos]==0) break; } else - if (digitcount<8) + if (digitcount < sizeof(digit)) { digit[digitcount]=s[pos]-'0'; + value=(value*10)+digit[digitcount]; digitcount++; } } @@ -93,21 +148,103 @@ } } +void printHtml(char *text) { + while(1) { + switch(*text) { + case '\0': return; + + case '"': printf("""); break; + case '&': printf("&"); break; + case '<': printf("<"); break; + case '>': printf(">"); break; + + default: + putc(*text, stdout); + } + ++text; + } +} + +enum ColorScheme { + SCHEME_WHITE, + SCHEME_BLACK, + SCHEME_PINK +}; + +struct Options { + enum ColorScheme colorscheme; + char* filename; + FILE *fp; + int htop_fix; + int iso; + int line_break; + int no_header; + int stylesheet; + char *title; + int word_wrap; +}; + +int divide (int dividend, int divisor){ + div_t result; + result = div (dividend, divisor); + return result.quot; +} + +void make_rgb (int color_id, char str_rgb[12]){ + + if (color_id < 16 || color_id > 255) + return; + if (color_id >= 232) + { + int index = color_id - 232; + int grey = index * 256 / 24; + sprintf(str_rgb, "%d,%d,%d", grey, grey, grey); + return; + } + int index_R = divide((color_id - 16), 36); + int rgb_R; + if (index_R > 0){ + rgb_R = 55 + index_R * 40; + } else { + rgb_R = 0; + } + + int index_G = divide(((color_id - 16) % 36), 6); + int rgb_G; + if (index_G > 0){ + rgb_G = 55 + index_G * 40; + } else { + rgb_G = 0; + } + + int index_B = ((color_id - 16) % 6); + int rgb_B; + if (index_B > 0){ + rgb_B = 55 + index_B * 40; + } else { + rgb_B = 0; + } + sprintf(str_rgb, "%d,%d,%d", rgb_R, rgb_G, rgb_B); +} + #define VERSION_PRINTF_MAKRO \ printf("\033[1;31mAnsi Html Adapter\033[0m Version "AHA_VERSION"\n"); -int main(int argc,char* args[]) +struct Options parseArgs(int argc, char* args[]) { - char* filename=NULL; - register FILE *fp = stdin; - int colorshema=0; //0:normal, 1:black, 2:pink - int iso=-1; //utf8 - char stylesheet=0; - char htop_fix=0; - char line_break=0; - char* title=NULL; - char word_wrap=0; - char no_header=0; + struct Options opts = (struct Options){ + .colorscheme = SCHEME_WHITE, + .filename = NULL, + .fp = stdin, + .htop_fix = 0, + .iso = -1, + .line_break = 0, + .no_header = 0, + .stylesheet = 0, + .title = NULL, + .word_wrap = 0 + }; + //Searching Parameters for (int p = 1;p<argc;p++) { @@ -138,13 +275,13 @@ printf(" \033[5;[email protected]\033[0m\n"); printf(" \033[5;36mhttps://github.com/theZiz/aha\033[0m\n"); printf("This application is subject to the \033[1;34mMPL\033[0m or \033[1;34mLGPL\033[0m.\n"); - return 0; + exit(EXIT_SUCCESS); } else if ((strcmp(args[p],(char*)"--version")==0) || (strcmp(args[p],(char*)"-v")==0)) { VERSION_PRINTF_MAKRO - return 0; + exit(EXIT_SUCCESS); } else if ((strcmp(args[p],"--title")==0) || (strcmp(args[p],"-t")==0)) @@ -152,46 +289,46 @@ if (p+1>=argc) { fprintf(stderr,"No title given!\n"); - return 0; + exit(EXIT_FAILURE); } - title=args[p+1]; + opts.title=args[p+1]; p++; } else if ((strcmp(args[p],"--line-fix")==0) || (strcmp(args[p],"-l")==0)) { - htop_fix=1; + opts.htop_fix=1; } else if ((strcmp(args[p],"--no-header")==0) || (strcmp(args[p],"-n")==0)) { - no_header=1; + opts.no_header=1; } else if ((strcmp(args[p],"--word-wrap")==0) || (strcmp(args[p],"-w")==0)) - word_wrap=1; + opts.word_wrap=1; else if ((strcmp(args[p],"--black")==0) || (strcmp(args[p],"-b")==0)) - colorshema=1; + opts.colorscheme=SCHEME_BLACK; else if ((strcmp(args[p],"--pink")==0) || (strcmp(args[p],"-p")==0)) - colorshema=2; + opts.colorscheme=SCHEME_PINK; else if ((strcmp(args[p],"--stylesheet")==0) || (strcmp(args[p],"-s")==0)) - stylesheet=1; + opts.stylesheet=1; else if ((strcmp(args[p],"--iso")==0) || (strcmp(args[p],"-i")==0)) { if (p+1>=argc) { fprintf(stderr,"No ISO code given!\n"); - return 0; + exit(EXIT_FAILURE); } - iso = atoi(args[p+1]); - if (iso<1 || iso>16) + opts.iso = atoi(args[p+1]); + if (opts.iso<1 || opts.iso>16) { fprintf(stderr,"not a valid ISO code: ISO 8859-%s\n",args[p+1]); - return 0; + exit(EXIT_FAILURE); } p++; } @@ -201,152 +338,256 @@ if (p+1>=argc) { fprintf(stderr,"no file to read given after \"-f\"!\n"); - return 0; + exit(EXIT_FAILURE); } - fp = fopen(args[p+1],"r"); - if (fp==NULL) + opts.fp = fopen(args[p+1],"r"); + if (opts.fp==NULL) { - fprintf(stderr,"file \"%s\" not found!\n",args[p+1]); - return 0; + char *errstr = strerror(errno); + fprintf(stderr,"Failed to open file \"%s\": %s\n",args[p+1],errstr); + exit(EXIT_FAILURE); } p++; - filename=args[p]; + opts.filename=args[p]; } else { fprintf(stderr,"Unknown parameter \"%s\"\n",args[p]); - return 0; + exit(EXIT_FAILURE); } } - if (no_header == 0) + return opts; +} + +enum ColorMode { + MODE_3BIT, + MODE_8BIT, + MODE_24BIT +}; + +struct State { + int fc, bc; + int bold; + int italic; + int underline; + int blink; + int crossedout; + enum ColorMode fc_colormode; + enum ColorMode bc_colormode; + int highlighted; //for fc AND bc although not correct... +}; + +void swapColors(struct State *const state) { + if (state->bc_colormode == MODE_3BIT && state->bc == -1) + state->bc = 8; + + if (state->fc_colormode == MODE_3BIT && state->fc == -1) + state->fc = 9; + + int temp = state->bc; + state->bc = state->fc; + state->fc = temp; + + enum ColorMode temp_colormode = state->bc_colormode; + state->bc_colormode = state->fc_colormode; + state->fc_colormode = temp_colormode; +} + + +const struct State default_state = { + .fc = -1, //Standard Foreground Color //IRC-Color+8 + .bc = -1, //Standard Background Color //IRC-Color+8 + .bold = 0, + .italic = 0, + .underline = 0, + .blink = 0, + .crossedout = 0, + .fc_colormode = MODE_3BIT, + .bc_colormode = MODE_3BIT, + .highlighted = 0, +}; + +int statesDiffer(const struct State *const old, const struct State *const new) { + return + (old->fc != new->fc) || + (old->bc != new->bc) || + (old->bold != new->bold) || + (old->italic != new->italic) || + (old->underline != new->underline) || + (old->blink != new->blink) || + (old->crossedout != new->crossedout) || + (old->fc_colormode != new->fc_colormode) || + (old->bc_colormode != new->bc_colormode) || + (old->highlighted != new->highlighted); +} + + +void printHeader(const struct Options *opts) +{ + char encoding[16] = "UTF-8"; + if(opts->iso>0) snprintf(encoding, sizeof(encoding), "ISO-8859-%i", opts->iso); + + printf("<?xml version=\"1.0\" encoding=\"%s\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n", encoding); + printf("<!-- This file was created with the aha Ansi HTML Adapter. https://github.com/theZiz/aha -->\n"); + printf("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"); + printf("<head>\n<meta http-equiv=\"Content-Type\" content=\"application/xml+xhtml; charset=%s\" />\n", encoding); + + printf("<title>"); + printHtml(opts->title ? opts->title : opts->filename ? opts->filename : "stdin"); + printf("</title>\n"); + + int style_tag = 0; + if (opts->stylesheet) { - //Header: - if (iso<0) - printf("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"); - else - printf("<?xml version=\"1.0\" encoding=\"ISO-8859-%i\" ?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n",iso); - printf("<!-- This file was created with the aha Ansi HTML Adapter. https://github.com/theZiz/aha -->\n"); - printf("<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"); - printf("<head>\n<meta http-equiv=\"Content-Type\" content=\"application/xml+xhtml; charset=UTF-8\" />\n"); - if (title) - printf("<title>%s</title>\n",title); - else + printf("<style type=\"text/css\">\n"); + style_tag = 1; + + switch (opts->colorscheme) { - if (filename==NULL) - printf("<title>stdin</title>\n"); - else - printf("<title>%s</title>\n",filename); + case SCHEME_BLACK: printf("body {color: white; background-color: black;}\n"); + printf(".reset {color: white;}\n"); + printf(".bg-reset {background-color: black;}\n"); + printf(".inverted {color: black;}\n"); + printf(".bg-inverted {background-color: white;}\n"); + break; + case SCHEME_PINK: printf("body {background-color: pink;}\n"); + printf(".reset {color: black;}\n"); + printf(".bg-reset {background-color: pink;}\n"); + printf(".inverted {color: pink;}\n"); + printf(".bg-inverted {background-color: black;}\n"); + break; + default: printf(".reset {color: black;}\n"); + printf(".bg-reset {background-color: white;}\n"); + printf(".inverted {color: white;}\n"); + printf(".bg-inverted {background-color: black;}\n"); } - if (stylesheet) + if (opts->colorscheme != SCHEME_BLACK) { + printf(".dimgray {color: dimgray;}\n"); + printf(".red {color: red;}\n"); + printf(".green {color: green;}\n"); + printf(".yellow {color: olive;}\n"); + printf(".blue {color: blue;}\n"); + printf(".purple {color: purple;}\n"); + printf(".cyan {color: teal;}\n"); + printf(".white {color: gray;}\n"); + printf(".bg-black {background-color: black;}\n"); + printf(".bg-red {background-color: red;}\n"); + printf(".bg-green {background-color: green;}\n"); + printf(".bg-yellow {background-color: olive;}\n"); + printf(".bg-blue {background-color: blue;}\n"); + printf(".bg-purple {background-color: purple;}\n"); + printf(".bg-cyan {background-color: teal;}\n"); + printf(".bg-white {background-color: gray;}\n"); + } + else + { + printf(".dimgray {color: dimgray;}\n"); + printf(".red {color: red;}\n"); + printf(".green {color: lime;}\n"); + printf(".yellow {color: yellow;}\n"); + printf(".blue {color: #3333FF;}\n"); + printf(".purple {color: fuchsia;}\n"); + printf(".cyan {color: aqua;}\n"); + printf(".white {color: white;}\n"); + printf(".bg-black {background-color: black;}\n"); + printf(".bg-red {background-color: red;}\n"); + printf(".bg-green {background-color: lime;}\n"); + printf(".bg-yellow {background-color: yellow;}\n"); + printf(".bg-blue {background-color: #3333FF;}\n"); + printf(".bg-purple {background-color: fuchsia;}\n"); + printf(".bg-cyan {background-color: aqua;}\n"); + printf(".bg-white {background-color: white;}\n"); + } + printf(".underline {text-decoration: underline;}\n"); + printf(".bold {font-weight: bold;}\n"); + printf(".italic {font-style: italic;}\n"); + printf(".blink {text-decoration: blink;}\n"); + printf(".crossed-out {text-decoration: line-through;}\n"); + printf(".highlighted {filter: contrast(70%%) brightness(190%%);}\n"); + } + + if (opts->word_wrap) + { + if (!style_tag) { printf("<style type=\"text/css\">\n"); - switch (colorshema) - { - case 1: printf("body {color: white; background-color: black;}\n"); - printf(".reset {color: white;}\n"); - printf(".bg-reset {background-color: black;}\n"); - printf(".inverted {color: black;}\n"); - printf(".bg-inverted {background-color: white;}\n"); - break; - case 2: printf("body {background-color: pink;}\n"); - printf(".reset {color: black;}\n"); - printf(".bg-reset {background-color: pink;}\n"); - printf(".inverted {color: pink;}\n"); - printf(".bg-inverted {background-color: black;}\n"); - break; - default: printf(".reset {color: black;}\n"); - printf(".bg-reset {background-color: white;}\n"); - printf(".inverted {color: white;}\n"); - printf(".bg-inverted {background-color: black;}\n"); - } - if (colorshema!=1) - { - printf(".dimgray {color: dimgray;}\n"); - printf(".red {color: red;}\n"); - printf(".green {color: green;}\n"); - printf(".yellow {color: olive;}\n"); - printf(".blue {color: blue;}\n"); - printf(".purple {color: purple;}\n"); - printf(".cyan {color: teal;}\n"); - printf(".white {color: gray;}\n"); - printf(".bg-black {background-color: black;}\n"); - printf(".bg-red {background-color: red;}\n"); - printf(".bg-green {background-color: green;}\n"); - printf(".bg-yellow {background-color: olive;}\n"); - printf(".bg-blue {background-color: blue;}\n"); - printf(".bg-purple {background-color: purple;}\n"); - printf(".bg-cyan {background-color: teal;}\n"); - printf(".bg-white {background-color: gray;}\n"); - } - else - { - printf(".dimgray {color: dimgray;}\n"); - printf(".red {color: red;}\n"); - printf(".green {color: lime;}\n"); - printf(".yellow {color: yellow;}\n"); - printf(".blue {color: #3333FF;}\n"); - printf(".purple {color: fuchsia;}\n"); - printf(".cyan {color: aqua;}\n"); - printf(".white {color: white;}\n"); - printf(".bg-black {background-color: black;}\n"); - printf(".bg-red {background-color: red;}\n"); - printf(".bg-green {background-color: lime;}\n"); - printf(".bg-yellow {background-color: yellow;}\n"); - printf(".bg-blue {background-color: #3333FF;}\n"); - printf(".bg-purple {background-color: fuchsia;}\n"); - printf(".bg-cyan {background-color: aqua;}\n"); - printf(".bg-white {background-color: white;}\n"); - } - printf(".underline {text-decoration: underline;}\n"); - printf(".bold {font-weight: bold;}\n"); - printf(".blink {text-decoration: blink;}\n"); - printf("</style>\n"); - } - if (word_wrap) - { - printf("<style type=\"text/css\">pre {white-space: pre-wrap; white-space: -moz-pre-wrap !important;\n"); - printf("white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;}</style>\n"); - } - printf("</head>\n"); - if (stylesheet || ! colorshema) - printf("<body>\n"); - else - { - switch (colorshema) - { - case 1: printf("<body style=\"color:white; background-color:black\">\n"); break; - case 2: printf("<body style=\"background-color:pink\">\n"); break; - } + style_tag = 1; } - //default values: - //printf("<div style=\"font-family:monospace; white-space:pre\">"); - printf("<pre>\n"); + printf("pre {white-space: pre-wrap; white-space: -moz-pre-wrap !important;\n"); + printf("white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;}\n"); + } + + if (style_tag) + printf("</style>\n"); + printf("</head>\n"); + + if (opts->stylesheet) + { + printf("<body>\n"); + } + else + { + switch (opts->colorscheme) + { + case SCHEME_BLACK: printf("<body style=\"color:white; background-color:black\">\n"); break; + case SCHEME_PINK: printf("<body style=\"background-color:pink\">\n"); break; + case SCHEME_WHITE: printf("<body>\n"); break; + } } + printf("<pre>\n"); +} + +int main(int argc,char* args[]) +{ + struct Options opts = parseArgs(argc, args); + register FILE* fp = opts.fp; + + char* fcstyle[10] = { + opts.stylesheet ? "dimgray " : "color:dimgray;", //Black + opts.stylesheet ? "red " : "color:red;", //Red + opts.stylesheet ? "green " : opts.colorscheme==SCHEME_BLACK ? "color:lime;" : "color:green;", //Green + opts.stylesheet ? "yellow " : opts.colorscheme==SCHEME_BLACK ? "color:yellow;" : "color:olive;", //Yellow + opts.stylesheet ? "blue " : opts.colorscheme==SCHEME_BLACK ? "color:#3333FF;" : "color:blue;", //Blue + opts.stylesheet ? "purple " : opts.colorscheme==SCHEME_BLACK ? "color:fuchsia;" : "color:purple;", //Purple + opts.stylesheet ? "cyan " : opts.colorscheme==SCHEME_BLACK ? "color:aqua;" : "color:teal;", //Cyan + opts.stylesheet ? "white " : opts.colorscheme==SCHEME_BLACK ? "color:white;" : "color:gray;", //White + opts.stylesheet ? "inverted " : opts.colorscheme==SCHEME_BLACK ? "color:black;" : opts.colorscheme==SCHEME_PINK ? "color:pink;" : "color:white;", //Background + opts.stylesheet ? "reset " : opts.colorscheme==SCHEME_BLACK ? "color:white;" : "color:black;" //Foreground + }; + + char* bcstyle[10] = { + opts.stylesheet ? "bg-black " : "background-color:black;", //Black + opts.stylesheet ? "bg-red " : "background-color:red;", //Red + opts.stylesheet ? "bg-green " : opts.colorscheme==SCHEME_BLACK ? "background-color:lime;" : "background-color:green;", //Green + opts.stylesheet ? "bg-yellow " : opts.colorscheme==SCHEME_BLACK ? "background-color:yellow;" : "background-color:olive;", //Yellow + opts.stylesheet ? "bg-blue " : opts.colorscheme==SCHEME_BLACK ? "background-color:#3333FF;" : "background-color:blue;", //Blue + opts.stylesheet ? "bg-purple " : opts.colorscheme==SCHEME_BLACK ? "background-color:fuchsia;" : "background-color:purple;", //Purple + opts.stylesheet ? "bg-cyan " : opts.colorscheme==SCHEME_BLACK ? "background-color:aqua;" : "background-color:teal;", //Cyan + opts.stylesheet ? "bg-white " : opts.colorscheme==SCHEME_BLACK ? "background-color:white;" : "background-color:gray;", //White + opts.stylesheet ? "bg-reset " : opts.colorscheme==SCHEME_BLACK ? "background-color:black;" : opts.colorscheme==SCHEME_PINK ? "background-color:pink;" : "background-color:white;", //Background + opts.stylesheet ? "bg-inverted " : opts.colorscheme==SCHEME_BLACK ? "background-color:white;" : "background-color:black;", //Foreground + }; + + if (!opts.no_header) + printHeader(&opts); + //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 + struct State state = default_state; + struct State oldstate; + int c; + int negative = 0; //No negative image + int special_char = 0; //No special characters int line=0; int momline=0; int newline=-1; - int temp; while ((c=fgetc(fp)) != EOF) { if (c=='\033') { - //Saving old values - ofc=fc; - obc=bc; - oul=ul; - obo=bo; - obl=bl; + oldstate = state; //Searching the end (a letter) and safe the insert: c=getNextChar(fp); if ( c == '[' ) // CSI code, see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors @@ -369,79 +610,242 @@ 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 (mompos<momelem->digitcount && momelem->digit[mompos]==0) - mompos++; - if (mompos==momelem->digitcount) //only zeros => delete all + switch (momelem->value) { - 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+1<momelem->digitcount) // 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+1<momelem->digitcount) // 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 - } + case 0: // 0 - Reset all + state = default_state; + negative=0; special_char=0; + break; + + case 1: // 1 - Enable Bold + state.bold=1; + break; + + case 3: // 3 - Enable Italic + state.italic=1; + break; + + case 4: // 4 - Enable underline + state.underline=1; + break; + + case 5: // 5 - Slow Blink + state.blink=1; + break; + + case 7: // 7 - Inverse video + swapColors(&state); + negative = !negative; + break; + + case 9: // 9 - Enable Crossed-out + state.crossedout=1; + break; + + case 21: // 21 - Reset bold + case 22: // 22 - Not bold, not "high intensity" color + state.bold=0; + break; + + case 23: // 23 - Reset italic + state.italic=0; + break; + + case 24: // 23 - Reset underline + state.underline=0; + break; + + case 25: // 25 - Reset blink + state.blink=0; + break; + + case 27: // 27 - Reset Inverted + if (negative) + { + swapColors(&state); //7, 7X is not defined (and supported) + negative = 0; + } + break; + + case 29: // 29 - Reset crossed-out + state.crossedout=0; + break; + + case 30: + case 31: + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: // 3X - Set foreground color + { + int *dest = &(state.fc); + if (negative != 0) + dest=&(state.bc); + if (momelem->value == 38 && + momelem->next && + momelem->next->value == 5 && + momelem->next->next)// 38;5;<n> -> 8 Bit + { + momelem = momelem->next->next; + state.fc_colormode = MODE_8BIT; + if (momelem->value >=8 && momelem->value <=15) + { + state.highlighted = 1; + *dest = momelem->value-8; + } + else + { + state.highlighted = 0; + *dest = momelem->value; + } + } + else + if (momelem->value == 38 && + momelem->next && + momelem->next->value == 2 && + momelem->next->next)// 38;2;<n> -> 24 Bit + { + momelem = momelem->next->next; + pelem r,g,b; + r = momelem; + momelem = momelem->next; + g = momelem; + if ( momelem ) + momelem = momelem->next; + b = momelem; + if ( r && g && b ) + { + state.highlighted = 0; + state.fc_colormode = MODE_24BIT; + *dest = + (r->value & 255) * 65536 + + (g->value & 255) * 256 + + (b->value & 255); + } + } + else + { + state.fc_colormode = MODE_3BIT; + state.highlighted = 0; + *dest=momelem->value-30; + } + } + break; + + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: + case 48: + case 49: // 4X - Set background color + { + int *dest = &(state.bc); + if (negative != 0) + dest=&(state.fc); + if (momelem->value == 48 && + momelem->next && + momelem->next->value == 5 && + momelem->next->next)// 48;5;<n> -> 8 Bit + { + momelem = momelem->next->next; + state.bc_colormode = MODE_8BIT; + if (momelem->value >=8 && momelem->value <=15) + { + state.highlighted = 1; + *dest = momelem->value-8; + } + else + { + state.highlighted = 0; + *dest = momelem->value; + } + } + else + if (momelem->value == 48 && + momelem->next && + momelem->next->value == 2 && + momelem->next->next)// 48;2;<n> -> 24 Bit + { + momelem = momelem->next->next; + pelem r,g,b; + r = momelem; + momelem = momelem->next; + g = momelem; + if ( momelem ) + momelem = momelem->next; + b = momelem; + if ( r && g && b ) + { + state.bc_colormode = MODE_24BIT; + state.highlighted = 0; + *dest = + (r->value & 255) * 65536 + + (g->value & 255) * 256 + + (b->value & 255); + } + } + else + { + state.bc_colormode = MODE_3BIT; + state.highlighted = 0; + *dest=momelem->value-40; + } + } + break; + case 90: + case 91: + case 92: + case 93: + case 94: + case 95: + case 96: + case 97: // 9X - Set foreground color highlighted + { + int *dest = &(state.fc); + if (negative != 0) + dest=&(state.bc); + state.fc_colormode = MODE_3BIT; + state.highlighted = 1; + *dest=momelem->value-90; + } + break; + + case 100: + case 101: + case 102: + case 103: + case 104: + case 105: + case 106: + case 107: // 10X - Set background color highlighted + { + int *dest = &(state.bc); + if (negative != 0) + dest=&(state.fc); + state.bc_colormode = MODE_3BIT; + state.highlighted = 1; + *dest=momelem->value-100; + } + break; } momelem=momelem->next; } deleteParse(elem); break; case 'H': - if (htop_fix) //a little dirty ... + if (opts.htop_fix) //a little dirty ... { elem=parseInsert(buffer); pelem second=elem->next; @@ -454,191 +858,118 @@ newline=(newline+1)*10+second->digit[2]-1; deleteParse(elem); if (newline<line) - line_break=1; + opts.line_break=1; } break; } - if (htop_fix) - if (line_break) + if (opts.htop_fix) + if (opts.line_break) { for (;line<80;line++) printf(" "); } //Checking the differences - if ((fc!=ofc) || (bc!=obc) || (ul!=oul) || (bo!=obo) || (bl!=obl)) //ANY Change + if ( statesDiffer(&state, &oldstate) ) //ANY Change { - if ((ofc!=-1) || (obc!=-1) || (oul!=0) || (obo!=0) || (obl!=0)) + // If old state was different than the default one, close the current <span> + if (statesDiffer(&oldstate, &default_state)) printf("</span>"); - if ((fc!=-1) || (bc!=-1) || (ul!=0) || (bo!=0) || (bl!=0)) + // Open new <span> if current state differs from the default one + if (statesDiffer(&state, &default_state)) { - if (stylesheet) + if (opts.stylesheet) printf("<span class=\""); else printf("<span style=\""); - switch (fc) - { - case 0: if (stylesheet) - printf("dimgray "); - else - printf("color:dimgray;"); - break; //Black - case 1: if (stylesheet) - printf("red "); - else - printf("color:red;"); - break; //Red - case 2: if (stylesheet) - printf("green "); - else if (colorshema!=1) - printf("color:green;"); - else - printf("color:lime;"); - break; //Green - case 3: if (stylesheet) - printf("yellow "); - else if (colorshema!=1) - printf("color:olive;"); - else - printf("color:yellow;"); - break; //Yellow - case 4: if (stylesheet) - printf("blue "); - else if (colorshema!=1) - printf("color:blue;"); - else - printf("color:#3333FF;"); - break; //Blue - case 5: if (stylesheet) - printf("purple "); - else if (colorshema!=1) - printf("color:purple;"); - else - printf("color:fuchsia;"); - break; //Purple - case 6: if (stylesheet) - printf("cyan "); - else if (colorshema!=1) - printf("color:teal;"); - else - printf("color:aqua;"); - break; //Cyan - case 7: if (stylesheet) - printf("white "); - else if (colorshema!=1) - printf("color:gray;"); - else - printf("color:white;"); - break; //White - case 8: if (stylesheet) - printf("inverted "); - else if (colorshema==1) - printf("color:black;"); - else if (colorshema==2) - printf("color:pink;"); - else - printf("color:white;"); - break; //Background Colour - case 9: if (stylesheet) - printf("reset "); - else if (colorshema!=1) - printf("color:black;"); - else - printf("color:white;"); - break; //Foreground Color - } - switch (bc) - { - case 0: if (stylesheet) - printf("bg-black "); - else - printf("background-color:black;"); - break; //Black - case 1: if (stylesheet) - printf("bg-red "); - else - printf("background-color:red;"); - break; //Red - case 2: if (stylesheet) - printf("bg-green "); - else if (colorshema!=1) - printf("background-color:green;"); - else - printf("background-color:lime;"); - break; //Green - case 3: if (stylesheet) - printf("bg-yellow "); - else if (colorshema!=1) - printf("background-color:olive;"); - else - printf("background-color:yellow;"); - break; //Yellow - case 4: if (stylesheet) - printf("bg-blue "); - else if (colorshema!=1) - printf("background-color:blue;"); - else - printf("background-color:#3333FF;"); - break; //Blue - case 5: if (stylesheet) - printf("bg-purple "); - else if (colorshema!=1) - printf("background-color:purple;"); - else - printf("background-color:fuchsia;"); - break; //Purple - case 6: if (stylesheet) - printf("bg-cyan "); - else if (colorshema!=1) - printf("background-color:teal;"); - else - printf("background-color:aqua;"); - break; //Cyan - case 7: if (stylesheet) - printf("bg-white "); - else if (colorshema!=1) - printf("background-color:gray;"); - else - printf("background-color:white;"); - break; //White - case 8: if (stylesheet) - printf("bg-reset "); - else if (colorshema==1) - printf("background-color:black;"); - else if (colorshema==2) - printf("background-color:pink;"); - else - printf("background-color:white;"); - break; //Background Colour - case 9: if (stylesheet) - printf("bg-inverted "); - else if (colorshema!=1) - printf("background-color:black;"); - else - printf("background-color:white;"); - break; //Foreground Colour - } - if (ul) + if (state.underline) { - if (stylesheet) + if (opts.stylesheet) printf("underline "); else printf("text-decoration:underline;"); } - if (bo) + if (state.bold) { - if (stylesheet) + if (opts.stylesheet) printf("bold "); else printf("font-weight:bold;"); } - if (bl) + if (state.italic) + { + if (opts.stylesheet) + printf("italic "); + else + printf("font-style:italic;"); + } + if (state.blink) { - if (stylesheet) + if (opts.stylesheet) printf("blink "); else printf("text-decoration:blink;"); } - + if (state.crossedout) + { + if (opts.stylesheet) + printf("crossed-out "); + else + printf("text-decoration:line-through;"); + } + if (state.highlighted) + { + if (opts.stylesheet) + printf("highlighted "); + else + printf("filter: contrast(70%%) brightness(190%%);"); + } if (opts.stylesheet && + state.fc_colormode != MODE_3BIT && + (state.fc_colormode != MODE_8BIT || state.fc>15)) + printf("\" style=\""); + switch (state.fc_colormode) + { + case MODE_3BIT: + if (state.fc>=0 && state.fc<=9) printf("%s", fcstyle[state.fc]); + break; + case MODE_8BIT: + if (state.fc>=0 && state.fc<=7) + printf("%s", fcstyle[state.fc]); + else + { + char rgb[12]; + make_rgb(state.fc,rgb); + printf("color: rgb(%s);",rgb); + } + break; + case MODE_24BIT: + printf("color: #%06x;",state.fc); + break; + }; + if (opts.stylesheet && + !(state.fc_colormode != MODE_3BIT && + (state.fc_colormode != MODE_8BIT || state.fc>15)) && //already in style + state.bc_colormode != MODE_3BIT && + (state.bc_colormode != MODE_8BIT || state.bc>15)) + printf("\" style=\""); + switch (state.bc_colormode) + { + case MODE_3BIT: + if (state.bc>=0 && state.bc<=9) printf("%s", bcstyle[state.bc]); + break; + case MODE_8BIT: + if (state.bc>=0 && state.bc<=7) + printf("%s", bcstyle[state.bc]); + else + { + char rgb[12]; + make_rgb(state.bc,rgb); + printf("background-color: rgb(%s);",rgb); + } + break; + case MODE_24BIT: + printf("background-color: #%06x;",state.bc); + break; + }; printf("\">"); } } @@ -646,7 +977,9 @@ else if ( c == ']' ) //Operating System Command (OSC), ignoring for now { - while (c != 2 && c != 7) //STX and BEL end an OSC. + while (c != 2 && c != 7 && c!= 27) //STX, BEL or ESC end an OSC. + c = getNextChar(fp); + if ( c == 27 ) // expecting \ after ESC c = getNextChar(fp); } else @@ -656,10 +989,14 @@ //(US ASCII character set), "(A" (UK ASCII character set) and //"(0" (Graphic). This whole "standard" is fucked up. Really... c = getNextChar(fp); + if (c == '0') //we do not ignore ESC(0 ;) + special_char=1; + else + special_char=0; } } else - if (c==13 && htop_fix) + if (c==13 && opts.htop_fix) { for (;line<80;line++) printf(" "); @@ -670,11 +1007,11 @@ else if (c!=8) { line++; - if (line_break) + if (opts.line_break) { printf("\n"); line=0; - line_break=0; + opts.line_break=0; momline++; } if (newline>=0) @@ -686,17 +1023,26 @@ } newline=-1; } + //I want fall throught, so I ignore the gcc warning for this switch + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wimplicit-fallthrough=" switch (c) { case '&': printf("&"); break; - case '\"': printf("""); break; + case '\"': printf("""); break; case '<': printf("<"); break; case '>': printf(">"); break; - case '\n':case 13: momline++; - line=0; - default: printf("%c",c); + case '\n':case 13: + momline++; + line=0; + default: + if (special_char) + printf("%s",ansi_vt220_character_set[((int)c+32) & 255]); + else + printf("%c",c); } - if (iso>0) //only at ISOS + #pragma GCC diagnostic pop + if (opts.iso>0) //only at ISOS if ((c & 128)==128) //first bit set => there must be followbytes { int bits=2; @@ -711,11 +1057,12 @@ } } - //Footer - if ((fc!=-1) || (bc!=-1) || (ul!=0) || (bo!=0) || (bl!=0)) + // If current state is different than the default, there is a <span> open - close it + if (statesDiffer(&state, &default_state)) printf("</span>\n"); - if (no_header == 0) + //Footer + if (opts.no_header == 0) { printf("</pre>\n"); printf("</body>\n");
