#if 0 ctime -begin ${0%.*}.ctm gcc -g -fsanitize=address $0 -o ${0%.*} hmml.a ctime -end ${0%.*}.ctm exit #endif #include #include #include "hmmlib.h" #ifndef bool typedef bool unsigned int; #endif #define TRUE 1 #define FALSE 0 typedef struct { char *Location; char *Ptr; int Size; } buffer; int TimecodeToSeconds(char *Timecode) { int HMS[3] = { 0, 0, 0 }; // 0 == Seconds; 1 == Minutes; 2 == Hours int Colons = 0; while(*Timecode) { if((*Timecode < '0' || *Timecode > '9') && *Timecode != ':') { return FALSE; } if(*Timecode == ':') { ++Colons; if(Colons > 2) { return FALSE; } for(int i = 0; i < Colons; ++i) { HMS[Colons - i] = HMS[Colons - (i + 1)]; } HMS[0] = 0; } else { HMS[0] = HMS[0] * 10 + *Timecode - '0'; } ++Timecode; } if(HMS[0] > 59 || HMS[1] > 59 || Timecode[-1] == ':') { return FALSE; } return HMS[2] * 60 * 60 + HMS[1] * 60 + HMS[0]; } int main(int ArgC, char **Args) { if(ArgC < 2) { fprintf(stderr, "Usage: %s filename(s)\n", Args[0]); return 1; } // NOTE(matt): Init MemoryArena char *MemoryArena; int ArenaSize = 1024 * 64; if(!(MemoryArena = calloc(ArenaSize, 1))) { perror(Args[0]); return 1; } int ClaimedMemory = 0; // NOTE(matt): Setup buffers and ptrs char *InPtr; buffer Template; buffer Working; buffer Out; FILE *TemplateFile; if(!(TemplateFile = fopen("style.css", "r"))) { perror(Args[0]); return 1; } fseek(TemplateFile, 0, SEEK_END); Template.Size = ftell(TemplateFile); fseek(TemplateFile, 0, SEEK_SET); Template.Location = MemoryArena + ClaimedMemory; ClaimedMemory += Template.Size; fread(Template.Location, Template.Size, 1, TemplateFile); fclose(TemplateFile); Out.Location = MemoryArena + ClaimedMemory; Out.Size = 1024 * 32; ClaimedMemory += Out.Size; for(int FileIndex = 1; FileIndex < ArgC; ++FileIndex) { FILE *InFile; if(!(InFile = fopen(Args[FileIndex], "r"))) { perror(Args[0]); free(MemoryArena); return 1; } HMML_Output HMML = hmml_parse_file(InFile); fclose(InFile); if(HMML.well_formed) { Working.Location = MemoryArena + ClaimedMemory; Working.Size = 351; ClaimedMemory += Working.Size; sprintf(Working.Location, "\n" " \n" " \n" "\n" " \n" " \n" " \n" " \n" " \n" "
\n" " %s\n", HMML.metadata.title); Working.Ptr = Working.Location; Out.Ptr = Out.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } Working.Location = '\0'; ClaimedMemory -= Working.Size; Working.Location = MemoryArena + ClaimedMemory; Working.Size = 1024; ClaimedMemory += Working.Size; int AnnotationIndex = 0; while(AnnotationIndex < HMML.annotation_count) { if(HMML.annotations[AnnotationIndex].reference_count) { sprintf(Working.Location, "
\n" " References ▼\n" "
\n" "
\n"); Working.Ptr = Working.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } while(AnnotationIndex < HMML.annotation_count) { for(int i = 0; i < HMML.annotations[AnnotationIndex].reference_count; ++i) { sprintf(Working.Location, " \n" " (%s)\n" " \n" "
%s
\n" "
%s
\n" "
\n" "
\n", HMML.annotations[AnnotationIndex].references[i].url, TimecodeToSeconds(HMML.annotations[AnnotationIndex].time), HMML.annotations[AnnotationIndex].time, HMML.annotations[AnnotationIndex].references[i].site ? HMML.annotations[AnnotationIndex].references[i].site : HMML.annotations[AnnotationIndex].references[i].author, HMML.annotations[AnnotationIndex].references[i].page ? HMML.annotations[AnnotationIndex].references[i].page : HMML.annotations[AnnotationIndex].references[i].title); Working.Ptr = Working.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } } ++AnnotationIndex; } } ++AnnotationIndex; } Working.Location = '\0'; ClaimedMemory -= Working.Size; Working.Location = MemoryArena + ClaimedMemory; Working.Size = 256; ClaimedMemory += Working.Size; Working.Location = '\0'; ClaimedMemory -= Working.Size; Working.Location = MemoryArena + ClaimedMemory; Working.Size = 1024; ClaimedMemory += Working.Size; sprintf(Working.Location, "
\n" "
\n" " Annotator: %s\n" "
\n" "
\n" "
\n" "
\n", HMML.metadata.annotator, HMML.metadata.id); Working.Ptr = Working.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } Working.Location = '\0'; ClaimedMemory -= Working.Size; int DataRef = 0; for(int AnnotationIndex = 0; AnnotationIndex < HMML.annotation_count; ++AnnotationIndex) { Working.Location = MemoryArena + ClaimedMemory; Working.Size = 1024; ClaimedMemory += Working.Size; if(HMML.annotations[AnnotationIndex].reference_count || HMML.annotations[AnnotationIndex].is_quote) { sprintf(Working.Location, "
\n", TimecodeToSeconds(HMML.annotations[AnnotationIndex].time), DataRef); ++DataRef; } else { sprintf(Working.Location, "
\n", TimecodeToSeconds(HMML.annotations[AnnotationIndex].time)); } Working.Ptr = Working.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } sprintf(Working.Location, "
%s%s
\n" "
\n" "
%s%s
\n" "
\n" "
\n" "
%s%s
\n" "
\n" "
\n", HMML.annotations[AnnotationIndex].time, HMML.annotations[AnnotationIndex].text, HMML.annotations[AnnotationIndex].time, HMML.annotations[AnnotationIndex].text, HMML.annotations[AnnotationIndex].time, HMML.annotations[AnnotationIndex].text); Working.Ptr = Working.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } Working.Location = '\0'; ClaimedMemory -= Working.Size; *Out.Ptr++ = '\n'; } Working.Location = MemoryArena + ClaimedMemory; Working.Size = 256; ClaimedMemory += Working.Size; sprintf(Working.Location, "
\n" "
\n" "\n" "\n" "\n"); Working.Ptr = Working.Location; while(*Working.Ptr) { *Out.Ptr++ = *Working.Ptr++; } hmml_free(&HMML); FILE *OutFile; //char *OutFilename; //sprintf(OutFilename, "%s.html", Args[FileIndex]); if(!(OutFile = fopen("out.html", "w"))) { perror(Args[0]); return 1; } fwrite(Out.Location, Out.Ptr - Out.Location, 1, OutFile); fclose(OutFile); } } free(MemoryArena); }