📄 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.
*/
void
xhtml_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 + -