theme-next / hexo-theme-next

Elegant and powerful theme for Hexo.
https://theme-next.org
Other
8.13k stars 2.05k forks source link

怎么让文中的标题自动编号 #873

Closed AlexHex7 closed 3 years ago

AlexHex7 commented 5 years ago

https://github.com/iissnan/hexo-theme-next/issues/1781

其中说明了如何取消sidebar的多级标题自动编号方法,那么如何启动文中各级标题自动编号,而非手动添加呢?

How to automatically add list number in article's headings? For example

# Heading 1
## Heading 2

I hope it will display in my articale like this:

1. Heading 1
    1.1 Heading 2
stevenjoezhang commented 5 years ago

如果你指的是在正文中,手动加CSS即可:

<style>
body {counter-reset: h2}
  h2 {counter-reset: h3}
  h3 {counter-reset: h4}
  h4 {counter-reset: h5}
  h5 {counter-reset: h6}
  h2:before {counter-increment: h2; content: counter(h2) ". "}
  h3:before {counter-increment: h3; content: counter(h2) "." counter(h3) ". "}
  h4:before {counter-increment: h4; content: counter(h2) "." counter(h3) "." counter(h4) ". "}
  h5:before {counter-increment: h5; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
  h6:before {counter-increment: h6; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}
  h2.nocount:before, h3.nocount:before, h4.nocount:before, h5.nocount:before, h6.nocount:before { content: ""; counter-increment: none }
</style>
AlexHex7 commented 5 years ago

@stevenjoezhang 感谢回复,请问这段CSS添加到哪个文件中?

stevenjoezhang commented 5 years ago

加到NexT下的source/css/_custom/custom.styl中即可(去掉<style></style>

AlexHex7 commented 5 years ago

@stevenjoezhang 按照你给的代码修改后,文中标题的编号与sidebar上面的对不上(因为一级标题没有被编号)。我尝试着改了一下代码,现在每篇post中的一级标题也能显示标号。

body {counter-reset: h1}
  h1 {counter-reset: h2}
  h2 {counter-reset: h3}
  h3 {counter-reset: h4}
  h4 {counter-reset: h5}
  h5 {counter-reset: h6}

  h1:before {counter-increment: h1; content: counter(h1) ". "}
  h2:before {counter-increment: h2; content: counter(h1) "." counter(h2) ". "}
  h3:before {counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". "}
  h4:before {counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "}
  h5:before {counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
  h6:before {counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}
  h1.nocount:before, h2.nocount:before, h3.nocount:before, h4.nocount:before, h5.nocount:before, h6.nocount:before { content: ""; counter-increment: none }

image

但是主页上的所有标题也会出现编号,如何让主页上不显示编号? image

AlexHex7 commented 5 years ago

目前我采用的解决方案是:(1)不显示一级标题的编号,从二级标题开始显示;(2)修改了一下二级标题的样式。十分感谢提供代码。 (目的是为了更好区分文中一二三级标题)修改后代码如下:

body {counter-reset: h1}
  h1 {counter-reset: h2}
  h2 {counter-reset: h3}
  h3 {counter-reset: h4}
  h4 {counter-reset: h5}
  h5 {counter-reset: h6}
  h2:before {counter-increment: h2; content: counter(h2) ") "}
  h3:before {counter-increment: h3; content: counter(h2) "." counter(h3) ") "}
  h4:before {counter-increment: h4; content: counter(h2) "." counter(h3) "." counter(h4) ") "}
  h5:before {counter-increment: h5; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ") "}
  h6:before {counter-increment: h6; content: counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ") "}
  h2.nocount:before, h3.nocount:before, h4.nocount:before, h5.nocount:before, h6.nocount:before { content: ""; counter-increment: none }

效果如下: image

AlexHex7 commented 5 years ago

@stevenjoezhang 感觉区别还是不明显……想问一下,如何将上面的代码(多级标题编号)只应用于各文章页面,而主页、tag、archive这三面页面不出现自动编号

stevenjoezhang commented 4 years ago

@AlexHex7 这个理论上也可以用CSS实现(不同页面的class name不同),我看下能不能做成插件

BaoHaoYu commented 4 years ago

themes\next\scripts\filters 创建一个js文件,代码如下

'use strict'

let cheerio

hexo.extend.filter.register(
  'after_post_render',
  (data) => {
    if (!cheerio) cheerio = require('cheerio')

    const $ = cheerio.load(data.content, {
      decodeEntities: false,
    })
    const $excerpt = cheerio.load(data.excerpt, {
      decodeEntities: false,
    })

    let elHlist = $('h2,h3,h4,h5,h6')
    // h2到h6的标题编号
    let h2 = '',
      h3 = '',
      h4 = '',
      h5 = '',
      h6 = '',
      // 相对于父级的第几个子标题
      h2index = 1,
      h3index = 1,
      h4index = 1,
      h5index = 1,
      h6index = 1

    elHlist.each((i, el) => {
      // 标题编号
      let hindexString = ''
      switch ($(el).get(0).tagName) {
        case 'h2': {
          h3index = 1
          h2 = h2index
          h2index++
          hindexString = h2
          break
        }
        case 'h3': {
          h4index = 1
          h3 = h2 + '.' + h3index
          h3index++
          hindexString = h3
          break
        }
        case 'h4': {
          h5index = 1
          h4 = h3 + '.' + h4index
          h4index++
          hindexString = h4
          break
        }
        case 'h5': {
          h6index = 1
          h5 = h4 + '.' + h5index
          h5index++
          hindexString = h5
          break
        }
        case 'h6': {
          h6 = h5 + '.' + h6index
          h6index++
          hindexString = h6
          break
        }
      }
      $(el).prepend(
        $('<span />')
          .addClass('post-title-index')
          .text(hindexString + '. ')
      )
    })

    data.content = $.html()
    data.excerpt = $excerpt.html()
  },
  10
)

修改 themes\next\source\css\main.styl, 隐藏原来的编号

 .nav-number {
   display: none;
 }

效果

stevenjoezhang commented 4 years ago

其实这可以做成一个独立于主题的插件。

找到了一个现成的,不知道这个能不能满足需求: https://github.com/r12f/hexo-heading-index

另见 https://github.com/hexojs/hexo-theme-landscape/issues/73

GitHub
r12f/hexo-heading-index
Automatically adding index to all headings for hexo. - r12f/hexo-heading-index
sli1989 commented 4 years ago

but introdued the confict between ordered list. 😢

pencilheart commented 4 years ago

vscode中添加markdown haed number插件,编辑文章的时候最后用插件加一下就ok了

bmxbmx3 commented 4 years ago

@stevenjoezhang 我找到一篇自动编号的文章Automatically numbering headings via CSS,根据这个改的。

我的Next版本:7.5.0

参考hexo的NexT主题,怎么取消“文章目录”对标题的自动编号?,把themes\next\_config.yml文件下的toc>number改成false,去掉文章目录的自动编号。

然后我参考了这个,在source\_data\styles.styl文件里添加了自定义的样式:

//加上.post-body,只应用于各文章页面,主页、tag、archive这三面页面不出现自动编号
.post-body {
  h1 {
    counter-reset: h2;
  }

  h2 {
    counter-reset: h3;
  }

  h3 {
    counter-reset: h4;
  }

  h4 {
    counter-reset: h5;
  }

  h5 {
    counter-reset: h6;
  }

  h2:before {
    counter-increment: h2;
    content: counter(h2) '. ';
  }

  h3:before {
    counter-increment: h3;
    content: counter(h2) '.' counter(h3) '. ';
  }

  h4:before {
    counter-increment: h4;
    content: counter(h2) '.' counter(h3) '.' counter(h4) '. ';
  }

  h5:before {
    counter-increment: h5;
    content: counter(h2) '.' counter(h3) '.' counter(h4) '.' counter(h5) '. ';
  }

  h6:before {
    counter-increment: h6;
    content: counter(h2) '.' counter(h3) '.' counter(h4) '.' counter(h5) '.' counter(h6) '. ';
  }
}

.nav {
  .nav-item.nav-level-1 {
    counter-reset: h2;
  }

  .nav-item.nav-level-2 {
    counter-reset: h3;
  }

  .nav-item.nav-level-3 {
    counter-reset: h4;
  }

  .nav-item.nav-level-4 {
    counter-reset: h5;
  }

  .nav-item.nav-level-5 {
    counter-reset: h6;
  }

  .nav-item.nav-level-1 ol .nav-item.nav-level-2 a span:before {
    counter-increment: h2;
    content: counter(h2) '. ';
  }

  .nav-item.nav-level-2 ol .nav-item.nav-level-3 a span:before {
    counter-increment: h3;
    content: counter(h2) '.' counter(h3) '. ';
  }

  .nav-item.nav-level-3 ol .nav-item.nav-level-4 a span:before {
    counter-increment: h4;
    content: counter(h2) '.' counter(h3) '.' counter(h4) '. ';
  }

  .nav-item.nav-level-4 ol .nav-item.nav-level-5 a span:before {
    counter-increment: h5;
    content: counter(h2) '.' counter(h3) '.' counter(h4) '.' counter(h5) '. ';
  }

  .nav-item.nav-level-5 ol .nav-item.nav-level-6 a span:before {
    counter-increment: h6;
    content: counter(h2) '.' counter(h3) '.' counter(h4) '.' counter(h5) '.' counter(h6) '. ';
  }
}

显示这个样子: hexo博客自动编号 按照传统上一级标题我没加序号。

BigeYoung commented 2 years ago

对于使用最新版Next 8.8.1的朋友,可以试试我这个代码:

.post-block {
  .post-body {counter-reset: h1}
          h1 {counter-reset: h2}
          h2 {counter-reset: h3}
          h3 {counter-reset: h4}
          h4 {counter-reset: h5}
          h5 {counter-reset: h6}
}
.post-body {
  h1:before {counter-increment: h1; content: counter(h1) ". "}
  h2:before {counter-increment: h2; content: counter(h1) "." counter(h2) ". "}
  h3:before {counter-increment: h3; content: counter(h1) "." counter(h2) "." counter(h3) ". "}
  h4:before {counter-increment: h4; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) ". "}
  h5:before {counter-increment: h5; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) ". "}
  h6:before {counter-increment: h6; content: counter(h1) "." counter(h2) "." counter(h3) "." counter(h4) "." counter(h5) "." counter(h6) ". "}
}

添加在 themes\next\source\css\main.styl 的末尾即可。