📄 bk_xhtml.c
字号:
* to its parent in the file tree. * */static void xhtml_ponder_layout(paragraph * p){ xhtmlsection *lastsection; xhtmlsection *currentsect; xhtmlfile *currentfile; lastfile = NULL; topsection = xhtml_new_section(NULL); topfile = xhtml_new_file(NULL); lastsection = topsection; currentfile = topfile; currentsect = topsection; if (conf.leaf_level == 0) { topfile->is_leaf = 1; topfile->sections = topsection; topsection->file = topfile; } for (; p; p = p->next) { int level = xhtml_para_level(p); if (level > 0) { /* actually a section */ xhtmlsection *sect; word *w; char *c; rdstringc fname_c = { 0, 0, NULL }; sect = xhtml_new_section(lastsection); lastsection = sect; sect->para = p; for (w = (p->kwtext2) ? (p->kwtext2) : (p->words); w; w = w->next) { /* kwtext2 because we want numbers only! */ switch (removeattr(w->type)) { case word_Normal: /*case word_Emph: case word_Code: case word_WeakCode: */ xhtml_utostr(w->text, &c); rdaddsc(&fname_c, c); sfree(c); break; } }/* rdaddsc(&fname_c, ".html");*/ sect->fragment = rdtrimc(&fname_c); sect->level = level; /* printf(" ! adding para @ %p as sect %s, level %i\n", sect->para, sect->fragment, level); */ if (level > currentsect->level) { /* case (3) */ if (level > conf.leaf_level) { /* same file */ assert(currentfile->is_leaf); currentsect->child = sect; sect->parent = currentsect; sect->file = currentfile; /* printf("connected '%s' to existing file '%s' [I]\n", sect->fragment, currentfile->filename); */ currentsect = sect; } else { /* new file */ xhtmlfile *file = xhtml_new_file(sect); assert(!currentfile->is_leaf); currentfile->child = file; sect->file = file; file->parent = currentfile; /* printf("connected '%s' to new file '%s' [I]\n", sect->fragment, file->filename); */ currentfile = file; currentsect = sect; } } else if (level >= currentsect->file->sections->level) { /* Case (1) or (2) *AND* still under the section that starts * the current file. * * I'm not convinced that this couldn't be rolled in with the * final else {} leg further down. It seems a lot of effort * this way. */ if (level > conf.leaf_level) { /* stick within the same file */ assert(currentfile->is_leaf); sect->file = currentfile; while (currentsect && currentsect->level > level && currentsect->file == currentsect->parent->file) { currentsect = currentsect->parent; } assert(currentsect); currentsect->next = sect; assert(currentsect->level == sect->level); sect->parent = currentsect->parent; currentsect = sect; /* printf("connected '%s' to existing file '%s' [II]\n", sect->fragment, currentfile->filename); */ } else { /* new file */ xhtmlfile *file = xhtml_new_file(sect); sect->file = file; currentfile->next = file; file->parent = currentfile->parent; file->is_leaf = (level == conf.leaf_level); file->sections = sect; /* printf("connected '%s' to new file '%s' [II]\n", sect->fragment, file->filename); */ currentfile = file; currentsect = sect; } } else { /* Case (1) or (2) and we must move up the file tree first */ /* this loop is now probably irrelevant - we know we can't connect * to anything in the current file */ while (currentsect && level < currentsect->level) { currentsect = currentsect->parent; if (currentsect) { /* printf(" * up one level to '%s'\n", currentsect->fragment); */ } else { /* printf(" * up one level (off top of current file)\n"); */ } } if (currentsect) { /* I'm pretty sure this can now never fire */ assert(currentfile->is_leaf); /* printf("connected '%s' to existing file '%s' [III]\n", sect->fragment, currentfile->filename); */ sect->file = currentfile; currentsect->next = sect; currentsect = sect; } else { /* find a file we can attach to */ while (currentfile && currentfile->sections && level < currentfile->sections->level) { currentfile = currentfile->parent; if (currentfile) { /* printf(" * up one file level to '%s'\n", currentfile->filename); */ } else { /* printf(" * up one file level (off top of tree)\n"); */ } } if (currentfile) { /* new file (we had to skip up a file to get here, so we must be dealing with a level no lower than the configured leaf_level */ xhtmlfile *file = xhtml_new_file(sect); currentfile->next = file; sect->file = file; file->parent = currentfile->parent; file->is_leaf = (level == conf.leaf_level); file->sections = sect; /* printf("connected '%s' to new file '%s' [III]\n", sect->fragment, file->filename); */ currentfile = file; currentsect = sect; } else { fatal(err_whatever, "Ran off the top trying to connect sibling: strange document."); } } } } } topsection = lastsection; /* get correct end of the chain */ xhtml_fixup_layout(topfile); /* leaf files not at leaf level marked as such */}static void xhtml_do_index();static void xhtml_do_file(xhtmlfile * file);static void xhtml_do_top_file(xhtmlfile * file, paragraph * sourceform);static void xhtml_do_paras(FILE * fp, paragraph * p);static int xhtml_do_contents_limit(FILE * fp, xhtmlfile * file, int limit);static int xhtml_do_contents_section_limit(FILE * fp, xhtmlsection * section, int limit);static int xhtml_add_contents_entry(FILE * fp, xhtmlsection * section, int limit);static int xhtml_do_contents(FILE * fp, xhtmlfile * file);static int xhtml_do_naked_contents(FILE * fp, xhtmlfile * file);static void xhtml_do_sections(FILE * fp, xhtmlsection * sections);/* * Do all the files in this structure. */static void xhtml_do_files(xhtmlfile * file){ xhtml_do_file(file); if (file->child) xhtml_do_files(file->child); if (file->next) xhtml_do_files(file->next);}/* * Free up all memory used by the file tree from 'xfile' downwards */static void xhtml_free_file(xhtmlfile * xfile){ if (xfile == NULL) { return; } if (xfile->filename) { sfree(xfile->filename); } xhtml_free_file(xfile->child); xhtml_free_file(xfile->next); sfree(xfile);}/* * Main function. */voidxhtml_backend(paragraph * sourceform, keywordlist * in_keywords, indexdata * in_idx){/* int i;*/ indexentry *ientry; int ti; xhtmlsection *xsect; sourceparas = sourceform; conf = xhtml_configure(sourceform); keywords = in_keywords; idx = in_idx; /* Clear up the index entries backend data pointers */ for (ti = 0; (ientry = (indexentry *) index234(idx->entries, ti)) != NULL; ti++) { ientry->backend_data = NULL; } xhtml_ponder_layout(sourceform); /* old system ... (writes to *.alt, but gets some stuff wrong and is ugly) *//* xhtml_level_0(sourceform); for (i=1; i<=conf.leaf_level; i++) { xhtml_level(sourceform, i); }*/ /* new system ... (writes to *.html, but isn't fully trusted) */ xhtml_do_top_file(topfile, sourceform); assert(!topfile->next); /* shouldn't have a sibling at all */ if (topfile->child) { xhtml_do_files(topfile->child); xhtml_do_index(); } /* release file, section, index data structures */ xsect = topsection; while (xsect) { xhtmlsection *tmp = xsect->chain; if (xsect->fragment) { sfree(xsect->fragment); } sfree(xsect); xsect = tmp; } xhtml_free_file(topfile); for (ti = 0; (ientry = (indexentry *) index234(idx->entries, ti)) != NULL; ti++) { if (ientry->backend_data != NULL) { xhtmlindex *xi = (xhtmlindex *) ientry->backend_data; if (xi->sections != NULL) { sfree(xi->sections); } sfree(xi); } ientry->backend_data = NULL; } { int i; sfree(conf.fchapter.number_suffix); for (i = 0; i < conf.nfsect; i++) sfree(conf.fsect[i].number_suffix); sfree(conf.fsect); }}static int xhtml_para_level(paragraph * p){ switch (p->type) { case para_Title: return 0; break; case para_UnnumberedChapter: case para_Chapter: case para_Appendix: return 1; break;/* case para_BiblioCited: return 2; break;*/ case para_Heading: case para_Subsect: return p->aux + 2; break; default: return -1; break; }}static char *xhtml_index_filename = "IndexPage.html";/* Output the nav links for the current file. * file == NULL means we're doing the index */static void xhtml_donavlinks(FILE * fp, xhtmlfile * file){ xhtmlfile *xhtml_next_file = NULL; fprintf(fp, "<p"); if (conf.nav_attrs != NULL) { fprintf(fp, " %ls>", conf.nav_attrs); } else { fprintf(fp, ">"); } if (xhtml_last_file == NULL) { fprintf(fp, "Previous | "); } else { fprintf(fp, "<a href='%s'>Previous</a> | ", xhtml_last_file->filename); } fprintf(fp, "<a href='Contents.html'>Contents</a> | "); if (file != NULL) { /* otherwise we're doing nav links for the index */ if (xhtml_next_file == NULL) xhtml_next_file = file->child; if (xhtml_next_file == NULL) xhtml_next_file = file->next; if (xhtml_next_file == NULL) xhtml_next_file = file->parent->next; } if (xhtml_next_file == NULL) { if (file == NULL) { /* index, so no next file */ fprintf(fp, "Next "); } else { fprintf(fp, "<a href='%s'>Next</a>", xhtml_index_filename); } } else { fprintf(fp, "<a href='%s'>Next</a>", xhtml_next_file->filename); } fprintf(fp, "</p>\n");}/* Write out the index file */static void xhtml_do_index_body(FILE * fp){ indexentry *y; int ti; if (count234(idx->entries) == 0) return; /* don't write anything at all */ fprintf(fp, "<dl>\n"); /* iterate over idx->entries using the tree functions and display everything */ for (ti = 0; (y = (indexentry *) index234(idx->entries, ti)) != NULL; ti++) { if (y->backend_data) { int i; xhtmlindex *xi; fprintf(fp, "<dt>"); xhtml_para(fp, y->text); fprintf(fp, "</dt>\n<dd>"); xi = (xhtmlindex *) y->backend_data; for (i = 0; i < xi->nsection; i++) { xhtmlsection *sect = xi->sections[i]; if (sect) { fprintf(fp, "<a href='%s#%s'>", sect->file->filename, sect->fragment); if (sect->para->kwtext) { xhtml_para(fp, sect->para->kwtext); } else if (sect->para->words) { xhtml_para(fp, sect->para->words); } fprintf(fp, "</a>"); if (i + 1 < xi->nsection) { fprintf(fp, ", "); } } } fprintf(fp, "</dd>\n"); } } fprintf(fp, "</dl>\n");}static void xhtml_do_index(){ word temp_word = { NULL, NULL, word_Normal, 0, 0, L"Index", {NULL, 0, 0} }; FILE *fp = fopen(xhtml_index_filename, "w"); if (fp == NULL) fatal(err_cantopenw, xhtml_index_filename); xhtml_doheader(fp, &temp_word); xhtml_donavlinks(fp, NULL); xhtml_do_index_body(fp); xhtml_donavlinks(fp, NULL); xhtml_dofooter(fp); fclose(fp);}/* Output the given file. This includes whatever contents at beginning and end, etc. etc. */static void xhtml_do_file(xhtmlfile * file){ FILE *fp = fopen(file->filename, "w"); if (fp == NULL) fatal(err_cantopenw, file->filename); if (file->sections->para->words) { xhtml_doheader(fp, file->sections->para->words); } else if (file->sections->para->kwtext) { xhtml_doheader(fp, file->sections->para->kwtext); } else { xhtml_doheader(fp, NULL); } xhtml_donavlinks(fp, file); if (file->is_leaf && conf.leaf_contains_contents && xhtml_do_contents(NULL, file) >= conf.leaf_smallest_contents) xhtml_do_contents(fp, file); xhtml_do_sections(fp, file->sections); if (!file->is_leaf) xhtml_do_naked_contents(fp, file); xhtml_donavlinks(fp, file); xhtml_dofooter(fp); fclose(fp); xhtml_last_file = file;}/* Output the top-level file. */static void xhtml_do_top_file(xhtmlfile * file, paragraph * sourceform){ paragraph *p; char fname[4096]; int done = FALSE; FILE *fp = fopen(file->filename, "w"); if (fp == NULL) fatal(err_cantopenw, file->filename); ustrtoa(conf.chm_toc_file, fname, 4096); if(*fname) { chm_toc = fopen(fname, "w"); if (chm_toc == NULL) fatal(err_cantopenw, fname); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -