📄 bk_xhtml.c
字号:
else
chm_toc = NULL;
ustrtoa(conf.chm_ind_file, fname, 4096);
if(*fname){
chm_ind = fopen(fname, "w");
if (chm_ind == NULL)
fatal(err_cantopenw, fname);
}
else
chm_ind = NULL;
/* Do the title -- only one allowed */
for (p = sourceform; p && !done; p = p->next)
{
if (p->type == para_Title)
{
xhtml_doheader(fp, p->words);
if(chm_toc)chm_doheader(chm_toc, p->words);
if(chm_ind)chm_doheader(chm_ind, p->words);
done = TRUE;
}
}
if (!done)
xhtml_doheader(fp, NULL /* Eek! */ );
/*
* Display the title.
*/
for (p = sourceform; p; p = p->next)
{
if (p->type == para_Title)
{
xhtml_heading(fp, p);
break;
}
}
/* Do the preamble and copyright */
for (p = sourceform; p; p = p->next)
{
if (p->type == para_Preamble)
{
fprintf(fp, "<p>");
xhtml_para(fp, p->words);
fprintf(fp, "</p>\n");
}
}
for (p = sourceform; p; p = p->next)
{
if (p->type == para_Copyright)
{
fprintf(fp, "<p>");
xhtml_para(fp, p->words);
fprintf(fp, "</p>\n");
}
}
xhtml_do_contents(fp, file);
xhtml_do_sections(fp, file->sections);
/*
* Put the index in the top file if we're in single-file mode
* (leaf-level 0).
*/
if (conf.leaf_level == 0 && count234(idx->entries) > 0)
{
fprintf(fp, "<a name=\"index\"></a><h1>Index</h1>\n");
xhtml_do_index_body(fp);
}
xhtml_dofooter(fp);
if(chm_toc)chm_dofooter(chm_toc);
if(chm_ind)chm_dofooter(chm_ind);
fclose(fp);
if(chm_toc)
{
fclose(chm_toc);
chm_toc = NULL;
}
if(chm_ind)
{
fclose(chm_ind);
chm_ind = NULL;
}
}
/* Convert a Unicode string to an ASCII one. '?' is
* used for unmappable characters.
*/
static void xhtml_utostr(wchar_t * in, char **out)
{
int l = ustrlen(in);
int i;
*out = smalloc(l + 1);
for (i = 0; i < l; i++)
{
if (in[i] >= 32 && in[i] <= 126)
(*out)[i] = (char) in[i];
else
(*out)[i] = '?';
}
(*out)[i] = 0;
}
/*
* Write contents for the given file, and subfiles, down to
* the appropriate contents depth. Returns the number of
* entries written.
*/
static int xhtml_do_contents(FILE * fp, xhtmlfile * file)
{
int level, limit, start_level, count = 0;
if (!file)
return 0;
level = (file->sections) ? (file->sections->level) : (0);
limit = conf.contents_depth[(level > 5) ? (5) : (level)];
start_level = (file->is_leaf) ? (level - 1) : (level);
last_level = start_level;
count += xhtml_do_contents_section_limit(fp, file->sections, limit);
count += xhtml_do_contents_limit(fp, file->child, limit);
if (fp != NULL)
{
while (last_level > start_level)
{
last_level--;
fprintf(fp, "</ul>\n");
if(chm_toc)fprintf(chm_toc, "</ul>\n");
}
}
return count;
}
/* As above, but doesn't do anything in the current file */
static int xhtml_do_naked_contents(FILE * fp, xhtmlfile * file)
{
int level, limit, start_level, count = 0;
if (!file)
return 0;
level = (file->sections) ? (file->sections->level) : (0);
limit = conf.contents_depth[(level > 5) ? (5) : (level)];
start_level = (file->is_leaf) ? (level - 1) : (level);
last_level = start_level;
count = xhtml_do_contents_limit(fp, file->child, limit);
if (fp != NULL)
{
while (last_level > start_level)
{
last_level--;
fprintf(fp, "</ul>\n");
if(chm_toc)fprintf(chm_toc, "</ul>\n");
}
}
return count;
}
/*
* Write contents for the given file, children, and siblings, down to
* given limit contents depth.
*/
static int xhtml_do_contents_limit(FILE * fp, xhtmlfile * file, int limit)
{
int count = 0;
while (file)
{
count += xhtml_do_contents_section_limit(fp, file->sections, limit);
count += xhtml_do_contents_limit(fp, file->child, limit);
file = file->next;
}
return count;
}
/*
* Write contents entries for the given section tree, down to the
* limit contents depth.
*/
static int
xhtml_do_contents_section_deep_limit(FILE * fp, xhtmlsection * section,
int limit)
{
int count = 0;
while (section)
{
if (!xhtml_add_contents_entry(fp, section, limit))
return 0;
else
count++;
count +=
xhtml_do_contents_section_deep_limit(fp, section->child, limit);
section = section->next;
}
return count;
}
/*
* Write contents entries for the given section tree, down to the
* limit contents depth.
*/
static int
xhtml_do_contents_section_limit(FILE * fp, xhtmlsection * section, int limit)
{
int count = 0;
if (!section)
return 0;
xhtml_add_contents_entry(fp, section, limit);
count = 1;
count += xhtml_do_contents_section_deep_limit(fp, section->child, limit);
/* section=section->child;
while (section && xhtml_add_contents_entry(fp, section, limit)) {
section = section->next;
} */
return count;
}
/*
* Add a section entry, unless we're exceeding the limit, in which
* case return FALSE (otherwise return TRUE).
*/
static int
xhtml_add_contents_entry(FILE * fp, xhtmlsection * section, int limit)
{
if (!section || section->level > limit)
return FALSE;
if (fp == NULL || section->level < 0)
return TRUE;
while (last_level > section->level)
{
last_level--;
fprintf(fp, "</ul>\n");
if(chm_toc)fprintf(chm_toc, "</ul>\n");
}
while (last_level < section->level)
{
last_level++;
fprintf(fp, "<ul>\n");
if(chm_toc)fprintf(chm_toc, "<ul>\n");
}
fprintf(fp, "<li>");
fprintf(fp, "<a %shref=\"%s#%s\">",
(section->para->type == para_Chapter|| section->para->type == para_Appendix) ? "class=\"btitle\" " : "",
section->file->filename,
(section->para->type == para_Chapter) ? "" : section->fragment);
if(chm_toc)fprintf(chm_toc, "<li><OBJECT type=\"text/sitemap\"><param name=\"Local\" value=\"%s#%s\"><param name=\"Name\" value=\"",
section->file->filename,
(section->para->type == para_Chapter) ? "" : section->fragment);
if(chm_ind)fprintf(chm_ind, "<li><OBJECT type=\"text/sitemap\"><param name=\"Local\" value=\"%s#%s\"><param name=\"Name\" value=\"",
section->file->filename,
(section->para->type == para_Chapter) ? "" : section->fragment);
//%s
if (section->para->type == para_Chapter
|| section->para->type == para_Appendix)
fprintf(fp, "<b>");
if ((section->para->type != para_Heading
&& section->para->type != para_Subsect) || (section->para->kwtext
&& !section->para->
words))
{
xhtml_para(fp, section->para->kwtext);
if(chm_toc)xhtml_para(chm_toc, section->para->kwtext);
if (section->para->words){
fprintf(fp, ": ");
if(chm_toc)fprintf(chm_toc, ": ");
}
}
if (section->para->type == para_Chapter
|| section->para->type == para_Appendix)
fprintf(fp, "</b>");
if (section->para->words)
{
xhtml_para(fp, section->para->words);
if(chm_toc)xhtml_para(chm_toc, section->para->words);
if(chm_ind)xhtml_para(chm_ind, section->para->words);
}
fprintf(fp, "</a></li>\n");
if(chm_toc)fprintf(chm_toc,"\"></OBJECT></li>\n");
if(chm_ind)fprintf(chm_ind,"\"></OBJECT></li>\n");
return TRUE;
}
/*
* Write all the sections in this file. Do all paragraphs in this section, then all
* children (recursively), then go on to the next one (tail recursively).
*/
static void xhtml_do_sections(FILE * fp, xhtmlsection * sections)
{
while (sections)
{
currentsection = sections;
xhtml_do_paras(fp, sections->para);
xhtml_do_sections(fp, sections->child);
sections = sections->next;
}
}
/* Write this list of paragraphs. Close off all lists at the end. */
static void xhtml_do_paras(FILE * fp, paragraph * p)
{
int last_type = -1, first = TRUE;
if (!p)
return;
/* for (; p && (xhtml_para_level(p)>limit || xhtml_para_level(p)==-1 || first); p=p->next) {*/
for (; p && (xhtml_para_level(p) == -1 || first); p = p->next)
{
first = FALSE;
switch (p->type)
{
/*
* Things we ignore because we've already processed them or
* aren't going to touch them in this pass.
*/
case para_IM:
case para_BR:
case para_Biblio: /* only touch BiblioCited */
case para_VersionID:
case para_Copyright:
case para_Preamble:
case para_NoCite:
case para_Title:
break;
/*
* Chapter titles.
*/
case para_Chapter:
case para_Appendix:
case para_UnnumberedChapter:
xhtml_heading(fp, p);
break;
case para_Heading:
case para_Subsect:
xhtml_heading(fp, p);
break;
case para_Rule:
fprintf(fp, "\n<hr />\n");
break;
case para_Normal:
fprintf(fp, "\n<p>");
xhtml_para(fp, p->words);
fprintf(fp, "</p>\n");
break;
case para_Bullet:
case para_NumberedList:
case para_BiblioCited:
if (last_type != p->type)
{
/* start up list if necessary */
if (p->type == para_Bullet)
{
fprintf(fp, "<ul>\n");
} else if (p->type == para_NumberedList)
{
fprintf(fp, "<ol>\n");
} else if (p->type == para_BiblioCited)
{
fprintf(fp, "<dl>\n");
}
}
if (p->type == para_Bullet || p->type == para_NumberedList)
fprintf(fp, "<li>");
else if (p->type == para_BiblioCited)
{
fprintf(fp, "<dt>");
xhtml_para(fp, p->kwtext);
fprintf(fp, "</dt>\n<dd>");
}
xhtml_para(fp, p->words);
if (p->type == para_BiblioCited)
{
fprintf(fp, "</dd>\n");
} else if (p->type == para_Bullet || p->type == para_NumberedList)
{
fprintf(fp, "</li>");
}
if (p->type == para_Bullet || p->type == para_NumberedList
|| p->type == para_BiblioCited)
/* close off list if necessary */
{
paragraph *p2 = p->next;
int close_off = FALSE;
/* if (p2 && (xhtml_para_level(p2)>limit || xhtml_para_level(p2)==-1)) {*/
if (p2 && xhtml_para_level(p2) == -1)
{
if (p2->type != p->type)
close_off = TRUE;
} else
{
close_off = TRUE;
}
if (close_off)
{
if (p->type == para_Bullet)
{
fprintf(fp, "</ul>\n");
} else if (p->type == para_NumberedList)
{
fprintf(fp, "</ol>\n");
} else if (p->type == para_BiblioCited)
{
fprintf(fp, "</dl>\n");
}
}
}
break;
case para_Code:
xhtml_codepara(fp, p->words);
break;
}
last_type = p->type;
}
}
/*
* Output a header for this XHTML file.
*/
static void xhtml_doheader(FILE * fp, word * title)
{
fprintf(fp,
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n");
fprintf(fp,
"\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n");
fprintf(fp,
"<html xmlns='http://www.w3.org/1999/xhtml'>\n\n<head>\n<title>");
if (title == NULL)
fprintf(fp, "Documentation");
else
xhtml_para(fp, title);
fprintf(fp, "</title>\n");
fprintf(fp,
"<meta name=\"generator\" content=\"Halibut %s xhtml-backend\" />\n",
version);
if (conf.author)
fprintf(fp, "<meta name=\"author\" content=\"%ls\" />\n", conf.author);
if (conf.description)
fprintf(fp, "<meta name=\"description\" content=\"%ls\" />\n",
conf.description);
if (conf.head_end)
fprintf(fp, "%ls\n", conf.head_end);
fprintf(fp, "</head>\n\n");
if (conf.body)
fprintf(fp, "%ls\n", conf.body);
else
fprintf(fp, "<body>\n");
if (conf.body_start)
fprintf(fp, "%ls\n", conf.body_start);
}
static void chm_doheader(FILE * fp, word * title)
{
fprintf(fp, "<HTML><BODY><UL><LI><OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"");
xhtml_para(fp, title);
fprintf(fp,"\"><param name=\"Local\" value=\"Contents.html\"></OBJECT></li>\n");
}
/*
* Output a footer for this XHTML file.
*/
static void xhtml_dofooter(FILE * fp)
{
fprintf(fp, "\n<hr />\n\n");
if (conf.body_end)
fprintf(fp, "%ls\n", conf.body_end);
if (!conf.suppress_address)
{
fprintf(fp, "<address>\n");
if (conf.address_start)
fprintf(fp, "%ls\n", conf.address_start);
/* Do the version ID */
if (conf.include_version_id)
{
paragraph *p;
int started = 0;
for (p = sourceparas; p; p = p->next)
if (p->type == para_VersionID)
{
xhtml_versionid(fp, p->words, started);
started = 1;
}
}
if (conf.address_end)
fprintf(fp, "%ls\n", conf.address_end);
fprintf(fp, "</address>\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -