自动建立目录html,HTML目录生成工具基础介绍

这篇博客介绍了如何使用C#编写的工具自动为HTML文章生成目录。该工具通过正则表达式解析HTML,根据设定的级别限制生成目录结构,并提供自定义样式。文章还分享了使用方法和潜在的改进方向,如避免使用正则解析HTML和生成标题的ID属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

园子里面很多博主都会为自己的博文创建目录,方便大家浏览。我很好奇大家是怎么做的,是不是有自动生成目录的工具可以推荐一下(我知道word可以,但是直接贴word文档会生成很多多余的html tag)。

前几天写前端网页最佳实践目录项实在有点多,手动加起来太麻烦了,我尝试搜了下没有找到,于是写了几行代码来完成这工作。拿出来分享给有同样需要的朋友。

工具代码

using System;

using System.IO;

using System.Text;

using System.Text.RegularExpressions;

namespace HtmlIndexGenerator

{

class Program

{

const string HeaderPattern = @"[1-6])[sS]*?>[sS]*?";

const string TagPattern = @"";

const string IdPattern = "(id|name)="(?[\s\S]*?)"";

const int MaxHeaderLimit = 6;

const string H1Style = @"font-weight:bold";

const string H2Style = @"";

const string H3Style = @"";

const string H4Style = @"";

const string H5Style = @"";

const string H6Style = @"font-size:10px;";

static string[] HeaderStyles = new string[]{

H1Style,

H2Style,

H3Style,

H4Style,

H5Style,

H6Style

};

static void Main(string[] args)

{

string fileName;

int limit;

ParseParameter(args, out fileName, out limit);

string html = GetHtml(fileName);

if (string.IsNullOrEmpty(html))

return;

string index = GenerateIndex(html, limit);

string outputFile = "index.htm";

File.WriteAllText(outputFile, index, Encoding.UTF8);

Console.WriteLine("{0} generated.", outputFile);

}

///

/// Prints help document.

///

private static void PrintHelp()

{

Console.WriteLine("Usage: IndexGen.exe [filename] [-l] level");

Console.WriteLine("-l: header level limit, -l 3 limit the output to

");

Console.WriteLine("Example: IndexGen.exe page.htm");

}

///

/// Parses command line paramters.

///

/// Input parameters

/// Output parameter for parsed file name. Null if parse failed.

/// Output parameter for header level limit.

private static void ParseParameter(string[] args, out string fileName, out int limit)

{

fileName = null;

limit = MaxHeaderLimit;

for (int i = 0; i < args.Length; i++)

{

if (args[i].Equals("-l", StringComparison.InvariantCultureIgnoreCase))

{

if (i + 1 >= args.Length || !int.TryParse(args[i + 1], out limit))

{

Console.WriteLine("Invalid parameter for -l");

PrintHelp();

return;

}

}

}

if (args.Length > 0)

{

fileName = args[args.Length - 1];

}

}

///

/// Reads html content according to specified file name.

///

/// File name

/// Html content of the specific file.

private static string GetHtml(string fileName)

{

string html = null;

if (string.IsNullOrEmpty(fileName))

{

Console.WriteLine("Specify a file name");

PrintHelp();

return html;

}

if (!File.Exists(fileName))

{

Console.WriteLine("File {0} dose not exist", fileName);

PrintHelp();

return html;

}

// Auto defect file encoding.

using (StreamReader reader = new StreamReader(fileName, detectEncodingFromByteOrderMarks: true))

{

Encoding encoding = reader.CurrentEncoding;

html = File.ReadAllText(fileName, encoding);

}

return html;

}

///

/// Generates the index html.

///

/// Html content of specified file.

/// Header limit

/// Generated index html

private static string GenerateIndex(string html, int limit)

{

Regex regex = new Regex(HeaderPattern, RegexOptions.IgnoreCase);

Regex regexId = new Regex(IdPattern, RegexOptions.IgnoreCase);

MatchCollection headerMatches = regex.Matches(html);

int previousLevel = 1;

StringBuilder indexBuilder = new StringBuilder();

indexBuilder.Append("

");

indexBuilder.Append("

  • ");

foreach (Match headerMatch in headerMatches)

{

int currentLevel = int.Parse(headerMatch.Groups["level"].Value);

string header = Regex.Replace(headerMatch.Value, TagPattern, string.Empty);

Match idMatch = regexId.Match(headerMatch.Value);

string id = idMatch.Success ? idMatch.Groups["id"].Value : null;

string link = string.IsNullOrEmpty(id) ? header : string.Format("{1}", id, header);

if (currentLevel == previousLevel)

{

indexBuilder.AppendFormat("

{0}", link, HeaderStyles[currentLevel - 1]);

}

else if (currentLevel > previousLevel && currentLevel <= limit)

{

indexBuilder.AppendFormat("

  • {0}", link, HeaderStyles[currentLevel - 1]);

previousLevel = currentLevel;

}

else if (currentLevel < previousLevel)

{

indexBuilder.AppendFormat("

{0}", link, HeaderStyles[currentLevel - 1]);

previousLevel = currentLevel;

}

}

indexBuilder.Append("

");

return indexBuilder.ToString();

}

}

}

使用方法

将程序编译成执行文件,把博文存成本地文件,注意要存成unicode或utf-8,通过命令行运行。一个名叫index.htm的文件会生成在相同目录下。

如果你只希望限制生成目录的级数,可以用 -l 参数指定,-l 3代表只生成

的目录。

e39289f500bf05ba89440c500b91433b.png

接下来需要做的是将生成的内容复制粘贴到博文你想放目录的地方。简单的目录就生成了,参看本文目录。

如果你想更改样式,可以直接修改代码中对不同的header的样式定义。

工具改进

这只是个小工具,肯定有很多让小伙伴们惊呆的不足,

首先不应该用正则表达式解析html,具体原因可以看这里,如果真的要分析html,.net推荐使用htmlagilitypack,python推荐使用beautifulsoup,我这里不想再引入外部库,所以假设我们解析的html都是标准格式。

另外我没写代码去生成标题的id属性,因为很多朋友希望id是有意义的名字而不简单的header1、lable2之类的,所以id还是需要你自己添加,不然超链接出不来。

也尝试把这段代码转换成powershell脚本省了大家编译,这里有介绍如何做的方法,可惜插件也有硬伤,有些语法还不支持,比如using, out 参数等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值