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





5.00/5 (7投票s)
本文修订了HTML创作工具HTML TOC Generator,该工具可为HTML文档生成目录。此外,该工具还可选择性地为HTML标题编号。
- 下载 HTML TOC Generator 项目 - 24 KB
- 下载 HTML TOC Generator 对话框项目 - 32 KB
- 下载 HTML TOC Generator 工具可执行文件 - 44 KB
目录
1. 简介     
 
 
本文是一个修订版,它
- 从本文、工具和下载中删除测试用例
- 添加了一个召回上次访问目录的功能
- 删除生成的“name”属性
- 删除 <img> width 和 height 属性上生成的“px”单位
本文修订了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 生成处理,本文中使用的某些基本术语需要定义。
所有 HTML 元素都被认为在其标签的起始 "<" 处开始,并在其结束标签的结束 ">" 处结束。
HTML 元素的内容被认为在其起始标签的结束 ">" 之后立即开始,并在其结束标签的起始 "<" 之前立即结束。在初步处理 <h?> 和 <div> 元素时,HTML TOC Generator 会删除任何先前生成的类为“toc-generated”的元素。例如,如果之前的示例标题已被处理,它可能会采用以下形式。
 
"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-image 或 toc-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-width 或 toc-image-width 属性值,则 toc-image-width 默认为 16 像素。请注意,不提供单位。在 HTML5 中,width 属性指定图像的宽度(以像素为单位)。
3.2.6. toc-image-height     
 
toc-image-height 指定将放置在 HTML 标题标签文本中返回目录链接中的图像高度。如果缺少 toc-image-height 或 toc-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_html 和 remove_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_html 和 remove_TOC_from_html 两种方法,但由于它生成了有用的 HTML,因此包含在本文的下载中。
本节提供的图片均为缩略图。点击图片可查看放大图片。
7.1. HTML TOC Generator 工具启动     
 
工具的输入通过 HTML 输入选项卡中的 RichTextBox 进行。有两种方式可以提供输入:
| 1. | 直接将 HTML 复制到 RichTextBox 中。 | 
| 2. | 使用“浏览”按钮选择 HTML 文件。 | 
 
7.2. HTML TOC Generator 工具输入阶段     
 
当 HTML 输入选项卡 RichTextBox 的内容提供后,“生成”按钮就会出现。如果 HTML 包含字符串“toc-generated”,则“删除”按钮也会出现。
 
在上面的例子中,“浏览”按钮被用来获取本文的 HTML。请注意,在底部附近定义了一个 TOC-div 元素。还要注意,“删除”按钮是可见的,即使目录尚未生成。这是因为本文包含了字符串“toc-generated”。
在单击“生成”按钮之前,可以修改 HTML 输入选项卡 RichTextBox 的内容。
7.3. HTML TOC Generator 工具创建目录     
 
该工具不可重入。因此,一旦点击“生成”按钮,其可见性将被设置为 false。要将该工具应用于另一个 HTML 文件,需要重新执行该工具。
 
点击“生成”按钮后,将针对 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. 返回目录图像     
 
 
对于不会由 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 | 原文 | 



