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





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 | 原文 |