HTML+CSS入门 快速了解HTML目录生成工具
沉沙 2018-05-29 来源 : 阅读 1015 评论 0

摘要:很多博主都会为自己的博文创建目录,方便大家浏览。本文写了几行代码来完成这工作。拿出来分享给有同样需要的朋友。希望阅读本篇文章以后大家有所收获,帮助大家HTML+CSS入门。

很多博主都会为自己的博文创建目录,方便大家浏览。本文写了几行代码来完成这工作。拿出来分享给有同样需要的朋友。
工具代码

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
 
namespace HtmlIndexGenerator
{
    class Program
    {
        const string HeaderPattern = @"<h(?<level>[1-6])[\s\S]*?>[\s\S]*?</h([1-6])>";
        const string TagPattern = @"<[\s\S]*?>";
        const string IdPattern = "(id|name)=\"(?<id>[\\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);
        }
 
        /// <summary>
        /// Prints help document.
        /// </summary>
        private static void PrintHelp()
        {
            Console.WriteLine("Usage: IndexGen.exe [filename] [-l] level");
            Console.WriteLine("-l: header level limit, -l 3 limit the output to <h3>");
            Console.WriteLine("Example: IndexGen.exe page.htm");
        }
 
        /// <summary>
        /// Parses command line paramters.
        /// </summary>
        /// <param name="args">Input parameters</param>
        /// <param name="fileName">Output parameter for parsed file name. Null if parse failed.</param>
        /// <param name="limit">Output parameter for header level limit.</param>
        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];
            }
        }
 
        /// <summary>
        /// Reads html content according to specified file name.
        /// </summary>
        /// <param name="fileName">File name</param>
        /// <returns>Html content of the specific file.</returns>
        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;
        }
 
        /// <summary>
        /// Generates the index html.
        /// </summary>
        /// <param name="html">Html content of specified file.</param>
        /// <param name="limit">Header limit</param>
        /// <returns>Generated index html</returns>
        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("<div id=\"doc-index\">");
            indexBuilder.Append("<ul>");
            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("<a href=\"#{0}\">{1}</a>", id, header);
 
                if (currentLevel == previousLevel)
                {
                    indexBuilder.AppendFormat("<li style=\"{1}\">{0}</li>", link, HeaderStyles[currentLevel - 1]);
                }
                else if (currentLevel > previousLevel && currentLevel <= limit)
                {
                    indexBuilder.AppendFormat("<ul><li style=\"{1}\">{0}</li>", link, HeaderStyles[currentLevel - 1]);
                    previousLevel = currentLevel;
                }
                else if (currentLevel < previousLevel)
                {
                    indexBuilder.AppendFormat("</ul><li style=\"{1}\">{0}</li>", link, HeaderStyles[currentLevel - 1]);
                    previousLevel = currentLevel;
                }
            }
            indexBuilder.Append("</ul></div>");
            return indexBuilder.ToString();
        }
    }
}


使用方法
将程序编译成执行文件,把博文存成本地文件,注意要存成unicode或utf-8,通过命令行运行。一个名叫index.htm的文件会生成在相同目录下。
如果你只希望限制生成目录的级数,可以用 -l 参数指定,-l 3代表只生成<h1> 到<h3>的目录。

HTML+CSS入门 快速了解HTML目录生成工具

双击打开后是这个样子,

HTML+CSS入门 快速了解HTML目录生成工具

接下来需要做的是将生成的内容复制粘贴到博文你想放目录的地方。简单的目录就生成了,参看本文目录。
如果你想更改样式,可以直接修改代码中对不同的header的样式定义。
工具改进
这只是个小工具,肯定有很多让小伙伴们惊呆的不足,
首先不应该用正则表达式解析html,具体原因可以看这里,如果真的要分析html,.net推荐使用htmlagilitypack,python推荐使用beautifulsoup,这里不想再引入外部库,所以假设我们解析的html都是标准格式。
另外没写代码去生成标题的id属性,因为很多朋友希望id是有意义的名字而不简单的header1、lable2之类的,所以id还是需要你自己添加,不然超链接出不来。 <h1 id="intro"></h1>
也尝试把这段代码转换成powershell脚本省了大家编译,这里有介绍如何做的方法,可惜插件也有硬伤,有些语法还不支持,比如using, out 参数等。

本文由职坐标整理并发布,了解更多内容,请关注职坐标WEB前端HTML/CSS频道!

本文由 @沉沙 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程