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

📄 bk_xhtml.c

📁 NullSofts criptable install system2.28源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  }
  fprintf(fp, "</body>\n\n</html>\n");
}
static void chm_dofooter(FILE * fp)
{
	fprintf(fp, "</ul></BODY></HTML>\n");
}

/*
 * Output the versionid paragraph. Typically this is a version control
 * ID string (such as $Id...$ in RCS).
 */
static void xhtml_versionid(FILE * fp, word * text, int started)
{
  rdstringc t = { 0, 0, NULL };

  rdaddc(&t, '[');              /* FIXME: configurability */
  xhtml_rdaddwc(&t, text, NULL);
  rdaddc(&t, ']');              /* FIXME: configurability */

  if (started)
    fprintf(fp, "<br>\n");
  fprintf(fp, "%s\n", t.text);
  sfree(t.text);
}

/* Is this an XHTML reserved character? */
static int xhtml_reservedchar(int c)
{
  if (c == '&' || c == '<' || c == '>' || c == '"')
    return TRUE;
  else
    return FALSE;
}

/*
 * Convert a wide string into valid XHTML: Anything outside ASCII will
 * be fixed up as an entity. Currently we don't worry about constraining the
 * encoded character set, which we should probably do at some point (we can
 * still fix up and return FALSE - see the last comment here). We also don't
 * currently
 *
 * Because this is only used for words, spaces are HARD spaces (any other
 * spaces will be word_Whitespace not word_Normal). So they become &nbsp;
 * Unless hard_spaces is FALSE, of course (code paragraphs break the above
 * rule).
 *
 * If `result' is non-NULL, mallocs the resulting string and stores a pointer to
 * it in `*result'. If `result' is NULL, merely checks whether all
 * characters in the string are feasible.
 *
 * Return is nonzero if all characters are OK. If not all
 * characters are OK but `result' is non-NULL, a result _will_
 * still be generated!
 */
static int xhtml_convert(wchar_t * s, char **result, int hard_spaces)
{
  int doing = (result != 0);
  int ok = TRUE;
  char *p = NULL;
  int plen = 0, psize = 0;

  for (; *s; s++)
  {
    wchar_t c = *s;

#define ensure_size(i) if (i>=psize) { psize = i+256; p = resize(p, psize); }

    if (((c == 32 && !hard_spaces)
         || (c > 32 && c <= 126 && !xhtml_reservedchar(c))))
    {
      /* Char is OK. */
      if (doing)
      {
        ensure_size(plen);
        p[plen++] = (char) c;
      }
    } else
    {
      /* Char needs fixing up. */
      /* ok = FALSE; -- currently we never return FALSE; we
       * might want to when considering a character set for the
       * encoded document.
       */
      if (doing)
      {
        if (c == 32)
        {                       /* a space in a word is a hard space */
          ensure_size(plen + 7);        /* includes space for the NUL, which is subsequently stomped on */
          sprintf(p + plen, "&nbsp;");
          plen += 6;
        } else
        {
          switch (c)
          {
          case '&':
            ensure_size(plen + 6);      /* includes space for the NUL, which is subsequently stomped on */
            plen += sprintf(p + plen, "&amp;");
            break;
          case '"':
            ensure_size(plen + 7);      /* includes space for the NUL, which is subsequently stomped on */
            plen += sprintf(p + plen, "&quot;");
            break;
          case '<':
            if (plen > 1 && *(s - 1) == '\\' && *(s - 2) == '\\')
            {
              ensure_size(--plen);
              p[plen - 1] = (char) c;
              p[plen] = 0;
            } else
            {
              ensure_size(plen + 5);    /* includes space for the NUL, which is subsequently stomped on */
              plen += sprintf(p + plen, "&lt;");
            }
            break;
          case '>':
            if (plen > 1 && *(s - 1) == '\\' && *(s - 2) == '\\')
            {
              ensure_size(--plen);
              p[plen - 1] = (char) c;
              p[plen] = 0;
            } else
            {
              ensure_size(plen + 5);    /* includes space for the NUL, which is subsequently stomped on */
              plen += sprintf(p + plen, "&gt;");
            }
            break;
          default:
            ensure_size(plen + 8);      /* includes space for the NUL, which is subsequently stomped on */
            plen += sprintf(p + plen, "&#%04i;", (int) c);
            break;
          }
        }
      }
    }
  }
  if (doing)
  {
    p = resize(p, plen + 1);
    p[plen] = '\0';
    *result = p;
  }

  return ok;
}

/*
 * This formats the given words as XHTML.
 */
static void xhtml_rdaddwc(rdstringc * rs, word * text, word * end)
{
  char *c;
  keyword *kwl;
  xhtmlsection *sect;
  indextag *itag;
  int ti;
  wchar_t *s;

  for (; text && text != end; text = text->next)
  {
    switch (text->type)
    {
    case word_HyperLink:
      xhtml_utostr(text->text, &c);
      rdaddsc(rs, "<a href=\"");
      if(chm_toc && *c == '.' && *(c+1) == '.')
        rdaddsc(rs, c + 1);
      else
	      rdaddsc(rs, c);
      rdaddsc(rs, "\">");
      sfree(c);
      break;

    case word_LocalHyperLink:
      xhtml_utostr(text->text, &c);
      rdaddsc(rs, "<a href=\"");
      if (conf.rlink_prefix)
      {
        char *c2;
        xhtml_utostr(conf.rlink_prefix, &c2);
        rdaddsc(rs, c2);
        sfree(c2);
      }
	    rdaddsc(rs, c);
      if (conf.rlink_suffix)
      {
        char *c2;
        xhtml_utostr(conf.rlink_suffix, &c2);
        rdaddsc(rs, c2);
        sfree(c2);
      }
      rdaddsc(rs, "\">");
      sfree(c);
      break;

    case word_UpperXref:
    case word_LowerXref:
    case word_FreeTextXref:
      kwl = kw_lookup(keywords, text->text);
      if (kwl)
      {
        sect = xhtml_find_section(kwl->para);
        if (sect)
        {
          rdaddsc(rs, "<a href=\"");
          rdaddsc(rs, sect->file->filename);
          rdaddc(rs, '#');
          rdaddsc(rs, sect->fragment);
          rdaddsc(rs, "\">");
        } else
        {
          rdaddsc(rs,
                  "<a href=\"Apologies.html\"><!-- probably a bibliography cross reference -->");
          error(err_whatever,
                "Couldn't locate cross-reference! (Probably a bibliography entry.)");
        }
      } else
      {
        rdaddsc(rs,
                "<a href=\"Apologies.html\"><!-- unknown cross-reference -->");
        error(err_whatever,
              "Couldn't locate cross-reference! (Wasn't in source file.)");
      }
      break;

    case word_IndexRef:        /* in theory we could make an index target here */
/*        rdaddsc(rs, "<a name=\"idx-");
        xhtml_utostr(text->text, &c);
        rdaddsc(rs, c);
        sfree(c);
        rdaddsc(rs, "\"></a>");*/
      /* what we _do_ need to do is to fix up the backend data
       * for any indexentry this points to.
       */
      for (ti = 0;
           (itag = (indextag *) index234(idx->tags, ti)) != NULL; ti++)
      {
        /* FIXME: really ustricmp() and not ustrcmp()? */
        if (ustricmp(itag->name, text->text) == 0)
        {
          break;
        }
      }
      if (itag != NULL)
      {
        if (itag->refs != NULL)
        {
          int i;
          for (i = 0; i < itag->nrefs; i++)
          {
            xhtmlindex *idx_ref;
            indexentry *ientry;

            ientry = itag->refs[i];
            if (ientry->backend_data == NULL)
            {
              idx_ref = (xhtmlindex *) smalloc(sizeof(xhtmlindex));
              if (idx_ref == NULL)
                fatal(err_nomemory);
              idx_ref->nsection = 0;
              idx_ref->size = 4;
              idx_ref->sections =
                  (xhtmlsection **) smalloc(idx_ref->size *
                                            sizeof(xhtmlsection *));
              if (idx_ref->sections == NULL)
                fatal(err_nomemory);
              ientry->backend_data = idx_ref;
            } else
            {
              idx_ref = ientry->backend_data;
              if (idx_ref->nsection + 1 > idx_ref->size)
              {
                int new_size = idx_ref->size * 2;
                idx_ref->sections =
                    srealloc(idx_ref->sections,
                             new_size * sizeof(xhtmlsection));
                if (idx_ref->sections == NULL)
                {
                  fatal(err_nomemory);
                }
                idx_ref->size = new_size;
              }
            }
            idx_ref->sections[idx_ref->nsection++] = currentsection;
#if 0
#endif
          }
        } else
        {
          fatal(err_whatever, "Index tag had no entries!");
        }
      } else
      {
        fprintf(stderr, "Looking for index entry '%ls'\n", text->text);
        fatal(err_whatever,
              "Couldn't locate index entry! (Wasn't in index.)");
      }
      break;

    case word_HyperEnd:
    case word_XrefEnd:
      rdaddsc(rs, "</a>");
      break;

    case word_Normal:
    case word_Emph:
    case word_Code:
    case word_WeakCode:
    case word_WhiteSpace:
    case word_EmphSpace:
    case word_CodeSpace:
    case word_WkCodeSpace:
    case word_Quote:
    case word_EmphQuote:
    case word_CodeQuote:
    case word_WkCodeQuote:
      assert(text->type != word_CodeQuote &&
             text->type != word_WkCodeQuote);
      if (towordstyle(text->type) == word_Emph &&
          (attraux(text->aux) == attr_First ||
           attraux(text->aux) == attr_Only))
        rdaddsc(rs, "<em>");
      else if ((towordstyle(text->type) == word_Code
                || towordstyle(text->type) == word_WeakCode)
               && (attraux(text->aux) == attr_First
                   || attraux(text->aux) == attr_Only))
        rdaddsc(rs, "<code>");

      if (removeattr(text->type) == word_Normal)
      {
        static int dont_convert = 0;
        if (dont_convert)
        {
          char buf[2] = " ";
          dont_convert = 0;
          s = text->text;
          for (; *s; s++)
          {
            buf[0] = (char) *s;
            rdaddsc(rs, buf);
          }
          buf[0] = 0;
          rdaddsc(rs, buf);
        } else
        {
          if (*text->text == '\\' && text->next
              && text->next->text && (*text->next->text == '&'
                                      || *text->next->text == '<'
                                      || *text->next->text == '>'
                                      || *text->next->text == '"'))
            dont_convert = 1;
          else
          {
            if (xhtml_convert(text->text, &c, TRUE))    /* spaces in the word are hard */
              rdaddsc(rs, c);
            else
              xhtml_rdaddwc(rs, text->alt, NULL);
            sfree(c);
          }
        }
      } else if (removeattr(text->type) == word_WhiteSpace)
      {
        rdaddc(rs, ' ');
      } else if (removeattr(text->type) == word_Quote)
      {
        rdaddsc(rs, "&quot;");
      }

      if (towordstyle(text->type) == word_Emph &&
          (attraux(text->aux) == attr_Last ||
           attraux(text->aux) == attr_Only))
        rdaddsc(rs, "</em>");
      else if ((towordstyle(text->type) == word_Code
                || towordstyle(text->type) == word_WeakCode)
               && (attraux(text->aux) == attr_Last
                   || attraux(text->aux) == attr_Only))
        rdaddsc(rs, "</code>");
      break;
    }
  }
}

/* Output a heading, formatted as XHTML.
 */
static void xhtml_heading(FILE * fp, paragraph * p)
{
  rdstringc t = { 0, 0, NULL };
  word *tprefix = p->kwtext;
  word *nprefix = p->kwtext2;
  word *text = p->words;
  int level = xhtml_para_level(p);
  xhtmlsection *sect = xhtml_find_section(p);
  xhtmlheadfmt *fmt;
  char *fragment;
  if (sect)
  {
    fragment = sect->fragment;
  } else
  {
    if (p->type == para_Title)
      fragment = "title";
    else
    {
      fragment = "";            /* FIXME: what else can we do? */
      error(err_whatever, "Couldn't locate heading cross-reference!");
    }
  }

  if (p->type == para_Title)
    fmt = NULL;
  else if (level == 1)
    fmt = &conf.fchapter;
  else if (level - 1 < conf.nfsect)
    fmt = &conf.fsect[level - 1];
  else
    fmt = &conf.fsect[conf.nfsect - 1];

  if (fmt && fmt->just_numbers && nprefix)
  {
    xhtml_rdaddwc(&t, nprefix, NULL);
    if (fmt)
    {
      char *c;
      if (xhtml_convert(fmt->number_suffix, &c, FALSE))
      {
        rdaddsc(&t, c);
        sfree(c);
      }
    }
  } else if (fmt && !fmt->just_numbers && tprefix)
  {
    xhtml_rdaddwc(&t, tprefix, NULL);
    if (fmt)
    {
      char *c;
      if (xhtml_convert(fmt->number_suffix, &c, FALSE))
      {
        rdaddsc(&t, c);
        sfree(c);
      }
    }
  }
  xhtml_rdaddwc(&t, text, NULL);
  /*
   * If we're outputting in single-file mode, we need to lower
   * the level of each heading by one, because the overall
   * document title will be sitting right at the top as an <h1>
   * and so chapters and sections should start at <h2>.
   * 
   * Even if not, the document title will come back from
   * xhtml_para_level() as level zero, so we must increment that
   * no matter what leaf_level is set to.
   */
  if (conf.leaf_level == 0 || level == 0)
    level++;
  fprintf(fp, "<a name=\"%s\"></a><h%i>%s</h%i>\n", fragment, level,
          t.text, level);
  sfree(t.text);
}

/* Output a paragraph. Styles are handled by xhtml_rdaddwc().
 * This looks pretty simple; I may have missed something ...
 */
static void xhtml_para(FILE * fp, word * text)
{
  rdstringc out = { 0, 0, NULL };
  xhtml_rdaddwc(&out, text, NULL);
  fprintf(fp, "%s", out.text);
  sfree(out.text);
}

/* Output a code paragraph. I'm treating this as preformatted, which
 * may not be entirely correct. See xhtml_para() for my worries about
 * this being overly-simple; however I think that most of the complexity
 * of the text backend came entirely out of word wrapping anyway.
 */
static void xhtml_codepara(FILE * fp, word * text)
{
  fprintf(fp, "<pre>");
  for (; text; text = text->next)
    if (text->type == word_WeakCode)
    {
      char *c;
      xhtml_convert(text->text, &c, FALSE);
      fprintf(fp, "%s\n", c);
      sfree(c);
    }
  fprintf(fp, "</pre>\n");
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -