⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bk_xhtml.c

📁 NullSofts criptable install system2.28源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 *     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 + -