#define HMMLIB_IMPLEMENTATION #include "hmmlib.h" #include "stb_sb.h" typedef struct { char* text; int* lines; } Index; static Index* index_find(Index* base, const char* text) { for(size_t i = 0; i < sb_count(base); ++i){ if(strcmp(base[i].text, text) == 0){ return base + i; } } return NULL; } void hmml_dump(HMML_Output* hmml) { if(!hmml){ puts("(null)"); return; } if(!hmml->well_formed){ printf("Error:%d:%d %s\n", hmml->error.line, hmml->error.col, hmml->error.message); return; } puts("Annotations:"); for(size_t i = 0; i < hmml->annotation_count; ++i){ HMML_Annotation* a = hmml->annotations + i; char time_buf[256]; char* tp = time_buf; if(a->h) { *tp++ = (a->h%10) + '0'; sprintf(tp, ":%02d:%02d", a->m, a->s); } else { sprintf(tp, " %2d:%02d", a->m, a->s); } printf("\t%3d [%s] [%s]\n", a->line, time_buf, a->text); } Index* authors = NULL; Index* markers[HMML_MARKER_COUNT] = {}; int max_text_len = 0; for(size_t i = 0; i < hmml->annotation_count; ++i){ HMML_Annotation* a = hmml->annotations + i; if(a->author){ int len = strlen(a->author); if(len > max_text_len){ max_text_len = len; } Index* idx; if(!(idx = index_find(authors, a->author))){ Index x = { .text = a->author }; sb_push(authors, x); idx = &sb_last(authors); } sb_push(idx->lines, a->line); } } for(size_t i = 0; i < hmml->annotation_count; ++i){ HMML_Annotation* a = hmml->annotations + i; for(size_t j = 0; j < a->marker_count; ++j){ int type = a->markers[j].type; char* text = a->markers[j].marker; int len = strlen(text); if(len > max_text_len){ max_text_len = len; } Index* idx; if(!(idx = index_find(markers[type], text))){ Index x = { .text = text }; sb_push(markers[type], x); idx = &sb_last(markers[type]); } sb_push(idx->lines, a->line); } } puts("Authors:"); for(size_t i = 0; i < sb_count(authors); ++i){ printf("\t %*s: ", max_text_len, authors[i].text); for(size_t j = 0; j < sb_count(authors[i].lines); ++j){ printf("%3d ", authors[i].lines[j]); } puts(""); } static const char* m_tags[HMML_MARKER_COUNT] = { "Categories", "Members", "Projects" }; for(size_t i = 0; i < HMML_MARKER_COUNT; ++i){ printf("%s:\n", m_tags[i]); for(size_t j = 0; j < sb_count(markers[i]); ++j){ printf("\t %*s: ", max_text_len, markers[i][j].text); for(size_t k = 0; k < sb_count(markers[i][j].lines); ++k){ printf("%3d ", markers[i][j].lines[k]); } puts(""); } } static const char* r_tags[] = { "Site", "Page", "URL", "Title", "Article", "Author", "Editor", "Publisher", "ISBN" }; puts("References:"); for(size_t i = 0; i < hmml->annotation_count; ++i){ HMML_Annotation* a = hmml->annotations + i; for(size_t j = 0; j < a->reference_count; ++j){ printf("\t%3d ", a->line); HMML_Reference* r = a->references + j; for(size_t k = 0; k < countof(r_tags); ++k){ char* item = ((char**)r)[k]; if(item){ printf("[%s = %s] ", r_tags[k], item); } } puts(""); } } puts("Quotes:"); for(size_t i = 0; i < hmml->annotation_count; ++i){ HMML_Annotation* a = hmml->annotations + i; if(a->quote.present){ if(a->quote.author){ printf("\t%3d [Quote #%d, by %s]", a->line, a->quote.id, a->quote.author); } else { printf("\t%3d [Quote #%d]", a->line, a->quote.id); } puts(""); } } for(size_t i = 0; i < sb_count(authors); ++i){ sb_free(authors[i].lines); } sb_free(authors); for(size_t i = 0; i < HMML_MARKER_COUNT; ++i){ for(size_t j = 0; j < sb_count(markers[i]); ++j){ sb_free(markers[i][j].lines); } sb_free(markers[i]); } } int main(int argc, char** argv) { if(argc < 2) { fprintf(stderr, "Usage: %s [file]\n", argv[0]); return 1; } FILE* f = fopen(argv[1], "r"); if(!f) { perror(argv[1]); return 1; } fseek(f, 0, SEEK_END); long size = ftell(f); rewind(f); char* mem = malloc(size+1); mem[size] = 0; fread(mem, 1, size, f); fclose(f); HMML_Output out = hmml_parse(mem); free(mem); // asm("int3"); hmml_dump(&out); hmml_free(&out); }