/* XChat scrollback to HTML converter by NovaSquirrel */ #include #include #include #include #include char *Colors[] = { "#CCCCCC","#000000","#3636B2","#2A8C2A","#C33B3B","#C73232","#80267F","#66361F", "#D9A641","#3DCC3D","#1A5555","#2F8C74","#4545E6","#B037B0","#4C4C4C","#959595", }; void CopyHere(char **Here, char *Message) { strcpy(*Here, Message); *Here += strlen(Message); } void ProcessLogs(char *ChannelName, char *OutputDir, int MaxLines) { char Temp[512]; sprintf(Temp, "%s.txt", ChannelName); // printf("Attempting to open %s\n", Temp); FILE *LogsFile = fopen(Temp,"rb"); if(LogsFile == NULL) { puts("Failed!"); return; } ChannelName = strrchr(ChannelName, '#') + 1; fseek(LogsFile, 0, SEEK_END); long FileSize = ftell(LogsFile); rewind(LogsFile); char *Buffer = (char*)malloc(sizeof(char)*FileSize); if(Buffer == NULL) { fputs("Memory error",stderr); exit(2); } if(FileSize != fread(Buffer,1,FileSize,LogsFile)) { fputs("Reading error",stderr); exit(3); } fclose(LogsFile); // get number of lines int NumLines = 0; char *Peek = Buffer; while(Peek = strchr(Peek+1, '\n')) NumLines += 1; Peek = Buffer; if(NumLines > MaxLines) { int i; for(i=0;i!=NumLines-MaxLines;i++) Peek = strchr(Peek+1, '\n'); } // time to write the logs sprintf(Temp, "%s/%s.html", OutputDir, ChannelName); // printf("Attempting to open %s\n", Temp); FILE *HTML = fopen(Temp, "w"); if(HTML == NULL) { puts("Failed!"); return; } fprintf(HTML, "%s logs", ChannelName); fputs("", HTML); char Line[768]; int Done = 0; while(!Done) { char *Next = strchr(Peek, '\n'); if(Next != NULL) { *Next = 0; strcpy(Line, Peek); Peek = Next+1; } else { strcpy(Line, Peek); Done = 1; } char OutLine[8192]; char *PeekL = Line; char *Poke = OutLine; int IsBold = 0; int IsUnderline = 0; int IsReverse = 0; int IsColor = 0; int BGColor = 0; int FGColor = 0; int temp; int IsLink = 0; void CancelEffects() { if(IsBold) CopyHere(&Poke, ""); if(IsUnderline) CopyHere(&Poke, ""); if(IsColor) CopyHere(&Poke, ""); IsBold = 0; IsUnderline = 0; IsColor = 0; FGColor = 1; BGColor = -1; } if(*PeekL != 'T') continue; PeekL += 2; CopyHere(&Poke, "\n"); } fputs("
"); time_t Time = strtol(PeekL, &PeekL, 10); struct tm *timeinfo; timeinfo = localtime(&Time); strftime(Temp,80,"%I:%M%p",timeinfo); CopyHere(&Poke, Temp); CopyHere(&Poke, ""); int IsNick = 1; if(NULL == strchr(PeekL, '\t')) { CopyHere(&Poke, ""); IsNick = 0; } else CopyHere(&Poke, "
"); CopyHere(&Poke, ""); while(*PeekL == ' ' && *PeekL) PeekL++; char *PeekC; while(*PeekL) { if(IsLink && strchr(" <>\"'\r\n", *PeekL)) { CopyHere(&Poke, ""); IsLink = 0; } switch(*PeekL) { case ' ': if(IsNick || PeekL[-1] == ' ') CopyHere(&Poke, " "); else *(Poke++) = ' '; break; case '&': CopyHere(&Poke, "&"); break; case '<': CopyHere(&Poke, "<"); break; case '>': CopyHere(&Poke, ">"); break; case 0x1f: // underline if(!IsUnderline) CopyHere(&Poke, ""); else CopyHere(&Poke, ""); IsUnderline ^= 1; break; case 0x02: // bold if(!IsBold) CopyHere(&Poke, ""); else CopyHere(&Poke, ""); IsBold ^= 1; break; case 0x03: // colors PeekC = PeekL + 1; FGColor = -1; BGColor = -1; if(isdigit(*PeekC)) { FGColor = *(PeekC++) - '0'; if(isdigit(*PeekC)) { FGColor = (FGColor*10) + (*(PeekC++) - '0'); FGColor &= 15; } if(*PeekC == ',') { // background color! PeekC++; if(isdigit(*PeekC)) { BGColor = *(PeekC++) - '0'; if(isdigit(*PeekC)) { BGColor = (BGColor*10) + (*(PeekC++) - '0'); BGColor &= 15; } } } PeekL = PeekC - 1; } goto NoInvert; case 0x16: // swap BG and FG if(FGColor > 15 || BGColor > 15) { CancelEffects(); goto NoInvert; } if(FGColor == -1) FGColor = 17; if(BGColor == -1) BGColor = 16; temp = BGColor; BGColor = FGColor; FGColor = temp; NoInvert: CopyHere(&Poke, ""); break; case 0x0f: // cancel all effects CancelEffects(); break; case '\t': if(!IsNick) break; CancelEffects(); CopyHere(&Poke, ""); if(IsNick) CopyHere(&Poke, "
"); CopyHere(&Poke, "
"); break; case 'h': if(!memcmp(PeekL, "http://", 4) || !memcmp(PeekL, "https://", 4)) { CopyHere(&Poke, "\"'\r\n", *PeekC); PeekC++) *(Poke++) = *PeekC; CopyHere(&Poke, "\">"); IsLink = 1; } default: if(*PeekL >= 32) *(Poke++) = *PeekL; } PeekL++; } CopyHere(&Poke, ""); fputs(OutLine, HTML); CopyHere(&Poke, "
", HTML); fclose(HTML); free(Buffer); } int main(int argc, char *argv[]) { if(argc < 4) { puts("Syntax: scrollback2html MaxLines OutputFolder Log1 Log2 Log3..."); return 0; } int i; for(i = 3; i