欢迎访问Ningto's博客

Menu
  • 首页
  • 归档
  • 关于
  • 书签
  • 必应壁纸
  • IT聚合
  • 工具
    • 我的工具列表
    • 我的网盘
    • 必应每日壁纸API
    • Html转Markdown
    • 仙尘光标
Menu

博客文章增加TOC

最后更新 2021-03-17 12:12:07   阅读量 1374

Table of Contents

  • 1. 获取所有h1标签
  • 2. 拼装成html文本
  • 3. 引入css
  • 4. 结果

博客文章是使用Markdown写的,有了TOC(Table of Contents)阅读起来体验更好,TOC就是所有h1组成的标签目录,点击后调到相应的位置。

获取所有h1标签

我用的是github_markdown库,在renderer的Header方法中可以获取,存储在level1List 列表中

func (r *renderer) Header(out *bytes.Buffer, text func() bool, level int, _ string) {
    marker := out.Len()
    doubleSpace(out)

    if !text() {
        out.Truncate(marker)
        return
    }

    textHTML := out.String()[marker:]
    out.Truncate(marker)

    // Extract text content of the heading.
    var textContent string
    if node, err := html.Parse(strings.NewReader(textHTML)); err == nil {
        textContent = extractText(node)
    } else {
        // Failed to parse HTML (probably can never happen), so just use the whole thing.
        textContent = html.UnescapeString(textHTML)
    }
    anchorName := sanitized_anchor_name.Create(textContent)

    out.WriteString(fmt.Sprintf(`<h%d><a name="%s" class="anchor" href="#%s" rel="nofollow" aria-hidden="true"><span class="octicon octicon-link"></span></a>`, level, anchorName, anchorName))
    out.WriteString(textHTML)
    out.WriteString(fmt.Sprintf("</h%d>\n", level))

    if level == 1 {
        r.level1List = append(r.level1List, anchorName)
    }
}

拼装成html文本

tocTemplate就是拼装后的html将其放在文章内容前面就可以了

func Markdown(text []byte) []byte {
    var htmlFlags = 0
    renderer := &renderer{Html: blackfriday.HtmlRenderer(htmlFlags, "", "").(*blackfriday.Html)}
    unsanitized := blackfriday.Markdown(text, renderer, extensions)
    sanitized := policy.SanitizeBytes(unsanitized)

    if len(renderer.level1List) > 0 {
        var headerNameList []string
        for i, v := range renderer.level1List {
            headerNameList = append(headerNameList, fmt.Sprintf(`<li><a class="ez-toc-link" href="#%s">%d. %s</a></li>`, v, i+1, v))
        }
        var tocTemplate = fmt.Sprintf(
            `<div id="ez-toc-container" class="ez-toc-light-blue">
                <div class="ez-toc-title-container">
                    <p class="ez-toc-title">Table of Contents</p>
                    <span class="ez-toc-title-toggle">
                        <a class="ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle">
                            <i class="fa fa-dedent"></i>
                        </a>
                    </span>
                </div>
                <nav><ul>%s</ul></nav>
            </div>`, strings.Join(headerNameList, ""))
        b := []byte(tocTemplate)
        b = append(b, sanitized...)
        return b
    }

    return sanitized
}

引入CSS

将css文件引入到html中

#ez-toc-container {
    background:#f9f9f9;
    border:1px solid #aaa;
    border-radius:4px;
    box-shadow:0 1px 1px rgba(0,0,0,.05);
    display:table;
    margin-bottom:1em;
    padding:10px;
    position:relative;
    width:auto
}
div.ez-toc-widget-container {
    padding:0;
    position:relative
}
#ez-toc-container.ez-toc-light-blue {
    background:#edf6ff
}
#ez-toc-container.ez-toc-white {
    background:#fff
}
#ez-toc-container.ez-toc-black {
    background:#000
}
#ez-toc-container.ez-toc-transparent {
    background:none transparent
}
div.ez-toc-widget-container ul {
    display:block
}
div.ez-toc-widget-container li {
    border:none;
    padding:0
}
div.ez-toc-widget-container ul.ez-toc-list {
    padding:10px
}
#ez-toc-container ul ul,.ez-toc div.ez-toc-widget-container ul ul {
    margin-left:1.5em
}
#ez-toc-container li,#ez-toc-container ul {
    margin:0;
    padding:0
}
#ez-toc-container li,#ez-toc-container ul,#ez-toc-container ul li,div.ez-toc-widget-container,div.ez-toc-widget-container li {
    background:0 0;
    list-style:none none;
    line-height:1.6;
    margin:0;
    overflow:hidden;
    z-index:1
}
#ez-toc-container p.ez-toc-title {
    text-align:left;
    line-height:1.45;
    margin:0;
    padding:0;
    color:#000;
    font-weight:bold;
    font-size: 1.2em;
}
.ez-toc-title-container {
    display:table;
    width:100%
}
.ez-toc-title,.ez-toc-title-toggle {
    display:table-cell;
    text-align:left;
    vertical-align:middle
}
#ez-toc-container.ez-toc-black p.ez-toc-title {
    color:#fff
}
#ez-toc-container div.ez-toc-title-container+ul.ez-toc-list {
    margin-top:1em
}
.ez-toc-wrap-left {
    float:left;
    margin-right:10px
}
.ez-toc-wrap-right {
    float:right;
    margin-left:10px
}
#ez-toc-container a {
    color:#444;
    text-decoration:none;
    text-shadow:none
}
#ez-toc-container a:visited {
    color:#9f9f9f
}
#ez-toc-container a:hover {
    text-decoration:underline
}
#ez-toc-container.ez-toc-black a {
    color:#fff
}
#ez-toc-container.ez-toc-black a:visited {
    color:#fff
}
#ez-toc-container a.ez-toc-toggle {
    color:#444
}
#ez-toc-container.counter-flat ul,#ez-toc-container.counter-hierarchy ul,.ez-toc-widget-container.counter-flat ul,.ez-toc-widget-container.counter-hierarchy ul {
    counter-reset:item
}
#ez-toc-container.counter-numeric li,.ez-toc-widget-container.counter-numeric li {
    list-style-type:decimal;
    list-style-position:inside
}
#ez-toc-container.counter-decimal ul.ez-toc-list li a::before,.ez-toc-widget-container.counter-decimal ul.ez-toc-list li a::before {
    content:counters(item,".") ". ";
    counter-increment:item
}
#ez-toc-container.counter-roman li a::before,.ez-toc-widget-container.counter-roman ul.ez-toc-list li a::before {
    content:counters(item,".",upper-roman) ". ";
    counter-increment:item
}
.ez-toc-widget-container ul.ez-toc-list li::before {
    content:' ';
    position:absolute;
    left:0;
    right:0;
    height:30px;
    line-height:30px;
    z-index:-1
}
.ez-toc-widget-container ul.ez-toc-list li.active::before {
    background-color:#ededed
}
.ez-toc-widget-container li.active>a {
    font-weight:900
}
.ez-toc-btn {
    display:inline-block;
    padding:6px 12px;
    margin-bottom:0;
    font-size:14px;
    font-weight:400;
    line-height:1.428571429;
    text-align:center;
    white-space:nowrap;
    vertical-align:middle;
    cursor:pointer;
    background-image:none;
    border:1px solid transparent;
    border-radius:4px;
    -webkit-user-select:none;
    -moz-user-select:none;
    -ms-user-select:none;
    -o-user-select:none;
    user-select:none
}
.ez-toc-btn:focus {
    outline:thin dotted #333;
    outline:5px auto -webkit-focus-ring-color;
    outline-offset:-2px
}
.ez-toc-btn:focus,.ez-toc-btn:hover {
    color:#333;
    text-decoration:none
}
.ez-toc-btn.active,.ez-toc-btn:active {
    background-image:none;
    outline:0;
    box-shadow:inset 0 3px 5px rgba(0,0,0,.125)
}
.ez-toc-btn-default {
    color:#333;
    background-color:#fff;
    border-color:#ccc
}
.ez-toc-btn-default.active,.ez-toc-btn-default:active,.ez-toc-btn-default:focus,.ez-toc-btn-default:hover {
    color:#333;
    background-color:#ebebeb;
    border-color:#adadad
}
.ez-toc-btn-default.active,.ez-toc-btn-default:active {
    background-image:none
}
.ez-toc-btn-sm,.ez-toc-btn-xs {
    padding:5px 10px;
    font-size:12px;
    line-height:1.5;
    border-radius:3px
}
.ez-toc-btn-xs {
    padding:1px 5px
}
.ez-toc-btn-default {
    text-shadow:0 -1px 0 rgba(0,0,0,.2);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)
}
.ez-toc-btn-default:active {
    box-shadow:inset 0 3px 5px rgba(0,0,0,.125)
}
.btn.active,.ez-toc-btn:active {
    background-image:none
}
.ez-toc-btn-default {
    text-shadow:0 1px 0 #fff;
    background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);
    background-repeat:repeat-x;
    border-color:#dbdbdb;
    border-color:#ccc
}
.ez-toc-btn-default:focus,.ez-toc-btn-default:hover {
    background-color:#e0e0e0;
    background-position:0 -15px
}
.ez-toc-btn-default.active,.ez-toc-btn-default:active {
    background-color:#e0e0e0;
    border-color:#dbdbdb
}
.ez-toc-pull-right {
    float:right!important;
    margin-left:10px
}

结果

效果就如本文章开头。

(转载本站文章请注明作者和出处:泞途 - ningto.com)

下一篇 – Chrome简单插件开发,自动初始化gitalk评论
上一篇 – Qt QTextEdit文本高亮

  1. Web
  2. Javascript
  3. Go

toningto@outlook.com

标签云

IOS Qt Life Linux Java MongoDB Boost MQ Node.js Mac C/C++ Tools Design Python Bug Others Javascript Tips React Android Web Mobile Shell Product Go Database Windows

推广链接

【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年99元

多谢支持,用了好几年,服务很稳定支持多设备!

其他

文章RSS

Copyright © 2016 Welcome To Ningto Blog | 鄂ICP备17003086号-2