65.9K
CodeProject 正在变化。 阅读更多。
Home

自动生成目录和标题编号 - 修改版

starIconstarIconstarIconstarIconstarIcon

5.00/5 (7投票s)

2015年4月10日

CPOL

16分钟阅读

viewsIcon

25224

downloadIcon

598

本文修订了HTML创作工具HTML TOC Generator,该工具可为HTML文档生成目录。此外,该工具还可选择性地为HTML标题编号。

1. 简介 目录

To TOC

本文是一个修订版,它

  • 从本文、工具和下载中删除测试用例
  • 添加了一个召回上次访问目录的功能
  • 删除生成的“name”属性
  • 删除 <img> width 和 height 属性上生成的“px”单位

最后两次修订是为了遵守 HTML5 标准 [^]。

本文修订了HTML创作工具HTML TOC Generator,该工具可为HTML文档生成目录。此外,该工具还可选择性地为HTML标题编号。

2. 目的 目录

HTML TOC Generator 工具根据类为“toc”的 <div> 元素的内容,对源 HTML 文档执行修改。它有三种不同的操作模式:生成删除编号

生成模式下,该工具

  • 为 HTML 文档中出现的 HTML <h2> 到 <h6> 标签 [^] 生成目录 (TOC)。
  • 允许指定哪些标签要包含在目录中。
  • 允许指定的标签不连续(例如,“h2,h3,h5”将为级别 2、3、5 的 HTML 标题生成目录 - 跳过 h4)。
  • 允许为目录和用于目录标题的 HTML 标题级别指定标题。
  • 允许指定是否需要返回目录的链接(此类链接允许读者从目录中包含的每个 HTML 标题返回到目录)。如果需要返回链接,则允许指定要放置在链接中的图像。
  • 目录将放置在 HTML 文档中 TOC <div> 元素所在的位置。

删除模式下,该工具

  • 从 HTML 文档中删除 HTML TOC Generator 之前生成的所有 HTML。
  • 从 HTML 文档中删除 TOC <div> 元素。

编号模式下,该工具执行与生成模式相同的操作,但此外还生成标题编号。

3. TOC-div 元素 目录

TOC-div 元素指定了所需的目录内容以及目录在 HTML 文档中的位置。TOC-div 元素在生成编号模式下都会影响 HTML 输出。在删除模式下则会被忽略。

其最简单的形式是,TOC-div 元素采用以下形式

      <div class="toc"></div>

生成的目录将放置在 HTML 文档中 TOC-div 元素所在的位置。生成的目录将替换 TOC-div 元素。

选择“toc”类是故意的。有了这个类,与 TOC 关联的样式可以在 CSS 中指定。如果 CSS 没有定义这样的类,以下内容可以放在 HTML 文档的 <head> 中。

  <style type="text/css">
    .toc
      {
      }
    .toc-generated
      {
      }
  </style>

下面将讨论“toc-generated”类。请注意,HTML TOC Generator 不需要定义这两个类即可执行。

TOC-div 元素的格式,以修改后的 BNF 表示,是

TOC-div           ::= <div class="toc" 
                          [style="[toc-headers[:<heading-tags-list>];]
                                  [toc-return[:(true|false)];]
                                  [toc-title[:<title-of-toc>];]
                                  [toc-image[:<path-to-image>];]
                                  [toc-image-width[:<width-in-pixels>];]
                                  [toc-image-height[:<height-in-pixels>];]
                                  [toc-header-level[:<heading-tag>];]
                                  [toc-numbering[:<level-list>];]"]>
                      </div> .

heading-tags-list ::= heading-tag 
                  ::= heading-tag, heading-tags-list .

heading-tag       ::= "h2"
                  ::= "h3"
                  ::= "h4"
                  ::= "h5"
                  ::= "h6" .

level-list        ::= level-value
                  ::= level-value, level-list .

level-value       ::= [heading-tag] digit .

digit             ::= "0"
                  ::= "1"
                  ::= "2"
                  ::= "3"
                  ::= "4"
                  ::= "5"
                  ::= "6"
                  ::= "7"
                  ::= "8"
                  ::= "9" .

3.1. TOC-div 属性 目录

TOC-div 元素的两个属性是“class”和“style”。

3.1.1. class 目录

class 属性是必需的,其属性值必须为“toc”。尽管属性值不区分大小写,但该值应为小写(W3C 推荐)。

3.1.2. style 目录

style 属性是可选的,并包含所需的 TOC 内容作为其属性。如果省略该属性,则将使用以下默认 TOC-div 元素

     <div class="toc"
          style="toc-headers:h2,h3,h4,h5,h6;
                 toc-return:true;
                 toc-title=Table of Contents;
                 toc-image:/app_themes/codeproject/img/gototop16.png;
                 toc-image-width:16;
                 toc-image-height:16;
                 toc-header-level:h2;">
     </div>

请注意,属性名称与其属性值之间用冒号(“:”)分隔,并且分号(“;”)将属性彼此分隔。当提供多个属性值时(如上面的 toc-headers 中所示),它们之间用逗号(“,”)分隔。

3.2. TOC-div 样式属性 目录

TOC-div 元素样式属性控制 HTML TOC Generator 生成的内容。如所示,style 属性及其属性可以省略。但是,通过使用 style 属性,可以对 TOC 生成的内容进行显著控制。

3.2.1. toc-headers 目录

toc-headers 指定哪些 HTML 标题标签将生成目录条目。请注意,HTML TOC Generator 永远不会处理 HTML <h1> 标签。

toc-headers 属性可以省略,如果省略,HTML 文档中出现的所有 HTML 标题标签的条目都将放置在目录中。同样,如果 toc-headers 属性存在,但省略了 heading-tags-list,则 HTML 文档中出现的所有 HTML 标题标签的条目都将放置在目录中。

heading-tags-list 由一个或多个“h2”、“h3”、“h4”、“h5”或“h6”组成,顺序不限,大小写不限,用逗号分隔。heading-tags-list 中的空格将被忽略。空的 heading-tags-list 将被视为省略了 heading-tags-list,并且 HTML 文档中出现的所有 HTML 标题标签的条目都将放置在目录中。heading-tags-list 中无法识别或重复的值将被忽略。

一个 heading-tags-list 的例子是“h3,H5,h 2,foo,h4bar,h8,h2”。对于这个例子,将为 HTML 标题标签 <h2>、<h3> 和 <h5> 生成 TOC 条目。“foo”、“h4bar”和“h8”将被忽略。条目“h 2”将被识别为“h2”,并且重复的“h2”将被忽略。条目“H5”将被修改为“h5”。尽管 heading-tags-list 中的条目是无序的,但 TOC 条目将是有序的。

在处理 HTML 标题时,HTML 文本格式化标签会保留。这些包括:

Tag描述
<b>粗体文本
<del>删除的文本
<em>强调的文本
<i>斜体文本
<ins>插入的文本
<mark>标记/高亮文本
<small>小文本
<strong>重要文本
<sub>下标文本
<sup>上标文本

为了更全面地理解 HTML TOC 生成处理,本文中使用的某些基本术语需要定义。

Element Definition

所有 HTML 元素都被认为在其标签的起始 "<" 处开始,并在其结束标签的结束 ">" 处结束。

HTML 元素的内容被认为在其起始标签的结束 ">" 之后立即开始,并在其结束标签的起始 "<" 之前立即结束。

在初步处理 <h?> 和 <div> 元素时,HTML TOC Generator 会删除任何先前生成的类为“toc-generated”的元素。例如,如果之前的示例标题已被处理,它可能会采用以下形式。

Expanded Element

"toc_bookmark_1" 书签是此标题在目录中条目的目标。“toc-generated”类是 HTML TOC Generator 的信号,表明此元素应在任何删除过程中删除。

第二个 <a> 元素中的 href 指向目录。<img> 元素之所以存在,是因为用户没有指定 toc-return-image,因此使用了默认值。同样,“toc-generated”类是删除此元素的信号。

当所有初始处理完成后,标题元素将显示为原始标题,如上文所示。

3.2.2. toc-return 目录

toc-return 指定是否在 HTML 标题标签的内容中放置返回目录的链接。此类返回链接允许读者从文档中的位置返回到目录。识别的属性值为“true”和“false”。

如果省略 toc-return 属性,或者如果 toc-return 属性存在但没有属性值,或者如果 toc-return 属性存在但提供了无法识别的属性值,则返回目录的链接将放置在 HTML 标题标签的 InnerHtml 中,并且一个名为“toc_return_to_toc”的书签将放置在目录中。

3.2.3. toc-title 目录

toc-title 指定目录的标题。如果缺少 toc-title,则标题“Table of Contents”将作为目录的前缀。

toc-title 的值可以包含任何字母数字字符以及以下任何字符

    
    Tilde (~)
    Exclamation mark (!)
    Number sign (#)
    Dollar sign ($)
    Percent sign (%)
    Circumflex accent (^)
    Ampersand (&)
    Asterisk (*)
    Left parenthesis (()
    Right parenthesis ())
    Underscore (_)
    Plus sign (+)
    Grave accent (`)
    Hyphen (-)
    Equals sign (=)
    Left bracket ([)
    Right bracket (])
    Vertical line (|)
    Semicolon (;)
    Colon (:)
    Greater-than symbol (>)
    Question mark(?)
    Comma (,) 
    Period (.)
    Space ( )

任何其他字符都将从 toc-title 中删除。如果处理后结果为空字符串,则不会生成目录标题。

3.2.4. toc-image 目录

toc-image 指定将放置在 HTML 标题标签文本中返回目录链接中的图像路径。如果缺少 toc-imagetoc-image 属性值,则路径

    "/app_themes/codeproject/img/gototop16.png" 

将被插入到目录中。属性值可以包含任何有效的路径字符。不进行任何测试以确保提供了有效的路径。

默认路径是专门为 Code Project 文章定义的。生成目录但不会在 Code Project 上发布的文档应指定 toc-image。图像路径必须对 HTML 文档“可见”。请参阅下面的讨论

3.2.5. toc-image-width 目录

toc-image-width 指定将放置在 HTML 标题标签文本中返回目录链接中的图像宽度。如果缺少 toc-image-widthtoc-image-width 属性值,则 toc-image-width 默认为 16 像素。请注意,不提供单位。在 HTML5 中,width 属性指定图像的宽度(以像素为单位)。

3.2.6. toc-image-height 目录

toc-image-height 指定将放置在 HTML 标题标签文本中返回目录链接中的图像高度。如果缺少 toc-image-heighttoc-image-height 属性值,则 toc-image-height 默认为 16 像素。请注意,不提供单位。在 HTML5 中,height 属性指定图像的高度(以像素为单位)。

3.2.7. toc-header-level 目录

toc-header-level 指定用于显示 TOC 标题的 HTML 标题级别。如果缺少 toc-header-level 属性,则 HTML 标题级别“h2”将用于 TOC 标题元素。

属性值可以是 HTML 标题级别“h2”、“h3”、“h4”、“h5”或“h6”中的任何一个。任何其他值都将被忽略,并且 toc-header-level 值将变为“h2”。

3.2.8. toc-numbering 目录

toc-numbering 用于在 HTML 文档中插入标题编号。如果缺少 toc-numbering,则不会在 HTML 文档中插入标题编号。

如果 toc-numbering 存在但 toc-numbering 属性值缺失,则所有标题的标题编号将使用“h21,h31,h41,h51,h61”的级别列表插入到 HTML 文档中。此级别列表将生成以下标题编号:

    1. H2 heading
    1.1. H3 heading
    1.1.1. H4 heading
    1.1.1.1. H5 heading
    1.1.1.1.1. H6 heading

如果一个大型 HTML 文档被分解为单独的 HTML 文档,通过使用从一个 HTML 文档到下一个 HTML 文档不同的级别列表,标题编号可以在单独的 HTML 文档之间保持连续。

例如,一个大型 HTML 文档的一部分是

    <div class="toc" 
         style="toc-numbering;"></div>
    <h2>Heading 1</h2>
        :
        large amount of HTML
        :
    <h2>Heading 2</h2>
        :
        large amount of HTML
        :
    <h2>Heading 3</h2>
        :
        large amount of HTML
        :

由于单个 h2 元素之间生成的 HTML 文本太大,无法适应所需的页面大小,因此 HTML 文档将按 h2 标题级别分解为较小的 HTML 文档。然而,希望标题编号在文档的所有部分中保持连续。通过修改每个较小 HTML 文档的级别列表属性,可以实现连续的标题编号。

    <div class="toc" 
         style="toc-numbering:h21;"></div>
    <h2>Heading 1</h2>
        :
        large amount of HTML
        :

    <div class="toc" 
         style="toc-numbering:h22;"></div>
    <h2>Heading 2</h2>
        :
        large amount of HTML
        :

    <div class="toc" 
         style="toc-numbering:h23;"></div>
    <h2>Heading 3</h2>
        :
        large amount of HTML
        :

任何级别(h2 到 h6)都可以指定其起始级别编号。

4. 生成的目录 目录

4.1. 生成 目录

以下讨论假设在提交给 HTML TOC Generator 的 HTML 文档中找到了以下 TOC-div 元素

    <div class="toc">
    </div>

TOC-div 元素将被重写以显示在处理 HTML 文档期间使用的属性。toc-title 被放置在重写的 TOC-div 元素内容中的默认标题级别条目(在本例中为 <h2>)中。toc-title 被分配给“toc-generated”类。标题之后将出现一个生成的 <div>,其中将包含实际的 TOC。此 <div> 被分配给“toc-generated”类。此 <div> 中的第一个条目将是 TOC 书签(“toc_return_to_toc”),用于从 HTML 文档中的位置返回到 TOC。紧随其后的是包含实际 TOC 的无序列表的起始标签。

到目前为止,生成的 TOC-div 元素将显示为

    <div class="toc"
         style="toc-headers:h2,h3,h4,h5,h6;
                toc-return:true;
                toc-title:Table of Contents;
                toc-return-image:/app_themes/codeproject/img/gototop16.png;
                toc-image_width:16;
                toc-image_height:16;
                toc-header-level:h2;" >
      <h2 class="toc-generated">Table of Contents</h2>
      <div class="toc-generated">
        <a id="toc_return_to_toc" </a>
        <ul>

完全取决于文档的内容,生成的目录条目是使用嵌入在可能嵌套的 <ul> 元素中的 <li> 元素创建的。当遇到从属标题级别时发生嵌套。给定以下 <h2> 标签

    <h2>Introduction</h2>

目录中将生成以下条目

    <li><a href="#toc_bookmark_1">Introduction</a></li>

并且 <h2> 元素将被修改为

    <h2>Introduction
      <a id="toc_bookmark_1"
         class="toc-generated" >
      </a>
      <a href="#toc_return_to_toc"
         class="toc-generated" >
        <img alt="Table of Contents"
             title="Table of Contents"
             src="/app_themes/codeproject/img/gototop16.png"
             width="16"
             height="16" />
      </a> 
    </h2>

任何带有“toc-generated”类的现有书签或链接都将被删除。在前面的示例中,在重新生成之前,剩下的只有

    <h2>Introduction</h2>

书签 ID 属性值(即,“toc_bookmark_1”)由 HTML TOC Generation 过程生成,并且在 HTML 文档中将是唯一的(假设输入 HTML 中不存在包含生成值的病态情况)。在此示例中,还生成了一个图像链接,单击该链接将使读者返回目录的顶部。

4.2. 编号 目录

如果指定了 toc-numbering,例如

    <div class="toc"
         style="toc-numbering;"
    </div>

则 TOC-div 元素的初始部分将生成为

    <div class="toc"
         style="toc-headers:h2,h3,h4,h5,h6;
                toc-return:true;
                toc-title:Table of Contents;
                toc-return-image:/app_themes/codeproject/img/gototop16.png;
                toc-image_width:16;
                toc-image_height:16;
                toc-header-level:h2;
                toc-numbering:h21,h31,h41,h51,h61;" >
      <h2 class="toc-generated">Table of Contents</h2>
      <div class="toc-generated">
        <a id="toc_return_to_toc" </a>
        <ul>

如果第二个 <h2> 元素是

    <h2>Introduction</h2>

目录中将生成以下条目

    <li><a href="#toc_bookmark_1">2. Introduction</a></li>

并且 <h2> 元素内容将被修改为

    <h2><span class="toc-generated" >2. </span>Introduction
      <a id="toc_bookmark_1"
         class="toc-generated" >
      </a>
      <a href="#toc_return_to_toc"
         class="toc-generated" >
        <img alt="Table of Contents"
             title="Table of Contents"
             src="/app_themes/codeproject/img/gototop16.png"
             width="16"
             height="16" />
      </a> 
    </h2>

4.3. 示例 目录

如果将以下 HTML 文档提交给 HTML TOC Generator

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
  <title>Test Auto TOC Generation</title>
  <link type="text/css" 
        rel="stylesheet" 
        href="http://s.codeproject.com/App_Themes/CodeProject/Css/Main.min.css?dt=2.6.130426.1" />
  <style type="text/css">
    .toc
      {
      }
    .toc-generated
      {
      }
  </style>
</head>
<body style="margin: 20px;">
<div class="toc">
</div>
<h2>Header Level <b>2</b> - <i>Number 1</i></h2>
<p>H2 1</p>
<h3>Header Level 3 - Number 1</h3>
<p>H3 1</p>
<h4>Header Level 4 - Number 1</h4>
<p>H4 1</p>
<h4>Header Level 4 - Number 2</h4>
<p>H4 2</p>
<h5>Header Level 5 - Number 1</h5>
<p>H5 1</p>
<h6>Header Level 6 - Number 1</h6>
<p>H6 1</p>
<h4>Header Level 4 - Number 3</h4>
<p>H4 3</p>
<h3>Header Level 3 - Number 2</h3>
<p>H3 2</p>
<h2>Header Level 2 - Number 2</h2>
<p>H2 2</p>
</body>
</html>

将生成的 HTML 文档是

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> 
  <title>Test Auto TOC Generation</title>
  <link type="text/css" 
        rel="stylesheet" 
        href="http://s.codeproject.com/App_Themes/CodeProject/Css/Main.min.css?dt=2.6.130426.1" />
  <style type="text/css">
    .toc
      {
      }
    .toc-generated
      {
      }
  </style>
</head>
<body style="margin: 20px;">
<div class="toc"
     style="toc-headers:h2,h3,h4,h5,h6;
            toc-return:true;
            toc-title:Table of Contents;
            toc-return-image:/app_themes/codeproject/img/gototop16.png;
            toc-image_width:16;
            toc-image_height:16;
            toc-header-level:h2;" >
  <h2 class="toc-generated">Table of Contents</h2>
  <div class="toc-generated">
    <a id="toc_return_to_toc"> </a>
    <ul>
      <li><a href="#toc_bookmark_0">Header Level <b>2</b> - <i>Number 1</i></a>
        <ul>
          <li><a href="#toc_bookmark_1">Header Level 3 - Number 1</a>
            <ul>
              <li><a href="#toc_bookmark_2">Header Level 4 - Number 1</a></li>
              <li><a href="#toc_bookmark_3">Header Level 4 - Number 2</a>
                <ul>
                  <li><a href="#toc_bookmark_4">Header Level 5 - Number 1</a>
                    <ul>
                      <li><a href="#toc_bookmark_5">Header Level 6 - Number 1</a></li>
                    </ul>
                  </li>
                </ul>
              </li>
              <li><a href="#toc_bookmark_6">Header Level 4 - Number 3</a></li>
            </ul>
          </li>
          <li><a href="#toc_bookmark_7">Header Level 3 - Number 2</a></li>
        </ul>
      </li>
      <li><a href="#toc_bookmark_8">Header Level 2 - Number 2</a></li>
    </ul>
    <p>
    The symbol 
    <a href="#toc_return_to_toc">
      <img alt="Table of Contents"
           title="Table of Contents"
           src="/app_themes/codeproject/img/gototop16.png"
           width="16"
           height="16" />
    </a> 
    returns the reader to the top of the Table of Contents.
    </p>
  </div>
</div>

<h2>Header Level <b>2</b> - <i>Number 1</i>
  <a id="toc_bookmark_0"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h2>
<p>H2 1</p>
<h3>Header Level 3 - Number 1
  <a id="toc_bookmark_1"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h3>
<p>H3 1</p>
<h4>Header Level 4 - Number 1
  <a id="toc_bookmark_2"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h4>
<p>H4 1</p>
<h4>Header Level 4 - Number 2
  <a id="toc_bookmark_3"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h4>
<p>H4 2</p>
<h5>Header Level 5 - Number 1
  <a id="toc_bookmark_4"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h5>
<p>H5 1</p>
<h6>Header Level 6 - Number 1
  <a id="toc_bookmark_5"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h6>
<p>H6 1</p>
<h4>Header Level 4 - Number 3
  <a id="toc_bookmark_6"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h4>
<p>H4 3</p>
<h3>Header Level 3 - Number 2
  <a id="toc_bookmark_7"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h3>
<p>H3 2</p>
<h2>Header Level 2 - Number 2
  <a id="toc_bookmark_8"
     class="toc-generated" >
  </a>
  <a href="#toc_return_to_toc"
     class="toc-generated" >
    <img alt="Table of Contents"
         title="Table of Contents"
         src="/app_themes/codeproject/img/gototop16.png"
         width="16"
         height="16" />
  </a> 
</h2>
<p>H2 2</p>
</body>
</html>

5. 目录删除 目录

当针对由 HTML TOC Generator 处理过的 HTML 文档调用目录删除过程时,所有生成的 HTML 都将被删除。这包括 TOC-div 元素以及所有带有“toc-generated”类的元素。

6. 实现 目录

HTML TOC Generator 封装在 HTMLTOCGenerator.cs 文件中。两个入口点提供服务:add_TOC_to_htmlremove_TOC_from_html。两者都接受一个字符串参数,该参数是要执行的 HTML。两者都返回一个包含可能已修订的 HTML 的字符串。

HTMLTOCGenerator.cs 的 using 指令是

    using System;
    using System.Collections.Generic;
    using System.Text;

    using CONST = HTMLTOCGenerator.Constants;
    using DATA = HTMLTOCGenerator.Data;
    using ELEMENT = HTMLTOCGenerator.Element;
    using HTMLPARSER = HTMLTOCGenerator.HTMLParser;
    using NUMBERING = HTMLTOCGenerator.TOCNumbering;
    using TOC = HTMLTOCGenerator.TOCDIV;
    using TYPE = HTMLTOCGenerator.Constants.Element_Type;

这两种方法是

      // ********************************************* add_TOC_to_html

      /// <summary>
      /// returns the html that was revised by applying the TOC-div 
      /// found in the supplied html
      /// 
      /// if a TOC-div is not found, returns the source html
      /// </summary>
      public static string add_TOC_to_html ( string html )
          {
          HTMLPARSER     HTML_parser = new HTMLPARSER ( );
          string         rewriten_html = html;

          HTML_parser.collect_all_desired_elements ( html );
          if ( TOC.HaveTOCDIV )
              {
              HTML_parser.revise_element_content ( );
              HTML_parser.eliminate_unwanted_elements ( );
              rewriten_html = rewrite_html ( html );
              }

          return ( rewriten_html );
          }

      // ************************************** remove_TOC_from_html

      /// <summary>
      /// returns the html that has all auto-generated TOC entries 
      /// removed from the source html
      /// </summary>
      public static string remove_TOC_from_html ( string html )
          {
          HTMLPARSER      HTML_parser = new HTMLPARSER ( );
          int             html_start = 0;
          int             html_to_copy = 0;
          StringBuilder   sb = new StringBuilder ( );

          HTML_parser.collect_all_desired_elements ( html );
          HTML_parser.revise_element_content ( );
          foreach ( ELEMENT element in DATA.Elements )
              {
                                      // copy html up to the next 
                                      // header or TOC-div element
              html_to_copy = element.ElementStartsAt - 
                             html_start - 1;
              if ( html_to_copy > 0 )
                  {
                  sb.Append ( html, html_start, html_to_copy );
                  }
                                      // copy in the rewritten 
                                      // contents of the element
              if ( element.ElementType == TYPE.TOCDIV )
                  {

                  }
              else
                  {
                  sb.AppendFormat ( "\n<{0}>{1}</{0}>\n",
                            element.TagName,
                            element.Content );
                  }
              html_start = element.ElementEndsAt + 1;
              }
          html_to_copy = html.Length - html_start;
          sb.Append ( html, html_start, html_to_copy );

          return ( sb.ToString ( ) );
          }

HTML 解析器封装在 HTMLParser 类中。该解析器最初由 Jeff Heaton 开发,可作为 C# 解析器 [^] 提供。对解析器进行了重大修改,使其自限制于 <h2>、<h3>、<h4>、<h5>、<h6> 和 <div> 元素。

生成编号删除过程对 HTML 进行一次遍历。当所有所需的标题和 <div> 都被识别后,HTML 将被复制到输出。

为了让生成编号模式修改源 HTML,TOC-div 元素必须位于源 HTML 中。如果找不到该元素,则返回未修改的源 HTML。调用程序可以通过测试源和返回的 HTML 的长度来确定是否发生了这种情况。如果长度相同,则未找到 TOC-div 元素,并且未进行任何修改。

删除过程不需要 TOC-div 元素存在。它会查找所有包含带有“toc-generated”类的 <a> 或 <span> 元素的标题元素。然后它会删除这些元素。它还会删除它找到的任何现有 TOC-div 元素。

复制过程在 HTML 中跳转,由收集到的标题和 <div> 数据引导。这由上面的 remove_TOC_from_html 源代码演示。

我正在考虑将 HTML 解析器从使用索引缓冲区的解析器替换为使用 StringReader [^] 的解析器。StringReader 的优点是它的预读能力(即 Peek 方法)。缺点是实现修订所需的时间。

7. HTML TOC Generator 工具 目录

尽管 HTML TOC Generator 工具旨在测试 add_TOC_to_htmlremove_TOC_from_html 两种方法,但由于它生成了有用的 HTML,因此包含在本文的下载中。

本节提供的图片均为缩略图。点击图片可查看放大图片。

7.1. HTML TOC Generator 工具启动 目录

工具的输入通过 HTML 输入选项卡中的 RichTextBox 进行。有两种方式可以提供输入:

1. 直接将 HTML 复制到 RichTextBox 中。
2. 使用“浏览”按钮选择 HTML 文件。

HTML TOC Start

7.2. HTML TOC Generator 工具输入阶段 目录

当 HTML 输入选项卡 RichTextBox 的内容提供后,“生成”按钮就会出现。如果 HTML 包含字符串“toc-generated”,则“删除”按钮也会出现。

HTML TOC Input

在上面的例子中,“浏览”按钮被用来获取本文的 HTML。请注意,在底部附近定义了一个 TOC-div 元素。还要注意,“删除”按钮是可见的,即使目录尚未生成。这是因为本文包含了字符串“toc-generated”。

在单击“生成”按钮之前,可以修改 HTML 输入选项卡 RichTextBox 的内容。

7.3. HTML TOC Generator 工具创建目录 目录

该工具不可重入。因此,一旦点击“生成”按钮,其可见性将被设置为 false。要将该工具应用于另一个 HTML 文件,需要重新执行该工具。

HTML TOC Revised

点击“生成”按钮后,将针对 HTML 输入选项卡 RichTextBox 的内容调用 add_TOC_to_html 方法。其执行结果将放置在修订后的 HTML 选项卡 RichTextBox 中。

在上面的示例中,所有标题都已被修改。此外(尽管不可见),TOC-div 元素已如上文所述被替换。

支持两个选项卡之间的导航。

如果需要,可以保存修订后的 HTML。这可以通过单击“保存”按钮并完成“保存文件”对话框来实现。为方便使用,系统会建议一个保存操作的文件名。它由原始输入文件名构成,在输入文件名之后和扩展名之前插入“.TOC”。

7.4. HTML TOC Generator 工具目录删除 目录

删除过程的操作方式与生成编号大致相同。选择一个 HTML 文件,如果在文档中找到“toc-generated”,则显示“删除”按钮。单击后,所有 HTML TOC 生成的元素都将被删除。TOC-div 元素也将被删除。

8. 返回目录图像 目录

Return To Toc

对于不会由 Code Project 发布的 HTML 文档,下载中包含一个名为 ReturnToToc.png 的图片,可用于 toc-image,位于 HTMLTOCGeneratorDialogProject ZIP 中。该图片为 31 x 31 像素。我建议将宽度和高度设置为 16(如左侧图片所示)。该图片没有版权限制。

9. 总结 目录

本文介绍了对 HTML 创作工具的修订,该工具可为 HTML 文档生成目录。此外,该工具还可指示生成带编号的 HTML 标题。

10. 参考 目录

11. 开发环境 目录

HTML TOC Generator 是在以下环境中开发的

Microsoft Windows 7 Professional Service Pack 1
Microsoft Visual Studio 2008 Professional
Microsoft .Net Framework Version 3.5 SP1
Microsoft Visual C# 2008

12. 历史 目录

08/22/2017 HTML TOC Generator V4.1
04/10/2015 原文
© . All rights reserved.